diff options
author | Werner Koch <wk@gnupg.org> | 2002-08-03 12:50:53 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2002-08-03 12:50:53 +0200 |
commit | 85aa3e18c296cdf18f76a47754d5270eb4e3630e (patch) | |
tree | c47a142fce35ba999e72fad2037a8020b3d8ab16 /cipher | |
parent | 2002-08-02 Timo Schulz <ts@winpt.org> (diff) | |
download | gnupg2-85aa3e18c296cdf18f76a47754d5270eb4e3630e.tar.xz gnupg2-85aa3e18c296cdf18f76a47754d5270eb4e3630e.zip |
The big extension module removal.
Diffstat (limited to 'cipher')
-rw-r--r-- | cipher/ChangeLog | 38 | ||||
-rw-r--r-- | cipher/Makefile.am | 72 | ||||
-rw-r--r-- | cipher/algorithms.h | 66 | ||||
-rw-r--r-- | cipher/blowfish.h | 10 | ||||
-rw-r--r-- | cipher/cipher.c | 75 | ||||
-rw-r--r-- | cipher/dynload.c | 606 | ||||
-rw-r--r-- | cipher/idea-stub.c | 187 | ||||
-rw-r--r-- | cipher/md.c | 138 | ||||
-rw-r--r-- | cipher/md5.c | 64 | ||||
-rw-r--r-- | cipher/pubkey.c | 69 | ||||
-rw-r--r-- | cipher/rand-internal.h | 18 | ||||
-rw-r--r-- | cipher/random.c | 42 | ||||
-rw-r--r-- | cipher/rmd160.c | 70 | ||||
-rw-r--r-- | cipher/rndegd.c | 75 | ||||
-rw-r--r-- | cipher/rndlinux.c | 94 | ||||
-rw-r--r-- | cipher/rndunix.c | 77 | ||||
-rw-r--r-- | cipher/rndw32.c | 292 | ||||
-rw-r--r-- | cipher/sha1.c | 70 | ||||
-rw-r--r-- | cipher/tiger.c | 92 |
19 files changed, 505 insertions, 1650 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 77efc4449..6599a51bc 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,41 @@ +2002-08-03 Werner Koch <wk@gnupg.org> + + * rndegd.c (do_read): Handle case when read returns 0 to avoid + gpg hanging when EGD died. By Christian Biere. + +2002-08-02 Werner Koch <wk@gnupg.org> + + The big extension removal. + + * Makefile.am: Removed all extension stuff. + * dynload.c: Removed everything except for + register_cipher_extension. + (dynload_enum_module_names): New. + * dynload.h: Removed. + * random.c (getfnc_gather_random,getfnc_fast_random_poll): + New. Replaced all dynload functions with these ones. + * rndunix.c (rndunix_gather_random): Renamed from + gather_random. Made global. Removed all dynload stuff. + * rndlinux.c (rndlinux_gather_random): Likewise. + * rndegd.c (rndegd_gather_random): Likewise. + * rndw32.c (rndw32_gather_random) + (rndw32_gather_random_fast): Likewise. Also removed the unsued + entropy dll code. + * md.c (new_list_item): Changed return value to indicate whether + an algorithms was loaded. + (load_digest_module): Simplified by removing all the dynload code. + * algorithms.h: New. + * md5.c (md5_get_info): Made global. Removed all dynload stuff. + * rmd160.c (rmd160_get_info): Likewise. + * sha1.c (sha1_get_info): Likewise. + * tiger.c (tiger_get_info): Likewise. Return NULL if we can't use + this module. + * idea-stub.c: New. + * blowfish.h (idea_get_info): Add prototype. + * cipher.c (setup_cipher_table): Try to load IDEA. + (load_cipher_modules): Removed all dynload code. + * pubkey.c (load_pubkey_modules): Removed the dynloading code. + 2002-07-25 David Shaw <dshaw@jabberwocky.com> * random.c: "warning" -> "WARNING" diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 83e81877e..59aae94d7 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -18,39 +18,14 @@ ## Process this file with automake to produce Makefile.in - INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl noinst_LIBRARIES = libcipher.a -# 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 -EXTRA_rndegd_SOURCES = rndegd.c -EXTRA_rndw32_SOURCES = rndw32.c -EXTRA_md5_SOURCES = md5.c -EXTRA_rmd160_SOURCES = rmd160.c -EXTRA_sha1_SOURCES = sha1.c -EXTRA_tiger_SOURCES = tiger.c - - -if ENABLE_GNUPG_EXTENSIONS -pkglib_PROGRAMS = @DYNAMIC_CIPHER_MODS@ -else -pkglib_PROGRAMS = -endif - - -DYNLINK_MOD_CFLAGS = -DIS_MODULE @DYNLINK_MOD_CFLAGS@ - -#libcipher_a_LDFLAGS = libcipher_a_SOURCES = cipher.c \ pubkey.c \ md.c \ dynload.c \ - dynload.h \ bithelp.h \ des.c \ des.h \ @@ -72,43 +47,22 @@ libcipher_a_SOURCES = cipher.c \ dsa.c \ g10c.c \ smallprime.c \ - construct.c - -# configure creates the constructor file -BUILT_SOURCES = construct.c -DISTCLEANFILES = construct.c + algorithms.h \ + rndlinux.c \ + rndunix.c \ + rndegd.c \ + rndw32.c \ + md5.c \ + rmd160.c \ + sha1.c \ + tiger.c -libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@ -libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@ +EXTRA_libcipher_a_SOURCES = idea-stub.c - -# If I remember it correct, automake 1.4 has a feature to set -# fooFLAGS depending on the program. So we should check it out. - -tiger$(EXEEXT): $(srcdir)/tiger.c - `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \ - sed -e 's/-O[2-9s]*/-O/g' ` +libcipher_a_DEPENDENCIES = @IDEA_O@ +libcipher_a_LIBADD = @IDEA_O@ tiger.o: $(srcdir)/tiger.c `echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' ` -#twofish: $(srcdir)/twofish.c -# `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \ -# sed -e 's/-O[0-9s]*/ /g' ` - -twofish: $(srcdir)/twofish.c - $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c - -#twofish.o: $(srcdir)/twofish.c -# `echo $(COMPILE) -c $(srcdir)/twofish.c | sed -e 's/-O[0-9s]*/ /g' ` - - -rndunix$(EXEEXT): $(srcdir)/rndunix.c - $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndunix $(srcdir)/rndunix.c - -rndlinux$(EXEEXT): $(srcdir)/rndlinux.c - $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndlinux $(srcdir)/rndlinux.c - -rndegd$(EXEEXT): $(srcdir)/rndegd.c - $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndegd $(srcdir)/rndegd.c diff --git a/cipher/algorithms.h b/cipher/algorithms.h new file mode 100644 index 000000000..a6b910612 --- /dev/null +++ b/cipher/algorithms.h @@ -0,0 +1,66 @@ +/* algorithms.h - prototypes for algorithm functions. + * Copyright (C) 2002 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 GNUPG_ALGORITHMS_H +#define GNUPG_ALGORITHMS_H 1 + +const char *dynload_enum_module_names (int seq); + + + +const char * +md5_get_info (int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); + + +const char * +rmd160_get_info (int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); + +const char * +sha1_get_info (int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); + +const char * +tiger_get_info (int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); + + + +#endif /*GNUPG_ALGORITHMS_H*/ diff --git a/cipher/blowfish.h b/cipher/blowfish.h index bed034c73..46e302288 100644 --- a/cipher/blowfish.h +++ b/cipher/blowfish.h @@ -41,7 +41,7 @@ twofish_get_info( int algo, size_t *keylen, void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) ); -/* this is just a kludge for the time we have not yet chnaged the cipher +/* this is just a kludge for the time we have not yet changed the cipher * stuff to the scheme we use for random and digests */ const char * rijndael_get_info( int algo, size_t *keylen, @@ -51,4 +51,12 @@ rijndael_get_info( int algo, size_t *keylen, void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) ); +const char * +idea_get_info( int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**setkeyf)( void *c, byte *key, unsigned keylen ), + void (**encryptf)( void *c, byte *outbuf, byte *inbuf ), + void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) + ); + #endif /*G10_BLOWFISH_H*/ diff --git a/cipher/cipher.c b/cipher/cipher.c index 2744f041a..761ec9b99 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -1,5 +1,5 @@ /* cipher.c - cipher dispatcher - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -30,7 +30,6 @@ #include "des.h" #include "blowfish.h" #include "cast5.h" -#include "dynload.h" #define MAX_BLOCKSIZE 16 @@ -162,6 +161,16 @@ setup_cipher_table(void) if( !cipher_table[i].name ) BUG(); i++; + cipher_table[i].algo = CIPHER_ALGO_IDEA; + cipher_table[i].name = idea_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].encrypt, + &cipher_table[i].decrypt ); + if (cipher_table[i].name) + i++; /* Note that IDEA is usually no available. */ #ifdef IS_DEVELOPMENT_VERSION cipher_table[i].algo = CIPHER_ALGO_DUMMY; @@ -186,63 +195,15 @@ setup_cipher_table(void) static int load_cipher_modules(void) { - static int done = 0; - static int initialized = 0; - void *context = NULL; - struct cipher_table_s *ct; - int ct_idx; - int i; - const char *name; - int any = 0; - - if( !initialized ) { - cipher_modules_constructor(); - setup_cipher_table(); /* load static modules on the first call */ - initialized = 1; - return 1; - } + static int initialized = 0; - if( done ) - return 0; - done = 1; - - for(ct_idx=0, ct = cipher_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) { - if( !ct->name ) - break; - } - if( ct_idx >= TABLE_SIZE-1 ) - BUG(); /* table already full */ - /* now load all extensions */ - while( (name = enum_gnupgext_ciphers( &context, &ct->algo, - &ct->keylen, &ct->blocksize, &ct->contextsize, - &ct->setkey, &ct->encrypt, &ct->decrypt)) ) { - if( ct->blocksize != 8 && ct->blocksize != 16 ) { - log_info("skipping cipher %d: unsupported blocksize\n", ct->algo); - continue; - } - for(i=0; cipher_table[i].name; i++ ) - if( cipher_table[i].algo == ct->algo ) - break; - if( cipher_table[i].name ) { - log_info("skipping cipher %d: already loaded\n", ct->algo ); - continue; - } - /* put it into the table */ - if( g10_opt_verbose > 1 ) - log_info("loaded cipher %d (%s)\n", ct->algo, name); - ct->name = name; - ct_idx++; - ct++; - any = 1; - /* check whether there are more available table slots */ - if( ct_idx >= TABLE_SIZE-1 ) { - log_info("cipher table full; ignoring other extensions\n"); - break; - } + if (!initialized ) + { + setup_cipher_table(); /* load static modules on the first call */ + initialized = 1; + return 1; } - enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL, - NULL, NULL, NULL ); - return any; + return 0; } diff --git a/cipher/dynload.c b/cipher/dynload.c index 09cd1366a..38c6a0c35 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -1,5 +1,5 @@ /* dynload.c - load cipher extensions - * Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -23,139 +23,22 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#ifdef HAVE_DL_DLOPEN - #include <dlfcn.h> -#elif defined(HAVE_DLD_DLD_LINK) - #include <dld.h> -#elif defined(HAVE_DL_SHL_LOAD) - #include <dl.h> - #include <errno.h> -#endif -#ifdef __MINGW32__ - #include <windows.h> -#endif #include "util.h" #include "cipher.h" -#include "dynload.h" - -#ifdef WITH_SYMBOL_UNDERSCORE - #define SYMBOL_VERSION "_gnupgext_version" - #define SYMBOL_ENUM "_gnupgext_enum_func" -#else - #define SYMBOL_VERSION "gnupgext_version" - #define SYMBOL_ENUM "gnupgext_enum_func" -#endif - - -#ifndef RTLD_NOW - #define RTLD_NOW 1 -#endif - -#ifdef HAVE_DL_SHL_LOAD /* HPUX has shl_load instead of dlopen */ -#define HAVE_DL_DLOPEN -#define dlopen(PATHNAME,MODE) \ - ((void *) shl_load(PATHNAME, DYNAMIC_PATH | \ - (((MODE) & RTLD_NOW) ? BIND_IMMEDIATE : BIND_DEFERRED), 0L)) -#define dlclose(HANDLE) shl_unload((shl_t) (HANDLE)) -#define dlerror() (errno == 0 ? NULL : strerror(errno)) - -static void * -dlsym(void *handle, char *name) -{ - void *addr; - if (shl_findsym((shl_t *)&handle,name,(short)TYPE_UNDEFINED,&addr) != 0) { - return NULL; - } - return addr; -} -#endif /*HAVE_DL_SHL_LOAD*/ - -#ifdef __MINGW32__ -#define HAVE_DL_DLOPEN -#define USE_DYNAMIC_LINKING - -static int last_error = 0; - -void* -dlopen(const char *pathname, int mode) -{ - void *h = LoadLibrary( pathname ); - if (!h) { - log_error( "LoadLibrary failed ec=%d\n", (int)GetLastError() ); - last_error = 1; - return NULL; - } - return h; -} - -int -dlclose( void *handle ) -{ - last_error = 0; - return FreeLibrary( handle ); -} - -char* -dlerror(void) -{ - static char dlerrstr[10]; - if (last_error) { - sprintf(dlerrstr, "%d", (int)GetLastError() ); - return dlerrstr; - } - return NULL; -} - -void* -dlsym( void *handle, const char *name ) -{ - void *h = GetProcAddress( handle, name ); - if (!h) { - log_error( "GetProcAddress failed ec=%d\n", (int)GetLastError() ); - last_error = 1; - return NULL; - } - return h; -} -#endif /*__MINGW32__*/ - - - +#include "algorithms.h" typedef struct ext_list { struct ext_list *next; - int internal; - #ifdef HAVE_DL_DLOPEN - void *handle; /* handle from dlopen() */ - #else - int handle; /* if the function has been loaded, this is true */ - #endif - int failed; /* already tried but failed */ - void * (*enumfunc)(int, int*, int*, int*); - char *hintstr; /* pointer into name */ char name[1]; } *EXTLIST; static EXTLIST extensions; -typedef struct { - EXTLIST r; - int seq1; - int seq2; - void *sym; - int reqalgo; -} ENUMCONTEXT; - - -#ifdef HAVE_DLD_DLD_LINK -static char *mainpgm_path; -static int did_dld_init; -static int dld_available; -#endif - - -/**************** +/* This is actually not used anymore but we keep a list of already + * set extensions modules here. + * + * Here is the ancient comment: * Register an extension module. The last registered module will * be loaded first. A name may have a list of classes * appended; e.g: @@ -174,10 +57,6 @@ register_cipher_extension( const char *mainpgm, const char *fname ) EXTLIST r, el, intex; char *p, *pe; - #ifdef HAVE_DLD_DLD_LINK - if( !mainpgm_path && mainpgm && *mainpgm ) - mainpgm_path = m_strdup(mainpgm); - #endif if( *fname != DIRSEP_C ) { /* do tilde expansion etc */ char *tmp; @@ -194,12 +73,8 @@ register_cipher_extension( const char *mainpgm, const char *fname ) strcpy(el->name, fname ); } /* check whether we have a class hint */ - if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) { + if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) *p = *pe = 0; - el->hintstr = p+1; - } - else - el->hintstr = NULL; /* check that it is not already registered */ intex = NULL; @@ -209,473 +84,20 @@ register_cipher_extension( const char *mainpgm, const char *fname ) m_free(el); return; } - else if( r->internal ) - intex = r; - } - /* and register */ - /* we put them after the internal extension modules */ - /* this is so that the external modules do not get loaded */ - /* as soon as the internal modules are requested */ - if( intex ) { - el->next = intex->next; - intex->next = el; - } - else { - el->next = extensions; - extensions = el; - } -} - -void -register_internal_cipher_extension( - const char *module_id, - void * (*enumfunc)(int, int*, int*, int*) - ) -{ - EXTLIST r, el; - - el = m_alloc_clear( sizeof *el + strlen(module_id) ); - strcpy(el->name, module_id ); - el->internal = 1; - - /* check that it is not already registered */ - for(r = extensions; r; r = r->next ) { - if( !compare_filenames(r->name, el->name) ) { - log_info("extension `%s' already registered\n", el->name ); - m_free(el); - return; - } } /* and register */ - el->enumfunc = enumfunc; - #ifdef HAVE_DL_DLOPEN - el->handle = (void*)1; - #else - el->handle = 1; - #endif el->next = extensions; extensions = el; } - -static int -load_extension( EXTLIST el ) -{ - #ifdef USE_DYNAMIC_LINKING - char **name; - #ifdef HAVE_DL_DLOPEN - const char *err; - int seq = 0; - int class, vers; - void *sym; - #else - unsigned long addr; - int rc; - #endif - - #ifndef __MINGW32__ - /* make sure we are not setuid */ - if( getuid() != geteuid() ) - log_bug("trying to load an extension while still setuid\n"); - #endif - - /* now that we are not setuid anymore, we can safely load modules */ - #ifdef HAVE_DL_DLOPEN - el->handle = dlopen(el->name, RTLD_NOW); - if( !el->handle ) { - log_error("%s: error loading extension: %s\n", el->name, dlerror() ); - goto failure; - } - name = (char**)dlsym(el->handle, SYMBOL_VERSION); - if( (err=dlerror()) ) { - log_error("%s: not a gnupg extension: %s\n", el->name, err ); - goto failure; - } - #else /* have dld */ - if( !did_dld_init ) { - did_dld_init = 1; - if( !mainpgm_path ) - log_error("DLD is not correctly initialized\n"); - else { - rc = dld_init( dld_find_executable(mainpgm_path) ); - if( rc ) - log_error("DLD init failed: %s\n", dld_strerror(rc) ); - else - dld_available = 1; - } - } - if( !dld_available ) { - log_error("%s: DLD not available\n", el->name ); - goto failure; - } - - rc = dld_link( el->name ); - if( rc ) { - log_error("%s: error loading extension: %s\n", - el->name, dld_strerror(rc) ); - goto failure; - } - addr = dld_get_symbol(SYMBOL_VERSION); - if( !addr ) { - log_error("%s: not a gnupg extension: %s\n", - el->name, dld_strerror(dld_errno) ); - goto failure; - } - name = (char**)addr; - #endif - - if( g10_opt_verbose > 1 ) - log_info("%s: %s%s%s%s\n", el->name, *name, - el->hintstr? " (":"", - el->hintstr? el->hintstr:"", - el->hintstr? ")":""); - - #ifdef HAVE_DL_DLOPEN - sym = dlsym(el->handle, SYMBOL_ENUM); - if( (err=dlerror()) ) { - log_error("%s: invalid gnupg extension: %s\n", el->name, err ); - goto failure; - } - el->enumfunc = (void *(*)(int,int*,int*,int*))sym; - #else /* dld */ - addr = dld_get_func(SYMBOL_ENUM); - if( !addr ) { - log_error("%s: invalid gnupg extension: %s\n", - el->name, dld_strerror(dld_errno) ); - goto failure; - } - rc = dld_function_executable_p(SYMBOL_ENUM); - if( rc ) { - log_error("%s: extension function is not executable: %s\n", - el->name, dld_strerror(rc) ); - goto failure; - } - el->enumfunc = (void *(*)(int,int*,int*,int*))addr; - el->handle = 1; /* mark as usable */ - #endif - - #ifdef HAVE_DL_DLOPEN - if( g10_opt_verbose > 2 ) { - /* list the contents of the module */ - while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) { - if( vers != 1 ) { - log_info("%s: ignoring func with version %d\n",el->name,vers); - continue; - } - switch( class ) { - case 11: - case 21: - case 31: - log_info("%s: provides %s algorithm %d\n", el->name, - class == 11? "md" : - class == 21? "cipher" : "pubkey", - *(int*)sym); - break; - default: - /*log_debug("%s: skipping class %d\n", el->name, class);*/ - break; - } - } - } - #endif - return 0; - - failure: - #ifdef HAVE_DL_DLOPEN - if( el->handle ) { - dlclose(el->handle); - el->handle = NULL; - } - #endif - el->failed = 1; - #endif /*USE_DYNAMIC_LINKING*/ - return -1; -} - -#ifdef __riscos__ -typedef -const char *(*DIGESTS_CAST)(int, size_t*,byte**, int*, int*, - void (**)(void*), - void (**)(void*,byte*,size_t), - void (**)(void*),byte *(**)(void*)); -#endif /* __riscos__ */ - -int -enum_gnupgext_digests( void **enum_context, - int *algo, - const char *(**r_get_info)( int, size_t*,byte**, int*, int*, - void (**)(void*), - void (**)(void*,byte*,size_t), - void (**)(void*),byte *(**)(void*)) ) -{ - EXTLIST r; - ENUMCONTEXT *ctx; - - if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); - ctx->r = extensions; - ctx->reqalgo = *algo; - *enum_context = ctx; - } - else if( !algo ) { /* release the context */ - m_free(*enum_context); - *enum_context = NULL; - return 0; - } - else - ctx = *enum_context; - - for( r = ctx->r; r; r = r->next ) { - int class, vers; - - if( r->failed ) - continue; - if( !r->handle && load_extension(r) ) - continue; - /* get a digest info function */ - if( ctx->sym ) - goto inner_loop; - while( (ctx->sym = (*r->enumfunc)(10, &ctx->seq1, &class, &vers)) ) { - void *sym; - /* must check class because enumfunc may be wrong coded */ - if( vers != 1 || class != 10 ) - continue; - inner_loop: -#ifndef __riscos__ - *r_get_info = ctx->sym; -#else /* __riscos__ */ - *r_get_info = (DIGESTS_CAST) ctx->sym; -#endif /* __riscos__ */ - while( (sym = (*r->enumfunc)(11, &ctx->seq2, &class, &vers)) ) { - if( vers != 1 || class != 11 ) - continue; - *algo = *(int*)sym; - ctx->r = r; - return 1; - } - ctx->seq2 = 0; - } - ctx->seq1 = 0; - } - ctx->r = r; - return 0; -} - -#ifdef __riscos__ -typedef -const char *(*CIPHERS_CAST)(int, size_t*, size_t*, size_t*, - int (**)( void *, byte *, unsigned), - void (**)( void *, byte *, byte *), - void (**)( void *, byte *, byte *)); -#endif /* __riscos__ */ - +/* Return the module name with index SEQ, return NULL as as indication + for end of list. */ const char * -enum_gnupgext_ciphers( void **enum_context, int *algo, - size_t *keylen, size_t *blocksize, size_t *contextsize, - int (**setkeyf)( void *c, byte *key, unsigned keylen ), - void (**encryptf)( void *c, byte *outbuf, byte *inbuf ), - void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) - ) +dynload_enum_module_names (int seq) { - EXTLIST r; - ENUMCONTEXT *ctx; - const char * (*finfo)(int, size_t*, size_t*, size_t*, - int (**)( void *, byte *, unsigned), - void (**)( void *, byte *, byte *), - void (**)( void *, byte *, byte *)); + EXTLIST el = extensions; - if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); - ctx->r = extensions; - *enum_context = ctx; - } - else if( !algo ) { /* release the context */ - m_free(*enum_context); - *enum_context = NULL; - return NULL; - } - else - ctx = *enum_context; - - for( r = ctx->r; r; r = r->next ) { - int class, vers; - - if( r->failed ) - continue; - if( !r->handle && load_extension(r) ) - continue; - /* get a cipher info function */ - if( ctx->sym ) - goto inner_loop; - while( (ctx->sym = (*r->enumfunc)(20, &ctx->seq1, &class, &vers)) ) { - void *sym; - /* must check class because enumfunc may be wrong coded */ - if( vers != 1 || class != 20 ) - continue; - inner_loop: -#ifndef __riscos__ - finfo = ctx->sym; -#else /* __riscos__ */ - finfo = (CIPHERS_CAST) ctx->sym; -#endif /* __riscos__ */ - while( (sym = (*r->enumfunc)(21, &ctx->seq2, &class, &vers)) ) { - const char *algname; - if( vers != 1 || class != 21 ) - continue; - *algo = *(int*)sym; - algname = (*finfo)( *algo, keylen, blocksize, contextsize, - setkeyf, encryptf, decryptf ); - if( algname ) { - ctx->r = r; - return algname; - } - } - ctx->seq2 = 0; - } - ctx->seq1 = 0; - } - ctx->r = r; - return NULL; -} - -#ifdef __riscos__ -typedef -const char *(*PUBKEYS_CAST)(int, int *, int *, int *, int *, int *, - int (**)(int, unsigned, MPI *, MPI **), - int (**)(int, MPI *), - int (**)(int, MPI *, MPI , MPI *), - int (**)(int, MPI *, MPI *, MPI *), - int (**)(int, MPI *, MPI , MPI *), - int (**)(int, MPI , MPI *, MPI *, - int (*)(void*,MPI), void *), - unsigned (**)( int , MPI *)); -#endif /* __riscos__ */ - -const char * -enum_gnupgext_pubkeys( void **enum_context, int *algo, - int *npkey, int *nskey, int *nenc, int *nsig, int *use, - int (**generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors ), - int (**check_secret_key)( int algo, MPI *skey ), - int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey ), - int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey ), - int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ), - int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey, - int (*cmp)(void *, MPI), void *opaquev ), - unsigned (**get_nbits)( int algo, MPI *pkey ) ) -{ - EXTLIST r; - ENUMCONTEXT *ctx; - const char * (*finfo)( int, int *, int *, int *, int *, int *, - int (**)( int, unsigned, MPI *, MPI **), - int (**)( int, MPI * ), - int (**)( int, MPI *, MPI , MPI * ), - int (**)( int, MPI *, MPI *, MPI * ), - int (**)( int, MPI *, MPI , MPI * ), - int (**)( int, MPI , MPI *, MPI *, - int (*)(void*,MPI), void *), - unsigned (**)( int , MPI * ) ); - - if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); - ctx->r = extensions; - *enum_context = ctx; - } - else if( !algo ) { /* release the context */ - m_free(*enum_context); - *enum_context = NULL; - return NULL; - } - else - ctx = *enum_context; - - for( r = ctx->r; r; r = r->next ) { - int class, vers; - - if( r->failed ) - continue; - if( !r->handle && load_extension(r) ) - continue; - /* get a pubkey info function */ - if( ctx->sym ) - goto inner_loop; - while( (ctx->sym = (*r->enumfunc)(30, &ctx->seq1, &class, &vers)) ) { - void *sym; - if( vers != 1 || class != 30 ) - continue; - inner_loop: -#ifndef __riscos__ - finfo = ctx->sym; -#else /* __riscos__ */ - finfo = (PUBKEYS_CAST) ctx->sym; -#endif /* __riscos__ */ - while( (sym = (*r->enumfunc)(31, &ctx->seq2, &class, &vers)) ) { - const char *algname; - if( vers != 1 || class != 31 ) - continue; - *algo = *(int*)sym; - algname = (*finfo)( *algo, npkey, nskey, nenc, nsig, use, - generate, check_secret_key, encryptf, - decryptf, sign, verify, get_nbits ); - if( algname ) { - ctx->r = r; - return algname; - } - } - ctx->seq2 = 0; - } - ctx->seq1 = 0; - } - ctx->r = r; - return NULL; -} - - -int (* -dynload_getfnc_gather_random())(void (*)(const void*, size_t, int), int, - size_t, int) -{ - EXTLIST r; - void *sym; - - for( r = extensions; r; r = r->next ) { - int seq, class, vers; - - if( r->failed ) - continue; - if( !r->handle && load_extension(r) ) - continue; - seq = 0; - while( (sym = (*r->enumfunc)(40, &seq, &class, &vers)) ) { - if( vers != 1 || class != 40 ) - continue; - return (int (*)(void (*)(const void*, size_t, int), int, - size_t, int))sym; - } - } - return NULL; + for (; el && el->name && seq; el = el->next, seq--) + ; + return el? el->name:NULL; } - - -void (* -dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int), int) -{ - EXTLIST r; - void *sym; - - for( r = extensions; r; r = r->next ) { - int seq, class, vers; - - if( r->failed ) - continue; - if( !r->handle && load_extension(r) ) - continue; - seq = 0; - while( (sym = (*r->enumfunc)(41, &seq, &class, &vers)) ) { - if( vers != 1 || class != 41 ) - continue; - return (void (*)( void (*)(const void*, size_t, int), int))sym; - } - } - return NULL; -} - diff --git a/cipher/idea-stub.c b/cipher/idea-stub.c new file mode 100644 index 000000000..3a9782037 --- /dev/null +++ b/cipher/idea-stub.c @@ -0,0 +1,187 @@ +/* idea-stub.c - Dummy module for the deprecated IDEA cipher. + * Copyright (C) 2002 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 + */ + +/* IDEA is a patented algorithm and therefore the use of IDEA in + countries where this patent is valid can not be allowed due to the + terms of the GNU General Public License. Those restrictions are + there to help protecting the freedom of software. For more + information on the nonsense of software patents and the general + problem with this, please see http://www.noepatents.org. + + However for research purposes and in certain situations it might be + useful to use this algorithm anyway. + + We provide this stub which will dynload a idea module and is only + used if the configure run did't found statically linked file. + See http://www.gnupg.org/why-not-dea.html for details. +*/ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#ifdef HAVE_DL_DLOPEN + #include <dlfcn.h> +#endif +#ifdef __MINGW32__ + #include <windows.h> +#endif +#include "util.h" +#include "algorithms.h" + +#ifndef RTLD_NOW + #define RTLD_NOW 1 +#endif + + +#ifdef __MINGW32__ +#define HAVE_DL_DLOPEN +#define USE_DYNAMIC_LINKING + +static int last_error = 0; + +void* +dlopen (const char *pathname, int mode) +{ + void *h = LoadLibrary (pathname); + if (!h) + { + log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError()); + last_error = 1; + return NULL; + } + return h; +} + +int +dlclose ( void *handle ) +{ + last_error = 0; + return FreeLibrary (handle); +} + +char* +dlerror (void) +{ + static char dlerrstr[10]; + if (last_error) + { + sprintf(dlerrstr, "%d", (int)GetLastError() ); + return dlerrstr; + } + return NULL; +} + +void* +dlsym ( void *handle, const char *name ) +{ + void *h = GetProcAddress (handle, name); + if (!h) + { + log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError()); + last_error = 1; + } + return h; +} +#endif /*__MINGW32__*/ + +/* We do only support dlopen and the Windows emulation of it. */ +#ifndef HAVE_DL_DLOPEN +#undef USE_DYNAMIC_LINKING +#endif + + +static void * +load_module (const char *name) +{ +#ifdef USE_DYNAMIC_LINKING + const char *err; + void *handle; + void *sym; + +#ifndef __MINGW32__ + /* Make sure we are not setuid. */ + if (getuid() != geteuid()) + log_bug("trying to load an extension while still setuid\n"); +#endif + + handle = dlopen (name, RTLD_NOW); + if (!name) + { + /*log_error ("error loading module `%s': %s\n", name, dlerror());*/ + goto failure; + } + + sym = dlsym (handle, "idea_get_info"); + if (dlerror ()) + sym = dlsym (handle, "_idea_get_info"); + if ((err=dlerror())) + { + log_info ("invalid module `%s': %s\n", name, err); + goto failure; + } + + return sym; + + failure: + if (handle) + dlclose (handle); +#endif /*USE_DYNAMIC_LINKING*/ + return NULL; +} + + +const char * +idea_get_info( int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**r_setkey)( void *c, byte *key, unsigned keylen ), + void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ), + void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf ) + ) +{ + static int initialized; + static const char * (*info_fnc)(int, size_t*, size_t*, size_t*, + int (**)( void *, byte *, unsigned), + void (**)( void *, byte *, byte *), + void (**)( void *, byte *, byte *)); + const char *rstr; + int i; + + if (!initialized) + { + initialized = 1; + for (i=0; (rstr = dynload_enum_module_names (i)); i++) + { + info_fnc = load_module (rstr); + if (info_fnc) + break; + } + } + if (!info_fnc) + return NULL; /* dynloadable module not found. */ + rstr = info_fnc (algo, keylen, blocksize, contextsize, + r_setkey, r_encrypt, r_decrypt); + if (rstr && *keylen == 128 && *blocksize == 8 + && *r_setkey && *r_encrypt && r_decrypt) + return rstr; + return NULL; +} + diff --git a/cipher/md.c b/cipher/md.c index 49728638b..85c1f5b2a 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -1,5 +1,5 @@ /* md.c - message digest dispatcher - * Copyright (C) 1998, 1999 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -27,9 +27,7 @@ #include "util.h" #include "cipher.h" #include "errors.h" -#include "dynload.h" -#include "rmd.h" - +#include "algorithms.h" /**************** * This structure is used for the list of available algorithms @@ -54,97 +52,63 @@ static struct md_digest_list_s *digest_list; static struct md_digest_list_s * -new_list_item( int algo, +new_list_item (int algo, const char *(*get_info)( int, size_t*,byte**, int*, int*, void (**)(void*), void (**)(void*,byte*,size_t), - void (**)(void*),byte *(**)(void*)) ) + void (**)(void*),byte *(**)(void*))) { - struct md_digest_list_s *r; - - r = m_alloc_clear( sizeof *r ); - r->algo = algo, - r->name = (*get_info)( algo, &r->contextsize, - &r->asnoid, &r->asnlen, &r->mdlen, - &r->init, &r->write, &r->final, &r->read ); - if( !r->name ) { - m_free(r); - r = NULL; + struct md_digest_list_s *r; + + r = m_alloc_clear (sizeof *r ); + r->algo = algo; + r->name = (*get_info)( algo, &r->contextsize, + &r->asnoid, &r->asnlen, &r->mdlen, + &r->init, &r->write, &r->final, &r->read ); + if (!r->name ) + { + m_free(r); + r = NULL; + } + if (r) + { + r->next = digest_list; + digest_list = r; } - return r; + return r; } -/**************** - * Try to load the modules with the requeste algorithm - * and return true if new modules are available - * If req_alog is -1 try to load all digest algorithms. +/* + Load all available hash algorithms and return true. Subsequent + calls will return 0. */ static int -load_digest_module( int req_algo ) +load_digest_module (void) { - static int initialized = 0; - static u32 checked_algos[256/32]; - static int checked_all = 0; - struct md_digest_list_s *r; - void *context = NULL; - int algo; - int any = 0; - const char *(*get_info)( int, size_t*,byte**, int*, int*, - void (**)(void*), - void (**)(void*,byte*,size_t), - void (**)(void*),byte *(**)(void*)); - - if( !initialized ) { - cipher_modules_constructor(); - initialized = 1; - } - algo = req_algo; - if( algo > 255 || !algo ) - return 0; /* algorithm number too high (does not fit into out bitmap)*/ - if( checked_all ) - return 0; /* already called with -1 */ - if( algo < 0 ) - checked_all = 1; - else if( (checked_algos[algo/32] & (1 << (algo%32))) ) - return 0; /* already checked and not found */ - else - checked_algos[algo/32] |= (1 << (algo%32)); - - while( enum_gnupgext_digests( &context, &algo, &get_info ) ) { - if( req_algo != -1 && algo != req_algo ) - continue; - for(r=digest_list; r; r = r->next ) - if( r->algo == algo ) - break; - if( r ) { - log_info("skipping digest %d: already loaded\n", algo ); - continue; - } - r = new_list_item( algo, get_info ); - if( ! r ) { - log_info("skipping digest %d: no name\n", algo ); - continue; - } - /* put it into the list */ - if( g10_opt_verbose > 1 ) - log_info("loaded digest %d\n", algo); - r->next = digest_list; - digest_list = r; - any = 1; - if( req_algo != -1 ) - break; - } - enum_gnupgext_digests( &context, NULL, NULL ); - return any; -} + static int initialized = 0; + if (initialized) + return 0; + initialized = 1; + + /* We load them in reverse order so that the most + frequently used are the first in the list. */ + new_list_item (DIGEST_ALGO_TIGER, tiger_get_info); + if (!new_list_item (DIGEST_ALGO_MD5, md5_get_info)) + BUG (); + if (!new_list_item (DIGEST_ALGO_RMD160, rmd160_get_info)) + BUG (); + if (!new_list_item (DIGEST_ALGO_SHA1, sha1_get_info)) + BUG (); + + return 1; +} /**************** - * Map a string to the digest algo - */ + * Map a string to the digest algo */ int string_to_digest_algo( const char *string ) { @@ -154,7 +118,7 @@ string_to_digest_algo( const char *string ) for(r = digest_list; r; r = r->next ) if( !ascii_strcasecmp( r->name, string ) ) return r->algo; - } while( !r && load_digest_module(-1) ); + } while( !r && load_digest_module () ); return 0; } @@ -171,7 +135,7 @@ digest_algo_to_string( int algo ) for(r = digest_list; r; r = r->next ) if( r->algo == algo ) return r->name; - } while( !r && load_digest_module( algo ) ); + } while( !r && load_digest_module () ); return NULL; } @@ -185,7 +149,7 @@ check_digest_algo( int algo ) for(r = digest_list; r; r = r->next ) if( r->algo == algo ) return 0; - } while( !r && load_digest_module(algo) ); + } while( !r && load_digest_module () ); return G10ERR_DIGEST_ALGO; } @@ -232,7 +196,7 @@ md_enable( MD_HANDLE h, int algo ) for(r = digest_list; r; r = r->next ) if( r->algo == algo ) break; - } while( !r && load_digest_module( algo ) ); + } while( !r && load_digest_module () ); if( !r ) { log_error("md_enable: algorithm %d not available\n", algo ); return; @@ -457,7 +421,7 @@ md_digest_length( int algo ) if( r->algo == algo ) return r->mdlen; } - } while( !r && load_digest_module( algo ) ); + } while( !r && load_digest_module () ); log_error("WARNING: no length for md algo %d\n", algo); return 0; } @@ -480,7 +444,7 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ) return r->asnoid; } } - } while( !r && load_digest_module( algo ) ); + } while( !r && load_digest_module () ); log_bug("no asn for md algo %d\n", algo); return NULL; } @@ -512,13 +476,13 @@ md_stop_debug( MD_HANDLE md ) fclose(md->debug); md->debug = NULL; } - #ifdef HAVE_U64_TYPEDEF +#ifdef HAVE_U64_TYPEDEF { /* a kludge to pull in the __muldi3 for Solaris */ volatile u32 a = (u32)(ulong)md; volatile u64 b = 42; volatile u64 c; c = a * b; } - #endif +#endif } diff --git a/cipher/md5.c b/cipher/md5.c index ef6886eb4..ca605b6fd 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -36,7 +36,7 @@ #include <assert.h> #include "util.h" #include "memory.h" -#include "dynload.h" +#include "algorithms.h" #include "bithelp.h" @@ -337,7 +337,7 @@ md5_read( MD5_CONTEXT *hd ) * Returns: A pointer to string describing the algorithm or NULL if * the ALGO is invalid. */ -static const char * +const char * md5_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asnlen, int *r_mdlen, void (**r_init)( void *c ), @@ -365,63 +365,3 @@ md5_get_info( int algo, size_t *contextsize, return "MD5"; } - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "MD5 ($Revision$)"; - -static struct { - int class; - int version; - int value; - void (*func)(void); -} func_table[] = { - { 10, 1, 0, (void(*)(void))md5_get_info }, - { 11, 1, 1 }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if( i >= DIM(func_table) || i < 0 ) - return NULL; - *class = func_table[i].class; - *vers = func_table[i].version; - switch( *class ) { - case 11: case 21: case 31: ret = &func_table[i].value; break; -#ifndef __riscos__ - default: ret = func_table[i].func; break; -#else /* __riscos__ */ - default: ret = (void *) func_table[i].func; break; -#endif /* __riscos__ */ - } - i++; - } while( what && what != *class ); - - *sequence = i; - return ret; -} - - - - -#ifndef IS_MODULE -void -md5_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func ); -} -#endif - - - -/* end of file */ diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 9136fa544..853c518be 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -31,8 +31,6 @@ #include "elgamal.h" #include "dsa.h" #include "rsa.h" -#include "dynload.h" - #define TABLE_SIZE 10 @@ -58,6 +56,7 @@ static struct pubkey_table_s pubkey_table[TABLE_SIZE]; static int disabled_algos[TABLE_SIZE]; +#if 0 static int dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) { log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } @@ -65,6 +64,7 @@ dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) static int dummy_check_secret_key( int algo, MPI *skey ) { log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +#endif static int dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) @@ -83,10 +83,11 @@ dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey, int (*cmp)(void *, MPI), void *opaquev ) { log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +#if 0 static unsigned dummy_get_nbits( int algo, MPI *pkey ) { log_bug("no get_nbits() for %d\n", algo ); return 0; } - +#endif /**************** * Put the static entries into the table. @@ -215,73 +216,13 @@ static int load_pubkey_modules(void) { static int initialized = 0; - static int done = 0; - void *context = NULL; - struct pubkey_table_s *ct; - int ct_idx; - int i; - const char *name; - int any = 0; - if( !initialized ) { - cipher_modules_constructor(); setup_pubkey_table(); initialized = 1; return 1; } - if( done ) - return 0; - done = 1; - for(ct_idx=0, ct = pubkey_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) { - if( !ct->name ) - break; - } - if( ct_idx >= TABLE_SIZE-1 ) - BUG(); /* table already full */ - /* now load all extensions */ - while( (name = enum_gnupgext_pubkeys( &context, &ct->algo, - &ct->npkey, &ct->nskey, &ct->nenc, - &ct->nsig, &ct->use, - &ct->generate, - &ct->check_secret_key, - &ct->encrypt, - &ct->decrypt, - &ct->sign, - &ct->verify, - &ct->get_nbits )) ) { - for(i=0; pubkey_table[i].name; i++ ) - if( pubkey_table[i].algo == ct->algo ) - break; - if( pubkey_table[i].name ) { - log_info("skipping pubkey %d: already loaded\n", ct->algo ); - continue; - } - - if( !ct->generate ) ct->generate = dummy_generate; - if( !ct->check_secret_key ) ct->check_secret_key = - dummy_check_secret_key; - if( !ct->encrypt ) ct->encrypt = dummy_encrypt; - if( !ct->decrypt ) ct->decrypt = dummy_decrypt; - if( !ct->sign ) ct->sign = dummy_sign; - if( !ct->verify ) ct->verify = dummy_verify; - if( !ct->get_nbits ) ct->get_nbits= dummy_get_nbits; - /* put it into the table */ - if( g10_opt_verbose > 1 ) - log_info("loaded pubkey %d (%s)\n", ct->algo, name); - ct->name = name; - ct_idx++; - ct++; - any = 1; - /* check whether there are more available table slots */ - if( ct_idx >= TABLE_SIZE-1 ) { - log_info("pubkey table full; ignoring other extensions\n"); - break; - } - } - enum_gnupgext_pubkeys( &context, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL ); - return any; + return 0; } diff --git a/cipher/rand-internal.h b/cipher/rand-internal.h index 6f5b52bae..eb81174f8 100644 --- a/cipher/rand-internal.h +++ b/cipher/rand-internal.h @@ -20,12 +20,16 @@ #ifndef G10_RAND_INTERNAL_H #define G10_RAND_INTERNAL_H -void rndlinux_constructor(void); -void rndunix_constructor(void); -void rndw32_constructor(void); -void rndos2_constructor(void); -void rndatari_constructor(void); -void rndmvs_constructor(void); -void rndriscos_constructor(void); +int rndunix_gather_random (void (*add)(const void*, size_t, int), + int requester, size_t length, int level); +int rndlinux_gather_random (void (*add)(const void*, size_t, int), + int requester, size_t length, int level); +int rndegd_gather_random (void (*add)(const void*, size_t, int), + int requester, size_t length, int level ); +int rndw32_gather_random (void (*add)(const void*, size_t, int), + int requester, size_t length, int level); +int rndw32_gather_random_fast (void (*add)(const void*, size_t, int), + int requester ); + #endif /*G10_RAND_INTERNAL_H*/ diff --git a/cipher/random.c b/cipher/random.c index 2c958d9d4..1d7bf8a93 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -1,5 +1,5 @@ /* random.c - random number generator - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -56,8 +56,7 @@ #include "i18n.h" #include "random.h" #include "rand-internal.h" -#include "dynload.h" - +#include "algorithms.h" #ifndef RAND_MAX /* for SunOS */ #define RAND_MAX 32767 @@ -125,6 +124,37 @@ static struct { ulong naddbytes; } rndstats; + +static int (* +getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, + size_t, int) +{ +#ifdef USE_RNDLINUX + return rndlinux_gather_random; +#endif +#ifdef USE_RNDUNIX + return rndunix_gather_random; +#endif +#ifdef USE_RNDEGD + return rndegd_gather_random; +#endif +#ifdef USE_RNDW32 + return rndw32_gather_random; +#endif + return NULL; +} + +static void (* +getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int) +{ +#ifdef USE_RNDW32 + return rndw32_gather_random_fast; +#endif + return NULL; +} + + + static void initialize(void) { @@ -136,7 +166,6 @@ initialize(void) keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN) : m_alloc_clear(POOLSIZE+BLOCKLEN); is_initialized = 1; - cipher_modules_constructor(); } static void @@ -560,7 +589,7 @@ fast_random_poll() if( !is_initialized ) initialize(); initialized = 1; - fnc = dynload_getfnc_fast_random_poll(); + fnc = getfnc_fast_random_poll(); } if( fnc ) { (*fnc)( add_randomness, 1 ); @@ -637,7 +666,7 @@ read_random_source( int requester, size_t length, int level ) if( !fnc ) { if( !is_initialized ) initialize(); - fnc = dynload_getfnc_gather_random(); + fnc = getfnc_gather_random(); if( !fnc ) { faked_rng = 1; fnc = gather_faked; @@ -685,3 +714,4 @@ gather_faked( void (*add)(const void*, size_t, int), int requester, return 0; /* okay */ } + diff --git a/cipher/rmd160.c b/cipher/rmd160.c index e35647af6..54dec6a15 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -26,8 +26,8 @@ #include "util.h" #include "memory.h" #include "rmd.h" -#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */ -#include "dynload.h" +#include "cipher.h" /* for rmd160_hash_buffer */ +#include "algorithms.h" #include "bithelp.h" @@ -558,7 +558,7 @@ rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length ) * Returns: A pointer to string describing the algorithm or NULL if * the ALGO is invalid. */ -static const char * +const char * rmd160_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asnlen, int *r_mdlen, void (**r_init)( void *c ), @@ -586,67 +586,3 @@ rmd160_get_info( int algo, size_t *contextsize, return "RIPEMD160"; } - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RMD160 ($Revision$)"; - -static struct { - int class; - int version; - int value; - void (*func)(void); -} func_table[] = { - { 10, 1, 0, (void(*)(void))rmd160_get_info }, - { 11, 1, 3 }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - switch( *class ) { - case 11: - case 21: - case 31: - ret = &func_table[i].value; - break; - default: -#ifndef __riscos__ - ret = func_table[i].func; -#else /* __riscos__ */ - ret = (void *) func_table[i].func; -#endif /* __riscos__ */ - break; - } - i++; - } while( what && what != *class ); - - *sequence = i; - return ret; -} - - - - -#ifndef IS_MODULE -void -rmd160_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func ); -} -#endif - diff --git a/cipher/rndegd.c b/cipher/rndegd.c index 64226eabb..7503ab464 100644 --- a/cipher/rndegd.c +++ b/cipher/rndegd.c @@ -1,5 +1,5 @@ /* rndegd.c - interface to the EGD - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -19,6 +19,9 @@ */ #include <config.h> + +#ifdef USE_RNDEG + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -33,14 +36,10 @@ #include "types.h" #include "util.h" #include "ttyio.h" -#include "dynload.h" +#include "algorithms.h" #include "cipher.h" +#include "i18n.h" -#ifdef IS_MODULE - #define _(a) (a) -#else - #include "i18n.h" -#endif #ifndef offsetof #define offsetof(type, member) ((size_t) &((type *)0)->member) @@ -76,6 +75,11 @@ do_read( int fd, void *buf, size_t nbytes ) } while( n == -1 && errno == EINTR ); if( n == -1 ) return -1; + else if( n == 0 ) { + /* EGD probably died. */ + errno = ECONNRESET; + return -1; + } nread += n; } while( nread < nbytes ); return nbytes; @@ -91,8 +95,8 @@ do_read( int fd, void *buf, size_t nbytes ) * 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, +int +rndegd_gather_random( void (*add)(const void*, size_t, int), int requester, size_t length, int level ) { static int fd = -1; @@ -175,11 +179,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester, } if( length ) { - #ifdef IS_MODULE - fprintf( stderr, - #else tty_printf( - #endif _("Please wait, entropy is being gathered. Do some work if it would\n" "keep you from getting bored, because it will improve the quality\n" "of the entropy.\n") ); @@ -205,51 +205,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester, return 0; /* success */ } - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RNDEGD ($Revision$)"; - -static struct { - int class; - int version; - int (*func)(void); -} func_table[] = { - { 40, 1, (int (*)(void))gather_random }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if ( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - ret = func_table[i].func; - i++; - } while ( what && what != *class ); - - *sequence = i; - return ret; -} - -#ifndef IS_MODULE -void -rndegd_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); -} -#endif - +#endif /*USE_RNDEGD*/ diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c index 0b138fcda..c31b7f71c 100644 --- a/cipher/rndlinux.c +++ b/cipher/rndlinux.c @@ -20,6 +20,9 @@ #include <config.h> + +#ifdef USE_RNDLINUX + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -41,17 +44,12 @@ #include "types.h" #include "util.h" #include "ttyio.h" -#include "dynload.h" +#include "algorithms.h" -#ifdef IS_MODULE - #define _(a) (a) -#else - #include "i18n.h" -#endif +#include "i18n.h" static int open_device( const char *name, int minor ); -static int gather_random( void (*add)(const void*, size_t, int), int requester, - size_t length, int level ); + #if 0 #ifdef HAVE_DEV_RANDOM_IOCTL @@ -92,8 +90,8 @@ open_device( const char *name, int minor ) * Note: Using a level of 0 should never block and better add nothing * to the pool. This is easy to accomplish with /dev/urandom. */ -static int -gather_random( void (*add)(const void*, size_t, int), int requester, +int +rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester, size_t length, int level ) { static int fd_urandom = -1; @@ -132,11 +130,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester, tv.tv_usec = 0; if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) { if( !warn ) - #ifdef IS_MODULE - fprintf(stderr, - #else tty_printf( - #endif _("\n" "Not enough random bytes available. Please do some other work to give\n" "the OS a chance to collect more entropy! (Need %d more bytes)\n"), (int)length ); @@ -144,11 +138,7 @@ _("\n" continue; } else if( rc == -1 ) { - #ifdef IS_MODULE - fprintf(stderr, - #else tty_printf( - #endif "select() error: %s\n", strerror(errno)); continue; } @@ -171,70 +161,4 @@ _("\n" return 0; /* success */ } - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RNDLINUX ($Revision$)"; - -static struct { - int class; - int version; - int (*func)(void); -} func_table[] = { - { 40, 1, (int (*)(void))gather_random }, -}; - - - -/**************** - * Enumerate the names of the functions together with informations about - * this function. Set sequence to an integer with a initial value of 0 and - * do not change it. - * If what is 0 all kind of functions are returned. - * Return values: class := class of function: - * 10 = message digest algorithm info function - * 11 = integer with available md algorithms - * 20 = cipher algorithm info function - * 21 = integer with available cipher algorithms - * 30 = public key algorithm info function - * 31 = integer with available pubkey algorithms - * 40 = get gather_random function - * 41 = get fast_random_poll function - * version = interface version of the function/pointer - * (currently this is 1 for all functions) - */ - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if ( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - ret = func_table[i].func; - i++; - } while ( what && what != *class ); - - *sequence = i; - return ret; -} - -#ifndef IS_MODULE -void -rndlinux_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); -} -#endif - +#endif /*USE_RNDLINUX*/ diff --git a/cipher/rndunix.c b/cipher/rndunix.c index a46b5ec97..c8d140efe 100644 --- a/cipher/rndunix.c +++ b/cipher/rndunix.c @@ -48,6 +48,9 @@ /* General includes */ #include <config.h> + +#ifdef USE_RNDUNIX + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -768,9 +771,9 @@ 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 ) +int +rndunix_gather_random( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static pid_t gatherer_pid = 0; static int pipedes[2]; @@ -846,70 +849,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester, return 0; } - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RNDUNIX ($Revision$)"; - - -static struct { - int class; - int version; - int (*func)(void); -} func_table[] = { - { 40, 1, (int (*)(void))gather_random }, -}; - -/**************** - * Enumerate the names of the functions together with informations about - * this function. Set sequence to an integer with a initial value of 0 and - * do not change it. - * If what is 0 all kind of functions are returned. - * Return values: class := class of function: - * 10 = message digest algorithm info function - * 11 = integer with available md algorithms - * 20 = cipher algorithm info function - * 21 = integer with available cipher algorithms - * 30 = public key algorithm info function - * 31 = integer with available pubkey algorithms - * 40 = get read_random_source() function - * 41 = get fast_random_poll function - * version = interface version of the function/pointer - * (currently this is 1 for all functions) - */ - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if ( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - ret = func_table[i].func; - i++; - } while ( what && what != *class ); - - *sequence = i; - return ret; -} - -#ifndef IS_MODULE -void -rndunix_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); -} -#endif - - +#endif /*USE_RNDUNIX*/ diff --git a/cipher/rndw32.c b/cipher/rndw32.c index f58d45866..87aa20878 100644 --- a/cipher/rndw32.c +++ b/cipher/rndw32.c @@ -1,5 +1,5 @@ /* rndw32.c - W32 entropy gatherer - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999 * * This file is part of GnuPG. @@ -60,6 +60,9 @@ */ #include <config.h> + +#ifdef USE_RNDW32 + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -74,230 +77,13 @@ #include "types.h" #include "util.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*/ +#include "algorithms.h" - - -#ifdef IS_MODULE - #define _(a) (a) -#else - #include "i18n.h" -#endif +#include "i18n.h" static int debug_me; -#ifdef USE_ENTROPY_DLL - -#define WIN32_SLOW_SEEDER 0 -#define WIN32_FAST_SEEDER 1 - -#define PCP_SUCCESS 0 -#define PCP_NULL_POINTER 1 -#define PCP_SEEDER_FAILED 2 -#define PCP_SEEDER_NO_MEM 3 -#define PCP_SEEDER_TOO_SMALL 4 -#define PCP_DLL_LOAD_FAILED 5 -#define PCP_UNKNOWN_PLATFORM 6 -#define PCP_ERROR_VERSION 7 -#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); -static void (WINAPI *delete_instance)( WIN32_SEEDER that ); -static unsigned int (WINAPI *get_internal_seed_size)( WIN32_SEEDER that ); -static void (WINAPI *set_internal_seed_size)( WIN32_SEEDER that, - unsigned int new_size); -static unsigned int (WINAPI *get_expected_seed_size)( WIN32_SEEDER that); -static unsigned int (WINAPI *get_seed)( WIN32_SEEDER that, byte *buffer, - unsigned int *desired_length); - -static WIN32_SEEDER slow_seeder, fast_seeder; -static byte *entropy_buffer; -static size_t entropy_buffer_size; - -/**************** - * Load and initialize the winseed DLL - * NOTE: winseed is not part of the GnuPG distribution. It should be available - * at the GNU crypto FTP server site. - * We do not load the DLL on demand to have a better control over the - * location of the library. - */ -static void -load_and_init_winseed( void ) -{ - HANDLE hInstance; - void *addr; - unsigned int reason = 0; - unsigned int n1, n2; - 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 ) - goto failure; - if( !(addr = GetProcAddress( hInstance, "WS_create_instance" )) ) - goto failure; - create_instance = addr; - if( !(addr = GetProcAddress( hInstance, "WS_delete_instance" )) ) - goto failure; - delete_instance = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_internal_seed_size" )) ) - goto failure; - get_internal_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_set_internal_seed_size" )) ) - goto failure; - set_internal_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_expected_seed_size" )) ) - goto failure; - get_expected_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_seed" )) ) - goto failure; - get_seed = addr; - - /* we have all the functions - init the system */ - slow_seeder = create_instance( WIN32_SLOW_SEEDER, &reason); - if( !slow_seeder ) { - g10_log_fatal("error creating winseed slow seeder: rc=%u\n", reason ); - goto failure; - } - fast_seeder = create_instance( WIN32_FAST_SEEDER, &reason); - if( !fast_seeder ) { - g10_log_fatal("error creating winseed fast seeder: rc=%u\n", reason ); - goto failure; - } - n1 = get_internal_seed_size( slow_seeder ); - /*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);*/ - - entropy_buffer_size = n1 > n2? n1: n2; - entropy_buffer = m_alloc( entropy_buffer_size ); - /*g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );*/ - - return; - - failure: - g10_log_fatal("error loading winseed DLL `%s'\n", dllname ); -} - - - - - -/* Note: we always use the highest level. - * TO boost the performance we may want to add some - * additional code for level 1 - */ -static int -gather_random( void (*add)(const void*, size_t, int), int requester, - size_t length, int level ) -{ - 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 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. - */ - if( level > 1 ) - length *= 100; - else if( level > 0 ) - length *= 10; - - 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 );*/ - (*add)( entropy_buffer, nbytes, requester ); - if( length <= nbytes ) - return 0; /* okay */ - length -= nbytes; - } -} - -static int -gather_random_fast( void (*add)(const void*, size_t, int), int requester ) -{ - unsigned int result; - unsigned int nbytes; - - if( !fast_seeder ) - load_and_init_winseed(); - - /* winseed delivers a constant ammount of entropy for a fast - * poll. We can simply use this and add it to the pool; no need - * a loop like it is used in the slow poll */ - nbytes = entropy_buffer_size; - result = get_seed( fast_seeder, entropy_buffer, &nbytes); - if( result ) { - g10_log_fatal("rndw32: get_seed(fast) failed: rc=%u\n", result); - return -1; /* actually never reached */ - } - /*g10_log_info("rndw32: fast poll got %u\n", (unsigned int)nbytes );*/ - (*add)( entropy_buffer, nbytes, 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 */ @@ -731,9 +517,9 @@ slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester ) } -static int -gather_random( void (*add)(const void*, size_t, int), int requester, - size_t length, int level ) +int +rndw32_gather_random (void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static int is_initialized; static int is_windowsNT, has_toolhelp; @@ -783,8 +569,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester, -static int -gather_random_fast( void (*add)(const void*, size_t, int), int requester ) +int +rndw32_gather_random_fast( void (*add)(const void*, size_t, int), int requester ) { static int addedFixedItems = 0; @@ -915,58 +701,4 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester ) } - - - -#endif /* !USE_ENTROPY_DLL */ - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RNDW32 ($Revision$)"; - -static struct { - int class; - int version; - void *func; -} func_table[] = { - { 40, 1, gather_random }, - { 41, 1, gather_random_fast }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -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; - } - *class = func_table[i].class; - *vers = func_table[i].version; - ret = func_table[i].func; - i++; - } while ( what && what != *class ); - - *sequence = i; - return ret; -} - -#ifndef IS_MODULE -void -rndw32_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); -} -#endif - +#endif /*USE_RNDW32*/ diff --git a/cipher/sha1.c b/cipher/sha1.c index 77749e4ee..06ca2532b 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -38,7 +38,7 @@ #include <assert.h> #include "util.h" #include "memory.h" -#include "dynload.h" +#include "algorithms.h" #include "bithelp.h" @@ -331,7 +331,7 @@ sha1_read( SHA1_CONTEXT *hd ) * Returns: A pointer to string describing the algorithm or NULL if * the ALGO is invalid. */ -static const char * +const char * sha1_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asnlen, int *r_mdlen, void (**r_init)( void *c ), @@ -357,69 +357,3 @@ sha1_get_info( int algo, size_t *contextsize, return "SHA1"; } - - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "SHA1 ($Revision$)"; - -static struct { - int class; - int version; - int value; - void (*func)(void); -} func_table[] = { - { 10, 1, 0, (void(*)(void))sha1_get_info }, - { 11, 1, 2 }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - switch( *class ) { - case 11: - case 21: - case 31: - ret = &func_table[i].value; - break; - default: -#ifndef __riscos__ - ret = func_table[i].func; -#else /* __riscos__ */ - ret = (void *) func_table[i].func; -#endif /* __riscos__ */ - break; - } - i++; - } while( what && what != *class ); - - *sequence = i; - return ret; -} - - - - -#ifndef IS_MODULE -void -sha1_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func ); -} -#endif - diff --git a/cipher/tiger.c b/cipher/tiger.c index 6da715d48..b5e8a8aad 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -25,7 +25,7 @@ #include <assert.h> #include "util.h" #include "memory.h" - +#include "algorithms.h" #ifdef HAVE_U64_TYPEDEF @@ -879,13 +879,15 @@ tiger_read( TIGER_CONTEXT *hd ) return hd->buf; } +#endif /*HAVE_U64_TYPEDEF*/ + /**************** * 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. */ -static const char * +const char * tiger_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asnlen, int *r_mdlen, void (**r_init)( void *c ), @@ -894,6 +896,7 @@ tiger_get_info( int algo, size_t *contextsize, byte *(**r_read)( void *c ) ) { +#ifdef HAVE_U64_TYPEDEF /* 40: SEQUENCE { * 12: SEQUENCE { * 8: OCTET STRING :54 49 47 45 52 31 39 32 @@ -904,6 +907,7 @@ tiger_get_info( int algo, size_t *contextsize, * * By replacing the 5th byte (0x04) with 0x16 we would have; * 8: IA5String 'TIGER192' + * Fixme: We should use a registered OID. */ static byte asn[18] = { 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47, @@ -922,87 +926,7 @@ tiger_get_info( int algo, size_t *contextsize, *(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read; return "TIGER192"; -} - - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "TIGER ($Revision$)"; - -static struct { - int class; - int version; - int value; - void (*func)(void); -} func_table[] = { - { 10, 1, 0, (void(*)(void))tiger_get_info }, - { 11, 1, 6 }, -}; - - - -/**************** - * Enumerate the names of the functions together with informations about - * this function. Set sequence to an integer with a initial value of 0 and - * do not change it. - * If what is 0 all kind of functions are returned. - * Return values: class := class of function: - * 10 = message digest algorithm info function - * 11 = integer with available md algorithms - * 20 = cipher algorithm info function - * 21 = integer with available cipher algorithms - * 30 = public key algorithm info function - * 31 = integer with available pubkey algorithms - * version = interface version of the function/pointer - * (currently this is 1 for all functions) - */ -#ifndef IS_MODULE -static +#else /*!HAVE_U64_TYPEDEF*/ + return NULL; /* Alorithm not available. */ #endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - do { - if( i >= DIM(func_table) || i < 0 ) { - /*fprintf(stderr, "failed\n");*/ - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - switch( *class ) { - case 11: - case 21: - case 31: - ret = &func_table[i].value; - break; - default: - ret = func_table[i].func; - break; - } - i++; - } while( what && what != *class ); - - *sequence = i; - /*fprintf(stderr, "success\n");*/ - return ret; -} - - - -#ifndef IS_MODULE -void -tiger_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); } -#endif - - -#endif /* HAVE_U64_TYPEDEF */ - |