1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-31 22:18:03 +02:00

The big extension module removal.

This commit is contained in:
Werner Koch 2002-08-03 10:50:53 +00:00
parent 14d050a272
commit 85aa3e18c2
28 changed files with 574 additions and 1880 deletions

View File

@ -1,3 +1,9 @@
2002-08-02 Werner Koch <wk@gnupg.org>
* configure.ac: Removed all extension stuff but keep the tests for
dlopen. We don't need to figure out the flags required. All
stuff is now statically loaded.
2002-07-30 David Shaw <dshaw@jabberwocky.com> 2002-07-30 David Shaw <dshaw@jabberwocky.com>
* README, configure.ac: --with-exec-path is now clarified into * README, configure.ac: --with-exec-path is now clarified into

4
NEWS
View File

@ -1,6 +1,10 @@
Noteworthy changes in version 1.1.91 Noteworthy changes in version 1.1.91
------------------------------------------------- -------------------------------------------------
* All modules are now linked statically; the --load-extension
option is in general not useful anymore. The only exception is
to specify the deprecated idea cipher.
* When using --batch with one of the --delete-key commands, the * When using --batch with one of the --delete-key commands, the
key must be specified by fingerprint. See the man page for key must be specified by fingerprint. See the man page for
details. details.

7
README
View File

@ -460,7 +460,7 @@
--enable-static-rnd=<name> --enable-static-rnd=<name>
Force the use of the random byte gathering Force the use of the random byte gathering
module <name>. Default is either to use /dev/random module <name>. Default is either to use /dev/random
or the standard Uix module. Value for name: or the standard Unix module. Value for name:
egd - Use the module which accesses the egd - Use the module which accesses the
Entropy Gathering Daemon. See the webpages Entropy Gathering Daemon. See the webpages
for more information about it. for more information about it.
@ -469,8 +469,6 @@
linux - Use the module which accesses /dev/random. linux - Use the module which accesses /dev/random.
This is the first choice and the default one This is the first choice and the default one
for GNU/Linux or *BSD. for GNU/Linux or *BSD.
none - Do not linkl any module in but rely on
a dynmically loaded modules.
--with-egd-socket=<name> --with-egd-socket=<name>
This is only used when EGD is used as random This is only used when EGD is used as random
@ -501,7 +499,8 @@
--disable-dynload --disable-dynload
If you have problems with dynamic loading, this If you have problems with dynamic loading, this
option disables all dynamic loading stuff. option disables all dynamic loading stuff. Note
that the use of dynamic linking is very limited.
--disable-asm --disable-asm
Do not use assembler modules. It is not possible Do not use assembler modules. It is not possible

1
THANKS
View File

@ -23,6 +23,7 @@ Cees van de Griend cees-list@griend.xs4all.nl
Charles Levert charles@comm.polymtl.ca Charles Levert charles@comm.polymtl.ca
Chip Salzenberg chip@valinux.com Chip Salzenberg chip@valinux.com
Chris Adams cmadams@hiwaay.net Chris Adams cmadams@hiwaay.net
Christian Biere christianbiere@gmx.de
Christian Kurz shorty@debian.org Christian Kurz shorty@debian.org
Christian von Roques roques@pond.sub.org Christian von Roques roques@pond.sub.org
Christopher Oliver oliver@fritz.traverse.net Christopher Oliver oliver@fritz.traverse.net

View File

@ -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> 2002-07-25 David Shaw <dshaw@jabberwocky.com>
* random.c: "warning" -> "WARNING" * random.c: "warning" -> "WARNING"

View File

@ -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. # This file is part of GnuPG.
# #
@ -18,39 +18,14 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl
noinst_LIBRARIES = libcipher.a 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 \ libcipher_a_SOURCES = cipher.c \
pubkey.c \ pubkey.c \
md.c \ md.c \
dynload.c \ dynload.c \
dynload.h \
bithelp.h \ bithelp.h \
des.c \ des.c \
des.h \ des.h \
@ -72,43 +47,22 @@ libcipher_a_SOURCES = cipher.c \
dsa.c \ dsa.c \
g10c.c \ g10c.c \
smallprime.c \ smallprime.c \
construct.c algorithms.h \
rndlinux.c \
rndunix.c \
rndegd.c \
rndw32.c \
md5.c \
rmd160.c \
sha1.c \
tiger.c
# configure creates the constructor file EXTRA_libcipher_a_SOURCES = idea-stub.c
BUILT_SOURCES = construct.c
DISTCLEANFILES = construct.c
libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@ libcipher_a_DEPENDENCIES = @IDEA_O@
libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@ libcipher_a_LIBADD = @IDEA_O@
# 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' `
tiger.o: $(srcdir)/tiger.c tiger.o: $(srcdir)/tiger.c
`echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' ` `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

66
cipher/algorithms.h Normal file
View File

@ -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*/

View File

@ -41,7 +41,7 @@ twofish_get_info( int algo, size_t *keylen,
void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) 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 */ * stuff to the scheme we use for random and digests */
const char * const char *
rijndael_get_info( int algo, size_t *keylen, 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 ) 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*/ #endif /*G10_BLOWFISH_H*/

View File

@ -1,5 +1,5 @@
/* cipher.c - cipher dispatcher /* 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. * This file is part of GnuPG.
* *
@ -30,7 +30,6 @@
#include "des.h" #include "des.h"
#include "blowfish.h" #include "blowfish.h"
#include "cast5.h" #include "cast5.h"
#include "dynload.h"
#define MAX_BLOCKSIZE 16 #define MAX_BLOCKSIZE 16
@ -162,6 +161,16 @@ setup_cipher_table(void)
if( !cipher_table[i].name ) if( !cipher_table[i].name )
BUG(); BUG();
i++; 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 #ifdef IS_DEVELOPMENT_VERSION
cipher_table[i].algo = CIPHER_ALGO_DUMMY; cipher_table[i].algo = CIPHER_ALGO_DUMMY;
@ -186,63 +195,15 @@ setup_cipher_table(void)
static int static int
load_cipher_modules(void) load_cipher_modules(void)
{ {
static int done = 0;
static int initialized = 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 ) { if (!initialized )
cipher_modules_constructor(); {
setup_cipher_table(); /* load static modules on the first call */ setup_cipher_table(); /* load static modules on the first call */
initialized = 1; initialized = 1;
return 1; return 1;
} }
if( done )
return 0; 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;
}
}
enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL,
NULL, NULL, NULL );
return any;
} }

View File

@ -1,5 +1,5 @@
/* dynload.c - load cipher extensions /* 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. * This file is part of GnuPG.
* *
@ -23,139 +23,22 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.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 "util.h"
#include "cipher.h" #include "cipher.h"
#include "dynload.h" #include "algorithms.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__*/
typedef struct ext_list { typedef struct ext_list {
struct ext_list *next; 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]; char name[1];
} *EXTLIST; } *EXTLIST;
static EXTLIST extensions; static EXTLIST extensions;
typedef struct { /* This is actually not used anymore but we keep a list of already
EXTLIST r; * set extensions modules here.
int seq1; *
int seq2; * Here is the ancient comment:
void *sym;
int reqalgo;
} ENUMCONTEXT;
#ifdef HAVE_DLD_DLD_LINK
static char *mainpgm_path;
static int did_dld_init;
static int dld_available;
#endif
/****************
* Register an extension module. The last registered module will * Register an extension module. The last registered module will
* be loaded first. A name may have a list of classes * be loaded first. A name may have a list of classes
* appended; e.g: * appended; e.g:
@ -174,10 +57,6 @@ register_cipher_extension( const char *mainpgm, const char *fname )
EXTLIST r, el, intex; EXTLIST r, el, intex;
char *p, *pe; 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 */ if( *fname != DIRSEP_C ) { /* do tilde expansion etc */
char *tmp; char *tmp;
@ -194,12 +73,8 @@ register_cipher_extension( const char *mainpgm, const char *fname )
strcpy(el->name, fname ); strcpy(el->name, fname );
} }
/* check whether we have a class hint */ /* 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; *p = *pe = 0;
el->hintstr = p+1;
}
else
el->hintstr = NULL;
/* check that it is not already registered */ /* check that it is not already registered */
intex = NULL; intex = NULL;
@ -209,473 +84,20 @@ register_cipher_extension( const char *mainpgm, const char *fname )
m_free(el); m_free(el);
return; return;
} }
else if( r->internal )
intex = r;
} }
/* and register */ /* 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; el->next = extensions;
extensions = el; extensions = el;
} }
/* Return the module name with index SEQ, return NULL as as indication
static int for end of list. */
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__ */
const char * const char *
enum_gnupgext_ciphers( void **enum_context, int *algo, dynload_enum_module_names (int seq)
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 )
)
{ {
EXTLIST r; EXTLIST el = extensions;
ENUMCONTEXT *ctx;
const char * (*finfo)(int, size_t*, size_t*, size_t*,
int (**)( void *, byte *, unsigned),
void (**)( void *, byte *, byte *),
void (**)( void *, byte *, byte *));
if( !*enum_context ) { /* init context */ for (; el && el->name && seq; el = el->next, seq--)
ctx = m_alloc_clear( sizeof( *ctx ) ); ;
ctx->r = extensions; return el? el->name:NULL;
*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;
}
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;
}

187
cipher/idea-stub.c Normal file
View File

@ -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;
}

View File

@ -1,5 +1,5 @@
/* md.c - message digest dispatcher /* 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. * This file is part of GnuPG.
* *
@ -27,9 +27,7 @@
#include "util.h" #include "util.h"
#include "cipher.h" #include "cipher.h"
#include "errors.h" #include "errors.h"
#include "dynload.h" #include "algorithms.h"
#include "rmd.h"
/**************** /****************
* This structure is used for the list of available algorithms * This structure is used for the list of available algorithms
@ -63,88 +61,54 @@ new_list_item( int algo,
struct md_digest_list_s *r; struct md_digest_list_s *r;
r = m_alloc_clear (sizeof *r ); r = m_alloc_clear (sizeof *r );
r->algo = algo, r->algo = algo;
r->name = (*get_info)( algo, &r->contextsize, r->name = (*get_info)( algo, &r->contextsize,
&r->asnoid, &r->asnlen, &r->mdlen, &r->asnoid, &r->asnlen, &r->mdlen,
&r->init, &r->write, &r->final, &r->read ); &r->init, &r->write, &r->final, &r->read );
if( !r->name ) { if (!r->name )
{
m_free(r); m_free(r);
r = NULL; r = NULL;
} }
if (r)
{
r->next = digest_list;
digest_list = r;
}
return r; return r;
} }
/**************** /*
* Try to load the modules with the requeste algorithm Load all available hash algorithms and return true. Subsequent
* and return true if new modules are available calls will return 0.
* If req_alog is -1 try to load all digest algorithms.
*/ */
static int static int
load_digest_module( int req_algo ) load_digest_module (void)
{ {
static int initialized = 0; 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 ) { if (initialized)
cipher_modules_constructor(); return 0;
initialized = 1; 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 ) ) { /* We load them in reverse order so that the most
if( req_algo != -1 && algo != req_algo ) frequently used are the first in the list. */
continue; new_list_item (DIGEST_ALGO_TIGER, tiger_get_info);
for(r=digest_list; r; r = r->next ) if (!new_list_item (DIGEST_ALGO_MD5, md5_get_info))
if( r->algo == algo ) BUG ();
break; if (!new_list_item (DIGEST_ALGO_RMD160, rmd160_get_info))
if( r ) { BUG ();
log_info("skipping digest %d: already loaded\n", algo ); if (!new_list_item (DIGEST_ALGO_SHA1, sha1_get_info))
continue; BUG ();
}
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;
}
return 1;
}
/**************** /****************
* Map a string to the digest algo * Map a string to the digest algo */
*/
int int
string_to_digest_algo( const char *string ) 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 ) for(r = digest_list; r; r = r->next )
if( !ascii_strcasecmp( r->name, string ) ) if( !ascii_strcasecmp( r->name, string ) )
return r->algo; return r->algo;
} while( !r && load_digest_module(-1) ); } while( !r && load_digest_module () );
return 0; return 0;
} }
@ -171,7 +135,7 @@ digest_algo_to_string( int algo )
for(r = digest_list; r; r = r->next ) for(r = digest_list; r; r = r->next )
if( r->algo == algo ) if( r->algo == algo )
return r->name; return r->name;
} while( !r && load_digest_module( algo ) ); } while( !r && load_digest_module () );
return NULL; return NULL;
} }
@ -185,7 +149,7 @@ check_digest_algo( int algo )
for(r = digest_list; r; r = r->next ) for(r = digest_list; r; r = r->next )
if( r->algo == algo ) if( r->algo == algo )
return 0; return 0;
} while( !r && load_digest_module(algo) ); } while( !r && load_digest_module () );
return G10ERR_DIGEST_ALGO; return G10ERR_DIGEST_ALGO;
} }
@ -232,7 +196,7 @@ md_enable( MD_HANDLE h, int algo )
for(r = digest_list; r; r = r->next ) for(r = digest_list; r; r = r->next )
if( r->algo == algo ) if( r->algo == algo )
break; break;
} while( !r && load_digest_module( algo ) ); } while( !r && load_digest_module () );
if( !r ) { if( !r ) {
log_error("md_enable: algorithm %d not available\n", algo ); log_error("md_enable: algorithm %d not available\n", algo );
return; return;
@ -457,7 +421,7 @@ md_digest_length( int algo )
if( r->algo == algo ) if( r->algo == algo )
return r->mdlen; 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); log_error("WARNING: no length for md algo %d\n", algo);
return 0; return 0;
} }
@ -480,7 +444,7 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
return r->asnoid; return r->asnoid;
} }
} }
} while( !r && load_digest_module( algo ) ); } while( !r && load_digest_module () );
log_bug("no asn for md algo %d\n", algo); log_bug("no asn for md algo %d\n", algo);
return NULL; return NULL;
} }

View File

@ -36,7 +36,7 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "dynload.h" #include "algorithms.h"
#include "bithelp.h" #include "bithelp.h"
@ -337,7 +337,7 @@ md5_read( MD5_CONTEXT *hd )
* Returns: A pointer to string describing the algorithm or NULL if * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
*/ */
static const char * const char *
md5_get_info( int algo, size_t *contextsize, md5_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen, byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ), void (**r_init)( void *c ),
@ -365,63 +365,3 @@ md5_get_info( int algo, size_t *contextsize,
return "MD5"; 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 */

View File

@ -31,8 +31,6 @@
#include "elgamal.h" #include "elgamal.h"
#include "dsa.h" #include "dsa.h"
#include "rsa.h" #include "rsa.h"
#include "dynload.h"
#define TABLE_SIZE 10 #define TABLE_SIZE 10
@ -58,6 +56,7 @@ static struct pubkey_table_s pubkey_table[TABLE_SIZE];
static int disabled_algos[TABLE_SIZE]; static int disabled_algos[TABLE_SIZE];
#if 0
static int static int
dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{ log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } { 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 static int
dummy_check_secret_key( int algo, MPI *skey ) dummy_check_secret_key( int algo, MPI *skey )
{ log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } { log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
#endif
static int static int
dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) 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 ) int (*cmp)(void *, MPI), void *opaquev )
{ log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } { log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
#if 0
static unsigned static unsigned
dummy_get_nbits( int algo, MPI *pkey ) dummy_get_nbits( int algo, MPI *pkey )
{ log_bug("no get_nbits() for %d\n", algo ); return 0; } { log_bug("no get_nbits() for %d\n", algo ); return 0; }
#endif
/**************** /****************
* Put the static entries into the table. * Put the static entries into the table.
@ -215,73 +216,13 @@ static int
load_pubkey_modules(void) load_pubkey_modules(void)
{ {
static int initialized = 0; 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 ) { if( !initialized ) {
cipher_modules_constructor();
setup_pubkey_table(); setup_pubkey_table();
initialized = 1; initialized = 1;
return 1; return 1;
} }
if( done )
return 0; 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;
} }

View File

@ -20,12 +20,16 @@
#ifndef G10_RAND_INTERNAL_H #ifndef G10_RAND_INTERNAL_H
#define G10_RAND_INTERNAL_H #define G10_RAND_INTERNAL_H
void rndlinux_constructor(void); int rndunix_gather_random (void (*add)(const void*, size_t, int),
void rndunix_constructor(void); int requester, size_t length, int level);
void rndw32_constructor(void); int rndlinux_gather_random (void (*add)(const void*, size_t, int),
void rndos2_constructor(void); int requester, size_t length, int level);
void rndatari_constructor(void); int rndegd_gather_random (void (*add)(const void*, size_t, int),
void rndmvs_constructor(void); int requester, size_t length, int level );
void rndriscos_constructor(void); 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*/ #endif /*G10_RAND_INTERNAL_H*/

View File

@ -1,5 +1,5 @@
/* random.c - random number generator /* 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. * This file is part of GnuPG.
* *
@ -56,8 +56,7 @@
#include "i18n.h" #include "i18n.h"
#include "random.h" #include "random.h"
#include "rand-internal.h" #include "rand-internal.h"
#include "dynload.h" #include "algorithms.h"
#ifndef RAND_MAX /* for SunOS */ #ifndef RAND_MAX /* for SunOS */
#define RAND_MAX 32767 #define RAND_MAX 32767
@ -125,6 +124,37 @@ static struct {
ulong naddbytes; ulong naddbytes;
} rndstats; } 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 static void
initialize(void) initialize(void)
{ {
@ -136,7 +166,6 @@ initialize(void)
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN) keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
: m_alloc_clear(POOLSIZE+BLOCKLEN); : m_alloc_clear(POOLSIZE+BLOCKLEN);
is_initialized = 1; is_initialized = 1;
cipher_modules_constructor();
} }
static void static void
@ -560,7 +589,7 @@ fast_random_poll()
if( !is_initialized ) if( !is_initialized )
initialize(); initialize();
initialized = 1; initialized = 1;
fnc = dynload_getfnc_fast_random_poll(); fnc = getfnc_fast_random_poll();
} }
if( fnc ) { if( fnc ) {
(*fnc)( add_randomness, 1 ); (*fnc)( add_randomness, 1 );
@ -637,7 +666,7 @@ read_random_source( int requester, size_t length, int level )
if( !fnc ) { if( !fnc ) {
if( !is_initialized ) if( !is_initialized )
initialize(); initialize();
fnc = dynload_getfnc_gather_random(); fnc = getfnc_gather_random();
if( !fnc ) { if( !fnc ) {
faked_rng = 1; faked_rng = 1;
fnc = gather_faked; fnc = gather_faked;
@ -685,3 +714,4 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
return 0; /* okay */ return 0; /* okay */
} }

View File

@ -26,8 +26,8 @@
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "rmd.h" #include "rmd.h"
#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */ #include "cipher.h" /* for rmd160_hash_buffer */
#include "dynload.h" #include "algorithms.h"
#include "bithelp.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 * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
*/ */
static const char * const char *
rmd160_get_info( int algo, size_t *contextsize, rmd160_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen, byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ), void (**r_init)( void *c ),
@ -586,67 +586,3 @@ rmd160_get_info( int algo, size_t *contextsize,
return "RIPEMD160"; 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

View File

@ -1,5 +1,5 @@
/* rndegd.c - interface to the EGD /* 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. * This file is part of GnuPG.
* *
@ -19,6 +19,9 @@
*/ */
#include <config.h> #include <config.h>
#ifdef USE_RNDEG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -33,14 +36,10 @@
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include "ttyio.h" #include "ttyio.h"
#include "dynload.h" #include "algorithms.h"
#include "cipher.h" #include "cipher.h"
#ifdef IS_MODULE
#define _(a) (a)
#else
#include "i18n.h" #include "i18n.h"
#endif
#ifndef offsetof #ifndef offsetof
#define offsetof(type, member) ((size_t) &((type *)0)->member) #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 ); } while( n == -1 && errno == EINTR );
if( n == -1 ) if( n == -1 )
return -1; return -1;
else if( n == 0 ) {
/* EGD probably died. */
errno = ECONNRESET;
return -1;
}
nread += n; nread += n;
} while( nread < nbytes ); } while( nread < nbytes );
return 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 * Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for EGD. * to the pool. So this is just a dummy for EGD.
*/ */
static int int
gather_random( void (*add)(const void*, size_t, int), int requester, rndegd_gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level ) size_t length, int level )
{ {
static int fd = -1; static int fd = -1;
@ -175,11 +179,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
} }
if( length ) { if( length ) {
#ifdef IS_MODULE
fprintf( stderr,
#else
tty_printf( tty_printf(
#endif
_("Please wait, entropy is being gathered. Do some work if it would\n" _("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" "keep you from getting bored, because it will improve the quality\n"
"of the entropy.\n") ); "of the entropy.\n") );
@ -205,51 +205,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
return 0; /* success */ return 0; /* success */
} }
#endif /*USE_RNDEGD*/
#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

View File

@ -20,6 +20,9 @@
#include <config.h> #include <config.h>
#ifdef USE_RNDLINUX
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -41,17 +44,12 @@
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include "ttyio.h" #include "ttyio.h"
#include "dynload.h" #include "algorithms.h"
#ifdef IS_MODULE
#define _(a) (a)
#else
#include "i18n.h" #include "i18n.h"
#endif
static int open_device( const char *name, int minor ); 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 #if 0
#ifdef HAVE_DEV_RANDOM_IOCTL #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 * Note: Using a level of 0 should never block and better add nothing
* to the pool. This is easy to accomplish with /dev/urandom. * to the pool. This is easy to accomplish with /dev/urandom.
*/ */
static int int
gather_random( void (*add)(const void*, size_t, int), int requester, rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level ) size_t length, int level )
{ {
static int fd_urandom = -1; static int fd_urandom = -1;
@ -132,11 +130,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
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 )
#ifdef IS_MODULE
fprintf(stderr,
#else
tty_printf( tty_printf(
#endif
_("\n" _("\n"
"Not enough random bytes available. Please do some other work to give\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 ); "the OS a chance to collect more entropy! (Need %d more bytes)\n"), (int)length );
@ -144,11 +138,7 @@ _("\n"
continue; continue;
} }
else if( rc == -1 ) { else if( rc == -1 ) {
#ifdef IS_MODULE
fprintf(stderr,
#else
tty_printf( tty_printf(
#endif
"select() error: %s\n", strerror(errno)); "select() error: %s\n", strerror(errno));
continue; continue;
} }
@ -171,70 +161,4 @@ _("\n"
return 0; /* success */ return 0; /* success */
} }
#endif /*USE_RNDLINUX*/
#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

View File

@ -48,6 +48,9 @@
/* General includes */ /* General includes */
#include <config.h> #include <config.h>
#ifdef USE_RNDUNIX
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -768,8 +771,8 @@ read_a_msg( int fd, GATHER_MSG *msg )
* Using a level of 0 should never block and better add nothing * Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for this gatherer. * to the pool. So this is just a dummy for this gatherer.
*/ */
static int int
gather_random( void (*add)(const void*, size_t, int), int requester, rndunix_gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level ) size_t length, int level )
{ {
static pid_t gatherer_pid = 0; static pid_t gatherer_pid = 0;
@ -846,70 +849,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
return 0; return 0;
} }
#endif /*USE_RNDUNIX*/
#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

View File

@ -1,5 +1,5 @@
/* rndw32.c - W32 entropy gatherer /* 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 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
* *
* This file is part of GnuPG. * This file is part of GnuPG.
@ -60,6 +60,9 @@
*/ */
#include <config.h> #include <config.h>
#ifdef USE_RNDW32
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -74,230 +77,13 @@
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include "dynload.h" #include "algorithms.h"
/* We do not use the netropy DLL anymore because a standalone program is
* easier to maintain and */
/*#define USE_ENTROPY_DLL*/
#ifdef IS_MODULE
#define _(a) (a)
#else
#include "i18n.h" #include "i18n.h"
#endif
static int debug_me; 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 * Definitions which are missing from the current GNU Windows32Api
*/ */
@ -731,8 +517,8 @@ slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
} }
static int int
gather_random( void (*add)(const void*, size_t, int), int requester, rndw32_gather_random (void (*add)(const void*, size_t, int), int requester,
size_t length, int level ) size_t length, int level )
{ {
static int is_initialized; static int is_initialized;
@ -783,8 +569,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
static int int
gather_random_fast( void (*add)(const void*, size_t, int), int requester ) rndw32_gather_random_fast( void (*add)(const void*, size_t, int), int requester )
{ {
static int addedFixedItems = 0; static int addedFixedItems = 0;
@ -915,58 +701,4 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester )
} }
#endif /*USE_RNDW32*/
#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

View File

@ -38,7 +38,7 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "dynload.h" #include "algorithms.h"
#include "bithelp.h" #include "bithelp.h"
@ -331,7 +331,7 @@ sha1_read( SHA1_CONTEXT *hd )
* Returns: A pointer to string describing the algorithm or NULL if * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
*/ */
static const char * const char *
sha1_get_info( int algo, size_t *contextsize, sha1_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen, byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ), void (**r_init)( void *c ),
@ -357,69 +357,3 @@ sha1_get_info( int algo, size_t *contextsize,
return "SHA1"; 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

View File

@ -25,7 +25,7 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "algorithms.h"
#ifdef HAVE_U64_TYPEDEF #ifdef HAVE_U64_TYPEDEF
@ -879,13 +879,15 @@ tiger_read( TIGER_CONTEXT *hd )
return hd->buf; return hd->buf;
} }
#endif /*HAVE_U64_TYPEDEF*/
/**************** /****************
* Return some information about the algorithm. We need algo here to * Return some information about the algorithm. We need algo here to
* distinguish different flavors of the algorithm. * distinguish different flavors of the algorithm.
* Returns: A pointer to string describing the algorithm or NULL if * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
*/ */
static const char * const char *
tiger_get_info( int algo, size_t *contextsize, tiger_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen, byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ), void (**r_init)( void *c ),
@ -894,6 +896,7 @@ tiger_get_info( int algo, size_t *contextsize,
byte *(**r_read)( void *c ) byte *(**r_read)( void *c )
) )
{ {
#ifdef HAVE_U64_TYPEDEF
/* 40: SEQUENCE { /* 40: SEQUENCE {
* 12: SEQUENCE { * 12: SEQUENCE {
* 8: OCTET STRING :54 49 47 45 52 31 39 32 * 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; * By replacing the 5th byte (0x04) with 0x16 we would have;
* 8: IA5String 'TIGER192' * 8: IA5String 'TIGER192'
* Fixme: We should use a registered OID.
*/ */
static byte asn[18] = static byte asn[18] =
{ 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47, { 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; *(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read;
return "TIGER192"; return "TIGER192";
} #else /*!HAVE_U64_TYPEDEF*/
return NULL; /* Alorithm not available. */
#ifndef IS_MODULE
static
#endif #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
#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 */

View File

@ -29,8 +29,6 @@ AC_INIT(gnupg, 1.1.91, bug-gnupg@gnu.org)
development_version=yes development_version=yes
ALL_LINGUAS="cs da de eo el es et fr gl id it ja nl pl pt_BR pt sv tr" ALL_LINGUAS="cs da de eo el es et fr gl id it ja nl pl pt_BR pt sv tr"
static_modules="sha1 md5 rmd160"
static_random_module=""
PACKAGE=$PACKAGE_NAME PACKAGE=$PACKAGE_NAME
VERSION=$PACKAGE_VERSION VERSION=$PACKAGE_VERSION
@ -47,18 +45,10 @@ AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
AC_DEFINE(_GNU_SOURCE,1,[Some tests rely on this (stpcpy) and it should be used for new programs anyway]) AC_DEFINE(_GNU_SOURCE,1,[Some tests rely on this (stpcpy) and it should be used for new programs anyway])
AC_PROG_AWK
MODULES_IN_CIPHER=`$AWK '/^EXTRA_PROGRAMS/ { for(i=3;i<=NF;i++) print $i}' \
$srcdir/cipher/Makefile.am`
dnl dnl
dnl Check for random module options dnl Check for random module options
dnl dnl
dnl Fixme: get the list of available modules from MODULES_IN_CIPHER AC_MSG_CHECKING([which random module to use])
dnl and check against this list
AC_MSG_CHECKING([which static random module to use])
AC_ARG_ENABLE(static-rnd, AC_ARG_ENABLE(static-rnd,
[ --enable-static-rnd=[egd|unix|linux|none] ], [ --enable-static-rnd=[egd|unix|linux|none] ],
[use_static_rnd=$enableval], [use_static_rnd=default] ) [use_static_rnd=$enableval], [use_static_rnd=default] )
@ -68,7 +58,7 @@ if test "$use_static_rnd" = no; then
fi fi
case "$use_static_rnd" in case "$use_static_rnd" in
egd | linux | unix | none | default ) egd | linux | unix | default )
AC_MSG_RESULT($use_static_rnd) AC_MSG_RESULT($use_static_rnd)
;; ;;
* ) * )
@ -226,21 +216,6 @@ AM_MAINTAINER_MODE
dnl Checks for programs. dnl Checks for programs.
dnl
dnl Setup some stuff depending on host/target.
dnl
case "${target}" in
*-*-mingw32*)
disallowed_modules="rndunix rndlinux rndegd"
;;
*-*-cygwin*)
disallowed_modules="rndunix rndlinux rndegd tiger"
;;
*)
disallowed_modules="rndw32"
;;
esac
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AM_SANITY_CHECK AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd` missing_dir=`cd $ac_aux_dir && pwd`
@ -334,11 +309,6 @@ esac
AC_SUBST(MPI_OPT_FLAGS) AC_SUBST(MPI_OPT_FLAGS)
GNUPG_SYS_SYMBOL_UNDERSCORE GNUPG_SYS_SYMBOL_UNDERSCORE
GNUPG_CHECK_PIC
GNUPG_CHECK_EXPORTDYNAMIC
if test "$NO_PIC" = yes; then
try_dynload=no
fi
dnl Must check for network library requirements before doing link tests dnl Must check for network library requirements before doing link tests
dnl for ldap, for example. If ldap libs are static (or dynamic and without dnl for ldap, for example. If ldap libs are static (or dynamic and without
@ -443,8 +413,7 @@ AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
# #
# 1. Set flags to be used for the extension modules # 1. Set names of random devices
# 2. Set names of random devices
# #
NAME_OF_DEV_RANDOM="/dev/random" NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom" NAME_OF_DEV_URANDOM="/dev/urandom"
@ -452,57 +421,6 @@ case "${target}" in
*-openbsd* | *-netbsd*) *-openbsd* | *-netbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom" NAME_OF_DEV_RANDOM="/dev/srandom"
NAME_OF_DEV_URANDOM="/dev/urandom" NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
;;
hpux*)
# if using the vendor (ANSI) compiler, arrange to have `-b' passed
# to the linker. If using gcc, it supports `-shared' to do the same.
if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
else
DYNLINK_MOD_CFLAGS='-Wl,-b'
fi
;;
*-irix6.5*)
# Irix 6.5 (and probably a lot earlier, but I only still have
# access to 6.5.x) doesn't require any additional flags, as `-KPIC'
# is the default. Also, `-shared' works with the vendor compiler
DYNLINK_MOD_CFLAGS="-shared"
;;
alpha*-dec-osf*)
# osf (i.e. OSF/1, Digital UNIX, or Tru64 UNIX, pick any one...)
# on alpha doesn't require any PIC flags, everything is PIC.
# This may not be the case for osf ports to other machines, so
# hence the more specific match for target.
#
# Also, `-shared' works with the vendor compiler or gcc.
# -expect_unresolved turns off warnings about unresolved symbols.
DYNLINK_MOD_CFLAGS='-shared -Wl,-expect_unresolved,\*'
;;
*-solaris*)
# -shared is a gcc-ism. Find pic flags from GNUPG_CHECK_PIC.
if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
else
DYNLINK_MOD_CFLAGS="-G $CFLAGS_PIC"
fi
;;
*-irix* | *-dec-osf* )
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
;;
*)
# -shared is a gcc-ism. Find pic flags from GNUPG_CHECK_PIC.
if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
else
DYNLINK_MOD_CFLAGS="$CFLAGS_PIC"
fi
;; ;;
esac esac
AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM", AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM",
@ -533,49 +451,20 @@ if test "$try_dynload" = yes ; then
[define to enable the use of extensions]) [define to enable the use of extensions])
AC_DEFINE(HAVE_DL_DLOPEN,1, AC_DEFINE(HAVE_DL_DLOPEN,1,
[Defined when the dlopen function family is available]) [Defined when the dlopen function family is available])
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
use_gnupg_extensions=yes
else else
AC_CHECK_FUNCS(dlopen) AC_CHECK_FUNCS(dlopen)
if test "$ac_cv_func_dlopen" = "yes"; then if test "$ac_cv_func_dlopen" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING) AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_DLOPEN) AC_DEFINE(HAVE_DL_DLOPEN)
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
use_gnupg_extensions=yes
else
AC_CHECK_LIB(dld,shl_load)
if test "$ac_cv_lib_dld_shl_load" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_SHL_LOAD,1,
[Defined if the shl_load function family is available])
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
use_gnupg_extensions=yes
dnl -----------------
dnl DLD is not ready for use. So I better disable this test
dnl
dnl AC_CHECK_LIB(dld,dld_link)
dnl if test "$ac_cv_lib_dld_dld_link" = "yes"; then
dnl AC_DEFINE(USE_DYNAMIC_LINKING)
dnl AC_DEFINE(HAVE_DLD_DLD_LINK)
dnl DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
dnl use_gnupg_extensions=yes
dnl ---------------
fi
fi fi
fi fi
else else
AC_MSG_CHECKING(for dynamic loading) AC_MSG_CHECKING(for dynamic loading)
DYNLINK_LDFLAGS= DYNLINK_LDFLAGS=
DYNLINK_MOD_CFLAGS= DYNLINK_MOD_CFLAGS=
use_gnupg_extensions=no
AC_MSG_RESULT(has been disabled) AC_MSG_RESULT(has been disabled)
fi fi
AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes )
AC_SUBST(DYNLINK_LDFLAGS)
AC_SUBST(DYNLINK_MOD_CFLAGS)
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h langinfo.h termio.h locale.h) AC_CHECK_HEADERS(unistd.h langinfo.h termio.h locale.h)
@ -713,9 +602,9 @@ fi
dnl dnl
dnl Figure out the default linkage mode for random modules dnl Figure out the default random module.
dnl dnl
print_egd_notice=no static_random_module=""
if test "$use_static_rnd" = default; then if test "$use_static_rnd" = default; then
if test "$ac_cv_have_dev_random" = yes; then if test "$ac_cv_have_dev_random" = yes; then
static_random_module="rndlinux" static_random_module="rndlinux"
@ -723,9 +612,6 @@ if test "$use_static_rnd" = default; then
case "${target}" in case "${target}" in
*-*-mingw32*|*-*-cygwin*) *-*-mingw32*|*-*-cygwin*)
static_random_module="rndw32" static_random_module="rndw32"
AC_DEFINE(USE_STATIC_RNDW32,1,
[At some point in the code we need to know that
we use the Windows random module.])
;; ;;
i?86-emx-os2|i?86-*-os2*emx) i?86-emx-os2|i?86-*-os2*emx)
static_random_module="rndos2" static_random_module="rndos2"
@ -738,23 +624,18 @@ if test "$use_static_rnd" = default; then
;; ;;
*) *)
static_random_module="rndunix" static_random_module="rndunix"
print_egd_notice=yes
;; ;;
esac esac
fi fi
else
if test "$use_static_rnd" = none; then
:
else
static_random_module="rnd$use_static_rnd"
if test "$use_static_rnd" = "unix"; then
print_egd_notice=yes
fi fi
fi case "$static_random_module" in
fi rndlinux)
AC_DEFINE(USE_RNDLINUX,1,
[Defined if the /dev/random based RNG shoudl be used.])
if test "$print_egd_notice" = "yes"; then ;;
rndunix)
AC_DEFINE(USE_RNDUNIX,1,
[Defined if the default Unix RNG should be used.])
AC_MSG_WARN([[ AC_MSG_WARN([[
*** ***
*** The performance of the UNIX random gatherer module is not very good *** The performance of the UNIX random gatherer module is not very good
@ -769,86 +650,36 @@ if test "$print_egd_notice" = "yes"; then
*** ***
*** http://www.gnupg.org/download.html#egd *** http://www.gnupg.org/download.html#egd
*** ***
*** You may want to run ./configure with --enable-static-rnd=none to be *** You may want to run ./configure with --enable-static-rnd=egd to use it.
*** able to load the EGD client code dynamically; this way you can choose
*** between RNDUNIX and RNDEGD without recompilation.
***]]) ***]])
fi ;;
rndegd)
AC_DEFINE(USE_RNDEGD,1,
[Defined if the EGD based RNG shoudl be used.])
;;
rndw32)
AC_DEFINE(USE_RNDW32,1,
[Defined if the Windows specific RNG should be used.])
;;
*)
AC_MSG_ERROR(no random module available)
;;
esac
dnl # We don't need idea but some people claim that they need it for
dnl Parse the modules list and build the list # research etc., so we allow to place an idea source code into the
dnl of static and dynamically linked modules # cipher directory and statically link it if available, otherwise we
dnl # link to a stub. We don't use AC_CHECK_FILE to avoid caching.
dnl (We always need a static rmd160) AC_MSG_CHECKING(for extra cipher modules)
static_modules="$static_modules rmd160 $static_random_module" tmp=""
STATIC_CIPHER_NAMES="" if test -f $srcdir/cipher/idea.c; then
STATIC_CIPHER_OBJS="" IDEA_O=idea.o
DYNAMIC_CIPHER_MODS="" tmp=idea
show_dynlink=""
for name in $MODULES_IN_CIPHER; do
x="yes"
for i in $disallowed_modules; do
if test "$name" = "$i" ; then x="no" ; fi
done;
if test $x = yes; then
x="no"
for i in $static_modules; do
if test "$name" = "$i" ; then
x="yes"
fi
done;
if test $x = yes; then
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.o"
else else
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name" IDEA_O=idea-stub.o
show_dynlink="$show_dynlink $name"
fi fi
fi AC_SUBST(IDEA_O)
done AC_MSG_RESULT($tmp)
AC_SUBST(STATIC_CIPHER_OBJS)
AC_SUBST(STATIC_CIPHER_NAMES)
AC_SUBST(DYNAMIC_CIPHER_MODS)
dnl
dnl And build the constructor file
dnl
test -d cipher || mkdir cipher
cat <<G10EOF >cipher/construct.c
/* automatically generated by configure - do not edit */
G10EOF
show_statlink=""
for name in $STATIC_CIPHER_NAMES; do
echo "void ${name}_constructor(void);" >>cipher/construct.c
show_statlink="$show_statlink $name"
done
cat <<G10EOF >>cipher/construct.c
void
cipher_modules_constructor(void)
{
static int done = 0;
if( done )
return;
done = 1;
G10EOF
for name in $STATIC_CIPHER_NAMES; do
echo " ${name}_constructor();" >>cipher/construct.c
done
echo '}' >>cipher/construct.c
dnl
dnl Figure how to link the cipher modules
dnl
AC_SUBST(STATIC_CIPHER_OBJS)
AC_SUBST(DYNAMIC_CIPHER_MODS)
dnl setup assembler stuff dnl setup assembler stuff
@ -1032,14 +863,7 @@ AC_OUTPUT
# Give some feedback # Give some feedback
echo echo
echo " Configured for: $PRINTABLE_OS_NAME ($target)" echo " Configured for: $PRINTABLE_OS_NAME ($target)"
if test -n "$show_dynlink"; then
echo " Dynamically linked modules:$show_dynlink"
fi
if test -n "$show_statlink"; then
echo " Statically linked modules:$show_statlink"
fi
if test -n "$show_extraasm"; then if test -n "$show_extraasm"; then
echo " Extra cpu specific functions:$show_extraasm" echo " Extra cpu specific functions:$show_extraasm"
fi fi
echo echo

View File

@ -1245,7 +1245,8 @@ Using this option will also prevent the creation of a
<listitem><para> <listitem><para>
Load an extension module. If &ParmName; does not Load an extension module. If &ParmName; does not
contain a slash it is searched in "/usr/local/lib/gnupg" contain a slash it is searched in "/usr/local/lib/gnupg"
See the manual for more information about extensions. Extension are in gernal not useful anymore; the use of this
option is deprecated.
</para></listitem></varlistentry> </para></listitem></varlistentry>

View File

@ -1,3 +1,7 @@
2002-08-02 Werner Koch <wk@gnupg.org>
* Makefile.am (LDFLAGS): Removed DYNLINK_LDFLAGS.
2002-07-30 David Shaw <dshaw@jabberwocky.com> 2002-07-30 David Shaw <dshaw@jabberwocky.com>
* options.h, g10.c (main), mainproc.c (proc_encrypted): Return a * options.h, g10.c (main), mainproc.c (proc_encrypted): Return a

View File

@ -22,7 +22,7 @@ INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl
EXTRA_DIST = options.skel EXTRA_DIST = options.skel
# it seems that we can't use this with automake 1.5 # it seems that we can't use this with automake 1.5
#OMIT_DEPENDENCIES = zlib.h zconf.h #OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@ LDFLAGS = @LDFLAGS@
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
#noinst_PROGRAMS = gpgd #noinst_PROGRAMS = gpgd

View File

@ -134,7 +134,7 @@ void md_stop_debug( MD_HANDLE a );
md_write( (h), NULL, 0 ); \ md_write( (h), NULL, 0 ); \
(h)->buffer[(h)->bufcount++] = (c) & 0xff; \ (h)->buffer[(h)->bufcount++] = (c) & 0xff; \
} while(0) } while(0)
/*-- rmd160.c --*/
void rmd160_hash_buffer (char *outbuf, const char *buffer, size_t length); void rmd160_hash_buffer (char *outbuf, const char *buffer, size_t length);