1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

Implemented -cs and some fixes to the rfc1991 symmetric only mode

This commit is contained in:
Werner Koch 2001-08-20 19:10:34 +00:00
parent 23589ae0a2
commit 98a8843e28
17 changed files with 522 additions and 64 deletions

View File

@ -1,5 +1,15 @@
2001-08-20 Werner Koch <wk@gnupg.org> 2001-08-20 Werner Koch <wk@gnupg.org>
* acinclude.m4: Add check for plock if mlock is broken.
* configure.ac: Use regular tests for -lsocket and -lnsl,
more thorough test for gethrtime, allow specifying the path to
the zlib library if it is not in the default compiler/linker
search path, use ${datadir}. All these test enhancements are by
Albert Chin.
* configure.ac: Set some compiler flags for dec-osf and hpux. By
Tim Mooney.
* configure.ac: Create g10defs.h with EXTSEP_S et al. * configure.ac: Create g10defs.h with EXTSEP_S et al.
2001-08-03 Werner Koch <wk@gnupg.org> 2001-08-03 Werner Koch <wk@gnupg.org>

1
NEWS
View File

@ -24,6 +24,7 @@
* Merged Stefan's patches for RISCOS in. See comments in * Merged Stefan's patches for RISCOS in. See comments in
scripts/build-riscos. scripts/build-riscos.
* It is now possible to sign an convenional encrypt a message (-cs).
Noteworthy changes in version 1.0.6 (2001-05-29) Noteworthy changes in version 1.0.6 (2001-05-29)
------------------------------------------------ ------------------------------------------------

4
TODO
View File

@ -7,8 +7,6 @@
* Put a note into readme.w32 that there is a man page and a options * Put a note into readme.w32 that there is a man page and a options
file; write the registry stuff in regedit format. file; write the registry stuff in regedit format.
* Allow "gpg -cs"
* Show more info does not work from edit->trust * Show more info does not work from edit->trust
* keyedit_menu: We first look for a secret key and then for a public * keyedit_menu: We first look for a secret key and then for a public
@ -77,6 +75,8 @@
* Using --list-only to check for recipients while decrypting may * Using --list-only to check for recipients while decrypting may
yield an error about an unknown packet. yield an error about an unknown packet.
* Check that the way we select cipher and digest algorithms w/o
preferences is okay and make AES the default.
Scheduled for 1.1 Scheduled for 1.1
----------------- -----------------

View File

@ -436,6 +436,7 @@ define(GNUPG_CHECK_MLOCK,
AC_DEFINE(HAVE_BROKEN_MLOCK,1, AC_DEFINE(HAVE_BROKEN_MLOCK,1,
[Defined if the mlock() call does not work]) [Defined if the mlock() call does not work])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_CHECK_FUNCS(plock)
else else
if test "$gnupg_cv_have_broken_mlock" = "no"; then if test "$gnupg_cv_have_broken_mlock" = "no"; then
AC_MSG_RESULT(no) AC_MSG_RESULT(no)

View File

@ -239,6 +239,15 @@ case "${target}" in
CFLAGS="$CFLAGS -w" CFLAGS="$CFLAGS -w"
fi fi
;; ;;
*-dec-osf5*)
if test -z "$GCC" ; then
# Use the newer compiler `-msg_disable ptrmismatch' to
# get rid of the unsigned/signed char mismatch warnings.
# Using this may hide other pointer mismatch warnings, but
# it at least lets other warning classes through
CFLAGS="$CFLAGS -msg_disable ptrmismatch"
fi
;;
m68k-atari-mint) m68k-atari-mint)
;; ;;
*) *)
@ -279,7 +288,13 @@ esac
AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME", AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
[A human readable text with the name of the OS]) [A human readable text with the name of the OS])
dnl Fixme: Are these the best flags for OpenBSD????
#
# 1. Set flags to be used for the extension modules
# 2. Set names of random devices
#
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
case "${target}" in case "${target}" in
*-openbsd* | *-netbsd*) *-openbsd* | *-netbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom" NAME_OF_DEV_RANDOM="/dev/srandom"
@ -287,15 +302,39 @@ case "${target}" in
DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x" DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
;; ;;
hpux*)
# if using the vendor (ANSI) compiler, arrange to have `-b' passed
# to the linker. If using gcc, it supports `-shared' to do the same.
if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
else
DYNLINK_MOD_CFLAGS='-Wl,-b'
fi
;;
*-irix6.5*)
# Irix 6.5 (and probably a lot earlier, but I only still have
# access to 6.5.x) doesn't require any additional flags, as `-KPIC'
# is the default. Also, `-shared' works with the vendor compiler
DYNLINK_MOD_CFLAGS="-shared"
;;
alpha*-dec-osf*)
# osf (i.e. OSF/1, Digital UNIX, or Tru64 UNIX, pick any one...)
# on alpha doesn't require any PIC flags, everything is PIC.
# This may not be the case for osf ports to other machines, so
# hence the more specific match for target.
#
# Also, `-shared' works with the vendor compiler or gcc.
# -expect_unresolved turns off warnings about unresolved symbols.
DYNLINK_MOD_CFLAGS='-shared -Wl,-expect_unresolved,\*'
;;
*-solaris* | *-irix* | *-dec-osf* ) *-solaris* | *-irix* | *-dec-osf* )
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC" DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
;; ;;
*) *)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
# -shared is a gcc-ism. Find pic flags from GNUPG_CHECK_PIC. # -shared is a gcc-ism. Find pic flags from GNUPG_CHECK_PIC.
if test -n "$GCC" ; then if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC" DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
@ -335,28 +374,33 @@ if test "$ac_cv_header_gdbm_h" = yes ; then
fi fi
fi fi
dnl This old test is here just for reference tin case it fails:
dnl
dnl Solaris needs -lsocket and -lnsl. Unisys system includes dnl Solaris needs -lsocket and -lnsl. Unisys system includes
dnl gethostbyname in libsocket but needs libnsl for socket. dnl gethostbyname in libsocket but needs libnsl for socket.
dnl The test does not workfor all system, so some are hardcoded here. dnl The test does not workfor all system, so some are hardcoded here.
case "${target}" in dnl case "${target}" in
i386-univel-sysv4*) dnl i386-univel-sysv4*)
LIBS="$LIBS -lsocket -lnsl" dnl LIBS="$LIBS -lsocket -lnsl"
;; dnl ;;
*) dnl *)
AC_CHECK_LIB(nsl, gethostbyname) dnl AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, socket, ac_need_libsocket=1, ac_try_nsl=1) dnl AC_CHECK_LIB(socket, socket, ac_need_libsocket=1, ac_try_nsl=1)
if test x$ac_need_libsocket = x1; then dnl if test x$ac_need_libsocket = x1; then
LIBS="$LIBS -lsocket" dnl LIBS="$LIBS -lsocket"
fi dnl fi
if test x$ac_try_nsl = x1; then dnl if test x$ac_try_nsl = x1; then
AC_CHECK_LIB(nsl, gethostbyname, ac_need_libnsl=1) dnl AC_CHECK_LIB(nsl, gethostbyname, ac_need_libnsl=1)
if test x$ac_need_libnsl = x1 dnl if test x$ac_need_libnsl = x1
then dnl then
LIBS="$LIBS -lnsl" dnl LIBS="$LIBS -lnsl"
fi dnl fi
fi dnl fi
;; dnl ;;
esac dnl esac
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
if test "$try_dynload" = yes ; then if test "$try_dynload" = yes ; then
@ -446,10 +490,17 @@ fi
dnl Checks for library functions. dnl Checks for library functions.
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror stpcpy strlwr stricmp tcgetattr rand strtoul mmap) AC_CHECK_FUNCS(strerror stpcpy strlwr stricmp tcgetattr rand strtoul mmap)
AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit clock_gettime) AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
AC_CHECK_FUNCS(memicmp atexit raise getpagesize strftime nl_langinfo) AC_CHECK_FUNCS(memicmp atexit raise getpagesize strftime nl_langinfo)
AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask fseeko) AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask fseeko)
AC_MSG_CHECKING(for gethrtime)
AC_TRY_LINK([#include <sys/times.h>],[
hrtime_t tv;
tv = gethrtime();
],[AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETHRTIME)], AC_MSG_RESULT(no))
GNUPG_CHECK_MLOCK GNUPG_CHECK_MLOCK
GNUPG_FUNC_MKDIR_TAKES_ONE_ARG GNUPG_FUNC_MKDIR_TAKES_ONE_ARG
@ -696,10 +747,23 @@ use_local_zlib=yes
if test "$g10_force_zlib" = "yes"; then if test "$g10_force_zlib" = "yes"; then
: :
else else
AC_CHECK_HEADERS(zlib.h) _cppflags="${CPPFLAGS}"
if test "$ac_cv_header_zlib_h" = yes ; then _ldflags="${LDFLAGS}"
AC_CHECK_LIB(z,deflateInit2_,use_local_zlib=no,:)
AC_ARG_WITH(zlib,
[ --with-zlib=DIR use libz in DIR],[
if test -d "$withval"; then
CPPFLAGS="${CPPFLAGS} -I$withval/include"
LDFLAGS="${LDFLAGS} -L$withval/lib"
fi fi
])
AC_CHECK_HEADER(zlib.h,
AC_CHECK_LIB(z, deflateInit2_,
use_local_zlib=no
LIBS="$LIBS -lz",
CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}),
CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags})
fi fi
if test "$use_local_zlib" = yes ; then if test "$use_local_zlib" = yes ; then
@ -709,7 +773,6 @@ if test "$use_local_zlib" = yes ; then
else else
AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false)
ZLIBS= ZLIBS=
LIBS="-lz $LIBS"
fi fi
AC_SUBST(ZLIBS) AC_SUBST(ZLIBS)
@ -757,7 +820,7 @@ cat >g10defs.tmp <<G10EOF
#define GNUPG_DATADIR "c:/lib/gnupg" #define GNUPG_DATADIR "c:/lib/gnupg"
#define GNUPG_HOMEDIR "c:/gnupg" #define GNUPG_HOMEDIR "c:/gnupg"
#else #else
#define G10_LOCALEDIR "${prefix}/${DATADIRNAME}/locale" #define G10_LOCALEDIR "${datadir}/locale"
#define GNUPG_LIBDIR "${libdir}/gnupg" #define GNUPG_LIBDIR "${libdir}/gnupg"
#define GNUPG_DATADIR "${datadir}/gnupg" #define GNUPG_DATADIR "${datadir}/gnupg"
#ifdef __VMS #ifdef __VMS
@ -806,14 +869,15 @@ checks/Makefile
AC_OUTPUT AC_OUTPUT
# Give some feedback # Give some feedback
echo "Configured for: $PRINTABLE_OS_NAME ($target)" echo
echo " Configured for: $PRINTABLE_OS_NAME ($target)"
if test -n "$show_dynlink"; then if test -n "$show_dynlink"; then
echo "Dynamically linked modules:$show_dynlink" echo " Dynamically linked modules:$show_dynlink"
fi fi
if test -n "$show_statlink"; then if test -n "$show_statlink"; then
echo "Statically linked modules:$show_statlink" echo " Statically linked modules:$show_statlink"
fi fi
if test -n "$show_extraasm"; then if test -n "$show_extraasm"; then
echo "Extra cpu specific functions:$show_extraasm" echo " Extra cpu specific functions:$show_extraasm"
fi fi

View File

@ -1,5 +1,18 @@
2001-08-20 Werner Koch <wk@gnupg.org> 2001-08-20 Werner Koch <wk@gnupg.org>
* encr-data.c (decrypt_data): Keep track on whether we already
printed information about the used algorithm.
* mainproc.c (proc_encrypted): Removed the non-working IDEA hack
and print a message about the assumed algorithm.
* passphrase.c (passphrase_to_dek): Use the same algorithm as above.
(proc_symkey_enc): Print the algorithm, so that the user knows it
before entering the passphrase.
(proc_pubkey_enc, proc_pubkey_enc): Zero the DEK out.
* encode.c (encode_crypt, encrypt_filter): Ditto.
* g10.c: Allow for --sign --symmetric.
* sign.c (sign_and_symencrypt): New.
Applied patches from Stefan Bellon <sbellon@sbellon.de> to support Applied patches from Stefan Bellon <sbellon@sbellon.de> to support
the RISCOS. Nearly all of these patches are identified by the the RISCOS. Nearly all of these patches are identified by the
__riscos__ macro. __riscos__ macro.

View File

@ -291,7 +291,7 @@ encode_crypt( const char *filename, STRLIST remusr )
} }
#endif #endif
/* create a session key */ /* create a session key */
cfx.dek = m_alloc_secure( sizeof *cfx.dek ); cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM ); cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
if( cfx.dek->algo == -1 ) if( cfx.dek->algo == -1 )
@ -415,14 +415,17 @@ encrypt_filter( void *opaque, int control,
} }
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
if( !efx->header_okay ) { if( !efx->header_okay ) {
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek ); efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
efx->cfx.dek->algo = efx->cfx.dek->algo =
select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM ); select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM );
if( efx->cfx.dek->algo == -1 ) if( efx->cfx.dek->algo == -1 ) {
/* because 3DES is implicitly in the prefs, this can only
* happen if we do not have any public keys in the list */
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
} }
}
else else
efx->cfx.dek->algo = opt.def_cipher_algo; efx->cfx.dek->algo = opt.def_cipher_algo;
make_session_key( efx->cfx.dek ); make_session_key( efx->cfx.dek );

View File

@ -60,12 +60,13 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
unsigned nprefix; unsigned nprefix;
memset( &dfx, 0, sizeof dfx ); memset( &dfx, 0, sizeof dfx );
if( opt.verbose ) { if( opt.verbose && !dek->algo_info_printed ) {
const char *s = cipher_algo_to_string( dek->algo ); const char *s = cipher_algo_to_string( dek->algo );
if( s ) if( s )
log_info(_("%s encrypted data\n"), s ); log_info(_("%s encrypted data\n"), s );
else else
log_info(_("encrypted with unknown algorithm %d\n"), dek->algo ); log_info(_("encrypted with unknown algorithm %d\n"), dek->algo );
dek->algo_info_printed = 1;
} }
if( (rc=check_cipher_algo(dek->algo)) ) if( (rc=check_cipher_algo(dek->algo)) )
goto leave; goto leave;

View File

@ -73,6 +73,7 @@ enum cmd_and_opt_values { aNull = 0,
aStore, aStore,
aKeygen, aKeygen,
aSignEncr, aSignEncr,
aSignSym,
aSignKey, aSignKey,
aLSignKey, aLSignKey,
aListPackets, aListPackets,
@ -607,6 +608,10 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
cmd = aSignEncr; cmd = aSignEncr;
else if( cmd == aEncr && new_cmd == aSign ) else if( cmd == aEncr && new_cmd == aSign )
cmd = aSignEncr; cmd = aSignEncr;
else if( cmd == aSign && new_cmd == aSym )
cmd = aSignSym;
else if( cmd == aSym && new_cmd == aSign )
cmd = aSignSym;
else if( cmd == aKMode && new_cmd == aSym ) else if( cmd == aKMode && new_cmd == aSym )
cmd = aKModeC; cmd = aKModeC;
else if( ( cmd == aSign && new_cmd == aClearsign ) else if( ( cmd == aSign && new_cmd == aClearsign )
@ -1316,11 +1321,21 @@ main( int argc, char **argv )
free_strlist(sl); free_strlist(sl);
break; break;
case aSignSym: /* sign and conventionally encrypt the given file */
if (argc > 1)
wrong_args(_("--sign --symmetric [filename]"));
rc = sign_symencrypt_file (fname, locusr);
if (rc)
log_error("%s: sign+symmetric failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
break;
case aClearsign: /* make a clearsig */ case aClearsign: /* make a clearsig */
if( argc > 1 ) if( argc > 1 )
wrong_args(_("--clearsign [filename]")); wrong_args(_("--clearsign [filename]"));
if( (rc = clearsign_file(fname, locusr, NULL)) ) if( (rc = clearsign_file(fname, locusr, NULL)) )
log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); log_error("%s: clearsign failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
break; break;
case aVerify: case aVerify:

View File

@ -82,6 +82,7 @@ int complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md );
int sign_file( STRLIST filenames, int detached, STRLIST locusr, int sign_file( STRLIST filenames, int detached, STRLIST locusr,
int do_encrypt, STRLIST remusr, const char *outfile ); int do_encrypt, STRLIST remusr, const char *outfile );
int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); int clearsign_file( const char *fname, STRLIST locusr, const char *outfile );
int sign_symencrypt_file (const char *fname, STRLIST locusr);
/*-- sig-check.c --*/ /*-- sig-check.c --*/
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );

View File

@ -247,8 +247,19 @@ proc_symkey_enc( CTX c, PACKET *pkt )
if (enc->seskeylen) if (enc->seskeylen)
log_error ("symkey_enc packet with session keys are not supported!\n"); log_error ("symkey_enc packet with session keys are not supported!\n");
else { else {
int algo = enc->cipher_algo;
const char *s;
s = cipher_algo_to_string (algo);
if( s )
log_info(_("%s encrypted data\n"), s );
else
log_info(_("encrypted with unknown algorithm %d\n"), algo );
c->last_was_session_key = 2; c->last_was_session_key = 2;
c->dek = passphrase_to_dek( NULL, 0, enc->cipher_algo, &enc->s2k, 0 ); c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0 );
if (c->dek)
c->dek->algo_info_printed = 1;
} }
free_packet(pkt); free_packet(pkt);
} }
@ -276,10 +287,10 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
} }
if( !opt.list_only && opt.override_session_key ) { if( !opt.list_only && opt.override_session_key ) {
/* It does not make nuch sense to store the session key in /* It does not make much sense to store the session key in
* secure memory because it has already been passed on the * secure memory because it has already been passed on the
* command line and the GCHQ knows about it */ * command line and the GCHQ knows about it */
c->dek = m_alloc( sizeof *c->dek ); c->dek = m_alloc_clear( sizeof *c->dek );
result = get_override_session_key ( c->dek, opt.override_session_key ); result = get_override_session_key ( c->dek, opt.override_session_key );
if ( result ) { if ( result ) {
m_free(c->dek); c->dek = NULL; m_free(c->dek); c->dek = NULL;
@ -293,7 +304,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
if( opt.list_only ) if( opt.list_only )
result = -1; result = -1;
else { else {
c->dek = m_alloc_secure( sizeof *c->dek ); c->dek = m_alloc_secure_clear( sizeof *c->dek );
if( (result = get_session_key( enc, c->dek )) ) { if( (result = get_session_key( enc, c->dek )) ) {
/* error: delete the DEK */ /* error: delete the DEK */
m_free(c->dek); c->dek = NULL; m_free(c->dek); c->dek = NULL;
@ -409,14 +420,14 @@ proc_encrypted( CTX c, PACKET *pkt )
if( opt.list_only ) if( opt.list_only )
result = -1; result = -1;
else if( !c->dek && !c->last_was_session_key ) { else if( !c->dek && !c->last_was_session_key ) {
int def_algo; int algo = opt.def_cipher_algo ? opt.def_cipher_algo
/* assume this is old conventional encrypted data : opt.s2k_cipher_algo;
* We use IDEA here if it is installed */ /* assume this is old style conventional encrypted data */
def_algo = check_cipher_algo (CIPHER_ALGO_IDEA)? log_info(_("assuming %s encrypted data\n"),
DEFAULT_CIPHER_ALGO : CIPHER_ALGO_IDEA; cipher_algo_to_string (algo) );
c->dek = passphrase_to_dek( NULL, 0, c->dek = passphrase_to_dek( NULL, 0, algo, NULL, 0);
opt.def_cipher_algo ? opt.def_cipher_algo if (c->dek)
: DEFAULT_CIPHER_ALGO, NULL, 0 ); c->dek->algo_info_printed = 1;
} }
else if( !c->dek ) else if( !c->dek )
result = G10ERR_NO_SECKEY; result = G10ERR_NO_SECKEY;

View File

@ -513,16 +513,14 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
STRING2KEY help_s2k; STRING2KEY help_s2k;
if( !s2k ) { if( !s2k ) {
int def_algo; /* This is used for the old rfc1991 mode
* Note: This must match the code in encode.c with opt.rfc1991 set */
int algo = opt.def_digest_algo ? opt.def_digest_algo
: opt.s2k_digest_algo;
s2k = &help_s2k; s2k = &help_s2k;
s2k->mode = 0; s2k->mode = 0;
/* If we have IDEA installed we use MD5 otherwise the default s2k->hash_algo = algo;
* hash algorithm. This can always be overriden from the
* commandline */
def_algo = check_cipher_algo (CIPHER_ALGO_IDEA)?
DEFAULT_DIGEST_ALGO : DIGEST_ALGO_MD5;
s2k->hash_algo = opt.def_digest_algo? opt.def_digest_algo : def_algo;
} }
if( !next_pw && is_status_enabled() ) { if( !next_pw && is_status_enabled() ) {
@ -632,7 +630,7 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
if( !pw || !*pw ) if( !pw || !*pw )
write_status( STATUS_MISSING_PASSPHRASE ); write_status( STATUS_MISSING_PASSPHRASE );
dek = m_alloc_secure( sizeof *dek ); dek = m_alloc_secure_clear ( sizeof *dek );
dek->algo = cipher_algo; dek->algo = cipher_algo;
if( !*pw && mode == 2 ) if( !*pw && mode == 2 )
dek->keylen = 0; dek->keylen = 0;

View File

@ -797,6 +797,328 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
return rc; return rc;
} }
/*
* Sign and conventionally encrypt the given file.
* FIXME: Far too much code is duplicated - revamp the whole file.
*/
int
sign_symencrypt_file (const char *fname, STRLIST locusr)
{
armor_filter_context_t afx;
compress_filter_context_t zfx;
md_filter_context_t mfx;
text_filter_context_t tfx;
cipher_filter_context_t cfx;
IOBUF inp = NULL, out = NULL;
PACKET pkt;
PKT_plaintext *pt = NULL;
STRING2KEY *s2k = NULL;
u32 filesize;
int rc = 0;
SK_LIST sk_list = NULL;
SK_LIST sk_rover = NULL;
int old_style = opt.rfc1991;
int compr_algo = -1; /* unknown */
int algo;
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
memset( &mfx, 0, sizeof mfx);
memset( &tfx, 0, sizeof tfx);
memset( &cfx, 0, sizeof cfx);
init_packet( &pkt );
rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG);
if (rc)
goto leave;
if( !old_style )
old_style = only_old_style( sk_list );
/* prepare iobufs */
inp = iobuf_open(fname);
if( !inp ) {
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
strerror(errno) );
rc = G10ERR_OPEN_FILE;
goto leave;
}
/* prepare key */
s2k = m_alloc_clear( sizeof *s2k );
s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
: opt.s2k_digest_algo;
algo = opt.def_cipher_algo ? opt.def_cipher_algo : opt.s2k_cipher_algo;
if (!opt.quiet || !opt.batch)
log_info (_("%s encryption will be used\n"),
cipher_algo_to_string(algo) );
cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2 );
if (!cfx.dek || !cfx.dek->keylen) {
rc = G10ERR_PASSPHRASE;
log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
goto leave;
}
/* now create the outfile */
rc = open_outfile (fname, opt.armor? 1:0, &out);
if (rc)
goto leave;
/* prepare to calculate the MD over the input */
if (opt.textmode)
iobuf_push_filter (inp, text_filter, &tfx);
mfx.md = md_open(0, 0);
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
PKT_secret_key *sk = sk_rover->sk;
md_enable (mfx.md, hash_for (sk->pubkey_algo, sk->version ));
}
iobuf_push_filter (inp, md_filter, &mfx);
/* Push armor output filter */
if (opt.armor)
iobuf_push_filter (out, armor_filter, &afx);
/* Write the symmetric key packet */
/*(current filters: armor)*/
if (!opt.rfc1991) {
PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc );
enc->version = 4;
enc->cipher_algo = cfx.dek->algo;
enc->s2k = *s2k;
pkt.pkttype = PKT_SYMKEY_ENC;
pkt.pkt.symkey_enc = enc;
if( (rc = build_packet( out, &pkt )) )
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
m_free(enc);
}
/* Push the encryption filter */
iobuf_push_filter( out, cipher_filter, &cfx );
/* Push the Zip filter */
if (opt.compress) {
if (!compr_algo)
; /* don't use compression */
else {
if( old_style || compr_algo == 1 )
zfx.algo = 1; /* use the non optional algorithm */
iobuf_push_filter( out, compress_filter, &zfx );
}
}
/* Write the one-pass signature packets */
/*(current filters: zip - encrypt - armor)*/
if (!old_style) {
int skcount=0;
/* loop over the secret certificates and build headers
* The specs now say that the data should be bracket by
* the onepass-sig and signature-packet; so we must build it
* here in reverse order */
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
skcount++;
for( ; skcount; skcount-- ) {
PKT_secret_key *sk;
PKT_onepass_sig *ops;
int i = 0;
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
if( ++i == skcount )
break;
sk = sk_rover->sk;
ops = m_alloc_clear( sizeof *ops );
ops->sig_class = opt.textmode? 0x01 : 0x00;
ops->digest_algo = hash_for(sk->pubkey_algo, sk->version);
ops->pubkey_algo = sk->pubkey_algo;
keyid_from_sk( sk, ops->keyid );
ops->last = skcount == 1;
init_packet(&pkt);
pkt.pkttype = PKT_ONEPASS_SIG;
pkt.pkt.onepass_sig = ops;
rc = build_packet( out, &pkt );
free_packet( &pkt );
if( rc ) {
log_error("build onepass_sig packet failed: %s\n",
g10_errstr(rc));
goto leave;
}
}
}
/* Pipe data through all filters; i.e. write the signed stuff */
/*(current filters: zip - encrypt - armor)*/
if (!opt.no_literal) {
if (fname || opt.set_filename) {
char *s = make_basename (opt.set_filename? opt.set_filename
: fname );
pt = m_alloc (sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen (s);
memcpy (pt->name, s, pt->namelen );
m_free (s);
}
else { /* no filename */
pt = m_alloc( sizeof *pt - 1 );
pt->namelen = 0;
}
}
/* try to calculate the length of the data */
if (fname) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("WARNING: `%s' is an empty file\n"), fname );
/* we can't yet encode the length of very large files,
* so we switch to partial length encoding in this case */
if (filesize >= IOBUF_FILELENGTH_LIMIT)
filesize = 0;
/* because the text_filter modifies the length of the
* data, it is not possible to know the used length
* without a double read of the file - to avoid that
* we simple use partial length packets.
*/
if (opt.textmode)
filesize = 0;
}
else {
filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */
}
if (!opt.no_literal) {
pt->timestamp = make_timestamp();
pt->mode = opt.textmode? 't':'b';
pt->len = filesize;
pt->new_ctb = !pt->len && !opt.rfc1991;
pt->buf = inp; /* take data from this iobuf */
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
/* build packet automagically write all the data */
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet(PLAINTEXT) failed: %s\n", g10_errstr(rc) );
pt->buf = NULL;
}
else {
byte copy_buffer[4096];
int bytes_copied;
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
rc = G10ERR_WRITE_FILE;
log_error("copying input to output failed: %s\n", g10_errstr(rc));
break;
}
memset(copy_buffer, 0, 4096); /* burn buffer */
}
/* catch errors from above */
if (rc)
goto leave;
/* Write the signature by looping over the secret certificates */
/*(current filters: zip - encrypt - armor)*/
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk;
PKT_signature *sig;
MD_HANDLE md;
sk = sk_rover->sk;
/* build the signature packet */
/* fixme: this code is partly duplicated in make_keysig_packet */
sig = m_alloc_clear( sizeof *sig );
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo, sk->version);
sig->pubkey_algo = sk->pubkey_algo;
sig->timestamp = make_timestamp();
sig->sig_class = opt.textmode? 0x01 : 0x00;
md = md_copy( mfx.md );
if( sig->version >= 4 ) {
build_sig_subpkt_from_sig( sig );
md_putc( md, sig->version );
}
mk_notation_and_policy( sig );
md_putc( md, sig->sig_class );
if( sig->version < 4 ) {
u32 a = sig->timestamp;
md_putc( md, (a >> 24) & 0xff );
md_putc( md, (a >> 16) & 0xff );
md_putc( md, (a >> 8) & 0xff );
md_putc( md, a & 0xff );
}
else {
byte buf[6];
size_t n;
md_putc( md, sig->pubkey_algo );
md_putc( md, sig->digest_algo );
if( sig->hashed ) {
n = sig->hashed->len;
md_putc (md, (n >> 8) );
md_putc (md, n );
md_write (md, sig->hashed->data, n );
n += 6;
}
else {
md_putc( md, 0 ); /* always hash the length of the subpacket*/
md_putc( md, 0 );
n = 6;
}
/* add some magic */
buf[0] = sig->version;
buf[1] = 0xff;
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
buf[3] = n >> 16;
buf[4] = n >> 8;
buf[5] = n;
md_write( md, buf, 6 );
}
md_final( md );
rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo, sk->version) );
md_close( md );
if( !rc ) { /* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
if( !rc && is_status_enabled() ) {
print_status_sig_created ( sk, sig, 'S');
}
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", g10_errstr(rc) );
}
if( rc )
goto leave;
}
leave:
if( rc )
iobuf_cancel(out);
else {
iobuf_close(out);
write_status( STATUS_END_ENCRYPTION );
}
iobuf_close(inp);
release_sk_list( sk_list );
md_close( mfx.md );
m_free(cfx.dek);
m_free(s2k);
return rc;
}
/**************** /****************
* Create a signature packet for the given public key certificate and * Create a signature packet for the given public key certificate and

View File

@ -1,5 +1,7 @@
2001-08-20 Werner Koch <wk@gnupg.org> 2001-08-20 Werner Koch <wk@gnupg.org>
* cipher.h (DEK): Added algo_info_printed;
* util.h [__riscos__]: Added prototypes and made sure that we * util.h [__riscos__]: Added prototypes and made sure that we
never use __attribute__. never use __attribute__.
* cipher.h, iobuf.h, memory.h, mpi.h [__riscos__]: extern hack. * cipher.h, iobuf.h, memory.h, mpi.h [__riscos__]: extern hack.

View File

@ -63,6 +63,7 @@
typedef struct { typedef struct {
int algo; int algo;
int keylen; int keylen;
int algo_info_printed;
byte key[32]; /* this is the largest used keylen (256 bit) */ byte key[32]; /* this is the largest used keylen (256 bit) */
} DEK; } DEK;

View File

@ -13,6 +13,10 @@
* memory.c [__riscos__]: Minor patches * memory.c [__riscos__]: Minor patches
* riscos.c (set_filetype): New. * riscos.c (set_filetype): New.
* secmem.c (lock_pool): Under HPUX mlock is broken but we might
have plock, so we use this to lock the entire process. By Albert
Chin.
2001-07-03 Werner Koch <wk@gnupg.org> 2001-07-03 Werner Koch <wk@gnupg.org>
* strgutil.c (utf8_to_native): Fixed printing of invalid utf-8 * strgutil.c (utf8_to_native): Fixed printing of invalid utf-8

View File

@ -32,6 +32,9 @@
#ifdef USE_CAPABILITIES #ifdef USE_CAPABILITIES
#include <sys/capability.h> #include <sys/capability.h>
#endif #endif
#ifdef HAVE_PLOCK
#include <sys/lock.h>
#endif
#endif #endif
#include "types.h" #include "types.h"
@ -120,6 +123,13 @@ lock_pool( void *p, size_t n )
uid = getuid(); uid = getuid();
#ifdef HAVE_BROKEN_MLOCK #ifdef HAVE_BROKEN_MLOCK
/* ick. but at least we get secured memory. about to lock
entire data segment. */
#ifdef HAVE_PLOCK
err = plock( DATLOCK );
if( err && errno )
err = errno;
#else /*!HAVE_PLOCK*/
if( uid ) { if( uid ) {
errno = EPERM; errno = EPERM;
err = errno; err = errno;
@ -129,6 +139,7 @@ lock_pool( void *p, size_t n )
if( err && errno ) if( err && errno )
err = errno; err = errno;
} }
#endif /*!HAVE_PLOCK*/
#else #else
err = mlock( p, n ); err = mlock( p, n );
if( err && errno ) if( err && errno )