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>
* 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
-------------------------------------------------
* 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
key must be specified by fingerprint. See the man page for
details.

7
README
View File

@ -460,7 +460,7 @@
--enable-static-rnd=<name>
Force the use of the random byte gathering
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
Entropy Gathering Daemon. See the webpages
for more information about it.
@ -469,8 +469,6 @@
linux - Use the module which accesses /dev/random.
This is the first choice and the default one
for GNU/Linux or *BSD.
none - Do not linkl any module in but rely on
a dynmically loaded modules.
--with-egd-socket=<name>
This is only used when EGD is used as random
@ -501,7 +499,8 @@
--disable-dynload
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
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
Chip Salzenberg chip@valinux.com
Chris Adams cmadams@hiwaay.net
Christian Biere christianbiere@gmx.de
Christian Kurz shorty@debian.org
Christian von Roques roques@pond.sub.org
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>
* 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.
#
@ -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
algorithms.h \
rndlinux.c \
rndunix.c \
rndegd.c \
rndw32.c \
md5.c \
rmd160.c \
sha1.c \
tiger.c
# configure creates the constructor file
BUILT_SOURCES = construct.c
DISTCLEANFILES = construct.c
EXTRA_libcipher_a_SOURCES = idea-stub.c
libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@
libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@
# 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

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 )
);
/* 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*/

View File

@ -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;
static int initialized = 0;
if( !initialized ) {
cipher_modules_constructor();
setup_cipher_table(); /* load static modules on the first call */
initialized = 1;
return 1;
if (!initialized )
{
setup_cipher_table(); /* load static modules on the first call */
initialized = 1;
return 1;
}
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;
}
}
enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL,
NULL, NULL, NULL );
return any;
return 0;
}

View File

@ -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;
for (; el && el->name && seq; el = el->next, seq--)
;
return el? el->name: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
* 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;
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;
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;
}
return r;
if (r)
{
r->next = digest_list;
digest_list = 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*));
static int initialized = 0;
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));
if (initialized)
return 0;
initialized = 1;
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;
}
/* 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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
#else /*!HAVE_U64_TYPEDEF*/
return NULL; /* Alorithm not available. */
#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
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
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(_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 Check for random module options
dnl
dnl Fixme: get the list of available modules from MODULES_IN_CIPHER
dnl and check against this list
AC_MSG_CHECKING([which static random module to use])
AC_MSG_CHECKING([which random module to use])
AC_ARG_ENABLE(static-rnd,
[ --enable-static-rnd=[egd|unix|linux|none] ],
[use_static_rnd=$enableval], [use_static_rnd=default] )
@ -68,7 +58,7 @@ if test "$use_static_rnd" = no; then
fi
case "$use_static_rnd" in
egd | linux | unix | none | default )
egd | linux | unix | default )
AC_MSG_RESULT($use_static_rnd)
;;
* )
@ -226,21 +216,6 @@ AM_MAINTAINER_MODE
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
AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd`
@ -334,11 +309,6 @@ esac
AC_SUBST(MPI_OPT_FLAGS)
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 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
# 2. Set names of random devices
# 1. Set names of random devices
#
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
@ -452,57 +421,6 @@ case "${target}" in
*-openbsd* | *-netbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom"
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
AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM",
@ -515,14 +433,14 @@ AC_SUBST(MPI_OPT_FLAGS)
dnl Checks for libraries.
if test "$try_gettext" = yes; then
AM_GNU_GETTEXT
AM_GNU_GETTEXT
else
USE_NLS=no
USE_INCLUDED_LIBINTL=no
BUILD_INCLUDED_LIBINTL=no
AC_SUBST(USE_NLS)
AC_SUBST(USE_INCLUDED_LIBINTL)
AC_SUBST(BUILD_INCLUDED_LIBINTL)
USE_NLS=no
USE_INCLUDED_LIBINTL=no
BUILD_INCLUDED_LIBINTL=no
AC_SUBST(USE_NLS)
AC_SUBST(USE_INCLUDED_LIBINTL)
AC_SUBST(BUILD_INCLUDED_LIBINTL)
fi
@ -533,49 +451,20 @@ if test "$try_dynload" = yes ; then
[define to enable the use of extensions])
AC_DEFINE(HAVE_DL_DLOPEN,1,
[Defined when the dlopen function family is available])
DYNLINK_LDFLAGS="$CFLAGS_EXPORTDYNAMIC"
use_gnupg_extensions=yes
else
AC_CHECK_FUNCS(dlopen)
if test "$ac_cv_func_dlopen" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_DLOPEN)
DYNLINK_LDFLAGS="$CFLAGS_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
else
AC_MSG_CHECKING(for dynamic loading)
DYNLINK_LDFLAGS=
DYNLINK_MOD_CFLAGS=
use_gnupg_extensions=no
AC_MSG_RESULT(has been disabled)
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.
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h langinfo.h termio.h locale.h)
@ -713,9 +602,9 @@ fi
dnl
dnl Figure out the default linkage mode for random modules
dnl Figure out the default random module.
dnl
print_egd_notice=no
static_random_module=""
if test "$use_static_rnd" = default; then
if test "$ac_cv_have_dev_random" = yes; then
static_random_module="rndlinux"
@ -723,9 +612,6 @@ if test "$use_static_rnd" = default; then
case "${target}" in
*-*-mingw32*|*-*-cygwin*)
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)
static_random_module="rndos2"
@ -738,24 +624,19 @@ if test "$use_static_rnd" = default; then
;;
*)
static_random_module="rndunix"
print_egd_notice=yes
;;
esac
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
if test "$print_egd_notice" = "yes"; then
AC_MSG_WARN([[
case "$static_random_module" in
rndlinux)
AC_DEFINE(USE_RNDLINUX,1,
[Defined if the /dev/random based RNG shoudl be used.])
;;
rndunix)
AC_DEFINE(USE_RNDUNIX,1,
[Defined if the default Unix RNG should be used.])
AC_MSG_WARN([[
***
*** The performance of the UNIX random gatherer module is not very good
*** and it does not keep the entropy pool over multiple invocations of
@ -769,86 +650,36 @@ if test "$print_egd_notice" = "yes"; then
***
*** http://www.gnupg.org/download.html#egd
***
*** You may want to run ./configure with --enable-static-rnd=none to be
*** able to load the EGD client code dynamically; this way you can choose
*** between RNDUNIX and RNDEGD without recompilation.
*** You may want to run ./configure with --enable-static-rnd=egd to use it.
***]])
;;
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
# We don't need idea but some people claim that they need it for
# research etc., so we allow to place an idea source code into the
# cipher directory and statically link it if available, otherwise we
# link to a stub. We don't use AC_CHECK_FILE to avoid caching.
AC_MSG_CHECKING(for extra cipher modules)
tmp=""
if test -f $srcdir/cipher/idea.c; then
IDEA_O=idea.o
tmp=idea
else
IDEA_O=idea-stub.o
fi
dnl
dnl Parse the modules list and build the list
dnl of static and dynamically linked modules
dnl
dnl (We always need a static rmd160)
static_modules="$static_modules rmd160 $static_random_module"
STATIC_CIPHER_NAMES=""
STATIC_CIPHER_OBJS=""
DYNAMIC_CIPHER_MODS=""
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
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
show_dynlink="$show_dynlink $name"
fi
fi
done
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)
AC_SUBST(IDEA_O)
AC_MSG_RESULT($tmp)
dnl setup assembler stuff
@ -1032,14 +863,7 @@ AC_OUTPUT
# Give some feedback
echo
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
echo " Extra cpu specific functions:$show_extraasm"
fi
echo

View File

@ -1245,7 +1245,8 @@ Using this option will also prevent the creation of a
<listitem><para>
Load an extension module. If &ParmName; does not
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>

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>
* 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
# it seems that we can't use this with automake 1.5
#OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
LDFLAGS = @LDFLAGS@
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
#noinst_PROGRAMS = gpgd

View File

@ -134,8 +134,8 @@ void md_stop_debug( MD_HANDLE a );
md_write( (h), NULL, 0 ); \
(h)->buffer[(h)->bufcount++] = (c) & 0xff; \
} 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);
/*-- cipher.c --*/