version 0.2.1

This commit is contained in:
Werner Koch 1998-01-28 16:09:43 +00:00
parent 3d637328c9
commit 9bf8ce27bc
35 changed files with 714 additions and 274 deletions

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
SUBDIRS = util mpi cipher tools po intl g10 SUBDIRS = @INTLSUB@ @POSUB@ util mpi cipher tools g10
EXTRA_DIST = VERSION EXTRA_DIST = VERSION

View File

@ -38,15 +38,16 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@ transform = @program_transform_name@
SUBDIRS = util mpi cipher tools po intl g10 SUBDIRS = @INTLSUB@ @POSUB@ util mpi cipher tools g10
EXTRA_DIST = VERSION EXTRA_DIST = VERSION
ACLOCAL = aclocal.m4
ACCONFIG = acconfig.h ACCONFIG = acconfig.h
CONFIG_HEADER_IN = config.h.in CONFIG_HEADER_IN = config.h.in
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ./config.h CONFIG_HEADER = ./config.h
DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \ DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS README TODO acconfig.h config.h.in \ Makefile.am Makefile.in NEWS README TODO acconfig.h aclocal.m4 \
configure configure.in stamp-h.in config.h.in configure configure.in stamp-h.in
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@

14
NEWS
View File

@ -1,4 +1,12 @@
* We have secure memeory on systems which support mlock().
It is not complete yet, because we do not have signal handler
which does a cleanup in very case.
We should also check the ulimit for the user in the case
that the admin does not have set a limit on locked pages.
* started with internationalization support.
* The logic to handle the web of trust is now implemented. It is * The logic to handle the web of trust is now implemented. It is
has some bugs; but I'm going to change the algorithm anyway. has some bugs; but I'm going to change the algorithm anyway.
It works by calculating the trustlevel on the fly. It may ask It works by calculating the trustlevel on the fly. It may ask
@ -14,12 +22,10 @@
* Read support for new version packets (OpenPGP). * Read support for new version packets (OpenPGP).
* Comment packets are now of coorect OpenPGP type 16. Old comment * Comment packets are now of correct OpenPGP type 16. Old comment
packets writen by G10 are detected because they always start with packets written by G10 are detected because they always start with
a hash which is an invalid version byte. a hash which is an invalid version byte.
* The string "(INSECURE!)" is appended to a new user-id if this * The string "(INSECURE!)" is appended to a new user-id if this
is generated on a system without a good random number generator. is generated on a system without a good random number generator.
* works (more or less) on a UltraPenguin (sparc64--gnu-linux)

3
README
View File

@ -10,6 +10,9 @@
* Some features are not yet implemented * Some features are not yet implemented
PLEASE USE "--no-armor" BECAUSE THERE IS STILL A BUG IN IT!
(put it into the option file)
Please subscribe to g10@net.lut.ac.uk by sending a mail with Please subscribe to g10@net.lut.ac.uk by sending a mail with
the word "subscribe" in the body to "g10-request@net.lut.ac.uk". the word "subscribe" in the body to "g10-request@net.lut.ac.uk".

2
TODO
View File

@ -5,9 +5,7 @@
* add a way to difference between errors and eof in the underflow/flush * add a way to difference between errors and eof in the underflow/flush
function of iobuf. function of iobuf.
* check that all output is filtered when displayed. * check that all output is filtered when displayed.
* add trust stuff
* add checking of armor trailers * add checking of armor trailers
* add real secure memory
* look for a way to reuse RSA signatures * look for a way to reuse RSA signatures
* remove all "Fixmes" * remove all "Fixmes"
* speed up the RIPE-MD-160 * speed up the RIPE-MD-160

View File

@ -1 +1 @@
0.2.0 0.2.1

View File

@ -31,6 +31,7 @@
#include "util.h" #include "util.h"
#include "cipher.h" #include "cipher.h"
#include "ttyio.h" #include "ttyio.h"
#include "i18n.h"
struct cache { struct cache {
int len; int len;
@ -51,7 +52,11 @@ quick_random_gen( int onoff )
int last = quick_test; int last = quick_test;
if( onoff != -1 ) if( onoff != -1 )
quick_test = onoff; quick_test = onoff;
#ifdef HAVE_DEV_RANDOM
return last; return last;
#else
return 1; /* insecure RNG */
#endif
} }
@ -137,9 +142,9 @@ fill_buffer( byte *buffer, size_t length, int level )
tv.tv_usec = 0; tv.tv_usec = 0;
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) { if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
if( !warn ) if( !warn )
tty_printf( tty_printf( _(
"\nNot enough random bytes available. Please do some other work to give "\nNot enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need %d more bytes)\n", length ); the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
warn = 1; warn = 1;
continue; continue;
} }
@ -177,10 +182,10 @@ fill_buffer( byte *buffer, size_t length, int level )
static int initialized=0; static int initialized=0;
if( !initialized ) { if( !initialized ) {
log_info("warning: using insecure random number generator!!\n"); log_info(_("warning: using insecure random number generator!!\n"));
tty_printf("The random number generator is only a kludge to let\n" tty_printf(_("The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n\n" "it compile - it is in no way a strong RNG!\n\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"); "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
initialized=1; initialized=1;
#ifdef HAVE_RAND #ifdef HAVE_RAND
srand(make_timestamp()*getpid()); srand(make_timestamp()*getpid());

View File

@ -124,6 +124,12 @@
/* Define if you have the getpagesize function. */ /* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE #undef HAVE_GETPAGESIZE
/* Define if you have the mlock function. */
#undef HAVE_MLOCK
/* Define if you have the mmap function. */
#undef HAVE_MMAP
/* Define if you have the munmap function. */ /* Define if you have the munmap function. */
#undef HAVE_MUNMAP #undef HAVE_MUNMAP

View File

@ -104,7 +104,7 @@ fi
dnl Checks for library functions. dnl Checks for library functions.
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul) AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul mlock mmap)

View File

@ -46,8 +46,8 @@ g10_SOURCES = g10.c \
sig-check.c sig-check.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \ LDADD = -L ../cipher -L ../mpi -L ../util \
-lcipher -lmpi -lutil -lintl -lcipher -lmpi -lutil
$(PROGRAMS): ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a $(PROGRAMS): ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a

View File

@ -83,8 +83,8 @@ g10_SOURCES = g10.c \
comment.c \ comment.c \
sig-check.c sig-check.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \ LDADD = -L ../cipher -L ../mpi -L ../util \
-lcipher -lmpi -lutil -lintl -lcipher -lmpi -lutil
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h CONFIG_HEADER = ../config.h
PROGRAMS = $(bin_PROGRAMS) PROGRAMS = $(bin_PROGRAMS)

View File

@ -66,18 +66,20 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void void
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ) g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{ {
ELG_secret_key skey; ELG_secret_key skey;
MPI frame; MPI frame;
byte *dp; byte *dp;
assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ); assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL );
if( !digest_algo )
digest_algo = md_get_algo(md);
md_final( md ); dp = md_read( md, digest_algo );
dp = md_read( md, 0 );
keyid_from_skc( skc, sig->keyid ); keyid_from_skc( skc, sig->keyid );
sig->d.elg.digest_algo = md_get_algo(md); sig->d.elg.digest_algo = digest_algo;
sig->d.elg.digest_start[0] = dp[0]; sig->d.elg.digest_start[0] = dp[0];
sig->d.elg.digest_start[1] = dp[1]; sig->d.elg.digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) ); sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );

View File

@ -35,9 +35,8 @@ typedef struct {
u32 crc; u32 crc;
byte helpbuf[100]; byte helpbuf[100];
int helpidx, helplen; int helpidx, helplen;
byte tempbuf[100]; int faked;
int tempidx, templen; int parse_state;
void *fake;
int inp_checked; /* set if inp has been checked */ int inp_checked; /* set if inp has been checked */
int inp_bypass; /* set if the input is not armored */ int inp_bypass; /* set if the input is not armored */
int inp_eof; int inp_eof;

View File

@ -116,7 +116,7 @@ wrong_args( const char *text)
fputs(_("Usage: g10 [options] "),stderr); fputs(_("Usage: g10 [options] "),stderr);
fputs(text,stderr); fputs(text,stderr);
putc('\n',stderr); putc('\n',stderr);
exit(2); g10_exit(2);
} }
static void static void
@ -150,14 +150,14 @@ set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
cmd = aKModeC; cmd = aKModeC;
else { else {
log_error(_("conflicting commands\n")); log_error(_("conflicting commands\n"));
exit(2); g10_exit(2);
} }
*ret_cmd = cmd; *ret_cmd = cmd;
} }
int void
main( int argc, char **argv ) main( int argc, char **argv )
{ {
static ARGPARSE_OPTS opts[] = { static ARGPARSE_OPTS opts[] = {
@ -237,6 +237,8 @@ main( int argc, char **argv )
enum cmd_values cmd = 0; enum cmd_values cmd = 0;
secmem_init( 16384 );
i18n_init(); i18n_init();
opt.compress = -1; /* defaults to standard compress level */ opt.compress = -1; /* defaults to standard compress level */
opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
@ -397,7 +399,7 @@ main( int argc, char **argv )
errors++; errors++;
} }
if( errors ) if( errors )
exit(2); g10_exit(2);
set_debug(); set_debug();
@ -673,7 +675,17 @@ main( int argc, char **argv )
/* cleanup */ /* cleanup */
FREE_STRLIST(remusr); FREE_STRLIST(remusr);
FREE_STRLIST(locusr); FREE_STRLIST(locusr);
return log_get_errorcount(0)? 2:0; g10_exit(0);
}
void
g10_exit( int rc )
{
if( opt.verbose )
secmem_dump_stats();
secmem_term();
exit( rc? rc : log_get_errorcount(0)? 2:0 );
} }

View File

@ -32,6 +32,7 @@
#include "ttyio.h" #include "ttyio.h"
#include "options.h" #include "options.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h"
#if 0 #if 0
#define TEST_ALGO 1 #define TEST_ALGO 1
@ -105,7 +106,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
PKT_public_cert *pkc; PKT_public_cert *pkc;
if( opt.verbose ) if( opt.verbose )
log_info("writing self signature\n"); log_info(_("writing self signature\n"));
/* get the uid packet from the tree */ /* get the uid packet from the tree */
for( kbctx=NULL; (node=walk_kbtree( root, &kbctx)) ; ) { for( kbctx=NULL; (node=walk_kbtree( root, &kbctx)) ; ) {
@ -201,19 +202,16 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
#ifdef ENABLE_RSA_KEYGEN #ifdef ENABLE_RSA_KEYGEN
static int static int
gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek, gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc ) PKT_secret_cert **ret_skc )
{ {
int rc; int rc;
PACKET pkt1, pkt2; PACKET *pkt;
PKT_secret_cert *skc; PKT_secret_cert *skc;
PKT_public_cert *pkc; PKT_public_cert *pkc;
RSA_public_key pk; RSA_public_key pk;
RSA_secret_key sk; RSA_secret_key sk;
init_packet(&pkt1);
init_packet(&pkt2);
rsa_generate( &pk, &sk, nbits ); rsa_generate( &pk, &sk, nbits );
skc = m_alloc_clear( sizeof *skc ); skc = m_alloc_clear( sizeof *skc );
@ -234,11 +232,11 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p ); skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q ); skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u ); skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
if( !dek ) {
skc->d.rsa.is_protected = 0; /* return an unprotected version of the skc */
skc->d.rsa.protect_algo = 0; *ret_skc = copy_secret_cert( NULL, skc );
}
else { if( dek ) {
skc->d.rsa.is_protected = 1; skc->d.rsa.is_protected = 1;
skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH; skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1); randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
@ -246,31 +244,22 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
rc = protect_secret_key( skc, dek ); rc = protect_secret_key( skc, dek );
if( rc ) { if( rc ) {
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) ); log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
goto leave; free_public_cert(pkc);
free_secret_cert(skc);
return rc;
} }
} }
pkt1.pkttype = PKT_PUBLIC_CERT; pkt = m_alloc_clear(sizeof *pkt);
pkt1.pkt.public_cert = pkc; pkt->pkttype = PKT_PUBLIC_CERT;
pkt2.pkttype = PKT_SECRET_CERT; pkt->pkt.public_cert = pkc;
pkt2.pkt.secret_cert = skc; add_kbnode(pub_root, new_kbnode( pkt ));
if( (rc = build_packet( pub_io, &pkt1 )) ) { pkt = m_alloc_clear(sizeof *pkt);
log_error("build public_cert packet failed: %s\n", g10_errstr(rc) ); pkt->pkttype = PKT_SECRET_CERT;
goto leave; pkt->pkt.secret_cert = skc;
} add_kbnode(sec_root, new_kbnode( pkt ));
if( (rc = build_packet( sec_io, &pkt2 )) ) {
log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
goto leave;
}
*ret_pkc = pkt1.pkt.public_cert;
pkt1.pkt.public_cert = NULL;
*ret_skc = pkt1.pkt.secret_cert;
pkt1.pkt.secret_cert = NULL;
leave:
free_packet(&pkt1);
free_packet(&pkt2);
return rc; return rc;
} }
#endif /*ENABLE_RSA_KEYGEN*/ #endif /*ENABLE_RSA_KEYGEN*/
@ -305,28 +294,27 @@ generate_keypair()
const char *algo_name; const char *algo_name;
char *aname, *acomment, *amail; char *aname, *acomment, *amail;
#ifndef TEST_ALGO #ifndef TEST_ALGO
if( opt.batch || opt.answer_yes || opt.answer_no ) if( opt.batch || opt.answer_yes || opt.answer_no )
log_fatal("Key generation can only be used in interactive mode\n"); log_fatal(_("Key generation can only be used in interactive mode\n"));
tty_printf("Please select the algorithm to use:\n" tty_printf(_("Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n" " (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n" " (2) DSA can only be used for signatures.\n"));
#ifdef ENABLE_RSA_KEYGEN #ifdef ENABLE_RSA_KEYGEN
" (3) RSA cannot be used in the U.S.\n" tty_printf(_(" (3) RSA cannot be used in the U.S.\n"));
#endif
);
#endif #endif
#endif
for(;;) { for(;;) {
#ifdef TEST_ALGO #ifdef TEST_ALGO
algo = TEST_ALGO; algo = TEST_ALGO;
#else #else
answer = tty_get("Your selection? (1,2" #ifdef ENABLE_RSA_KEYGEN
#ifdef ENABLE_RSA_KEYGEN answer = tty_get(_("Your selection? (1,2,3) "));
",3" #else
#endif answer = tty_get(_("Your selection? (1,2) "));
") "); #endif
tty_kill_prompt(); tty_kill_prompt();
algo = *answer? atoi(answer): 1; algo = *answer? atoi(answer): 1;
m_free(answer); m_free(answer);
@ -339,7 +327,7 @@ generate_keypair()
else if( algo == 2 ) { else if( algo == 2 ) {
algo = PUBKEY_ALGO_DSA; algo = PUBKEY_ALGO_DSA;
algo_name = "DSA"; algo_name = "DSA";
tty_printf("Sorry; DSA is not yet supported.\n"); tty_printf(_("Sorry; DSA is not yet supported.\n"));
} }
#ifdef ENABLE_RSA_KEYGEN #ifdef ENABLE_RSA_KEYGEN
else if( algo == 3 ) { else if( algo == 3 ) {
@ -352,36 +340,33 @@ generate_keypair()
tty_printf("About to generate a new %s keypair.\n" tty_printf(_("About to generate a new %s keypair.\n"
#ifndef TEST_NBITS " minimum keysize is 768 bits\n"
" minimum keysize is 768 bits\n" " default keysize is 1024 bits\n"
" default keysize is 1024 bits\n" " highest suggested keysize is 2048 bits\n"), algo_name );
" highest suggested keysize is 2048 bits\n"
#endif
, algo_name );
for(;;) { for(;;) {
#ifdef TEST_NBITS #ifdef TEST_NBITS
nbits = TEST_NBITS; nbits = TEST_NBITS;
#else #else
answer = tty_get("What keysize do you want? (1024) "); answer = tty_get(_("What keysize do you want? (1024) "));
tty_kill_prompt(); tty_kill_prompt();
nbits = *answer? atoi(answer): 1024; nbits = *answer? atoi(answer): 1024;
m_free(answer); m_free(answer);
#endif #endif
if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) ) if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
tty_printf("DSA does only allow keysizes from 512 to 1024\n"); tty_printf(_("DSA does only allow keysizes from 512 to 1024\n"));
else if( nbits < 768 ) else if( nbits < 768 )
tty_printf("keysize too small; 768 is smallest value allowed.\n"); tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
else if( nbits > 2048 ) { else if( nbits > 2048 ) {
tty_printf("Keysizes larger than 2048 are not suggested, because " tty_printf(_("Keysizes larger than 2048 are not suggested, because "
"computations take REALLY long!\n"); "computations take REALLY long!\n"));
answer = tty_get("Are you sure, that you want this keysize? "); answer = tty_get(_("Are you sure, that you want this keysize? "));
tty_kill_prompt(); tty_kill_prompt();
if( answer_is_yes(answer) ) { if( answer_is_yes(answer) ) {
m_free(answer); m_free(answer);
tty_printf("Okay, but keep in mind that your monitor " tty_printf(_("Okay, but keep in mind that your monitor "
"and keyboard radiation is also very vulnerable " "and keyboard radiation is also very vulnerable "
"to attacks!\n"); "to attacks!\n"));
break; break;
} }
m_free(answer); m_free(answer);
@ -389,24 +374,24 @@ generate_keypair()
else else
break; break;
} }
tty_printf("Requested keysize is %u bits\n", nbits ); tty_printf(_("Requested keysize is %u bits\n"), nbits );
if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) {
nbits = ((nbits + 63) / 64) * 64; nbits = ((nbits + 63) / 64) * 64;
tty_printf("rounded up to %u bits\n", nbits ); tty_printf(_("rounded up to %u bits\n"), nbits );
} }
else if( (nbits % 32) ) { else if( (nbits % 32) ) {
nbits = ((nbits + 31) / 32) * 32; nbits = ((nbits + 31) / 32) * 32;
tty_printf("rounded up to %u bits\n", nbits ); tty_printf(_("rounded up to %u bits\n"), nbits );
} }
#ifdef TEST_UID #ifdef TEST_UID
uid = m_alloc(strlen(TEST_UID)+1); uid = m_alloc(strlen(TEST_UID)+1);
strcpy(uid, TEST_UID); strcpy(uid, TEST_UID);
#else #else
tty_printf( "\n" tty_printf( _("\n"
"You need a User-ID to identify your key; the software constructs the user id\n" "You need a User-ID to identify your key; the software constructs the user id\n"
"from Real Name, Comment and Email Address in this form:\n" "from Real Name, Comment and Email Address in this form:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n" ); " \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n") );
uid = NULL; uid = NULL;
aname=acomment=amail=NULL; aname=acomment=amail=NULL;
for(;;) { for(;;) {
@ -415,15 +400,15 @@ generate_keypair()
if( !aname ) { if( !aname ) {
for(;;) { for(;;) {
m_free(aname); m_free(aname);
aname = tty_get("Real name: "); aname = tty_get(_("Real name: "));
trim_spaces(aname); trim_spaces(aname);
tty_kill_prompt(); tty_kill_prompt();
if( strpbrk( aname, "<([])>" ) ) if( strpbrk( aname, "<([])>" ) )
tty_printf("Invalid character in name\n"); tty_printf(_("Invalid character in name\n"));
else if( isdigit(*aname) ) else if( isdigit(*aname) )
tty_printf("Name may not start with a digit\n"); tty_printf(_("Name may not start with a digit\n"));
else if( strlen(aname) < 5 ) else if( strlen(aname) < 5 )
tty_printf("Name must be at least 5 characters long\n"); tty_printf(_("Name must be at least 5 characters long\n"));
else else
break; break;
} }
@ -431,7 +416,7 @@ generate_keypair()
if( !amail ) { if( !amail ) {
for(;;) { for(;;) {
m_free(amail); m_free(amail);
amail = tty_get("Email address: "); amail = tty_get(_("Email address: "));
trim_spaces(amail); trim_spaces(amail);
strlwr(amail); strlwr(amail);
tty_kill_prompt(); tty_kill_prompt();
@ -443,7 +428,7 @@ generate_keypair()
|| amail[strlen(amail)-1] == '@' || amail[strlen(amail)-1] == '@'
|| amail[strlen(amail)-1] == '.' || amail[strlen(amail)-1] == '.'
|| strstr(amail, "..") ) || strstr(amail, "..") )
tty_printf("Not a valid email address\n"); tty_printf(_("Not a valid email address\n"));
else else
break; break;
} }
@ -451,13 +436,13 @@ generate_keypair()
if( !acomment ) { if( !acomment ) {
for(;;) { for(;;) {
m_free(acomment); m_free(acomment);
acomment = tty_get("Comment: "); acomment = tty_get(_("Comment: "));
trim_spaces(acomment); trim_spaces(acomment);
tty_kill_prompt(); tty_kill_prompt();
if( !*acomment ) if( !*acomment )
break; /* no comment is okay */ break; /* no comment is okay */
else if( strpbrk( acomment, "()" ) ) else if( strpbrk( acomment, "()" ) )
tty_printf("Invalid character in comment\n"); tty_printf(_("Invalid character in comment\n"));
else else
break; break;
} }
@ -473,15 +458,13 @@ generate_keypair()
/* append a warning if we do not have dev/random /* append a warning if we do not have dev/random
* or it is switched into quick testmode */ * or it is switched into quick testmode */
#ifdef HAVE_DEV_RANDOM
if( quick_random_gen(-1) ) if( quick_random_gen(-1) )
#endif
strcpy(p, " (INSECURE!)" ); strcpy(p, " (INSECURE!)" );
tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid); tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid);
for(;;) { for(;;) {
answer = tty_get("Edit (N)ame, (C)omment, (E)mail or (O)kay? "); answer = tty_get(_("Edit (N)ame, (C)omment, (E)mail or (O)kay? "));
tty_kill_prompt(); tty_kill_prompt();
if( strlen(answer) > 1 ) if( strlen(answer) > 1 )
; ;
@ -513,7 +496,7 @@ generate_keypair()
#endif #endif
tty_printf( "You need a Passphrase to protect your secret key.\n\n" ); tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
dek = m_alloc_secure( sizeof *dek ); dek = m_alloc_secure( sizeof *dek );
for(;;) { for(;;) {
@ -521,14 +504,14 @@ generate_keypair()
rc = make_dek_from_passphrase( dek , 2 ); rc = make_dek_from_passphrase( dek , 2 );
if( rc == -1 ) { if( rc == -1 ) {
m_free(dek); dek = NULL; m_free(dek); dek = NULL;
tty_printf( tty_printf(_(
"You don't what a passphrase - this is probably a *bad* idea!\n" "You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n" "I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n\n" ); "using this program with the option \"--change-passphrase\"\n\n"));
break; break;
} }
else if( rc == G10ERR_PASSPHRASE ) { else if( rc == G10ERR_PASSPHRASE ) {
tty_printf("passphrase not correctly repeated; try again.\n"); tty_printf(_("passphrase not correctly repeated; try again.\n"));
} }
else if( rc ) { else if( rc ) {
m_free(dek); dek = NULL; m_free(dek); dek = NULL;
@ -545,8 +528,8 @@ generate_keypair()
pub_fname = make_filename("~/.g10", "pubring.g10", NULL ); pub_fname = make_filename("~/.g10", "pubring.g10", NULL );
sec_fname = make_filename("~/.g10", "secring.g10", NULL ); sec_fname = make_filename("~/.g10", "secring.g10", NULL );
if( opt.verbose ) { if( opt.verbose ) {
tty_printf("writing public certificate to '%s'\n", pub_fname ); tty_printf(_("writing public certificate to '%s'\n"), pub_fname );
tty_printf("writing secret certificate to '%s'\n", sec_fname ); tty_printf(_("writing secret certificate to '%s'\n"), sec_fname );
} }
/* we create the packets as a tree of kbnodes. Because the structure /* we create the packets as a tree of kbnodes. Because the structure
@ -557,17 +540,17 @@ generate_keypair()
pub_root = make_comment_node("#created by G10 pre-release " VERSION ); pub_root = make_comment_node("#created by G10 pre-release " VERSION );
sec_root = make_comment_node("#created by G10 pre-release " VERSION ); sec_root = make_comment_node("#created by G10 pre-release " VERSION );
tty_printf( tty_printf(_(
"We need to generate a lot of random bytes. It is a good idea to perform\n" "We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (work in another window, move the mouse, utilize the\n" "some other action (work in another window, move the mouse, utilize the\n"
"network and the disks) during the prime generation; this gives the random\n" "network and the disks) during the prime generation; this gives the random\n"
"number generator a better chance to gain enough entropy.\n" ); "number generator a better chance to gain enough entropy.\n") );
if( algo == PUBKEY_ALGO_ELGAMAL ) if( algo == PUBKEY_ALGO_ELGAMAL )
rc = gen_elg(nbits, pub_root, sec_root, dek, &skc ); rc = gen_elg(nbits, pub_root, sec_root, dek, &skc );
#ifdef ENABLE_RSA_KEYGEN #ifdef ENABLE_RSA_KEYGEN
else if( algo == PUBKEY_ALGO_RSA ) else if( algo == PUBKEY_ALGO_RSA )
rc = gen_rsa(nbits, pub_io, sec_io, dek, &skc ); rc = gen_rsa(nbits, pub_root, sec_root, dek, &skc );
#endif #endif
else if( algo == PUBKEY_ALGO_DSA ) else if( algo == PUBKEY_ALGO_DSA )
rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc ); rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc );
@ -625,7 +608,7 @@ generate_keypair()
else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) ) else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
log_error("can't write secret key: %s\n", g10_errstr(rc) ); log_error("can't write secret key: %s\n", g10_errstr(rc) );
else { else {
tty_printf("public and secret key created and signed.\n" ); tty_printf(_("public and secret key created and signed.\n") );
} }
if( !rc1 ) if( !rc1 )
@ -636,7 +619,7 @@ generate_keypair()
if( rc ) if( rc )
tty_printf("Key generation failed: %s\n", g10_errstr(rc) ); tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
release_kbnode( pub_root ); release_kbnode( pub_root );
release_kbnode( sec_root ); release_kbnode( sec_root );
if( skc ) /* the unprotected secret certificate */ if( skc ) /* the unprotected secret certificate */

View File

@ -32,6 +32,13 @@ typedef struct {
} encrypt_filter_context_t; } encrypt_filter_context_t;
/*-- g10.c --*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
void g10_exit(int rc) __attribute__ ((noreturn));
#else
void g10_exit(int rc);
#endif
/*-- encode.c --*/ /*-- encode.c --*/
int encode_symmetric( const char *filename ); int encode_symmetric( const char *filename );
int encode_store( const char *filename ); int encode_store( const char *filename );
@ -71,11 +78,13 @@ KBNODE make_comment_node( const char *s );
/*-- elg.c --*/ /*-- elg.c --*/
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ); void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- rsa.c --*/ /*-- rsa.c --*/
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ); void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- import.c --*/ /*-- import.c --*/
int import_pubkeys( const char *filename ); int import_pubkeys( const char *filename );

View File

@ -613,7 +613,7 @@ proc_tree( CTX c, KBNODE node )
print_keyid( stderr, sig->keyid ); print_keyid( stderr, sig->keyid );
putc('\n', stderr); putc('\n', stderr);
if( opt.batch ) if( opt.batch )
exit(1); g10_exit(1);
} }
else else
log_error("Can't check signature made by %08lX: %s\n", log_error("Can't check signature made by %08lX: %s\n",

View File

@ -64,19 +64,20 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void void
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ) g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{ {
#ifdef HAVE_RSA_CIPHER #ifdef HAVE_RSA_CIPHER
RSA_secret_key skey; RSA_secret_key skey;
byte *dp; byte *dp;
assert( sig->pubkey_algo == PUBKEY_ALGO_RSA ); assert( sig->pubkey_algo == PUBKEY_ALGO_RSA );
if( !digest_algo )
digest_algo = md_get_algo(md);
md_final( md ); dp = md_read( md, digest_algo );
dp = md_read( md, 0 );
keyid_from_skc( skc, sig->keyid ); keyid_from_skc( skc, sig->keyid );
sig->d.rsa.digest_algo = md_get_algo( md ); sig->d.rsa.digest_algo = digest_algo;
sig->d.rsa.digest_start[0] = dp[0]; sig->d.rsa.digest_start[0] = dp[0];
sig->d.rsa.digest_start[1] = dp[1]; sig->d.rsa.digest_start[1] = dp[1];
sig->d.rsa.rsa_integer = sig->d.rsa.rsa_integer =

View File

@ -48,9 +48,9 @@ complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
if( (rc=check_secret_key( skc )) ) if( (rc=check_secret_key( skc )) )
; ;
else if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) else if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
g10_elg_sign( skc, sig, md ); g10_elg_sign( skc, sig, md, 0 );
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
g10_rsa_sign( skc, sig, md ); g10_rsa_sign( skc, sig, md, 0 );
else else
BUG(); BUG();
@ -246,7 +246,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
PKT_secret_cert *skc; PKT_secret_cert *skc;
PKT_signature *sig; PKT_signature *sig;
MD_HANDLE md; MD_HANDLE md;
byte *dp;
skc = skc_rover->skc; skc = skc_rover->skc;
@ -265,58 +264,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
md_putc( md, a & 0xff ); md_putc( md, a & 0xff );
} }
md_final( md ); md_final( md );
dp = md_read( md, DIGEST_ALGO_RMD160 );
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
ELG_secret_key skey; g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
MPI frame; else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
keyid_from_skc( skc, sig->keyid );
sig->d.elg.digest_algo = DIGEST_ALGO_RMD160;
sig->d.elg.digest_start[0] = dp[0];
sig->d.elg.digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
sig->d.elg.b = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
frame = encode_rmd160_value( dp, 20, mpi_get_nbits(skc->d.elg.p) );
skey.p = skc->d.elg.p;
skey.g = skc->d.elg.g;
skey.y = skc->d.elg.y;
skey.x = skc->d.elg.x;
elg_sign( sig->d.elg.a, sig->d.elg.b, frame, &skey);
memset( &skey, 0, sizeof skey );
mpi_free(frame);
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("ELG signature from: %s\n", ustr );
m_free(ustr);
}
}
#ifdef HAVE_RSA_CIPHER
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
RSA_secret_key skey;
keyid_from_skc( skc, sig->keyid );
sig->d.rsa.digest_algo = DIGEST_ALGO_RMD160;
sig->d.rsa.digest_start[0] = dp[0];
sig->d.rsa.digest_start[1] = dp[1];
sig->d.rsa.rsa_integer = encode_rmd160_value( dp, 20,
mpi_get_nbits(skc->d.rsa.rsa_n) );
skey.e = skc->d.rsa.rsa_e;
skey.n = skc->d.rsa.rsa_n;
skey.p = skc->d.rsa.rsa_p;
skey.q = skc->d.rsa.rsa_q;
skey.d = skc->d.rsa.rsa_d;
skey.u = skc->d.rsa.rsa_u;
rsa_secret( sig->d.rsa.rsa_integer, sig->d.rsa.rsa_integer, &skey);
memset( &skey, 0, sizeof skey );
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("RSA signature from: %s\n", ustr );
m_free(ustr);
}
/* fixme: should we check wether the signature is okay? */
}
#endif/*HAVE_RSA_CIPHER*/
else else
BUG(); BUG();

View File

@ -61,9 +61,20 @@ char *m_strdup( const char * a);
size_t m_size( const void *a ); size_t m_size( const void *a );
int m_is_secure( const void *p ); int m_is_secure( const void *p );
/*-- secmem.c --*/
void secmem_init( size_t npool );
void secmem_term( void );
void *secmem_malloc( size_t size );
void secmem_free( void *a );
void secmem_dump_stats(void);
#define DBG_MEMORY memory_debug_mode #define DBG_MEMORY memory_debug_mode
#define DBG_MEMSTAT memory_stat_debug_mode #define DBG_MEMSTAT memory_stat_debug_mode
int memory_debug_mode; int memory_debug_mode;
int memory_stat_debug_mode; int memory_stat_debug_mode;
#endif /*G10_MEMORY_H*/ #endif /*G10_MEMORY_H*/

View File

@ -216,11 +216,11 @@ mpi_sub_ui(MPI w, MPI u, unsigned long v )
void void
mpi_sub(MPI w, MPI u, MPI v) mpi_sub(MPI w, MPI u, MPI v)
{ {
if( 1 || w == v ) { if( w == v ) {
MPI vv = mpi_copy(v); MPI vv = mpi_copy(v);
vv->sign = !vv->sign; vv->sign = !vv->sign;
mpi_add( w, u, vv ); mpi_add( w, u, vv );
m_free(vv); mpi_free(vv);
} }
else { else {
/* fixme: this is not thread-save (we temp. modify v) */ /* fixme: this is not thread-save (we temp. modify v) */

0
po/ChangeLog Normal file
View File

View File

@ -55,7 +55,7 @@ SOURCES = cat-id-tbl.c
POFILES = @POFILES@ POFILES = @POFILES@
GMOFILES = @GMOFILES@ GMOFILES = @GMOFILES@
DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) $(POFILES) $(SOURCES)
POTFILES = \ POTFILES = \
@ -168,11 +168,12 @@ maintainer-clean: distclean
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
dist dist-gettext: update-po $(DISTFILES) distdir: $(DEP_DISTFILES)
for file in $(DISTFILES); do \ @for file in `cd $(srcdir) && echo $(DISTFILES)`; do \
ln $(srcdir)/$$file $(distdir) 2> /dev/null \ test -f $(distdir)/$$file \
|| cp -p $(srcdir)/$$file $(distdir); \ || ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir)/$$file; \
done done
update-po: Makefile update-po: Makefile

View File

@ -4,11 +4,12 @@
# utility # utility
# cipher # cipher
cipher/random.c
# main program # main program
g10/g10.c g10/g10.c
g10/pkclist.c g10/pkclist.c
g10/keygen.c

224
po/de.po
View File

@ -6,6 +6,32 @@ msgstr ""
"Xgettext-Options: --default-domain=g10 --directory=.. --add-comments --keyword=_ --keyword=N_ --files-from=./POTFILES.in\n" "Xgettext-Options: --default-domain=g10 --directory=.. --add-comments --keyword=_ --keyword=N_ --files-from=./POTFILES.in\n"
"Files: g10/g10.c g10/pkclist.c\n" "Files: g10/g10.c g10/pkclist.c\n"
#: cipher/random.c:146
msgid ""
"\n"
"Not enough random bytes available. Please do some other work to give"
msgstr ""
#: cipher/random.c:185
msgid "warning: using insecure random number generator!!\n"
msgstr ""
#: cipher/random.c:186
msgid ""
"The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n"
"\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
"\n"
msgstr ""
#: g10/g10.c:72
msgid ""
"Syntax: g10 [options] [files]\n"
"sign, check, encrypt or decrypt\n"
"default operation depends on the input data\n"
msgstr ""
#: g10/g10.c:77 #: g10/g10.c:77
msgid "Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n" msgid "Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n"
msgstr "Berichte über Wanzen bitte an <g10-bugs@isil.d.shuttle.de>.\n" msgstr "Berichte über Wanzen bitte an <g10-bugs@isil.d.shuttle.de>.\n"
@ -36,27 +62,27 @@ msgid ""
msgstr "" msgstr ""
" (RSA Verfahren ist vorhanden.)\n" " (RSA Verfahren ist vorhanden.)\n"
#: g10/g10.c:109 #: g10/g10.c:116
msgid "Usage: g10 [options] " msgid "Usage: g10 [options] "
msgstr "Aufruf: g10 [Opeionen] " msgstr "Aufruf: g10 [Opeionen] "
#: g10/g10.c:145 #: g10/g10.c:152
msgid "conflicting commands\n" msgid "conflicting commands\n"
msgstr "" msgstr ""
#: g10/g10.c:157 #: g10/g10.c:164
msgid "create ascii armored output" msgid "create ascii armored output"
msgstr "Ausgabe mit ASCII Armor versehen" msgstr "Ausgabe mit ASCII Armor versehen"
#: g10/g10.c:158 #: g10/g10.c:165
msgid "verbose" msgid "verbose"
msgstr "detailierte Informationen" msgstr "detailierte Informationen"
#: g10/g10.c:159 #: g10/g10.c:166
msgid "set compress level (0 disables)" msgid "set compress level (0 disables)"
msgstr "Kompressionspegel sethen (aussschalten mit 0)" msgstr "Kompressionspegel sethen (aussschalten mit 0)"
#: g10/g10.c:160 #: g10/g10.c:167
msgid "don't make any changes" msgid "don't make any changes"
msgstr "Keine wirklichen Änderungen durchführen" msgstr "Keine wirklichen Änderungen durchführen"
@ -208,43 +234,43 @@ msgstr ""
msgid "export all or the given keys" msgid "export all or the given keys"
msgstr "" msgstr ""
#: g10/g10.c:280 #: g10/g10.c:282
msgid "note: no default option file '%s'\n" msgid "note: no default option file '%s'\n"
msgstr "" msgstr ""
#: g10/g10.c:283 #: g10/g10.c:285
msgid "option file '%s': %s\n" msgid "option file '%s': %s\n"
msgstr "" msgstr ""
#: g10/g10.c:288 #: g10/g10.c:290
msgid "reading options from '%s'\n" msgid "reading options from '%s'\n"
msgstr "" msgstr ""
#: g10/g10.c:380 #: g10/g10.c:382
msgid "selected cipher algorithm is invalid\n" msgid "selected cipher algorithm is invalid\n"
msgstr "" msgstr ""
#: g10/g10.c:384 #: g10/g10.c:386
msgid "selected pubkey algorithm is invalid\n" msgid "selected pubkey algorithm is invalid\n"
msgstr "" msgstr ""
#: g10/g10.c:388 #: g10/g10.c:390
msgid "selected digest algorithm is invalid\n" msgid "selected digest algorithm is invalid\n"
msgstr "" msgstr ""
#: g10/g10.c:392 #: g10/g10.c:394
msgid "completes-needed must be greater than 0\n" msgid "completes-needed must be greater than 0\n"
msgstr "" msgstr ""
#: g10/g10.c:396 #: g10/g10.c:398
msgid "marginals-needed must be greater than 1\n" msgid "marginals-needed must be greater than 1\n"
msgstr "" msgstr ""
#: g10/g10.c:460 #: g10/g10.c:462
msgid "failed to initialize the TrustDB: %s\n" msgid "failed to initialize the TrustDB: %s\n"
msgstr "" msgstr ""
#: g10/g10.c:552 g10/g10.c:569 g10/g10.c:658 #: g10/g10.c:554 g10/g10.c:571 g10/g10.c:660
msgid "can't open '%s'\n" msgid "can't open '%s'\n"
msgstr "" msgstr ""
@ -306,3 +332,169 @@ msgstr ""
"Ein gültiger Trust Path konnte für diesen Key nicht gefunden werden.\n" "Ein gültiger Trust Path konnte für diesen Key nicht gefunden werden.\n"
"Mal sehen ob wir now weitere Ownertrust Werte zuordnen können.\n" "Mal sehen ob wir now weitere Ownertrust Werte zuordnen können.\n"
"\n" "\n"
#: g10/keygen.c:109
msgid "writing self signature\n"
msgstr ""
#: g10/keygen.c:299
msgid "Key generation can only be used in interactive mode\n"
msgstr ""
#: g10/keygen.c:301
msgid ""
"Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n"
msgstr ""
#: g10/keygen.c:305
msgid " (3) RSA cannot be used in the U.S.\n"
msgstr ""
#: g10/keygen.c:314
msgid "Your selection? (1,2,3) "
msgstr ""
#: g10/keygen.c:316
msgid "Your selection? (1,2) "
msgstr ""
#: g10/keygen.c:330
msgid "Sorry; DSA is not yet supported.\n"
msgstr ""
#: g10/keygen.c:343
msgid ""
"About to generate a new %s keypair.\n"
" minimum keysize is 768 bits\n"
" default keysize is 1024 bits\n"
" highest suggested keysize is 2048 bits\n"
msgstr ""
#: g10/keygen.c:351
msgid "What keysize do you want? (1024) "
msgstr ""
#: g10/keygen.c:357
msgid "DSA does only allow keysizes from 512 to 1024\n"
msgstr ""
#: g10/keygen.c:359
msgid "keysize too small; 768 is smallest value allowed.\n"
msgstr ""
#: g10/keygen.c:361
msgid "Keysizes larger than 2048 are not suggested, because computations take REALLY long!\n"
msgstr ""
#: g10/keygen.c:363
msgid "Are you sure, that you want this keysize? "
msgstr ""
#: g10/keygen.c:367
msgid "Okay, but keep in mind that your monitor and keyboard radiation is also very vulnerable to attacks!\n"
msgstr ""
#: g10/keygen.c:377
msgid "Requested keysize is %u bits\n"
msgstr ""
#: g10/keygen.c:380 g10/keygen.c:384
msgid "rounded up to %u bits\n"
msgstr ""
#: g10/keygen.c:391
msgid ""
"\n"
"You need a User-ID to identify your key; the software constructs the user id\n"
"from Real Name, Comment and Email Address in this form:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n"
"\n"
msgstr ""
#: g10/keygen.c:403
msgid "Real name: "
msgstr ""
#: g10/keygen.c:407
msgid "Invalid character in name\n"
msgstr ""
#: g10/keygen.c:409
msgid "Name may not start with a digit\n"
msgstr ""
#: g10/keygen.c:411
msgid "Name must be at least 5 characters long\n"
msgstr ""
#: g10/keygen.c:419
msgid "Email address: "
msgstr ""
#: g10/keygen.c:431
msgid "Not a valid email address\n"
msgstr ""
#: g10/keygen.c:439
msgid "Comment: "
msgstr ""
#. no comment is okay
#: g10/keygen.c:445
msgid "Invalid character in comment\n"
msgstr ""
#: g10/keygen.c:465
msgid ""
"You selected this USER-ID:\n"
" \"%s\"\n"
"\n"
msgstr ""
#: g10/keygen.c:467
msgid "Edit (N)ame, (C)omment, (E)mail or (O)kay? "
msgstr ""
#: g10/keygen.c:499
msgid ""
"You need a Passphrase to protect your secret key.\n"
"\n"
msgstr ""
#: g10/keygen.c:508
msgid ""
"You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n"
"\n"
msgstr ""
#: g10/keygen.c:514
msgid "passphrase not correctly repeated; try again.\n"
msgstr ""
#: g10/keygen.c:531
msgid "writing public certificate to '%s'\n"
msgstr ""
#: g10/keygen.c:532
msgid "writing secret certificate to '%s'\n"
msgstr ""
#: g10/keygen.c:544
msgid ""
"We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (work in another window, move the mouse, utilize the\n"
"network and the disks) during the prime generation; this gives the random\n"
"number generator a better chance to gain enough entropy.\n"
msgstr ""
#: g10/keygen.c:611
msgid "public and secret key created and signed.\n"
msgstr ""
#: g10/keygen.c:622
msgid "Key generation failed: %s\n"
msgstr ""

View File

@ -2,3 +2,4 @@ config.guess
config.sub config.sub
install-sh install-sh
mkinstalldirs mkinstalldirs
mkdiff

View File

@ -2,12 +2,15 @@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
bin_PROGRAMS = mpicalc noinst_PROGRAMS = mpicalc bftest
mpicalc_SOURCES = mpicalc.c mpicalc_SOURCES = mpicalc.c
bftest_SOURCES = bftest.c
LDADD = -L ../cipher -L ../mpi -L ../util -lmpi -lutil
$(PROGRAMS): ../mpi/libmpi.a LDADD = -L ../cipher -L ../mpi -L ../util -L ../cipher \
-lmpi -lutil -lmpi -lutil -lcipher
$(PROGRAMS): ../mpi/libmpi.a ../cipher/libcipher.a

View File

@ -40,14 +40,17 @@ transform = @program_transform_name@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
bin_PROGRAMS = mpicalc noinst_PROGRAMS = mpicalc bftest
mpicalc_SOURCES = mpicalc.c mpicalc_SOURCES = mpicalc.c
LDADD = -L ../cipher -L ../mpi -L ../util -lmpi -lutil bftest_SOURCES = bftest.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../cipher \
-lmpi -lutil -lmpi -lutil -lcipher
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h CONFIG_HEADER = ../config.h
PROGRAMS = $(bin_PROGRAMS) PROGRAMS = $(noinst_PROGRAMS)
CC = @CC@ CC = @CC@
@ -65,6 +68,9 @@ LINK = $(CC) $(LDFLAGS) -o $@
mpicalc_OBJECTS = mpicalc.o mpicalc_OBJECTS = mpicalc.o
EXTRA_mpicalc_SOURCES = EXTRA_mpicalc_SOURCES =
mpicalc_LDADD = $(LDADD) mpicalc_LDADD = $(LDADD)
bftest_OBJECTS = bftest.o
EXTRA_bftest_SOURCES =
bftest_LDADD = $(LDADD)
DIST_COMMON = Makefile.am Makefile.in DIST_COMMON = Makefile.am Makefile.in
@ -77,9 +83,9 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
$(TEXINFOS) $(INFO_DEPS) $(MANS) $(EXTRA_DIST) $(DATA) $(TEXINFOS) $(INFO_DEPS) $(MANS) $(EXTRA_DIST) $(DATA)
TAR = tar TAR = tar
DEP_FILES = $(srcdir)/.deps/mpicalc.P DEP_FILES = $(srcdir)/.deps/bftest.P $(srcdir)/.deps/mpicalc.P
SOURCES = $(mpicalc_SOURCES) SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES)
OBJECTS = $(mpicalc_OBJECTS) OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS)
default: all default: all
@ -90,27 +96,14 @@ $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
Makefile: $(top_builddir)/config.status Makefile.in Makefile: $(top_builddir)/config.status Makefile.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
mostlyclean-binPROGRAMS: mostlyclean-noinstPROGRAMS:
clean-binPROGRAMS: clean-noinstPROGRAMS:
rm -f $(bin_PROGRAMS) rm -f $(noinst_PROGRAMS)
distclean-binPROGRAMS: distclean-noinstPROGRAMS:
maintainer-clean-binPROGRAMS: maintainer-clean-noinstPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
$(mkinstalldirs) $(bindir)
list="$(bin_PROGRAMS)"; for p in $$list; do \
if test -f $$p; then \
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
list="$(bin_PROGRAMS)"; for p in $$list; do \
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
done
.c.o: .c.o:
$(COMPILE) $< $(COMPILE) $<
@ -128,6 +121,10 @@ $(mpicalc_OBJECTS): ../config.h
mpicalc: $(mpicalc_OBJECTS) $(mpicalc_DEPENDENCIES) mpicalc: $(mpicalc_OBJECTS) $(mpicalc_DEPENDENCIES)
$(LINK) $(mpicalc_OBJECTS) $(mpicalc_LDADD) $(LIBS) $(LINK) $(mpicalc_OBJECTS) $(mpicalc_LDADD) $(LIBS)
$(bftest_OBJECTS): ../config.h
bftest: $(bftest_OBJECTS) $(bftest_DEPENDENCIES)
$(LINK) $(bftest_OBJECTS) $(bftest_LDADD) $(LIBS)
ID: $(HEADERS) $(SOURCES) ID: $(HEADERS) $(SOURCES)
here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS) here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
@ -189,21 +186,20 @@ check: all
installcheck: installcheck:
install-exec: install-binPROGRAMS install-exec:
install-data: install-data:
install: install-exec install-data all install: install-exec install-data all
@: @:
uninstall: uninstall-binPROGRAMS uninstall:
all: $(PROGRAMS) Makefile all: $(PROGRAMS) Makefile
install-strip: install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
installdirs: installdirs:
$(mkinstalldirs) $(bindir)
mostlyclean-generic: mostlyclean-generic:
@ -219,25 +215,25 @@ distclean-generic:
maintainer-clean-generic: maintainer-clean-generic:
test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean: mostlyclean-noinstPROGRAMS mostlyclean-compile \
mostlyclean-tags mostlyclean-generic mostlyclean-tags mostlyclean-generic
clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ clean: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \
mostlyclean mostlyclean
distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean: distclean-noinstPROGRAMS distclean-compile distclean-tags \
distclean-generic clean distclean-generic clean
rm -f config.status rm -f config.status
maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ maintainer-clean: maintainer-clean-noinstPROGRAMS \
maintainer-clean-tags maintainer-clean-generic \ maintainer-clean-compile maintainer-clean-tags \
distclean maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
.PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ .PHONY: default mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir info dvi check installcheck \ clean-tags maintainer-clean-tags distdir info dvi check installcheck \
install-exec install-data install uninstall all installdirs \ install-exec install-data install uninstall all installdirs \
@ -245,7 +241,7 @@ mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean maintainer-clean-generic clean mostlyclean distclean maintainer-clean
$(PROGRAMS): ../mpi/libmpi.a $(PROGRAMS): ../mpi/libmpi.a ../cipher/libcipher.a
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .o .SUFFIXES: .c .o

View File

@ -22,9 +22,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef __MINGW32__
#include <io.h>
#include <fcntl.h>
#endif
#include "util.h" #include "util.h"
#include "blowfish.h" #include "cipher.h"
static void static void
my_usage(void) my_usage(void)
@ -48,6 +52,11 @@ main(int argc, char **argv)
char iv[BLOWFISH_BLOCKSIZE]; char iv[BLOWFISH_BLOCKSIZE];
int n, size=8; int n, size=8;
#ifdef __MINGW32__
setmode( fileno(stdin), O_BINARY );
setmode( fileno(stdout), O_BINARY );
#endif
if( argc > 1 && !strcmp(argv[1], "-e") ) { if( argc > 1 && !strcmp(argv[1], "-e") ) {
encode++; encode++;
argc--; argv++; argc--; argv++;

View File

@ -6,7 +6,7 @@ noinst_LIBRARIES = util
util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \ util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c errors.c iobuf.c ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c

View File

@ -43,7 +43,7 @@ INCLUDES = -I$(top_srcdir)/include
noinst_LIBRARIES = util noinst_LIBRARIES = util
util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \ util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c errors.c iobuf.c ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h CONFIG_HEADER = ../config.h
LIBRARIES = $(noinst_LIBRARIES) LIBRARIES = $(noinst_LIBRARIES)
@ -64,7 +64,7 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(LDFLAGS) -o $@ LINK = $(CC) $(LDFLAGS) -o $@
util_LIBADD = util_LIBADD =
util_OBJECTS = logger.o fileutil.o miscutil.o strgutil.o ttyio.o \ util_OBJECTS = logger.o fileutil.o miscutil.o strgutil.o ttyio.o \
argparse.o memory.o errors.o iobuf.o argparse.o memory.o secmem.o errors.o iobuf.o
EXTRA_util_SOURCES = EXTRA_util_SOURCES =
LIBFILES = libutil.a LIBFILES = libutil.a
AR = ar AR = ar
@ -84,8 +84,8 @@ TAR = tar
DEP_FILES = $(srcdir)/.deps/argparse.P $(srcdir)/.deps/errors.P \ DEP_FILES = $(srcdir)/.deps/argparse.P $(srcdir)/.deps/errors.P \
$(srcdir)/.deps/fileutil.P $(srcdir)/.deps/iobuf.P \ $(srcdir)/.deps/fileutil.P $(srcdir)/.deps/iobuf.P \
$(srcdir)/.deps/logger.P $(srcdir)/.deps/memory.P \ $(srcdir)/.deps/logger.P $(srcdir)/.deps/memory.P \
$(srcdir)/.deps/miscutil.P $(srcdir)/.deps/strgutil.P \ $(srcdir)/.deps/miscutil.P $(srcdir)/.deps/secmem.P \
$(srcdir)/.deps/ttyio.P $(srcdir)/.deps/strgutil.P $(srcdir)/.deps/ttyio.P
SOURCES = $(util_SOURCES) SOURCES = $(util_SOURCES)
OBJECTS = $(util_OBJECTS) OBJECTS = $(util_OBJECTS)
@ -170,11 +170,11 @@ $(srcdir)/.deps/%.P: $(srcdir)/%.c
@echo "mkdeps $< > $@" @echo "mkdeps $< > $@"
@re=`echo 's,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g' | sed 's,\.,\\\\.,g'`; \ @re=`echo 's,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g' | sed 's,\.,\\\\.,g'`; \
$(MKDEP) $< | sed "$$re" > $@-tmp $(MKDEP) $< | sed "$$re" > $@-tmp
@if test -n "$o"; then \ @if test -n "$o"; then \
sed 's/\.o:/$$o:/' $@-tmp > $@; \ sed 's/\.o:/$$o:/' $@-tmp > $@; \
rm $@-tmp; \ rm $@-tmp; \
else \ else \
mv $@-tmp $@; \ mv $@-tmp $@; \
fi fi
# End of maintainer-only section # End of maintainer-only section
@ -186,14 +186,14 @@ check: all
installcheck: installcheck:
install-exec: install-exec:
install-data: install-data:
install: install-exec install-data all install: install-exec install-data all
@: @:
uninstall: uninstall:
all: $(LIBFILES) Makefile all: $(LIBFILES) Makefile
@ -218,16 +218,16 @@ maintainer-clean-generic:
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-generic mostlyclean-tags mostlyclean-generic
clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
mostlyclean mostlyclean
distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \ distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \
distclean-generic clean distclean-generic clean
rm -f config.status rm -f config.status
maintainer-clean: maintainer-clean-noinstLIBRARIES \ maintainer-clean: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."

View File

@ -545,7 +545,7 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags )
indent += 10; indent += 10;
puts("Options:"); puts("Options:");
for(i=0; opts[i].short_opt; i++ ) { for(i=0; opts[i].short_opt; i++ ) {
s = _(opts[i].description); s = _( opts[i].description );
if( s && *s== '\r' ) /* hide this line */ if( s && *s== '\r' ) /* hide this line */
continue; continue;
if( opts[i].short_opt < 256 ) if( opts[i].short_opt < 256 )

View File

@ -111,6 +111,7 @@ log_fatal( const char *fmt, ... )
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
secmem_dump_stats();
exit(2); exit(2);
} }
@ -124,6 +125,7 @@ log_bug( const char *fmt, ... )
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
fflush(stderr); fflush(stderr);
secmem_dump_stats();
abort(); abort();
} }

View File

@ -314,9 +314,10 @@ membug( const char *fmt, ... )
static void static void
out_of_core(size_t n) out_of_core(size_t n, int secure)
{ {
log_fatal("out of memory while allocating %u bytes\n", (unsigned)n ); log_fatal("out of %s memory while allocating %u bytes\n",
secure? "secure":"" ,(unsigned)n );
} }
/**************** /****************
@ -329,7 +330,7 @@ FNAME(alloc)( size_t n FNAMEPRT )
char *p; char *p;
if( !(p = malloc( n + 5 )) ) if( !(p = malloc( n + 5 )) )
out_of_core(n); out_of_core(n,0);
store_len(p,n,0); store_len(p,n,0);
p[4+n] = MAGIC_END_BYTE; /* need to add the length somewhere */ p[4+n] = MAGIC_END_BYTE; /* need to add the length somewhere */
return p+4; return p+4;
@ -344,8 +345,8 @@ FNAME(alloc_secure)( size_t n FNAMEPRT )
{ {
char *p; char *p;
if( !(p = malloc( n + 5 )) ) /* fixme: should alloc from the secure heap*/ if( !(p = secmem_malloc( n + 5 )) )
out_of_core(n); out_of_core(n,1);
store_len(p,n,1); store_len(p,n,1);
p[4+n] = MAGIC_END_BYTE; p[4+n] = MAGIC_END_BYTE;
return p+4; return p+4;
@ -408,7 +409,10 @@ FNAME(free)( void *a FNAMEPRT )
free_entry(p-4, info); free_entry(p-4, info);
#else #else
m_check(p); m_check(p);
free(p-4); if( m_is_secure(a) )
secmem_free(p-4);
else
free(p-4);
#endif #endif
} }

243
util/secmem.c Normal file
View File

@ -0,0 +1,243 @@
/* secmem.c - memory allocation from a secure heap
* Copyright (c) 1997 by Werner Koch (dd9jn)
*
* This file is part of G10.
*
* G10 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.
*
* G10 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 <errno.h>
#include <stdarg.h>
#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#endif
#include "types.h"
#include "memory.h"
#include "util.h"
#define DEFAULT_POOLSIZE 8196
typedef struct memblock_struct MEMBLOCK;
struct memblock_struct {
unsigned size;
union {
MEMBLOCK *next;
long align_dummy;
char d[1];
} u;
};
static void *pool;
static int pool_okay;
static int pool_is_mmapped;
static size_t poolsize; /* allocated length */
static size_t poollen; /* used length */
static MEMBLOCK *unused_blocks;
static unsigned max_alloced;
static unsigned cur_alloced;
static unsigned max_blocks;
static unsigned cur_blocks;
static void
lock_pool( void *p, size_t n )
{
#ifdef HAVE_MLOCK
uid_t uid;
int err;
err = mlock( p, n );
if( err && errno )
err = errno;
uid = getuid();
if( uid && !geteuid() ) {
if( setuid( uid ) )
log_fatal("failed to reset uid: %s\n", strerror(errno));
}
if( err ) {
log_error("can´t lock memory: %s\n", strerror(err));
log_info("Warning: using insecure memory!\n");
}
#else
log_info("Please note that you don´t have secure memory on this system\n");
#endif
}
static void
init_pool( size_t n)
{
poolsize = n;
#if HAVE_MMAP && defined(MAP_ANONYMOUS)
poolsize = (poolsize + 4095) & ~4095;
pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if( pool == (void*)-1 )
log_error("can´t mmap pool of %u bytes: %s - using malloc\n",
(unsigned)poolsize, strerror(errno));
else {
pool_is_mmapped = 1;
pool_okay = 1;
}
#endif
if( !pool_okay ) {
pool = malloc( poolsize );
if( !pool )
log_fatal("can´t allocate memory pool of %u bytes\n",
(unsigned)poolsize);
else
pool_okay = 1;
}
lock_pool( pool, poolsize );
poollen = 0;
}
/* concatenate unused blocks */
static void
compress_pool(void)
{
}
void
secmem_init( size_t n )
{
if( n < DEFAULT_POOLSIZE )
n = DEFAULT_POOLSIZE;
if( !pool_okay )
init_pool(n);
else
log_error("Oops, secure memory pool already initialized\n");
}
void *
secmem_malloc( size_t size )
{
MEMBLOCK *mb, *mb2;
int compressed=0;
if( !pool_okay )
init_pool(DEFAULT_POOLSIZE);
/* blocks are always a multiple of 32 */
size += sizeof(MEMBLOCK);
size = ((size + 31) / 32) * 32;
retry:
/* try to get it from the used blocks */
for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next )
if( mb->size >= size ) {
if( mb2 )
mb2->u.next = mb->u.next;
else
unused_blocks = mb->u.next;
goto leave;
}
/* allocate a new block */
if( (poollen + size <= poolsize) ) {
mb = pool + poollen;
poollen += size;
mb->size = size;
}
else if( !compressed ) {
compressed=1;
compress_pool();
goto retry;
}
else
return NULL;
leave:
cur_alloced += mb->size;
cur_blocks++;
if( cur_alloced > max_alloced )
max_alloced = cur_alloced;
if( cur_blocks > max_blocks )
max_blocks = cur_blocks;
return &mb->u.d;
}
void
secmem_free( void *a )
{
MEMBLOCK *mb;
size_t size;
if( !a )
return;
mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.d));
size = mb->size;
memset(mb, 0xff, size );
memset(mb, 0xaa, size );
memset(mb, 0x55, size );
memset(mb, 0x00, size );
mb->size = size;
mb->u.next = unused_blocks;
unused_blocks = mb;
cur_blocks--;
cur_alloced -= size;
}
void
secmem_term()
{
if( !pool_okay )
return;
memset( pool, 0xff, poolsize);
memset( pool, 0xaa, poolsize);
memset( pool, 0x55, poolsize);
memset( pool, 0x00, poolsize);
#if HAVE_MMAP
if( pool_is_mmapped )
munmap( pool, poolsize );
#endif
pool = NULL;
pool_okay = 0;
poolsize=0;
poollen=0;
unused_blocks=NULL;
}
void
secmem_dump_stats()
{
fprintf(stderr,
"secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
cur_alloced, max_alloced, cur_blocks, max_blocks,
(ulong)poollen, (ulong)poolsize );
}