mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
See ChangeLog: Fri Jul 14 19:38:23 CEST 2000 Werner Koch
This commit is contained in:
parent
d1648b4d7a
commit
92cd255508
65
ChangeLog
65
ChangeLog
@ -1,6 +1,69 @@
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
The big merge between this one and the stable branch 1.0. Still need
|
||||
to merge TNANKS, AUTHORS and such. It probaly does not compile yet.
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
|
||||
|
||||
* configure.in: Add check for termio.h, wait unctiosn and sigaction.
|
||||
|
||||
* acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
|
||||
|
||||
* acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gaël Quéri.
|
||||
|
||||
* configure.in (AM_INIT_AUTOMAKE): Use this now. By Gaël.
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
|
||||
GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
|
||||
Contributed by Dave Dykstra.
|
||||
* configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
|
||||
|
||||
* configure.in: Add a test for unisgned long long.
|
||||
|
||||
* configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
|
||||
|
||||
* configure.in: Add check for clock_gettime
|
||||
|
||||
* configure.in (ALL_LINGUAS): Add nl.
|
||||
* configure.in (ALL_LINGUAS): Add Esperanto.
|
||||
* configure.in (ALL_LINGUAS): Add sv and ja.
|
||||
|
||||
* configure.in: Use /usr/local for CFLAGS and LDFLAGS when
|
||||
target is freebsd. By Rémi.
|
||||
|
||||
* configure.in: Do not set development version when the version has
|
||||
a dash in it. Suggested by Dave Dykstra.
|
||||
|
||||
* configure.in: Removed substitution for doc/gph/Makefile.
|
||||
Do all the gcc warning only in maintainer mode.
|
||||
|
||||
* configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
|
||||
Suggested by Alexandre Oliva.
|
||||
(-Wall): Moved the settting of gcc warning options near to the end
|
||||
so that tests don't get confused. Suggested by Paul D. Smith.
|
||||
|
||||
* acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
|
||||
(GNUPG_CHECK_RDYNAMIC): Ditto.
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
|
||||
librt. Test suggested by Jeff Long.
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
|
||||
we can't link a test program. This way GNU systems don't need
|
||||
to link against linrt.
|
||||
(GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro. From Tim Mooney.
|
||||
|
||||
* acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
|
||||
DJGPP.
|
||||
(GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
|
||||
|
||||
* acconfig.h (HAVE_MLOCK): Added
|
||||
|
||||
Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* configure.in: Now uses the Docbook M$s from GPH.
|
||||
* configure.in: Now uses the Docbook M4s from GPH.
|
||||
|
||||
Mon Jan 31 17:46:35 CET 2000 Werner Koch <wk@>
|
||||
|
||||
|
@ -53,6 +53,8 @@
|
||||
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
#undef HAVE_MLOCK
|
||||
|
||||
|
||||
#undef BIG_ENDIAN_HOST
|
||||
#undef LITTLE_ENDIAN_HOST
|
||||
|
119
acinclude.m4
119
acinclude.m4
@ -50,6 +50,25 @@ AC_DEFUN(GNUPG_FIX_HDR_VERSION,
|
||||
])
|
||||
|
||||
|
||||
dnl GNUPG_CHECK_GNUMAKE
|
||||
dnl
|
||||
AC_DEFUN(GNUPG_CHECK_GNUMAKE,
|
||||
[
|
||||
if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
AC_MSG_WARN([[
|
||||
***
|
||||
*** It seems that you are not using GNU make. Some make tools have serious
|
||||
*** flaws and you may not be able to build this software at all. Before you
|
||||
*** complain, please try GNU make: GNU make is easy to build and available
|
||||
*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make.
|
||||
***]])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
dnl GNUPG_LINK_FILES( SRC, DEST )
|
||||
dnl same as AC_LINK_FILES, but collect the files to link in
|
||||
dnl some special variables and do the link
|
||||
@ -212,39 +231,38 @@ define(GNUPG_CHECK_PIC,
|
||||
|
||||
|
||||
######################################################################
|
||||
# Check for rdynamic flag
|
||||
# This sets CFLAGS_RDYNAMIC to the required flags
|
||||
# Check for export-dynamic flag
|
||||
# This sets CFLAGS_EXPORTDYNAMIC to the required flags
|
||||
######################################################################
|
||||
dnl GNUPG_CHECK_RDYNAMIC
|
||||
dnl GNUPG_CHECK_EXPORTDYNAMIC
|
||||
dnl
|
||||
define(GNUPG_CHECK_RDYNAMIC,
|
||||
[ AC_MSG_CHECKING(how to specify -rdynamic)
|
||||
CFLAGS_RDYNAMIC=
|
||||
define(GNUPG_CHECK_EXPORTDYNAMIC,
|
||||
[ AC_MSG_CHECKING(how to specify -export-dynamic)
|
||||
if test "$cross_compiling" = yes; then
|
||||
AC_MSG_RESULT(assume none)
|
||||
AC_MSG_RESULT(assume none)
|
||||
CFLAGS_EXPORTDYNAMIC=""
|
||||
else
|
||||
case "$host_os" in
|
||||
solaris* )
|
||||
CFLAGS_RDYNAMIC="-Wl,-dy"
|
||||
;;
|
||||
|
||||
hpux* )
|
||||
CFLAGS_RDYNAMIC="-Wl,-E"
|
||||
;;
|
||||
|
||||
openbsd* | freebsd2* | osf4* | irix* )
|
||||
CFLAGS_RDYNAMIC=""
|
||||
;;
|
||||
|
||||
* )
|
||||
CFLAGS_RDYNAMIC="-Wl,-export-dynamic"
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT($CFLAGS_RDYNAMIC)
|
||||
AC_CACHE_VAL(gnupg_cv_export_dynamic,[
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -Wl,--version 2>&1 |
|
||||
grep "GNU ld" >/dev/null]); then
|
||||
# using gnu's linker
|
||||
gnupg_cv_export_dynamic="-Wl,-export-dynamic"
|
||||
else
|
||||
case "$host_os" in
|
||||
hpux* )
|
||||
gnupg_cv_export_dynamic="-Wl,-E"
|
||||
;;
|
||||
* )
|
||||
gnupg_cv_export_dynamic=""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT($gnupg_cv_export_dynamic)
|
||||
CFLAGS_EXPORTDYNAMIC="$gnupg_cv_export_dynamic"
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Check for SysV IPC (from GIMP)
|
||||
# And see whether we have a SHM_LOCK (FreeBSD does not have it).
|
||||
@ -299,7 +317,8 @@ define(GNUPG_CHECK_IPC,
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>],[
|
||||
int foo( int shm_id ) { shmctl(shm_id, SHM_LOCK, 0); }
|
||||
int shm_id;
|
||||
shmctl(shm_id, SHM_LOCK, 0);
|
||||
],
|
||||
gnupg_cv_ipc_have_shm_lock="yes",
|
||||
gnupg_cv_ipc_have_shm_lock="no"
|
||||
@ -318,11 +337,46 @@ define(GNUPG_CHECK_IPC,
|
||||
######################################################################
|
||||
# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
|
||||
# is not called from uid 0 (not tested whether uid 0 works)
|
||||
# For DECs Tru64 we have also to check whether mlock is in librt
|
||||
# mlock is there a macro using memlk()
|
||||
######################################################################
|
||||
dnl GNUPG_CHECK_MLOCK
|
||||
dnl
|
||||
define(GNUPG_CHECK_MLOCK,
|
||||
[ AC_CHECK_FUNCS(mlock)
|
||||
if test "$ac_cv_func_mlock" = "no"; then
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
if test "$ac_cv_header_sys_mman_h" = "yes"; then
|
||||
# Add librt to LIBS:
|
||||
AC_CHECK_LIB(rt, memlk)
|
||||
AC_CACHE_CHECK([whether mlock is in sys/mman.h],
|
||||
gnupg_cv_mlock_is_in_sys_mman,
|
||||
[AC_TRY_LINK([
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#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
|
||||
* is an alias. */
|
||||
#if defined (__stub_mlock) || defined (__stub___mlock)
|
||||
choke me
|
||||
#else
|
||||
mlock(&i, 4);
|
||||
#endif
|
||||
; return 0;
|
||||
],
|
||||
gnupg_cv_mlock_is_in_sys_mman=yes,
|
||||
gnupg_cv_mlock_is_in_sys_mman=no)])
|
||||
if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
|
||||
AC_DEFINE(HAVE_MLOCK)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$ac_cv_func_mlock" = "yes"; then
|
||||
AC_MSG_CHECKING(whether mlock is broken)
|
||||
AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
|
||||
@ -372,9 +426,10 @@ define(GNUPG_CHECK_MLOCK,
|
||||
])
|
||||
|
||||
|
||||
################################################################
|
||||
|
||||
################################################################
|
||||
# GNUPG_PROG_NM - find the path to a BSD-compatible name lister
|
||||
################################################################
|
||||
AC_DEFUN(GNUPG_PROG_NM,
|
||||
[AC_MSG_CHECKING([for BSD-compatible nm])
|
||||
AC_CACHE_VAL(ac_cv_path_NM,
|
||||
@ -433,7 +488,7 @@ case "$host_os" in
|
||||
aix*)
|
||||
ac_symcode='[BCDTU]'
|
||||
;;
|
||||
freebsd* | netbsd* | openbsd* | sunos* | cygwin32* | mingw32*)
|
||||
freebsd* | netbsd* | openbsd* | bsdi* | sunos* | cygwin32* | mingw32*)
|
||||
ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
|
||||
ac_symxfrm='_\1 \1'
|
||||
;;
|
||||
@ -586,7 +641,7 @@ AC_CHECK_TOOL(AS, as, false)
|
||||
AC_DEFUN(GNUPG_SYS_SYMBOL_UNDERSCORE,
|
||||
[tmp_do_check="no"
|
||||
case "${target}" in
|
||||
i386-emx-os2 | i[3456]86-pc-os2*emx )
|
||||
i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
|
||||
ac_cv_sys_symbol_underscore=yes
|
||||
;;
|
||||
*)
|
||||
@ -645,7 +700,8 @@ dnl Stolen from gcc
|
||||
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
|
||||
dnl of the usual 2.
|
||||
AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
|
||||
[AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg,
|
||||
[AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h)
|
||||
AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg,
|
||||
[AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
@ -663,7 +719,6 @@ if test $gnupg_cv_mkdir_takes_one_arg = yes ; then
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl GPH_PROG_DOCBOOK()
|
||||
dnl Check whether we have the needed Docbook environment
|
||||
dnl and issue a warning if this is not the case.
|
||||
|
@ -1,3 +1,85 @@
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
|
||||
|
||||
* Makefile.am: Never compile mingw32 as module.
|
||||
|
||||
* Makefile.am: Tweaked module build and removed libtool
|
||||
|
||||
* Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
|
||||
|
||||
* elgamal.c (sign): Removed inactive code.
|
||||
|
||||
* rsa.c, rsa.h: New based on the old module version (only in CVS for now).
|
||||
* pubkey.c (setup_pubkey_table): Added commented support for RSA.
|
||||
|
||||
* rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
|
||||
(my_popen): Do the FD_CLOEXEC only if it is available
|
||||
(start_gatherer): Cope with missing _SC_OPEN_MAX
|
||||
|
||||
* rndunix.c: Add some more headers for QNX. By Sam Roberts.
|
||||
|
||||
* rndegd.c (gather_random): Shortcut level 0.
|
||||
* rndunix.c (gather_random): Ditto.
|
||||
* rndw32.c (gather_random): Ditto.
|
||||
|
||||
* rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
|
||||
* rndw32.c: Add some debuging code enabled by an environment variable.
|
||||
|
||||
* random.c (read_seed_file): Binary open for DOSish system
|
||||
(update_random_seed_file): Ditto.
|
||||
* random.c [MINGW32]: Include process.h for getpid.
|
||||
* random.c (fast_random_poll): Add clock_gettime() as fallback for
|
||||
system which support this POSIX.4 fucntion. By Sam Roberts.
|
||||
|
||||
* random.c (read_seed_file): Removed the S_ISLNK test becuase it
|
||||
is already covered by !S_ISREG and is not defined in Unixware.
|
||||
Reported by Dave Dykstra.
|
||||
(update_random_seed_file): Silently ignore update request when pool
|
||||
is not filled.
|
||||
|
||||
* random.c (read_seed_file): New.
|
||||
(set_random_seed_file): New.
|
||||
(read_pool): Try to read the seeding file.
|
||||
(update_random_seed_file): New.
|
||||
|
||||
(read_pool): Do an initial extra seeding when level 2 quality random
|
||||
is requested the first time. This requestes at least POOLSIZE/2 bytes
|
||||
of entropy. Compined with the seeding file this should make normal
|
||||
random bytes cheaper and increase the quality of the random bytes
|
||||
used for key generation.
|
||||
|
||||
* random.c (read_pool): Print a more friendly error message in
|
||||
cases when too much random is requested in one call.
|
||||
|
||||
* random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
|
||||
this is not the case for some ESIX and Unixware, although they have
|
||||
getrusage().
|
||||
|
||||
* primegen.c (generate_elg_prime): All primes are now generated with
|
||||
the lowest random quality level. Because they are public anyway we
|
||||
don't need stronger random and by this we do not drain the systems
|
||||
entropy so much.
|
||||
|
||||
* primegen.c (register_primegen_progress): New.
|
||||
* dsa.c (register_pk_dsa_progress): New.
|
||||
* elgamal.c (register_pk_elg_progress): New.
|
||||
|
||||
* elgamal.c (wiener_map): New.
|
||||
(gen_k): Use a much smaller k.
|
||||
(generate): Calculate the qbits using the wiener map and
|
||||
choose an x at a size comparable to the one choosen in gen_k
|
||||
|
||||
* rmd160.c (rmd160_get_info): Moved casting to the left side due to a
|
||||
problem with UTS4.3. Suggested by Dave Dykstra.
|
||||
* sha1.c (sha1_get_info): Ditto.
|
||||
* tiger.c (tiger_get_info): Ditto.
|
||||
* md5.c (md5_get_info): Ditto
|
||||
* des.c (des_get_info): Ditto.
|
||||
* blowfish.c (blowfish_get_info): Ditto.
|
||||
* cast5.c (cast5_get_info): Ditto.
|
||||
* twofish.c (twofish_get_info): Ditto.
|
||||
|
||||
Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* md.c (md_open): Add hmac arg and allocate space for the pads.
|
||||
|
@ -5,15 +5,8 @@ INCLUDES = -I$(top_srcdir)/gcrypt
|
||||
|
||||
noinst_LTLIBRARIES = libcipher.la
|
||||
|
||||
# The configure script greps the module names from the following lines.
|
||||
# You must also add all these names to EXTRA_PROGRAMS some lines below
|
||||
# and EXTRA_foo_SOURCES entries.
|
||||
# Hmmm is there a more easy way to do this? (EXTRA_PROGRAMS
|
||||
# might also list programs which are not modules)
|
||||
# MODULES: rndunix rndlinux rndegd rndw32
|
||||
# MODULES: sha1 rmd160 md5 tiger
|
||||
EXTRA_PROGRAMS = rndunix rndlinux rndegd rndw32 \
|
||||
sha1 rmd160 md5 tiger
|
||||
# The configure script greps the module names from the EXTRA_PROGRAMS line
|
||||
EXTRA_PROGRAMS = rndlinux rndunix rndegd rndw32 sha1 rmd160 md5 tiger
|
||||
|
||||
EXTRA_rndlinux_SOURCES = rndlinux.c
|
||||
EXTRA_rndunix_SOURCES = rndunix.c
|
||||
@ -73,7 +66,7 @@ libcipher_la_LIBADD = @STATIC_CIPHER_OBJS@
|
||||
|
||||
tiger: $(srcdir)/tiger.c
|
||||
`echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
|
||||
sed -e 's/-O[2-9s]*/-O1/g' `
|
||||
sed -e 's/-O[2-9s]*/-O/g' `
|
||||
|
||||
tiger.o: $(srcdir)/tiger.c
|
||||
`echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' `
|
||||
@ -98,9 +91,3 @@ rndlinux: $(srcdir)/rndlinux.c
|
||||
rndegd: $(srcdir)/rndegd.c
|
||||
$(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndegd $(srcdir)/rndegd.c
|
||||
|
||||
# We need to have a better system for selection which modules
|
||||
# to compile. For now this works.
|
||||
rndw32: $(srcdir)/rndw32.c
|
||||
echo "#!/bin/sh" >rndw32
|
||||
echo "Not usable as a module" >>rndw32
|
||||
|
||||
|
@ -584,9 +584,12 @@ blowfish_get_info( int algo, size_t *keylen,
|
||||
*keylen = 128;
|
||||
*blocksize = BLOWFISH_BLOCKSIZE;
|
||||
*contextsize = sizeof(BLOWFISH_context);
|
||||
*r_setkey = FNCCAST_SETKEY(bf_setkey);
|
||||
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
|
||||
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
|
||||
*(int (**)(BLOWFISH_context*, byte*, unsigned))r_setkey
|
||||
= bf_setkey;
|
||||
*(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt
|
||||
= encrypt_block;
|
||||
*(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt
|
||||
= decrypt_block;
|
||||
|
||||
if( algo == CIPHER_ALGO_BLOWFISH )
|
||||
return "BLOWFISH";
|
||||
|
@ -610,9 +610,13 @@ cast5_get_info( int algo, size_t *keylen,
|
||||
*keylen = 128;
|
||||
*blocksize = CAST5_BLOCKSIZE;
|
||||
*contextsize = sizeof(CAST5_context);
|
||||
*r_setkey = FNCCAST_SETKEY(cast_setkey);
|
||||
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
|
||||
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
|
||||
*(int (**)(CAST5_context*, byte*, unsigned))r_setkey
|
||||
= cast_setkey;
|
||||
*(void (**)(CAST5_context*, byte*, byte*))r_encrypt
|
||||
= encrypt_block;
|
||||
*(void (**)(CAST5_context*, byte*, byte*))r_decrypt
|
||||
= decrypt_block;
|
||||
|
||||
|
||||
if( algo == CIPHER_ALGO_CAST5 )
|
||||
return "CAST5";
|
||||
|
@ -1001,9 +1001,12 @@ des_get_info( int algo, size_t *keylen,
|
||||
*keylen = 192;
|
||||
*blocksize = 8;
|
||||
*contextsize = sizeof(struct _tripledes_ctx);
|
||||
*r_setkey = FNCCAST_SETKEY(do_tripledes_setkey);
|
||||
*r_encrypt= FNCCAST_CRYPT(do_tripledes_encrypt);
|
||||
*r_decrypt= FNCCAST_CRYPT(do_tripledes_decrypt);
|
||||
*(int (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
|
||||
= do_tripledes_setkey;
|
||||
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt
|
||||
= do_tripledes_encrypt;
|
||||
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt
|
||||
= do_tripledes_decrypt;
|
||||
return "3DES";
|
||||
}
|
||||
return NULL;
|
||||
|
19
cipher/dsa.c
19
cipher/dsa.c
@ -1,5 +1,5 @@
|
||||
/* dsa.c - DSA signature scheme
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -52,13 +52,28 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
|
||||
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
|
||||
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
|
||||
|
||||
static void (*progress_cb) ( void *, int );
|
||||
static void *progress_cb_data;
|
||||
|
||||
void
|
||||
register_pk_dsa_progress ( void (*cb)( void *, int), void *cb_data )
|
||||
{
|
||||
progress_cb = cb;
|
||||
progress_cb_data = cb_data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
progress( int c )
|
||||
{
|
||||
fputc( c, stderr );
|
||||
if ( progress_cb )
|
||||
progress_cb ( progress_cb_data, c );
|
||||
else
|
||||
fputc( c, stderr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a random secret exponent k less than q
|
||||
*/
|
||||
|
141
cipher/elgamal.c
141
cipher/elgamal.c
@ -1,5 +1,5 @@
|
||||
/* elgamal.c - ElGamal Public Key encryption
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* For a description of the algorithm, see:
|
||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
|
||||
@ -56,13 +56,67 @@ static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
|
||||
static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
|
||||
|
||||
|
||||
static void (*progress_cb) ( void *, int );
|
||||
static void *progress_cb_data;
|
||||
|
||||
void
|
||||
register_pk_elg_progress ( void (*cb)( void *, int), void *cb_data )
|
||||
{
|
||||
progress_cb = cb;
|
||||
progress_cb_data = cb_data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
progress( int c )
|
||||
{
|
||||
fputc( c, stderr );
|
||||
if ( progress_cb )
|
||||
progress_cb ( progress_cb_data, c );
|
||||
else
|
||||
fputc( c, stderr );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Michael Wiener's table on subgroup sizes to match field sizes
|
||||
* (floating around somewhere - Fixme: need a reference)
|
||||
*/
|
||||
static unsigned int
|
||||
wiener_map( unsigned int n )
|
||||
{
|
||||
static struct { unsigned int p_n, q_n; } t[] =
|
||||
{ /* p q attack cost */
|
||||
{ 512, 119 }, /* 9 x 10^17 */
|
||||
{ 768, 145 }, /* 6 x 10^21 */
|
||||
{ 1024, 165 }, /* 7 x 10^24 */
|
||||
{ 1280, 183 }, /* 3 x 10^27 */
|
||||
{ 1536, 198 }, /* 7 x 10^29 */
|
||||
{ 1792, 212 }, /* 9 x 10^31 */
|
||||
{ 2048, 225 }, /* 8 x 10^33 */
|
||||
{ 2304, 237 }, /* 5 x 10^35 */
|
||||
{ 2560, 249 }, /* 3 x 10^37 */
|
||||
{ 2816, 259 }, /* 1 x 10^39 */
|
||||
{ 3072, 269 }, /* 3 x 10^40 */
|
||||
{ 3328, 279 }, /* 8 x 10^41 */
|
||||
{ 3584, 288 }, /* 2 x 10^43 */
|
||||
{ 3840, 296 }, /* 4 x 10^44 */
|
||||
{ 4096, 305 }, /* 7 x 10^45 */
|
||||
{ 4352, 313 }, /* 1 x 10^47 */
|
||||
{ 4608, 320 }, /* 2 x 10^48 */
|
||||
{ 4864, 328 }, /* 2 x 10^49 */
|
||||
{ 5120, 335 }, /* 3 x 10^50 */
|
||||
{ 0, 0 }
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i=0; t[i].p_n; i++ ) {
|
||||
if( n <= t[i].p_n )
|
||||
return t[i].q_n;
|
||||
}
|
||||
/* not in table - use some arbitrary high number ;-) */
|
||||
return n / 8 + 200;
|
||||
}
|
||||
|
||||
static void
|
||||
test_keys( ELG_secret_key *sk, unsigned nbits )
|
||||
{
|
||||
@ -104,38 +158,44 @@ gen_k( MPI p )
|
||||
MPI k = mpi_alloc_secure( 0 );
|
||||
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
MPI p_1 = mpi_copy(p);
|
||||
unsigned int nbits = mpi_get_nbits(p);
|
||||
unsigned int nbytes = (nbits+7)/8;
|
||||
unsigned int orig_nbits = mpi_get_nbits(p);
|
||||
unsigned int nbits, nbytes;
|
||||
char *rndbuf = NULL;
|
||||
|
||||
/* IMO using a k much lesser than p is sufficient and it greatly
|
||||
* improves the encryption performance. We use Wiener's table
|
||||
* and add a large safety margin.
|
||||
*/
|
||||
nbits = wiener_map( orig_nbits ) * 3 / 2;
|
||||
if( nbits >= orig_nbits )
|
||||
BUG();
|
||||
|
||||
nbytes = (nbits+7)/8;
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random k ");
|
||||
mpi_sub_ui( p_1, p, 1);
|
||||
for(;;) {
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
if( !rndbuf || nbits < 32 ) {
|
||||
g10_free(rndbuf);
|
||||
rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
|
||||
}
|
||||
else { /* change only some of the higher bits */
|
||||
/* we could imporove this by directly requesting more memory
|
||||
/* we could improve this by directly requesting more memory
|
||||
* at the first call to get_random_bytes() and use this the here
|
||||
* maybe it is easier to do this directly in random.c */
|
||||
* maybe it is easier to do this directly in random.c
|
||||
* Anyway, it is highly inlikely that we will ever reach this code
|
||||
*/
|
||||
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
|
||||
memcpy( rndbuf, pp, 4 );
|
||||
g10_free(pp);
|
||||
log_debug("gen_k: tsss, never expected to reach this\n");
|
||||
}
|
||||
mpi_set_buffer( k, rndbuf, nbytes, 0 );
|
||||
|
||||
for(;;) {
|
||||
/* make sure that the number is of the exact lenght */
|
||||
if( mpi_test_bit( k, nbits-1 ) )
|
||||
mpi_set_highbit( k, nbits-1 );
|
||||
else {
|
||||
mpi_set_highbit( k, nbits-1 );
|
||||
mpi_clear_bit( k, nbits-1 );
|
||||
}
|
||||
/* Hmm, actually we don't need this step here
|
||||
* because we use k much smaller than p - we do it anyway
|
||||
* just in case the keep on adding a one to k ;) */
|
||||
if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
|
||||
if( DBG_CIPHER )
|
||||
progress('+');
|
||||
@ -149,6 +209,8 @@ gen_k( MPI p )
|
||||
if( mpi_gcd( temp, k, p_1 ) )
|
||||
goto found; /* okay, k is relatively prime to (p-1) */
|
||||
mpi_add_ui( k, k, 1 );
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
}
|
||||
}
|
||||
found:
|
||||
@ -167,7 +229,7 @@ gen_k( MPI p )
|
||||
* and an array with n-1 factors of (p-1)
|
||||
*/
|
||||
static void
|
||||
generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
||||
generate( ELG_secret_key *sk, unsigned int nbits, MPI **ret_factors )
|
||||
{
|
||||
MPI p; /* the prime */
|
||||
MPI p_min1;
|
||||
@ -175,19 +237,15 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
||||
MPI x; /* the secret exponent */
|
||||
MPI y;
|
||||
MPI temp;
|
||||
unsigned qbits;
|
||||
unsigned int qbits;
|
||||
unsigned int xbits;
|
||||
byte *rndbuf;
|
||||
|
||||
p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
if( nbits < 512 )
|
||||
qbits = 120;
|
||||
else if( nbits <= 1024 )
|
||||
qbits = 160;
|
||||
else if( nbits <= 2048 )
|
||||
qbits = 200;
|
||||
else
|
||||
qbits = 240;
|
||||
qbits = wiener_map( nbits );
|
||||
if( qbits & 1 ) /* better have a even one */
|
||||
qbits++;
|
||||
g = mpi_alloc(1);
|
||||
p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
|
||||
mpi_sub_ui(p_min1, p, 1);
|
||||
@ -198,18 +256,26 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
||||
* This must be a very good random number because this is the
|
||||
* secret part. The prime is public and may be shared anyway,
|
||||
* so a random generator level of 1 is used for the prime.
|
||||
*
|
||||
* I don't see a reason to have a x of about the same size
|
||||
* as the p. It should be sufficient to have one about the size
|
||||
* of q or the later used k plus a large safety margin. Decryption
|
||||
* will be much faster with such an x.
|
||||
*/
|
||||
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
|
||||
xbits = qbits * 3 / 2;
|
||||
if( xbits >= nbits )
|
||||
BUG();
|
||||
x = mpi_alloc_secure( xbits/BITS_PER_MPI_LIMB );
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random x ");
|
||||
log_debug("choosing a random x of size %u", xbits );
|
||||
rndbuf = NULL;
|
||||
do {
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
if( rndbuf ) { /* change only some of the higher bits */
|
||||
if( nbits < 16 ) {/* should never happen ... */
|
||||
if( xbits < 16 ) {/* should never happen ... */
|
||||
g10_free(rndbuf);
|
||||
rndbuf = gcry_random_bytes_secure( (nbits+7)/8,
|
||||
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
|
||||
GCRY_VERY_STRONG_RANDOM );
|
||||
}
|
||||
else {
|
||||
@ -220,11 +286,11 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
||||
}
|
||||
}
|
||||
else {
|
||||
rndbuf = gcry_random_bytes_secure( (nbits+7)/8,
|
||||
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
|
||||
GCRY_VERY_STRONG_RANDOM );
|
||||
}
|
||||
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, nbits+1 );
|
||||
mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, xbits+1 );
|
||||
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
|
||||
g10_free(rndbuf);
|
||||
|
||||
@ -311,7 +377,6 @@ decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
|
||||
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
|
||||
|
||||
/* output = b/(a^x) mod p */
|
||||
|
||||
gcry_mpi_powm( t1, a, skey->x, skey->p );
|
||||
mpi_invm( t1, t1, skey->p );
|
||||
mpi_mulm( output, b, t1, skey->p );
|
||||
@ -351,10 +416,6 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
|
||||
gcry_mpi_powm( a, skey->g, k, skey->p );
|
||||
mpi_mul(t, skey->x, a );
|
||||
mpi_subm(t, input, t, p_1 );
|
||||
while( mpi_is_neg(t) ) {
|
||||
BUG(); /* That is nonsense code - left over from a very early test?*/
|
||||
mpi_add(t, t, p_1);
|
||||
}
|
||||
mpi_invm(inv, k, p_1 );
|
||||
mpi_mulm(b, t, inv, p_1 );
|
||||
|
||||
@ -557,7 +618,7 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
unsigned int
|
||||
elg_get_nbits( int algo, MPI *pkey )
|
||||
{
|
||||
if( !is_ELGAMAL(algo) )
|
||||
@ -587,10 +648,10 @@ elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
|
||||
*nsig = 2;
|
||||
|
||||
switch( algo ) {
|
||||
case PUBKEY_ALGO_ELGAMAL:
|
||||
case GCRY_PK_ELG:
|
||||
*use = GCRY_PK_USAGE_SIGN|GCRY_PK_USAGE_ENCR;
|
||||
return "ELG";
|
||||
case PUBKEY_ALGO_ELGAMAL_E:
|
||||
case GCRY_PK_ELG_E:
|
||||
*use = GCRY_PK_USAGE_SIGN|GCRY_PK_USAGE_ENCR;
|
||||
return "ELG-E";
|
||||
default: *use = 0; return NULL;
|
||||
|
10
cipher/md.c
10
cipher/md.c
@ -562,6 +562,12 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
|
||||
else if ( !(rc = prepare_macpads( hd, buffer, buflen )) )
|
||||
gcry_md_reset( hd );
|
||||
}
|
||||
else if( cmd == GCRYCTL_START_DUMP ) {
|
||||
md_start_debug( hd, buffer );
|
||||
}
|
||||
else if( cmd == GCRYCTL_STOP_DUMP ) {
|
||||
md_stop_debug( hd );
|
||||
}
|
||||
else
|
||||
rc = GCRYERR_INV_OP;
|
||||
return set_lasterr( rc );
|
||||
@ -834,7 +840,7 @@ gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
|
||||
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
md_start_debug( GCRY_MD_HD md, const char *suffix )
|
||||
{
|
||||
static int idx=0;
|
||||
@ -851,7 +857,7 @@ md_start_debug( GCRY_MD_HD md, const char *suffix )
|
||||
log_debug("md debug: can't open %s\n", buf );
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
md_stop_debug( GCRY_MD_HD md )
|
||||
{
|
||||
if( md->ctx->debug ) {
|
||||
|
@ -344,10 +344,10 @@ md5_get_info( int algo, size_t *contextsize,
|
||||
*r_asnoid = asn;
|
||||
*r_asnlen = DIM(asn);
|
||||
*r_mdlen = 16;
|
||||
*r_init = (void (*)(void *))md5_init;
|
||||
*r_write = (void (*)(void *, byte*, size_t))md5_write;
|
||||
*r_final = (void (*)(void *))md5_final;
|
||||
*r_read = (byte *(*)(void *))md5_read;
|
||||
*(void (**)(MD5_CONTEXT *))r_init = md5_init;
|
||||
*(void (**)(MD5_CONTEXT *, byte*, size_t))r_write = md5_write;
|
||||
*(void (**)(MD5_CONTEXT *))r_final = md5_final;
|
||||
*(byte *(**)(MD5_CONTEXT *))r_read = md5_read;
|
||||
|
||||
return "MD5";
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* primegen.c - prime number generator
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -38,11 +38,24 @@ static int check_prime( MPI prime, MPI val_2 );
|
||||
static int is_prime( MPI n, int steps, int *count );
|
||||
static void m_out_of_n( char *array, int m, int n );
|
||||
|
||||
static void (*progress_cb) ( void *, int );
|
||||
static void *progress_cb_data;
|
||||
|
||||
void
|
||||
register_primegen_progress ( void (*cb)( void *, int), void *cb_data )
|
||||
{
|
||||
progress_cb = cb;
|
||||
progress_cb_data = cb_data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
progress( int c )
|
||||
{
|
||||
fputc( c, stderr );
|
||||
if ( progress_cb )
|
||||
progress_cb ( progress_cb_data, c );
|
||||
else
|
||||
fputc( c, stderr );
|
||||
}
|
||||
|
||||
|
||||
@ -117,8 +130,8 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
|
||||
pbits, req_qbits, qbits, fbits, n );
|
||||
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
|
||||
q = gen_prime( qbits, 0, 0 );
|
||||
q_factor = mode==1? gen_prime( req_qbits, 0, 0 ) : NULL;
|
||||
|
||||
/* allocate an array to hold the factors + 2 for later usage */
|
||||
factors = g10_xcalloc( n+2, sizeof *factors );
|
||||
@ -177,7 +190,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
count1 = 0;
|
||||
qbits++;
|
||||
progress('>');
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
q = gen_prime( qbits, 0, 0 );
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
@ -188,7 +201,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
count2 = 0;
|
||||
qbits--;
|
||||
progress('<');
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
q = gen_prime( qbits, 0, 0 );
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* pubkey.c - pubkey dispatcher
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -30,6 +30,9 @@
|
||||
#include "cipher.h"
|
||||
#include "elgamal.h"
|
||||
#include "dsa.h"
|
||||
#if 0
|
||||
#include "rsa.h"
|
||||
#endif
|
||||
#include "dynload.h"
|
||||
|
||||
/* FIXME: use set_lasterr() */
|
||||
@ -193,6 +196,60 @@ 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,
|
||||
&pubkey_table[i].nskey,
|
||||
&pubkey_table[i].nenc,
|
||||
&pubkey_table[i].nsig,
|
||||
&pubkey_table[i].use );
|
||||
pubkey_table[i].generate = rsa_generate;
|
||||
pubkey_table[i].check_secret_key = rsa_check_secret_key;
|
||||
pubkey_table[i].encrypt = rsa_encrypt;
|
||||
pubkey_table[i].decrypt = rsa_decrypt;
|
||||
pubkey_table[i].sign = rsa_sign;
|
||||
pubkey_table[i].verify = rsa_verify;
|
||||
pubkey_table[i].get_nbits = rsa_get_nbits;
|
||||
if( !pubkey_table[i].name )
|
||||
BUG();
|
||||
i++;
|
||||
pubkey_table[i].algo = PUBKEY_ALGO_RSA_E;
|
||||
pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
|
||||
&pubkey_table[i].npkey,
|
||||
&pubkey_table[i].nskey,
|
||||
&pubkey_table[i].nenc,
|
||||
&pubkey_table[i].nsig,
|
||||
&pubkey_table[i].use );
|
||||
pubkey_table[i].generate = rsa_generate;
|
||||
pubkey_table[i].check_secret_key = rsa_check_secret_key;
|
||||
pubkey_table[i].encrypt = rsa_encrypt;
|
||||
pubkey_table[i].decrypt = rsa_decrypt;
|
||||
pubkey_table[i].sign = dummy_sign;
|
||||
pubkey_table[i].verify = dummy_verify;
|
||||
pubkey_table[i].get_nbits = rsa_get_nbits;
|
||||
if( !pubkey_table[i].name )
|
||||
BUG();
|
||||
i++;
|
||||
pubkey_table[i].algo = PUBKEY_ALGO_RSA_S;
|
||||
pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
|
||||
&pubkey_table[i].npkey,
|
||||
&pubkey_table[i].nskey,
|
||||
&pubkey_table[i].nenc,
|
||||
&pubkey_table[i].nsig,
|
||||
&pubkey_table[i].use );
|
||||
pubkey_table[i].generate = rsa_generate;
|
||||
pubkey_table[i].check_secret_key = rsa_check_secret_key;
|
||||
pubkey_table[i].encrypt = dummy_encrypt;
|
||||
pubkey_table[i].decrypt = dummy_decrypt;
|
||||
pubkey_table[i].sign = rsa_sign;
|
||||
pubkey_table[i].verify = rsa_verify;
|
||||
pubkey_table[i].get_nbits = rsa_get_nbits;
|
||||
if( !pubkey_table[i].name )
|
||||
BUG();
|
||||
i++;
|
||||
#endif
|
||||
|
||||
for( ; i < TABLE_SIZE; i++ )
|
||||
pubkey_table[i].name = NULL;
|
||||
}
|
||||
|
204
cipher/random.c
204
cipher/random.c
@ -1,5 +1,5 @@
|
||||
/* random.c - random number generator
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -36,15 +36,22 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_GETHRTIME
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef __MINGW32__
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include "g10lib.h"
|
||||
#include "rmd.h"
|
||||
#include "random.h"
|
||||
@ -89,6 +96,9 @@ static size_t pool_writepos;
|
||||
static int pool_filled;
|
||||
static int pool_balance;
|
||||
static int just_mixed;
|
||||
static int did_initial_extra_seeding;
|
||||
static char *seed_file_name;
|
||||
static int allow_seed_file_update;
|
||||
|
||||
static int secure_alloc;
|
||||
static int quick_test;
|
||||
@ -274,6 +284,139 @@ mix_pool(byte *pool)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_random_seed_file( const char *name )
|
||||
{
|
||||
if( seed_file_name )
|
||||
BUG();
|
||||
seed_file_name = g10_xstrdup( name );
|
||||
}
|
||||
|
||||
/****************
|
||||
* Read in a seed form the random_seed file
|
||||
* and return true if this was successful
|
||||
*/
|
||||
static int
|
||||
read_seed_file()
|
||||
{
|
||||
int fd;
|
||||
struct stat sb;
|
||||
unsigned char buffer[POOLSIZE];
|
||||
int n;
|
||||
|
||||
if( !seed_file_name )
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
fd = open( seed_file_name, O_RDONLY | O_BINARY );
|
||||
#else
|
||||
fd = open( seed_file_name, O_RDONLY );
|
||||
#endif
|
||||
if( fd == -1 && errno == ENOENT) {
|
||||
allow_seed_file_update = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( fd == -1 ) {
|
||||
log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
return 0;
|
||||
}
|
||||
if( fstat( fd, &sb ) ) {
|
||||
log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if( !S_ISREG(sb.st_mode) ) {
|
||||
log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if( !sb.st_size ) {
|
||||
log_info(_("note: random_seed file is empty\n") );
|
||||
close(fd);
|
||||
allow_seed_file_update = 1;
|
||||
return 0;
|
||||
}
|
||||
if( sb.st_size != POOLSIZE ) {
|
||||
log_info(_("warning: invalid size of random_seed file - not used\n") );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
n = read( fd, buffer, POOLSIZE );
|
||||
} while( n == -1 && errno == EINTR );
|
||||
if( n != POOLSIZE ) {
|
||||
log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
add_randomness( buffer, POOLSIZE, 0 );
|
||||
/* add some minor entropy to the pool now (this will also force a mixing) */
|
||||
{ pid_t x = getpid();
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
{ time_t x = time(NULL);
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
{ clock_t x = clock();
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
/* And read a few bytes from our entropy source. By using
|
||||
* a level of 0 this will not block and might not return anything
|
||||
* with some entropy drivers, however the rndlinux driver will use
|
||||
* /dev/urandom and return some stuff - Do not read to much as we
|
||||
* want to be friendly to the scare system entropy resource. */
|
||||
read_random_source( 0, 16, 0 );
|
||||
|
||||
allow_seed_file_update = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
update_random_seed_file()
|
||||
{
|
||||
ulong *sp, *dp;
|
||||
int fd, i;
|
||||
|
||||
if( !seed_file_name || !is_initialized || !pool_filled )
|
||||
return;
|
||||
if( !allow_seed_file_update ) {
|
||||
log_info(_("note: random_seed file not updated\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* copy the entropy pool to a scratch pool and mix both of them */
|
||||
for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
|
||||
i < POOLWORDS; i++, dp++, sp++ ) {
|
||||
*dp = *sp + ADD_VALUE;
|
||||
}
|
||||
mix_pool(rndpool); rndstats.mixrnd++;
|
||||
mix_pool(keypool); rndstats.mixkey++;
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
|
||||
S_IRUSR|S_IWUSR );
|
||||
#else
|
||||
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
|
||||
#endif
|
||||
if( fd == -1 ) {
|
||||
log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
return;
|
||||
}
|
||||
do {
|
||||
i = write( fd, keypool, POOLSIZE );
|
||||
} while( i == -1 && errno == EINTR );
|
||||
if( i != POOLSIZE ) {
|
||||
log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
}
|
||||
if( close(fd) )
|
||||
log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_pool( byte *buffer, size_t length, int level )
|
||||
@ -281,8 +424,31 @@ read_pool( byte *buffer, size_t length, int level )
|
||||
int i;
|
||||
ulong *sp, *dp;
|
||||
|
||||
if( length >= POOLSIZE )
|
||||
BUG(); /* not allowed */
|
||||
if( length >= POOLSIZE ) {
|
||||
log_fatal(_("too many random bits requested; the limit is %d\n"),
|
||||
POOLSIZE*8-1 );
|
||||
}
|
||||
|
||||
if( !pool_filled ) {
|
||||
if( read_seed_file() )
|
||||
pool_filled = 1;
|
||||
}
|
||||
|
||||
/* For level 2 quality (key generation) we alwas make
|
||||
* sure that the pool has been seeded enough initially */
|
||||
if( level == 2 && !did_initial_extra_seeding ) {
|
||||
size_t needed;
|
||||
|
||||
pool_balance = 0;
|
||||
needed = length - pool_balance;
|
||||
if( needed < POOLSIZE/2 )
|
||||
needed = POOLSIZE/2;
|
||||
else if( needed > POOLSIZE )
|
||||
BUG();
|
||||
read_random_source( 3, needed, 2 );
|
||||
pool_balance += needed;
|
||||
did_initial_extra_seeding=1;
|
||||
}
|
||||
|
||||
/* for level 2 make sure that there is enough random in the pool */
|
||||
if( level == 2 && pool_balance < length ) {
|
||||
@ -347,6 +513,12 @@ read_pool( byte *buffer, size_t length, int level )
|
||||
/****************
|
||||
* Add LENGTH bytes of randomness from buffer to the pool.
|
||||
* source may be used to specify the randomness source.
|
||||
* Source is:
|
||||
* 0 - used ony for initialization
|
||||
* 1 - fast random poll function
|
||||
* 2 - normal poll function
|
||||
* 3 - used when level 2 random quality has been requested
|
||||
* to do an extra pool seed.
|
||||
*/
|
||||
static void
|
||||
add_randomness( const void *buffer, size_t length, int source )
|
||||
@ -410,6 +582,13 @@ fast_random_poll()
|
||||
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
|
||||
add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
|
||||
}
|
||||
#elif HAVE_CLOCK_GETTIME
|
||||
{ struct timespec tv;
|
||||
if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
|
||||
BUG();
|
||||
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
|
||||
add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
|
||||
}
|
||||
#else /* use times */
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
{ struct tms buf;
|
||||
@ -419,13 +598,28 @@ fast_random_poll()
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
#ifndef RUSAGE_SELF
|
||||
#ifdef __GCC__
|
||||
#warning There is no RUSAGE_SELF on this system
|
||||
#endif
|
||||
#else
|
||||
{ struct rusage buf;
|
||||
if( getrusage( RUSAGE_SELF, &buf ) )
|
||||
BUG();
|
||||
add_randomness( &buf, sizeof buf, 1 );
|
||||
memset( &buf, 0, sizeof buf );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* time and clock are availabe on all systems - so
|
||||
* we better do it just in case one of the above functions
|
||||
* didn't work */
|
||||
{ time_t x = time(NULL);
|
||||
add_randomness( &x, sizeof(x), 1 );
|
||||
}
|
||||
{ clock_t x = clock();
|
||||
add_randomness( &x, sizeof(x), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -472,9 +666,9 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
|
||||
#endif
|
||||
initialized=1;
|
||||
#ifdef HAVE_RAND
|
||||
srand( time(NULL) * getpid());
|
||||
srand(make_timestamp()*getpid());
|
||||
#else
|
||||
srandom( time(NULL) * getpid());
|
||||
srandom(make_timestamp()*getpid());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -562,10 +562,10 @@ rmd160_get_info( int algo, size_t *contextsize,
|
||||
*r_asnoid = asn;
|
||||
*r_asnlen = DIM(asn);
|
||||
*r_mdlen = 20;
|
||||
*r_init = (void (*)(void *))rmd160_init;
|
||||
*r_write = (void (*)(void *, byte*, size_t))rmd160_write;
|
||||
*r_final = (void (*)(void *))rmd160_final;
|
||||
*r_read = (byte *(*)(void *))rmd160_read;
|
||||
*(void (**)(RMD160_CONTEXT *))r_init = rmd160_init;
|
||||
*(void (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
|
||||
*(void (**)(RMD160_CONTEXT *))r_final = rmd160_final;
|
||||
*(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read;
|
||||
|
||||
return "RIPEMD160";
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* rndegd.c - interface to the EGD
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -117,9 +117,13 @@ do_read( int fd, void *buf, size_t nbytes )
|
||||
|
||||
|
||||
|
||||
/* Note: we always use the highest level.
|
||||
/****************
|
||||
* Note: we always use the highest level.
|
||||
* TO boost the performance we may want to add some
|
||||
* additional code for level 1
|
||||
*
|
||||
* Using a level of 0 should never block and better add nothing
|
||||
* to the pool. So this is just a dummy for EGD.
|
||||
*/
|
||||
static int
|
||||
gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
@ -133,7 +137,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
|
||||
if( !length )
|
||||
return 0;
|
||||
|
||||
if( !level )
|
||||
return 0;
|
||||
|
||||
restart:
|
||||
if( do_restart ) {
|
||||
|
@ -77,7 +77,7 @@
|
||||
#ifndef __QNX__
|
||||
#include <sys/resource.h>
|
||||
#endif /* __QNX__ */
|
||||
#ifdef _AIX
|
||||
#if defined( _AIX ) || defined( __QNX__ )
|
||||
#include <sys/select.h>
|
||||
#endif /* _AIX */
|
||||
#ifndef __QNX__
|
||||
@ -91,6 +91,10 @@
|
||||
#endif /* __hpux 9.x, after that it's in unistd.h */
|
||||
#include <sys/wait.h>
|
||||
/* #include <kitchensink.h> */
|
||||
#ifdef __QNX__
|
||||
#include <signal.h>
|
||||
#include <process.h>
|
||||
#endif /* __QNX__ */
|
||||
#include <errno.h>
|
||||
|
||||
#include "types.h" /* for byte and u32 typedefs */
|
||||
@ -100,7 +104,13 @@
|
||||
#include "g10lib.h"
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
#endif
|
||||
#ifndef STDIN_FILENO
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
|
||||
#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
|
||||
@ -306,6 +316,32 @@ typedef struct {
|
||||
char data[500]; /* gathered data */
|
||||
} GATHER_MSG;
|
||||
|
||||
#ifndef HAVE_WAITPID
|
||||
pid_t
|
||||
waitpid(pid_t pid, int *statptr, int options)
|
||||
{
|
||||
#ifdef HAVE_WAIT4
|
||||
return wait4(pid, statptr, options, NULL);
|
||||
#else
|
||||
/* If wait4 is also not available, try wait3 for SVR3 variants */
|
||||
/* Less ideal because can't actually request a specific pid */
|
||||
/* For that reason, first check to see if pid is for an */
|
||||
/* existing process. */
|
||||
int tmp_pid, dummystat;;
|
||||
if (kill(pid, 0) == -1) {
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
if (statptr == NULL)
|
||||
statptr = &dummystat;
|
||||
while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
|
||||
(tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
|
||||
;
|
||||
return tmp_pid;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Under SunOS popen() doesn't record the pid of the child process. When
|
||||
* pclose() is called, instead of calling waitpid() for the correct child, it
|
||||
* calls wait() repeatedly until the right child is reaped. The problem is
|
||||
@ -376,7 +412,9 @@ my_popen(struct RI *entry)
|
||||
* close on exec, so new children won't see it */
|
||||
close(pipedes[STDOUT_FILENO]);
|
||||
|
||||
#ifdef FD_CLOEXEC
|
||||
fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
stream = fdopen(pipedes[STDIN_FILENO], "r");
|
||||
|
||||
@ -616,6 +654,7 @@ start_gatherer( int pipefd )
|
||||
}
|
||||
/* close all files but the ones we need */
|
||||
{ int nmax, n1, n2, i;
|
||||
#ifdef _SC_OPEN_MAX
|
||||
if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
|
||||
#ifdef _POSIX_OPEN_MAX
|
||||
nmax = _POSIX_OPEN_MAX;
|
||||
@ -623,6 +662,9 @@ start_gatherer( int pipefd )
|
||||
nmax = 20; /* assume a reasonable value */
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
nmax = 20; /* assume a reasonable value */
|
||||
#endif
|
||||
n1 = fileno( stderr );
|
||||
n2 = dbgfp? fileno( dbgfp ) : -1;
|
||||
for(i=0; i < nmax; i++ ) {
|
||||
@ -718,6 +760,10 @@ read_a_msg( int fd, GATHER_MSG *msg )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Using a level of 0 should never block and better add nothing
|
||||
* to the pool. So this is just a dummy for this gatherer.
|
||||
*/
|
||||
static int
|
||||
gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
size_t length, int level )
|
||||
@ -727,6 +773,9 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
GATHER_MSG msg;
|
||||
size_t n;
|
||||
|
||||
if( !level )
|
||||
return 0;
|
||||
|
||||
if( !gatherer_pid ) {
|
||||
/* make sure we are not setuid */
|
||||
if( getuid() != geteuid() )
|
||||
|
739
cipher/rndw32.c
739
cipher/rndw32.c
@ -1,5 +1,6 @@
|
||||
/* rndw32.c - interface to the Winseed DLL
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
/* rndw32.c - W32 entropy gatherer
|
||||
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
* Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,6 +17,46 @@
|
||||
* You should have received a copy of the GNU 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
|
||||
*
|
||||
*************************************************************************
|
||||
* The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
|
||||
* Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
|
||||
* copyright notice:
|
||||
*
|
||||
* This module is part of the cryptlib continuously seeded pseudorandom
|
||||
* number generator. For usage conditions, see lib_rand.c
|
||||
*
|
||||
* [Here is the notice from lib_rand.c, which is now called dev_sys.c]
|
||||
*
|
||||
* This module and the misc/rnd*.c modules represent the cryptlib
|
||||
* continuously seeded pseudorandom number generator (CSPRNG) as described in
|
||||
* my 1998 Usenix Security Symposium paper "The generation of random numbers
|
||||
* for cryptographic purposes".
|
||||
*
|
||||
* The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
|
||||
* 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
|
||||
* modules and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice
|
||||
* and this permission notice in its entirety.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the copyright notice in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. A copy of any bugfixes or enhancements made must be provided to the
|
||||
* author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
|
||||
* baseline version of the code.
|
||||
*
|
||||
* ALTERNATIVELY, the code may be distributed under the terms of the GNU
|
||||
* General Public License, version 2 or any later version published by the
|
||||
* Free Software Foundation, in which case the provisions of the GNU GPL are
|
||||
* required INSTEAD OF the above restrictions.
|
||||
*
|
||||
* Although not required under the terms of the GPL, it would still be nice if
|
||||
* you could make any changes available to the author to allow a consistent
|
||||
* code base to be maintained
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -27,10 +68,16 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "dynload.h"
|
||||
|
||||
/* We do not use the netropy DLL anymore because a standalone program is
|
||||
* easier to maintain and */
|
||||
/*#define USE_ENTROPY_DLL*/
|
||||
|
||||
|
||||
|
||||
#ifdef IS_MODULE
|
||||
#define _(a) (a)
|
||||
@ -39,6 +86,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
static int debug_me;
|
||||
|
||||
#ifdef USE_ENTROPY_DLL
|
||||
|
||||
#define WIN32_SLOW_SEEDER 0
|
||||
#define WIN32_FAST_SEEDER 1
|
||||
|
||||
@ -53,6 +104,17 @@
|
||||
#define PCP_DLL_FUNC 8
|
||||
#define PCP_UNKNOWN_SEEDER_TYPE 9
|
||||
|
||||
|
||||
/****************
|
||||
* We sometimes get a SEEDER_TOO_SMALL error, in which case we increment
|
||||
* the internal buffer by SEEDER_INC_CHUNK until we reach MAX_SEEDER_SIZE
|
||||
* MAX_SEEDER_SIZE is used as an arbitrary limit to protect against
|
||||
* bugs in Winseed.
|
||||
*/
|
||||
#define MAX_SEEDER_SIZE 500000
|
||||
#define SEEDER_INC_CHUNK 50000
|
||||
|
||||
|
||||
typedef void *WIN32_SEEDER;
|
||||
|
||||
static WIN32_SEEDER (WINAPI *create_instance)( byte type, unsigned int *reason);
|
||||
@ -68,8 +130,6 @@ static WIN32_SEEDER slow_seeder, fast_seeder;
|
||||
static byte *entropy_buffer;
|
||||
static size_t entropy_buffer_size;
|
||||
|
||||
static char *entropy_dll;
|
||||
|
||||
/****************
|
||||
* Load and initialize the winseed DLL
|
||||
* NOTE: winseed is not part of the GnuPG distribution. It should be available
|
||||
@ -80,11 +140,17 @@ static char *entropy_dll;
|
||||
static void
|
||||
load_and_init_winseed( void )
|
||||
{
|
||||
int hInstance;
|
||||
HANDLE hInstance;
|
||||
void *addr;
|
||||
unsigned int reason = 0;
|
||||
unsigned int n1, n2;
|
||||
const char *dllname = entropy_dll? entropy_dll : "c:/gnupg/entropy.dll";
|
||||
const char *dllname;
|
||||
|
||||
dllname = read_w32_registry_string( "HKEY_LOCAL_MACHINE",
|
||||
"Software\\GNU\\GnuPG",
|
||||
"EntropyDLL" );
|
||||
if( !dllname )
|
||||
dllname = "c:/gnupg/entropy.dll";
|
||||
|
||||
hInstance = LoadLibrary( dllname );
|
||||
if( !hInstance )
|
||||
@ -119,15 +185,14 @@ load_and_init_winseed( void )
|
||||
g10_log_fatal("error creating winseed fast seeder: rc=%u\n", reason );
|
||||
goto failure;
|
||||
}
|
||||
g10_log_info("slow and fast seeders created.\n");
|
||||
n1 = get_internal_seed_size( slow_seeder );
|
||||
g10_log_info("slow buffer size=%u\n", n1);
|
||||
/*g10_log_info("slow buffer size=%u\n", n1);*/
|
||||
n2 = get_internal_seed_size( fast_seeder );
|
||||
g10_log_info("fast buffer size=%u\n", n2);
|
||||
/*g10_log_info("fast buffer size=%u\n", n2);*/
|
||||
|
||||
entropy_buffer_size = n1 > n2? n1: n2;
|
||||
entropy_buffer = g10_xmalloc( entropy_buffer_size );
|
||||
g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );
|
||||
entropy_buffer = m_alloc( entropy_buffer_size );
|
||||
/*g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );*/
|
||||
|
||||
return;
|
||||
|
||||
@ -150,13 +215,16 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
unsigned int result;
|
||||
unsigned int nbytes;
|
||||
|
||||
if( !level )
|
||||
return 0;
|
||||
|
||||
if( !slow_seeder )
|
||||
load_and_init_winseed();
|
||||
|
||||
/* Our estimation on how much entropy we should use is very vague.
|
||||
* Winseed delivers some amount of entropy on each slow poll and
|
||||
* we add it to our random pool. Depending on the required quality
|
||||
* level we adjust the requested length so that for higer quality
|
||||
* level we adjust the requested length so that for higher quality
|
||||
* we make sure to add more entropy to our pool. However, as we don't
|
||||
* like to waste any entropy collected by winseed, we always add
|
||||
* at least everything we got from winseed.
|
||||
@ -169,17 +237,35 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
for(;;) {
|
||||
nbytes = entropy_buffer_size;
|
||||
result = get_seed( slow_seeder, entropy_buffer, &nbytes);
|
||||
if( result == PCP_SEEDER_TOO_SMALL ) {
|
||||
unsigned int n1 = get_internal_seed_size( slow_seeder );
|
||||
|
||||
if( n1 > MAX_SEEDER_SIZE ) {
|
||||
g10_log_fatal("rndw32: internal seeder problem (size=%u)\n",
|
||||
n1);
|
||||
return -1; /* actually never reached */
|
||||
}
|
||||
n1 += SEEDER_INC_CHUNK;
|
||||
set_internal_seed_size( slow_seeder, n1 );
|
||||
if( n1 > entropy_buffer_size ) {
|
||||
entropy_buffer_size = n1;
|
||||
entropy_buffer = m_realloc( entropy_buffer,
|
||||
entropy_buffer_size );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( result ) {
|
||||
g10_log_fatal("rndw32: get_seed(slow) failed: rc=%u\n", result);
|
||||
return -1; /* actually never reached */
|
||||
}
|
||||
g10_log_info("rndw32: slow poll level %d, need %u, got %u\n",
|
||||
level, (unsigned int)length, (unsigned int)nbytes );
|
||||
/*g10_log_info("rndw32: slow poll level %d, need %u, got %u\n",
|
||||
level, (unsigned int)length, (unsigned int)nbytes );*/
|
||||
(*add)( entropy_buffer, nbytes, requester );
|
||||
if( length <= nbytes )
|
||||
return 0; /* okay */
|
||||
length -= nbytes;
|
||||
g10_log_info("rndw32: need more\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +292,619 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester )
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !USE_ENTROPY_DLL */
|
||||
/* This is the new code which does not require the entropy.dll */
|
||||
|
||||
/*
|
||||
* Definitions which are missing from the current GNU Windows32Api
|
||||
*/
|
||||
|
||||
#define TH32CS_SNAPHEAPLIST 1
|
||||
#define TH32CS_SNAPPROCESS 2
|
||||
#define TH32CS_SNAPTHREAD 4
|
||||
#define TH32CS_SNAPMODULE 8
|
||||
#define TH32CS_SNAPALL (1|2|4|8)
|
||||
#define TH32CS_INHERIT 0x80000000
|
||||
|
||||
#define IOCTL_DISK_PERFORMANCE 0x00070020
|
||||
#define VER_PLATFORM_WIN32_WINDOWS 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
DWORD dwSize;
|
||||
DWORD th32ProcessID;
|
||||
DWORD th32HeapID;
|
||||
DWORD dwFlags;
|
||||
} HEAPLIST32;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwSize;
|
||||
HANDLE hHandle;
|
||||
DWORD dwAddress;
|
||||
DWORD dwBlockSize;
|
||||
DWORD dwFlags;
|
||||
DWORD dwLockCount;
|
||||
DWORD dwResvd;
|
||||
DWORD th32ProcessID;
|
||||
DWORD th32HeapID;
|
||||
} HEAPENTRY32;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwSize;
|
||||
DWORD cntUsage;
|
||||
DWORD th32ProcessID;
|
||||
DWORD th32DefaultHeapID;
|
||||
DWORD th32ModuleID;
|
||||
DWORD cntThreads;
|
||||
DWORD th32ParentProcessID;
|
||||
LONG pcPriClassBase;
|
||||
DWORD dwFlags;
|
||||
char szExeFile[260];
|
||||
} PROCESSENTRY32;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwSize;
|
||||
DWORD cntUsage;
|
||||
DWORD th32ThreadID;
|
||||
DWORD th32OwnerProcessID;
|
||||
LONG tpBasePri;
|
||||
LONG tpDeltaPri;
|
||||
DWORD dwFlags;
|
||||
} THREADENTRY32;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwSize;
|
||||
DWORD th32ModuleID;
|
||||
DWORD th32ProcessID;
|
||||
DWORD GlblcntUsage;
|
||||
DWORD ProccntUsage;
|
||||
BYTE *modBaseAddr;
|
||||
DWORD modBaseSize;
|
||||
HMODULE hModule;
|
||||
char szModule[256];
|
||||
char szExePath[260];
|
||||
} MODULEENTRY32;
|
||||
|
||||
|
||||
|
||||
/* Type definitions for function pointers to call Toolhelp32 functions
|
||||
* used with the windows95 gatherer */
|
||||
typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, MODULEENTRY32 *lpme);
|
||||
typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, THREADENTRY32 *lpte);
|
||||
typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, PROCESSENTRY32 *lppe);
|
||||
typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, HEAPLIST32 *lphl);
|
||||
typedef BOOL (WINAPI * HEAPFIRST) (HEAPENTRY32 *lphe, DWORD th32ProcessID,
|
||||
DWORD th32HeapID);
|
||||
typedef BOOL (WINAPI * HEAPNEXT) (HEAPENTRY32 *lphe);
|
||||
typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID);
|
||||
|
||||
/* Type definitions for function pointers to call NetAPI32 functions */
|
||||
typedef DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
|
||||
DWORD dwLevel, DWORD dwOptions,
|
||||
LPBYTE * lpBuffer);
|
||||
typedef DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
|
||||
typedef DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
|
||||
|
||||
|
||||
/* When we query the performance counters, we allocate an initial buffer and
|
||||
* then reallocate it as required until RegQueryValueEx() stops returning
|
||||
* ERROR_MORE_DATA. The following values define the initial buffer size and
|
||||
* step size by which the buffer is increased
|
||||
*/
|
||||
#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
|
||||
#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
|
||||
|
||||
|
||||
static void
|
||||
slow_gatherer_windows95( void (*add)(const void*, size_t, int), int requester )
|
||||
{
|
||||
static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
|
||||
static MODULEWALK pModule32First = NULL;
|
||||
static MODULEWALK pModule32Next = NULL;
|
||||
static PROCESSWALK pProcess32First = NULL;
|
||||
static PROCESSWALK pProcess32Next = NULL;
|
||||
static THREADWALK pThread32First = NULL;
|
||||
static THREADWALK pThread32Next = NULL;
|
||||
static HEAPLISTWALK pHeap32ListFirst = NULL;
|
||||
static HEAPLISTWALK pHeap32ListNext = NULL;
|
||||
static HEAPFIRST pHeap32First = NULL;
|
||||
static HEAPNEXT pHeap32Next = NULL;
|
||||
HANDLE hSnapshot;
|
||||
|
||||
|
||||
/* initialize the Toolhelp32 function pointers */
|
||||
if ( !pCreateToolhelp32Snapshot ) {
|
||||
HANDLE hKernel;
|
||||
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_95: init toolkit\n" );
|
||||
|
||||
/* Obtain the module handle of the kernel to retrieve the addresses
|
||||
* of the Toolhelp32 functions */
|
||||
if ( ( !(hKernel = GetModuleHandle ("KERNEL32.DLL"))) ) {
|
||||
g10_log_fatal ( "rndw32: can't get module handle\n" );
|
||||
}
|
||||
|
||||
/* Now get pointers to the functions */
|
||||
pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel,
|
||||
"CreateToolhelp32Snapshot");
|
||||
pModule32First = (MODULEWALK) GetProcAddress (hKernel, "Module32First");
|
||||
pModule32Next = (MODULEWALK) GetProcAddress (hKernel, "Module32Next");
|
||||
pProcess32First = (PROCESSWALK) GetProcAddress (hKernel,
|
||||
"Process32First");
|
||||
pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel,
|
||||
"Process32Next");
|
||||
pThread32First = (THREADWALK) GetProcAddress (hKernel, "Thread32First");
|
||||
pThread32Next = (THREADWALK) GetProcAddress (hKernel, "Thread32Next");
|
||||
pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel,
|
||||
"Heap32ListFirst");
|
||||
pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel,
|
||||
"Heap32ListNext");
|
||||
pHeap32First = (HEAPFIRST) GetProcAddress (hKernel, "Heap32First");
|
||||
pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel, "Heap32Next");
|
||||
|
||||
if ( !pCreateToolhelp32Snapshot
|
||||
|| !pModule32First || !pModule32Next
|
||||
|| !pProcess32First || !pProcess32Next
|
||||
|| !pThread32First || !pThread32Next
|
||||
|| !pHeap32ListFirst || !pHeap32ListNext
|
||||
|| !pHeap32First || !pHeap32Next ) {
|
||||
g10_log_fatal ( "rndw32: failed to get a toolhep function\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Take a snapshot of everything we can get to which is currently
|
||||
* in the system */
|
||||
if ( !(hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0)) ) {
|
||||
g10_log_fatal ( "rndw32: failed to take a toolhelp snapshot\n" );
|
||||
}
|
||||
|
||||
/* Walk through the local heap */
|
||||
{ HEAPLIST32 hl32;
|
||||
hl32.dwSize = sizeof (HEAPLIST32);
|
||||
if (pHeap32ListFirst (hSnapshot, &hl32)) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_95: walk heap\n" );
|
||||
do {
|
||||
HEAPENTRY32 he32;
|
||||
|
||||
/* First add the information from the basic Heaplist32 struct */
|
||||
(*add) ( &hl32, sizeof (hl32), requester );
|
||||
|
||||
/* Now walk through the heap blocks getting information
|
||||
* on each of them */
|
||||
he32.dwSize = sizeof (HEAPENTRY32);
|
||||
if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID)){
|
||||
do {
|
||||
(*add) ( &he32, sizeof (he32), requester );
|
||||
} while (pHeap32Next (&he32));
|
||||
}
|
||||
} while (pHeap32ListNext (hSnapshot, &hl32));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Walk through all processes */
|
||||
{ PROCESSENTRY32 pe32;
|
||||
pe32.dwSize = sizeof (PROCESSENTRY32);
|
||||
if (pProcess32First (hSnapshot, &pe32)) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_95: walk processes\n" );
|
||||
do {
|
||||
(*add) ( &pe32, sizeof (pe32), requester );
|
||||
} while (pProcess32Next (hSnapshot, &pe32));
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk through all threads */
|
||||
{ THREADENTRY32 te32;
|
||||
te32.dwSize = sizeof (THREADENTRY32);
|
||||
if (pThread32First (hSnapshot, &te32)) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_95: walk threads\n" );
|
||||
do {
|
||||
(*add) ( &te32, sizeof (te32), requester );
|
||||
} while (pThread32Next (hSnapshot, &te32));
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk through all modules associated with the process */
|
||||
{ MODULEENTRY32 me32;
|
||||
me32.dwSize = sizeof (MODULEENTRY32);
|
||||
if (pModule32First (hSnapshot, &me32)) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_95: walk modules\n" );
|
||||
do {
|
||||
(*add) ( &me32, sizeof (me32), requester );
|
||||
} while (pModule32Next (hSnapshot, &me32));
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle (hSnapshot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
|
||||
{
|
||||
static int is_initialized = 0;
|
||||
static NETSTATISTICSGET pNetStatisticsGet = NULL;
|
||||
static NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
|
||||
static NETAPIBUFFERFREE pNetApiBufferFree = NULL;
|
||||
static int is_workstation = 1;
|
||||
|
||||
static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
|
||||
PERF_DATA_BLOCK *pPerfData;
|
||||
HANDLE hDevice, hNetAPI32 = NULL;
|
||||
DWORD dwSize, status;
|
||||
int nDrive;
|
||||
|
||||
if ( !is_initialized ) {
|
||||
HKEY hKey;
|
||||
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: init toolkit\n" );
|
||||
/* Find out whether this is an NT server or workstation if necessary */
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
||||
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
BYTE szValue[32];
|
||||
dwSize = sizeof (szValue);
|
||||
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: check product options\n" );
|
||||
status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
|
||||
szValue, &dwSize);
|
||||
if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) {
|
||||
/* Note: There are (at least) three cases for ProductType:
|
||||
* WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
|
||||
* NT Server acting as a Domain Controller */
|
||||
is_workstation = 0;
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32: this is a NT server\n");
|
||||
}
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
|
||||
/* Initialize the NetAPI32 function pointers if necessary */
|
||||
if ( (hNetAPI32 = LoadLibrary ("NETAPI32.DLL")) ) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: netapi32 loaded\n" );
|
||||
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
|
||||
"NetStatisticsGet");
|
||||
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferSize");
|
||||
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferFree");
|
||||
|
||||
if ( !pNetStatisticsGet
|
||||
|| !pNetApiBufferSize || !pNetApiBufferFree ) {
|
||||
FreeLibrary (hNetAPI32);
|
||||
hNetAPI32 = NULL;
|
||||
g10_log_debug ("rndw32: No NETAPI found\n" );
|
||||
}
|
||||
}
|
||||
|
||||
is_initialized = 1;
|
||||
}
|
||||
|
||||
/* Get network statistics. Note: Both NT Workstation and NT Server by
|
||||
* default will be running both the workstation and server services. The
|
||||
* heuristic below is probably useful though on the assumption that the
|
||||
* majority of the network traffic will be via the appropriate service.
|
||||
* In any case the network statistics return almost no randomness */
|
||||
{ LPBYTE lpBuffer;
|
||||
if (hNetAPI32 && !pNetStatisticsGet (NULL,
|
||||
is_workstation ? L"LanmanWorkstation" :
|
||||
L"LanmanServer", 0, 0, &lpBuffer) ) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: get netstats\n" );
|
||||
pNetApiBufferSize (lpBuffer, &dwSize);
|
||||
(*add) ( lpBuffer, dwSize,requester );
|
||||
pNetApiBufferFree (lpBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get disk I/O statistics for all the hard drives */
|
||||
for (nDrive = 0;; nDrive++) {
|
||||
DISK_PERFORMANCE diskPerformance;
|
||||
char szDevice[50];
|
||||
|
||||
/* Check whether we can access this device */
|
||||
sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
|
||||
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
/* Note: This only works if you have turned on the disk performance
|
||||
* counters with 'diskperf -y'. These counters are off by default */
|
||||
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
|
||||
&diskPerformance, sizeof (DISK_PERFORMANCE),
|
||||
&dwSize, NULL))
|
||||
{
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: iostats drive %d\n",
|
||||
nDrive );
|
||||
(*add) ( &diskPerformance, dwSize, requester );
|
||||
}
|
||||
else {
|
||||
log_info ("NOTE: you should run 'diskperf -y' "
|
||||
"to enable the disk statistics\n");
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
|
||||
#if 0 /* we don't need this in GnuPG */
|
||||
/* Wait for any async keyset driver binding to complete. You may be
|
||||
* wondering what this call is doing here... the reason it's necessary is
|
||||
* because RegQueryValueEx() will hang indefinitely if the async driver
|
||||
* bind is in progress. The problem occurs in the dynamic loading and
|
||||
* linking of driver DLL's, which work as follows:
|
||||
*
|
||||
* hDriver = LoadLibrary( DRIVERNAME );
|
||||
* pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 );
|
||||
* pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 );
|
||||
*
|
||||
* If RegQueryValueEx() is called while the GetProcAddress()'s are in
|
||||
* progress, it will hang indefinitely. This is probably due to some
|
||||
* synchronisation problem in the NT kernel where the GetProcAddress()
|
||||
* calls affect something like a module reference count or function
|
||||
* reference count while RegQueryValueEx() is trying to take a snapshot
|
||||
* of the statistics, which include the reference counts. Because of
|
||||
* this, we have to wait until any async driver bind has completed
|
||||
* before we can call RegQueryValueEx() */
|
||||
waitSemaphore (SEMAPHORE_DRIVERBIND);
|
||||
#endif
|
||||
|
||||
/* Get information from the system performance counters. This can take
|
||||
* a few seconds to do. In some environments the call to
|
||||
* RegQueryValueEx() can produce an access violation at some random time
|
||||
* in the future, adding a short delay after the following code block
|
||||
* makes the problem go away. This problem is extremely difficult to
|
||||
* reproduce, I haven't been able to get it to occur despite running it
|
||||
* on a number of machines. The best explanation for the problem is that
|
||||
* on the machine where it did occur, it was caused by an external driver
|
||||
* or other program which adds its own values under the
|
||||
* HKEY_PERFORMANCE_DATA key. The NT kernel calls the required external
|
||||
* modules to map in the data, if there's a synchronisation problem the
|
||||
* external module would write its data at an inappropriate moment,
|
||||
* causing the access violation. A low-level memory checker indicated
|
||||
* that ExpandEnvironmentStrings() in KERNEL32.DLL, called an
|
||||
* interminable number of calls down inside RegQueryValueEx(), was
|
||||
* overwriting memory (it wrote twice the allocated size of a buffer to a
|
||||
* buffer allocated by the NT kernel). This may be what's causing the
|
||||
* problem, but since it's in the kernel there isn't much which can be
|
||||
* done.
|
||||
*
|
||||
* In addition to these problems the code in RegQueryValueEx() which
|
||||
* estimates the amount of memory required to return the performance
|
||||
* counter information isn't very accurate, since it always returns a
|
||||
* worst-case estimate which is usually nowhere near the actual amount
|
||||
* required. For example it may report that 128K of memory is required,
|
||||
* but only return 64K of data */
|
||||
{ pPerfData = m_alloc (cbPerfData);
|
||||
for (;;) {
|
||||
dwSize = cbPerfData;
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
|
||||
status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
|
||||
NULL, (LPBYTE) pPerfData, &dwSize);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
if (!memcmp (pPerfData->Signature, L"PERF", 8)) {
|
||||
(*add) ( pPerfData, dwSize, requester );
|
||||
}
|
||||
else
|
||||
g10_log_debug ( "rndw32: no PERF signature\n");
|
||||
break;
|
||||
}
|
||||
else if (status == ERROR_MORE_DATA) {
|
||||
cbPerfData += PERFORMANCE_BUFFER_STEP;
|
||||
pPerfData = m_realloc (pPerfData, cbPerfData);
|
||||
}
|
||||
else {
|
||||
g10_log_debug ( "rndw32: get performance data problem\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_free (pPerfData);
|
||||
}
|
||||
/* Although this isn't documented in the Win32 API docs, it's necessary
|
||||
to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
|
||||
implicitly opened on the first call to RegQueryValueEx()). If this
|
||||
isn't done then any system components which provide performance data
|
||||
can't be removed or changed while the handle remains active */
|
||||
RegCloseKey (HKEY_PERFORMANCE_DATA);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
size_t length, int level )
|
||||
{
|
||||
static int is_initialized;
|
||||
static int is_windows95;
|
||||
|
||||
|
||||
if( !level )
|
||||
return 0;
|
||||
/* We don't differentiate between level 1 and 2 here because
|
||||
* there is no nternal entropy pool as a scary resource. It may
|
||||
* all work slower, but because our entropy source will never
|
||||
* block but deliver some not easy to measure entropy, we assume level 2
|
||||
*/
|
||||
|
||||
|
||||
if ( !is_initialized ) {
|
||||
OSVERSIONINFO osvi = { sizeof( osvi ) };
|
||||
DWORD platform;
|
||||
|
||||
GetVersionEx( &osvi );
|
||||
platform = osvi.dwPlatformId;
|
||||
is_windows95 = platform == VER_PLATFORM_WIN32_WINDOWS;
|
||||
|
||||
if ( platform == VER_PLATFORM_WIN32s ) {
|
||||
g10_log_fatal("can't run on a W32s platform\n" );
|
||||
}
|
||||
is_initialized = 1;
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#gather_random: platform=%d\n", (int)platform );
|
||||
}
|
||||
|
||||
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#gather_random: req=%d len=%u lvl=%d\n",
|
||||
requester, (unsigned int)length, level );
|
||||
|
||||
if (is_windows95 ) {
|
||||
slow_gatherer_windows95( add, requester );
|
||||
}
|
||||
else {
|
||||
slow_gatherer_windowsNT( add, requester );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
gather_random_fast( void (*add)(const void*, size_t, int), int requester )
|
||||
{
|
||||
static int addedFixedItems = 0;
|
||||
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#gather_random_fast: req=%d\n", requester );
|
||||
|
||||
/* Get various basic pieces of system information: Handle of active
|
||||
* window, handle of window with mouse capture, handle of clipboard owner
|
||||
* handle of start of clpboard viewer list, pseudohandle of current
|
||||
* process, current process ID, pseudohandle of current thread, current
|
||||
* thread ID, handle of desktop window, handle of window with keyboard
|
||||
* focus, whether system queue has any events, cursor position for last
|
||||
* message, 1 ms time for last message, handle of window with clipboard
|
||||
* open, handle of process heap, handle of procs window station, types of
|
||||
* events in input queue, and milliseconds since Windows was started */
|
||||
{ byte buffer[20*sizeof(ulong)], *bufptr;
|
||||
bufptr = buffer;
|
||||
#define ADD(f) do { ulong along = (ulong)(f); \
|
||||
memcpy (bufptr, &along, sizeof (along) ); \
|
||||
bufptr += sizeof (along); } while (0)
|
||||
ADD ( GetActiveWindow ());
|
||||
ADD ( GetCapture ());
|
||||
ADD ( GetClipboardOwner ());
|
||||
ADD ( GetClipboardViewer ());
|
||||
ADD ( GetCurrentProcess ());
|
||||
ADD ( GetCurrentProcessId ());
|
||||
ADD ( GetCurrentThread ());
|
||||
ADD ( GetCurrentThreadId ());
|
||||
ADD ( GetDesktopWindow ());
|
||||
ADD ( GetFocus ());
|
||||
ADD ( GetInputState ());
|
||||
ADD ( GetMessagePos ());
|
||||
ADD ( GetMessageTime ());
|
||||
ADD ( GetOpenClipboardWindow ());
|
||||
ADD ( GetProcessHeap ());
|
||||
ADD ( GetProcessWindowStation ());
|
||||
ADD ( GetQueueStatus (QS_ALLEVENTS));
|
||||
ADD ( GetTickCount ());
|
||||
|
||||
assert ( bufptr-buffer < sizeof (buffer) );
|
||||
(*add) ( buffer, bufptr-buffer, requester );
|
||||
#undef ADD
|
||||
}
|
||||
|
||||
/* Get multiword system information: Current caret position, current
|
||||
* mouse cursor position */
|
||||
{ POINT point;
|
||||
GetCaretPos (&point);
|
||||
(*add) ( &point, sizeof (point), requester );
|
||||
GetCursorPos (&point);
|
||||
(*add) ( &point, sizeof (point), requester );
|
||||
}
|
||||
|
||||
/* Get percent of memory in use, bytes of physical memory, bytes of free
|
||||
* physical memory, bytes in paging file, free bytes in paging file, user
|
||||
* bytes of address space, and free user bytes */
|
||||
{ MEMORYSTATUS memoryStatus;
|
||||
memoryStatus.dwLength = sizeof (MEMORYSTATUS);
|
||||
GlobalMemoryStatus (&memoryStatus);
|
||||
(*add) ( &memoryStatus, sizeof (memoryStatus), requester );
|
||||
}
|
||||
|
||||
/* Get thread and process creation time, exit time, time in kernel mode,
|
||||
and time in user mode in 100ns intervals */
|
||||
{ HANDLE handle;
|
||||
FILETIME creationTime, exitTime, kernelTime, userTime;
|
||||
DWORD minimumWorkingSetSize, maximumWorkingSetSize;
|
||||
|
||||
handle = GetCurrentThread ();
|
||||
GetThreadTimes (handle, &creationTime, &exitTime,
|
||||
&kernelTime, &userTime);
|
||||
(*add) ( &creationTime, sizeof (creationTime), requester );
|
||||
(*add) ( &exitTime, sizeof (exitTime), requester );
|
||||
(*add) ( &kernelTime, sizeof (kernelTime), requester );
|
||||
(*add) ( &userTime, sizeof (userTime), requester );
|
||||
|
||||
handle = GetCurrentProcess ();
|
||||
GetProcessTimes (handle, &creationTime, &exitTime,
|
||||
&kernelTime, &userTime);
|
||||
(*add) ( &creationTime, sizeof (creationTime), requester );
|
||||
(*add) ( &exitTime, sizeof (exitTime), requester );
|
||||
(*add) ( &kernelTime, sizeof (kernelTime), requester );
|
||||
(*add) ( &userTime, sizeof (userTime), requester );
|
||||
|
||||
/* Get the minimum and maximum working set size for the current process */
|
||||
GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
|
||||
&maximumWorkingSetSize);
|
||||
(*add) ( &minimumWorkingSetSize,
|
||||
sizeof (&minimumWorkingSetSize), requester );
|
||||
(*add) ( &maximumWorkingSetSize,
|
||||
sizeof (&maximumWorkingSetSize), requester );
|
||||
}
|
||||
|
||||
|
||||
/* The following are fixed for the lifetime of the process so we only
|
||||
* add them once */
|
||||
if (!addedFixedItems) {
|
||||
STARTUPINFO startupInfo;
|
||||
|
||||
/* Get name of desktop, console window title, new window position and
|
||||
* size, window flags, and handles for stdin, stdout, and stderr */
|
||||
startupInfo.cb = sizeof (STARTUPINFO);
|
||||
GetStartupInfo (&startupInfo);
|
||||
(*add) ( &startupInfo, sizeof (STARTUPINFO), requester );
|
||||
addedFixedItems = 1;
|
||||
}
|
||||
|
||||
/* The performance of QPC varies depending on the architecture it's
|
||||
* running on and on the OS. Under NT it reads the CPU's 64-bit timestamp
|
||||
* counter (at least on a Pentium and newer '486's, it hasn't been tested
|
||||
* on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC
|
||||
* timer. There are vague mumblings in the docs that it may fail if the
|
||||
* appropriate hardware isn't available (possibly '386's or MIPS machines
|
||||
* running NT), but who's going to run NT on a '386? */
|
||||
{ LARGE_INTEGER performanceCount;
|
||||
if (QueryPerformanceCounter (&performanceCount)) {
|
||||
if ( debug_me )
|
||||
log_debug ("rndw32#gather_random_fast: perf data\n");
|
||||
(*add) (&performanceCount, sizeof (&performanceCount), requester);
|
||||
}
|
||||
else { /* Millisecond accuracy at best... */
|
||||
DWORD aword = GetTickCount ();
|
||||
(*add) (&aword, sizeof (aword), requester );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !USE_ENTROPY_DLL */
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
@ -232,6 +931,8 @@ gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
void *ret;
|
||||
int i = *sequence;
|
||||
|
||||
debug_me = !!getenv("DEBUG_RNDW32");
|
||||
|
||||
do {
|
||||
if ( i >= DIM(func_table) || i < 0 ) {
|
||||
return NULL;
|
||||
@ -246,14 +947,6 @@ gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_STATIC_RNDW32
|
||||
void
|
||||
rndw32_set_dll_name( const char *name )
|
||||
{
|
||||
entropy_dll = m_strdup( name );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IS_MODULE
|
||||
void
|
||||
rndw32_constructor(void)
|
||||
|
375
cipher/rsa.c
Normal file
375
cipher/rsa.c
Normal file
@ -0,0 +1,375 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "rsa.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
MPI n; /* modulus */
|
||||
MPI e; /* exponent */
|
||||
} RSA_public_key;
|
||||
|
||||
|
||||
typedef struct {
|
||||
MPI n; /* public modulus */
|
||||
MPI e; /* public exponent */
|
||||
MPI d; /* exponent */
|
||||
MPI p; /* prime p. */
|
||||
MPI q; /* prime q. */
|
||||
MPI u; /* inverse of p mod q. */
|
||||
} RSA_secret_key;
|
||||
|
||||
|
||||
static void test_keys( RSA_secret_key *sk, unsigned nbits );
|
||||
static void generate( RSA_secret_key *sk, unsigned nbits );
|
||||
static int check_secret_key( RSA_secret_key *sk );
|
||||
static void public(MPI output, MPI input, RSA_public_key *skey );
|
||||
static void secret(MPI output, MPI input, RSA_secret_key *skey );
|
||||
|
||||
|
||||
static void
|
||||
test_keys( RSA_secret_key *sk, unsigned nbits )
|
||||
{
|
||||
RSA_public_key pk;
|
||||
MPI test = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
MPI out1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
MPI out2 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
|
||||
pk.n = sk->n;
|
||||
pk.e = sk->e;
|
||||
{ char *p = get_random_bits( nbits, 0, 0 );
|
||||
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
public( out1, test, &pk );
|
||||
secret( out2, out1, sk );
|
||||
if( mpi_cmp( test, out2 ) )
|
||||
log_fatal("RSA operation: public, secret failed\n");
|
||||
secret( out1, test, sk );
|
||||
public( out2, out1, &pk );
|
||||
if( mpi_cmp( test, out2 ) )
|
||||
log_fatal("RSA operation: secret, public failed\n");
|
||||
mpi_free( test );
|
||||
mpi_free( out1 );
|
||||
mpi_free( out2 );
|
||||
}
|
||||
|
||||
/****************
|
||||
* Generate a key pair with a key of size NBITS
|
||||
* Returns: 2 structures filles with all needed values
|
||||
*/
|
||||
static void
|
||||
generate( RSA_secret_key *sk, unsigned nbits )
|
||||
{
|
||||
MPI p, q; /* the two primes */
|
||||
MPI d; /* the private key */
|
||||
MPI u;
|
||||
MPI t1, t2;
|
||||
MPI n; /* the public key */
|
||||
MPI e; /* the exponent */
|
||||
MPI phi; /* helper: (p-a)(q-1) */
|
||||
MPI g;
|
||||
MPI f;
|
||||
|
||||
/* select two (very secret) primes */
|
||||
p = generate_secret_prime( nbits / 2 );
|
||||
q = generate_secret_prime( nbits / 2 );
|
||||
if( mpi_cmp( p, q ) > 0 ) /* p shall be smaller than q (for calc of u)*/
|
||||
mpi_swap(p,q);
|
||||
/* calculate Euler totient: phi = (p-1)(q-1) */
|
||||
t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
|
||||
t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
|
||||
phi = mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
g = mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
f = mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
mpi_sub_ui( t1, p, 1 );
|
||||
mpi_sub_ui( t2, q, 1 );
|
||||
mpi_mul( phi, t1, t2 );
|
||||
mpi_gcd(g, t1, t2);
|
||||
mpi_fdiv_q(f, phi, g);
|
||||
/* multiply them to make the private key */
|
||||
n = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
mpi_mul( n, p, q );
|
||||
/* find a public exponent */
|
||||
e = mpi_alloc( (6+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
mpi_set_ui( e, 17); /* start with 17 */
|
||||
while( !mpi_gcd(t1, e, phi) ) /* (while gcd is not 1) */
|
||||
mpi_add_ui( e, e, 2);
|
||||
/* calculate the secret key d = e^1 mod phi */
|
||||
d = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
mpi_invm(d, e, f );
|
||||
/* calculate the inverse of p and q (used for chinese remainder theorem)*/
|
||||
u = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
|
||||
mpi_invm(u, p, q );
|
||||
|
||||
if( DBG_CIPHER ) {
|
||||
log_mpidump(" p= ", p );
|
||||
log_mpidump(" q= ", q );
|
||||
log_mpidump("phi= ", phi );
|
||||
log_mpidump(" g= ", g );
|
||||
log_mpidump(" f= ", f );
|
||||
log_mpidump(" n= ", n );
|
||||
log_mpidump(" e= ", e );
|
||||
log_mpidump(" d= ", d );
|
||||
log_mpidump(" u= ", u );
|
||||
}
|
||||
|
||||
mpi_free(t1);
|
||||
mpi_free(t2);
|
||||
mpi_free(phi);
|
||||
mpi_free(f);
|
||||
mpi_free(g);
|
||||
|
||||
sk->n = n;
|
||||
sk->e = e;
|
||||
sk->p = p;
|
||||
sk->q = q;
|
||||
sk->d = d;
|
||||
sk->u = u;
|
||||
|
||||
/* now we can test our keys (this should never fail!) */
|
||||
test_keys( sk, nbits - 64 );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Test wether the secret key is valid.
|
||||
* Returns: true if this is a valid key.
|
||||
*/
|
||||
static int
|
||||
check_secret_key( RSA_secret_key *sk )
|
||||
{
|
||||
int rc;
|
||||
MPI temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
|
||||
|
||||
mpi_mul(temp, sk->p, sk->q );
|
||||
rc = mpi_cmp( temp, sk->n );
|
||||
mpi_free(temp);
|
||||
return !rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT.
|
||||
*
|
||||
* c = m^e mod n
|
||||
*
|
||||
* Where c is OUTPUT, m is INPUT and e,n are elements of PKEY.
|
||||
*/
|
||||
static void
|
||||
public(MPI output, MPI input, RSA_public_key *pkey )
|
||||
{
|
||||
if( output == input ) { /* powm doesn't like output and input the same */
|
||||
MPI x = mpi_alloc( mpi_get_nlimbs(input)*2 );
|
||||
mpi_powm( x, input, pkey->e, pkey->n );
|
||||
mpi_set(output, x);
|
||||
mpi_free(x);
|
||||
}
|
||||
else
|
||||
mpi_powm( output, input, pkey->e, pkey->n );
|
||||
}
|
||||
|
||||
/****************
|
||||
* 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.
|
||||
*
|
||||
* FIXME: We should better use the Chinese Remainder Theorem
|
||||
*/
|
||||
static void
|
||||
secret(MPI output, MPI input, RSA_secret_key *skey )
|
||||
{
|
||||
mpi_powm( output, input, skey->d, skey->n );
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
************** interface ******************
|
||||
*********************************************/
|
||||
|
||||
int
|
||||
rsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
||||
{
|
||||
RSA_secret_key sk;
|
||||
|
||||
if( !is_RSA(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
generate( &sk, nbits );
|
||||
skey[0] = sk.n;
|
||||
skey[1] = sk.e;
|
||||
skey[2] = sk.d;
|
||||
skey[3] = sk.p;
|
||||
skey[4] = sk.q;
|
||||
skey[5] = sk.u;
|
||||
/* make an empty list of factors */
|
||||
*retfactors = m_alloc_clear( 1 * sizeof **retfactors );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rsa_check_secret_key( int algo, MPI *skey )
|
||||
{
|
||||
RSA_secret_key sk;
|
||||
|
||||
if( !is_RSA(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
sk.n = skey[0];
|
||||
sk.e = skey[1];
|
||||
sk.d = skey[2];
|
||||
sk.p = skey[3];
|
||||
sk.q = skey[4];
|
||||
sk.u = skey[5];
|
||||
if( !check_secret_key( &sk ) )
|
||||
return G10ERR_BAD_SECKEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
|
||||
{
|
||||
RSA_public_key pk;
|
||||
|
||||
if( algo != 1 && algo != 2 )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
pk.n = pkey[0];
|
||||
pk.e = pkey[1];
|
||||
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.n ) );
|
||||
public( resarr[0], data, &pk );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
||||
{
|
||||
RSA_secret_key sk;
|
||||
|
||||
if( algo != 1 && algo != 2 )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
sk.n = skey[0];
|
||||
sk.e = skey[1];
|
||||
sk.d = skey[2];
|
||||
sk.p = skey[3];
|
||||
sk.q = skey[4];
|
||||
sk.u = skey[5];
|
||||
*result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) );
|
||||
secret( *result, data[0], &sk );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
||||
{
|
||||
RSA_secret_key sk;
|
||||
|
||||
if( algo != 1 && algo != 3 )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
sk.n = skey[0];
|
||||
sk.e = skey[1];
|
||||
sk.d = skey[2];
|
||||
sk.p = skey[3];
|
||||
sk.q = skey[4];
|
||||
sk.u = skey[5];
|
||||
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.n ) );
|
||||
secret( resarr[0], data, &sk );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *opaque, MPI tmp), void *opaquev )
|
||||
{
|
||||
RSA_public_key pk;
|
||||
MPI result;
|
||||
int rc;
|
||||
|
||||
if( algo != 1 && algo != 3 )
|
||||
return G10ERR_PUBKEY_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;
|
||||
mpi_free(result);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
rsa_get_nbits( int algo, MPI *pkey )
|
||||
{
|
||||
if( !is_RSA(algo) )
|
||||
return 0;
|
||||
return mpi_get_nbits( pkey[0] );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return some information about the algorithm. We need algo here to
|
||||
* distinguish different flavors of the algorithm.
|
||||
* Returns: A pointer to string describing the algorithm or NULL if
|
||||
* the ALGO is invalid.
|
||||
* Usage: Bit 0 set : allows signing
|
||||
* 1 set : allows encryption
|
||||
*/
|
||||
const char *
|
||||
rsa_get_info( int algo,
|
||||
int *npkey, int *nskey, int *nenc, int *nsig, int *usage )
|
||||
{
|
||||
*npkey = 2;
|
||||
*nskey = 6;
|
||||
*nenc = 1;
|
||||
*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";
|
||||
default:*usage = 0; return NULL;
|
||||
}
|
||||
}
|
||||
|
36
cipher/rsa.h
Normal file
36
cipher/rsa.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* rsa.h
|
||||
* Copyright (C) 1997,1998 by Werner Koch (dd9jn)
|
||||
* Copyright (C) 2000 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifndef G10_RSA_H
|
||||
#define G10_RSA_H
|
||||
|
||||
int rsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
|
||||
int rsa_check_secret_key( int algo, MPI *skey );
|
||||
int rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
|
||||
int rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
|
||||
int rsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
|
||||
int rsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI), void *opaquev );
|
||||
unsigned rsa_get_nbits( int algo, MPI *pkey );
|
||||
const char *rsa_get_info( int algo, int *npkey, int *nskey,
|
||||
int *nenc, int *nsig, int *use );
|
||||
|
||||
|
||||
#endif /*G10_RSA_H*/
|
@ -337,10 +337,10 @@ sha1_get_info( int algo, size_t *contextsize,
|
||||
*r_asnoid = asn;
|
||||
*r_asnlen = DIM(asn);
|
||||
*r_mdlen = 20;
|
||||
*r_init = (void (*)(void *))sha1_init;
|
||||
*r_write = (void (*)(void *, byte*, size_t))sha1_write;
|
||||
*r_final = (void (*)(void *))sha1_final;
|
||||
*r_read = (byte *(*)(void *))sha1_read;
|
||||
*(void (**)(SHA1_CONTEXT *))r_init = sha1_init;
|
||||
*(void (**)(SHA1_CONTEXT *, byte*, size_t))r_write = sha1_write;
|
||||
*(void (**)(SHA1_CONTEXT *))r_final = sha1_final;
|
||||
*(byte *(**)(SHA1_CONTEXT *))r_read = sha1_read;
|
||||
|
||||
return "SHA1";
|
||||
}
|
||||
|
@ -899,10 +899,10 @@ tiger_get_info( int algo, size_t *contextsize,
|
||||
*r_asnoid = asn;
|
||||
*r_asnlen = DIM(asn);
|
||||
*r_mdlen = 24;
|
||||
*r_init = (void (*)(void *))tiger_init;
|
||||
*r_write = (void (*)(void *, byte*, size_t))tiger_write;
|
||||
*r_final = (void (*)(void *))tiger_final;
|
||||
*r_read = (byte *(*)(void *))tiger_read;
|
||||
*(void (**)(TIGER_CONTEXT *))r_init = tiger_init;
|
||||
*(void (**)(TIGER_CONTEXT *, byte*, size_t))r_write = tiger_write;
|
||||
*(void (**)(TIGER_CONTEXT *))r_final = tiger_final;
|
||||
*(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read;
|
||||
|
||||
return "TIGER";
|
||||
}
|
||||
|
@ -34,10 +34,6 @@
|
||||
/* Prototype for the self-test function. */
|
||||
static const char *selftest(void);
|
||||
|
||||
/* Macros used by the info function. */
|
||||
#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
|
||||
#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
|
||||
|
||||
/* Structure for an expanded Twofish key. s contains the key-dependent
|
||||
* S-boxes composed with the MDS matrix; w contains the eight "whitening"
|
||||
* subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
|
||||
@ -990,16 +986,20 @@ twofish_get_info (int algo, size_t *keylen,
|
||||
*keylen = algo==10? 256 : 128;
|
||||
*blocksize = 16;
|
||||
*contextsize = sizeof (TWOFISH_context);
|
||||
*r_setkey = FNCCAST_SETKEY (twofish_setkey);
|
||||
*r_encrypt= FNCCAST_CRYPT (twofish_encrypt);
|
||||
*r_decrypt= FNCCAST_CRYPT (twofish_decrypt);
|
||||
|
||||
if( algo == 10 )
|
||||
return "TWOFISH";
|
||||
if (algo == 102) /* This algorithm number is assigned for
|
||||
* experiments, so we can use it */
|
||||
return "TWOFISH128";
|
||||
return NULL;
|
||||
*(int (**)(TWOFISH_context*, const byte*, const unsigned))r_setkey
|
||||
= twofish_setkey;
|
||||
*(void (**)(const TWOFISH_context*, byte*, const byte*))r_encrypt
|
||||
= twofish_encrypt;
|
||||
*(void (**)(const TWOFISH_context*, byte*, const byte*))r_decrypt
|
||||
= twofish_decrypt;
|
||||
|
||||
if( algo == 10 )
|
||||
return "TWOFISH";
|
||||
if (algo == 102) /* This algorithm number is assigned for
|
||||
* experiments, so we can use it */
|
||||
return "TWOFISH128";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
118
configure.in
118
configure.in
@ -11,19 +11,17 @@ AC_PREREQ(2.13)
|
||||
AC_INIT(g10/gpg.c)
|
||||
AC_CONFIG_AUX_DIR(scripts)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CANONICAL_SYSTEM
|
||||
AM_INIT_AUTOMAKE(gnupg,`cat $srcdir/VERSION`)
|
||||
|
||||
|
||||
VERSION=`cat $srcdir/VERSION`
|
||||
PACKAGE=gnupg
|
||||
ALL_LINGUAS="de es_ES fr it pl pt_BR pt_PT ru"
|
||||
ALL_LINGUAS="da de eo es_ES fr id it ja nl pl pt_BR pt_PT ru sv"
|
||||
static_modules="sha1 md5 rmd160"
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
|
||||
static_random_module=""
|
||||
|
||||
MODULES_IN_CIPHER=`awk '/# MODULES: / { for(i=3;i<=NF;i++) print $i}' \
|
||||
$srcdir/cipher/Makefile.am`
|
||||
AC_PROG_AWK
|
||||
|
||||
MODULES_IN_CIPHER=`$AWK '/^EXTRA_PROGRAMS/ { for(i=3;i<=NF;i++) print $i}' \
|
||||
$srcdir/cipher/Makefile.am`
|
||||
|
||||
dnl
|
||||
dnl Check for random module options
|
||||
@ -132,7 +130,6 @@ AM_MAINTAINER_MODE
|
||||
|
||||
dnl Checks for programs.
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
dnl
|
||||
dnl Setup some stuff depending on host/target.
|
||||
dnl
|
||||
@ -145,8 +142,10 @@ case "${target}" in
|
||||
CC="${target}-gcc"
|
||||
CPP="${target}-gcc -E"
|
||||
RANLIB="${target}-ranlib"
|
||||
disallowed_modules="rndunix rndlinux rndegd"
|
||||
;;
|
||||
*)
|
||||
disallowed_modules="rndw32"
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -177,9 +176,6 @@ AM_PROG_LIBTOOL
|
||||
|
||||
|
||||
MPI_OPT_FLAGS=""
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
|
||||
fi
|
||||
|
||||
|
||||
try_gettext=yes
|
||||
@ -213,6 +209,12 @@ case "${target}" in
|
||||
try_gdbm="no"
|
||||
;;
|
||||
|
||||
*-*-freebsd*)
|
||||
# FreeBSD
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
if test -z "$GCC" ; then
|
||||
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
|
||||
@ -234,7 +236,7 @@ esac
|
||||
AC_SUBST(MPI_OPT_FLAGS)
|
||||
GNUPG_SYS_SYMBOL_UNDERSCORE
|
||||
GNUPG_CHECK_PIC
|
||||
GNUPG_CHECK_RDYNAMIC
|
||||
GNUPG_CHECK_EXPORTDYNAMIC
|
||||
if test "$NO_PIC" = yes; then
|
||||
try_dynload=no
|
||||
fi
|
||||
@ -272,6 +274,13 @@ case "${target}" in
|
||||
NAME_OF_DEV_URANDOM="/dev/urandom"
|
||||
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -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"
|
||||
;;
|
||||
|
||||
*)
|
||||
NAME_OF_DEV_RANDOM="/dev/random"
|
||||
NAME_OF_DEV_URANDOM="/dev/urandom"
|
||||
@ -327,21 +336,21 @@ if test "$try_dynload" = yes ; then
|
||||
if test "$ac_cv_lib_dl_dlopen" = "yes"; then
|
||||
AC_DEFINE(USE_DYNAMIC_LINKING)
|
||||
AC_DEFINE(HAVE_DL_DLOPEN)
|
||||
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
|
||||
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
|
||||
use_gnupg_extensions=yes
|
||||
else
|
||||
AC_CHECK_LIB(c,dlopen)
|
||||
if test "$ac_cv_lib_c_dlopen" = "yes"; then
|
||||
AC_CHECK_FUNCS(dlopen)
|
||||
if test "$ac_cv_func_dlopen" = "yes"; then
|
||||
AC_DEFINE(USE_DYNAMIC_LINKING)
|
||||
AC_DEFINE(HAVE_DL_DLOPEN)
|
||||
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
|
||||
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
|
||||
use_gnupg_extensions=yes
|
||||
else
|
||||
AC_CHECK_LIB(dld,shl_load)
|
||||
if test "$ac_cv_lib_dld_shl_load" = "yes"; then
|
||||
AC_DEFINE(USE_DYNAMIC_LINKING)
|
||||
AC_DEFINE(HAVE_DL_SHL_LOAD)
|
||||
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
|
||||
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
|
||||
use_gnupg_extensions=yes
|
||||
dnl -----------------
|
||||
dnl DLD is not ready for use. So I better disable this test
|
||||
@ -350,7 +359,7 @@ dnl AC_CHECK_LIB(dld,dld_link)
|
||||
dnl if test "$ac_cv_lib_dld_dld_link" = "yes"; then
|
||||
dnl AC_DEFINE(USE_DYNAMIC_LINKING)
|
||||
dnl AC_DEFINE(HAVE_DLD_DLD_LINK)
|
||||
dnl DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
|
||||
dnl DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
|
||||
dnl use_gnupg_extensions=yes
|
||||
dnl ---------------
|
||||
fi
|
||||
@ -371,7 +380,7 @@ AC_SUBST(DYNLINK_MOD_CFLAGS)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(unistd.h langinfo.h)
|
||||
AC_CHECK_HEADERS(unistd.h langinfo.h termio.h)
|
||||
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@ -393,6 +402,7 @@ GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
|
||||
AC_CHECK_SIZEOF(unsigned short, 2)
|
||||
AC_CHECK_SIZEOF(unsigned int, 4)
|
||||
AC_CHECK_SIZEOF(unsigned long, 4)
|
||||
AC_CHECK_SIZEOF(unsigned long long, 0)
|
||||
|
||||
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|
||||
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
|
||||
@ -405,8 +415,9 @@ fi
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(strerror stpcpy strlwr stricmp tcgetattr rand strtoul mmap)
|
||||
AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit)
|
||||
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)
|
||||
|
||||
GNUPG_CHECK_MLOCK
|
||||
GNUPG_FUNC_MKDIR_TAKES_ONE_ARG
|
||||
@ -483,29 +494,27 @@ fi
|
||||
dnl
|
||||
dnl Figure out the default linkage mode for cipher modules
|
||||
dnl
|
||||
dnl (We always need a static rmd160)
|
||||
print_egd_notice=no
|
||||
static_modules="$static_modules rmd160"
|
||||
if test "$use_static_rnd" = default; then
|
||||
if test "$ac_cv_have_dev_random" = yes; then
|
||||
static_modules="$static_modules rndlinux"
|
||||
static_random_module="rndlinux"
|
||||
else
|
||||
case "${target}" in
|
||||
*-*-mingw32)
|
||||
static_modules="$static_modules rndw32"
|
||||
static_random_module="rndw32"
|
||||
AC_DEFINE(USE_STATIC_RNDW32)
|
||||
;;
|
||||
i?86-emx-os2|i?86-*-os2*emx)
|
||||
static_modules="$static_modules rndos2"
|
||||
static_random_module="rndos2"
|
||||
;;
|
||||
m68k-atari-mint)
|
||||
static_modules="$static_modules rndatari"
|
||||
static_random_module="rndatari"
|
||||
;;
|
||||
i?86-*-msdosdjgpp*)
|
||||
static_modules="$static_modules"
|
||||
:
|
||||
;;
|
||||
*)
|
||||
static_modules="$static_modules rndunix"
|
||||
static_random_module="rndunix"
|
||||
print_egd_notice=yes
|
||||
;;
|
||||
esac
|
||||
@ -514,7 +523,7 @@ else
|
||||
if test "$use_static_rnd" = none; then
|
||||
:
|
||||
else
|
||||
static_modules="$static_modules rnd$use_static_rnd"
|
||||
static_random_module="rnd$use_static_rnd"
|
||||
if test "$use_static_rnd" = "unix"; then
|
||||
print_egd_notice=yes
|
||||
fi
|
||||
@ -547,23 +556,31 @@ dnl
|
||||
dnl Parse the modules list and build the list
|
||||
dnl of static and dymically linked modules
|
||||
dnl
|
||||
dnl (We always need a static rmd160)
|
||||
static_modules="$static_modules rmd160 $static_random_module"
|
||||
STATIC_CIPHER_NAMES=""
|
||||
STATIC_CIPHER_OBJS=""
|
||||
DYNAMIC_CIPHER_MODS=""
|
||||
GNUPG_MSG_PRINT([dynamically linked cipher modules:])
|
||||
for name in $MODULES_IN_CIPHER; do
|
||||
x="no"
|
||||
for i in $static_modules; do
|
||||
if test "$name" = "$i" ; then
|
||||
x="yes"
|
||||
fi
|
||||
x="yes"
|
||||
for i in $disallowed_modules; do
|
||||
if test "$name" = "$i" ; then x="no" ; fi
|
||||
done;
|
||||
if test $x = yes; then
|
||||
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
|
||||
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.lo"
|
||||
else
|
||||
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
|
||||
GNUPG_MSG_PRINT([$name])
|
||||
x="no"
|
||||
for i in $static_modules; do
|
||||
if test "$name" = "$i" ; then
|
||||
x="yes"
|
||||
fi
|
||||
done;
|
||||
if test $x = yes; then
|
||||
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
|
||||
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.o"
|
||||
else
|
||||
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
|
||||
GNUPG_MSG_PRINT([$name])
|
||||
fi
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT()
|
||||
@ -663,6 +680,9 @@ fi
|
||||
AC_SUBST(ZLIBS)
|
||||
|
||||
|
||||
# Allow users to append something to the version string without
|
||||
# flagging it as development version. The user version parts is
|
||||
# considered everything after a dash.
|
||||
changequote(,)dnl
|
||||
tmp_pat='[a-zA-Z]'
|
||||
changequote([,])dnl
|
||||
@ -678,12 +698,26 @@ AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
|
||||
|
||||
GNUPG_DO_LINK_FILES
|
||||
|
||||
GNUPG_CHECK_GNUMAKE
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
if test "$MAINTAINER_MODE" = "yes"; then
|
||||
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
|
||||
else
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Make the version number in gcrypt/gcrypt.h the same as the one here.
|
||||
dnl (this is easier than to have a .in file just for one substitution)
|
||||
dnl
|
||||
GNUPG_FIX_HDR_VERSION(gcrypt/gcrypt.h, GCRYPT_VERSION)
|
||||
|
||||
GCRYPT_LIBS="-L${libdir} -lgcrypt"
|
||||
GCRYPT_CFLAGS=""
|
||||
AC_SUBST(GCRYPT_LIBS)
|
||||
AC_SUBST(GCRYPT_CFLAGS)
|
||||
|
||||
AC_OUTPUT_COMMANDS([
|
||||
chmod +x scripts/db2html
|
||||
|
814
g10/ChangeLog
814
g10/ChangeLog
@ -1,231 +1,710 @@
|
||||
Thu May 25 18:39:11 CEST 2000 Werner Koch <wk@openit.de>
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* kbxio.c: New.
|
||||
Replaced everything with the code from the STABLE-BRANCH-1-0 and
|
||||
started to backport the changes from the 1.1 development branch
|
||||
which are dated according to the ChangeLog of the 1.1 from
|
||||
Sat Sep 18 12:16:08 CEST 1999 to Thu May 25 18:39:11 CEST 2000.
|
||||
Here are those changes, some of them are duplicates because they
|
||||
have been done on both branch simultaneously.
|
||||
|
||||
* kbxfile.c (print_kbxfile): Add a loop
|
||||
(do_print_kbxfile): Fixed passing to kbx_dump_blob.
|
||||
* gpg.c (print_mds): Add arg keys as a kludge to print hmacs
|
||||
(main): New option --print-hmac.
|
||||
|
||||
Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
|
||||
* trustdb.c (verify_own_keys): Do not print warning about unprotected
|
||||
key when in quiet mode.
|
||||
|
||||
* gpg.c (print_mds): Add arg keys as a kludge to print hmacs
|
||||
(main): New option --print-hmac.
|
||||
* build-paket.c (do_user_id): Save offset where name has been stored.
|
||||
|
||||
* ringedit.c : Add new access method KBXF
|
||||
|
||||
* kbxfile.c: New.
|
||||
|
||||
* kbx.h: New.
|
||||
* kbxblob.c: Started to work on the keybox stuff.
|
||||
|
||||
* keygen.c (gen_dsa): Modified to work with gcry_pk_genkey.
|
||||
|
||||
* Removed dummy-cipher.h from all files.
|
||||
|
||||
* keygen.c (gen_elg): Modified to work with gcry_pk_genkey.
|
||||
(key_from_sexp): New.
|
||||
(factors_from_sexp): New.
|
||||
|
||||
* g10.c : Renamed to ...
|
||||
* gpg.c : ... this
|
||||
* Makefile.am: And fixed it here.
|
||||
|
||||
* Changed all "g10_"/"GPG_" prefixes to "gpg_"/"GPG_".
|
||||
|
||||
* misc.c (mpi_read_opaque): Fixed double counting.
|
||||
|
||||
* seckey-cert.c (do_check): Removed buffer and the unmotivated free
|
||||
on it.
|
||||
|
||||
* pubkey-enc.c (pk_decrypt): New wrapper for the gcry_ function.
|
||||
* seckey-cert.c (pk_check_secret_key): Likewise.
|
||||
* encode.c (pk_encrypt): Likewise.
|
||||
|
||||
* parse-packet.c (parse_key): Fixed case of unencrypted secret keys.
|
||||
|
||||
* misc.c (mpi_print): Use gcry_mpi_aprint.
|
||||
(pubkey_nbits): Kludge to use the gcry_pk_ API.
|
||||
|
||||
* seskey.c (encode_session_key): Replaced mpi_set_buffer by *_scan.
|
||||
(do_encode_md): Ditto.
|
||||
(encode_md_value): Ditto.
|
||||
* seckey-cert.c (protect_secret_key): Ditto.
|
||||
* comment.c (make_mpi_comment_node): Replaced mpi_get_buffer by _print.
|
||||
* pubkey-enc.c (get_it): Ditto.
|
||||
* sig-check.c (do_signature_check): Ditto.
|
||||
|
||||
* keyid.c (do_fingerprint_md): Replaced mpi_get_buffer by gcry_mpi_print.
|
||||
(v3_keyid): New.
|
||||
(keyid_from_sk): And use it here.
|
||||
(keyid_from_pk): Ditto.
|
||||
(fingerprint_from_sk): Ditto.
|
||||
(fingerprint_from_pk): Ditto.
|
||||
|
||||
* misc.c (mpi_print): New.
|
||||
|
||||
* misc.c (checksum_mpi): Now uses gcry_mpi_print to get the data.
|
||||
|
||||
* seckey-cert.c (do_check): Replaced mpi_read_from_buffer.
|
||||
|
||||
* armor.c (armor_filter): Made the "Comment:" header translatable.
|
||||
|
||||
* seckey-cert.c: Removed obsolete mpi_*_protect_flag.
|
||||
* parse-packet.c: Ditto.
|
||||
|
||||
* misc.c (mpi_read): Removed the secure argumet becuase it is
|
||||
never used. Changed all Callers.
|
||||
(mpi_read_opaque): New.
|
||||
(mpi_write_opaque): New.
|
||||
* parse-packet.c (parse_key): Use the opaque method also for
|
||||
v3 keys.
|
||||
* build-packet.c (do_secret_key): Likewise.
|
||||
|
||||
* g10.c (main): Check libgcrypt version.
|
||||
|
||||
* packet.h: replaced inclusion of mpi.h by a plain typeedef of the
|
||||
gcry_mpi structure and removed all inclusions of "mpi.h" in all
|
||||
sources.
|
||||
|
||||
* g10.c: Add --delete-secret-key to the help page.
|
||||
|
||||
* g10.c (main): Changed the default homedir to "~/.gnupg-test" so
|
||||
that we don't mess up with the stable version.
|
||||
|
||||
* misc.c (mpi_write): New.
|
||||
(mpi_write): New.
|
||||
|
||||
* misc.c (checksum_u16_nobug): Removed.
|
||||
(checksum_mpi_counted_nbits): Renamed to ...
|
||||
(checksum_mpi): ... this to superseed the old one. Changed all
|
||||
callers. This is because we do not emulate the old gpg bug anymore.
|
||||
* g10.c (oEmuChecksumBug): Removed.
|
||||
|
||||
* g10.c (register_extension): New...
|
||||
(main): Use it here instead of register_cipher_extesnion.
|
||||
(strusage): s/strusage/my_strusage/ . Made static.
|
||||
(main): Use set_strusage().
|
||||
|
||||
* tdbdump.c (HEXTOBIN): Changed the name of the argument, so that
|
||||
traditional cpp don't mess up the macros. Suggested by Jos Backus.
|
||||
|
||||
* armor.c (parse_header_line): Stop parsing on a only WS line too.
|
||||
Suggested by Aric Cyr.
|
||||
|
||||
* misc.c (pull_in_libs): Removed.
|
||||
|
||||
* mainproc.c (list_node): Print the PK algo in the --with-colon mode.
|
||||
* keylist.c (list_keyblock): Ditto.
|
||||
|
||||
* misc.c (pull_in_libs): Removed pull in of g10c.
|
||||
|
||||
* misc.c (map_gcry_rc): Removed here and chnaged all users.
|
||||
|
||||
* getkey.c: Replaced check_pubkey_algo by openpgp_pk_test_algo.
|
||||
* import.c (delete_inv_parts): Ditto.
|
||||
* pkclist.c: Ditto.
|
||||
* skclist.c: Ditto.
|
||||
* pubkey-enc.c: Ditto.
|
||||
|
||||
* g10.c (main): Replaced the function to diable PK algos.
|
||||
|
||||
* g10.c (main): Replaced get_random_bits by gcry_random_bytes.
|
||||
* seskey.c (encode_session_key): Likewise.
|
||||
(make_session_key): Renamed randomize_buffer to gcry_randomize
|
||||
and use the GCRY_xxx_RANDOM constants.
|
||||
* cipher.c (write_header): Ditto.
|
||||
* passphrase.c (hash_passphrase): Ditto.
|
||||
* seckey-cert.c (protect_secret_key): Ditto.
|
||||
|
||||
* getkey.c (find_by_name): Replaced rmd160_hash_buffer
|
||||
by gcry_md_hash_buffer.
|
||||
* keyedit.c (show_prefs): Ditto.
|
||||
* keylist.c (list_keyblock): Ditto.
|
||||
* trustdb.c (print_uid_from_keyblock): Ditto.
|
||||
(make_uid_records): Ditto.
|
||||
|
||||
* skclist.c (build_sk_list): Removed the test on faked RNGs.
|
||||
(is_insecure): Removed.
|
||||
* g10.c (--quick-random): Removed this option.
|
||||
|
||||
* Replaced all PUBKEY_ALGO_xxx by GCRY_PK_xxxx.
|
||||
|
||||
* misc.c (pubkey_algo_npkey): New as a wrapper around the gcry fucntion.
|
||||
(pubkey_algo_nskey): Ditto.
|
||||
(pubkey_algo_nsig): Ditto.
|
||||
(pubkey_algo_nenc): Ditto.
|
||||
|
||||
* Makefile.am (basicdefs.h): Added.
|
||||
(install-data-local): Removed the handling for historic gpgm.
|
||||
|
||||
* misc.c (openpgp_cipher_test_algo): New.
|
||||
(openpgp_pk_test_algo): New.
|
||||
(openpgp_md_test_algo): New.
|
||||
|
||||
* g10.c (build_list): Changed to use the new functions from libgcrypt.
|
||||
|
||||
* ringedit.c (enum_keyblocks): Set .rt to 0 on open.
|
||||
|
||||
* encode.c (encode_simple): Use new CTB when we don't have the
|
||||
length of the file. This is somewhat strange as the comment above
|
||||
indicates that this part is actually fixed for PGP 5 - maybe I simply
|
||||
lost the source line, tsss.
|
||||
|
||||
* sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:"
|
||||
line. Those headers are now only _not_ printed when there are
|
||||
only old-style keys _and_ all hashs are MD5.
|
||||
|
||||
(clearsign_file): Use gcry_md_test_algo() and gcry_md_algo_name().
|
||||
|
||||
* openfile.c (make_outfile_name): Use case-insenstive compare for
|
||||
DOS systems. Add ".pgp" to the list of know extensions.
|
||||
(open_outfile): For DOS systems try to replace the suffix instead of
|
||||
appending it.
|
||||
|
||||
* encr-data.c (decrypt_data): Reset error on a weak key.
|
||||
|
||||
* cipher.c: Replaced the cipher and digest functions by the gcry_ ones.
|
||||
* seckey-cert.c: Ditto.
|
||||
* seskey.c: Ditto.
|
||||
* g10.c (print_mds): Replaced digst functions with the new gcry_ ones.
|
||||
* keyid.c: Ditto.
|
||||
* mainproc.c: Ditto.
|
||||
* passphrase.c: Ditto.
|
||||
* sig-check.c: Ditto.
|
||||
* sign.c: Ditto.
|
||||
|
||||
* pkclist.c (do_edit_ownertrust): Made the answer string const.
|
||||
|
||||
* basicdefs.h: New. Move some defs and decl to this header.
|
||||
|
||||
* openfile.c (open_outfile): Fixed the 8dot3 handling.
|
||||
|
||||
* passphrase.c (passphrase_to_dek): Print uid using utf8 func.
|
||||
* delkey.c (delete_key): Ditto.
|
||||
* pkclist.c (show_paths,do_edit_ownertrust,do_we_trust): Ditto
|
||||
(do_we_trust_pre): Ditto.
|
||||
* trustdb.c (print_user_id,check_uidsigs): Ditto.
|
||||
* revoke.c (gen_revoke,ask_revoke_sig): Ditto.
|
||||
|
||||
* filter.h: Changed cipher handle types to the the GCRY_xxx ones.
|
||||
replaces include cipher by system header include gcrypt.h.
|
||||
* cipher.c: replaced the cipher functions by the gcry_ ones.
|
||||
Ditto for the md functions.
|
||||
|
||||
* misc.c (map_gcry_rc): New.
|
||||
|
||||
Wed Jun 28 11:54:44 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* armor.c (armor_filter): Set sigclass to 0 in case of non-dash-escaped
|
||||
clearsig. This makes this mode work again.
|
||||
|
||||
* mainproc.c (proc_tree): Fixed handling of one-pass-sig packets in textmode.
|
||||
Disabled the ugly workaround for PGP 5 - let's see whether thi breaks less
|
||||
cases. Found by Ted Cabeen.
|
||||
|
||||
* options.h (DBG_HASHING): New. All commented md_start_debug are now
|
||||
controlled by this debug option.
|
||||
|
||||
* sign.c (print_status_sig_created): New and called from 2 places.
|
||||
|
||||
* keygen.c (gen_rsa): New, but commented.
|
||||
(ask_algo): Commented support for RSA.
|
||||
|
||||
* seckey-cert.c (protect_secret_key): Started to fix the code for v4 RSA
|
||||
keys - it is not solved yet. However, we have time until, Sep 20th ;)
|
||||
|
||||
Wed Jun 14 12:27:09 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* status.c (init_shm_coprocessing): Changed the sequence of the get,attach
|
||||
to cope with the changes in newer Linux kernels. This bug has been found
|
||||
by <dmitri@advantrix.com> who also proposed this solution. Hopefully
|
||||
this does not break gpg on to many systems.
|
||||
|
||||
* cipher.c (write_header): Protect the IV with the MDC too.
|
||||
* encr-data.c (decrypt_data): Likewise.
|
||||
|
||||
Fri Jun 9 10:09:52 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* g10.c: New options --no-auto-key-retrieve
|
||||
* options.h (auto_key_retrieve): New.
|
||||
* mainproc.c (check_sig_and_print): Implemented that.
|
||||
|
||||
Wed Jun 7 19:19:09 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* sig-check.c (do_check): Use EMULATE_MDENCODE also on v4 paclets.
|
||||
|
||||
Wed Jun 7 17:25:38 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* cipher.c (write_header): Use plain CFB mode for MDC encrypted packets.
|
||||
* encr-data.c (decrypt_data): Ditto.
|
||||
|
||||
Mon Jun 5 23:41:54 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* seskey.c (do_encode_md, encode_md_value): Add new arg v3compathack to work
|
||||
around a bug in old versions.
|
||||
* sig-check.c (do_check): use the aboved workaround when enabled.
|
||||
* g10.c: New option --emulate-md-decode-bug
|
||||
|
||||
Mon Jun 5 12:37:43 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* build-packet.c (do_mdc): New.
|
||||
(do_encrypted_mdc): Changed for the new proposal.
|
||||
* parse-packet.c (parse_mdc): New.
|
||||
(parse_encrypted): Fixed for the new proposal.
|
||||
* packet.h (PKT_MDC): New.
|
||||
* cipher.c (cipher_filter): Build the MDC packet here.
|
||||
* g10.c (main): Enable --force-mdc.
|
||||
* encr-data.c (mdc_decode_filter): Fixed for new MDC method
|
||||
|
||||
* options.h(rfc2440): New.
|
||||
* g10.c (main): Changed the selected values for --openpgp to not include
|
||||
optional algorithms.
|
||||
|
||||
Thu May 18 11:38:54 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* keyedit.c (keyedit_menu): Add a keyword arg to the prompt.
|
||||
|
||||
* status.c, status.h: Added 3 new status tokens.
|
||||
* status.c (do_get_from_fd): New.
|
||||
(cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt,
|
||||
cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work
|
||||
with the new function.
|
||||
* g10.c: Add new option --command-fd.
|
||||
|
||||
* status.c (progress_cb): New.
|
||||
(set_status_fd): Register progress functions
|
||||
|
||||
Fri May 12 14:01:20 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* delkey.c (delete_key): Add 2 new status messages
|
||||
* status.c, status.h (STATUS_DELETE_PROBLEM): New.
|
||||
|
||||
Fixed years of copyright in all source files.
|
||||
|
||||
Mon May 1 17:08:14 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* trustdb.c (propagate_validity): Fixed the bug that only one uid
|
||||
gets fully trusted even when all are signed by an ultimate key.
|
||||
|
||||
Mon May 1 15:38:04 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* getkey.c (key_byname): Always returned a defined context. Fixed
|
||||
a segv for invalid user id specifications. Reported by Walter Koch.
|
||||
|
||||
* getkey.c (get_user_id): I18ned "no user id" string. By Walter.
|
||||
|
||||
* pkclist.c (do_show_revocation_reason): Typo fixes.
|
||||
* helptext.c: Ditto.
|
||||
|
||||
* armor.c (armor_filter): Fixed some CRLF issues. By Mike McEwan.
|
||||
|
||||
Fri Apr 14 19:37:08 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* pkclist.c (do_show_revocation_reason): New.
|
||||
(show_revocation_reason): New and called at various places.
|
||||
|
||||
* g10.c (main): Fixed small typo.
|
||||
|
||||
* pkclist.c (do_we_trust): Act on always_trust but not for revoked
|
||||
keys. Suggested by Chip Salzenberg.
|
||||
|
||||
* g10.c: New option --lock-never.
|
||||
|
||||
* ringedit.c (get_writable_keyblock_file): New.
|
||||
* keygen.c (do_generate_keypair): Use this instead of the hardwired one.
|
||||
|
||||
* keygen.c (ask_user_id): Check that the email address is in the
|
||||
correct field. Suggested by Christian Kurz.
|
||||
|
||||
Mon Apr 10 13:34:19 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* keyedit.c (show_key_with_all_names): s/sbb/ssb/
|
||||
|
||||
Tue Mar 28 14:26:58 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* trustdb.c (verify_own_keys): Do not print warning about unprotected
|
||||
key when in quiet mode.
|
||||
|
||||
Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
|
||||
Wed Mar 22 13:50:24 CET 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* build-paket.c (do_user_id): Save offset where name has been stored.
|
||||
* mainproc.c (print_userid): Do UTF8 conversion before printing.
|
||||
* import.c (import_one): Ditto.
|
||||
(import_secret_one): Ditto.
|
||||
(delete_inv_parts): Ditto.
|
||||
|
||||
* ringedit.c : Add new access method KBXF
|
||||
Thu Mar 16 16:20:23 CET 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* kbxfile.c: New.
|
||||
* keylist.c (print_key_data): Handle a NULL pk gracefully.
|
||||
|
||||
Mon Feb 21 22:43:01 CET 2000 Werner Koch <wk@>
|
||||
* getkey.c (merge_one_pk_and_selfsig): Fixed silly code for
|
||||
getting the primary keys keyID but kept using the one from the
|
||||
subkey.
|
||||
* pubkey-enc.c (get_it): Print a note for expired subkeys.
|
||||
|
||||
* kbx.h: New.
|
||||
* kbxblob.c: Started to work on the keybox stuff.
|
||||
* getkey.c (has_expired): New.
|
||||
(subkeys_expiretime): New.
|
||||
(finish_lookup): Check for expired subkeys needed for encryption.
|
||||
(merge_keys_and_selfsig): Fixed expiration date merging for subkeys.
|
||||
|
||||
Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
* keylist.c (list_keyblock): Print expiration time for "sub".
|
||||
(list_one): Add missing merging for public keys.
|
||||
* mainproc.c (list_node): Ditto.
|
||||
|
||||
* keygen.c (gen_dsa): Modified to work with gcry_pk_genkey.
|
||||
2000-03-14 13:49:38 Werner Koch (wk@habibti.openit.de)
|
||||
|
||||
* Removed dummy-cipher.h from all files.
|
||||
* keygen.c (keyedit_menu): Do not allow to use certain commands
|
||||
while the secret key is selected.
|
||||
|
||||
Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
2000-03-09 12:53:09 Werner Koch (wk@habibti.openit.de)
|
||||
|
||||
* keygen.c (gen_elg): Modified to work with gcry_pk_genkey.
|
||||
(key_from_sexp): New.
|
||||
(factors_from_sexp): New.
|
||||
* keygen.c (ask_expire_interval): Movede parsig to ...
|
||||
(parse_expire_string): ... this new function. And some new control
|
||||
commands.
|
||||
(proc_parameter_file): Add expire date parsing.
|
||||
(do_generate_keypair): Allow the use of specified output files.
|
||||
|
||||
* g10.c : Renamed to ...
|
||||
* gpg.c : ... this
|
||||
* Makefile.am: And fixed it here.
|
||||
2000-03-08 10:38:38 Werner Koch (wk@habibti.openit.de)
|
||||
|
||||
* Changed all "g10_"/"GPG_" prefixes to "gpg_"/"GPG_".
|
||||
* keygen.c (ask_algo): Removed is_v4 return value and the commented
|
||||
code to create Elg keys in a v3 packet. Removed the rounding
|
||||
of key sizes here.
|
||||
(do_create): Likewise removed arg v4_packet.
|
||||
(gen_elg): Likewise removed arg version. Now rounding keysizes here.
|
||||
(gen_dsa): Rounding keysize now here.
|
||||
(release_parameter_list): New
|
||||
(get_parameter*): New.
|
||||
(proc_parameter_file): New.
|
||||
(read_parameter_file): New.
|
||||
(generate_keypair): Splitted. Now uses read_parameter_file when in
|
||||
batch mode. Additional argument to specify a parameter file.
|
||||
(do_generate_keypair): Main bulk of above fucntion and uses the
|
||||
parameter list.
|
||||
(do_create): Don't print long notice in batch mode.
|
||||
* g10.c (main): Allow batched key generation.
|
||||
|
||||
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* misc.c (mpi_read_opaque): Fixed double counting.
|
||||
* pubkey-enc.c (get_it): Print a note about unknown cipher algos.
|
||||
|
||||
* seckey-cert.c (do_check): Removed buffer and the unmotivated free
|
||||
on it.
|
||||
* g10.c (opts): Add a note to the help listing about the man page
|
||||
and removed some options from the help listing.
|
||||
|
||||
* pubkey-enc.c (pk_decrypt): New wrapper for the gcry_ function.
|
||||
* seckey-cert.c (pk_check_secret_key): Likewise.
|
||||
* encode.c (pk_encrypt): Likewise.
|
||||
* keyedit.c (print_and_check_one_sig): Use a new function to truncate
|
||||
the output of the user ID. Suggested by Jan-Benedict Glaw.
|
||||
|
||||
* parse-packet.c (parse_key): Fixed case of unencrypted secret keys.
|
||||
Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
* helptext.c: typo fix.
|
||||
|
||||
* misc.c (mpi_print): Use gcry_mpi_aprint.
|
||||
(pubkey_nbits): Kludge to use the gcry_pk_ API.
|
||||
Thu Feb 17 13:39:32 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* seskey.c (encode_session_key): Replaced mpi_set_buffer by *_scan.
|
||||
(do_encode_md): Ditto.
|
||||
(encode_md_value): Ditto.
|
||||
* seckey-cert.c (protect_secret_key): Ditto.
|
||||
* comment.c (make_mpi_comment_node): Replaced mpi_get_buffer by _print.
|
||||
* pubkey-enc.c (get_it): Ditto.
|
||||
* sig-check.c (do_signature_check): Ditto.
|
||||
* revoke.c: Removed a bunch of commented code.
|
||||
|
||||
Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
* packet.h (SIGSUBPKT_REVOC_REASON): New.
|
||||
* build-packet.c (build_sig_subpkt): Support new sub packet.
|
||||
* parse-packet.c (parse_one_sig_subpkt): Ditto.
|
||||
(dump_sig_subpkt): Ditto.
|
||||
* revoke.c (ask_revocation_reason): New.
|
||||
(release_revocation_reason_info): New.
|
||||
(revocation_reason_build_cb): New.
|
||||
(gen_revoke): Ask for reason.
|
||||
* main.h (struct revocation_reason_info): Add declaration.
|
||||
* keyedit.c (menu_revsig): Add support for revocation reason.
|
||||
(menu_revkey): Ditto.
|
||||
(sign_uid_mk_attrib): Renamed to ...
|
||||
(sign_mk_attrib): ... this, made static and add support for reasons.
|
||||
|
||||
* keyid.c (do_fingerprint_md): Replaced mpi_get_buffer by gcry_mpi_print.
|
||||
(v3_keyid): New.
|
||||
(keyid_from_sk): And use it here.
|
||||
(keyid_from_pk): Ditto.
|
||||
(fingerprint_from_sk): Ditto.
|
||||
(fingerprint_from_pk): Ditto.
|
||||
Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* misc.c (mpi_print): New.
|
||||
* build-packet.c (build_packet): Fixed fixing of old comment packets.
|
||||
|
||||
* misc.c (checksum_mpi): Now uses gcry_mpi_print to get the data.
|
||||
* import.c (import_keys): Fixed importing from stdin when called with
|
||||
nnames set to zero as it normally happens.
|
||||
|
||||
* seckey-cert.c (do_check): Replaced mpi_read_from_buffer.
|
||||
Mon Feb 14 14:30:20 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* sig-check.c (check_key_signature2): Add new arg r_expired.
|
||||
(do_signature_check): New arg to pass it down to ...
|
||||
(do_check): New arg r-expire which is set when the signature
|
||||
has expired.
|
||||
* trustdb.c (check_sig_record): Set SIGF_EXPIRED flag and set
|
||||
the expiretime to zero so that thi signature will not be checked
|
||||
anymore.
|
||||
|
||||
Fri Feb 11 17:44:40 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* g10.c (g10_exit): Update the random seed_file.
|
||||
(main): Set the random seed file. New option --no-random-seed-file.
|
||||
|
||||
Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* keyedit.c (menu_expire): Fixed segv due to unitialized sub_pk.
|
||||
By Rémi.
|
||||
|
||||
Thu Feb 10 11:39:41 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* keylist.c (list_keyblock): Don't print warnings in the middle of
|
||||
regulat output lines. By Rémi.
|
||||
|
||||
* sig-check.c: Include options.h
|
||||
|
||||
Wed Feb 9 15:33:44 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* gpg.c: New option --ignore-time-conflict
|
||||
* sig-check.c (do_check): Implemented this option.
|
||||
* trustdb.c (check_trust): Ditto.
|
||||
* sign.c (do_sign): Ditto.
|
||||
* keygen.c (generate_subkeypair): Ditto.
|
||||
|
||||
* encode.c (encode_simple): use iobuf_cancel after open failure.
|
||||
Reported by Huy Le.
|
||||
|
||||
Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* packet.h (STRING2KEY): Changed mode from byte to int.
|
||||
* parse-packet.c (parse_key): Add the special GNU protection stuff
|
||||
* build-packet.c (so_secret_key): Ditto.
|
||||
* seckey-cert.c (do_check): Ditto.
|
||||
* keyedit.c (change_passphrase): Ditto.
|
||||
* export.c (export_secsubkeys): New.
|
||||
(do_export_stream): Hack to export the primary key using mode 1001.
|
||||
* g10.c: New command --export-secret-subkeys
|
||||
|
||||
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* armor.c (is_armored): Check for 1-pass-sig packets. Reported by
|
||||
David Hallinan <hallinan@rtd.com>.
|
||||
(armor_filter): Replaced one LF by the LF macro. Reported by
|
||||
Wolfgang Redtenbacher.
|
||||
|
||||
Wed Jan 5 11:51:17 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* g10.c (main): Reset new global flag opt.pgp2_workarounds
|
||||
when --openpgp is used.
|
||||
* mainproc.c (proc_plaintext): Do the PGP2,5 workarounds only
|
||||
when the global flag is set.
|
||||
(proc_tree): Ditto.
|
||||
* textfilter.c (copy_clearsig_text): Ditto.
|
||||
* armor.c (armor_filter): Ditto.
|
||||
|
||||
* g10.c: New option --list-only
|
||||
* mainproc.c (proc_tree): Don't do it if opt.list_only is active.
|
||||
(proc_pubkey_enc): Implement option.
|
||||
|
||||
* status.h, status.c ({BEGIN,END}_{EN,DE}CRYPTION): New.
|
||||
* cipher.c (cipher_filter): New status outputs.
|
||||
* mainproc.c (proc_encrypted): New status outputs.
|
||||
|
||||
Fri Dec 31 14:08:15 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* armor.c (armor_filter): Made the "Comment:" header translatable.
|
||||
|
||||
Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
* hkp.c (hkp_import): Make sure that the program does not return
|
||||
success when there is a connection problem. Reported by Phillip Jones.
|
||||
|
||||
* seckey-cert.c: Removed obsolete mpi_*_protect_flag.
|
||||
* parse-packet.c: Ditto.
|
||||
Sun Dec 19 15:22:26 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* misc.c (mpi_read): Removed the secure argumet becuase it is
|
||||
never used. Changed all Callers.
|
||||
(mpi_read_opaque): New.
|
||||
(mpi_write_opaque): New.
|
||||
* parse-packet.c (parse_key): Use the opaque method also for
|
||||
v3 keys.
|
||||
* build-packet.c (do_secret_key): Likewise.
|
||||
* armor.c (LF): Use this new macro at all places where a line LF
|
||||
is needed. This way DOSish textfiles should be created when the
|
||||
input data is also in dos mode.
|
||||
* sign.c (LF): Ditto.
|
||||
* textfilter.c (LF): Ditto.
|
||||
(copy_clearsig_text): Disabled the forcing of CR,LF sequences
|
||||
for DOS systems.
|
||||
|
||||
* g10.c (main): Check libgcrypt version.
|
||||
* plaintext.c (handle_plaintext): Fixes for line endings on DOS.
|
||||
and react on a LF in cleartext.
|
||||
* armor.c (fake_packet): Restore the original line ending after
|
||||
removing trailing spaces.
|
||||
|
||||
* packet.h: replaced inclusion of mpi.h by a plain typeedef of the
|
||||
gcry_mpi structure and removed all inclusions of "mpi.h" in all
|
||||
sources.
|
||||
* signal.c (got_fatal_signal): DOS fix.
|
||||
|
||||
Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* mainproc.c (print_failed_pkenc): Fix for unknown algorithm.
|
||||
Found by fygrave@epr0.org.
|
||||
|
||||
Thu Dec 9 10:31:05 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* hkp.c: i18n the strings.
|
||||
|
||||
Sat Dec 4 15:32:20 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* trustdb.c (verify_key): Shortcut for ultimately trusted keys.
|
||||
|
||||
Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* pkclist.c (build_pk_list): Validate the trust using the namehash
|
||||
if this one has been set by the key lookup.
|
||||
|
||||
* g10.c: Add --delete-secret-key to the help page.
|
||||
|
||||
* g10.c (main): Changed the default homedir to "~/.gnupg-test" so
|
||||
that we don't mess up with the stable version.
|
||||
* openfile.c (copy_options_file): Made static.
|
||||
(try_make_homedir): New.
|
||||
* ringedit.c (add_keyblock_resource): Use the try_make_hoemdir logic.
|
||||
* tdbio.c (tdbio_set_dbname): Likewise.
|
||||
|
||||
* misc.c (mpi_write): New.
|
||||
(mpi_write): New.
|
||||
* keygen.c (generate_user_id): Use m_alloc_clear() here. We should
|
||||
better use an allocation function specific to the user_id packet.
|
||||
|
||||
* misc.c (checksum_u16_nobug): Removed.
|
||||
(checksum_mpi_counted_nbits): Renamed to ...
|
||||
(checksum_mpi): ... this to superseed the old one. Changed all
|
||||
callers. This is because we do not emulate the old gpg bug anymore.
|
||||
* g10.c (oEmuChecksumBug): Removed.
|
||||
* keygen.c (keygen_add_std_prefs): Changed symmetric preferences
|
||||
to include Blowfish again. This is due to it's better speed compared
|
||||
to CAST5.
|
||||
|
||||
Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
* g10.c (strusage): Print the home directory.
|
||||
|
||||
* g10.c (register_extension): New...
|
||||
(main): Use it here instead of register_cipher_extesnion.
|
||||
(strusage): s/strusage/my_strusage/ . Made static.
|
||||
(main): Use set_strusage().
|
||||
* armor.c (armor_filter): Take action on the cancel control msg.
|
||||
* filter.h (armor_filter_context_t): Add cancel flag.
|
||||
|
||||
Mon Nov 29 21:52:11 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* g10.c: New option --fast-list-mode ..
|
||||
* keylist.c (list_keyblock): .. and implemented.
|
||||
* mainproc.c (list_node): Ditto.
|
||||
|
||||
* import.c (mark_non_selfsigned_uids_valid): Fixed the case that there
|
||||
is a uid without any packet following.
|
||||
|
||||
Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* mainproc.c (proc_plaintext): Never enable the hash processing
|
||||
when skip_verify is active.
|
||||
|
||||
* armor.c (parse_header_line): Stop parsing on a WS line too.
|
||||
Suggested by Aric Cyr.
|
||||
|
||||
* tdbdump.c (HEXTOBIN): Changed the name of the argument, so that
|
||||
traditional cpp don't mess up the macros. Suggested by Jos Backus.
|
||||
|
||||
* armor.c (parse_header_line): Stop parsing on a only WS line too.
|
||||
Suggested by Aric Cyr.
|
||||
|
||||
Mon Nov 15 21:36:02 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* misc.c (pull_in_libs): Removed.
|
||||
|
||||
Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* mainproc.c (list_node): Print the PK algo in the --with-colon mode.
|
||||
* keylist.c (list_keyblock): Ditto.
|
||||
|
||||
* misc.c (pull_in_libs): Removed pull in of g10c.
|
||||
* signal.c (got_fatal_signal): Found the reason why exit(8) did not
|
||||
work - it is better to set the disposition back to default before
|
||||
raising the signal. Print the notice on stderr always.
|
||||
|
||||
* misc.c (map_gcry_rc): Removed here and chnaged all users.
|
||||
Fri Nov 12 20:33:19 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* getkey.c: Replaced check_pubkey_algo by openpgp_pk_test_algo.
|
||||
* import.c (delete_inv_parts): Ditto.
|
||||
* pkclist.c: Ditto.
|
||||
* skclist.c: Ditto.
|
||||
* pubkey-enc.c: Ditto.
|
||||
* g10.c (make_username): Swapped the logic.
|
||||
* keylist.c (public_key_list): Now takes a STRLIST as arg and moved
|
||||
the creation ot this list to the caller, so that he can copy with
|
||||
UTF-conversion of user IDs. Changed all callers.
|
||||
(secret_key_list): Likewise.
|
||||
|
||||
* g10.c (main): Replaced the function to diable PK algos.
|
||||
* getkey.c (get_user_id_string_native): New and ...
|
||||
* encode.c (write_pubkey_enc_from_list): ... use it here.
|
||||
|
||||
* g10.c (main): Replaced get_random_bits by gcry_random_bytes.
|
||||
* seskey.c (encode_session_key): Likewise.
|
||||
(make_session_key): Renamed randomize_buffer to gcry_randomize
|
||||
and use the GCRY_xxx_RANDOM constants.
|
||||
* cipher.c (write_header): Ditto.
|
||||
* passphrase.c (hash_passphrase): Ditto.
|
||||
* seckey-cert.c (protect_secret_key): Ditto.
|
||||
* pubring.asc: Updated.
|
||||
|
||||
* getkey.c (find_by_name): Replaced rmd160_hash_buffer
|
||||
by gcry_md_hash_buffer.
|
||||
* packet.h (PKT_PHOTO_ID): New.
|
||||
* parse-packet.c (parse_photo_id): New.
|
||||
* build-packet.c (do_user_id: Handle photo IDs.
|
||||
(build_packet): Change CTB for photo IDs
|
||||
* free-packet.c (free_user_id): Release memory used for photo IDs
|
||||
* sig-check.c (hash_uid_node): Handle photo IDs too.
|
||||
* trustdb.c (print_uid_from_keyblock): Hash photo ID.
|
||||
(make_uid_records): Ditto.
|
||||
* getkey.c (find_by_name): Ditto.
|
||||
* keyedit.c (show_prefs): Ditto.
|
||||
* keylist.c (list_keyblock): Ditto.
|
||||
* trustdb.c (print_uid_from_keyblock): Ditto.
|
||||
(make_uid_records): Ditto.
|
||||
|
||||
* skclist.c (build_sk_list): Removed the test on faked RNGs.
|
||||
(is_insecure): Removed.
|
||||
* g10.c (--quick-random): Removed this option.
|
||||
Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* Replaced all PUBKEY_ALGO_xxx by GCRY_PK_xxxx.
|
||||
* keygen.c (ask_expire_interval): Print a warning for systems
|
||||
with a signed 32 time_t if the exiration time is beyoind 2038.
|
||||
|
||||
* misc.c (pubkey_algo_npkey): New as a wrapper around the gcry fucntion.
|
||||
(pubkey_algo_nskey): Ditto.
|
||||
(pubkey_algo_nsig): Ditto.
|
||||
(pubkey_algo_nenc): Ditto.
|
||||
Fri Oct 8 20:40:50 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
Tue Oct 26 20:03:44 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
* ringedit.c (enum_keyblocks): The last fix way really stupid;
|
||||
reverted and set rt to Unknown.
|
||||
|
||||
* Makefile.am (basicdefs.h): Added.
|
||||
(install-data-local): Removed the handling for historic gpgm.
|
||||
Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
* ringedit.c (enum_keyblocks): Zero the entire kbpos out on open.
|
||||
|
||||
* misc.c (openpgp_cipher_test_algo): New.
|
||||
(openpgp_pk_test_algo): New.
|
||||
(openpgp_md_test_algo): New.
|
||||
* g10.c (oEntropyDLL): Removed option.
|
||||
(main): Made the warning on development versions more verbose.
|
||||
|
||||
* g10.c (build_list): Changed to use the new functions from libgcrypt.
|
||||
* g10.c (oHonorHttpProxy): New option.
|
||||
* hkp.c (hkp_ask_import,hkp_export): Implement this option.
|
||||
* options.skel: Enable this option for new installations
|
||||
|
||||
* ringedit.c (enum_keyblocks): Set .rt to 0 on open.
|
||||
Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* import.c (import_keys): Changed calling interface, adjusted caller.
|
||||
(import): Moved printing of stats out ...
|
||||
(print_stats): New. ... to here.
|
||||
(import_keys_stream): Call stats print here.
|
||||
(import_keys): Print stats as totals for all files.
|
||||
|
||||
* tdbio.h (DIRF_NEWKEYS): New
|
||||
* tdbio.c (tdbio_dump_record): Print the new flag.
|
||||
* trustdb.c (check_trust_record): New arg sigs_only. Adapted all
|
||||
callers.
|
||||
(do_update_trust_record): Removed recheck arg and add a new sigs_only
|
||||
do we can later improve on the performance. Changed all callers too.
|
||||
(check_trustdb): Evalutate the new flag and add a status output.
|
||||
Do a check when the dir record has not been checked.
|
||||
(build_cert_tree): Evaluate the new flag.
|
||||
(check_trust): Ditto. Do a trust_record check, when the dir record
|
||||
is not marked as checked.
|
||||
(mark_fresh_keys): New.
|
||||
(clear_lid_table): New.
|
||||
(sync_trustdb): New.
|
||||
* import.c (import_keys): Call sync_trustdb() after processing.
|
||||
(import_keys_stream): Ditto.
|
||||
* tdbdump.c (import_ownertrust): Ditto.
|
||||
|
||||
* import.c (import_revoke_cert): Notify the trust DB.
|
||||
(do_update_trust_record): Use |= to set the REVOKED bit and not &=;
|
||||
shame on me for this bad copy+paste introduced bug.
|
||||
(do_we_trust): Add trustmask to allow revoked key override to work.
|
||||
Chnaged are to allow return of a mofified trustlevel. Adapted the
|
||||
one caller.
|
||||
|
||||
* g10.c: New options --emulate-3des-s2k-bug
|
||||
* passphrase.c (hash_passphrase): Implemented above.
|
||||
|
||||
* mainproc.c (proc_tree): Check for standalone signatures.
|
||||
(do_check_sig): Print a notice for a standalone revocation
|
||||
(check_sig_and_print): Do not print an error for unchecked standalone
|
||||
revocations.
|
||||
|
||||
Tue Sep 28 20:54:37 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* encode.c (encode_simple): Use new CTB when we don't have the
|
||||
length of the file. This is somewhat strange as the comment above
|
||||
indicates that this part is actually fixed for PGP 5 - maybe I simply
|
||||
lost the source line, tsss.
|
||||
|
||||
* sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:"
|
||||
line. Those headers are now only _not_ printed when there are
|
||||
only old-style keys _and_ all hashs are MD5.
|
||||
* armor.c (armor_filter): Set a flag if no OpenPGP data has been found.
|
||||
* verify.c (verify_signatures): Add an error helptext.
|
||||
|
||||
(clearsign_file): Use gcry_md_test_algo() and gcry_md_algo_name().
|
||||
|
||||
* openfile.c (make_outfile_name): Use case-insenstive compare for
|
||||
DOS systems. Add ".pgp" to the list of know extensions.
|
||||
(open_outfile): For DOS systems try to replace the suffix instead of
|
||||
appending it.
|
||||
|
||||
* encr-data.c (decrypt_data): Reset error on a weak key.
|
||||
|
||||
* cipher.c: Replaced the cipher and digest functions by the gcry_ ones.
|
||||
* seckey-cert.c: Ditto.
|
||||
* seskey.c: Ditto.
|
||||
* g10.c (print_mds): Replaced digst functions with the new gcry_ ones.
|
||||
* keyid.c: Ditto.
|
||||
* mainproc.c: Ditto.
|
||||
* passphrase.c: Ditto.
|
||||
* sig-check.c: Ditto.
|
||||
* sign.c: Ditto.
|
||||
|
||||
* pkclist.c (do_edit_ownertrust): Made the answer string const.
|
||||
|
||||
* basicdefs.h: New. Move some defs and decl to this header.
|
||||
Thu Sep 23 19:24:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* openfile.c (open_outfile): Fixed the 8dot3 handling.
|
||||
|
||||
@ -236,18 +715,34 @@ Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
* trustdb.c (print_user_id,check_uidsigs): Ditto.
|
||||
* revoke.c (gen_revoke,ask_revoke_sig): Ditto.
|
||||
|
||||
Sat Sep 18 12:16:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
Thu Sep 23 09:52:58 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* filter.h: Changed cipher handle types to the the GCRY_xxx ones.
|
||||
replaces include cipher by system header include gcrypt.h.
|
||||
* cipher.c: replaced the cipher functions by the gcry_ ones.
|
||||
Ditto for the md functions.
|
||||
* verify.c (print_file_status): New.
|
||||
(verify_one_file): Moved status print to th new fnc. Add error status.
|
||||
* status.c, status.h (STATUS_FILE_ERROR): New
|
||||
|
||||
* misc.c (map_gcry_rc): New.
|
||||
Wed Sep 22 10:14:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* openfile.c (make_outfile_name): Use case-insenstive compare for
|
||||
DOS systems. Add ".pgp" to the list of know extensions.
|
||||
(open_outfile): For DOS systems try to replace the suffiy instead of
|
||||
appending it.
|
||||
|
||||
* status.c, status.h: Add STATUS_FILE_{START,DONE}.
|
||||
* verify.c (verify_one_file): Emit these new stati.
|
||||
|
||||
* sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:"
|
||||
line. Those headers are now only _not_ printed when there are
|
||||
only old-style keys _and_ all hashs are MD5.
|
||||
|
||||
Mon Sep 20 12:24:41 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
|
||||
* verify.c (verify_files, ferify_one_file): New.
|
||||
* g10.c: New command --verify-files
|
||||
|
||||
Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
|
||||
* g10.c: Add UK spelling as alias for armor options ;-)
|
||||
|
||||
* import.c (append_uid): Fixed a SEGV when there is no selfsig and
|
||||
@ -256,16 +751,13 @@ Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
|
||||
* g10.c: New option --entropy-dll-name
|
||||
|
||||
Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
|
||||
* signal.c (got_fatal_signal): Print message using write(2) and
|
||||
only for development versions.
|
||||
|
||||
|
||||
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* tdbio.c (tdbio_set_dbname): Use mkdir macro
|
||||
|
@ -6,10 +6,11 @@ OMIT_DEPENDENCIES = zlib.h zconf.h
|
||||
LDFLAGS = -static @LDFLAGS@ @DYNLINK_LDFLAGS@
|
||||
# we need to add libutil.la a second time because we have to resolve
|
||||
# gpg_log_ in some libjnlib modules. - very ugly - should be removed soon.
|
||||
needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la ../jnlib/libjnlib.la ../util/libutil.la
|
||||
needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la \
|
||||
../jnlib/libjnlib.la ../util/libutil.la
|
||||
|
||||
#noinst_PROGRAMS = gpgd
|
||||
bin_PROGRAMS = gpg kbxutil
|
||||
bin_PROGRAMS = gpg kbxutil
|
||||
|
||||
common_source = \
|
||||
build-packet.c \
|
||||
|
63
g10/armor.c
63
g10/armor.c
@ -1,5 +1,5 @@
|
||||
/* armor.c - Armor flter
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -37,6 +37,11 @@
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#define LF "\r\n"
|
||||
#else
|
||||
#define LF "\n"
|
||||
#endif
|
||||
|
||||
#define MAX_LINELEN 20000
|
||||
|
||||
@ -162,6 +167,7 @@ is_armored( const byte *buf )
|
||||
switch( pkttype ) {
|
||||
case PKT_MARKER:
|
||||
case PKT_SYMKEY_ENC:
|
||||
case PKT_ONEPASS_SIG:
|
||||
case PKT_PUBLIC_KEY:
|
||||
case PKT_SECRET_KEY:
|
||||
case PKT_PUBKEY_ENC:
|
||||
@ -485,13 +491,26 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
|
||||
if( !maxlen )
|
||||
afx->truncated++;
|
||||
if( !afx->not_dash_escaped ) {
|
||||
int crlf;
|
||||
p = afx->buffer;
|
||||
n = afx->buffer_len;
|
||||
crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
|
||||
|
||||
/* PGP2 does not treat a tab as white space character */
|
||||
afx->buffer_len =
|
||||
trim_trailing_chars( afx->buffer, afx->buffer_len,
|
||||
afx->buffer_len = trim_trailing_chars( p, n,
|
||||
afx->pgp2mode ? " \r\n" : " \t\r\n");
|
||||
/* the buffer is always allocated with enough space to append
|
||||
* a CR, LF, Nul */
|
||||
afx->buffer[afx->buffer_len++] = '\r';
|
||||
* the removed [CR], LF and a Nul
|
||||
* The reason for this complicated procedure is to keep at least
|
||||
* the original tupe of lineending - handling of the removed
|
||||
* trailing spaces seems to be impossible in our method
|
||||
* of faking a packet; either we have to use a temporary file
|
||||
* or calculate the hash here in this module and somehow find
|
||||
* a way to send the hash down the processing line (well, a special
|
||||
* faked packet could do the job).
|
||||
*/
|
||||
if( crlf )
|
||||
afx->buffer[afx->buffer_len++] = '\r';
|
||||
afx->buffer[afx->buffer_len++] = '\n';
|
||||
afx->buffer[afx->buffer_len] = 0;
|
||||
}
|
||||
@ -819,7 +838,8 @@ armor_filter( void *opaque, int control,
|
||||
hashes &= 1|2|4|8;
|
||||
if( !hashes ) {
|
||||
hashes |= 4; /* default to MD 5 */
|
||||
afx->pgp2mode = 1;
|
||||
if( opt.pgp2_workarounds )
|
||||
afx->pgp2mode = 1;
|
||||
}
|
||||
n=0;
|
||||
do {
|
||||
@ -827,7 +847,7 @@ armor_filter( void *opaque, int control,
|
||||
buf[n++] = 0x90; /* old format, type 4, 1 length byte */
|
||||
buf[n++] = 13; /* length */
|
||||
buf[n++] = 3; /* version */
|
||||
buf[n++] = 0x01; /* sigclass 0x01 (canonical text mode)*/
|
||||
buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
|
||||
if( hashes & 1 ) {
|
||||
hashes &= ~1;
|
||||
buf[n++] = GCRY_MD_RMD160;
|
||||
@ -874,7 +894,7 @@ armor_filter( void *opaque, int control,
|
||||
#endif
|
||||
*ret_len = n;
|
||||
}
|
||||
else if( control == IOBUFCTRL_FLUSH ) {
|
||||
else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
|
||||
if( !afx->status ) { /* write the header line */
|
||||
const char *s;
|
||||
|
||||
@ -882,10 +902,10 @@ armor_filter( void *opaque, int control,
|
||||
log_bug("afx->what=%d", afx->what);
|
||||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, head_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----\n");
|
||||
iobuf_writestr(a, "-----" LF );
|
||||
if( !opt.no_version )
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")\n");
|
||||
PRINTABLE_OS_NAME ")" LF );
|
||||
|
||||
/* write the comment string or a default one */
|
||||
s = opt.comment_string ? opt.comment_string
|
||||
@ -902,16 +922,17 @@ armor_filter( void *opaque, int control,
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
iobuf_put(a, '\n' );
|
||||
iobuf_writestr(a, LF );
|
||||
}
|
||||
|
||||
if( afx->hdrlines )
|
||||
iobuf_writestr(a, afx->hdrlines);
|
||||
iobuf_put(a, '\n');
|
||||
iobuf_writestr(a, LF );
|
||||
afx->status++;
|
||||
afx->idx = 0;
|
||||
afx->idx2 = 0;
|
||||
afx->crc = CRCINIT;
|
||||
|
||||
}
|
||||
crc = afx->crc;
|
||||
idx = afx->idx;
|
||||
@ -936,7 +957,7 @@ armor_filter( void *opaque, int control,
|
||||
c = bintoasc[radbuf[2]&077];
|
||||
iobuf_put(a, c);
|
||||
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
|
||||
iobuf_put(a, '\n');
|
||||
iobuf_writestr(a, LF );
|
||||
idx2=0;
|
||||
}
|
||||
}
|
||||
@ -951,8 +972,13 @@ armor_filter( void *opaque, int control,
|
||||
if( !is_initialized )
|
||||
initialize();
|
||||
}
|
||||
else if( control == IOBUFCTRL_CANCEL ) {
|
||||
afx->cancel = 1;
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
if( afx->status ) { /* pad, write cecksum, and bottom line */
|
||||
if( afx->cancel )
|
||||
;
|
||||
else if( afx->status ) { /* pad, write cecksum, and bottom line */
|
||||
crc = afx->crc;
|
||||
idx = afx->idx;
|
||||
idx2 = afx->idx2;
|
||||
@ -975,13 +1001,13 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, '=');
|
||||
}
|
||||
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
|
||||
iobuf_put(a, '\n');
|
||||
iobuf_writestr(a, LF );
|
||||
idx2=0;
|
||||
}
|
||||
}
|
||||
/* may need a linefeed */
|
||||
if( idx2 )
|
||||
iobuf_put(a, '\n');
|
||||
iobuf_writestr(a, LF );
|
||||
/* write the CRC */
|
||||
iobuf_put(a, '=');
|
||||
radbuf[0] = crc >>16;
|
||||
@ -995,16 +1021,17 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, c);
|
||||
c = bintoasc[radbuf[2]&077];
|
||||
iobuf_put(a, c);
|
||||
iobuf_put(a, '\n');
|
||||
iobuf_writestr(a, LF );
|
||||
/* and the the trailer */
|
||||
if( afx->what >= DIM(tail_strings) )
|
||||
log_bug("afx->what=%d", afx->what);
|
||||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, tail_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----\n");
|
||||
iobuf_writestr(a, "-----" LF );
|
||||
}
|
||||
else if( !afx->any_data && !afx->inp_bypass ) {
|
||||
log_error(_("no valid OpenPGP data found.\n"));
|
||||
afx->no_openpgp_data = 1;
|
||||
write_status_text( STATUS_NODATA, "1" );
|
||||
}
|
||||
if( afx->truncated )
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* build-packet.c - assemble packets and write them
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,11 +24,11 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
@ -43,6 +43,7 @@ static u32 calc_plaintext( PKT_plaintext *pt );
|
||||
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
|
||||
static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
|
||||
static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
|
||||
static int do_mdc( IOBUF out, PKT_mdc *mdc );
|
||||
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
|
||||
static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
|
||||
static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
|
||||
@ -66,25 +67,31 @@ int
|
||||
build_packet( IOBUF out, PACKET *pkt )
|
||||
{
|
||||
int new_ctb=0, rc=0, ctb;
|
||||
int pkttype;
|
||||
|
||||
if( DBG_PACKET )
|
||||
log_debug("build_packet() type=%d\n", pkt->pkttype );
|
||||
assert( pkt->pkt.generic );
|
||||
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_OLD_COMMENT: pkt->pkttype = PKT_COMMENT; break;
|
||||
switch( (pkttype = pkt->pkttype) ) {
|
||||
case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
|
||||
case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
|
||||
case PKT_ENCRYPTED:
|
||||
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
|
||||
case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
|
||||
case PKT_USER_ID:
|
||||
if( pkt->pkt.user_id->photo )
|
||||
pkttype = PKT_PHOTO_ID;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if( new_ctb || pkt->pkttype > 15 ) /* new format */
|
||||
ctb = 0xc0 | (pkt->pkttype & 0x3f);
|
||||
if( new_ctb || pkttype > 15 ) /* new format */
|
||||
ctb = 0xc0 | (pkttype & 0x3f);
|
||||
else
|
||||
ctb = 0x80 | ((pkt->pkttype & 15)<<2);
|
||||
switch( pkt->pkttype ) {
|
||||
ctb = 0x80 | ((pkttype & 15)<<2);
|
||||
switch( pkttype ) {
|
||||
case PKT_PHOTO_ID:
|
||||
case PKT_USER_ID:
|
||||
rc = do_user_id( out, ctb, pkt->pkt.user_id );
|
||||
break;
|
||||
@ -114,6 +121,9 @@ build_packet( IOBUF out, PACKET *pkt )
|
||||
case PKT_ENCRYPTED_MDC:
|
||||
rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
|
||||
break;
|
||||
case PKT_MDC:
|
||||
rc = do_mdc( out, pkt->pkt.mdc );
|
||||
break;
|
||||
case PKT_COMPRESSED:
|
||||
rc = do_compressed( out, ctb, pkt->pkt.compressed );
|
||||
break;
|
||||
@ -148,6 +158,7 @@ calc_packet_length( PACKET *pkt )
|
||||
n = calc_plaintext( pkt->pkt.plaintext );
|
||||
new_ctb = pkt->pkt.plaintext->new_ctb;
|
||||
break;
|
||||
case PKT_PHOTO_ID:
|
||||
case PKT_USER_ID:
|
||||
case PKT_COMMENT:
|
||||
case PKT_PUBLIC_KEY:
|
||||
@ -172,11 +183,11 @@ static void
|
||||
write_fake_data( IOBUF out, MPI a )
|
||||
{
|
||||
if( a ) {
|
||||
size_t i;
|
||||
int i;
|
||||
void *p;
|
||||
|
||||
p = gcry_mpi_get_opaque( a, &i );
|
||||
iobuf_write( out, p, (i+7)/8 );
|
||||
p = mpi_get_opaque( a, &i );
|
||||
iobuf_write( out, p, i );
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,11 +206,20 @@ do_comment( IOBUF out, int ctb, PKT_comment *rem )
|
||||
static int
|
||||
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
|
||||
{
|
||||
write_header(out, ctb, uid->len);
|
||||
uid->stored_at = iobuf_get_temp_length ( out ); /* what a hack ... */
|
||||
/* ... and it does only work when used with a temp iobuf */
|
||||
if( iobuf_write( out, uid->name, uid->len ) )
|
||||
return GPGERR_WRITE_FILE;
|
||||
if( uid->photo ) {
|
||||
write_header(out, ctb, uid->photolen);
|
||||
uid->stored_at = iobuf_get_temp_length ( out ); /* what a hack ... */
|
||||
/* ... and it does only work when used with a temp iobuf */
|
||||
if( iobuf_write( out, uid->photo, uid->photolen ) )
|
||||
return GPGERR_WRITE_FILE;
|
||||
}
|
||||
else {
|
||||
write_header(out, ctb, uid->len);
|
||||
uid->stored_at = iobuf_get_temp_length ( out ); /* what a hack ... */
|
||||
/* ... and it does only work when used with a temp iobuf */
|
||||
if( iobuf_write( out, uid->name, uid->len ) )
|
||||
return GPGERR_WRITE_FILE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -358,19 +378,30 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||
else {
|
||||
iobuf_put(a, 0xff );
|
||||
iobuf_put(a, sk->protect.algo );
|
||||
iobuf_put(a, sk->protect.s2k.mode );
|
||||
iobuf_put(a, sk->protect.s2k.hash_algo );
|
||||
if( sk->protect.s2k.mode >= 1000 ) {
|
||||
iobuf_put(a, 101 );
|
||||
iobuf_put(a, sk->protect.s2k.hash_algo );
|
||||
iobuf_write(a, "GNU", 3 );
|
||||
iobuf_put(a, sk->protect.s2k.mode - 1000 );
|
||||
}
|
||||
else {
|
||||
iobuf_put(a, sk->protect.s2k.mode );
|
||||
iobuf_put(a, sk->protect.s2k.hash_algo );
|
||||
}
|
||||
if( sk->protect.s2k.mode == 1
|
||||
|| sk->protect.s2k.mode == 3 )
|
||||
iobuf_write(a, sk->protect.s2k.salt, 8 );
|
||||
if( sk->protect.s2k.mode == 3 )
|
||||
iobuf_put(a, sk->protect.s2k.count );
|
||||
iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
|
||||
if( sk->protect.s2k.mode != 1001 )
|
||||
iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
|
||||
}
|
||||
}
|
||||
else
|
||||
iobuf_put(a, 0 );
|
||||
if( sk->is_protected && sk->version >= 4 ) {
|
||||
if( sk->protect.s2k.mode == 1001 )
|
||||
;
|
||||
else if( sk->is_protected && sk->version >= 4 ) {
|
||||
byte *p;
|
||||
size_t n;
|
||||
assert( gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
|
||||
@ -379,7 +410,7 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||
}
|
||||
else {
|
||||
for( ; i < nskey; i++ )
|
||||
mpi_write_opaque(a, sk->skey[i] );
|
||||
mpi_write(a, sk->skey[i] );
|
||||
write_16(a, sk->csum );
|
||||
}
|
||||
|
||||
@ -527,13 +558,24 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
|
||||
n = ed->len ? (ed->len + 10) : 0;
|
||||
write_header(out, ctb, n );
|
||||
iobuf_put(out, 1 ); /* version */
|
||||
iobuf_put(out, ed->mdc_method );
|
||||
|
||||
/* This is all. The caller has to write the real data */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_mdc( IOBUF out, PKT_mdc *mdc )
|
||||
{
|
||||
/* This packet requires a fixed header encoding */
|
||||
iobuf_put( out, 0xd3 ); /* packet ID and 1 byte length */
|
||||
iobuf_put( out, 0x14 ); /* length = 20 */
|
||||
if( iobuf_write( out, mdc->hash, sizeof(mdc->hash) ) )
|
||||
return GPGERR_WRITE_FILE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
|
||||
{
|
||||
@ -623,7 +665,6 @@ void
|
||||
build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
const byte *buffer, size_t buflen )
|
||||
{
|
||||
|
||||
byte *data;
|
||||
size_t hlen, dlen, nlen;
|
||||
int found=0;
|
||||
@ -659,6 +700,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
case SIGSUBPKT_KEY_EXPIRE:
|
||||
case SIGSUBPKT_NOTATION:
|
||||
case SIGSUBPKT_POLICY:
|
||||
case SIGSUBPKT_REVOC_REASON:
|
||||
hashed = 1; break;
|
||||
default: hashed = 0; break;
|
||||
}
|
||||
|
49
g10/cipher.c
49
g10/cipher.c
@ -1,5 +1,5 @@
|
||||
/* cipher.c - En-/De-ciphering filter
|
||||
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#include "packet.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
|
||||
|
||||
#define MIN_PARTIAL_SIZE 512
|
||||
@ -44,10 +45,18 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
PACKET pkt;
|
||||
PKT_encrypted ed;
|
||||
byte temp[18];
|
||||
int blocksize;
|
||||
unsigned nprefix;
|
||||
int use_mdc = opt.force_mdc;
|
||||
unsigned int blocksize;
|
||||
unsigned int nprefix;
|
||||
int rc;
|
||||
int use_mdc = opt.force_mdc;
|
||||
|
||||
blocksize = gcry_cipher_get_algo_blklen( cfx->dek->algo );
|
||||
if( blocksize < 8 || blocksize > 16 )
|
||||
log_fatal("unsupported blocksize %u\n", blocksize );
|
||||
if( blocksize != 8 )
|
||||
use_mdc = 1; /* enable it for all modern ciphers */
|
||||
if( opt.rfc2440 )
|
||||
use_mdc = 0; /* override - rfc2440 does not know about MDC */
|
||||
|
||||
memset( &ed, 0, sizeof ed );
|
||||
ed.len = cfx->datalen;
|
||||
@ -55,18 +64,16 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
if( use_mdc ) {
|
||||
ed.mdc_method = GCRY_MD_SHA1;
|
||||
cfx->mdc_hash = gcry_md_open( GCRY_MD_SHA1, 0 );
|
||||
/*should we check the function works, or is it better to provide
|
||||
a flag which makes the function die itself ?? FIXME */
|
||||
/*md_start_debug( cfx->mdc_hash, "mdccreat" );*/
|
||||
if( !cfx->mdc_hash )
|
||||
BUG();
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug( cfx->mdc_hash, "creatmdc" );
|
||||
}
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
|
||||
pkt.pkt.encrypted = &ed;
|
||||
if( build_packet( a, &pkt ))
|
||||
log_bug("build_packet(ENCR_DATA) failed\n");
|
||||
blocksize = gcry_cipher_get_algo_blklen( cfx->dek->algo );
|
||||
if( blocksize < 8 || blocksize > 16 )
|
||||
log_fatal("unsupported blocksize %d\n", blocksize );
|
||||
nprefix = blocksize;
|
||||
gcry_randomize( temp, nprefix, GCRY_STRONG_RANDOM );
|
||||
temp[nprefix] = temp[nprefix-2];
|
||||
@ -75,7 +82,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
if( !(cfx->cipher_hd = gcry_cipher_open( cfx->dek->algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| (cfx->dek->algo >= 100 ?
|
||||
| ((use_mdc || cfx->dek->algo >= 100) ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC)))
|
||||
) {
|
||||
/* we should never get an error here cause we already checked, that
|
||||
@ -83,6 +90,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/
|
||||
rc = gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
|
||||
if( !rc )
|
||||
@ -99,6 +107,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
log_fatal("encrypt failed: %s\n", gcry_strerror(rc) );
|
||||
iobuf_write(a, temp, nprefix+2);
|
||||
cfx->header=1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -120,6 +129,7 @@ cipher_filter( void *opaque, int control,
|
||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||
assert(a);
|
||||
if( !cfx->header ) {
|
||||
write_status( STATUS_BEGIN_ENCRYPTION );
|
||||
write_header( cfx, a );
|
||||
}
|
||||
if( cfx->mdc_hash )
|
||||
@ -134,15 +144,26 @@ cipher_filter( void *opaque, int control,
|
||||
if( cfx->mdc_hash ) {
|
||||
byte *hash;
|
||||
int hashlen = gcry_md_get_algo_dlen( gcry_md_get_algo( cfx->mdc_hash ) );
|
||||
byte temp[22];
|
||||
|
||||
assert( hashlen == 20 );
|
||||
/* we must hash the prefix of the MDC packet here */
|
||||
temp[0] = 0xd3;
|
||||
temp[1] = 0x14;
|
||||
gcry_md_putc( cfx->mdc_hash, temp[0] );
|
||||
gcry_md_putc( cfx->mdc_hash, temp[1] );
|
||||
|
||||
hash = gcry_md_read( cfx->mdc_hash, 0 );
|
||||
rc = gcry_cipher_encrypt( cfx->cipher_hd, hash, hashlen, NULL, 0 );
|
||||
memcpy(temp+2, hash, 20);
|
||||
rc = gcry_cipher_encrypt( cfx->cipher_hd, temp, 22, NULL, 0 );
|
||||
if( rc )
|
||||
log_fatal("encrypt failed: %s\n", gcry_strerror(rc) );
|
||||
if( iobuf_write( a, hash, hashlen ) )
|
||||
rc = GPGERR_WRITE_FILE;
|
||||
gcry_md_close( cfx->mdc_hash ); cfx->mdc_hash = NULL;
|
||||
if( iobuf_write( a, temp, 22 ) )
|
||||
log_error("writing MDC packet failed\n" );
|
||||
}
|
||||
gcry_cipher_close(cfx->cipher_hd);
|
||||
write_status( STATUS_END_ENCRYPTION );
|
||||
}
|
||||
else if( control == IOBUFCTRL_DESC ) {
|
||||
*(char**)buf = "cipher_filter";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* comment.c - write comment stuff
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* compress.c - compress filter
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -27,8 +27,8 @@
|
||||
#include <errno.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "util.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "filter.h"
|
||||
#include "options.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* dearmor.c - Armor utility
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,9 +25,9 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "packet.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* decrypt.c - verify signed data
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,12 +25,12 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* delkey.c - delete keys
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -62,6 +62,7 @@ delete_key( const char *username, int secret )
|
||||
: find_keyblock_byname( &kbpos, username );
|
||||
if( rc ) {
|
||||
log_error(_("%s: user not found\n"), username );
|
||||
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -93,10 +94,12 @@ delete_key( const char *username, int secret )
|
||||
"there is a secret key for this public key!\n"));
|
||||
log_info(_(
|
||||
"use option \"--delete-secret-key\" to delete it first.\n"));
|
||||
write_status_text( STATUS_DELETE_PROBLEM, "2" );
|
||||
rc = -1;
|
||||
}
|
||||
else if( rc != GPGERR_NO_SECKEY )
|
||||
else if( rc != GPGERR_NO_SECKEY ) {
|
||||
log_error("%s: get secret key: %s\n", username, gpg_errstr(rc) );
|
||||
}
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* encode.c - encode data
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -41,6 +41,7 @@
|
||||
static int encode_simple( const char *filename, int mode );
|
||||
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
|
||||
|
||||
|
||||
/****************
|
||||
* Emulate our old PK interface here - sometime in the future we might
|
||||
* change the internal design to directly fit to libgcrypt.
|
||||
@ -162,7 +163,7 @@ encode_simple( const char *filename, int mode )
|
||||
}
|
||||
|
||||
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
|
||||
iobuf_close(inp);
|
||||
iobuf_cancel(inp);
|
||||
gcry_free(cfx.dek);
|
||||
gcry_free(s2k);
|
||||
return rc;
|
||||
@ -510,7 +511,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
|
||||
* number of bits we have to use. We then encode the session
|
||||
* key in some way and we get it back in the big intger value
|
||||
* FRAME. Then we use FRAME, the public key PK->PKEY and the
|
||||
* algorithm number PK->PUBKEY_ALGO and pass it to pk_encrypt
|
||||
* algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
|
||||
* which returns the encrypted value in the array ENC->DATA.
|
||||
* This array has a size which depends on the used algorithm
|
||||
* (e.g. 2 for ElGamal). We don't need frame anymore because we
|
||||
@ -525,7 +526,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
|
||||
log_error("pubkey_encrypt failed: %s\n", gpg_errstr(rc) );
|
||||
else {
|
||||
if( opt.verbose ) {
|
||||
char *ustr = get_user_id_string( enc->keyid );
|
||||
char *ustr = get_user_id_string_native( enc->keyid );
|
||||
log_info(_("%s/%s encrypted for: %s\n"),
|
||||
gcry_pk_algo_name(enc->pubkey_algo),
|
||||
gcry_cipher_algo_name(dek->algo), ustr );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* encr-data.c - process an encrypted data packet
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
@ -30,9 +31,9 @@
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
static int decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len);
|
||||
static int mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len);
|
||||
static int decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len);
|
||||
|
||||
typedef struct {
|
||||
@ -54,8 +55,8 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
byte *p;
|
||||
int rc=0, c, i;
|
||||
byte temp[32];
|
||||
int blocksize;
|
||||
unsigned nprefix;
|
||||
unsigned int blocksize;
|
||||
unsigned int nprefix;
|
||||
|
||||
memset( &dfx, 0, sizeof dfx );
|
||||
if( gcry_cipher_test_algo( dek->algo ) ) {
|
||||
@ -68,7 +69,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
log_info(_("%s encrypted data\n"), gcry_cipher_algo_name( dek->algo ) );
|
||||
|
||||
blocksize = gcry_cipher_get_algo_blklen( dek->algo );
|
||||
if( blocksize < 1 || blocksize > 16 )
|
||||
if( !blocksize || blocksize > 16 )
|
||||
log_fatal("unsupported blocksize %u\n", blocksize );
|
||||
nprefix = blocksize;
|
||||
if( ed->len && ed->len < (nprefix+2) )
|
||||
@ -76,13 +77,13 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
|
||||
if( ed->mdc_method ) {
|
||||
dfx.mdc_hash = gcry_md_open( ed->mdc_method, 0 );
|
||||
if( !dfx.mdc_hash )
|
||||
BUG();
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug(dfx.mdc_hash, "checkmdc");
|
||||
}
|
||||
if( !(dfx.cipher_hd = gcry_cipher_open( dek->algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| (dek->algo >= 100 ?
|
||||
| ((ed->mdc_method || dek->algo >= 100)?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC) ))
|
||||
) {
|
||||
/* we should never get an error here cause we already checked, that
|
||||
@ -122,8 +123,6 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
temp[i] = c;
|
||||
}
|
||||
gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0 );
|
||||
if( dfx.mdc_hash )
|
||||
gcry_md_write( dfx.mdc_hash, temp, nprefix+2 );
|
||||
gcry_cipher_sync( dfx.cipher_hd );
|
||||
p = temp;
|
||||
/* log_hexdump( "prefix", temp, nprefix+2 ); */
|
||||
@ -131,22 +130,30 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
rc = GPGERR_BAD_KEY;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( dfx.mdc_hash )
|
||||
gcry_md_write( dfx.mdc_hash, temp, nprefix+2 );
|
||||
|
||||
if( ed->mdc_method )
|
||||
iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
|
||||
else
|
||||
iobuf_push_filter( ed->buf, decode_filter, &dfx );
|
||||
proc_packets( procctx, ed->buf);
|
||||
|
||||
proc_packets( procctx, ed->buf );
|
||||
ed->buf = NULL;
|
||||
if( ed->mdc_method && dfx.eof_seen == 2 )
|
||||
rc = GPGERR_INVALID_PACKET;
|
||||
else if( ed->mdc_method ) { /* check the mdc */
|
||||
int datalen = gcry_md_get_algo_dlen( ed->mdc_method );
|
||||
|
||||
gcry_cipher_decrypt( dfx.cipher_hd, dfx.defer, 20, NULL, 0);
|
||||
if( datalen != 20
|
||||
|| memcmp(gcry_md_read( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
|
||||
rc = GPGERR_BAD_SIGN;
|
||||
log_hexdump("MDC calculated:", gcry_md_read( dfx.mdc_hash, 0), datalen);
|
||||
log_hexdump("MDC message :", dfx.defer, 20);
|
||||
/*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/
|
||||
/*log_hexdump("MDC message :", dfx.defer, 20);*/
|
||||
}
|
||||
|
||||
leave:
|
||||
gcry_cipher_close(dfx.cipher_hd);
|
||||
gcry_md_close( dfx.mdc_hash );
|
||||
@ -154,6 +161,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* I think we should merge this with cipher_filter */
|
||||
static int
|
||||
mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
@ -180,11 +188,14 @@ mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
}
|
||||
if( n == 40 ) {
|
||||
/* we have enough stuff - flush the deferred stuff */
|
||||
/* (we have asserted that the buffer is large enough */
|
||||
if( !dfx->defer_filled ) /* the first time */
|
||||
/* (we have asserted that the buffer is large enough) */
|
||||
if( !dfx->defer_filled ) { /* the first time */
|
||||
memcpy(buf, buf+20, 20 );
|
||||
else
|
||||
n = 20;
|
||||
}
|
||||
else {
|
||||
memcpy(buf, dfx->defer, 20 );
|
||||
}
|
||||
/* now fill up */
|
||||
for(; n < size; n++ ) {
|
||||
if( (c = iobuf_get(a)) == -1 )
|
||||
@ -198,7 +209,7 @@ mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
dfx->defer_filled = 1;
|
||||
}
|
||||
else if( !dfx->defer_filled ) { /* eof seen buf empty defer */
|
||||
/* this is very bad because there is an incomplete hash */
|
||||
/* this is bad because there is an incomplete hash */
|
||||
n -= 20;
|
||||
memcpy(buf, buf+20, n );
|
||||
dfx->eof_seen = 2; /* eof with incomplete hash */
|
||||
@ -238,7 +249,7 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
|
||||
n = iobuf_read( a, buf, size );
|
||||
if( n == -1 ) n = 0;
|
||||
if( n )
|
||||
gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0);
|
||||
gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0 );
|
||||
else
|
||||
rc = -1; /* eof */
|
||||
*ret_len = n;
|
||||
|
35
g10/export.c
35
g10/export.c
@ -1,5 +1,5 @@
|
||||
/* export.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,11 +25,11 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
@ -71,6 +71,12 @@ export_seckeys( STRLIST users )
|
||||
return do_export( users, 1, 0 );
|
||||
}
|
||||
|
||||
int
|
||||
export_secsubkeys( STRLIST users )
|
||||
{
|
||||
return do_export( users, 2, 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
do_export( STRLIST users, int secret, int onlyrfc )
|
||||
{
|
||||
@ -168,6 +174,16 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
|
||||
}
|
||||
}
|
||||
|
||||
/* we can't apply GNU mode 1001 on an unprotected key */
|
||||
if( secret == 2
|
||||
&& (node = find_kbnode( keyblock, PKT_SECRET_KEY ))
|
||||
&& !node->pkt->pkt.secret_key->is_protected )
|
||||
{
|
||||
log_info(_("key %08lX: not protected - skipped\n"),
|
||||
(ulong)keyid_from_sk( node->pkt->pkt.secret_key, NULL) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* and write it */
|
||||
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
|
||||
/* don't export any comment packets but those in the
|
||||
@ -183,7 +199,20 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
|
||||
continue; /* not exportable */
|
||||
}
|
||||
|
||||
if( (rc = build_packet( out, node->pkt )) ) {
|
||||
if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
/* we don't want to export the secret parts of the
|
||||
* primary key, this is done by using GNU protection mode 1001
|
||||
*/
|
||||
int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
|
||||
node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
|
||||
rc = build_packet( out, node->pkt );
|
||||
node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
|
||||
}
|
||||
else {
|
||||
rc = build_packet( out, node->pkt );
|
||||
}
|
||||
|
||||
if( rc ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, gpg_errstr(rc) );
|
||||
rc = GPGERR_WRITE_FILE;
|
||||
|
12
g10/filter.h
12
g10/filter.h
@ -1,5 +1,5 @@
|
||||
/* filter.h
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -26,7 +26,6 @@
|
||||
#include "iobuf.h"
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
GCRY_MD_HD md; /* catch all */
|
||||
GCRY_MD_HD md2; /* if we want to calculate an alternate hash */
|
||||
@ -39,6 +38,9 @@ typedef struct {
|
||||
int only_keyblocks; /* skip all headers but ".... key block" */
|
||||
const char *hdrlines; /* write these headerlines */
|
||||
|
||||
/* these fileds must be initialized to zero */
|
||||
int no_openpgp_data; /* output flag: "No valid OpenPGP data found" */
|
||||
|
||||
/* the following fields must be initialized to zero */
|
||||
int inp_checked; /* set if the input has been checked */
|
||||
int inp_bypass; /* set if the input is not armored */
|
||||
@ -60,6 +62,7 @@ typedef struct {
|
||||
u32 crc;
|
||||
|
||||
int status; /* an internal state flag */
|
||||
int cancel;
|
||||
int any_data; /* any valid armored data seen */
|
||||
int pending_lf; /* used together with faked */
|
||||
} armor_filter_context_t;
|
||||
@ -83,6 +86,8 @@ typedef struct {
|
||||
GCRY_CIPHER_HD cipher_hd;
|
||||
int header;
|
||||
GCRY_MD_HD mdc_hash;
|
||||
byte enchash[20];
|
||||
int create_mdc; /* flag will be set by the cipher filter */
|
||||
} cipher_filter_context_t;
|
||||
|
||||
|
||||
@ -93,7 +98,6 @@ typedef struct {
|
||||
} encrypt_filter_context_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
byte *buffer; /* malloced buffer */
|
||||
unsigned buffer_size; /* and size of this buffer */
|
||||
@ -108,8 +112,6 @@ typedef struct {
|
||||
} text_filter_context_t;
|
||||
|
||||
|
||||
/* encrypt_filter_context_t defined in main.h */
|
||||
|
||||
/*-- mdfilter.c --*/
|
||||
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
||||
void free_md_filter_context( md_filter_context_t *mfx );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* free-packet.c - cleanup stuff for packets
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,10 +24,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
@ -219,6 +219,8 @@ free_comment( PKT_comment *rem )
|
||||
void
|
||||
free_user_id( PKT_user_id *uid )
|
||||
{
|
||||
if( uid->photo )
|
||||
gcry_free( uid->photo );
|
||||
gcry_free(uid);
|
||||
}
|
||||
|
||||
|
120
g10/getkey.c
120
g10/getkey.c
@ -1,5 +1,5 @@
|
||||
/* getkey.c - Get a key from the database
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,9 +24,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include <gcrypt.h>
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "options.h"
|
||||
@ -45,7 +46,11 @@
|
||||
* that they are all valid.
|
||||
* Note: We must use numerical values here in case that this program
|
||||
* will be converted to those little blue HAL9000s with their strange
|
||||
* EBCDIC character set (user ids are UTF-8). */
|
||||
* EBCDIC character set (user ids are UTF-8).
|
||||
* wk 2000-04-13: Hmmm, does this really make sense, given the fact that
|
||||
* we can run gpg now on a S/390 running GNU/Linux, where the code
|
||||
* translation is done by the device drivers?
|
||||
*/
|
||||
static const byte word_match_chars[256] = {
|
||||
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -154,6 +159,7 @@ static int uid_cache_entries; /* number of entries in uid cache */
|
||||
static char* prepare_word_match( const byte *name );
|
||||
static int lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_kb );
|
||||
static int lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_kb );
|
||||
static u32 subkeys_expiretime( KBNODE node, u32 *mainkid );
|
||||
|
||||
|
||||
#if 0
|
||||
@ -696,6 +702,8 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
||||
STRLIST r;
|
||||
GETKEY_CTX ctx;
|
||||
|
||||
if( retctx ) /* reset the returned context in case of error */
|
||||
*retctx = NULL;
|
||||
assert( !pk ^ !sk );
|
||||
|
||||
/* build the search context */
|
||||
@ -941,7 +949,7 @@ get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk,
|
||||
|
||||
if( !sk ) {
|
||||
/* Performance Hint: key_byname should not need a sk here */
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
rc = key_byname( retctx, names, NULL, sk, ret_keyblock );
|
||||
free_secret_key( sk );
|
||||
}
|
||||
@ -959,7 +967,7 @@ get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
|
||||
|
||||
if( !sk ) {
|
||||
/* Performance Hint: lookup_read should not need a pk in this case */
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
rc = lookup_sk( ctx, sk, ret_keyblock );
|
||||
free_secret_key( sk );
|
||||
}
|
||||
@ -1150,7 +1158,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode,
|
||||
k = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
if( !k )
|
||||
BUG(); /* keyblock without primary key!!! */
|
||||
keyid_from_pk( knode->pkt->pkt.public_key, kid );
|
||||
keyid_from_pk( k->pkt->pkt.public_key, kid );
|
||||
}
|
||||
else
|
||||
keyid_from_pk( pk, kid );
|
||||
@ -1208,6 +1216,10 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
||||
pk = NULL; /* not needed for old keys */
|
||||
else if( k->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||
keyid_from_pk( pk, kid );
|
||||
else if( !pk->expiredate ) { /* and subkey */
|
||||
/* insert the expiration date here */
|
||||
pk->expiredate = subkeys_expiretime( k, kid );
|
||||
}
|
||||
sigdate = 0;
|
||||
}
|
||||
else if( k->pkt->pkttype == PKT_SECRET_KEY
|
||||
@ -1222,8 +1234,11 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
||||
else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10
|
||||
&& sig->sig_class <= 0x30 && sig->version > 3
|
||||
&& !(sig->sig_class == 0x18 || sig->sig_class == 0x28)
|
||||
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
|
||||
/* okay this is a self-signature which can be used.
|
||||
* This is not used for subkey binding signature, becuase this
|
||||
* is done above.
|
||||
* FIXME: We should only use this if the signature is valid
|
||||
* but this is time consuming - we must provide another
|
||||
* way to handle this
|
||||
@ -1279,9 +1294,16 @@ find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name,
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
if( k->pkt->pkt.user_id->photo ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
k->pkt->pkt.user_id->photo,
|
||||
k->pkt->pkt.user_id->photolen );
|
||||
}
|
||||
else {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
}
|
||||
*use_namehash = 1;
|
||||
return kk;
|
||||
}
|
||||
@ -1516,6 +1538,56 @@ find_by_fpr_sk( KBNODE keyblock, PKT_secret_key *sk,
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return the expiretime of a subkey.
|
||||
*/
|
||||
static u32
|
||||
subkeys_expiretime( KBNODE node, u32 *mainkid )
|
||||
{
|
||||
KBNODE k;
|
||||
PKT_signature *sig;
|
||||
u32 expires = 0, sigdate = 0;
|
||||
|
||||
assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
for(k=node->next; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (sig=k->pkt->pkt.signature)->sig_class == 0x18
|
||||
&& sig->keyid[0] == mainkid[0]
|
||||
&& sig->keyid[1] == mainkid[1]
|
||||
&& sig->version > 3
|
||||
&& sig->timestamp > sigdate ) {
|
||||
/* okay this is a key-binding which can be used.
|
||||
* We use the latest self-signature.
|
||||
* FIXME: We should only use this if the binding signature is valid
|
||||
* but this is time consuming - we must provide another
|
||||
* way to handle this
|
||||
*/
|
||||
const byte *p;
|
||||
u32 ed;
|
||||
|
||||
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
|
||||
ed = p? node->pkt->pkt.public_key->timestamp + buffer_to_u32(p):0;
|
||||
sigdate = sig->timestamp;
|
||||
expires = ed;
|
||||
}
|
||||
else if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
break; /* stop at the next subkey */
|
||||
}
|
||||
|
||||
return expires;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Check whether the subkey has expired. Node must point to the subkey
|
||||
*/
|
||||
static int
|
||||
has_expired( KBNODE node, u32 *mainkid, u32 cur_time )
|
||||
{
|
||||
u32 expires = subkeys_expiretime( node, mainkid );
|
||||
return expires && expires <= cur_time;
|
||||
}
|
||||
|
||||
static void
|
||||
finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
int use_namehash, int primary )
|
||||
@ -1534,6 +1606,10 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
pk->pubkey_usage ) == GPGERR_WR_PUBKEY_ALGO ) {
|
||||
/* if the usage is not correct, try to use a subkey */
|
||||
KBNODE save_k = k;
|
||||
u32 mainkid[2];
|
||||
u32 cur_time = make_timestamp();
|
||||
|
||||
keyid_from_pk( keyblock->pkt->pkt.public_key, mainkid );
|
||||
|
||||
k = NULL;
|
||||
/* kludge for pgp 5: which doesn't accept type 20:
|
||||
@ -1545,7 +1621,8 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
== GCRY_PK_ELG_E
|
||||
&& !openpgp_pk_test_algo(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
pk->pubkey_usage )
|
||||
&& !has_expired(k, mainkid, cur_time) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1555,7 +1632,10 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
&& !openpgp_pk_test_algo(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
pk->pubkey_usage )
|
||||
&& ( pk->pubkey_usage != GCRY_PK_USAGE_ENCR
|
||||
|| !has_expired( k, mainkid, cur_time ) )
|
||||
)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1887,6 +1967,18 @@ get_user_id_string( u32 *keyid )
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
get_user_id_string_native( u32 *keyid )
|
||||
{
|
||||
char *p = get_user_id_string( keyid );
|
||||
char *p2 = utf8_to_native( p, strlen(p) );
|
||||
|
||||
gcry_free(p);
|
||||
return p2;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
get_long_user_id_string( u32 *keyid )
|
||||
{
|
||||
@ -1914,6 +2006,7 @@ get_user_id( u32 *keyid, size_t *rn )
|
||||
user_id_db_t r;
|
||||
char *p;
|
||||
int pass=0;
|
||||
|
||||
/* try it two times; second pass reads from key resources */
|
||||
do {
|
||||
for(r=user_id_db; r; r = r->next )
|
||||
@ -1924,9 +2017,8 @@ get_user_id( u32 *keyid, size_t *rn )
|
||||
return p;
|
||||
}
|
||||
} while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
|
||||
p = gcry_xmalloc( 19 );
|
||||
memcpy(p, "[User id not found]", 19 );
|
||||
*rn = 19;
|
||||
p = gcry_xstrdup( _("[User id not found]") );
|
||||
*rn = strlen(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
279
g10/gpg.c
279
g10/gpg.c
@ -26,8 +26,8 @@
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
@ -77,6 +77,7 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
aImport,
|
||||
aFastImport,
|
||||
aVerify,
|
||||
aVerifyFiles,
|
||||
aListKeys,
|
||||
aListSigs,
|
||||
aListSecretKeys,
|
||||
@ -85,12 +86,13 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
aExport,
|
||||
aExportAll,
|
||||
aExportSecret,
|
||||
aExportSecretSub,
|
||||
aCheckKeys,
|
||||
aGenRevoke,
|
||||
aPrimegen,
|
||||
aPrintMD,
|
||||
aPrintHMAC,
|
||||
aPrintMDs,
|
||||
aPrintHMAC,
|
||||
aCheckTrustDB,
|
||||
aUpdateTrustDB,
|
||||
aFixTrustDB,
|
||||
@ -130,6 +132,7 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
oDigestAlgo,
|
||||
oCompressAlgo,
|
||||
oPasswdFD,
|
||||
oCommandFD,
|
||||
oNoVerbose,
|
||||
oTrustDBName,
|
||||
oNoSecmemWarn,
|
||||
@ -146,7 +149,6 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
oCompressKeys,
|
||||
oCompressSigs,
|
||||
oAlwaysTrust,
|
||||
oEmuChecksumBug,
|
||||
oRunAsShmCP,
|
||||
oSetFilename,
|
||||
oSetPolicyURL,
|
||||
@ -164,6 +166,7 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
oEscapeFrom,
|
||||
oLockOnce,
|
||||
oLockMultiple,
|
||||
oLockNever,
|
||||
oKeyServer,
|
||||
oEncryptTo,
|
||||
oNoEncryptTo,
|
||||
@ -175,7 +178,14 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
oAllowNonSelfsignedUID,
|
||||
oNoLiteral,
|
||||
oSetFilesize,
|
||||
oEntropyDLLName,
|
||||
oHonorHttpProxy,
|
||||
oFastListMode,
|
||||
oListOnly,
|
||||
oIgnoreTimeConflict,
|
||||
oNoRandomSeedFile,
|
||||
oNoAutoKeyRetrieve,
|
||||
oEmu3DESS2KBug, /* will be removed in 1.1 */
|
||||
oEmuMDEncodeBug,
|
||||
aTest };
|
||||
|
||||
|
||||
@ -191,6 +201,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ aStore, "store", 256, N_("store only")},
|
||||
{ aDecrypt, "decrypt", 256, N_("decrypt data (default)")},
|
||||
{ aVerify, "verify" , 256, N_("verify a signature")},
|
||||
{ aVerifyFiles, "verify-files" , 256, "@" },
|
||||
{ aListKeys, "list-keys", 256, N_("list keys")},
|
||||
{ aListKeys, "list-public-keys", 256, "@" },
|
||||
{ aListSigs, "list-sigs", 256, N_("list keys and signatures")},
|
||||
@ -210,6 +221,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") },
|
||||
{ aExportAll, "export-all" , 256, "@" },
|
||||
{ aExportSecret, "export-secret-keys" , 256, "@" },
|
||||
{ aExportSecretSub, "export-secret-subkeys" , 256, "@" },
|
||||
{ aImport, "import", 256 , N_("import/merge keys")},
|
||||
{ aFastImport, "fast-import", 256 , "@"},
|
||||
{ aListPackets, "list-packets",256,N_("list only the sequence of packets")},
|
||||
@ -266,12 +278,12 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
|
||||
{ oOptions, "options" , 2, N_("read options from file")},
|
||||
|
||||
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
|
||||
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
|
||||
{ oDebug, "debug" ,4|16, "@"},
|
||||
{ oDebugAll, "debug-all" ,0, "@"},
|
||||
{ oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
|
||||
{ oNoComment, "no-comment", 0, N_("do not write comment packets")},
|
||||
{ oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
|
||||
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
|
||||
{ oNoComment, "no-comment", 0, "@"},
|
||||
{ oCompletesNeeded, "completes-needed", 1, "@"},
|
||||
{ oMarginalsNeeded, "marginals-needed", 1, "@"},
|
||||
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
|
||||
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
|
||||
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
|
||||
@ -287,7 +299,11 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
|
||||
{ oNotation, "notation-data", 2, N_("|NAME=VALUE|use this notation data")},
|
||||
|
||||
{ 302, NULL, 0, N_("@\nExamples:\n\n"
|
||||
{ 302, NULL, 0, N_(
|
||||
"@\n(See the man page for a complete listing of all commands and options)\n"
|
||||
)},
|
||||
|
||||
{ 303, NULL, 0, N_("@\nExamples:\n\n"
|
||||
" -se -r Bob [file] sign and encrypt for user Bob\n"
|
||||
" --clearsign [file] make a clear text signature\n"
|
||||
" --detach-sign [file] make a detached signature\n"
|
||||
@ -301,6 +317,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ aListTrustPath, "list-trust-path",0, "@"},
|
||||
{ oKOption, NULL, 0, "@"},
|
||||
{ oPasswdFD, "passphrase-fd",1, "@" },
|
||||
{ oCommandFD, "command-fd",1, "@" },
|
||||
{ oNoVerbose, "no-verbose", 0, "@"},
|
||||
{ oTrustDBName, "trustdb-name", 2, "@" },
|
||||
{ oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
|
||||
@ -331,6 +348,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oEscapeFrom, "escape-from-lines", 0, "@" },
|
||||
{ oLockOnce, "lock-once", 0, "@" },
|
||||
{ oLockMultiple, "lock-multiple", 0, "@" },
|
||||
{ oLockNever, "lock-never", 0, "@" },
|
||||
{ oLoggerFD, "logger-fd",1, "@" },
|
||||
{ oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
|
||||
{ oUtf8Strings, "utf8-strings", 0, "@" },
|
||||
@ -341,7 +359,14 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
|
||||
{ oNoLiteral, "no-literal", 0, "@" },
|
||||
{ oSetFilesize, "set-filesize", 20, "@" },
|
||||
{ oEntropyDLLName, "entropy-dll-name", 2, "@" },
|
||||
{ oHonorHttpProxy,"honor-http-proxy", 0, "@" },
|
||||
{ oFastListMode,"fast-list-mode", 0, "@" },
|
||||
{ oListOnly, "list-only", 0, "@"},
|
||||
{ oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
|
||||
{ oNoRandomSeedFile, "no-random-seed-file", 0, "@" },
|
||||
{ oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
|
||||
{ oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"},
|
||||
{ oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
|
||||
{0} };
|
||||
|
||||
|
||||
@ -351,8 +376,8 @@ int gpg_errors_seen = 0;
|
||||
static int utf8_strings = 0;
|
||||
static int maybe_setuid = 1;
|
||||
|
||||
static char *build_list( const char *text, const char * (*mapf)(int),
|
||||
int (*chkf)(int) );
|
||||
static char *build_list( const char *text,
|
||||
const char *(*mapf)(int), int (*chkf)(int) );
|
||||
static void set_cmd( enum cmd_and_opt_values *ret_cmd,
|
||||
enum cmd_and_opt_values new_cmd );
|
||||
static void print_hex( byte *p, size_t n );
|
||||
@ -360,13 +385,13 @@ static void print_mds( const char *fname, int algo, const char *key );
|
||||
static void add_notation_data( const char *string );
|
||||
static int check_policy_url( const char *s );
|
||||
|
||||
|
||||
static int
|
||||
our_pk_test_algo( int algo )
|
||||
{
|
||||
return openpgp_pk_test_algo( algo, 0 );
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
my_strusage( int level )
|
||||
{
|
||||
@ -390,26 +415,29 @@ my_strusage( int level )
|
||||
"default operation depends on the input data\n");
|
||||
break;
|
||||
|
||||
case 31: p = _("\nSupported algorithms:\n"); break;
|
||||
case 32:
|
||||
case 31: p = "\nHome: "; break;
|
||||
case 32: p = opt.homedir; break;
|
||||
case 33: p = _("\nSupported algorithms:\n"); break;
|
||||
case 34:
|
||||
if( !ciphers )
|
||||
ciphers = build_list("Cipher: ", gcry_cipher_algo_name,
|
||||
openpgp_cipher_test_algo );
|
||||
p = ciphers;
|
||||
break;
|
||||
case 33:
|
||||
case 35:
|
||||
if( !pubkeys )
|
||||
pubkeys = build_list("Pubkey: ", gcry_pk_algo_name,
|
||||
our_pk_test_algo );
|
||||
p = pubkeys;
|
||||
break;
|
||||
case 34:
|
||||
case 36:
|
||||
if( !digests )
|
||||
digests = build_list("Hash: ", gcry_md_algo_name,
|
||||
openpgp_md_test_algo );
|
||||
p = digests;
|
||||
break;
|
||||
|
||||
|
||||
default: p = NULL;
|
||||
}
|
||||
return p;
|
||||
@ -465,27 +493,6 @@ i18n_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
wrong_args( const char *text)
|
||||
{
|
||||
fputs(_("usage: gpg [options] "),stderr);
|
||||
fputs(text,stderr);
|
||||
putc('\n',stderr);
|
||||
gpg_exit(2);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
make_username( const char *string )
|
||||
{
|
||||
char *p;
|
||||
if( utf8_strings )
|
||||
p = native_to_utf8( string );
|
||||
else
|
||||
p = gcry_xstrdup(string);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
register_extension( const char *mainpgm, const char *fname )
|
||||
@ -509,16 +516,38 @@ register_extension( const char *mainpgm, const char *fname )
|
||||
|
||||
|
||||
|
||||
static void
|
||||
wrong_args( const char *text)
|
||||
{
|
||||
fputs(_("usage: gpg [options] "),stderr);
|
||||
fputs(text,stderr);
|
||||
putc('\n',stderr);
|
||||
gpg_exit(2);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
make_username( const char *string )
|
||||
{
|
||||
char *p;
|
||||
if( utf8_strings )
|
||||
p = gcry_xstrdup(string);
|
||||
else
|
||||
p = native_to_utf8( string );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_debug(void)
|
||||
{
|
||||
#if 0
|
||||
#warning memory debuggig not enabled
|
||||
#if 0
|
||||
#warning memory debugging not enabled
|
||||
if( opt.debug & DBG_MEMORY_VALUE )
|
||||
memory_debug_mode = 1;
|
||||
if( opt.debug & DBG_MEMSTAT_VALUE )
|
||||
memory_stat_debug_mode = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if( opt.debug & DBG_MPI_VALUE )
|
||||
gcry_control( GCRYCTL_SET_DEBUG_FLAGS, 2 );
|
||||
@ -579,6 +608,7 @@ main( int argc, char **argv )
|
||||
int default_keyring = 1;
|
||||
int greeting = 0;
|
||||
int nogreeting = 0;
|
||||
int use_random_seed = 1;
|
||||
enum cmd_and_opt_values cmd = 0;
|
||||
const char *trustdb_name = NULL;
|
||||
char *def_cipher_string = NULL;
|
||||
@ -611,6 +641,7 @@ main( int argc, char **argv )
|
||||
init_signals();
|
||||
create_dotlock(NULL); /* register locking cleanup */
|
||||
i18n_init();
|
||||
opt.command_fd = -1; /* no command fd */
|
||||
opt.compress = -1; /* defaults to standard compress level */
|
||||
/* note: if you change these lines, look at oOpenPGP */
|
||||
opt.def_cipher_algo = 0;
|
||||
@ -622,7 +653,13 @@ main( int argc, char **argv )
|
||||
opt.completes_needed = 1;
|
||||
opt.marginals_needed = 3;
|
||||
opt.max_cert_depth = 5;
|
||||
opt.pgp2_workarounds = 1;
|
||||
opt.auto_key_retrieve = 1;
|
||||
#ifdef __MINGW32__
|
||||
opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
|
||||
#else
|
||||
opt.homedir = getenv("GNUPGHOME");
|
||||
#endif
|
||||
if( !opt.homedir || !*opt.homedir ) {
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
opt.homedir = "c:/gnupg-test";
|
||||
@ -679,7 +716,6 @@ main( int argc, char **argv )
|
||||
if( default_config )
|
||||
configname = make_filename(opt.homedir, "options", NULL );
|
||||
|
||||
|
||||
argc = orig_argc;
|
||||
argv = orig_argv;
|
||||
pargs.argc = &argc;
|
||||
@ -721,13 +757,16 @@ main( int argc, char **argv )
|
||||
case aListKeys: set_cmd( &cmd, aListKeys); break;
|
||||
case aListSigs: set_cmd( &cmd, aListSigs); break;
|
||||
case aExportSecret: set_cmd( &cmd, aExportSecret); break;
|
||||
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
|
||||
case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey);
|
||||
greeting=1; break;
|
||||
case aDeleteKey: set_cmd( &cmd, aDeleteKey); greeting=1; break;
|
||||
|
||||
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
|
||||
case aSym: set_cmd( &cmd, aSym); break;
|
||||
|
||||
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
|
||||
|
||||
case aEncr: set_cmd( &cmd, aEncr); break;
|
||||
case aSign: set_cmd( &cmd, aSign ); break;
|
||||
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
|
||||
@ -738,11 +777,12 @@ main( int argc, char **argv )
|
||||
case aClearsign: set_cmd( &cmd, aClearsign); break;
|
||||
case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
|
||||
case aVerify: set_cmd( &cmd, aVerify); break;
|
||||
case aVerifyFiles: set_cmd( &cmd, aVerifyFiles); break;
|
||||
case aPrimegen: set_cmd( &cmd, aPrimegen); break;
|
||||
case aGenRandom: set_cmd( &cmd, aGenRandom); break;
|
||||
case aPrintMD: set_cmd( &cmd, aPrintMD); break;
|
||||
case aPrintHMAC: set_cmd( &cmd, aPrintHMAC); break;
|
||||
case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
|
||||
case aPrintHMAC: set_cmd( &cmd, aPrintHMAC); break;
|
||||
case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
|
||||
case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
|
||||
case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
|
||||
@ -828,11 +868,14 @@ main( int argc, char **argv )
|
||||
break;
|
||||
case oRFC1991:
|
||||
opt.rfc1991 = 1;
|
||||
opt.rfc2440 = 0;
|
||||
opt.no_comment = 1;
|
||||
opt.escape_from = 1;
|
||||
break;
|
||||
case oOpenPGP:
|
||||
opt.rfc1991 = 0;
|
||||
opt.rfc2440 = 1;
|
||||
opt.pgp2_workarounds = 0;
|
||||
opt.escape_from = 0;
|
||||
opt.force_v3_sigs = 0;
|
||||
opt.compress_keys = 0; /* not mandated but we do it */
|
||||
@ -840,11 +883,13 @@ main( int argc, char **argv )
|
||||
opt.not_dash_escaped = 0;
|
||||
opt.def_cipher_algo = 0;
|
||||
opt.def_digest_algo = 0;
|
||||
opt.def_compress_algo = 2;
|
||||
opt.def_compress_algo = 1;
|
||||
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;
|
||||
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:
|
||||
#ifndef USE_SHM_COPROCESSING
|
||||
@ -880,6 +925,7 @@ main( int argc, char **argv )
|
||||
break;
|
||||
case oCompress: opt.compress = pargs.r.ret_int; break;
|
||||
case oPasswdFD: pwfd = pargs.r.ret_int; break;
|
||||
case oCommandFD: opt.command_fd = pargs.r.ret_int; break;
|
||||
case oCipherAlgo: def_cipher_string = gcry_xstrdup(pargs.r.ret_str); break;
|
||||
case oDigestAlgo: def_digest_string = gcry_xstrdup(pargs.r.ret_str); break;
|
||||
case oNoSecmemWarn: gcry_control( GCRYCTL_DISABLE_SECMEM_WARN ); break;
|
||||
@ -891,6 +937,10 @@ main( int argc, char **argv )
|
||||
case oNotDashEscaped: opt.not_dash_escaped = 1; break;
|
||||
case oEscapeFrom: opt.escape_from = 1; break;
|
||||
case oLockOnce: opt.lock_once = 1; break;
|
||||
#if 0
|
||||
#warning no disable_dotlock() yet
|
||||
case oLockNever: disable_dotlock(); break;
|
||||
#endif
|
||||
case oLockMultiple: opt.lock_once = 0; break;
|
||||
case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
|
||||
case oNotation: add_notation_data( pargs.r.ret_str ); break;
|
||||
@ -908,22 +958,15 @@ main( int argc, char **argv )
|
||||
&algo, sizeof algo );
|
||||
}
|
||||
break;
|
||||
case oAllowNonSelfsignedUID:
|
||||
opt.allow_non_selfsigned_uid = 1;
|
||||
break;
|
||||
case oNoLiteral:
|
||||
opt.no_literal = 1;
|
||||
break;
|
||||
case oSetFilesize:
|
||||
opt.set_filesize = pargs.r.ret_ulong;
|
||||
break;
|
||||
|
||||
case oEntropyDLLName:
|
||||
#ifdef USE_STATIC_RNDW32
|
||||
log_info("set dllname to `%s'\n", pargs.r.ret_str );
|
||||
rndw32_set_dll_name( pargs.r.ret_str );
|
||||
#endif
|
||||
break;
|
||||
case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_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;
|
||||
case oFastListMode: opt.fast_list_mode = 1; break;
|
||||
case oListOnly: opt.list_only=1; break;
|
||||
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
|
||||
case oNoRandomSeedFile: use_random_seed = 0; break;
|
||||
case oNoAutoKeyRetrieve: opt.auto_key_retrieve = 0; break;
|
||||
|
||||
default : pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
@ -946,14 +989,12 @@ main( int argc, char **argv )
|
||||
fprintf(stderr, "%s\n", strusage(15) );
|
||||
}
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
if( !opt.batch )
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
#endif
|
||||
if( opt.force_mdc ) {
|
||||
log_info("--force-mdc ignored because"
|
||||
" the OpenPGP WG has not yet aggreed on MDCs\n");
|
||||
opt.force_mdc = 0;
|
||||
if( !opt.batch ) {
|
||||
log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
|
||||
log_info("It is only intended for test purposes and should NOT be\n");
|
||||
log_info("used in a production environment or with production keys!\n");
|
||||
}
|
||||
#endif
|
||||
if (opt.no_literal) {
|
||||
log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
|
||||
if (opt.textmode)
|
||||
@ -975,7 +1016,7 @@ main( int argc, char **argv )
|
||||
* gpg_opt_homedir = opt.homedir; */
|
||||
|
||||
/* must do this after dropping setuid, because string_to...
|
||||
* may try to load a module */
|
||||
* may try to load an module */
|
||||
if( def_cipher_string ) {
|
||||
opt.def_cipher_algo = gcry_cipher_map_name(def_cipher_string);
|
||||
gcry_free(def_cipher_string); def_cipher_string = NULL;
|
||||
@ -1025,8 +1066,19 @@ main( int argc, char **argv )
|
||||
if( log_get_errorcount(0) )
|
||||
gpg_exit(2);
|
||||
|
||||
if( !cmd && opt.fingerprint && !with_fpr )
|
||||
/* set the random seed file */
|
||||
if( use_random_seed ) {
|
||||
char *p = make_filename(opt.homedir, "random_seed", NULL );
|
||||
#if 0
|
||||
#warning set_random_seed_file missing
|
||||
set_random_seed_file(p);
|
||||
#endif
|
||||
gcry_free(p);
|
||||
}
|
||||
|
||||
if( !cmd && opt.fingerprint && !with_fpr ) {
|
||||
set_cmd( &cmd, aListKeys);
|
||||
}
|
||||
|
||||
if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
|
||||
if( cmd == aKModeC ) {
|
||||
@ -1077,8 +1129,8 @@ main( int argc, char **argv )
|
||||
switch( cmd ) {
|
||||
case aPrimegen:
|
||||
case aPrintMD:
|
||||
case aPrintHMAC:
|
||||
case aPrintMDs:
|
||||
case aPrintHMAC:
|
||||
case aGenRandom:
|
||||
case aDeArmor:
|
||||
case aEnArmor:
|
||||
@ -1167,6 +1219,11 @@ main( int argc, char **argv )
|
||||
log_error("verify signatures failed: %s\n", gpg_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aVerifyFiles:
|
||||
if( (rc = verify_files( argc, argv ) ))
|
||||
log_error("verify files failed: %s\n", gpg_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aDecrypt:
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--decrypt [filename]"));
|
||||
@ -1225,16 +1282,28 @@ main( int argc, char **argv )
|
||||
case aListSigs:
|
||||
opt.list_sigs = 1;
|
||||
case aListKeys:
|
||||
/* fixme: we chnaged this in 1.0 */
|
||||
public_key_list( argc, argv );
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
public_key_list( sl );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
case aListSecretKeys:
|
||||
secret_key_list( argc, argv );
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
secret_key_list( sl );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
case aKMode: /* list keyring -- NOTE: This will be removed soon */
|
||||
if( argc < 2 ) /* -kv [userid] */
|
||||
public_key_list( (argc && **argv)? 1:0, argv );
|
||||
if( argc < 2 ) { /* -kv [userid] */
|
||||
sl = NULL;
|
||||
if (argc && **argv)
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
public_key_list( sl );
|
||||
free_strlist(sl);
|
||||
}
|
||||
else if( argc == 2 ) { /* -kv userid keyring */
|
||||
if( access( argv[1], R_OK ) ) {
|
||||
log_error(_("can't open %s: %s\n"),
|
||||
@ -1244,32 +1313,33 @@ main( int argc, char **argv )
|
||||
/* add keyring (default keyrings are not registered in this
|
||||
* special case */
|
||||
add_keyblock_resource( argv[1], 0, 0 );
|
||||
public_key_list( **argv?1:0, argv );
|
||||
sl = NULL;
|
||||
if (**argv)
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
public_key_list( sl );
|
||||
free_strlist(sl);
|
||||
}
|
||||
}
|
||||
else
|
||||
wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
|
||||
break;
|
||||
|
||||
case aKeygen: /* generate a key (interactive) */
|
||||
if( argc )
|
||||
wrong_args("--gen-key");
|
||||
generate_keypair();
|
||||
case aKeygen: /* generate a key */
|
||||
if( opt.batch ) {
|
||||
if( argc > 1 )
|
||||
wrong_args("--gen-key [parameterfile]");
|
||||
generate_keypair( argc? *argv : NULL );
|
||||
}
|
||||
else {
|
||||
if( argc )
|
||||
wrong_args("--gen-key");
|
||||
generate_keypair(NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case aFastImport:
|
||||
case aImport:
|
||||
if( !argc ) {
|
||||
rc = import_keys( NULL, (cmd == aFastImport) );
|
||||
if( rc )
|
||||
log_error("import failed: %s\n", gpg_errstr(rc) );
|
||||
}
|
||||
for( ; argc; argc--, argv++ ) {
|
||||
rc = import_keys( *argv, (cmd == aFastImport) );
|
||||
if( rc )
|
||||
log_error("import from `%s' failed: %s\n",
|
||||
*argv, gpg_errstr(rc) );
|
||||
}
|
||||
import_keys( argc? argv:NULL, argc, (cmd == aFastImport) );
|
||||
break;
|
||||
|
||||
case aExport:
|
||||
@ -1296,6 +1366,14 @@ main( int argc, char **argv )
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
case aExportSecretSub:
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
export_secsubkeys( sl );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
case aGenRevoke:
|
||||
if( argc != 1 )
|
||||
wrong_args("--gen-revoke user-id");
|
||||
@ -1342,7 +1420,7 @@ main( int argc, char **argv )
|
||||
mpi_print( stdout, factors[0], 1 ); /* print q */
|
||||
}
|
||||
else if( mode == 4 && argc == 3 ) {
|
||||
MPI g = mpi_new(8);
|
||||
MPI g = mpi_alloc(1);
|
||||
mpi_print( stdout, generate_elg_prime(
|
||||
0, atoi(argv[1]),
|
||||
atoi(argv[2]), g, NULL ), 1);
|
||||
@ -1424,6 +1502,7 @@ main( int argc, char **argv )
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case aPrintMDs: /* old option */
|
||||
if( !argc )
|
||||
print_mds(NULL,0,NULL);
|
||||
@ -1461,11 +1540,9 @@ main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case aFixTrustDB:
|
||||
log_error("this command is not yet implemented.\"\n");
|
||||
log_error("this command is not yet implemented.\n");
|
||||
log_error("A workaround is to use \"--export-ownertrust\", remove\n");
|
||||
log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
|
||||
#warning removed the next line
|
||||
export_as_kbxfile();
|
||||
break;
|
||||
|
||||
case aListTrustPath:
|
||||
@ -1533,6 +1610,10 @@ main( int argc, char **argv )
|
||||
void
|
||||
gpg_exit( int rc )
|
||||
{
|
||||
#if 0
|
||||
#warning no update_random_seed_file
|
||||
update_random_seed_file();
|
||||
#endif
|
||||
if( opt.debug & DBG_MEMSTAT_VALUE ) {
|
||||
gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
|
||||
gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
|
||||
@ -1629,7 +1710,7 @@ print_mds( const char *fname, int algo, const char *key )
|
||||
if( algo ) {
|
||||
if( fname )
|
||||
fputs( pname, stdout );
|
||||
print_hex( gcry_md_read(md, algo), gcry_md_get_algo_dlen(algo) );
|
||||
print_hex(gcry_md_read(md, algo), gcry_md_get_algo_dlen(algo) );
|
||||
}
|
||||
else {
|
||||
printf( "%s MD5 = ", fname?pname:"" );
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* gpg.c - The GnuPG daemon (keyserver)
|
||||
/* ggpd.c - The GnuPG daemon (keyserver)
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
@ -38,6 +38,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
@ -84,7 +85,7 @@ strusage( int level )
|
||||
case 33:
|
||||
if( !pubkeys )
|
||||
pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string,
|
||||
openpgp_pk_test_algo );
|
||||
check_pubkey_algo );
|
||||
p = pubkeys;
|
||||
break;
|
||||
case 34:
|
||||
@ -137,7 +138,7 @@ set_debug(void)
|
||||
if( opt.debug & DBG_MPI_VALUE )
|
||||
mpi_debug_mode = 1;
|
||||
if( opt.debug & DBG_CIPHER_VALUE )
|
||||
gpgc_debug_mode = 1;
|
||||
g10c_debug_mode = 1;
|
||||
if( opt.debug & DBG_IOBUF_VALUE )
|
||||
iobuf_debug_mode = 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* helptext.c - English help texts
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -224,6 +224,29 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
|
||||
"file (which is shown in brackets) will be used."
|
||||
)},
|
||||
|
||||
/* revoke.c (ask_revocation_reason) */
|
||||
{ "ask_revocation_reason.code", N_(
|
||||
"You should specify a reason for the certification. Depending on the\n"
|
||||
"context you have the ability to choose from this list:\n"
|
||||
" \"Key has been compromised\"\n"
|
||||
" Use this if you have a reason to believe that unauthorized persons\n"
|
||||
" got access to your secret key.\n"
|
||||
" \"Key is superseeded\"\n"
|
||||
" Use this if you have replaced this key with a newer one.\n"
|
||||
" \"Key is no longer used\"\n"
|
||||
" Use this if you have retired this key.\n"
|
||||
" \"User ID is no longer valid\"\n"
|
||||
" Use this to state that the user ID should not longer be used;\n"
|
||||
" this is normally used to mark an email address invalid.\n"
|
||||
)},
|
||||
|
||||
/* revoke.c (ask_revocation_reason) */
|
||||
{ "ask_revocation_reason.text", N_(
|
||||
"If you like, you can enter a text describing why you issue this\n"
|
||||
"revocation certificate. Please keep this text concise.\n"
|
||||
"An empty line ends the text.\n"
|
||||
)},
|
||||
|
||||
/* end of list */
|
||||
{ NULL, NULL } };
|
||||
|
||||
|
38
g10/hkp.c
38
g10/hkp.c
@ -30,7 +30,6 @@
|
||||
#include "util.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "filter.h"
|
||||
#include "http.h"
|
||||
@ -56,19 +55,24 @@ hkp_ask_import( u32 *keyid )
|
||||
struct http_context hd;
|
||||
char *request;
|
||||
int rc;
|
||||
unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0;
|
||||
|
||||
if( !opt.keyserver_name )
|
||||
return -1;
|
||||
log_info("requesting key %08lX from %s ...\n", (ulong)keyid[1],
|
||||
log_info(_("requesting key %08lX from %s ...\n"), (ulong)keyid[1],
|
||||
opt.keyserver_name );
|
||||
request = gcry_xmalloc( strlen( opt.keyserver_name ) + 100 );
|
||||
/* hkp does not accept the long keyid - we should really write a
|
||||
* nicer one */
|
||||
* nicer one :-)
|
||||
* FIXME: request binary mode - need to pass no_armor mode
|
||||
* down to the import function. Marc told that there is such a
|
||||
* binary mode ... how?
|
||||
*/
|
||||
sprintf( request, "x-hkp://%s:11371/pks/lookup?op=get&search=0x%08lX",
|
||||
opt.keyserver_name, (ulong)keyid[1] );
|
||||
rc = http_open_document( &hd, request, 0 );
|
||||
rc = http_open_document( &hd, request, hflags );
|
||||
if( rc ) {
|
||||
log_info("can't get key from keyserver: %s\n",
|
||||
log_info(_("can't get key from keyserver: %s\n"),
|
||||
rc == GPGERR_NETWORK? strerror(errno)
|
||||
: gpg_errstr(rc) );
|
||||
}
|
||||
@ -91,7 +95,7 @@ hkp_import( STRLIST users )
|
||||
return -1;
|
||||
#else
|
||||
if( !opt.keyserver_name ) {
|
||||
log_error("no keyserver known (use option --keyserver)\n");
|
||||
log_error(_("no keyserver known (use option --keyserver)\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -99,10 +103,15 @@ hkp_import( STRLIST users )
|
||||
u32 kid[2];
|
||||
int type = classify_user_id( users->d, kid, NULL, NULL, NULL );
|
||||
if( type != 10 && type != 11 ) {
|
||||
log_info("%s: not a valid key ID\n", users->d );
|
||||
log_info(_("%s: not a valid key ID\n"), users->d );
|
||||
continue;
|
||||
}
|
||||
hkp_ask_import( kid );
|
||||
/* because the function may use log_info in some situations, the
|
||||
* errorcounter ist not increaed and the program will return
|
||||
* with success - which is not good when this function is used.
|
||||
*/
|
||||
if( hkp_ask_import( kid ) )
|
||||
log_inc_errorcount();
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
@ -121,9 +130,10 @@ hkp_export( STRLIST users )
|
||||
struct http_context hd;
|
||||
char *request;
|
||||
unsigned int status;
|
||||
unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0;
|
||||
|
||||
if( !opt.keyserver_name ) {
|
||||
log_error("no keyserver known (use option --keyserver)\n");
|
||||
log_error(_("no keyserver known (use option --keyserver)\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -143,9 +153,9 @@ hkp_export( STRLIST users )
|
||||
|
||||
request = gcry_xmalloc( strlen( opt.keyserver_name ) + 100 );
|
||||
sprintf( request, "x-hkp://%s:11371/pks/add", opt.keyserver_name );
|
||||
rc = http_open( &hd, HTTP_REQ_POST, request , 0 );
|
||||
rc = http_open( &hd, HTTP_REQ_POST, request , hflags );
|
||||
if( rc ) {
|
||||
log_error("can't connect to `%s': %s\n",
|
||||
log_error(_("can't connect to `%s': %s\n"),
|
||||
opt.keyserver_name,
|
||||
rc == GPGERR_NETWORK? strerror(errno)
|
||||
: gpg_errstr(rc) );
|
||||
@ -169,7 +179,7 @@ hkp_export( STRLIST users )
|
||||
|
||||
rc = http_wait_response( &hd, &status );
|
||||
if( rc ) {
|
||||
log_error("error sending to `%s': %s\n",
|
||||
log_error(_("error sending to `%s': %s\n"),
|
||||
opt.keyserver_name, gpg_errstr(rc) );
|
||||
}
|
||||
else {
|
||||
@ -181,10 +191,10 @@ hkp_export( STRLIST users )
|
||||
}
|
||||
#endif
|
||||
if( (status/100) == 2 )
|
||||
log_info("success sending to `%s' (status=%u)\n",
|
||||
log_info(_("success sending to `%s' (status=%u)\n"),
|
||||
opt.keyserver_name, status );
|
||||
else
|
||||
log_error("failed sending to `%s': status=%u\n",
|
||||
log_error(_("failed sending to `%s': status=%u\n"),
|
||||
opt.keyserver_name, status );
|
||||
}
|
||||
http_close( &hd );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* hkp.h - Horrowitz Keyserver Protocol
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
106
g10/import.c
106
g10/import.c
@ -1,5 +1,5 @@
|
||||
/* import.c
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -38,6 +38,7 @@
|
||||
|
||||
|
||||
static struct {
|
||||
ulong count;
|
||||
ulong no_user_id;
|
||||
ulong imported;
|
||||
ulong imported_rsa;
|
||||
@ -53,6 +54,7 @@ static struct {
|
||||
|
||||
|
||||
static int import( IOBUF inp, int fast, const char* fname );
|
||||
static void print_stats(void);
|
||||
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
|
||||
static int import_one( const char *fname, KBNODE keyblock, int fast );
|
||||
static int import_secret_one( const char *fname, KBNODE keyblock );
|
||||
@ -105,30 +107,51 @@ static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
|
||||
* Key revocation certificates have special handling.
|
||||
*
|
||||
*/
|
||||
int
|
||||
import_keys( const char *fname, int fast )
|
||||
void
|
||||
import_keys( char **fnames, int nnames, int fast )
|
||||
{
|
||||
IOBUF inp = NULL;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
inp = iobuf_open(fname);
|
||||
if( !fname )
|
||||
fname = "[stdin]";
|
||||
if( !inp ) {
|
||||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
return GPGERR_OPEN_FILE;
|
||||
/* fixme: don't use static variables */
|
||||
memset( &stats, 0, sizeof( stats ) );
|
||||
|
||||
if( !fnames && !nnames )
|
||||
nnames = 1; /* Ohh what a ugly hack to jump into the loop */
|
||||
|
||||
for(i=0; i < nnames; i++ ) {
|
||||
const char *fname = fnames? fnames[i] : NULL;
|
||||
IOBUF inp = iobuf_open(fname);
|
||||
if( !fname )
|
||||
fname = "[stdin]";
|
||||
if( !inp )
|
||||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
else {
|
||||
int rc = import( inp, fast, fname );
|
||||
iobuf_close(inp);
|
||||
if( rc )
|
||||
log_error("import from `%s' failed: %s\n", fname,
|
||||
gpg_errstr(rc) );
|
||||
}
|
||||
if( !fname )
|
||||
break;
|
||||
}
|
||||
|
||||
rc = import( inp, fast, fname );
|
||||
|
||||
iobuf_close(inp);
|
||||
return rc;
|
||||
print_stats();
|
||||
if( !fast )
|
||||
sync_trustdb();
|
||||
}
|
||||
|
||||
int
|
||||
import_keys_stream( IOBUF inp, int fast )
|
||||
{
|
||||
return import( inp, fast, "[stream]" );
|
||||
int rc = 0;
|
||||
|
||||
/* fixme: don't use static variables */
|
||||
memset( &stats, 0, sizeof( stats ) );
|
||||
rc = import( inp, fast, "[stream]" );
|
||||
print_stats();
|
||||
if( !fast )
|
||||
sync_trustdb();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -137,10 +160,6 @@ import( IOBUF inp, int fast, const char* fname )
|
||||
PACKET *pending_pkt = NULL;
|
||||
KBNODE keyblock;
|
||||
int rc = 0;
|
||||
ulong count=0;
|
||||
|
||||
/* fixme: don't use static variables */
|
||||
memset( &stats, 0, sizeof( stats ) );
|
||||
|
||||
getkey_disable_caches();
|
||||
|
||||
@ -165,16 +184,23 @@ import( IOBUF inp, int fast, const char* fname )
|
||||
release_kbnode(keyblock);
|
||||
if( rc )
|
||||
break;
|
||||
if( !(++count % 100) && !opt.quiet )
|
||||
log_info(_("%lu keys so far processed\n"), count );
|
||||
if( !(++stats.count % 100) && !opt.quiet )
|
||||
log_info(_("%lu keys so far processed\n"), stats.count );
|
||||
}
|
||||
if( rc == -1 )
|
||||
rc = 0;
|
||||
else if( rc && rc != GPGERR_INV_KEYRING )
|
||||
log_error( _("error reading `%s': %s\n"), fname, gpg_errstr(rc));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_stats()
|
||||
{
|
||||
if( !opt.quiet ) {
|
||||
log_info(_("Total number processed: %lu\n"), count );
|
||||
log_info(_("Total number processed: %lu\n"), stats.count );
|
||||
if( stats.no_user_id )
|
||||
log_info(_(" w/o user IDs: %lu\n"), stats.no_user_id );
|
||||
if( stats.imported || stats.imported_rsa ) {
|
||||
@ -202,9 +228,9 @@ import( IOBUF inp, int fast, const char* fname )
|
||||
}
|
||||
|
||||
if( is_status_enabled() ) {
|
||||
char buf[12*16];
|
||||
char buf[12*20];
|
||||
sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
|
||||
count,
|
||||
stats.count,
|
||||
stats.no_user_id,
|
||||
stats.imported,
|
||||
stats.imported_rsa,
|
||||
@ -218,8 +244,6 @@ import( IOBUF inp, int fast, const char* fname )
|
||||
stats.secret_dups);
|
||||
write_status_text( STATUS_IMPORT_RES, buf );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -354,8 +378,8 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
||||
pubkey_letter( pk->pubkey_algo ),
|
||||
(ulong)keyid[1], datestr_from_pk(pk) );
|
||||
if( uidnode )
|
||||
print_string( stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len, 0 );
|
||||
print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
if( !uidnode ) {
|
||||
@ -545,8 +569,8 @@ import_secret_one( const char *fname, KBNODE keyblock )
|
||||
pubkey_letter( sk->pubkey_algo ),
|
||||
(ulong)keyid[1], datestr_from_sk(sk) );
|
||||
if( uidnode )
|
||||
print_string( stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len, 0 );
|
||||
print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
stats.secret_read++;
|
||||
@ -678,6 +702,15 @@ import_revoke_cert( const char *fname, KBNODE node )
|
||||
log_info( _("key %08lX: revocation certificate imported\n"),
|
||||
(ulong)keyid[1]);
|
||||
stats.n_revoc++;
|
||||
if( clear_trust_checked_flag( pk ) ) {
|
||||
/* seems that we have to insert the record first */
|
||||
rc = insert_trust_record( keyblock );
|
||||
if( rc )
|
||||
log_error("key %08lX: trustdb insert failed: %s\n",
|
||||
(ulong)keyid[1], gpg_errstr(rc) );
|
||||
else
|
||||
rc = clear_trust_checked_flag( pk );
|
||||
}
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
@ -764,7 +797,8 @@ mark_non_selfsigned_uids_valid( KBNODE keyblock, u32 *kid )
|
||||
KBNODE node;
|
||||
for(node=keyblock->next; node; node = node->next ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) ) {
|
||||
if( node->next && node->next->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
if( (node->next && node->next->pkt->pkttype == PKT_SIGNATURE)
|
||||
|| !node->next ) {
|
||||
node->flag |= 1;
|
||||
log_info( _("key %08lX: accepted non self-signed user ID '"),
|
||||
(ulong)kid[1]);
|
||||
@ -797,8 +831,8 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
|
||||
if( opt.verbose ) {
|
||||
log_info( _("key %08lX: skipped user ID '"),
|
||||
(ulong)keyid[1]);
|
||||
print_string( stderr, node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len, 0 );
|
||||
print_utf8_string( stderr, node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
fputs("'\n", stderr );
|
||||
}
|
||||
delete_kbnode( node ); /* the user-id */
|
||||
@ -831,7 +865,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
|
||||
}
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& openpgp_pk_test_algo( node->pkt->pkt.signature->pubkey_algo, 0)
|
||||
&& openpgp_pk_test_algo( node->pkt->pkt.signature->pubkey_algo, 0 )
|
||||
&& node->pkt->pkt.signature->pubkey_algo != GCRY_PK_RSA )
|
||||
delete_kbnode( node ); /* build_packet() can't handle this */
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* kbnode.c - keyblock node utility functions
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -23,8 +23,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "keydb.h"
|
||||
|
||||
@ -165,7 +166,7 @@ find_prev_kbnode( KBNODE root, KBNODE node, int pkttype )
|
||||
KBNODE n1;
|
||||
|
||||
for(n1=NULL ; root && root != node; root = root->next )
|
||||
if( !pkttype || root->pkt->pkttype == pkttype )
|
||||
if( !pkttype || root->pkt->pkttype == pkttype )
|
||||
n1 = root;
|
||||
return n1;
|
||||
}
|
||||
|
@ -511,7 +511,7 @@ kbx_create_blob ( KBXBLOB *r_blob, KBNODE keyblock )
|
||||
KBXBLOB blob;
|
||||
|
||||
*r_blob = NULL;
|
||||
blob = gcry_calloc (1, sizeof *blob );
|
||||
blob = gcry_xcalloc (1, sizeof *blob );
|
||||
if( !blob )
|
||||
return GCRYERR_NO_MEM;
|
||||
|
||||
@ -529,9 +529,9 @@ kbx_create_blob ( KBXBLOB *r_blob, KBNODE keyblock )
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
blob->keys = gcry_calloc ( blob->nkeys, sizeof ( *blob->keys ) );
|
||||
blob->uids = gcry_calloc ( blob->nuids, sizeof ( *blob->uids ) );
|
||||
blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( *blob->sigs ) );
|
||||
blob->keys = gcry_xcalloc ( blob->nkeys, sizeof ( *blob->keys ) );
|
||||
blob->uids = gcry_xcalloc ( blob->nuids, sizeof ( *blob->uids ) );
|
||||
blob->sigs = gcry_xcalloc ( blob->nsigs, sizeof ( *blob->sigs ) );
|
||||
if ( !blob->keys || !blob->uids || !blob->sigs ) {
|
||||
rc = GCRYERR_NO_MEM;
|
||||
goto leave;
|
||||
@ -581,7 +581,7 @@ kbx_new_blob ( KBXBLOB *r_blob, char *image, size_t imagelen )
|
||||
KBXBLOB blob;
|
||||
|
||||
*r_blob = NULL;
|
||||
blob = gcry_calloc (1, sizeof *blob );
|
||||
blob = gcry_xcalloc (1, sizeof *blob );
|
||||
if( !blob )
|
||||
return GCRYERR_NO_MEM;
|
||||
blob->blob = image;
|
||||
|
@ -321,7 +321,7 @@ print_kbxfile( const char *filename )
|
||||
fp = fopen ( filename, "rb" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
while ( !do_print_kbxfile( filename, fp ) )
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* keydb.h - Key database
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,6 +25,7 @@
|
||||
#include <gdbm.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "basicdefs.h"
|
||||
#include "packet.h"
|
||||
|
||||
@ -156,6 +157,7 @@ void get_seckey_end( GETKEY_CTX ctx );
|
||||
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
|
||||
void merge_keys_and_selfsig( KBNODE keyblock );
|
||||
char*get_user_id_string( u32 *keyid );
|
||||
char*get_user_id_string_native( u32 *keyid );
|
||||
char*get_long_user_id_string( u32 *keyid );
|
||||
char*get_user_id( u32 *keyid, size_t *rn );
|
||||
|
||||
@ -197,6 +199,7 @@ const char *enum_keyblock_resources( int *sequence, int secret );
|
||||
int add_keyblock_resource( const char *resname, int force, int secret );
|
||||
const char *keyblock_resource_name( KBPOS *kbpos );
|
||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||
char *get_writable_keyblock_file( int secret );
|
||||
int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
|
||||
int fprlen, int secret );
|
||||
int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
|
||||
|
182
g10/keyedit.c
182
g10/keyedit.c
@ -1,5 +1,5 @@
|
||||
/* keyedit.c - keyedit stuff
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -74,8 +74,9 @@ static int enable_disable_key( KBNODE keyblock, int disable );
|
||||
#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
|
||||
|
||||
|
||||
struct sign_uid_attrib {
|
||||
struct sign_attrib {
|
||||
int non_exportable;
|
||||
struct revocation_reason_info *reason;
|
||||
};
|
||||
|
||||
|
||||
@ -157,7 +158,7 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
|
||||
else {
|
||||
size_t n;
|
||||
char *p = get_user_id( sig->keyid, &n );
|
||||
tty_print_utf8_string( p, n > 40? 40 : n );
|
||||
tty_print_utf8_string2( p, n, 40 );
|
||||
gcry_free(p);
|
||||
}
|
||||
tty_printf("\n");
|
||||
@ -239,16 +240,18 @@ check_all_keysigs( KBNODE keyblock, int only_selected )
|
||||
|
||||
|
||||
|
||||
int
|
||||
sign_uid_mk_attrib( PKT_signature *sig, void *opaque )
|
||||
static int
|
||||
sign_mk_attrib( PKT_signature *sig, void *opaque )
|
||||
{
|
||||
struct sign_uid_attrib *attrib = opaque;
|
||||
struct sign_attrib *attrib = opaque;
|
||||
byte buf[8];
|
||||
|
||||
if( attrib->non_exportable ) {
|
||||
buf[0] = 0; /* not exportable */
|
||||
build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
|
||||
}
|
||||
if( attrib->reason )
|
||||
revocation_reason_build_cb( sig, attrib->reason );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -353,7 +356,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
|
||||
&& (node->flag & NODFLG_MARK_A) ) {
|
||||
PACKET *pkt;
|
||||
PKT_signature *sig;
|
||||
struct sign_uid_attrib attrib;
|
||||
struct sign_attrib attrib;
|
||||
|
||||
assert( primary_pk );
|
||||
memset( &attrib, 0, sizeof attrib );
|
||||
@ -364,7 +367,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
|
||||
NULL,
|
||||
sk,
|
||||
0x10, 0,
|
||||
sign_uid_mk_attrib,
|
||||
sign_mk_attrib,
|
||||
&attrib );
|
||||
if( rc ) {
|
||||
log_error(_("signing failed: %s\n"), gpg_errstr(rc));
|
||||
@ -407,6 +410,7 @@ change_passphrase( KBNODE keyblock )
|
||||
KBNODE node;
|
||||
PKT_secret_key *sk;
|
||||
char *passphrase = NULL;
|
||||
int no_primary_secrets = 0;
|
||||
|
||||
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
||||
if( !node ) {
|
||||
@ -423,10 +427,16 @@ change_passphrase( KBNODE keyblock )
|
||||
tty_printf(_("This key is not protected.\n"));
|
||||
break;
|
||||
default:
|
||||
tty_printf(_("Key is protected.\n"));
|
||||
rc = check_secret_key( sk, 0 );
|
||||
if( !rc )
|
||||
passphrase = get_last_passphrase();
|
||||
if( sk->protect.s2k.mode == 1001 ) {
|
||||
tty_printf(_("Secret parts of primary key are not available.\n"));
|
||||
no_primary_secrets = 1;
|
||||
}
|
||||
else {
|
||||
tty_printf(_("Key is protected.\n"));
|
||||
rc = check_secret_key( sk, 0 );
|
||||
if( !rc )
|
||||
passphrase = get_last_passphrase();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -436,6 +446,8 @@ change_passphrase( KBNODE keyblock )
|
||||
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
|
||||
set_next_passphrase( passphrase );
|
||||
rc = check_secret_key( subsk, 0 );
|
||||
if( !rc && !passphrase )
|
||||
passphrase = get_last_passphrase();
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,9 +477,12 @@ change_passphrase( KBNODE keyblock )
|
||||
break;
|
||||
}
|
||||
else { /* okay */
|
||||
sk->protect.algo = dek->algo;
|
||||
sk->protect.s2k = *s2k;
|
||||
rc = protect_secret_key( sk, dek );
|
||||
rc = 0;
|
||||
if( !no_primary_secrets ) {
|
||||
sk->protect.algo = dek->algo;
|
||||
sk->protect.s2k = *s2k;
|
||||
rc = protect_secret_key( sk, dek );
|
||||
}
|
||||
for(node=keyblock; !rc && node; node = node->next ) {
|
||||
if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
||||
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
|
||||
@ -558,41 +573,42 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
static struct { const char *name;
|
||||
enum cmdids id;
|
||||
int need_sk;
|
||||
int not_with_sk;
|
||||
int signmode;
|
||||
const char *desc;
|
||||
} cmds[] = {
|
||||
{ N_("quit") , cmdQUIT , 0,1, N_("quit this menu") },
|
||||
{ N_("q") , cmdQUIT , 0,1, NULL },
|
||||
{ N_("save") , cmdSAVE , 0,1, N_("save and quit") },
|
||||
{ N_("help") , cmdHELP , 0,1, N_("show this help") },
|
||||
{ "?" , cmdHELP , 0,1, NULL },
|
||||
{ N_("fpr") , cmdFPR , 0,1, N_("show fingerprint") },
|
||||
{ N_("list") , cmdLIST , 0,1, N_("list key and user IDs") },
|
||||
{ N_("l") , cmdLIST , 0,1, NULL },
|
||||
{ N_("uid") , cmdSELUID , 0,1, N_("select user ID N") },
|
||||
{ N_("key") , cmdSELKEY , 0,0, N_("select secondary key N") },
|
||||
{ N_("check") , cmdCHECK , 0,1, N_("list signatures") },
|
||||
{ N_("c") , cmdCHECK , 0,1, NULL },
|
||||
{ N_("sign") , cmdSIGN , 0,1, N_("sign the key") },
|
||||
{ N_("s") , cmdSIGN , 0,1, NULL },
|
||||
{ N_("lsign") , cmdLSIGN , 0,1, N_("sign the key locally") },
|
||||
{ N_("debug") , cmdDEBUG , 0,0, NULL },
|
||||
{ N_("adduid") , cmdADDUID , 1,0, N_("add a user ID") },
|
||||
{ N_("deluid") , cmdDELUID , 0,0, N_("delete user ID") },
|
||||
{ N_("addkey") , cmdADDKEY , 1,0, N_("add a secondary key") },
|
||||
{ N_("delkey") , cmdDELKEY , 0,0, N_("delete a secondary key") },
|
||||
{ N_("delsig") , cmdDELSIG , 0,0, N_("delete signatures") },
|
||||
{ N_("expire") , cmdEXPIRE , 1,0, N_("change the expire date") },
|
||||
{ N_("toggle") , cmdTOGGLE , 1,0, N_("toggle between secret "
|
||||
"and public key listing") },
|
||||
{ N_("t" ) , cmdTOGGLE , 1,0, NULL },
|
||||
{ N_("pref") , cmdPREF , 0,0, N_("list preferences") },
|
||||
{ N_("passwd") , cmdPASSWD , 1,0, N_("change the passphrase") },
|
||||
{ N_("trust") , cmdTRUST , 0,0, N_("change the ownertrust") },
|
||||
{ N_("revsig") , cmdREVSIG , 0,0, N_("revoke signatures") },
|
||||
{ N_("revkey") , cmdREVKEY , 1,0, N_("revoke a secondary key") },
|
||||
{ N_("disable") , cmdDISABLEKEY, 0,0, N_("disable a key") },
|
||||
{ N_("enable") , cmdENABLEKEY , 0,0, N_("enable a key") },
|
||||
{ N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") },
|
||||
{ N_("q") , cmdQUIT , 0,0,1, NULL },
|
||||
{ N_("save") , cmdSAVE , 0,0,1, N_("save and quit") },
|
||||
{ N_("help") , cmdHELP , 0,0,1, N_("show this help") },
|
||||
{ "?" , cmdHELP , 0,0,1, NULL },
|
||||
{ N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") },
|
||||
{ N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") },
|
||||
{ N_("l") , cmdLIST , 0,0,1, NULL },
|
||||
{ N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") },
|
||||
{ N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") },
|
||||
{ N_("check") , cmdCHECK , 0,0,1, N_("list signatures") },
|
||||
{ N_("c") , cmdCHECK , 0,0,1, NULL },
|
||||
{ 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_("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") },
|
||||
{ N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") },
|
||||
{ N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") },
|
||||
{ N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") },
|
||||
{ N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret "
|
||||
"and public key listing") },
|
||||
{ N_("t" ) , cmdTOGGLE , 1,0,0, NULL },
|
||||
{ N_("pref") , cmdPREF , 0,1,0, N_("list preferences") },
|
||||
{ N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") },
|
||||
{ N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") },
|
||||
{ N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") },
|
||||
{ N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") },
|
||||
{ N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
|
||||
{ N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") },
|
||||
|
||||
{ NULL, cmdNONE } };
|
||||
enum cmdids cmd = 0;
|
||||
@ -678,7 +694,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
have_commands = 0;
|
||||
}
|
||||
if( !have_commands ) {
|
||||
answer = cpr_get("", _("Command> "));
|
||||
answer = cpr_get("keyedit.prompt", _("Command> "));
|
||||
cpr_kill_prompt();
|
||||
}
|
||||
trim_spaces(answer);
|
||||
@ -711,6 +727,10 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
tty_printf(_("Need the secret key to do this.\n"));
|
||||
cmd = cmdNOP;
|
||||
}
|
||||
else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
|
||||
tty_printf(_("Please use the command \"toggle\" first.\n"));
|
||||
cmd = cmdNOP;
|
||||
}
|
||||
else
|
||||
cmd = cmds[i].id;
|
||||
}
|
||||
@ -763,6 +783,11 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
if( !sign_uids( keyblock, locusr, &modified, cmd == cmdLSIGN )
|
||||
&& sign_mode )
|
||||
goto do_cmd_save;
|
||||
/* Actually we should do a update_trust_record() here so that
|
||||
* the trust gets displayed correctly. however this is not possible
|
||||
* because we would have to save the keyblock first - something
|
||||
* we don't want to do without an explicit save command.
|
||||
*/
|
||||
break;
|
||||
|
||||
case cmdDEBUG:
|
||||
@ -1005,7 +1030,13 @@ show_prefs( KBNODE keyblock, PKT_user_id *uid )
|
||||
return;
|
||||
}
|
||||
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, uid->name, uid->len );
|
||||
if( uid->photo ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, uid->photo,
|
||||
uid->photolen );
|
||||
}
|
||||
else {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, uid->name, uid->len );
|
||||
}
|
||||
|
||||
p = get_pref_data( pk->local_id, namehash, &n );
|
||||
if( !p )
|
||||
@ -1049,7 +1080,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
otrust = get_ownertrust_info( pk->local_id );
|
||||
}
|
||||
|
||||
tty_printf("%s%c %4u%c/%08lX created: %s expires: %s",
|
||||
tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
|
||||
node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
|
||||
(node->flag & NODFLG_SELKEY)? '*':' ',
|
||||
nbits_from_pk( pk ),
|
||||
@ -1058,7 +1089,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
datestr_from_pk(pk),
|
||||
expirestr_from_pk(pk) );
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
||||
tty_printf(" trust: %c/%c", otrust, trust );
|
||||
tty_printf(_(" trust: %c/%c"), otrust, trust );
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
&& (get_ownertrust( pk->local_id )&TRUST_FLAG_DISABLED)) {
|
||||
tty_printf("\n*** ");
|
||||
@ -1075,14 +1106,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
else if( node->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
|
||||
PKT_secret_key *sk = node->pkt->pkt.secret_key;
|
||||
tty_printf("%s%c %4u%c/%08lX created: %s expires: %s\n",
|
||||
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"sbb",
|
||||
tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
|
||||
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
|
||||
(node->flag & NODFLG_SELKEY)? '*':' ',
|
||||
nbits_from_sk( sk ),
|
||||
pubkey_letter( sk->pubkey_algo ),
|
||||
(ulong)keyid_from_sk(sk,NULL),
|
||||
datestr_from_sk(sk),
|
||||
expirestr_from_sk(sk) );
|
||||
tty_printf("\n");
|
||||
}
|
||||
else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& node->pkt->pkt.signature->sig_class == 0x28 ) {
|
||||
@ -1090,12 +1122,12 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
|
||||
rc = check_key_signature( keyblock, node, NULL );
|
||||
if( !rc )
|
||||
tty_printf( "rev! subkey has been revoked: %s\n",
|
||||
tty_printf( _("rev! subkey has been revoked: %s\n"),
|
||||
datestr_from_sig( sig ) );
|
||||
else if( rc == GPGERR_BAD_SIGN )
|
||||
tty_printf( "rev- faked revocation found\n" );
|
||||
tty_printf( _("rev- faked revocation found\n") );
|
||||
else if( rc )
|
||||
tty_printf( "rev? problem checking revocation: %s\n",
|
||||
tty_printf( _("rev? problem checking revocation: %s\n"),
|
||||
gpg_errstr(rc) );
|
||||
}
|
||||
}
|
||||
@ -1156,7 +1188,7 @@ show_fingerprint( PKT_public_key *pk )
|
||||
|
||||
fingerprint_from_pk( pk, array, &n );
|
||||
p = array;
|
||||
tty_printf(" Fingerprint:");
|
||||
tty_printf(_(" Fingerprint:"));
|
||||
if( n == 20 ) {
|
||||
for(i=0; i < n ; i++, i++, p += 2 ) {
|
||||
if( i == 10 )
|
||||
@ -1471,7 +1503,8 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_USER_ID )
|
||||
uid = node->pkt->pkt.user_id;
|
||||
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& sub_pk != NULL ) {
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
|
||||
&& ( (mainkey && uid && (sig->sig_class&~3) == 0x10)
|
||||
@ -1535,6 +1568,7 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
gcry_free( sn->pkt );
|
||||
sn->pkt = newpkt;
|
||||
}
|
||||
sub_pk = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1735,6 +1769,7 @@ menu_revsig( KBNODE keyblock )
|
||||
int changed = 0;
|
||||
int upd_trust = 0;
|
||||
int rc, any;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
|
||||
/* FIXME: detect duplicates here */
|
||||
tty_printf(_("You have signed these user IDs:\n"));
|
||||
@ -1797,6 +1832,10 @@ menu_revsig( KBNODE keyblock )
|
||||
_("Really create the revocation certificates? (y/N)")) )
|
||||
return 0; /* forget it */
|
||||
|
||||
reason = ask_revocation_reason( 0, 1, 0 );
|
||||
if( !reason ) { /* user decided to cancel */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now we can sign the user ids */
|
||||
reloop: /* (must use this, because we are modifing the list) */
|
||||
@ -1804,7 +1843,7 @@ menu_revsig( KBNODE keyblock )
|
||||
for( node=keyblock; node; node = node->next ) {
|
||||
KBNODE unode;
|
||||
PACKET *pkt;
|
||||
struct sign_uid_attrib attrib;
|
||||
struct sign_attrib attrib;
|
||||
PKT_secret_key *sk;
|
||||
|
||||
if( !(node->flag & NODFLG_MARK_A)
|
||||
@ -1814,8 +1853,10 @@ menu_revsig( KBNODE keyblock )
|
||||
assert( unode ); /* we already checked this */
|
||||
|
||||
memset( &attrib, 0, sizeof attrib );
|
||||
attrib.reason = reason;
|
||||
|
||||
node->flag &= ~NODFLG_MARK_A;
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
sk = gcry_xcalloc_secure( 1, sizeof *sk );
|
||||
if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
|
||||
log_info(_("no secret key\n"));
|
||||
continue;
|
||||
@ -1825,11 +1866,12 @@ menu_revsig( KBNODE keyblock )
|
||||
NULL,
|
||||
sk,
|
||||
0x30, 0,
|
||||
sign_uid_mk_attrib,
|
||||
sign_mk_attrib,
|
||||
&attrib );
|
||||
free_secret_key(sk);
|
||||
if( rc ) {
|
||||
log_error(_("signing failed: %s\n"), gpg_errstr(rc));
|
||||
release_revocation_reason_info( reason );
|
||||
return changed;
|
||||
}
|
||||
changed = 1; /* we changed the keyblock */
|
||||
@ -1844,7 +1886,7 @@ menu_revsig( KBNODE keyblock )
|
||||
|
||||
if( upd_trust )
|
||||
clear_trust_checked_flag( primary_pk );
|
||||
|
||||
release_revocation_reason_info( reason );
|
||||
return changed;
|
||||
}
|
||||
|
||||
@ -1861,6 +1903,13 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
int changed = 0;
|
||||
int upd_trust = 0;
|
||||
int rc;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
|
||||
reason = ask_revocation_reason( 1, 0, 0 );
|
||||
if( !reason ) { /* user decided to cancel */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
reloop: /* (better this way because we are modifing the keyring) */
|
||||
mainpk = pub_keyblock->pkt->pkt.public_key;
|
||||
@ -1871,14 +1920,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
PKT_signature *sig;
|
||||
PKT_secret_key *sk;
|
||||
PKT_public_key *subpk = node->pkt->pkt.public_key;
|
||||
struct sign_attrib attrib;
|
||||
|
||||
memset( &attrib, 0, sizeof attrib );
|
||||
attrib.reason = reason;
|
||||
|
||||
node->flag &= ~NODFLG_SELKEY;
|
||||
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
|
||||
rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0,
|
||||
NULL, NULL );
|
||||
sign_mk_attrib,
|
||||
&attrib );
|
||||
free_secret_key(sk);
|
||||
if( rc ) {
|
||||
log_error(_("signing failed: %s\n"), gpg_errstr(rc));
|
||||
release_revocation_reason_info( reason );
|
||||
return changed;
|
||||
}
|
||||
changed = 1; /* we changed the keyblock */
|
||||
@ -1897,6 +1952,7 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
if( upd_trust )
|
||||
clear_trust_checked_flag( mainpk );
|
||||
|
||||
release_revocation_reason_info( reason );
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
954
g10/keygen.c
954
g10/keygen.c
File diff suppressed because it is too large
Load Diff
10
g10/keyid.c
10
g10/keyid.c
@ -1,5 +1,5 @@
|
||||
/* keyid.c - jeyid and fingerprint handling
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,12 +25,14 @@
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "packet.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
int
|
||||
@ -52,7 +54,7 @@ static GCRY_MD_HD
|
||||
do_fingerprint_md( PKT_public_key *pk )
|
||||
{
|
||||
GCRY_MD_HD md;
|
||||
unsigned n;
|
||||
unsigned int n;
|
||||
unsigned int nn[GNUPG_MAX_NPKEY];
|
||||
byte *pp[GNUPG_MAX_NPKEY];
|
||||
int i;
|
||||
@ -339,7 +341,7 @@ expirestr_from_pk( PKT_public_key *pk )
|
||||
time_t atime;
|
||||
|
||||
if( !pk->expiredate )
|
||||
return "never ";
|
||||
return _("never ");
|
||||
atime = pk->expiredate;
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
@ -354,7 +356,7 @@ expirestr_from_sk( PKT_secret_key *sk )
|
||||
time_t atime;
|
||||
|
||||
if( !sk->expiredate )
|
||||
return "never ";
|
||||
return _("never ");
|
||||
atime = sk->expiredate;
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* keylist.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -43,34 +43,24 @@ static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
|
||||
|
||||
/****************
|
||||
* List the keys
|
||||
* If NNAMES is 0; all available keys are listed
|
||||
* If list is NULL, all available keys are listed
|
||||
*/
|
||||
void
|
||||
public_key_list( int nnames, char **names )
|
||||
public_key_list( STRLIST list )
|
||||
{
|
||||
if( !nnames )
|
||||
if( !list )
|
||||
list_all(0);
|
||||
else { /* List by user id */
|
||||
STRLIST list = NULL;
|
||||
for( ; nnames ; nnames--, names++ )
|
||||
add_to_strlist( &list, *names );
|
||||
else
|
||||
list_one( list, 0 );
|
||||
free_strlist( list );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
secret_key_list( int nnames, char **names )
|
||||
secret_key_list( STRLIST list )
|
||||
{
|
||||
if( !nnames )
|
||||
if( !list )
|
||||
list_all(1);
|
||||
else { /* List by user id */
|
||||
STRLIST list = NULL;
|
||||
for( ; nnames ; nnames--, names++ )
|
||||
add_to_strlist( &list, *names );
|
||||
else /* List by user id */
|
||||
list_one( list, 1 );
|
||||
free_strlist( list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -145,6 +135,7 @@ list_one( STRLIST names, int secret )
|
||||
return;
|
||||
}
|
||||
do {
|
||||
merge_keys_and_selfsig( keyblock );
|
||||
list_keyblock( keyblock, 0 );
|
||||
release_kbnode( keyblock );
|
||||
} while( !get_pubkey_next( ctx, NULL, &keyblock ) );
|
||||
@ -155,7 +146,7 @@ list_one( STRLIST names, int secret )
|
||||
static void
|
||||
print_key_data( PKT_public_key *pk, u32 *keyid )
|
||||
{
|
||||
int n = pubkey_get_npkey( pk->pubkey_algo );
|
||||
int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
|
||||
int i;
|
||||
|
||||
for(i=0; i < n; i++ ) {
|
||||
@ -211,21 +202,26 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
sk = NULL;
|
||||
keyid_from_pk( pk, keyid );
|
||||
if( opt.with_colons ) {
|
||||
trustletter = query_trust_info( pk, NULL );
|
||||
if( trustletter == 'u' )
|
||||
ulti_hack = 1;
|
||||
printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
|
||||
trustletter,
|
||||
if ( opt.fast_list_mode ) {
|
||||
fputs( "pub::", stdout );
|
||||
trustletter = 0;
|
||||
}
|
||||
else {
|
||||
trustletter = query_trust_info( pk, NULL );
|
||||
if( trustletter == 'u' )
|
||||
ulti_hack = 1;
|
||||
printf("pub:%c:", trustletter );
|
||||
}
|
||||
printf("%u:%d:%08lX%08lX:%s:%s:",
|
||||
nbits_from_pk( pk ),
|
||||
pk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_pk( pk ),
|
||||
pk->expiredate? strtimestamp(pk->expiredate):""
|
||||
);
|
||||
pk->expiredate? strtimestamp(pk->expiredate):"" );
|
||||
if( pk->local_id )
|
||||
printf("%lu", pk->local_id );
|
||||
putchar(':');
|
||||
if( pk->local_id )
|
||||
if( pk->local_id && !opt.fast_list_mode )
|
||||
putchar( get_ownertrust_info( pk->local_id ) );
|
||||
putchar(':');
|
||||
}
|
||||
@ -237,15 +233,22 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
}
|
||||
|
||||
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
|
||||
if( any ) {
|
||||
if( opt.with_colons ) {
|
||||
if ( opt.with_colons ) {
|
||||
byte namehash[20];
|
||||
|
||||
if( pk && !ulti_hack ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
if( node->pkt->pkt.user_id->photo ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
}
|
||||
else {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, namehash,
|
||||
node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
}
|
||||
trustletter = query_trust_info( pk, namehash );
|
||||
}
|
||||
else
|
||||
@ -288,8 +291,13 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
|
||||
keyid_from_pk( pk2, keyid2 );
|
||||
if( opt.with_colons ) {
|
||||
printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
|
||||
trustletter,
|
||||
if ( opt.fast_list_mode ) {
|
||||
fputs( "sub::", stdout );
|
||||
}
|
||||
else {
|
||||
printf("sub:%c:", trustletter );
|
||||
}
|
||||
printf("%u:%d:%08lX%08lX:%s:%s:",
|
||||
nbits_from_pk( pk2 ),
|
||||
pk2->pubkey_algo,
|
||||
(ulong)keyid2[0],(ulong)keyid2[1],
|
||||
@ -303,11 +311,16 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
putchar(':');
|
||||
putchar('\n');
|
||||
}
|
||||
else
|
||||
printf("sub %4u%c/%08lX %s\n", nbits_from_pk( pk2 ),
|
||||
else {
|
||||
printf("sub %4u%c/%08lX %s", nbits_from_pk( pk2 ),
|
||||
pubkey_letter( pk2->pubkey_algo ),
|
||||
(ulong)keyid2[1],
|
||||
datestr_from_pk( pk2 ) );
|
||||
if( pk2->expiredate ) {
|
||||
printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) );
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
if( opt.fingerprint > 1 )
|
||||
fingerprint( pk2, NULL );
|
||||
if( opt.with_key_data )
|
||||
@ -346,6 +359,7 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
int sigrc;
|
||||
char *sigstr;
|
||||
|
||||
if( !any ) { /* no user id, (maybe a revocation follows)*/
|
||||
if( sig->sig_class == 0x20 )
|
||||
@ -363,11 +377,11 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
|
||||
if( sig->sig_class == 0x20 || sig->sig_class == 0x28
|
||||
|| sig->sig_class == 0x30 )
|
||||
fputs("rev", stdout);
|
||||
sigstr = "rev";
|
||||
else if( (sig->sig_class&~3) == 0x10 )
|
||||
fputs("sig", stdout);
|
||||
sigstr = "sig";
|
||||
else if( sig->sig_class == 0x18 )
|
||||
fputs("sig", stdout);
|
||||
sigstr = "sig";
|
||||
else {
|
||||
if( opt.with_colons )
|
||||
printf("sig::::::::::%02x:\n",sig->sig_class );
|
||||
@ -390,6 +404,7 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
rc = 0;
|
||||
sigrc = ' ';
|
||||
}
|
||||
fputs( sigstr, stdout );
|
||||
if( opt.with_colons ) {
|
||||
putchar(':');
|
||||
if( sigrc != ' ' )
|
||||
@ -405,7 +420,7 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
printf("[%s] ", gpg_errstr(rc) );
|
||||
else if( sigrc == '?' )
|
||||
;
|
||||
else {
|
||||
else if ( !opt.fast_list_mode ) {
|
||||
size_t n;
|
||||
char *p = get_user_id( sig->keyid, &n );
|
||||
if( opt.with_colons )
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ks-proto.h
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
24
g10/main.h
24
g10/main.h
@ -1,5 +1,5 @@
|
||||
/* main.h
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -73,7 +73,6 @@ int pubkey_get_nsig( int algo );
|
||||
int pubkey_get_nenc( int algo );
|
||||
unsigned int pubkey_nbits( int algo, MPI *pkey );
|
||||
|
||||
|
||||
/*-- helptext.c --*/
|
||||
void display_online_help( const char *keyword );
|
||||
|
||||
@ -94,7 +93,7 @@ int clearsign_file( const char *fname, STRLIST locusr, const char *outfile );
|
||||
/*-- sig-check.c --*/
|
||||
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
|
||||
int check_key_signature2( KBNODE root, KBNODE node,
|
||||
int *is_selfsig, u32 *r_expire );
|
||||
int *is_selfsig, u32 *r_expiredate, int *r_expired );
|
||||
|
||||
/*-- delkey.c --*/
|
||||
int delete_key( const char *username, int secure );
|
||||
@ -105,7 +104,7 @@ void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds,
|
||||
|
||||
/*-- keygen.c --*/
|
||||
u32 ask_expiredate(void);
|
||||
void generate_keypair(void);
|
||||
void generate_keypair( const char *fname );
|
||||
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
||||
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
|
||||
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||
@ -116,20 +115,20 @@ char *make_outfile_name( const char *iname );
|
||||
char *ask_outfile_name( const char *name, size_t namelen );
|
||||
int open_outfile( const char *iname, int mode, IOBUF *a );
|
||||
IOBUF open_sigfile( const char *iname );
|
||||
void copy_options_file( const char *destdir );
|
||||
void try_make_homedir( const char *fname );
|
||||
|
||||
/*-- seskey.c --*/
|
||||
void make_session_key( DEK *dek );
|
||||
MPI encode_session_key( DEK *dek, unsigned nbits );
|
||||
MPI encode_md_value( int pubkey_algo, GCRY_MD_HD md,
|
||||
int hash_algo, unsigned nbits );
|
||||
int hash_algo, unsigned nbits, int v3compathack );
|
||||
|
||||
/*-- comment.c --*/
|
||||
KBNODE make_comment_node( const char *s );
|
||||
KBNODE make_mpi_comment_node( const char *s, MPI a );
|
||||
|
||||
/*-- import.c --*/
|
||||
int import_keys( const char *filename, int fast );
|
||||
void import_keys( char **fnames, int nnames, int fast );
|
||||
int import_keys_stream( IOBUF inp, int fast );
|
||||
int collapse_uids( KBNODE *keyblock );
|
||||
|
||||
@ -137,20 +136,27 @@ int collapse_uids( KBNODE *keyblock );
|
||||
int export_pubkeys( STRLIST users, int onlyrfc );
|
||||
int export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc );
|
||||
int export_seckeys( STRLIST users );
|
||||
int export_secsubkeys( STRLIST users );
|
||||
|
||||
/* dearmor.c --*/
|
||||
int dearmor_file( const char *fname );
|
||||
int enarmor_file( const char *fname );
|
||||
|
||||
/*-- revoke.c --*/
|
||||
struct revocation_reason_info;
|
||||
int gen_revoke( const char *uname );
|
||||
int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
|
||||
struct revocation_reason_info *
|
||||
ask_revocation_reason( int key_rev, int cert_rev, int hint );
|
||||
void release_revocation_reason_info( struct revocation_reason_info *reason );
|
||||
|
||||
/*-- keylist.c --*/
|
||||
void public_key_list( int nnames, char **names );
|
||||
void secret_key_list( int nnames, char **names );
|
||||
void public_key_list( STRLIST list );
|
||||
void secret_key_list( STRLIST list );
|
||||
|
||||
/*-- verify.c --*/
|
||||
int verify_signatures( int nfiles, char **files );
|
||||
int verify_files( int nfiles, char **files );
|
||||
|
||||
/*-- decrypt.c --*/
|
||||
int decrypt_message( const char *filename );
|
||||
|
161
g10/mainproc.c
161
g10/mainproc.c
@ -1,5 +1,5 @@
|
||||
/* mainproc.c - handle packets
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -160,11 +160,11 @@ add_signature( CTX c, PACKET *pkt )
|
||||
|
||||
if( pkt->pkttype == PKT_SIGNATURE && !c->list ) {
|
||||
/* This is the first signature for the following datafile.
|
||||
* gpg does not write such packets; instead it always uses
|
||||
* GPG does not write such packets; instead it always uses
|
||||
* onepass-sig packets. The drawback of PGP's method
|
||||
* of prepending the signature to the data is
|
||||
* that it is not possible to make a signature from data read
|
||||
* from stdin. (gpg is able to read PGP stuff anyway.) */
|
||||
* from stdin. (GPG is able to read PGP stuff anyway.) */
|
||||
node = new_kbnode( pkt );
|
||||
c->list = node;
|
||||
return 1;
|
||||
@ -224,10 +224,14 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
|| is_RSA(enc->pubkey_algo) ) {
|
||||
if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
|
||||
|| !seckey_available( enc->keyid )) ) {
|
||||
c->dek = gcry_xmalloc_secure( sizeof *c->dek );
|
||||
if( (result = get_session_key( enc, c->dek )) ) {
|
||||
/* error: delete the DEK */
|
||||
gcry_free(c->dek); c->dek = NULL;
|
||||
if( opt.list_only )
|
||||
result = -1;
|
||||
else {
|
||||
c->dek = gcry_xmalloc_secure( sizeof *c->dek );
|
||||
if( (result = get_session_key( enc, c->dek )) ) {
|
||||
/* error: delete the DEK */
|
||||
gcry_free(c->dek); c->dek = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -267,6 +271,8 @@ print_failed_pkenc( struct kidlist_item *list )
|
||||
PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
|
||||
const char *algstr = gcry_pk_algo_name( list->pubkey_algo );
|
||||
|
||||
if( !algstr )
|
||||
algstr = "[?]";
|
||||
pk->pubkey_algo = list->pubkey_algo;
|
||||
if( !get_pubkey( pk, list->kid ) ) {
|
||||
size_t n;
|
||||
@ -309,10 +315,14 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
|
||||
print_failed_pkenc( c->failed_pkenc );
|
||||
|
||||
write_status( STATUS_BEGIN_DECRYPTION );
|
||||
|
||||
/*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
|
||||
if( !c->dek && !c->last_was_session_key ) {
|
||||
if( opt.list_only )
|
||||
result = -1;
|
||||
else if( !c->dek && !c->last_was_session_key ) {
|
||||
/* assume this is old conventional encrypted data
|
||||
* Actually we should use IDEA and MD5 in this case, but becuase
|
||||
* Actually we should use IDEA and MD5 in this case, but because
|
||||
* IDEA is patented we can't do so */
|
||||
c->dek = passphrase_to_dek( NULL, 0,
|
||||
opt.def_cipher_algo ? opt.def_cipher_algo
|
||||
@ -322,6 +332,7 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
result = GPGERR_NO_SECKEY;
|
||||
if( !result )
|
||||
result = decrypt_data( c, pkt->pkt.encrypted, c->dek );
|
||||
|
||||
gcry_free(c->dek); c->dek = NULL;
|
||||
if( result == -1 )
|
||||
;
|
||||
@ -339,11 +350,12 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
else {
|
||||
write_status( STATUS_DECRYPTION_FAILED );
|
||||
log_error(_("decryption failed: %s\n"), gpg_errstr(result));
|
||||
/* Hmmm: does this work when we have encrypted using a multiple
|
||||
/* Hmmm: does this work when we have encrypted using multiple
|
||||
* ways to specify the session key (symmmetric and PK)*/
|
||||
}
|
||||
free_packet(pkt);
|
||||
c->last_was_session_key = 0;
|
||||
write_status( STATUS_END_DECRYPTION );
|
||||
}
|
||||
|
||||
|
||||
@ -360,7 +372,8 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
else if( opt.verbose )
|
||||
log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name);
|
||||
free_md_filter_context( &c->mfx );
|
||||
if( !(c->mfx.md = gcry_md_open( 0, 0)) )
|
||||
c->mfx.md = gcry_md_open( 0, 0);
|
||||
if( !c->mfx.md )
|
||||
BUG();
|
||||
/* fixme: we may need to push the textfilter if we have sigclass 1
|
||||
* and no armoring - Not yet tested
|
||||
@ -372,8 +385,7 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
for(n=c->list; n; n = n->next ) {
|
||||
if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
if( n->pkt->pkt.onepass_sig->digest_algo ) {
|
||||
gcry_md_enable( c->mfx.md,
|
||||
n->pkt->pkt.onepass_sig->digest_algo );
|
||||
gcry_md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo );
|
||||
if( !any && n->pkt->pkt.onepass_sig->digest_algo
|
||||
== GCRY_MD_MD5 )
|
||||
only_md5 = 1;
|
||||
@ -398,24 +410,28 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
clearsig = 1;
|
||||
}
|
||||
}
|
||||
if( !any ) { /* no onepass sig packet: enable all standard algos */
|
||||
|
||||
if( !any && !opt.skip_verify ) {
|
||||
/* no onepass sig packet: enable all standard algos */
|
||||
gcry_md_enable( c->mfx.md, GCRY_MD_RMD160 );
|
||||
gcry_md_enable( c->mfx.md, GCRY_MD_SHA1 );
|
||||
gcry_md_enable( c->mfx.md, GCRY_MD_MD5 );
|
||||
}
|
||||
if( only_md5 ) {
|
||||
if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) {
|
||||
/* This is a kludge to work around a bug in pgp2. It does only
|
||||
* catch those mails which are armored. To catch the non-armored
|
||||
* pgp mails we could see whether there is the signature packet
|
||||
* in front of the plaintext. If someone needs this, send me a patch.
|
||||
*/
|
||||
if( !(c->mfx.md2 = gcry_md_open( GCRY_MD_MD5, 0)) )
|
||||
c->mfx.md2 = gcry_md_open( GCRY_MD_MD5, 0);
|
||||
if( !c->mfx.md2 )
|
||||
BUG();
|
||||
}
|
||||
#if 0
|
||||
#warning md_start_debug is enabled
|
||||
md_start_debug( c->mfx.md, "verify" );
|
||||
#endif
|
||||
if ( DBG_HASHING ) {
|
||||
gcry_md_start_debug( c->mfx.md, "verify" );
|
||||
if ( c->mfx.md2 )
|
||||
gcry_md_start_debug( c->mfx.md2, "verify2" );
|
||||
}
|
||||
rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
|
||||
if( rc == GPGERR_CREATE_FILE && !c->sigs_only) {
|
||||
/* can't write output but we hash it anyway to
|
||||
@ -494,12 +510,17 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
|
||||
* in canonical mode ??? (calculating both modes???) */
|
||||
if( c->mfx.md ) {
|
||||
md = gcry_md_copy( c->mfx.md );
|
||||
if( c->mfx.md2 )
|
||||
if( !md )
|
||||
BUG();
|
||||
if( c->mfx.md2 ) {
|
||||
md2 = gcry_md_copy( c->mfx.md2 );
|
||||
if( !md2 )
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
else { /* detached signature */
|
||||
log_debug("Do we really need this here?");
|
||||
md = gcry_md_open( 0, 0 ); /* signature_check() will enable the md*/
|
||||
log_debug("Do we really need this here?");
|
||||
md = gcry_md_open( 0, 0 ); /* signature_check() will enable the md*/
|
||||
md2 = gcry_md_open( 0, 0 );
|
||||
if( !md || !md2 )
|
||||
BUG();
|
||||
@ -513,6 +534,11 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
|
||||
|| c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
return check_key_signature( c->list, node, is_selfsig );
|
||||
}
|
||||
else if( sig->sig_class == 0x20 ) {
|
||||
log_info(_("standalone revocation - "
|
||||
"use \"gpg --import\" to apply\n"));
|
||||
return GPGERR_NOT_PROCESSED;
|
||||
}
|
||||
else {
|
||||
log_error("invalid root packet for sigclass %02x\n",
|
||||
sig->sig_class);
|
||||
@ -540,8 +566,12 @@ print_userid( PACKET *pkt )
|
||||
printf("ERROR: unexpected packet type %d", pkt->pkttype );
|
||||
return;
|
||||
}
|
||||
print_string( stdout, pkt->pkt.user_id->name, pkt->pkt.user_id->len,
|
||||
opt.with_colons );
|
||||
if( opt.with_colons )
|
||||
print_string( stdout, pkt->pkt.user_id->name,
|
||||
pkt->pkt.user_id->len, ':');
|
||||
else
|
||||
print_utf8_string( stdout, pkt->pkt.user_id->name,
|
||||
pkt->pkt.user_id->len );
|
||||
}
|
||||
|
||||
|
||||
@ -644,11 +674,13 @@ list_node( CTX c, KBNODE node )
|
||||
keyid_from_pk( pk, keyid );
|
||||
if( mainkey ) {
|
||||
c->local_id = pk->local_id;
|
||||
c->trustletter = query_trust_info( pk, NULL );
|
||||
c->trustletter = opt.fast_list_mode?
|
||||
0 : query_trust_info( pk, NULL );
|
||||
}
|
||||
printf("%s:%c:%u:%d:%08lX%08lX:%s:%s:",
|
||||
mainkey? "pub":"sub",
|
||||
c->trustletter,
|
||||
printf("%s:", mainkey? "pub":"sub" );
|
||||
if( c->trustletter )
|
||||
putchar( c->trustletter );
|
||||
printf(":%u:%d:%08lX%08lX:%s:%s:",
|
||||
nbits_from_pk( pk ),
|
||||
pk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
@ -657,7 +689,7 @@ list_node( CTX c, KBNODE node )
|
||||
if( c->local_id )
|
||||
printf("%lu", c->local_id );
|
||||
putchar(':');
|
||||
if( c->local_id )
|
||||
if( c->local_id && !opt.fast_list_mode )
|
||||
putchar( get_ownertrust_info( c->local_id ) );
|
||||
putchar(':');
|
||||
if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) {
|
||||
@ -675,6 +707,7 @@ list_node( CTX c, KBNODE node )
|
||||
pubkey_letter( pk->pubkey_algo ),
|
||||
(ulong)keyid_from_pk( pk, NULL ),
|
||||
datestr_from_pk( pk ) );
|
||||
|
||||
if( mainkey ) {
|
||||
/* and now list all userids with their signatures */
|
||||
for( node = node->next; node; node = node->next ) {
|
||||
@ -717,6 +750,10 @@ list_node( CTX c, KBNODE node )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( pk->expiredate ) { /* of subkey */
|
||||
printf(_(" [expires: %s]"), expirestr_from_pk( pk ) );
|
||||
}
|
||||
|
||||
if( !any )
|
||||
putchar('\n');
|
||||
if( !mainkey && opt.fingerprint > 1 )
|
||||
@ -847,7 +884,7 @@ list_node( CTX c, KBNODE node )
|
||||
if( opt.with_colons )
|
||||
putchar(':');
|
||||
}
|
||||
else {
|
||||
else if( !opt.fast_list_mode ) {
|
||||
p = get_user_id( sig->keyid, &n );
|
||||
print_string( stdout, p, n, opt.with_colons );
|
||||
gcry_free(p);
|
||||
@ -861,6 +898,7 @@ list_node( CTX c, KBNODE node )
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
proc_packets( void *anchor, IOBUF a )
|
||||
{
|
||||
@ -873,6 +911,8 @@ proc_packets( void *anchor, IOBUF a )
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
proc_signature_packets( void *anchor, IOBUF a,
|
||||
STRLIST signedfiles, const char *sigfilename )
|
||||
@ -1027,7 +1067,7 @@ static int
|
||||
check_sig_and_print( CTX c, KBNODE node )
|
||||
{
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
const char *tstr;
|
||||
const char *astr, *tstr;
|
||||
int rc;
|
||||
|
||||
if( opt.skip_verify ) {
|
||||
@ -1036,12 +1076,12 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
}
|
||||
|
||||
tstr = asctimestamp(sig->timestamp);
|
||||
astr = gcry_pk_algo_name( sig->pubkey_algo );
|
||||
log_info(_("Signature made %.*s using %s key ID %08lX\n"),
|
||||
(int)strlen(tstr), tstr, gcry_pk_algo_name( sig->pubkey_algo ),
|
||||
(ulong)sig->keyid[1] );
|
||||
(int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] );
|
||||
|
||||
rc = do_check_sig(c, node, NULL );
|
||||
if( rc == GPGERR_NO_PUBKEY && opt.keyserver_name ) {
|
||||
if( rc == GPGERR_NO_PUBKEY && opt.keyserver_name && opt.auto_key_retrieve) {
|
||||
if( !hkp_ask_import( sig->keyid ) )
|
||||
rc = do_check_sig(c, node, NULL );
|
||||
}
|
||||
@ -1121,7 +1161,8 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
buf[16] = 0;
|
||||
write_status_text( STATUS_NO_PUBKEY, buf );
|
||||
}
|
||||
log_error(_("Can't check signature: %s\n"), gpg_errstr(rc) );
|
||||
if( rc != GPGERR_NOT_PROCESSED )
|
||||
log_error(_("Can't check signature: %s\n"), gpg_errstr(rc) );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -1136,7 +1177,7 @@ proc_tree( CTX c, KBNODE node )
|
||||
KBNODE n1;
|
||||
int rc;
|
||||
|
||||
if( opt.list_packets )
|
||||
if( opt.list_packets || opt.list_only )
|
||||
return;
|
||||
|
||||
c->local_id = 0;
|
||||
@ -1155,7 +1196,7 @@ proc_tree( CTX c, KBNODE node )
|
||||
if( !c->have_data ) {
|
||||
free_md_filter_context( &c->mfx );
|
||||
/* prepare to create all requested message digests */
|
||||
if( !(c->mfx.md = gcry_md_open(0, 0)) )
|
||||
if ( !(c->mfx.md = gcry_md_open(0, 0)) )
|
||||
BUG();
|
||||
|
||||
/* fixme: why looking for the signature packet and not 1passpacket*/
|
||||
@ -1163,13 +1204,16 @@ proc_tree( CTX c, KBNODE node )
|
||||
gcry_md_enable( c->mfx.md, n1->pkt->pkt.signature->digest_algo);
|
||||
}
|
||||
/* ask for file and hash it */
|
||||
if( c->sigs_only )
|
||||
if( c->sigs_only ) {
|
||||
rc = hash_datafiles( c->mfx.md, NULL,
|
||||
c->signed_data, c->sigfilename,
|
||||
n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
|
||||
else
|
||||
}
|
||||
else {
|
||||
rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2,
|
||||
iobuf_get_fname(c->iobuf), 0 );
|
||||
iobuf_get_fname(c->iobuf),
|
||||
n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
|
||||
}
|
||||
if( rc ) {
|
||||
log_error("can't hash datafile: %s\n", gpg_errstr(rc));
|
||||
return;
|
||||
@ -1182,15 +1226,22 @@ proc_tree( CTX c, KBNODE node )
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
|
||||
if( !c->have_data ) {
|
||||
if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
|
||||
log_info(_("standalone signature of class 0x%02x\n"),
|
||||
sig->sig_class);
|
||||
else if( !c->have_data ) {
|
||||
/* detached signature */
|
||||
free_md_filter_context( &c->mfx );
|
||||
if( !(c->mfx.md = gcry_md_open(sig->digest_algo, 0)) )
|
||||
c->mfx.md = gcry_md_open(sig->digest_algo, 0);
|
||||
if ( !c->mfx.md )
|
||||
BUG();
|
||||
if( sig->digest_algo == GCRY_MD_MD5
|
||||
&& is_RSA( sig->pubkey_algo ) ) {
|
||||
if( !opt.pgp2_workarounds )
|
||||
;
|
||||
else if( sig->digest_algo == GCRY_MD_MD5
|
||||
&& is_RSA( sig->pubkey_algo ) ) {
|
||||
/* enable a workaround for a pgp2 bug */
|
||||
if( !(c->mfx.md2 = gcry_md_open( GCRY_MD_MD5, 0 )) )
|
||||
c->mfx.md2 = gcry_md_open( GCRY_MD_MD5, 0 );
|
||||
if ( !c->mfx.md2 )
|
||||
BUG();
|
||||
}
|
||||
else if( sig->digest_algo == GCRY_MD_SHA1
|
||||
@ -1198,9 +1249,11 @@ proc_tree( CTX c, KBNODE node )
|
||||
&& sig->sig_class == 0x01 ) {
|
||||
/* enable the workaround also for pgp5 when the detached
|
||||
* signature has been created in textmode */
|
||||
if( !(c->mfx.md2 = gcry_md_open( sig->digest_algo, 0 )) )
|
||||
c->mfx.md2 = gcry_md_open( sig->digest_algo, 0 );
|
||||
if ( !c->mfx.md2 )
|
||||
BUG();
|
||||
}
|
||||
#if 0 /* workaround disabled */
|
||||
/* Here we have another hack to work around a pgp 2 bug
|
||||
* It works by not using the textmode for detached signatures;
|
||||
* this will let the first signature check (on md) fail
|
||||
@ -1208,14 +1261,18 @@ proc_tree( CTX c, KBNODE node )
|
||||
* then produce the "correct" hash. This is very, very ugly
|
||||
* hack but it may help in some cases (and break others)
|
||||
*/
|
||||
if( c->sigs_only )
|
||||
/* c->mfx.md2? 0 :(sig->sig_class == 0x01) */
|
||||
#endif
|
||||
if( c->sigs_only ) {
|
||||
rc = hash_datafiles( c->mfx.md, c->mfx.md2,
|
||||
c->signed_data, c->sigfilename,
|
||||
c->mfx.md2? 0 :(sig->sig_class == 0x01) );
|
||||
else
|
||||
(sig->sig_class == 0x01) );
|
||||
}
|
||||
else {
|
||||
rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2,
|
||||
iobuf_get_fname(c->iobuf),
|
||||
c->mfx.md2? 0 :(sig->sig_class == 0x01) );
|
||||
iobuf_get_fname(c->iobuf),
|
||||
(sig->sig_class == 0x01) );
|
||||
}
|
||||
if( rc ) {
|
||||
log_error("can't hash datafile: %s\n", gpg_errstr(rc));
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* mdfilter.c - filter data and calculate a message digest
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,9 +25,9 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* misc.c - miscellaneous functions
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -23,7 +23,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
|
||||
#include <asm/sysinfo.h>
|
||||
#include <asm/unistd.h>
|
||||
@ -32,6 +31,8 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
@ -41,7 +42,6 @@
|
||||
|
||||
#define MAX_EXTERN_MPI_BITS 16384
|
||||
|
||||
|
||||
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
|
||||
#warning using trap_unaligned
|
||||
static int
|
||||
@ -246,6 +246,7 @@ mpi_print( FILE *fp, MPI a, int mode )
|
||||
}
|
||||
|
||||
|
||||
|
||||
u16
|
||||
checksum_u16( unsigned n )
|
||||
{
|
||||
@ -289,7 +290,6 @@ checksum_mpi( MPI a )
|
||||
}
|
||||
|
||||
|
||||
|
||||
u32
|
||||
buffer_to_u32( const byte *buffer )
|
||||
{
|
||||
@ -359,6 +359,7 @@ print_digest_algo_note( int algo )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Wrapper around the libgcrypt function with addional checks on
|
||||
* openPGP contrainst for the algo ID.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* openfile.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,6 +24,9 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
#include <gcrypt.h>
|
||||
@ -39,13 +42,16 @@
|
||||
#define SKELEXT ".skel"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#define CMP_FILENAME(a,b) stricmp( (a), (b) )
|
||||
#else
|
||||
#define CMP_FILENAME(a,b) strcmp( (a), (b) )
|
||||
#endif
|
||||
|
||||
#ifdef MKDIR_TAKES_ONE_ARG
|
||||
# undef mkdir
|
||||
# define mkdir(a,b) mkdir(a)
|
||||
#endif
|
||||
|
||||
/* FIXME: Implement opt.interactive. */
|
||||
|
||||
@ -78,7 +84,6 @@ overwrite_filep( const char *fname )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Strip know extensions from iname and return a newly allocated
|
||||
* filename. Return NULL if we can't do that.
|
||||
@ -176,7 +181,7 @@ open_outfile( const char *iname, int mode, IOBUF *a )
|
||||
name = opt.outfile;
|
||||
else {
|
||||
#ifdef USE_ONLY_8DOT3
|
||||
/* It is quite common for DOS system to have only one dot in a
|
||||
/* It is quite common DOS system to have only one dot in a
|
||||
* a filename So if we have something like this, we simple
|
||||
* replace the suffix execpt in cases where the suffix is
|
||||
* larger than 3 characters and not the same as.
|
||||
@ -195,7 +200,7 @@ open_outfile( const char *iname, int mode, IOBUF *a )
|
||||
strcpy(dot, newsfx );
|
||||
}
|
||||
else if( dot && !dot[1] ) /* don't duplicate a dot */
|
||||
strcat( dot, newsfx+1 );
|
||||
strcpy( dot, newsfx+1 );
|
||||
else
|
||||
strcat( buf, newsfx );
|
||||
#else
|
||||
@ -253,7 +258,7 @@ open_sigfile( const char *iname )
|
||||
/****************
|
||||
* Copy the option file skeleton to the given directory.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
copy_options_file( const char *destdir )
|
||||
{
|
||||
const char *datadir = GNUPG_DATADIR;
|
||||
@ -296,3 +301,23 @@ copy_options_file( const char *destdir )
|
||||
gcry_free(fname);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
try_make_homedir( const char *fname )
|
||||
{
|
||||
if( opt.dry_run )
|
||||
return;
|
||||
if( strlen(fname) >= 7
|
||||
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
log_fatal( _("%s: can't create directory: %s\n"),
|
||||
fname, strerror(errno) );
|
||||
else if( !opt.quiet )
|
||||
log_info( _("%s: directory created\n"), fname );
|
||||
copy_options_file( fname );
|
||||
log_info(_("you have to start GnuPG again, "
|
||||
"so it can read the new options file\n") );
|
||||
gpg_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* options.h
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -28,11 +28,12 @@
|
||||
struct {
|
||||
int verbose;
|
||||
int quiet;
|
||||
unsigned debug;
|
||||
unsigned int debug;
|
||||
int armor;
|
||||
int compress;
|
||||
char *outfile;
|
||||
int dry_run;
|
||||
int list_only;
|
||||
int textmode;
|
||||
int batch; /* run in batch mode */
|
||||
int answer_yes; /* answer yes on most questions */
|
||||
@ -63,7 +64,9 @@ struct {
|
||||
int compress_sigs;
|
||||
int always_trust;
|
||||
int rfc1991;
|
||||
unsigned emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
|
||||
int rfc2440;
|
||||
int pgp2_workarounds;
|
||||
unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
|
||||
int shm_coprocess;
|
||||
const char *set_filename;
|
||||
const char *comment_string;
|
||||
@ -83,9 +86,17 @@ struct {
|
||||
int allow_non_selfsigned_uid;
|
||||
int no_literal;
|
||||
ulong set_filesize;
|
||||
int honor_http_proxy;
|
||||
int fast_list_mode;
|
||||
int ignore_time_conflict;
|
||||
int command_fd;
|
||||
int auto_key_retrieve;
|
||||
} opt;
|
||||
|
||||
|
||||
#define EMUBUG_3DESS2K 2
|
||||
#define EMUBUG_MDENCODE 4
|
||||
|
||||
#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
|
||||
#define DBG_MPI_VALUE 2 /* debug mpi details */
|
||||
#define DBG_CIPHER_VALUE 4 /* debug cipher handling */
|
||||
@ -96,6 +107,7 @@ struct {
|
||||
#define DBG_CACHE_VALUE 64 /* debug the cacheing */
|
||||
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
|
||||
#define DBG_TRUST_VALUE 256 /* debug the trustdb */
|
||||
#define DBG_HASHING_VALUE 512 /* debug hashing operations */
|
||||
|
||||
|
||||
#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE)
|
||||
@ -104,6 +116,6 @@ struct {
|
||||
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
|
||||
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
|
||||
#define DBG_CIPHER (opt.debug & DBG_CIPHER_VALUE)
|
||||
|
||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||
|
||||
#endif /*GPG_OPTIONS_H*/
|
||||
|
21
g10/packet.h
21
g10/packet.h
@ -1,5 +1,5 @@
|
||||
/* packet.h - packet read/write stuff
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -54,14 +54,16 @@ typedef enum {
|
||||
PKT_USER_ID =13, /* user id packet */
|
||||
PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */
|
||||
PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
|
||||
PKT_PHOTO_ID =17, /* PGP's photo ID */
|
||||
PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */
|
||||
PKT_MDC =19, /* manipulaion detection code packet */
|
||||
PKT_COMMENT =61, /* new comment packet (private) */
|
||||
PKT_ENCRYPTED_MDC =62, /* test: encrypted data with MDC */
|
||||
} pkttype_t;
|
||||
|
||||
typedef struct packet_struct PACKET;
|
||||
|
||||
typedef struct {
|
||||
byte mode;
|
||||
int mode;
|
||||
byte hash_algo;
|
||||
byte salt[8];
|
||||
u32 count;
|
||||
@ -105,7 +107,7 @@ typedef struct {
|
||||
byte version;
|
||||
byte sig_class; /* sig classification, append for MD calculation*/
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
/* (PUBKEY_ALGO_xxx) */
|
||||
/* (GCRY_PK_xxx) */
|
||||
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
|
||||
byte *hashed_data; /* all subpackets with hashed data (v4 only) */
|
||||
byte *unhashed_data; /* ditto for unhashed data */
|
||||
@ -165,6 +167,8 @@ typedef struct {
|
||||
ulong stored_at; /* the stream offset where it was stored
|
||||
* by build-packet */
|
||||
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 */
|
||||
char name[1];
|
||||
} PKT_user_id;
|
||||
|
||||
@ -178,10 +182,14 @@ typedef struct {
|
||||
typedef struct {
|
||||
u32 len; /* length of encrypted data */
|
||||
byte new_ctb; /* uses a new CTB */
|
||||
byte mdc_method; /* test: > 0: this is is an encrypted_mdc packet */
|
||||
byte mdc_method; /* > 0: integrity protected encrypted data packet */
|
||||
IOBUF buf; /* IOBUF reference */
|
||||
} PKT_encrypted;
|
||||
|
||||
typedef struct {
|
||||
byte hash[20];
|
||||
} PKT_mdc;
|
||||
|
||||
typedef struct {
|
||||
unsigned int trustval;
|
||||
} PKT_ring_trust;
|
||||
@ -212,6 +220,7 @@ struct packet_struct {
|
||||
PKT_user_id *user_id; /* PKT_USER_ID */
|
||||
PKT_compressed *compressed; /* PKT_COMPRESSED */
|
||||
PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC] */
|
||||
PKT_mdc *mdc; /* PKT_MDC */
|
||||
PKT_ring_trust *ring_trust; /* PKT_RING_TRUST */
|
||||
PKT_plaintext *plaintext; /* PKT_PLAINTEXT */
|
||||
} pkt;
|
||||
@ -246,6 +255,7 @@ typedef enum {
|
||||
SIGSUBPKT_POLICY =26, /* policy URL */
|
||||
SIGSUBPKT_KEY_FLAGS =27, /* key flags */
|
||||
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
|
||||
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
||||
SIGSUBPKT_PRIV_ADD_SIG =101,/* signatur is also valid for this uid */
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL=128
|
||||
@ -339,7 +349,6 @@ int handle_compressed( void *ctx, PKT_compressed *cd,
|
||||
|
||||
/*-- encr-data.c --*/
|
||||
int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek );
|
||||
int encrypt_data( PKT_encrypted *ed, DEK *dek );
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* parse-packet.c - read packets
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,10 +24,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include <gcrypt.h>
|
||||
#include "filter.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
@ -59,6 +59,8 @@ static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
byte *hdr, int hdrlen, PACKET *packet );
|
||||
static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet );
|
||||
static int parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet );
|
||||
static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet );
|
||||
static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
@ -69,6 +71,8 @@ static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet, int new_ctb );
|
||||
static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet, int new_ctb);
|
||||
static int parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet, int new_ctb);
|
||||
|
||||
static unsigned short
|
||||
read_16(IOBUF inp)
|
||||
@ -415,6 +419,10 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
|
||||
case PKT_USER_ID:
|
||||
rc = parse_user_id(inp, pkttype, pktlen, pkt );
|
||||
break;
|
||||
case PKT_PHOTO_ID:
|
||||
pkt->pkttype = pkttype = PKT_USER_ID; /* must fix it */
|
||||
rc = parse_photo_id(inp, pkttype, pktlen, pkt);
|
||||
break;
|
||||
case PKT_OLD_COMMENT:
|
||||
case PKT_COMMENT:
|
||||
rc = parse_comment(inp, pkttype, pktlen, pkt);
|
||||
@ -433,6 +441,9 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
|
||||
case PKT_ENCRYPTED_MDC:
|
||||
rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
|
||||
break;
|
||||
case PKT_MDC:
|
||||
rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
|
||||
break;
|
||||
default:
|
||||
skip_packet(inp, pkttype, pktlen);
|
||||
break;
|
||||
@ -803,6 +814,13 @@ dump_sig_subpkt( int hashed, int type, int critical,
|
||||
case SIGSUBPKT_SIGNERS_UID:
|
||||
p = "signer's user ID";
|
||||
break;
|
||||
case SIGSUBPKT_REVOC_REASON:
|
||||
if( length ) {
|
||||
printf("revocation reason 0x%02x (", *buffer );
|
||||
print_string( stdout, buffer+1, length-1, ')' );
|
||||
p = ")";
|
||||
}
|
||||
break;
|
||||
case SIGSUBPKT_PRIV_ADD_SIG:
|
||||
p = "signs additional user ID";
|
||||
break;
|
||||
@ -840,6 +858,10 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
|
||||
if( n < 8 ) /* minimum length needed */
|
||||
break;
|
||||
return 0;
|
||||
case SIGSUBPKT_REVOC_REASON:
|
||||
if( !n )
|
||||
break;
|
||||
return 0;
|
||||
case SIGSUBPKT_PREF_SYM:
|
||||
case SIGSUBPKT_PREF_HASH:
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
@ -877,7 +899,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
return 1;
|
||||
|
||||
case SIGSUBPKT_POLICY: /* Is enough to show the policy? */
|
||||
case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -896,8 +918,12 @@ enum_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype,
|
||||
int seq = 0;
|
||||
int reqseq = start? *start: 0;
|
||||
|
||||
if( !buffer || reqseq == -1 )
|
||||
return NULL;
|
||||
if( !buffer || reqseq == -1 ) {
|
||||
/* return some value different from NULL to indicate that
|
||||
* there is no crtitical bit we do not understand. The caller
|
||||
* will never use the value. Yes I know, it is an ugly hack */
|
||||
return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&buffer : NULL;
|
||||
}
|
||||
buflen = (*buffer << 8) | buffer[1];
|
||||
buffer += 2;
|
||||
while( buflen ) {
|
||||
@ -1131,8 +1157,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
unknown_pubkey_warning( sig->pubkey_algo );
|
||||
/* we store the plain material in data[0], so that we are able
|
||||
* to write it back with build_packet() */
|
||||
sig->data[0] = gcry_mpi_set_opaque(NULL,
|
||||
read_rest(inp, pktlen), pktlen*8 );
|
||||
sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
|
||||
pktlen = 0;
|
||||
}
|
||||
else {
|
||||
@ -1317,6 +1342,24 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
|
||||
sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
|
||||
sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
/* check for the special GNU extension */
|
||||
if( is_v4 && sk->protect.s2k.mode == 101 ) {
|
||||
for(i=0; i < 4 && pktlen; i++, pktlen-- )
|
||||
temp[i] = iobuf_get_noeof(inp);
|
||||
if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
|
||||
if( list_mode )
|
||||
printf( "\tunknown S2K %d\n",
|
||||
sk->protect.s2k.mode );
|
||||
rc = GPGERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
/* here we know that it is a gnu extension
|
||||
* What follows is the GNU protection mode:
|
||||
* All values have special meanings
|
||||
* and they are mapped in the mode with a base of 1000.
|
||||
*/
|
||||
sk->protect.s2k.mode = 1000 + temp[3];
|
||||
}
|
||||
switch( sk->protect.s2k.mode ) {
|
||||
case 1:
|
||||
case 3:
|
||||
@ -1332,10 +1375,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
break;
|
||||
case 3: if( list_mode ) printf( "\titer+salt S2K" );
|
||||
break;
|
||||
case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
|
||||
break;
|
||||
default:
|
||||
if( list_mode )
|
||||
printf( "\tunknown S2K %d\n",
|
||||
sk->protect.s2k.mode );
|
||||
printf( "\tunknown %sS2K %d\n",
|
||||
sk->protect.s2k.mode < 1000? "":"GNU ",
|
||||
sk->protect.s2k.mode );
|
||||
rc = GPGERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
@ -1388,6 +1434,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
default:
|
||||
sk->protect.ivlen = 8;
|
||||
}
|
||||
if( sk->protect.s2k.mode == 1001 )
|
||||
sk->protect.ivlen = 0;
|
||||
|
||||
if( pktlen < sk->protect.ivlen ) {
|
||||
rc = GPGERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
@ -1408,10 +1457,15 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
* If the user is so careless, not to protect his secret key,
|
||||
* we can assume, that he operates an open system :=(.
|
||||
* So we put the key into secure memory when we unprotect it. */
|
||||
if( is_v4 && sk->is_protected ) {
|
||||
if( sk->protect.s2k.mode == 1001 ) {
|
||||
/* better set some dummy stuff here */
|
||||
sk->skey[npkey] = mpi_set_opaque(NULL, gcry_xstrdup("dummydata"), 10);
|
||||
pktlen = 0;
|
||||
}
|
||||
else if( is_v4 && sk->is_protected ) {
|
||||
/* ugly; the length is encrypted too, so we read all
|
||||
* stuff up to the end of the packet into the first
|
||||
* skey element (which is the one indexed by npkey) */
|
||||
* skey element */
|
||||
sk->skey[npkey] = gcry_mpi_set_opaque(NULL,
|
||||
read_rest(inp, pktlen), pktlen*8 );
|
||||
pktlen = 0;
|
||||
@ -1475,6 +1529,8 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
|
||||
packet->pkt.user_id = gcry_xmalloc(sizeof *packet->pkt.user_id + pktlen);
|
||||
packet->pkt.user_id->len = pktlen;
|
||||
packet->pkt.user_id->photo = NULL;
|
||||
packet->pkt.user_id->photolen = 0;
|
||||
p = packet->pkt.user_id->name;
|
||||
for( ; pktlen; pktlen--, p++ )
|
||||
*p = iobuf_get_noeof(inp);
|
||||
@ -1496,6 +1552,31 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* PGP generates a packet of type 17. We assume this is a photo ID and
|
||||
* simply store it here as a comment packet.
|
||||
*/
|
||||
static int
|
||||
parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
{
|
||||
byte *p;
|
||||
|
||||
packet->pkt.user_id = gcry_xmalloc(sizeof *packet->pkt.user_id + 30);
|
||||
sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen );
|
||||
packet->pkt.user_id->len = strlen(packet->pkt.user_id->name);
|
||||
|
||||
packet->pkt.user_id->photo = gcry_xmalloc(sizeof *packet->pkt.user_id + pktlen);
|
||||
packet->pkt.user_id->photolen = pktlen;
|
||||
p = packet->pkt.user_id->photo;
|
||||
for( ; pktlen; pktlen--, p++ )
|
||||
*p = iobuf_get_noeof(inp);
|
||||
|
||||
if( list_mode ) {
|
||||
printf(":photo_id packet: %s\n", packet->pkt.user_id->name );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
@ -1624,9 +1705,8 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
ed->new_ctb = new_ctb;
|
||||
ed->mdc_method = 0;
|
||||
if( pkttype == PKT_ENCRYPTED_MDC ) {
|
||||
/* test: this is the new encrypted_mdc packet */
|
||||
/* fixme: add some pktlen sanity checks */
|
||||
int version, method;
|
||||
int version;
|
||||
|
||||
version = iobuf_get_noeof(inp); pktlen--;
|
||||
if( version != 1 ) {
|
||||
@ -1634,12 +1714,7 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
version);
|
||||
goto leave;
|
||||
}
|
||||
method = iobuf_get_noeof(inp); pktlen--;
|
||||
if( method != GCRY_MD_SHA1 ) {
|
||||
log_error("encrypted_mdc does not use SHA1 method\n" );
|
||||
goto leave;
|
||||
}
|
||||
ed->mdc_method = method;
|
||||
ed->mdc_method = GCRY_MD_SHA1;
|
||||
}
|
||||
if( pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
|
||||
log_error("packet(%d) too short\n", pkttype);
|
||||
@ -1662,3 +1737,26 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *pkt, int new_ctb )
|
||||
{
|
||||
PKT_mdc *mdc;
|
||||
byte *p;
|
||||
|
||||
mdc = pkt->pkt.mdc= gcry_xmalloc(sizeof *pkt->pkt.mdc );
|
||||
if( list_mode )
|
||||
printf(":mdc packet: length=%lu\n", pktlen);
|
||||
if( !new_ctb || pktlen != 20 ) {
|
||||
log_error("mdc_packet with invalid encoding\n");
|
||||
goto leave;
|
||||
}
|
||||
p = mdc->hash;
|
||||
for( ; pktlen; pktlen--, p++ )
|
||||
*p = iobuf_get_noeof(inp);
|
||||
|
||||
leave:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* passphrase.c - Get a passphrase
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,8 +24,9 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "options.h"
|
||||
#include "ttyio.h"
|
||||
#include "keydb.h"
|
||||
@ -163,9 +164,9 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
||||
tty_printf("\"\n");
|
||||
|
||||
if( !get_pubkey( pk, keyid ) ) {
|
||||
const char *s = gcry_pk_algo_name( pk->pubkey_algo );
|
||||
tty_printf( _("%u-bit %s key, ID %08lX, created %s"),
|
||||
nbits_from_pk( pk ),
|
||||
gcry_pk_algo_name( pk->pubkey_algo ), (ulong)keyid[1],
|
||||
nbits_from_pk( pk ), s?s:"?", (ulong)keyid[1],
|
||||
strtimestamp(pk->timestamp) );
|
||||
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
|
||||
&& keyid[1] != keyid[3] )
|
||||
|
154
g10/pkclist.c
154
g10/pkclist.c
@ -1,5 +1,5 @@
|
||||
/* pkclist.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,11 +24,10 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "main.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include "util.h"
|
||||
@ -36,6 +35,7 @@
|
||||
#include "ttyio.h"
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
#define CONTROL_D ('D' - 'A' + 1)
|
||||
@ -97,6 +97,112 @@ fpr_info( PKT_public_key *pk )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Show the revocation reason as it is stored with the given signature
|
||||
*/
|
||||
static void
|
||||
do_show_revocation_reason( PKT_signature *sig )
|
||||
{
|
||||
size_t n, nn;
|
||||
const byte *p, *pp;
|
||||
int seq = 0;
|
||||
const char *text;
|
||||
|
||||
while( (p = enum_sig_subpkt( sig->hashed_data, SIGSUBPKT_REVOC_REASON,
|
||||
&n, &seq )) ) {
|
||||
if( !n )
|
||||
continue; /* invalid - just skip it */
|
||||
|
||||
if( *p == 0 )
|
||||
text = _("No reason specified");
|
||||
else if( *p == 0x01 )
|
||||
text = _("Key is superseeded");
|
||||
else if( *p == 0x02 )
|
||||
text = _("Key has been compromised");
|
||||
else if( *p == 0x03 )
|
||||
text = _("Key is no longer used");
|
||||
else if( *p == 0x20 )
|
||||
text = _("User ID is no longer valid");
|
||||
else
|
||||
text = NULL;
|
||||
|
||||
log_info( _("Reason for revocation: ") );
|
||||
if( text )
|
||||
fputs( text, log_stream() );
|
||||
else
|
||||
fprintf( log_stream(), "code=%02x", *p );
|
||||
putc( '\n', log_stream() );
|
||||
n--; p++;
|
||||
pp = NULL;
|
||||
do {
|
||||
/* We don't want any empty lines, so skip them */
|
||||
while( n && *p == '\n' ) {
|
||||
p++;
|
||||
n--;
|
||||
}
|
||||
if( n ) {
|
||||
pp = memchr( p, '\n', n );
|
||||
nn = pp? pp - p : n;
|
||||
log_info( _("Revocation comment: ") );
|
||||
print_string( log_stream(), p, nn, 0 );
|
||||
putc( '\n', log_stream() );
|
||||
p += nn; n -= nn;
|
||||
}
|
||||
} while( pp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
show_revocation_reason( PKT_public_key *pk )
|
||||
{
|
||||
/* Hmmm, this is not so easy becuase we have to duplicate the code
|
||||
* used in the trustbd to calculate the keyflags. We need to find
|
||||
* a clean way to check revocation certificates on keys and signatures.
|
||||
* And there should be no duplicate code. Because we enter this function
|
||||
* only when the trustdb toldus, taht we have a revoked key, we could
|
||||
* simplylook for a revocation cert and display this one, when there is
|
||||
* only one. Let's try to do this until we have a better solution.
|
||||
*/
|
||||
KBNODE node, keyblock = NULL;
|
||||
byte fingerprint[MAX_FINGERPRINT_LEN];
|
||||
size_t fingerlen;
|
||||
int rc;
|
||||
|
||||
/* get the keyblock */
|
||||
fingerprint_from_pk( pk, fingerprint, &fingerlen );
|
||||
rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
|
||||
if( rc ) { /* that should never happen */
|
||||
log_debug( "failed to get the keyblock\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for( node=keyblock; node; node = node->next ) {
|
||||
if( ( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
&& !cmp_public_keys( node->pkt->pkt.public_key, pk ) )
|
||||
break;
|
||||
}
|
||||
if( !node ) {
|
||||
log_debug("Oops, PK not in keyblock\n");
|
||||
release_kbnode( keyblock );
|
||||
return;
|
||||
}
|
||||
/* now find the revocation certificate */
|
||||
for( node = node->next; node ; node = node->next ) {
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
break;
|
||||
if( node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (node->pkt->pkt.signature->sig_class == 0x20
|
||||
|| node->pkt->pkt.signature->sig_class == 0x28 ) ) {
|
||||
/* FIXME: we should check the signature here */
|
||||
do_show_revocation_reason ( node->pkt->pkt.signature );
|
||||
}
|
||||
}
|
||||
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
show_paths( ulong lid, int only_first )
|
||||
@ -338,38 +444,53 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
|
||||
|
||||
/****************
|
||||
* Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
|
||||
* Returns: true if we trust.
|
||||
* Returns: true if we trust. Might change the trustlevel
|
||||
*/
|
||||
static int
|
||||
do_we_trust( PKT_public_key *pk, int trustlevel )
|
||||
do_we_trust( PKT_public_key *pk, int *trustlevel )
|
||||
{
|
||||
int rc;
|
||||
int did_add = 0;
|
||||
int trustmask = 0;
|
||||
|
||||
retry:
|
||||
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
|
||||
if( (*trustlevel & TRUST_FLAG_REVOKED) ) {
|
||||
log_info(_("key %08lX: key has been revoked!\n"),
|
||||
(ulong)keyid_from_pk( pk, NULL) );
|
||||
show_revocation_reason( pk );
|
||||
if( opt.batch )
|
||||
return 0;
|
||||
|
||||
if( !cpr_get_answer_is_yes("revoked_key.override",
|
||||
_("Use this key anyway? ")) )
|
||||
return 0;
|
||||
trustmask |= TRUST_FLAG_REVOKED;
|
||||
}
|
||||
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
|
||||
else if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
|
||||
log_info(_("key %08lX: subkey has been revoked!\n"),
|
||||
(ulong)keyid_from_pk( pk, NULL) );
|
||||
show_revocation_reason( pk );
|
||||
if( opt.batch )
|
||||
return 0;
|
||||
|
||||
if( !cpr_get_answer_is_yes("revoked_key.override",
|
||||
_("Use this key anyway? ")) )
|
||||
return 0;
|
||||
trustmask |= TRUST_FLAG_SUB_REVOKED;
|
||||
}
|
||||
*trustlevel &= ~trustmask;
|
||||
|
||||
if( opt.always_trust) {
|
||||
if( opt.verbose )
|
||||
log_info("No trust check due to --always-trust option\n");
|
||||
/* The problem with this, is that EXPIRE can't be checked as
|
||||
* this needs to insert a ne key into the trustdb first and
|
||||
* we don't want that */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
switch( (trustlevel & TRUST_MASK) ) {
|
||||
switch( (*trustlevel & TRUST_MASK) ) {
|
||||
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
|
||||
rc = insert_trust_record_by_pk( pk );
|
||||
if( rc ) {
|
||||
@ -377,11 +498,12 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
|
||||
gpg_errstr(rc) );
|
||||
return 0; /* no */
|
||||
}
|
||||
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
||||
rc = check_trust( pk, trustlevel, NULL, NULL, NULL );
|
||||
*trustlevel &= ~trustmask;
|
||||
if( rc )
|
||||
log_fatal("trust check after insert failed: %s\n",
|
||||
gpg_errstr(rc) );
|
||||
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) {
|
||||
if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) {
|
||||
log_debug("do_we_trust: oops at %d\n", __LINE__ );
|
||||
return 0;
|
||||
}
|
||||
@ -399,7 +521,8 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
|
||||
else {
|
||||
int quit;
|
||||
|
||||
rc = add_ownertrust( pk, &quit, &trustlevel );
|
||||
rc = add_ownertrust( pk, &quit, trustlevel );
|
||||
*trustlevel &= ~trustmask;
|
||||
if( !rc && !did_add && !quit ) {
|
||||
did_add = 1;
|
||||
goto retry;
|
||||
@ -445,7 +568,7 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = do_we_trust( pk, trustlevel );
|
||||
rc = do_we_trust( pk, &trustlevel );
|
||||
|
||||
if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
|
||||
return 0;
|
||||
@ -528,10 +651,12 @@ check_signatures_trust( PKT_signature *sig )
|
||||
write_status( STATUS_KEYREVOKED );
|
||||
log_info(_("WARNING: This key has been revoked by its owner!\n"));
|
||||
log_info(_(" This could mean that the signature is forgery.\n"));
|
||||
show_revocation_reason( pk );
|
||||
}
|
||||
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
|
||||
write_status( STATUS_KEYREVOKED );
|
||||
log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
|
||||
show_revocation_reason( pk );
|
||||
}
|
||||
|
||||
|
||||
@ -770,7 +895,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
||||
else {
|
||||
int trustlevel;
|
||||
|
||||
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
||||
rc = check_trust( pk, &trustlevel, pk->namehash,
|
||||
NULL, NULL );
|
||||
if( rc ) {
|
||||
log_error("error checking pk of `%s': %s\n",
|
||||
answer, gpg_errstr(rc) );
|
||||
@ -844,7 +970,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
||||
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
|
||||
int trustlevel;
|
||||
|
||||
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
||||
rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL );
|
||||
if( rc ) {
|
||||
free_public_key( pk ); pk = NULL;
|
||||
log_error(_("%s: error checking key: %s\n"),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* plaintext.c - process an plaintext packet
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -107,8 +107,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
}
|
||||
if( mfx->md )
|
||||
gcry_md_putc(mfx->md, c );
|
||||
if( c == '\r' )
|
||||
continue; /* fixme: this hack might be too simple */
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if( c == '\r' ) /* convert to native line ending */
|
||||
continue; /* fixme: this hack might be too simple */
|
||||
#endif
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
@ -152,8 +154,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
||||
if( mfx->md )
|
||||
gcry_md_putc(mfx->md, c );
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if( convert && c == '\r' )
|
||||
continue; /* fixme: this hack might be too simple */
|
||||
#endif
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
@ -169,10 +173,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
int eof;
|
||||
for( eof=0; !eof; ) {
|
||||
/* Why do we check for len < 32768:
|
||||
* If we won´ we would practically read 2 EOFS but
|
||||
* If we won't, we would practically read 2 EOFs but
|
||||
* the first one has already popped the block_filter
|
||||
* off and therefore we don't catch the boundary.
|
||||
* Always assume EOF if iobuf_read returns less bytes
|
||||
* So, always assume EOF if iobuf_read returns less bytes
|
||||
* then requested */
|
||||
int len = iobuf_read( pt->buf, buffer, 32768 );
|
||||
if( len == -1 )
|
||||
@ -217,6 +221,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
if( !state ) {
|
||||
if( c == '\r' )
|
||||
state = 1;
|
||||
else if( c == '\n' )
|
||||
state = 2;
|
||||
else
|
||||
gcry_md_putc(mfx->md, c );
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* pubkey-enc.c - public key encoded packet handling
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -23,14 +23,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "main.h"
|
||||
#include "keydb.h"
|
||||
#include "trustdb.h"
|
||||
#include "status.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static int get_it( PKT_pubkey_enc *k,
|
||||
@ -103,7 +104,6 @@ pk_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Get the session key from a pubkey enc paket and return
|
||||
* it in DEK, which should have been allocated in secure memory.
|
||||
@ -169,7 +169,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
int rc;
|
||||
MPI plain_dek = NULL;
|
||||
byte *frame = NULL;
|
||||
unsigned n;
|
||||
unsigned int n;
|
||||
size_t nframe;
|
||||
u16 csum, csum2;
|
||||
|
||||
@ -199,7 +199,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
* DEK is the encryption key (session key) with length k
|
||||
* CSUM
|
||||
*/
|
||||
if( (opt.debug & DBG_CIPHER_VALUE) )
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK frame:", frame, nframe );
|
||||
n=0;
|
||||
if( n + 7 > nframe )
|
||||
@ -219,10 +219,14 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
|
||||
dek->keylen = nframe - (n+1) - 2;
|
||||
dek->algo = frame[n++];
|
||||
if( dek->algo == GCRY_CIPHER_IDEA )
|
||||
if( dek->algo == GCRY_CIPHER_IDEA )
|
||||
write_status(STATUS_RSA_OR_IDEA);
|
||||
rc = openpgp_cipher_test_algo( dek->algo );
|
||||
if( rc ) {
|
||||
if( !opt.quiet && rc == GPGERR_CIPHER_ALGO ) {
|
||||
log_info(_("cipher algorithm %d is unknown or disabled\n"),
|
||||
dek->algo);
|
||||
}
|
||||
dek->algo = 0;
|
||||
goto leave;
|
||||
}
|
||||
@ -241,9 +245,9 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
rc = GPGERR_WRONG_SECKEY;
|
||||
goto leave;
|
||||
}
|
||||
if( (opt.debug & DBG_CIPHER_VALUE) )
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is:", dek->key, dek->keylen );
|
||||
/* check that the algo is in the preferences */
|
||||
/* check that the algo is in the preferences and whether it has expired */
|
||||
{
|
||||
PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
|
||||
if( (rc = get_pubkey( pk, keyid )) )
|
||||
@ -262,10 +266,25 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
"NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
dek->algo );
|
||||
}
|
||||
|
||||
|
||||
if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) {
|
||||
log_info(_("NOTE: secret key %08lX expired at %s\n"),
|
||||
(ulong)keyid[1], asctimestamp( pk->expiredate) );
|
||||
}
|
||||
|
||||
/* FIXME: check wheter the key has been revoked and display
|
||||
* the revocation reason. Actually the user should know this himself,
|
||||
* but the sender might not know already and therefor the user
|
||||
* should get a notice that an revoked key has been used to decode
|
||||
* the message. The user can than watch out for snakes send by
|
||||
* one of those Eves outside his paradise :-)
|
||||
*/
|
||||
free_public_key( pk );
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
mpi_release(plain_dek);
|
||||
gcry_free(frame);
|
||||
|
352
g10/revoke.c
352
g10/revoke.c
@ -1,5 +1,5 @@
|
||||
/* revoke.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -24,6 +24,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
@ -37,6 +38,38 @@
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
struct revocation_reason_info {
|
||||
int code;
|
||||
char *desc;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
revocation_reason_build_cb( PKT_signature *sig, void *opaque )
|
||||
{
|
||||
struct revocation_reason_info *reason = opaque;
|
||||
char *ud = NULL;
|
||||
byte *buffer;
|
||||
size_t buflen = 1;
|
||||
|
||||
if( reason->desc ) {
|
||||
ud = native_to_utf8( reason->desc );
|
||||
buflen += strlen(ud);
|
||||
}
|
||||
buffer = gcry_xmalloc( buflen );
|
||||
*buffer = reason->code;
|
||||
if( ud ) {
|
||||
memcpy(buffer+1, ud, strlen(ud) );
|
||||
gcry_free( ud );
|
||||
}
|
||||
|
||||
build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
|
||||
gcry_free( buffer );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a revocation certificate for UNAME
|
||||
*/
|
||||
@ -55,6 +88,7 @@ gen_revoke( const char *uname )
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE node;
|
||||
KBPOS kbpos;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
@ -62,19 +96,6 @@ gen_revoke( const char *uname )
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: ask for the reason of revocation
|
||||
0x00 - No reason specified (key revocations or cert revocations)
|
||||
Does not make sense!
|
||||
|
||||
0x01 - Key is superceded (key revocations)
|
||||
0x02 - Key material has been compromised (key revocations)
|
||||
0x03 - Key is no longer used (key revocations)
|
||||
0x20 - User id information is no longer valid (cert revocations)
|
||||
|
||||
Following the revocation code is a string of octets which gives
|
||||
information about the reason for revocation in human-readable form
|
||||
*/
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
init_packet( &pkt );
|
||||
@ -136,6 +157,13 @@ gen_revoke( const char *uname )
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get the reason for the revocation */
|
||||
reason = ask_revocation_reason( 1, 0, 1 );
|
||||
if( !reason ) { /* user decided to cancel */
|
||||
rc = 0;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
switch( is_secret_key_protected( sk ) ) {
|
||||
case -1:
|
||||
log_error(_("unknown protection algorithm\n"));
|
||||
@ -163,7 +191,9 @@ gen_revoke( const char *uname )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, NULL, NULL);
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
|
||||
revocation_reason_build_cb,
|
||||
reason );
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), gpg_errstr(rc));
|
||||
goto leave;
|
||||
@ -198,193 +228,127 @@ gen_revoke( const char *uname )
|
||||
iobuf_cancel(out);
|
||||
else
|
||||
iobuf_close(out);
|
||||
release_revocation_reason_info( reason );
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0 /* The code is not complete but anyway, now we use */
|
||||
/* the edit menu to revoke signature */
|
||||
/****************
|
||||
* Return true if there is already a revocation signature for KEYID
|
||||
* in KEYBLOCK at point node.
|
||||
*/
|
||||
static int
|
||||
already_revoked( const KBNODE keyblock, const KBNODE node, u32 *keyid ) ) {
|
||||
{
|
||||
const KBNODE n = find_prev_kbnode( keyblock, node, PKT_USER_ID );
|
||||
|
||||
for( ; n; n = n->next ) {
|
||||
PKT_signature *sig;
|
||||
if( n->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (sig = node->pkt->pkt.signature)->sig_class == 0x30
|
||||
&& sig->keyid[0] == keyid[0]
|
||||
&& sig->keyid[1] == keyid[1] )
|
||||
return 1;
|
||||
|
||||
struct revocation_reason_info *
|
||||
ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
{
|
||||
int code;
|
||||
char *description = NULL;
|
||||
struct revocation_reason_info *reason;
|
||||
const char *text_1 = _("Key has been compromised");
|
||||
const char *text_2 = _("Key is superseded");
|
||||
const char *text_3 = _("Key is no longer used");
|
||||
const char *text_4 = _("User ID is non longer valid");
|
||||
const char *code_text = NULL;
|
||||
|
||||
do {
|
||||
gcry_free(description);
|
||||
description = NULL;
|
||||
|
||||
tty_printf(_("Please select the reason for the revocation:\n"));
|
||||
if( key_rev )
|
||||
tty_printf(" 1 = %s\n", text_1 );
|
||||
if( key_rev )
|
||||
tty_printf(" 2 = %s\n", text_2 );
|
||||
if( key_rev )
|
||||
tty_printf(" 3 = %s\n", text_3 );
|
||||
if( cert_rev )
|
||||
tty_printf(" 4 = %s\n", text_4 );
|
||||
tty_printf( " 0 = %s\n", _("Cancel") );
|
||||
if( hint )
|
||||
tty_printf(_("(Probably you want to select %d here)\n"), hint );
|
||||
|
||||
for(code = 0; !code;) {
|
||||
int n;
|
||||
char *answer = cpr_get("ask_revocation_reason.code",
|
||||
_("Your decision? "));
|
||||
trim_spaces( answer );
|
||||
cpr_kill_prompt();
|
||||
if( *answer == 'q' || *answer == 'Q' )
|
||||
n = 0;
|
||||
else if( !isdigit( *answer ) )
|
||||
n = -1;
|
||||
else if( hint && !*answer )
|
||||
n = hint;
|
||||
else
|
||||
n = atoi(answer);
|
||||
gcry_free(answer);
|
||||
if( !n )
|
||||
return NULL; /* cancel */
|
||||
else if( key_rev && n == 1 ) {
|
||||
code = 0x02; /* key has been compromised */
|
||||
code_text = text_1;
|
||||
}
|
||||
else if( key_rev && n == 2 ) {
|
||||
code = 0x01; /* key is superseded */
|
||||
code_text = text_2;
|
||||
}
|
||||
else if( key_rev && n == 3 ) {
|
||||
code = 0x03; /* key is no longer used */
|
||||
code_text = text_3;
|
||||
}
|
||||
else if( cert_rev && n == 4 ) {
|
||||
code = 0x20; /* uid is non longer valid */
|
||||
code_text = text_4;
|
||||
}
|
||||
else
|
||||
tty_printf(_("Invalid selection.\n"));
|
||||
}
|
||||
else if( n->pkt->pkttype == PKT_USER_ID
|
||||
break;
|
||||
else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
tty_printf(_("Enter an optional description; "
|
||||
"end it with an empty line:\n") );
|
||||
for(;;) {
|
||||
char *answer = cpr_get("ask_revocation_reason.text", "> " );
|
||||
trim_trailing_ws( answer, strlen(answer) );
|
||||
cpr_kill_prompt();
|
||||
if( !*answer ) {
|
||||
gcry_free(answer);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
char *p = make_printable_string( answer, strlen(answer), 0 );
|
||||
gcry_free(answer);
|
||||
answer = p;
|
||||
}
|
||||
|
||||
if( !description )
|
||||
description = gcry_xstrdup(answer);
|
||||
else {
|
||||
char *p = gcry_xmalloc( strlen(description) + strlen(answer) + 2 );
|
||||
strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
|
||||
gcry_free(description);
|
||||
description = p;
|
||||
}
|
||||
gcry_free(answer);
|
||||
}
|
||||
|
||||
tty_printf(_("Reason for revocation: %s\n"), code_text );
|
||||
if( !description )
|
||||
tty_printf(_("(No description given)\n") );
|
||||
else
|
||||
tty_printf("%s\n", description );
|
||||
|
||||
} while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
|
||||
_("Is this okay? ")) );
|
||||
|
||||
reason = gcry_xmalloc( sizeof *reason );
|
||||
reason->code = code;
|
||||
reason->desc = description;
|
||||
return reason;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Ask whether the signature should be revoked. If the user commits this,
|
||||
* flag bit 0 is set.
|
||||
*/
|
||||
static void
|
||||
ask_revoke_sig( KBNODE keyblock, KBNODE node, PKT_signature *sig ) ) {
|
||||
void
|
||||
release_revocation_reason_info( struct revocation_reason_info *reason )
|
||||
{
|
||||
KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
|
||||
|
||||
if( !unode ) {
|
||||
log_error("Oops: no user ID for signature\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tty_printf(_("user ID: \""));
|
||||
tty_print_utf8_string( unode->pkt->pkt.user_id->name,
|
||||
unode->pkt->pkt.user_id->len, 0 );
|
||||
tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
|
||||
sig->keyid[1], datestr_from_sig(sig) );
|
||||
|
||||
if( cpr_get_answer_is_yes("ask_revoke_sig.one",
|
||||
_("Create a revocation certificate for this signature? (y/N)")) ) {
|
||||
node->flag |= 1;
|
||||
if( reason ) {
|
||||
gcry_free( reason->desc );
|
||||
gcry_free( reason );
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Generate a signature revocation certificate for UNAME
|
||||
*/
|
||||
int
|
||||
gen_sig_revoke( const char *uname )
|
||||
{
|
||||
int rc = 0;
|
||||
armor_filter_context_t afx;
|
||||
compress_filter_context_t zfx;
|
||||
PACKET pkt;
|
||||
IOBUF out = NULL;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE node;
|
||||
KBPOS kbpos;
|
||||
int uidchg;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
init_packet( &pkt );
|
||||
|
||||
|
||||
/* get the keyblock */
|
||||
rc = find_keyblock_byname( &kbpos, uname );
|
||||
if( rc ) {
|
||||
log_error(_("public key for user `%s' not found\n"), uname );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* read the keyblock */
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error(_("error reading the certificate: %s\n"), gpg_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error(_("Oops; public key lost!\n"));
|
||||
rc = GPGERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( (rc = open_outfile( NULL, 0, &out )) )
|
||||
goto leave;
|
||||
|
||||
if( opt.armor ) {
|
||||
afx.what = 1;
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
}
|
||||
|
||||
/* Now walk over all signatures which we did with one of
|
||||
* our secret keys. Hmmm: Should we check for duplicate signatures */
|
||||
clear_kbnode_flags( flags );
|
||||
for( node = keyblock; node; node = node->next ) {
|
||||
PKT_signature *sig;
|
||||
if( node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& ((sig = node->pkt->pkt.signature)->sig_class&~3) == 0x10
|
||||
&& seckey_available( sig->keyid )
|
||||
&& !already_revoked( keyblock, node, sig->keyid ) ) { ) {
|
||||
ask_revoke_sig( keyblock, node, sig )
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for( node = keyblock; node; node = node->next ) { {
|
||||
if( (node->flag & 1) )
|
||||
break;
|
||||
}
|
||||
if( !node ) {
|
||||
log_info(_("nothing to revoke\n"));
|
||||
iobuf_cancel(out);
|
||||
out = NULL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_PUBLIC_KEY;
|
||||
pkt.pkt.public_key = keyblock->pkt->pkt.public_key;
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), gpg_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
uidchg = 1;
|
||||
for( node = keyblock; node; node = node->next ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID )
|
||||
uidchg = 1;
|
||||
if( !(node->flag & 1) )
|
||||
continue;
|
||||
|
||||
if( uidchg ) {
|
||||
/* create a user ID packet */
|
||||
.......
|
||||
uidchg = 0;
|
||||
}
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x30, 0, NULL, NULL);
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), gpg_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), gpg_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
if( !out )
|
||||
;
|
||||
else if( rc )
|
||||
iobuf_cancel(out);
|
||||
else
|
||||
iobuf_close(out);
|
||||
return rc;
|
||||
}
|
||||
#endif /* unused code */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ringedit.c - Function for key ring editing
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -51,9 +51,10 @@
|
||||
#ifdef HAVE_LIBGDBM
|
||||
#include <gdbm.h>
|
||||
#endif
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include <gcrypt.h>
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "host2net.h"
|
||||
@ -63,10 +64,6 @@
|
||||
#include "kbx.h"
|
||||
|
||||
|
||||
#ifdef MKDIR_TAKES_ONE_ARG
|
||||
# undef mkdir
|
||||
# define mkdir(a,b) mkdir(a)
|
||||
#endif
|
||||
|
||||
|
||||
struct resource_table_struct {
|
||||
@ -191,7 +188,6 @@ enum_keyblock_resources( int *sequence, int secret )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Register a resource (which currently may only be a keyring file).
|
||||
* The first keyring which is added by this function is
|
||||
@ -312,24 +308,13 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
*last_slash_in_filename = 0;
|
||||
|
||||
if( access(filename, F_OK) ) {
|
||||
if( strlen(filename) >= 7
|
||||
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
|
||||
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
|
||||
{
|
||||
log_error( _("%s: can't create directory: %s\n"),
|
||||
filename, strerror(errno));
|
||||
rc = GPGERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else if( !opt.quiet )
|
||||
log_info( _("%s: directory created\n"), filename );
|
||||
copy_options_file( filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = GPGERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
/* on the first time we try to create the default homedir and
|
||||
* in this case the process will be terminated, so that on the
|
||||
* next invocation it can read the options file in on startup
|
||||
*/
|
||||
try_make_homedir( filename );
|
||||
rc = GPGERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
*last_slash_in_filename = '/';
|
||||
@ -363,7 +348,6 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
resource_table[i].dbf = gdbm_open( filename, 0,
|
||||
@ -457,6 +441,35 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return the filename of the firstkeyblock resource which is intended
|
||||
* for write access. This will either be the default resource or in
|
||||
* case this is not writable one of the others. If no writable is found,
|
||||
* the default filename in the homedirectory will be returned.
|
||||
* Caller must free, will never return NULL.
|
||||
*/
|
||||
char *
|
||||
get_writable_keyblock_file( int secret )
|
||||
{
|
||||
int i = secret? default_secret_resource : default_public_resource;
|
||||
|
||||
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
|
||||
if( !access( resource_table[i].fname, R_OK|W_OK ) ) {
|
||||
return gcry_xstrdup( resource_table[i].fname );
|
||||
}
|
||||
}
|
||||
for(i=0; i < MAX_RESOURCES; i++ ) {
|
||||
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
|
||||
if( !access( resource_table[i].fname, R_OK|W_OK ) ) {
|
||||
return gcry_xstrdup( resource_table[i].fname );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Assume the home dir is always writable */
|
||||
return make_filename(opt.homedir, secret? "secring.gpg"
|
||||
: "pubring.gpg", NULL );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Search a keyblock which starts with the given packet and puts all
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* seckey-cert.c - secret key certificate packet handling
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#include "i18n.h"
|
||||
#include "status.h"
|
||||
|
||||
|
||||
/****************
|
||||
* Emulate our old PK interface here - sometime in the future we might
|
||||
* change the internal design to directly fit to libgcrypt.
|
||||
@ -82,9 +83,11 @@ pk_check_secret_key( int algo, MPI *skey )
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_check( PKT_secret_key *sk )
|
||||
{
|
||||
byte *buffer;
|
||||
u16 csum=0;
|
||||
int i, res;
|
||||
unsigned nbytes;
|
||||
@ -95,6 +98,10 @@ do_check( PKT_secret_key *sk )
|
||||
GCRY_CIPHER_HD cipher_hd=NULL;
|
||||
PKT_secret_key *save_sk;
|
||||
|
||||
if( sk->protect.s2k.mode == 1001 ) {
|
||||
log_info(_("secret key parts are not available\n"));
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
if( sk->protect.algo == GCRY_CIPHER_NONE )
|
||||
BUG();
|
||||
if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
|
||||
@ -112,6 +119,7 @@ do_check( PKT_secret_key *sk )
|
||||
}
|
||||
dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
|
||||
&sk->protect.s2k, 0 );
|
||||
/* Hmmm: Do we use sync mode here even for Twofish? */
|
||||
if( !(cipher_hd = gcry_cipher_open( sk->protect.algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
@ -198,7 +206,8 @@ do_check( PKT_secret_key *sk )
|
||||
free_secret_key( save_sk );
|
||||
return GPGERR_BAD_PASS;
|
||||
}
|
||||
/* the checksum may fail, so we also check the key itself */
|
||||
/* the checksum may be correct in some cases,
|
||||
* so we also check the key itself */
|
||||
res = pk_check_secret_key( sk->pubkey_algo, sk->skey );
|
||||
if( res ) {
|
||||
copy_secret_key( sk, save_sk );
|
||||
@ -300,8 +309,6 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
) {
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
rc = gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
||||
if( rc == GCRYERR_WEAK_KEY ) {
|
||||
log_info(_("WARNING: Weak key detected"
|
||||
@ -316,18 +323,19 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
if( blocksize != 8 && blocksize != 16 )
|
||||
log_fatal("unsupported blocksize %d\n", blocksize );
|
||||
sk->protect.ivlen = blocksize;
|
||||
assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
|
||||
}
|
||||
|
||||
assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
|
||||
gcry_randomize(sk->protect.iv, sk->protect.ivlen,
|
||||
GCRY_STRONG_RANDOM);
|
||||
GCRY_STRONG_RANDOM);
|
||||
gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
|
||||
|
||||
#warning FIXME: replace set/get buffer
|
||||
if( sk->version >= 4 ) {
|
||||
#define NMPIS (GNUPG_MAX_NSKEY - GNUPG_MAX_NPKEY)
|
||||
byte *bufarr[NMPIS];
|
||||
unsigned narr[NMPIS];
|
||||
unsigned nbits[NMPIS];
|
||||
/* 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];
|
||||
int ndata=0;
|
||||
byte *p, *data;
|
||||
|
||||
@ -342,13 +350,13 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
nbits[j] = gcry_mpi_get_nbits( sk->skey[i] );
|
||||
ndata += narr[j] + 2;
|
||||
}
|
||||
for( ; j < NMPIS; j++ )
|
||||
for( ; j < GNUPG_MAX_NSKEY; j++ )
|
||||
bufarr[j] = NULL;
|
||||
ndata += 2; /* for checksum */
|
||||
|
||||
data = gcry_xmalloc_secure( ndata );
|
||||
p = data;
|
||||
for(j=0; j < NMPIS && bufarr[j]; j++ ) {
|
||||
for(j=0; j < GNUPG_MAX_NSKEY && bufarr[j]; j++ ) {
|
||||
p[0] = nbits[j] >> 8 ;
|
||||
p[1] = nbits[j];
|
||||
p += 2;
|
||||
@ -356,7 +364,6 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
p += narr[j];
|
||||
gcry_free(bufarr[j]);
|
||||
}
|
||||
#undef NMPIS
|
||||
csum = checksum( data, ndata-2);
|
||||
sk->csum = csum;
|
||||
*p++ = csum >> 8;
|
||||
|
20
g10/seskey.c
20
g10/seskey.c
@ -1,5 +1,5 @@
|
||||
/* seskey.c - make sesssion keys etc.
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -152,7 +152,7 @@ encode_session_key( DEK *dek, unsigned nbits )
|
||||
|
||||
static MPI
|
||||
do_encode_md( GCRY_MD_HD md, int algo, size_t len, unsigned nbits,
|
||||
const byte *asn, size_t asnlen )
|
||||
const byte *asn, size_t asnlen, int v3compathack )
|
||||
{
|
||||
int nframe = (nbits+7) / 8;
|
||||
byte *frame;
|
||||
@ -165,7 +165,7 @@ do_encode_md( GCRY_MD_HD md, int algo, size_t len, unsigned nbits,
|
||||
|
||||
/* We encode the MD in this way:
|
||||
*
|
||||
* 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
|
||||
* 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
|
||||
*
|
||||
* PAD consists of FF bytes.
|
||||
*/
|
||||
@ -173,7 +173,7 @@ do_encode_md( GCRY_MD_HD md, int algo, size_t len, unsigned nbits,
|
||||
: gcry_xmalloc( nframe );
|
||||
n = 0;
|
||||
frame[n++] = 0;
|
||||
frame[n++] = algo;
|
||||
frame[n++] = v3compathack? algo : 1; /* block type */
|
||||
i = nframe - len - asnlen -3 ;
|
||||
assert( i > 1 );
|
||||
memset( frame+n, 0xff, i ); n += i;
|
||||
@ -188,8 +188,15 @@ do_encode_md( GCRY_MD_HD md, int algo, size_t len, unsigned nbits,
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Encode a message digest into an MPI.
|
||||
* v3compathack is used to work around a bug in old GnuPG versions
|
||||
* which did put the algo identifier inseatd of the block type 1 into
|
||||
* the encoded value. setting this vare force the old behaviour.
|
||||
*/
|
||||
MPI
|
||||
encode_md_value( int pubkey_algo, GCRY_MD_HD md, int hash_algo, unsigned nbits )
|
||||
encode_md_value( int pubkey_algo, GCRY_MD_HD md, int hash_algo,
|
||||
unsigned nbits, int v3compathack )
|
||||
{
|
||||
int algo = hash_algo? hash_algo : gcry_md_get_algo(md);
|
||||
MPI frame;
|
||||
@ -211,9 +218,10 @@ encode_md_value( int pubkey_algo, GCRY_MD_HD md, int hash_algo, unsigned nbits )
|
||||
if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) )
|
||||
BUG();
|
||||
frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ),
|
||||
nbits, asn, asnlen );
|
||||
nbits, asn, asnlen, v3compathack );
|
||||
gcry_free( asn );
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
|
193
g10/sig-check.c
193
g10/sig-check.c
@ -1,5 +1,5 @@
|
||||
/* sig-check.c - Check a signature
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -31,6 +31,7 @@
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
|
||||
struct cmp_help_context_s {
|
||||
PKT_signature *sig;
|
||||
@ -39,9 +40,10 @@ struct cmp_help_context_s {
|
||||
|
||||
|
||||
static int do_signature_check( PKT_signature *sig, GCRY_MD_HD digest,
|
||||
u32 *r_expire );
|
||||
u32 *r_expiredate, int *r_expired );
|
||||
static int do_check( PKT_public_key *pk, PKT_signature *sig,
|
||||
GCRY_MD_HD digest );
|
||||
GCRY_MD_HD digest, int *r_expired );
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
@ -131,11 +133,13 @@ int
|
||||
signature_check( PKT_signature *sig, GCRY_MD_HD digest )
|
||||
{
|
||||
u32 dummy;
|
||||
return do_signature_check( sig, digest, &dummy );
|
||||
int dum2;
|
||||
return do_signature_check( sig, digest, &dummy, &dum2 );
|
||||
}
|
||||
|
||||
static int
|
||||
do_signature_check( PKT_signature *sig, GCRY_MD_HD digest, u32 *r_expire )
|
||||
do_signature_check( PKT_signature *sig, GCRY_MD_HD digest,
|
||||
u32 *r_expiredate, int *r_expired )
|
||||
{
|
||||
PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
|
||||
int rc=0;
|
||||
@ -143,12 +147,12 @@ do_signature_check( PKT_signature *sig, GCRY_MD_HD digest, u32 *r_expire )
|
||||
if( is_RSA(sig->pubkey_algo) )
|
||||
write_status(STATUS_RSA_OR_IDEA);
|
||||
|
||||
*r_expire = 0;
|
||||
*r_expiredate = 0;
|
||||
if( get_pubkey( pk, sig->keyid ) )
|
||||
rc = GPGERR_NO_PUBKEY;
|
||||
else {
|
||||
*r_expire = pk->expiredate;
|
||||
rc = do_check( pk, sig, digest );
|
||||
*r_expiredate = pk->expiredate;
|
||||
rc = do_check( pk, sig, digest, r_expired );
|
||||
}
|
||||
|
||||
free_public_key( pk );
|
||||
@ -199,97 +203,6 @@ do_signature_check( PKT_signature *sig, GCRY_MD_HD digest, u32 *r_expire )
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* not anymore used */
|
||||
/****************
|
||||
* Check the MDC which is contained in SIG.
|
||||
* The GCRY_MD_HD should be currently open, so that this function
|
||||
* is able to append some data, before finalizing the digest.
|
||||
*/
|
||||
int
|
||||
mdc_kludge_check( PKT_signature *sig, GCRY_MD_HD digest )
|
||||
{
|
||||
int rc=0;
|
||||
|
||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||
return rc;
|
||||
|
||||
/* make sure the digest algo is enabled (in case of a detached mdc??) */
|
||||
md_enable( digest, sig->digest_algo );
|
||||
|
||||
/* complete the digest */
|
||||
if( sig->version >= 4 )
|
||||
gcry_md_putc( digest, sig->version );
|
||||
gcry_md_putc( digest, sig->sig_class );
|
||||
if( sig->version < 4 ) {
|
||||
u32 a = sig->timestamp;
|
||||
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 );
|
||||
}
|
||||
else {
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
gcry_md_putc( digest, sig->pubkey_algo );
|
||||
gcry_md_putc( digest, sig->digest_algo );
|
||||
if( sig->hashed_data ) {
|
||||
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
|
||||
gcry_md_write( digest, sig->hashed_data, n+2 );
|
||||
n += 6;
|
||||
}
|
||||
else
|
||||
n = 6;
|
||||
/* add some magic */
|
||||
buf[0] = sig->version;
|
||||
buf[1] = 0xff;
|
||||
buf[2] = n >> 24;
|
||||
buf[3] = n >> 16;
|
||||
buf[4] = n >> 8;
|
||||
buf[5] = n;
|
||||
gcry_md_write( digest, buf, 6 );
|
||||
}
|
||||
md_final( digest );
|
||||
|
||||
rc = GPGERR_BAD_SIGN;
|
||||
{ const byte *s1 = md_read( digest, sig->digest_algo );
|
||||
int s1len = md_digest_length( sig->digest_algo );
|
||||
|
||||
log_hexdump( "MDC calculated", s1, s1len );
|
||||
|
||||
if( !sig->data[0] )
|
||||
log_debug("sig_data[0] is NULL\n");
|
||||
else {
|
||||
unsigned s2len;
|
||||
char *s2;
|
||||
|
||||
if( gcry_mpi_print( GCRYMPI_FMT_USG, &s2, &s2len, sig->data[0] ))
|
||||
BUG();
|
||||
|
||||
log_hexdump( "MDC stored ", s2, s2len );
|
||||
|
||||
if( s2len != s1len )
|
||||
log_debug("MDC check: len differ: %d/%d\n", s1len, s2len);
|
||||
else if( memcmp( s1, s2, s1len ) )
|
||||
log_debug("MDC check: hashs differ\n");
|
||||
else
|
||||
rc = 0;
|
||||
gcry_free(s2);
|
||||
}
|
||||
}
|
||||
|
||||
if( !rc && sig->flags.unknown_critical ) {
|
||||
log_info(_("assuming bad MDC due to an unknown critical bit\n"));
|
||||
rc = GPGERR_BAD_SIGN;
|
||||
}
|
||||
sig->flags.checked = 1;
|
||||
sig->flags.valid = !rc;
|
||||
|
||||
/* FIXME: check that we are actually in an encrypted packet */
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* This function gets called by pubkey_verify() if the algorithm needs it.
|
||||
*/
|
||||
@ -366,16 +279,18 @@ cmp_help( void *opaque, MPI result )
|
||||
|
||||
|
||||
static int
|
||||
do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
|
||||
do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest,
|
||||
int *r_expired )
|
||||
{
|
||||
MPI result = NULL;
|
||||
int rc=0;
|
||||
struct cmp_help_context_s ctx;
|
||||
u32 cur_time;
|
||||
|
||||
*r_expired = 0;
|
||||
if( pk->version == 4 && pk->pubkey_algo == GCRY_PK_ELG_E ) {
|
||||
log_info(_("this is a PGP generated "
|
||||
"ElGamal key which is NOT secure for signatures!\n"));
|
||||
"ElGamal key which is NOT secure for signatures!\n"));
|
||||
return GPGERR_PUBKEY_ALGO;
|
||||
}
|
||||
|
||||
@ -385,7 +300,8 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
|
||||
? _("public key is %lu second newer than the signature\n")
|
||||
: _("public key is %lu seconds newer than the signature\n"),
|
||||
d );
|
||||
return GPGERR_TIME_CONFLICT; /* pubkey newer than signature */
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPGERR_TIME_CONFLICT; /* pubkey newer than signature */
|
||||
}
|
||||
|
||||
cur_time = make_timestamp();
|
||||
@ -395,13 +311,15 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
|
||||
"in future (time warp or clock problem)\n")
|
||||
: _("key has been created %lu seconds "
|
||||
"in future (time warp or clock problem)\n"), d );
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
if( pk->expiredate && pk->expiredate < cur_time ) {
|
||||
log_info(_("NOTE: signature key expired %s\n"),
|
||||
asctimestamp( pk->expiredate ) );
|
||||
write_status(STATUS_SIGEXPIRED);
|
||||
*r_expired = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -448,13 +366,24 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
|
||||
gcry_md_final( digest );
|
||||
|
||||
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
|
||||
gcry_mpi_get_nbits(pk->pkey[0]));
|
||||
|
||||
gcry_mpi_get_nbits(pk->pkey[0]), 0);
|
||||
ctx.sig = sig;
|
||||
ctx.md = digest;
|
||||
rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
|
||||
cmp_help, &ctx );
|
||||
mpi_release( result );
|
||||
if( (opt.emulate_bugs & EMUBUG_MDENCODE)
|
||||
&& rc == GPGERR_BAD_SIGN && is_ELGAMAL(pk->pubkey_algo) ) {
|
||||
/* In this case we try again because old GnuPG versions didn't encode
|
||||
* the hash right. There is no problem with DSA however */
|
||||
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
|
||||
gcry_mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
|
||||
ctx.sig = sig;
|
||||
ctx.md = digest;
|
||||
rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
|
||||
cmp_help, &ctx );
|
||||
}
|
||||
|
||||
if( !rc && sig->flags.unknown_critical ) {
|
||||
log_info(_("assuming bad signature due to an unknown critical bit\n"));
|
||||
rc = GPGERR_BAD_SIGN;
|
||||
@ -472,16 +401,30 @@ hash_uid_node( KBNODE unode, GCRY_MD_HD md, PKT_signature *sig )
|
||||
PKT_user_id *uid = unode->pkt->pkt.user_id;
|
||||
|
||||
assert( unode->pkt->pkttype == PKT_USER_ID );
|
||||
if( sig->version >=4 ) {
|
||||
byte buf[5];
|
||||
buf[0] = 0xb4; /* indicates a userid packet */
|
||||
buf[1] = uid->len >> 24; /* always use 4 length bytes */
|
||||
buf[2] = uid->len >> 16;
|
||||
buf[3] = uid->len >> 8;
|
||||
buf[4] = uid->len;
|
||||
gcry_md_write( md, buf, 5 );
|
||||
if( uid->photo ) {
|
||||
if( sig->version >=4 ) {
|
||||
byte buf[5];
|
||||
buf[0] = 0xd1; /* packet of type 17 */
|
||||
buf[1] = uid->photolen >> 24; /* always use 4 length bytes */
|
||||
buf[2] = uid->photolen >> 16;
|
||||
buf[3] = uid->photolen >> 8;
|
||||
buf[4] = uid->photolen;
|
||||
gcry_md_write( md, buf, 5 );
|
||||
}
|
||||
gcry_md_write( md, uid->photo, uid->photolen );
|
||||
}
|
||||
else {
|
||||
if( sig->version >=4 ) {
|
||||
byte buf[5];
|
||||
buf[0] = 0xb4; /* indicates a userid packet */
|
||||
buf[1] = uid->len >> 24; /* always use 4 length bytes */
|
||||
buf[2] = uid->len >> 16;
|
||||
buf[3] = uid->len >> 8;
|
||||
buf[4] = uid->len;
|
||||
gcry_md_write( md, buf, 5 );
|
||||
}
|
||||
gcry_md_write( md, uid->name, uid->len );
|
||||
}
|
||||
gcry_md_write( md, uid->name, uid->len );
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -493,11 +436,13 @@ int
|
||||
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
|
||||
{
|
||||
u32 dummy;
|
||||
return check_key_signature2(root, node, is_selfsig, &dummy );
|
||||
int dum2;
|
||||
return check_key_signature2(root, node, is_selfsig, &dummy, &dum2 );
|
||||
}
|
||||
|
||||
int
|
||||
check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
|
||||
u32 *r_expiredate, int *r_expired )
|
||||
{
|
||||
GCRY_MD_HD md;
|
||||
PKT_public_key *pk;
|
||||
@ -507,7 +452,8 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
|
||||
if( is_selfsig )
|
||||
*is_selfsig = 0;
|
||||
*r_expire = 0;
|
||||
*r_expiredate = 0;
|
||||
*r_expired = 0;
|
||||
assert( node->pkt->pkttype == PKT_SIGNATURE );
|
||||
assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||
|
||||
@ -528,7 +474,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
if( !(md = gcry_md_open( algo, 0 )) )
|
||||
BUG();
|
||||
hash_public_key( md, pk );
|
||||
rc = do_check( pk, sig, md );
|
||||
rc = do_check( pk, sig, md, r_expired );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
|
||||
@ -539,7 +485,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
BUG();
|
||||
hash_public_key( md, pk );
|
||||
hash_public_key( md, snode->pkt->pkt.public_key );
|
||||
rc = do_check( pk, sig, md );
|
||||
rc = do_check( pk, sig, md, r_expired );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
@ -562,7 +508,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
BUG();
|
||||
hash_public_key( md, pk );
|
||||
hash_public_key( md, snode->pkt->pkt.public_key );
|
||||
rc = do_check( pk, sig, md );
|
||||
rc = do_check( pk, sig, md, r_expired );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
@ -584,10 +530,11 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
|
||||
if( is_selfsig )
|
||||
*is_selfsig = 1;
|
||||
rc = do_check( pk, sig, md );
|
||||
rc = do_check( pk, sig, md, r_expired );
|
||||
}
|
||||
else {
|
||||
rc = do_signature_check( sig, md, r_expiredate, r_expired );
|
||||
}
|
||||
else
|
||||
rc = do_signature_check( sig, md, r_expire );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
|
52
g10/sign.c
52
g10/sign.c
@ -1,5 +1,5 @@
|
||||
/* sign.c - sign data
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -36,9 +36,16 @@
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "trustdb.h"
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#define LF "\r\n"
|
||||
#else
|
||||
#define LF "\n"
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Emulate our old PK interface here - sometime in the future we might
|
||||
* change the internal design to directly fit to libgcrypt.
|
||||
@ -163,7 +170,8 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
"in future (time warp or clock problem)\n")
|
||||
: _("key has been created %lu seconds "
|
||||
"in future (time warp or clock problem)\n"), d );
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
|
||||
@ -178,7 +186,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
frame = encode_md_value( sk->pubkey_algo, md,
|
||||
digest_algo, gcry_mpi_get_nbits(sk->skey[0]));
|
||||
digest_algo, gcry_mpi_get_nbits(sk->skey[0]), 0 );
|
||||
rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
|
||||
mpi_release(frame);
|
||||
if( rc )
|
||||
@ -240,6 +248,25 @@ only_old_style( SK_LIST sk_list )
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
|
||||
{
|
||||
byte array[MAX_FINGERPRINT_LEN], *p;
|
||||
char buf[100+MAX_FINGERPRINT_LEN*2];
|
||||
size_t i, n;
|
||||
|
||||
sprintf(buf, "%c %d %d %02x %lu ",
|
||||
what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
|
||||
(ulong)sig->timestamp );
|
||||
|
||||
fingerprint_from_sk( sk, array, &n );
|
||||
p = buf + strlen(buf);
|
||||
for(i=0; i < n ; i++ )
|
||||
sprintf(p+2*i, "%02X", array[i] );
|
||||
|
||||
write_status_text( STATUS_SIG_CREATED, buf );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Sign the files whose names are in FILENAME.
|
||||
@ -521,6 +548,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
|
||||
|
||||
md = gcry_md_copy( mfx.md );
|
||||
if( !md )
|
||||
BUG();
|
||||
|
||||
if( sig->version >= 4 ) {
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
@ -573,12 +602,16 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
rc = build_packet( out, &pkt );
|
||||
if( !rc && is_status_enabled() ) {
|
||||
print_status_sig_created ( sk, sig, detached ? 'D':'S');
|
||||
}
|
||||
free_packet( &pkt );
|
||||
if( rc )
|
||||
log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
|
||||
}
|
||||
if( rc )
|
||||
goto leave;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -640,7 +673,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
else if( (rc = open_outfile( fname, 1, &out )) )
|
||||
goto leave;
|
||||
|
||||
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" );
|
||||
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
|
||||
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
@ -683,13 +716,15 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
}
|
||||
|
||||
|
||||
if( !(textmd = gcry_md_open(0, 0)) )
|
||||
textmd = gcry_md_open(0, 0);
|
||||
if( !textmd )
|
||||
BUG();
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
gcry_md_enable(textmd, hash_for(sk->pubkey_algo));
|
||||
}
|
||||
/*md_start_debug( textmd, "sign" );*/
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug( textmd, "clearsign" );
|
||||
copy_clearsig_text( out, inp, textmd,
|
||||
!opt.not_dash_escaped, opt.escape_from, old_style );
|
||||
/* fixme: check for read errors */
|
||||
@ -717,6 +752,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
sig->sig_class = 0x01;
|
||||
|
||||
md = gcry_md_copy( textmd );
|
||||
if( !md )
|
||||
BUG();
|
||||
if( sig->version >= 4 ) {
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
gcry_md_putc( md, sig->version );
|
||||
@ -768,6 +805,9 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
rc = build_packet( out, &pkt );
|
||||
if( !rc && is_status_enabled() ) {
|
||||
print_status_sig_created ( sk, sig, 'C');
|
||||
}
|
||||
free_packet( &pkt );
|
||||
if( rc )
|
||||
log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
|
||||
|
17
g10/signal.c
17
g10/signal.c
@ -1,5 +1,5 @@
|
||||
/* signal.c - signal handling
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -27,9 +27,9 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "errors.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "ttyio.h"
|
||||
@ -59,14 +59,23 @@ got_fatal_signal( int sig )
|
||||
caught_fatal_sig = 1;
|
||||
|
||||
gcry_control( GCRYCTL_TERM_SECMEM );
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
/* better don't transtale these messages */
|
||||
write(2, "\n", 1 );
|
||||
s = log_get_name(); if( s ) write(2, s, strlen(s) );
|
||||
write(2, ": ", 2 );
|
||||
s = get_signal_name(sig); write(2, s, strlen(s) );
|
||||
write(2, " caught ... exiting\n", 21 );
|
||||
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
{ /* reset action to default action and raise signal again */
|
||||
struct sigaction nact;
|
||||
nact.sa_handler = SIG_DFL;
|
||||
sigemptyset( &nact.sa_mask );
|
||||
nact.sa_flags = 0;
|
||||
sigaction( sig, &nact, NULL);
|
||||
}
|
||||
#endif
|
||||
exit(8); /* Hmmm, for some reasons rais2e does not work */
|
||||
raise( sig );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* skclist.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -66,7 +66,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
|
||||
}
|
||||
else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
|
||||
SK_LIST r;
|
||||
if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN)
|
||||
if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN )
|
||||
&& sk->pubkey_algo == GCRY_PK_ELG_E ) {
|
||||
log_info("this is a PGP generated "
|
||||
"ElGamal key which is NOT secure for signatures!\n");
|
||||
|
155
g10/status.c
155
g10/status.c
@ -1,5 +1,5 @@
|
||||
/* status.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -38,12 +38,13 @@
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "status.h"
|
||||
#include "ttyio.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
#include <gcrypt.h>
|
||||
#include "i18n.h"
|
||||
|
||||
static int fd = -1;
|
||||
@ -54,10 +55,32 @@ static int fd = -1;
|
||||
static int shm_is_locked;
|
||||
#endif /*USE_SHM_COPROCESSING*/
|
||||
|
||||
|
||||
static void
|
||||
progress_cb ( void *ctx, int c )
|
||||
{
|
||||
char buf[50];
|
||||
|
||||
if ( c == '\n' )
|
||||
sprintf ( buf, "%.20s X 100 100", (char*)ctx );
|
||||
else
|
||||
sprintf ( buf, "%.20s %c 0 0", (char*)ctx, c );
|
||||
write_status_text ( STATUS_PROGRESS, buf );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_status_fd ( int newfd )
|
||||
{
|
||||
fd = newfd;
|
||||
if ( fd != -1 ) {
|
||||
#if 0
|
||||
#warning fixme - progress functions
|
||||
register_primegen_progress ( progress_cb, "primegen" );
|
||||
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
|
||||
register_pk_elg_progress ( progress_cb, "pk_elg" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -96,6 +119,10 @@ write_status_text ( int no, const char *text)
|
||||
case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL\n"; break;
|
||||
case STATUS_TRUST_FULLY : s = "TRUST_FULLY\n"; break;
|
||||
case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE\n"; break;
|
||||
case STATUS_GET_BOOL : s = "GET_BOOL\n"; break;
|
||||
case STATUS_GET_LINE : s = "GET_LINE\n"; break;
|
||||
case STATUS_GET_HIDDEN : s = "GET_HIDDEN\n"; break;
|
||||
case STATUS_GOT_IT : s = "GOT_IT\n"; break;
|
||||
case STATUS_SHM_INFO : s = "SHM_INFO\n"; break;
|
||||
case STATUS_SHM_GET : s = "SHM_GET\n"; break;
|
||||
case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL\n"; break;
|
||||
@ -118,6 +145,16 @@ write_status_text ( int no, const char *text)
|
||||
case STATUS_ERRMDC : s = "ERRMDC\n"; break;
|
||||
case STATUS_IMPORTED : s = "IMPORTED\n"; break;
|
||||
case STATUS_IMPORT_RES : s = "IMPORT_RES\n"; break;
|
||||
case STATUS_FILE_START : s = "FILE_START\n"; break;
|
||||
case STATUS_FILE_DONE : s = "FILE_DONE\n"; break;
|
||||
case STATUS_FILE_ERROR : s = "FILE_ERROR\n"; break;
|
||||
case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION\n"; break;
|
||||
case STATUS_END_DECRYPTION : s = "END_DECRYPTION\n"; break;
|
||||
case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION\n"; break;
|
||||
case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION\n"; break;
|
||||
case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM\n"; break;
|
||||
case STATUS_PROGRESS : s = "PROGRESS\n"; break;
|
||||
case STATUS_SIG_CREATED : s = "SIG_CREATED\n"; break;
|
||||
default: s = "?\n"; break;
|
||||
}
|
||||
|
||||
@ -164,6 +201,10 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem )
|
||||
if ( shm_id == -1 )
|
||||
log_fatal("can't get %uk of shared memory: %s\n",
|
||||
(unsigned)shm_size/1024, strerror(errno));
|
||||
|
||||
#if !defined(IPC_HAVE_SHM_LOCK) \
|
||||
&& defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
|
||||
/* part of the old code which uses mlock */
|
||||
shm_area = shmat( shm_id, 0, 0 );
|
||||
if ( shm_area == (char*)-1 )
|
||||
log_fatal("can't attach %uk shared memory: %s\n",
|
||||
@ -174,29 +215,17 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem )
|
||||
#ifdef USE_CAPABILITIES
|
||||
cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
|
||||
#endif
|
||||
#ifdef IPC_HAVE_SHM_LOCK
|
||||
if ( shmctl (shm_id, SHM_LOCK, 0) )
|
||||
log_info("locking shared memory %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
else
|
||||
shm_is_locked = 1;
|
||||
#elif defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
|
||||
/* (need the cast for Solaris with Sun's workshop compilers) */
|
||||
if ( mlock ( (char*)shm_area, shm_size) )
|
||||
log_info("locking shared memory %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
else
|
||||
shm_is_locked = 1;
|
||||
#else
|
||||
log_info("Locking shared memory %d failed: No way to do it\n", shm_id );
|
||||
#endif
|
||||
#ifdef USE_CAPABILITIES
|
||||
cap_set_proc( cap_from_text("cap_ipc_lock+p") );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef IPC_RMID_DEFERRED_RELEASE
|
||||
if( shmctl( shm_id, IPC_RMID, 0) )
|
||||
log_fatal("shmctl IPC_RMDID of %d failed: %s\n",
|
||||
@ -213,13 +242,59 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem )
|
||||
shm_id, strerror(errno));
|
||||
}
|
||||
|
||||
#else /* this is the new code which handles the changes in the SHM semantics
|
||||
* introduced with Linux 2.4. The changes is that we now change the
|
||||
* permissions and then attach to the memory.
|
||||
*/
|
||||
|
||||
if( lock_mem ) {
|
||||
#ifdef USE_CAPABILITIES
|
||||
cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
|
||||
#endif
|
||||
#ifdef IPC_HAVE_SHM_LOCK
|
||||
if ( shmctl (shm_id, SHM_LOCK, 0) )
|
||||
log_info("locking shared memory %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
else
|
||||
shm_is_locked = 1;
|
||||
#else
|
||||
log_info("Locking shared memory %d failed: No way to do it\n", shm_id );
|
||||
#endif
|
||||
#ifdef USE_CAPABILITIES
|
||||
cap_set_proc( cap_from_text("cap_ipc_lock+p") );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( shmctl( shm_id, IPC_STAT, &shmds ) )
|
||||
log_fatal("shmctl IPC_STAT of %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
if( shmds.shm_perm.uid != getuid() ) {
|
||||
shmds.shm_perm.uid = getuid();
|
||||
if( shmctl( shm_id, IPC_SET, &shmds ) )
|
||||
log_fatal("shmctl IPC_SET of %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
}
|
||||
|
||||
shm_area = shmat( shm_id, 0, 0 );
|
||||
if ( shm_area == (char*)-1 )
|
||||
log_fatal("can't attach %uk shared memory: %s\n",
|
||||
(unsigned)shm_size/1024, strerror(errno));
|
||||
log_debug("mapped %uk shared memory at %p, id=%d\n",
|
||||
(unsigned)shm_size/1024, shm_area, shm_id );
|
||||
|
||||
#ifdef IPC_RMID_DEFERRED_RELEASE
|
||||
if( shmctl( shm_id, IPC_RMID, 0) )
|
||||
log_fatal("shmctl IPC_RMDID of %d failed: %s\n",
|
||||
shm_id, strerror(errno));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* write info; Protocol version, id, size, locked size */
|
||||
sprintf( buf, "pv=1 pid=%d shmid=%d sz=%u lz=%u", (int)getpid(),
|
||||
shm_id, (unsigned)shm_size, shm_is_locked? (unsigned)shm_size:0 );
|
||||
write_status_text( STATUS_SHM_INFO, buf );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Request a string from client
|
||||
* If bool, returns static string on true (do not free) or NULL for false
|
||||
@ -269,10 +344,50 @@ do_shm_get( const char *keyword, int hidden, int bool )
|
||||
#endif /* USE_SHM_COPROCESSING */
|
||||
|
||||
|
||||
/****************
|
||||
* Request a string from the client over the command-fd
|
||||
* If bool, returns static string on true (do not free) or NULL for false
|
||||
*/
|
||||
static char *
|
||||
do_get_from_fd( const char *keyword, int hidden, int bool )
|
||||
{
|
||||
int i, len;
|
||||
char *string;
|
||||
|
||||
write_status_text( bool? STATUS_GET_BOOL :
|
||||
hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword );
|
||||
|
||||
for( string = NULL, i = len = 200; ; i++ ) {
|
||||
if( i >= len-1 ) {
|
||||
char *save = string;
|
||||
len += 100;
|
||||
string = hidden? gcry_xmalloc_secure ( len ) : gcry_malloc ( len );
|
||||
if( save )
|
||||
memcpy(string, save, i );
|
||||
else
|
||||
i=0;
|
||||
}
|
||||
/* Hmmm: why not use our read_line function here */
|
||||
if( read( fd, string+i, 1) != 1 || string[i] == '\n' )
|
||||
break;
|
||||
}
|
||||
string[i] = 0;
|
||||
|
||||
write_status( STATUS_GOT_IT );
|
||||
|
||||
if( bool ) /* Fixme: is this correct??? */
|
||||
return string[0] == 'Y' ? "" : NULL;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
cpr_enabled()
|
||||
{
|
||||
if( opt.command_fd != -1 )
|
||||
return 1;
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return 1;
|
||||
@ -285,6 +400,8 @@ cpr_get( const char *keyword, const char *prompt )
|
||||
{
|
||||
char *p;
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return do_get_from_fd ( keyword, 0, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return do_shm_get( keyword, 0, 0 );
|
||||
@ -318,6 +435,8 @@ cpr_get_hidden( const char *keyword, const char *prompt )
|
||||
{
|
||||
char *p;
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return do_get_from_fd ( keyword, 1, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return do_shm_get( keyword, 1, 0 );
|
||||
@ -336,6 +455,8 @@ cpr_get_hidden( const char *keyword, const char *prompt )
|
||||
void
|
||||
cpr_kill_prompt(void)
|
||||
{
|
||||
if( opt.command_fd != -1 )
|
||||
return;
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return;
|
||||
@ -350,6 +471,8 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt )
|
||||
int yes;
|
||||
char *p;
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return !!do_get_from_fd ( keyword, 0, 1 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return !!do_shm_get( keyword, 0, 1 );
|
||||
@ -376,6 +499,8 @@ cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt )
|
||||
int yes;
|
||||
char *p;
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return !!do_get_from_fd ( keyword, 0, 1 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return !!do_shm_get( keyword, 0, 1 );
|
||||
|
17
g10/status.h
17
g10/status.h
@ -1,5 +1,5 @@
|
||||
/* status.h
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -65,7 +65,22 @@
|
||||
#define STATUS_ERRMDC 35
|
||||
#define STATUS_IMPORTED 36
|
||||
#define STATUS_IMPORT_RES 37
|
||||
#define STATUS_FILE_START 38
|
||||
#define STATUS_FILE_DONE 39
|
||||
#define STATUS_FILE_ERROR 40
|
||||
|
||||
#define STATUS_BEGIN_DECRYPTION 41
|
||||
#define STATUS_END_DECRYPTION 42
|
||||
#define STATUS_BEGIN_ENCRYPTION 43
|
||||
#define STATUS_END_ENCRYPTION 44
|
||||
|
||||
#define STATUS_DELETE_PROBLEM 45
|
||||
#define STATUS_GET_BOOL 46
|
||||
#define STATUS_GET_LINE 47
|
||||
#define STATUS_GET_HIDDEN 48
|
||||
#define STATUS_GOT_IT 49
|
||||
#define STATUS_PROGRESS 50
|
||||
#define STATUS_SIG_CREATED 51
|
||||
|
||||
/*-- status.c --*/
|
||||
void set_status_fd ( int fd );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* tdbdump.c
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -520,5 +520,6 @@ import_ownertrust( const char *fname )
|
||||
if( !is_stdin )
|
||||
fclose(fp);
|
||||
do_sync();
|
||||
sync_trustdb();
|
||||
}
|
||||
|
||||
|
22
g10/tdbio.c
22
g10/tdbio.c
@ -1,5 +1,5 @@
|
||||
/* tdbio.c
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -40,11 +40,6 @@
|
||||
#include "tdbio.h"
|
||||
|
||||
|
||||
#ifdef MKDIR_TAKES_ONE_ARG
|
||||
# undef mkdir
|
||||
# define mkdir(a,b) mkdir(a)
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Yes, this is a very simple implementation. We should really
|
||||
* use a page aligned buffer and read complete pages.
|
||||
@ -439,17 +434,8 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
assert(p);
|
||||
*p = 0;
|
||||
if( access( fname, F_OK ) ) {
|
||||
if( strlen(fname) >= 7
|
||||
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
log_fatal( _("%s: can't create directory: %s\n"),
|
||||
fname, strerror(errno) );
|
||||
else if( !opt.quiet )
|
||||
log_info( _("%s: directory created\n"), fname );
|
||||
copy_options_file( fname );
|
||||
}
|
||||
else
|
||||
log_fatal( _("%s: directory does not exist!\n"), fname );
|
||||
try_make_homedir( fname );
|
||||
log_fatal( _("%s: directory does not exist!\n"), fname );
|
||||
}
|
||||
*p = '/';
|
||||
|
||||
@ -1130,6 +1116,8 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
fputs(", expired", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_NEWKEYS )
|
||||
fputs(", newkeys", fp );
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* tdbio.h - Trust database I/O functions
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -52,6 +52,7 @@
|
||||
/* one uid with a selfsignature or an revocation */
|
||||
#define DIRF_EXPIRED 4 /* the complete key has expired */
|
||||
#define DIRF_REVOKED 8 /* the complete key has been revoked */
|
||||
#define DIRF_NEWKEYS 128 /* new keys are available: we can check the sigs */
|
||||
|
||||
#define KEYF_CHECKED 1 /* This key has been checked */
|
||||
#define KEYF_VALID 2 /* This is a valid (sub)key */
|
||||
@ -121,7 +122,7 @@ struct trust_record {
|
||||
} uid;
|
||||
struct { /* preference record */
|
||||
ulong lid; /* point back to the directory record */
|
||||
/* or 0 for a glocal pref record */
|
||||
/* or 0 for a global pref record */
|
||||
ulong next; /* points to next pref record */
|
||||
byte data[ITEMS_PER_PREF_RECORD];
|
||||
} pref;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* textfilter.c
|
||||
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -31,7 +31,13 @@
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#define LF "\r\n"
|
||||
#else
|
||||
#define LF "\n"
|
||||
#endif
|
||||
|
||||
#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */
|
||||
/* to make sure that a warning is displayed while */
|
||||
@ -151,6 +157,9 @@ copy_clearsig_text( IOBUF out, IOBUF inp, GCRY_MD_HD md,
|
||||
int truncated = 0;
|
||||
int pending_lf = 0;
|
||||
|
||||
if( !opt.pgp2_workarounds )
|
||||
pgp2mode = 0;
|
||||
|
||||
if( !escape_dash )
|
||||
escape_from = 0;
|
||||
|
||||
@ -183,12 +192,37 @@ copy_clearsig_text( IOBUF out, IOBUF inp, GCRY_MD_HD md,
|
||||
iobuf_put( out, '-' );
|
||||
iobuf_put( out, ' ' );
|
||||
}
|
||||
|
||||
#if 0 /*defined(HAVE_DOSISH_SYSTEM)*/
|
||||
/* We don't use this anymore because my interpretation of rfc2440 7.1
|
||||
* is that there is no conversion needed. If one decides to
|
||||
* clearsign a unix file on a DOS box he will get a mixed line endings.
|
||||
* If at some point it turns out, that a conversion is a nice feature
|
||||
* we can make an option out of it.
|
||||
*/
|
||||
/* make sure the lines do end in CR,LF */
|
||||
if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' )
|
||||
|| (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) {
|
||||
iobuf_write( out, buffer, n-2 );
|
||||
iobuf_put( out, '\r');
|
||||
iobuf_put( out, '\n');
|
||||
}
|
||||
else if( n && buffer[n-1] == '\n' ) {
|
||||
iobuf_write( out, buffer, n-1 );
|
||||
iobuf_put( out, '\r');
|
||||
iobuf_put( out, '\n');
|
||||
}
|
||||
else
|
||||
iobuf_write( out, buffer, n );
|
||||
|
||||
#else
|
||||
iobuf_write( out, buffer, n );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* at eof */
|
||||
if( !pending_lf ) { /* make sure that the file ends with a LF */
|
||||
iobuf_put( out, '\n');
|
||||
iobuf_writestr( out, LF );
|
||||
if( !escape_dash )
|
||||
gcry_md_putc( md, '\n' );
|
||||
}
|
||||
|
294
g10/trustdb.c
294
g10/trustdb.c
@ -1,5 +1,5 @@
|
||||
/* trustdb.c
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -110,7 +110,6 @@ static int alloced_tns;
|
||||
static int max_alloced_tns;
|
||||
|
||||
|
||||
|
||||
static LOCAL_ID_TABLE new_lid_table(void);
|
||||
static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
|
||||
static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
|
||||
@ -125,13 +124,22 @@ static int do_check( TRUSTREC *drec, unsigned *trustlevel,
|
||||
unsigned *retflgs);
|
||||
static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
|
||||
static int do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
int recheck, int *modified );
|
||||
static int check_trust_record( TRUSTREC *drec );
|
||||
int sigs_only, int *modified );
|
||||
static int check_trust_record( TRUSTREC *drec, int sigs_only );
|
||||
static void mark_fresh_keys(void);
|
||||
|
||||
/* a table used to keep track of ultimately trusted keys
|
||||
* which are the ones from our secrings and the trusted keys */
|
||||
static LOCAL_ID_TABLE ultikey_table;
|
||||
|
||||
|
||||
/* a table to keep track of newly importted keys. This one is
|
||||
* create by the insert_trust_record function and from time to time
|
||||
* used to verify key signature which have been done with these new keys */
|
||||
static LOCAL_ID_TABLE fresh_imported_keys;
|
||||
static int fresh_imported_keys_count;
|
||||
#define FRESH_KEY_CHECK_THRESHOLD 200
|
||||
|
||||
/* list of unused lid items and tables */
|
||||
static LOCAL_ID_TABLE unused_lid_tables;
|
||||
static struct local_id_item *unused_lid_items;
|
||||
@ -245,6 +253,27 @@ release_lid_table( LOCAL_ID_TABLE tbl )
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************
|
||||
* Remove all items from a LID table
|
||||
*/
|
||||
static void
|
||||
clear_lid_table( LOCAL_ID_TABLE tbl )
|
||||
{
|
||||
struct local_id_item *a, *a2;
|
||||
int i;
|
||||
|
||||
for(i=0; i < 16; i++ ) {
|
||||
for(a=tbl->items[i]; a; a = a2 ) {
|
||||
a2 = a->next;
|
||||
a->next = unused_lid_items;
|
||||
unused_lid_items = a;
|
||||
}
|
||||
tbl->items[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Add a new item to the table or return 1 if we already have this item
|
||||
*/
|
||||
@ -454,7 +483,7 @@ verify_own_keys(void)
|
||||
if( DBG_TRUST )
|
||||
log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
|
||||
|
||||
if( is_secret_key_protected( sk ) < 1 )
|
||||
if( !opt.quiet && is_secret_key_protected( sk ) < 1 )
|
||||
log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
|
||||
(ulong)keyid[1] );
|
||||
|
||||
@ -572,6 +601,18 @@ init_trustdb()
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* This function should be called in certain cases to sync the internal state
|
||||
* of the trustdb with the file image. Currently it is needed after
|
||||
* a sequence of insert_trust_record() calls.
|
||||
*/
|
||||
void
|
||||
sync_trustdb()
|
||||
{
|
||||
if( fresh_imported_keys && fresh_imported_keys_count )
|
||||
mark_fresh_keys();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************
|
||||
@ -652,7 +693,7 @@ print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
|
||||
p = get_user_id( keyid, &n );
|
||||
putc(' ', fp);
|
||||
putc('\"', fp);
|
||||
print_utf8_string( fp, p, n > 40? 40:n, 0 );
|
||||
print_utf8_string( fp, p, n > 40? 40:n );
|
||||
putc('\"', fp);
|
||||
gcry_free(p);
|
||||
putc('\n', fp );
|
||||
@ -683,8 +724,14 @@ print_uid_from_keyblock( FILE *fp, KBNODE keyblock, ulong urecno )
|
||||
if( node->pkt->pkttype == PKT_USER_ID ) {
|
||||
PKT_user_id *uidpkt = node->pkt->pkt.user_id;
|
||||
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uhash,
|
||||
uidpkt->name, uidpkt->len );
|
||||
if( uidpkt->photo ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uhash,
|
||||
uidpkt->photo, uidpkt->photolen );
|
||||
}
|
||||
else {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uhash,
|
||||
uidpkt->name, uidpkt->len );
|
||||
}
|
||||
if( !memcmp( uhash, urec.r.uid.namehash, 20 ) ) {
|
||||
print_string( fp, uidpkt->name, uidpkt->len, ':' );
|
||||
return;
|
||||
@ -1001,7 +1048,7 @@ check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid,
|
||||
(ulong)mainkid[1], lid );
|
||||
assert(keynode->pkt->pkttype == PKT_USER_ID );
|
||||
uid = keynode->pkt->pkt.user_id;
|
||||
print_utf8_string( log_stream(), uid->name, uid->len );
|
||||
print_string( log_stream(), uid->name, uid->len, '\"' );
|
||||
fputs("\"\n", log_stream());
|
||||
}
|
||||
|
||||
@ -1083,17 +1130,17 @@ check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid,
|
||||
static unsigned int
|
||||
check_sig_record( KBNODE keyblock, KBNODE signode,
|
||||
ulong siglid, int sigidx, u32 *keyid, ulong lid,
|
||||
u32 *r_expire )
|
||||
u32 *r_expiretime, int *mod_down, int *mod_up )
|
||||
{
|
||||
PKT_signature *sig = signode->pkt->pkt.signature;
|
||||
unsigned int sigflag = 0;
|
||||
TRUSTREC tmp;
|
||||
int revocation=0, rc;
|
||||
int revocation=0, expired=0, rc;
|
||||
|
||||
if( DBG_TRUST )
|
||||
log_debug("check_sig_record: %08lX.%lu %lu[%d]\n",
|
||||
(ulong)keyid[1], lid, siglid, sigidx );
|
||||
*r_expire = 0;
|
||||
*r_expiretime = 0;
|
||||
if( (sig->sig_class&~3) == 0x10 ) /* regular certification */
|
||||
;
|
||||
else if( sig->sig_class == 0x30 ) /* cert revocation */
|
||||
@ -1104,7 +1151,8 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
|
||||
read_record( siglid, &tmp, 0 );
|
||||
if( tmp.rectype == RECTYPE_DIR ) {
|
||||
/* the public key is in the trustdb: check sig */
|
||||
rc = check_key_signature2( keyblock, signode, NULL, r_expire );
|
||||
rc = check_key_signature2( keyblock, signode, NULL,
|
||||
r_expiretime, &expired );
|
||||
if( !rc ) { /* valid signature */
|
||||
if( opt.verbose )
|
||||
log_info("sig %08lX.%lu/%lu[%d]/%08lX: %s\n",
|
||||
@ -1113,18 +1161,25 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
|
||||
revocation? _("Valid certificate revocation")
|
||||
: _("Good certificate") );
|
||||
sigflag |= SIGF_CHECKED | SIGF_VALID;
|
||||
if( expired ) {
|
||||
sigflag |= SIGF_EXPIRED;
|
||||
/* We have to reset the expiretime, so that this signature
|
||||
* does not get checked over and over due to the reached
|
||||
* expiretime */
|
||||
*r_expiretime = 0;
|
||||
}
|
||||
if( revocation ) {
|
||||
sigflag |= SIGF_REVOKED;
|
||||
/**mod_down = 1;*/
|
||||
*mod_down = 1;
|
||||
}
|
||||
else
|
||||
/**mod_up = 1*/;
|
||||
*mod_up = 1;
|
||||
}
|
||||
else if( rc == GPGERR_NO_PUBKEY ) {
|
||||
/* This may happen if the key is still in the trustdb
|
||||
* but not available in the keystorage */
|
||||
sigflag |= SIGF_NOPUBKEY;
|
||||
/**mod_down = 1;*/
|
||||
*mod_down = 1;
|
||||
if( revocation )
|
||||
sigflag |= SIGF_REVOKED;
|
||||
}
|
||||
@ -1138,7 +1193,7 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
|
||||
sigflag |= SIGF_CHECKED;
|
||||
if( revocation ) {
|
||||
sigflag |= SIGF_REVOKED;
|
||||
/**mod_down = 1;*/
|
||||
*mod_down = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1169,14 +1224,15 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
|
||||
*/
|
||||
static ulong
|
||||
make_sig_records( KBNODE keyblock, KBNODE uidnode,
|
||||
ulong lid, u32 *mainkid, u32 *min_expire )
|
||||
ulong lid, u32 *mainkid, u32 *min_expire,
|
||||
int *mod_down, int *mod_up )
|
||||
{
|
||||
TRUSTREC *srecs, **s_end, *s=NULL, *s2;
|
||||
KBNODE node;
|
||||
PKT_signature *sig;
|
||||
ulong sigrecno, siglid;
|
||||
int i, sigidx = 0;
|
||||
u32 expire;
|
||||
u32 expiretime;
|
||||
|
||||
srecs = NULL; s_end = &srecs;
|
||||
for( node=uidnode->next; node; node = node->next ) {
|
||||
@ -1191,6 +1247,12 @@ make_sig_records( KBNODE keyblock, KBNODE uidnode,
|
||||
|
||||
siglid = find_or_create_lid( sig );
|
||||
/* smash dups */
|
||||
/* FIXME: Here we have a problem:
|
||||
* We can't distinguish between a certification and a certification
|
||||
* revocation without looking at class of the signature - we have
|
||||
* to see how we can store the sigclass in the sigrecord..
|
||||
* Argg- I hope I can get rid of this ugly trustdb ASAP.
|
||||
*/
|
||||
for( s2 = s; s2 ; s2 = s2->next ) {
|
||||
for(i=0; i < sigidx; i++ ) {
|
||||
if( s2->r.sig.sig[i].lid == siglid )
|
||||
@ -1219,7 +1281,8 @@ make_sig_records( KBNODE keyblock, KBNODE uidnode,
|
||||
s->r.sig.sig[sigidx].lid = siglid;
|
||||
s->r.sig.sig[sigidx].flag= check_sig_record( keyblock, node,
|
||||
siglid, sigidx,
|
||||
mainkid, lid, &expire );
|
||||
mainkid, lid, &expiretime,
|
||||
mod_down, mod_up );
|
||||
|
||||
sigidx++;
|
||||
if( sigidx == SIGS_PER_RECORD ) {
|
||||
@ -1229,8 +1292,8 @@ make_sig_records( KBNODE keyblock, KBNODE uidnode,
|
||||
sigidx = 0;
|
||||
}
|
||||
/* keep track of signers pk expire time */
|
||||
if( expire && (!*min_expire || *min_expire > expire ) )
|
||||
*min_expire = expire;
|
||||
if( expiretime && (!*min_expire || *min_expire > expiretime ) )
|
||||
*min_expire = expiretime;
|
||||
}
|
||||
if( sigidx ) {
|
||||
s->recnum = tdbio_new_recnum();
|
||||
@ -1320,7 +1383,8 @@ make_pref_record( PKT_signature *sig, ulong lid )
|
||||
|
||||
|
||||
static ulong
|
||||
make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire )
|
||||
make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire,
|
||||
int *mod_down, int *mod_up )
|
||||
{
|
||||
TRUSTREC *urecs, **uend, *u, *u2;
|
||||
KBNODE node;
|
||||
@ -1335,7 +1399,14 @@ make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire )
|
||||
if( node->pkt->pkttype != PKT_USER_ID )
|
||||
continue;
|
||||
uid = node->pkt->pkt.user_id;
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uidhash, uid->name, uid->len );
|
||||
if( uid->photo ) {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uidhash,
|
||||
uid->photo, uid->photolen );
|
||||
}
|
||||
else {
|
||||
gcry_md_hash_buffer( GCRY_MD_RMD160, uidhash,
|
||||
uid->name, uid->len );
|
||||
}
|
||||
|
||||
/* create the uid record */
|
||||
u = gcry_xcalloc( 1, sizeof *u );
|
||||
@ -1352,9 +1423,21 @@ make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire )
|
||||
&& (u->r.uid.uidflags & UIDF_VALID) ) {
|
||||
u->r.uid.prefrec = bestsig? make_pref_record( bestsig, lid ) : 0;
|
||||
}
|
||||
|
||||
/* the next test is really bad because we should modify
|
||||
* out modification timestamps only if we really have a change.
|
||||
* But because we are deleting the uid records first it is somewhat
|
||||
* difficult to track those changes. fixme */
|
||||
if( !( u->r.uid.uidflags & UIDF_VALID )
|
||||
|| ( u->r.uid.uidflags & UIDF_REVOKED ) )
|
||||
*mod_down=1;
|
||||
else
|
||||
*mod_up=1;
|
||||
|
||||
/* create the list of signatures */
|
||||
u->r.uid.siglist = make_sig_records( keyblock, node,
|
||||
lid, keyid, min_expire );
|
||||
lid, keyid, min_expire,
|
||||
mod_down, mod_up );
|
||||
}
|
||||
|
||||
uidrecno = urecs? urecs->recnum : 0;
|
||||
@ -1381,6 +1464,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
|
||||
TRUSTREC drec;
|
||||
int rc;
|
||||
|
||||
/* NOTE: We don't need recheck anymore, but this might chnage again in
|
||||
* the future */
|
||||
if( opt.dry_run )
|
||||
return 0;
|
||||
if( modified )
|
||||
@ -1391,26 +1476,27 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
rc = do_update_trust_record( keyblock, &drec, recheck, modified );
|
||||
rc = do_update_trust_record( keyblock, &drec, 0, modified );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Same as update_trust_record, but tghis functions expects the dir record.
|
||||
* On exit the dirrecord will reflect any changes made.
|
||||
* Same as update_trust_record, but this functions expects the dir record.
|
||||
* On exit the dir record will reflect any changes made.
|
||||
* With sigs_only set only foreign key signatures are checked.
|
||||
*/
|
||||
static int
|
||||
do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
int recheck, int *modified )
|
||||
int sigs_only, int *modified )
|
||||
{
|
||||
PKT_public_key *primary_pk;
|
||||
TRUSTREC krec, urec, prec, helprec;
|
||||
int i, rc = 0;
|
||||
u32 keyid[2]; /* keyid of primary key */
|
||||
/* int mod_up = 0;
|
||||
int mod_down = 0; */
|
||||
int mod_up = 0;
|
||||
int mod_down = 0;
|
||||
ulong recno, r2;
|
||||
u32 expire;
|
||||
u32 expiretime;
|
||||
|
||||
primary_pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
|
||||
if( !primary_pk->local_id )
|
||||
@ -1425,7 +1511,7 @@ do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
/* delete the old stuff */
|
||||
/* delete the old stuff FIXME: implementend sigs_only */
|
||||
for( recno=drec->r.dir.keylist; recno; recno = krec.r.key.next ) {
|
||||
read_record( recno, &krec, RECTYPE_KEY );
|
||||
delete_record( recno );
|
||||
@ -1448,22 +1534,13 @@ do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
|
||||
/* insert new stuff */
|
||||
drec->r.dir.dirflags &= ~DIRF_REVOKED;
|
||||
drec->r.dir.dirflags &= ~DIRF_NEWKEYS;
|
||||
drec->r.dir.keylist = make_key_records( keyblock, drec->recnum, keyid, &i );
|
||||
if( i ) /* primary key has been revoked */
|
||||
drec->r.dir.dirflags &= DIRF_REVOKED;
|
||||
expire = 0;
|
||||
drec->r.dir.dirflags |= DIRF_REVOKED;
|
||||
expiretime = 0;
|
||||
drec->r.dir.uidlist = make_uid_records( keyblock, drec->recnum, keyid,
|
||||
&expire );
|
||||
#if 0
|
||||
if( orig_uidflags != urec.r.uid.uidflags ) {
|
||||
write_record( &urec );
|
||||
if( !( urec.r.uid.uidflags & UIDF_VALID )
|
||||
|| ( urec.r.uid.uidflags & UIDF_REVOKED ) )
|
||||
*mod_down=1;
|
||||
else
|
||||
*mod_up=1; /*(maybe a new user id)*/
|
||||
#endif
|
||||
|
||||
&expiretime, &mod_down, &mod_up );
|
||||
if( rc )
|
||||
rc = tdbio_cancel_transaction();
|
||||
else {
|
||||
@ -1471,9 +1548,9 @@ do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
*modified = 1;
|
||||
drec->r.dir.dirflags |= DIRF_CHECKED;
|
||||
drec->r.dir.valcheck = 0;
|
||||
drec->r.dir.checkat = expire;
|
||||
drec->r.dir.checkat = expiretime;
|
||||
write_record( drec );
|
||||
/*tdbio_write_modify_stamp( mod_up, mod_down );*/
|
||||
tdbio_write_modify_stamp( mod_up, mod_down );
|
||||
rc = tdbio_end_transaction();
|
||||
}
|
||||
return rc;
|
||||
@ -1538,16 +1615,28 @@ insert_trust_record( KBNODE keyblock )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mark tdb as modified upwards */
|
||||
tdbio_write_modify_stamp( 1, 0 );
|
||||
|
||||
/* and put all the other stuff into the keydb */
|
||||
rc = do_update_trust_record( keyblock, &dirrec, 1, NULL );
|
||||
rc = do_update_trust_record( keyblock, &dirrec, 0, NULL );
|
||||
|
||||
do_sync();
|
||||
|
||||
/* keep track of new keys */
|
||||
if( !fresh_imported_keys )
|
||||
fresh_imported_keys = new_lid_table();
|
||||
ins_lid_table_item( fresh_imported_keys, pk->local_id, 0 );
|
||||
if( ++fresh_imported_keys_count > FRESH_KEY_CHECK_THRESHOLD )
|
||||
mark_fresh_keys();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Insert a trust record indentified by a PK into the TrustDB
|
||||
*/
|
||||
@ -1585,7 +1674,7 @@ insert_trust_record_by_pk( PKT_public_key *pk )
|
||||
* Currently we only do an update_trust_record.
|
||||
*/
|
||||
static int
|
||||
check_trust_record( TRUSTREC *drec )
|
||||
check_trust_record( TRUSTREC *drec, int sigs_only )
|
||||
{
|
||||
KBNODE keyblock;
|
||||
int modified, rc;
|
||||
@ -1597,7 +1686,7 @@ check_trust_record( TRUSTREC *drec )
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = do_update_trust_record( keyblock, drec, 0, &modified );
|
||||
rc = do_update_trust_record( keyblock, drec, sigs_only, &modified );
|
||||
release_kbnode( keyblock );
|
||||
|
||||
return rc;
|
||||
@ -1674,7 +1763,7 @@ update_trustdb()
|
||||
|
||||
|
||||
/****************
|
||||
* Do all required check in the trustdb. This function walks over all
|
||||
* Do all required checks in the trustdb. This function walks over all
|
||||
* records in the trustdb and does scheduled processing.
|
||||
*/
|
||||
void
|
||||
@ -1682,7 +1771,7 @@ check_trustdb( const char *username )
|
||||
{
|
||||
TRUSTREC rec;
|
||||
ulong recnum;
|
||||
ulong count=0, upd_count=0, err_count=0, skip_count=0;
|
||||
ulong count=0, upd_count=0, err_count=0, skip_count=0, sigonly_count=0;
|
||||
ulong current_time = make_timestamp();
|
||||
|
||||
if( username )
|
||||
@ -1691,15 +1780,25 @@ check_trustdb( const char *username )
|
||||
init_trustdb();
|
||||
|
||||
for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
|
||||
int sigs_only;
|
||||
|
||||
if( rec.rectype != RECTYPE_DIR )
|
||||
continue; /* we only want the dir records */
|
||||
|
||||
if( count && !(count % 100) && !opt.quiet )
|
||||
log_info(_("%lu keys so far processed\n"), count);
|
||||
count++;
|
||||
if( !rec.r.dir.checkat || rec.r.dir.checkat > current_time ) {
|
||||
skip_count++;
|
||||
continue; /* not scheduled for checking */
|
||||
sigs_only = 0;
|
||||
|
||||
if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
|
||||
;
|
||||
else if( !rec.r.dir.checkat || rec.r.dir.checkat > current_time ) {
|
||||
if( !(rec.r.dir.dirflags & DIRF_NEWKEYS) ) {
|
||||
skip_count++;
|
||||
continue; /* not scheduled for checking */
|
||||
}
|
||||
sigs_only = 1; /* new public keys - check them */
|
||||
sigonly_count++;
|
||||
}
|
||||
|
||||
if( !rec.r.dir.keylist ) {
|
||||
@ -1708,11 +1807,12 @@ check_trustdb( const char *username )
|
||||
continue;
|
||||
}
|
||||
|
||||
check_trust_record( &rec );
|
||||
|
||||
check_trust_record( &rec, sigs_only );
|
||||
}
|
||||
|
||||
log_info(_("%lu keys processed\n"), count);
|
||||
if( sigonly_count )
|
||||
log_info(_("\t%lu due to new pubkeys\n"), sigonly_count);
|
||||
if( skip_count )
|
||||
log_info(_("\t%lu keys skipped\n"), skip_count);
|
||||
if( err_count )
|
||||
@ -1772,8 +1872,12 @@ build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( dirrec.r.dir.checkat && dirrec.r.dir.checkat <= make_timestamp() )
|
||||
check_trust_record( &dirrec );
|
||||
if( dirrec.r.dir.checkat && dirrec.r.dir.checkat <= make_timestamp() ) {
|
||||
check_trust_record( &dirrec, 0 );
|
||||
}
|
||||
else if( (dirrec.r.dir.dirflags & DIRF_NEWKEYS) ) {
|
||||
check_trust_record( &dirrec, 1 );
|
||||
}
|
||||
|
||||
keynode->n.k.ownertrust = dirrec.r.dir.ownertrust & TRUST_MASK;
|
||||
|
||||
@ -1924,10 +2028,10 @@ propagate_validity( TN root, TN node, int (*add_fnc)(ulong), unsigned *retflgs )
|
||||
}
|
||||
|
||||
/* loop over all user ids */
|
||||
for( ur=node->list; ur && max_validity < TRUST_FULLY; ur = ur->next ) {
|
||||
for( ur=node->list; ur && max_validity <= TRUST_FULLY; ur = ur->next ) {
|
||||
assert( ur->is_uid );
|
||||
/* loop over all signators */
|
||||
for(kr=ur->list; kr && max_validity < TRUST_FULLY; kr = kr->next ) {
|
||||
for(kr=ur->list; kr && max_validity <= TRUST_FULLY; kr = kr->next ) {
|
||||
if( propagate_validity( root, kr, add_fnc, retflgs ) )
|
||||
return -1; /* quit */
|
||||
if( kr->n.k.validity == TRUST_ULTIMATE ) {
|
||||
@ -2001,8 +2105,12 @@ verify_key( int max_depth, TRUSTREC *drec, const char *namehash,
|
||||
if( !tree )
|
||||
return TRUST_UNDEFINED;
|
||||
pv_result = propagate_validity( tree, tree, add_fnc, retflgs );
|
||||
if( namehash ) {
|
||||
if( namehash && tree->n.k.validity != TRUST_ULTIMATE ) {
|
||||
/* find the matching user id.
|
||||
* We don't do this here if the key is ultimately trusted; in
|
||||
* this case there will be no lids for the user IDs and frankly
|
||||
* it does not make sense to compare by the name if we do
|
||||
* have the secret key.
|
||||
* fixme: the way we handle this is too inefficient */
|
||||
TN ur;
|
||||
TRUSTREC rec;
|
||||
@ -2075,6 +2183,7 @@ do_check( TRUSTREC *dr, unsigned *validity,
|
||||
}
|
||||
else if( !add_fnc
|
||||
&& tdbio_db_matches_options()
|
||||
/* FIXME, TODO: This comparision is WRONG ! */
|
||||
&& dr->r.dir.valcheck
|
||||
> tdbio_read_modify_stamp( (dr->r.dir.validity < TRUST_FULLY) )
|
||||
&& dr->r.dir.validity )
|
||||
@ -2240,10 +2349,16 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
|
||||
log_info(_("key %08lX.%lu: created in future "
|
||||
"(time warp or clock problem)\n"),
|
||||
(ulong)keyid[1], pk->local_id );
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPGERR_TIME_CONFLICT;
|
||||
}
|
||||
if( rec.r.dir.checkat && rec.r.dir.checkat <= cur_time )
|
||||
check_trust_record( &rec );
|
||||
|
||||
if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
|
||||
check_trust_record( &rec, 0 );
|
||||
else if( rec.r.dir.checkat && rec.r.dir.checkat <= cur_time )
|
||||
check_trust_record( &rec, 0 );
|
||||
else if( (rec.r.dir.dirflags & DIRF_NEWKEYS) )
|
||||
check_trust_record( &rec, 1 );
|
||||
|
||||
if( pk->expiredate && pk->expiredate <= cur_time ) {
|
||||
log_info(_("key %08lX.%lu: expired at %s\n"),
|
||||
@ -2299,6 +2414,51 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* scan the whole trustdb and mark all signature records whose keys
|
||||
* are freshly imported.
|
||||
*/
|
||||
static void
|
||||
mark_fresh_keys()
|
||||
{
|
||||
TRUSTREC dirrec, rec;
|
||||
ulong recnum, lid;
|
||||
int i;
|
||||
|
||||
memset( &dirrec, 0, sizeof dirrec );
|
||||
|
||||
for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
|
||||
if( rec.rectype != RECTYPE_SIG )
|
||||
continue;
|
||||
/* if we have already have the dir record, we can check it now */
|
||||
if( dirrec.recnum == rec.r.sig.lid
|
||||
&& (dirrec.r.dir.dirflags & DIRF_NEWKEYS) )
|
||||
continue; /* flag is already set */
|
||||
|
||||
for(i=0; i < SIGS_PER_RECORD; i++ ) {
|
||||
if( !(lid=rec.r.sig.sig[i].lid) )
|
||||
continue; /* skip deleted sigs */
|
||||
if( !(rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||
continue; /* skip checked signatures */
|
||||
if( qry_lid_table_flag( fresh_imported_keys, lid, NULL ) )
|
||||
continue; /* not in the list of new keys */
|
||||
read_record( rec.r.sig.lid, &dirrec, RECTYPE_DIR );
|
||||
if( !(dirrec.r.dir.dirflags & DIRF_NEWKEYS) ) {
|
||||
dirrec.r.dir.dirflags |= DIRF_NEWKEYS;
|
||||
write_record( &dirrec );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do_sync();
|
||||
|
||||
clear_lid_table( fresh_imported_keys );
|
||||
fresh_imported_keys_count = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
query_trust_info( PKT_public_key *pk, const byte *namehash )
|
||||
{
|
||||
@ -2532,7 +2692,7 @@ enum_cert_paths_print( void **context, FILE *fp,
|
||||
/*
|
||||
* Return an allocated buffer with the preference values for
|
||||
* the key with LID and the userid which is identified by the
|
||||
* HAMEHASH or the firstone if namehash is NULL. ret_n receives
|
||||
* HAMEHASH or the first one if namehash is NULL. ret_n receives
|
||||
* the length of the allocated buffer. Structure of the buffer is
|
||||
* a repeated sequences of 2 bytes; where the first byte describes the
|
||||
* type of the preference and the second one the value. The constants
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* trustdb.h - Trust database
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -49,6 +49,7 @@ void check_trustdb( const char *username );
|
||||
void update_trustdb( void );
|
||||
int setup_trustdb( int level, const char *dbname );
|
||||
void init_trustdb( void );
|
||||
void sync_trustdb( void );
|
||||
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
|
||||
const byte* nh, int (*add_fnc)(ulong), unsigned *retflgs );
|
||||
int query_trust_info( PKT_public_key *pk, const byte *nh );
|
||||
|
91
g10/verify.c
91
g10/verify.c
@ -1,5 +1,5 @@
|
||||
/* verify.c - verify signed data
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -25,14 +25,15 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include <gcrypt.h>
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
@ -58,6 +59,7 @@ verify_signatures( int nfiles, char **files )
|
||||
int i, rc;
|
||||
STRLIST sl;
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
sigfile = nfiles? *files : NULL;
|
||||
|
||||
/* open the signature file */
|
||||
@ -67,6 +69,51 @@ verify_signatures( int nfiles, char **files )
|
||||
return GPGERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
if( !opt.no_armor && use_armor_filter( fp ) )
|
||||
iobuf_push_filter( fp, armor_filter, &afx );
|
||||
|
||||
sl = NULL;
|
||||
for(i=1 ; i < nfiles; i++ )
|
||||
add_to_strlist( &sl, files[i] );
|
||||
rc = proc_signature_packets( NULL, fp, sl, sigfile );
|
||||
free_strlist(sl);
|
||||
iobuf_close(fp);
|
||||
if( afx.no_openpgp_data && rc == -1 ) {
|
||||
log_error(_("the signature could not be verified.\n"
|
||||
"Please remember that the signature file (.sig or .asc)\n"
|
||||
"should be the first file given on the command line.\n") );
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_file_status( int status, const char *name, int what )
|
||||
{
|
||||
char *p = gcry_xmalloc(strlen(name)+10);
|
||||
sprintf(p, "%d %s", what, name );
|
||||
write_status_text( status, p );
|
||||
gcry_free(p);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
verify_one_file( const char *name )
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
int rc;
|
||||
|
||||
print_file_status( STATUS_FILE_START, name, 1 );
|
||||
fp = iobuf_open(name);
|
||||
if( !fp ) {
|
||||
print_file_status( STATUS_FILE_ERROR, name, 1 );
|
||||
log_error(_("can't open `%s'\n"), print_fname_stdin(name));
|
||||
return GPGERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
if( !opt.no_armor ) {
|
||||
if( use_armor_filter( fp ) ) {
|
||||
memset( &afx, 0, sizeof afx);
|
||||
@ -74,14 +121,44 @@ verify_signatures( int nfiles, char **files )
|
||||
}
|
||||
}
|
||||
|
||||
sl = NULL;
|
||||
for(i=1 ; i < nfiles; i++ )
|
||||
add_to_strlist( &sl, files[i] );
|
||||
rc = proc_signature_packets( NULL, fp, sl, sigfile );
|
||||
free_strlist(sl);
|
||||
rc = proc_signature_packets( NULL, fp, NULL, name );
|
||||
iobuf_close(fp);
|
||||
write_status( STATUS_FILE_DONE );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Verify each file given in the files array or read the names of the
|
||||
* files from stdin.
|
||||
* Note: This function can not handle detached signatures.
|
||||
*/
|
||||
int
|
||||
verify_files( int nfiles, char **files )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !nfiles ) { /* read the filenames from stdin */
|
||||
char line[2048];
|
||||
unsigned int lno = 0;
|
||||
|
||||
while( fgets(line, DIM(line), stdin) ) {
|
||||
lno++;
|
||||
if( !*line || line[strlen(line)-1] != '\n' ) {
|
||||
log_error(_("input line %u too long or missing LF\n"), lno );
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
/* This code does not work on MSDOS but how cares there are
|
||||
* also no script languages available. We don't strip any
|
||||
* spaces, so that we can process nearly all filenames */
|
||||
line[strlen(line)-1] = 0;
|
||||
verify_one_file( line );
|
||||
}
|
||||
|
||||
}
|
||||
else { /* take filenames from the array */
|
||||
for(i=0; i < nfiles; i++ )
|
||||
verify_one_file( files[i] );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,13 @@
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* http.h (HTTP_FLAG_TRY_PROXY): new.
|
||||
|
||||
* error.h (G10ERR_NOT_PROCESSED): New.
|
||||
|
||||
* iobuf.h (IOBUFCTRL_CANCEL): New.
|
||||
|
||||
* types.h (HAVE_U64_TYPEDEF): Defined depending on configure test.
|
||||
|
||||
Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* Changed all "g10_"/"GPG_" prefixes to "gpg_"/"GPG_".
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* errors.h - erro code
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
/* errors.h - error codes fro GnuPG
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
*
|
||||
@ -74,6 +74,7 @@
|
||||
#define GPGERR_UNKNOWN_HOST 149
|
||||
#define GPGERR_SELFTEST_FAILED 50
|
||||
#define GPGERR_NOT_ENCRYPTED 151
|
||||
#define GPGERR_NOT_PROCESSED 152
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
char *strerror( int n );
|
||||
|
@ -49,6 +49,10 @@ typedef enum {
|
||||
HTTP_REQ_POST = 3
|
||||
} HTTP_REQ_TYPE;
|
||||
|
||||
enum { /* put flag values into an enum, so that gdb can display them */
|
||||
HTTP_FLAG_TRY_PROXY = 1
|
||||
};
|
||||
|
||||
struct http_context {
|
||||
int initialized;
|
||||
unsigned int status_code;
|
||||
@ -60,7 +64,8 @@ struct http_context {
|
||||
PARSED_URI uri;
|
||||
HTTP_REQ_TYPE req_type;
|
||||
byte *buffer; /* line buffer */
|
||||
unsigned buffer_size;
|
||||
unsigned int buffer_size;
|
||||
unsigned int flags;
|
||||
};
|
||||
typedef struct http_context *HTTP_HD;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define IOBUFCTRL_UNDERFLOW 3
|
||||
#define IOBUFCTRL_FLUSH 4
|
||||
#define IOBUFCTRL_DESC 5
|
||||
#define IOBUFCTRL_CANCEL 6
|
||||
#define IOBUFCTRL_USER 16
|
||||
|
||||
typedef struct iobuf_struct *IOBUF;
|
||||
|
@ -83,6 +83,11 @@
|
||||
#define HAVE_U32_TYPEDEF
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Warning: Some systems segfault when this u64 typedef and
|
||||
* the dummy code in cipher/md.c is not available. Examples are
|
||||
* Solaris and IRIX.
|
||||
*/
|
||||
#ifndef HAVE_U64_TYPEDEF
|
||||
#undef u64 /* maybe there is a macro with this name */
|
||||
#if SIZEOF_UNSIGNED_INT == 8
|
||||
@ -91,7 +96,7 @@
|
||||
#elif SIZEOF_UNSIGNED_LONG == 8
|
||||
typedef unsigned long u64;
|
||||
#define HAVE_U64_TYPEDEF
|
||||
#elif __GNUC__ >= 2 || defined(__SUNPRO_C)
|
||||
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||
typedef unsigned long long u64;
|
||||
#define HAVE_U64_TYPEDEF
|
||||
#endif
|
||||
|
@ -40,6 +40,7 @@ void gpg_log_print_prefix(const char *text);
|
||||
void log_set_name( const char *name );
|
||||
const char *log_get_name(void);
|
||||
void log_set_pid( int pid );
|
||||
void log_inc_errorcount(void);
|
||||
int log_get_errorcount( int clear );
|
||||
void gpg_log_hexdump( const char *text, const char *buf, size_t len );
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* argparse.c (default_strusage): Changed year of default copyright.
|
||||
|
||||
* dotlock.c (disable_dotlock): New.
|
||||
|
||||
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* README: New.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* [argparse.c wk 17.06.97] Argument Parser for option handling
|
||||
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
@ -899,7 +899,7 @@ strusage( int level )
|
||||
switch( level ) {
|
||||
case 11: p = "foo"; break;
|
||||
case 13: p = "0.0"; break;
|
||||
case 14: p = "Copyright (C) 1999 Free Software Foundation, Inc."; break;
|
||||
case 14: p = "Copyright (C) 2000 Free Software Foundation, Inc."; break;
|
||||
case 15: p =
|
||||
"This program comes with ABSOLUTELY NO WARRANTY.\n"
|
||||
"This is free software, and you are welcome to redistribute it\n"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* dotlock.c - dotfile locking
|
||||
* Copyright (C) 1998,2000 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -42,14 +42,22 @@ struct dotlock_handle {
|
||||
char *tname; /* name of lockfile template */
|
||||
char *lockname; /* name of the real lockfile */
|
||||
int locked; /* lock status */
|
||||
int disable; /* locking */
|
||||
};
|
||||
|
||||
|
||||
static DOTLOCK all_lockfiles;
|
||||
static int never_lock;
|
||||
|
||||
static int read_lockfile( const char *name );
|
||||
static void remove_lockfiles(void);
|
||||
|
||||
void
|
||||
disable_dotlock(void)
|
||||
{
|
||||
never_lock = 1;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Create a lockfile with the given name and return an object of
|
||||
* type DOTLOCK which may be used later to actually do the lock.
|
||||
@ -88,6 +96,16 @@ create_dotlock( const char *file_to_lock )
|
||||
return NULL;
|
||||
|
||||
h = jnlib_xcalloc( 1, sizeof *h );
|
||||
if( never_lock ) {
|
||||
h->disable = 1;
|
||||
#ifdef _REENTRANT
|
||||
/* fixme: aquire mutex on all_lockfiles */
|
||||
#endif
|
||||
h->next = all_lockfiles;
|
||||
all_lockfiles = h;
|
||||
return h;
|
||||
}
|
||||
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
sprintf( pidstr, "%10d\n", (int)getpid() );
|
||||
/* fixme: add the hostname to the second line (FQDN or IP addr?) */
|
||||
@ -191,6 +209,10 @@ make_dotlock( DOTLOCK h, long timeout )
|
||||
const char *maybe_dead="";
|
||||
int backoff=0;
|
||||
|
||||
if( h->disable ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( h->locked ) {
|
||||
log_debug("oops, `%s' is already locked\n", h->lockname );
|
||||
return 0;
|
||||
@ -259,6 +281,10 @@ release_dotlock( DOTLOCK h )
|
||||
#else
|
||||
int pid;
|
||||
|
||||
if( h->disable ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !h->locked ) {
|
||||
log_debug("oops, `%s' is not locked\n", h->lockname );
|
||||
return 0;
|
||||
@ -333,11 +359,13 @@ remove_lockfiles()
|
||||
|
||||
while( h ) {
|
||||
h2 = h->next;
|
||||
if( h->locked )
|
||||
unlink( h->lockname );
|
||||
unlink(h->tname);
|
||||
jnlib_free(h->tname);
|
||||
jnlib_free(h->lockname);
|
||||
if( !h->disable ) {
|
||||
if( h->locked )
|
||||
unlink( h->lockname );
|
||||
unlink(h->tname);
|
||||
jnlib_free(h->tname);
|
||||
jnlib_free(h->lockname);
|
||||
}
|
||||
jnlib_free(h);
|
||||
h = h2;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
struct dotlock_handle;
|
||||
typedef struct dotlock_handle *DOTLOCK;
|
||||
|
||||
void disable_dotlock(void);
|
||||
DOTLOCK create_dotlock( const char *file_to_lock );
|
||||
int make_dotlock( DOTLOCK h, long timeout );
|
||||
int release_dotlock( DOTLOCK h );
|
||||
|
@ -1,3 +1,28 @@
|
||||
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
|
||||
|
||||
* iobuf.c (iobuf_cancel): Broadcast the new Cancel message to all
|
||||
filters. Fix for MSDOS.
|
||||
|
||||
* miscutil.c (asctimestamp): Fix for possible buffer overflow by
|
||||
a large system returned date format string.
|
||||
|
||||
* logger.c (log_inc_errorcount): New.
|
||||
|
||||
* w32reg.c: New.
|
||||
|
||||
* simple-gettext.c: Use the Registry to locate the mo file.
|
||||
|
||||
* http.c (send_request): Add support for proxys; suggested by
|
||||
Walter Hofmann.
|
||||
(http_open_document): Pass flags to http_open.
|
||||
|
||||
* ttyio.c (do_get): Replaced #if __MINGW32__ by #ifdef because
|
||||
gcc 2.95.1 assigns a floating point value (0.2) to this macro,
|
||||
which in turn can't be used in an expression.
|
||||
* ttyio.c: Simulate termios with termios. By Dave Dykstra.
|
||||
* ttyio.c (tty_print_utf8_string): Oops.
|
||||
* ttyio.c (tty_print_utf8_string2): New to allow a max output size.
|
||||
|
||||
Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* Changed all "g10_"/"GPG_" prefixes to "gpg_"/"GPG_".
|
||||
|
@ -8,7 +8,7 @@ noinst_LTLIBRARIES = libutil.la
|
||||
libutil_la_LDFLAGS =
|
||||
libutil_la_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
|
||||
ttyio.c errors.c iobuf.c \
|
||||
http.c simple-gettext.c
|
||||
http.c simple-gettext.c w32reg.c
|
||||
|
||||
|
||||
http-test: http.c
|
||||
|
42
util/http.c
42
util/http.c
@ -1,5 +1,5 @@
|
||||
/* http.c - HTTP protocol handler
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
#ifndef HAVE_DOSISH_SYSTEM /* fixme: add support W32 sockets */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@ -76,7 +76,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( flags || !(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST) )
|
||||
if( !(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST) )
|
||||
return GPGERR_INV_ARG;
|
||||
|
||||
/* initialize the handle */
|
||||
@ -84,6 +84,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
|
||||
hd->sock = -1;
|
||||
hd->initialized = 1;
|
||||
hd->req_type = reqtype;
|
||||
hd->flags = flags;
|
||||
|
||||
rc = parse_uri( &hd->uri, url );
|
||||
if( !rc ) {
|
||||
@ -150,10 +151,7 @@ http_open_document( HTTP_HD hd, const char *document, unsigned int flags )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( flags )
|
||||
return GPGERR_INV_ARG;
|
||||
|
||||
rc = http_open( hd, HTTP_REQ_GET, document, 0 );
|
||||
rc = http_open( hd, HTTP_REQ_GET, document, flags );
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
@ -429,21 +427,47 @@ send_request( HTTP_HD hd )
|
||||
byte *request, *p;
|
||||
ushort port;
|
||||
int rc;
|
||||
const char *http_proxy = NULL;
|
||||
|
||||
server = *hd->uri->host? hd->uri->host : "localhost";
|
||||
port = hd->uri->port? hd->uri->port : 80;
|
||||
|
||||
hd->sock = connect_server( server, port );
|
||||
if( (hd->flags & HTTP_FLAG_TRY_PROXY)
|
||||
&& (http_proxy = getenv( "http_proxy" )) ) {
|
||||
PARSED_URI uri;
|
||||
|
||||
rc = parse_uri( &uri, http_proxy );
|
||||
if (rc) {
|
||||
log_error("invalid $http_proxy: %s\n", gpg_errstr(rc));
|
||||
release_parsed_uri( uri );
|
||||
return GPGERR_NETWORK;
|
||||
}
|
||||
hd->sock = connect_server( *uri->host? uri->host : "localhost",
|
||||
uri->port? uri->port : 80 );
|
||||
release_parsed_uri( uri );
|
||||
}
|
||||
else
|
||||
hd->sock = connect_server( server, port );
|
||||
|
||||
if( hd->sock == -1 )
|
||||
return GPGERR_NETWORK;
|
||||
|
||||
p = build_rel_path( hd->uri );
|
||||
request = gcry_xmalloc( strlen(p) + 20 );
|
||||
sprintf( request, "%s %s%s HTTP/1.0\r\n",
|
||||
if( http_proxy ) {
|
||||
sprintf( request, "%s http://%s:%hu%s%s HTTP/1.0\r\n",
|
||||
hd->req_type == HTTP_REQ_GET ? "GET" :
|
||||
hd->req_type == HTTP_REQ_HEAD? "HEAD":
|
||||
hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
|
||||
server, port, *p == '/'? "":"/", p );
|
||||
}
|
||||
else {
|
||||
sprintf( request, "%s %s%s HTTP/1.0\r\n",
|
||||
hd->req_type == HTTP_REQ_GET ? "GET" :
|
||||
hd->req_type == HTTP_REQ_HEAD? "HEAD":
|
||||
hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
|
||||
*p == '/'? "":"/", p );
|
||||
}
|
||||
gcry_free(p);
|
||||
|
||||
rc = write_server( hd->sock, request, strlen(request) );
|
||||
|
42
util/iobuf.c
42
util/iobuf.c
@ -1,5 +1,5 @@
|
||||
/* iobuf.c - file handling
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -81,6 +81,8 @@ static int underflow(IOBUF a);
|
||||
* IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
|
||||
* *RET_LAN is the number of bytes in BUF.
|
||||
*
|
||||
* IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
|
||||
* filter may take appropriate action on this message.
|
||||
*/
|
||||
static int
|
||||
file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
|
||||
@ -494,19 +496,47 @@ iobuf_close( IOBUF a )
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iobuf_cancel( IOBUF a )
|
||||
{
|
||||
const char *s;
|
||||
IOBUF a2;
|
||||
int rc;
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
char *remove_name = NULL;
|
||||
#endif
|
||||
|
||||
if( a && a->use == 2 ) {
|
||||
s = iobuf_get_real_fname(a);
|
||||
if( s && *s )
|
||||
remove(s); /* remove the file. Fixme: this will fail for MSDOZE*/
|
||||
} /* because the file is still open */
|
||||
return iobuf_close(a);
|
||||
}
|
||||
if( s && *s ) {
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
remove_name = m_strdup ( s );
|
||||
#else
|
||||
remove(s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* send a cancel message to all filters */
|
||||
for( a2 = a; a2 ; a2 = a2->chain ) {
|
||||
size_t dummy;
|
||||
if( a2->filter )
|
||||
a2->filter( a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain,
|
||||
NULL, &dummy );
|
||||
}
|
||||
|
||||
rc = iobuf_close(a);
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if ( remove_name ) {
|
||||
/* Argg, MSDOS does not allow to remove open files. So
|
||||
* we have to do it here */
|
||||
remove ( remove_name );
|
||||
m_free ( remove_name );
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* create a temporary iobuf, which can be used to collect stuff
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* logger.c - log functions
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -102,6 +102,12 @@ log_get_errorcount( int clear)
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
log_inc_errorcount()
|
||||
{
|
||||
errorcount++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gpg_log_print_prefix(const char *text)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user