Update head to match stable 1.0
[gnupg.git] / cipher / dynload.c
1 /* dynload.c - load cipher extensions
2  *      Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #ifdef HAVE_DL_DLOPEN
27   #include <dlfcn.h>
28 #elif defined(HAVE_DLD_DLD_LINK)
29   #include <dld.h>
30 #elif defined(HAVE_DL_SHL_LOAD)
31   #include <dl.h>
32   #include <errno.h>
33 #endif
34 #ifdef __MINGW32__
35   #include <windows.h>
36 #endif
37 #include "util.h"
38 #include "cipher.h"
39 #include "dynload.h"
40
41 #ifdef WITH_SYMBOL_UNDERSCORE
42   #define SYMBOL_VERSION "_gnupgext_version"
43   #define SYMBOL_ENUM    "_gnupgext_enum_func"
44 #else
45   #define SYMBOL_VERSION "gnupgext_version"
46   #define SYMBOL_ENUM    "gnupgext_enum_func"
47 #endif
48
49
50 #ifndef RTLD_NOW
51   #define RTLD_NOW  1
52 #endif
53
54 #ifdef HAVE_DL_SHL_LOAD  /* HPUX has shl_load instead of dlopen */
55 #define HAVE_DL_DLOPEN
56 #define dlopen(PATHNAME,MODE) \
57     ((void *) shl_load(PATHNAME, DYNAMIC_PATH | \
58               (((MODE) & RTLD_NOW) ? BIND_IMMEDIATE : BIND_DEFERRED), 0L))
59 #define dlclose(HANDLE) shl_unload((shl_t) (HANDLE))
60 #define dlerror() (errno == 0 ? NULL : strerror(errno))
61
62 static void *
63 dlsym(void *handle, char *name)
64 {
65     void *addr;
66     if (shl_findsym((shl_t *)&handle,name,(short)TYPE_UNDEFINED,&addr) != 0) {
67       return NULL;
68     }
69     return addr;
70 }
71 #endif /*HAVE_DL_SHL_LOAD*/
72
73 #ifdef __MINGW32__
74 #define HAVE_DL_DLOPEN
75 #define USE_DYNAMIC_LINKING
76
77 static int last_error = 0;
78     
79 void*
80 dlopen(const char *pathname, int mode)
81 {
82         void *h = LoadLibrary( pathname );
83         if (!h) {
84         log_error( "LoadLibrary failed ec=%d\n", (int)GetLastError() );
85         last_error = 1;
86         return NULL;
87         }
88         return h;
89 }
90
91 int
92 dlclose( void *handle )
93 {
94         last_error = 0;
95         return  FreeLibrary( handle );
96 }
97
98 char*
99 dlerror(void)
100 {
101         static char dlerrstr[10];
102         if (last_error) {
103         sprintf(dlerrstr, "%d", (int)GetLastError() );
104         return dlerrstr;
105         }
106         return NULL;
107 }
108
109 void*
110 dlsym( void *handle, const char *name )
111 {
112         void *h = GetProcAddress( handle, name );
113         if (!h) {
114         log_error( "GetProcAddress failed ec=%d\n", (int)GetLastError() );
115         last_error = 1;
116         return NULL;
117         }
118         return h;
119 }
120 #endif /*__MINGW32__*/
121
122
123
124
125
126 typedef struct ext_list {
127     struct ext_list *next;
128     int internal;
129   #ifdef HAVE_DL_DLOPEN
130     void *handle; /* handle from dlopen() */
131   #else
132     int handle;   /* if the function has been loaded, this is true */
133   #endif
134     int  failed;  /* already tried but failed */
135     void * (*enumfunc)(int, int*, int*, int*);
136     char *hintstr; /* pointer into name */
137     char name[1];
138 } *EXTLIST;
139
140 static EXTLIST extensions;
141
142 typedef struct {
143     EXTLIST r;
144     int seq1;
145     int seq2;
146     void *sym;
147     int reqalgo;
148 } ENUMCONTEXT;
149
150
151 #ifdef HAVE_DLD_DLD_LINK
152 static char *mainpgm_path;
153 static int did_dld_init;
154 static int dld_available;
155 #endif
156
157
158 /****************
159  * Register an extension module.  The last registered module will
160  * be loaded first.  A name may have a list of classes
161  * appended; e.g:
162  *      mymodule.so(1:17,3:20,3:109)
163  * means that this module provides digest algorithm 17 and public key
164  * algorithms 20 and 109.  This is only a hint but if it is there the
165  * loader may decide to only load a module which claims to have a
166  * requested algorithm.
167  *
168  * mainpgm is the path to the program which wants to load a module
169  * it is only used in some environments.
170  */
171 void
172 register_cipher_extension( const char *mainpgm, const char *fname )
173 {
174     EXTLIST r, el, intex;
175     char *p, *pe;
176
177   #ifdef HAVE_DLD_DLD_LINK
178     if( !mainpgm_path && mainpgm && *mainpgm )
179         mainpgm_path = m_strdup(mainpgm);
180   #endif
181     if( *fname != DIRSEP_C ) { /* do tilde expansion etc */
182         char *tmp;
183
184         if( strchr(fname, DIRSEP_C) )
185             tmp = make_filename(fname, NULL);
186         else
187             tmp = make_filename(GNUPG_LIBDIR, fname, NULL);
188         el = m_alloc_clear( sizeof *el + strlen(tmp) );
189         strcpy(el->name, tmp );
190         m_free(tmp);
191     }
192     else {
193         el = m_alloc_clear( sizeof *el + strlen(fname) );
194         strcpy(el->name, fname );
195     }
196     /* check whether we have a class hint */
197     if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) {
198         *p = *pe = 0;
199         el->hintstr = p+1;
200     }
201     else
202         el->hintstr = NULL;
203
204     /* check that it is not already registered */
205     intex = NULL;
206     for(r = extensions; r; r = r->next ) {
207         if( !compare_filenames(r->name, el->name) ) {
208             log_info("extension `%s' already registered\n", el->name );
209             m_free(el);
210             return;
211         }
212         else if( r->internal )
213             intex = r;
214     }
215     /* and register */
216     /* we put them after the internal extension modules */
217     /* this is so that the external modules do not get loaded */
218     /* as soon as the internal modules are requested */
219     if( intex ) {
220         el->next = intex->next;
221         intex->next = el;
222     }
223     else {
224         el->next = extensions;
225         extensions = el;
226     }
227 }
228
229 void
230 register_internal_cipher_extension(
231                         const char *module_id,
232                         void * (*enumfunc)(int, int*, int*, int*)
233                                   )
234 {
235     EXTLIST r, el;
236
237     el = m_alloc_clear( sizeof *el + strlen(module_id) );
238     strcpy(el->name, module_id );
239     el->internal = 1;
240
241     /* check that it is not already registered */
242     for(r = extensions; r; r = r->next ) {
243         if( !compare_filenames(r->name, el->name) ) {
244             log_info("extension `%s' already registered\n", el->name );
245             m_free(el);
246             return;
247         }
248     }
249     /* and register */
250     el->enumfunc = enumfunc;
251   #ifdef HAVE_DL_DLOPEN
252     el->handle = (void*)1;
253   #else
254     el->handle = 1;
255   #endif
256     el->next = extensions;
257     extensions = el;
258 }
259
260
261 static int
262 load_extension( EXTLIST el )
263 {
264   #ifdef USE_DYNAMIC_LINKING
265     char **name;
266   #ifdef HAVE_DL_DLOPEN
267     const char *err;
268     int seq = 0;
269     int class, vers;
270     void *sym;
271   #else
272     unsigned long addr;
273     int rc;
274   #endif
275
276   #ifndef __MINGW32__
277     /* make sure we are not setuid */
278     if( getuid() != geteuid() )
279         log_bug("trying to load an extension while still setuid\n");
280   #endif
281
282     /* now that we are not setuid anymore, we can safely load modules */
283   #ifdef HAVE_DL_DLOPEN
284     el->handle = dlopen(el->name, RTLD_NOW);
285     if( !el->handle ) {
286         log_error("%s: error loading extension: %s\n", el->name, dlerror() );
287         goto failure;
288     }
289     name = (char**)dlsym(el->handle, SYMBOL_VERSION);
290     if( (err=dlerror()) ) {
291         log_error("%s: not a gnupg extension: %s\n", el->name, err );
292         goto failure;
293     }
294   #else /* have dld */
295     if( !did_dld_init ) {
296         did_dld_init = 1;
297         if( !mainpgm_path )
298             log_error("DLD is not correctly initialized\n");
299         else {
300             rc = dld_init( dld_find_executable(mainpgm_path) );
301             if( rc )
302                 log_error("DLD init failed: %s\n", dld_strerror(rc) );
303             else
304                 dld_available = 1;
305         }
306     }
307     if( !dld_available ) {
308         log_error("%s: DLD not available\n", el->name );
309         goto failure;
310     }
311
312     rc = dld_link( el->name );
313     if( rc ) {
314         log_error("%s: error loading extension: %s\n",
315                                     el->name, dld_strerror(rc) );
316         goto failure;
317     }
318     addr = dld_get_symbol(SYMBOL_VERSION);
319     if( !addr ) {
320         log_error("%s: not a gnupg extension: %s\n",
321                                 el->name, dld_strerror(dld_errno) );
322         goto failure;
323     }
324     name = (char**)addr;
325   #endif
326
327     if( g10_opt_verbose > 1 )
328         log_info("%s: %s%s%s%s\n", el->name, *name,
329                   el->hintstr? " (":"",
330                   el->hintstr? el->hintstr:"",
331                   el->hintstr? ")":"");
332
333   #ifdef HAVE_DL_DLOPEN
334     sym = dlsym(el->handle, SYMBOL_ENUM);
335     if( (err=dlerror()) ) {
336         log_error("%s: invalid gnupg extension: %s\n", el->name, err );
337         goto failure;
338     }
339     el->enumfunc = (void *(*)(int,int*,int*,int*))sym;
340   #else /* dld */
341     addr = dld_get_func(SYMBOL_ENUM);
342     if( !addr ) {
343         log_error("%s: invalid gnupg extension: %s\n",
344                                 el->name, dld_strerror(dld_errno) );
345         goto failure;
346     }
347     rc = dld_function_executable_p(SYMBOL_ENUM);
348     if( rc ) {
349         log_error("%s: extension function is not executable: %s\n",
350                                         el->name, dld_strerror(rc) );
351         goto failure;
352     }
353     el->enumfunc = (void *(*)(int,int*,int*,int*))addr;
354     el->handle = 1; /* mark as usable */
355   #endif
356
357   #ifdef HAVE_DL_DLOPEN
358     if( g10_opt_verbose > 2 ) {
359         /* list the contents of the module */
360         while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) {
361             if( vers != 1 ) {
362                 log_info("%s: ignoring func with version %d\n",el->name,vers);
363                 continue;
364             }
365             switch( class ) {
366               case 11:
367               case 21:
368               case 31:
369                 log_info("%s: provides %s algorithm %d\n", el->name,
370                                 class == 11? "md"     :
371                                 class == 21? "cipher" : "pubkey",
372                                                        *(int*)sym);
373                 break;
374               default:
375                 /*log_debug("%s: skipping class %d\n", el->name, class);*/
376                 break;
377             }
378         }
379     }
380   #endif
381     return 0;
382
383   failure:
384   #ifdef HAVE_DL_DLOPEN
385     if( el->handle ) {
386         dlclose(el->handle);
387         el->handle = NULL;
388     }
389   #endif
390     el->failed = 1;
391   #endif /*USE_DYNAMIC_LINKING*/
392     return -1;
393 }
394
395 #ifdef __riscos__
396 typedef
397 const char *(*DIGESTS_CAST)(int, size_t*,byte**, int*, int*,
398                             void (**)(void*),
399                             void (**)(void*,byte*,size_t),
400                             void (**)(void*),byte *(**)(void*));
401 #endif /* __riscos__ */
402
403 int
404 enum_gnupgext_digests( void **enum_context,
405             int *algo,
406             const char *(**r_get_info)( int, size_t*,byte**, int*, int*,
407                                        void (**)(void*),
408                                        void (**)(void*,byte*,size_t),
409                                        void (**)(void*),byte *(**)(void*)) )
410 {
411     EXTLIST r;
412     ENUMCONTEXT *ctx;
413
414     if( !*enum_context ) { /* init context */
415         ctx = m_alloc_clear( sizeof( *ctx ) );
416         ctx->r = extensions;
417         ctx->reqalgo = *algo;
418         *enum_context = ctx;
419     }
420     else if( !algo ) { /* release the context */
421         m_free(*enum_context);
422         *enum_context = NULL;
423         return 0;
424     }
425     else
426         ctx = *enum_context;
427
428     for( r = ctx->r; r; r = r->next )  {
429         int class, vers;
430
431         if( r->failed )
432             continue;
433         if( !r->handle && load_extension(r) )
434             continue;
435         /* get a digest info function */
436         if( ctx->sym )
437             goto inner_loop;
438         while( (ctx->sym = (*r->enumfunc)(10, &ctx->seq1, &class, &vers)) ) {
439             void *sym;
440             /* must check class because enumfunc may be wrong coded */
441             if( vers != 1 || class != 10 )
442                 continue;
443           inner_loop:
444 #ifndef __riscos__
445             *r_get_info = ctx->sym;
446 #else /* __riscos__ */
447             *r_get_info = (DIGESTS_CAST) ctx->sym;
448 #endif /* __riscos__ */
449             while( (sym = (*r->enumfunc)(11, &ctx->seq2, &class, &vers)) ) {
450                 if( vers != 1 || class != 11 )
451                     continue;
452                 *algo = *(int*)sym;
453                 ctx->r = r;
454                 return 1;
455             }
456             ctx->seq2 = 0;
457         }
458         ctx->seq1 = 0;
459     }
460     ctx->r = r;
461     return 0;
462 }
463
464 #ifdef __riscos__
465 typedef
466 const char *(*CIPHERS_CAST)(int, size_t*, size_t*, size_t*,
467                             int  (**)( void *, byte *, unsigned),
468                             void (**)( void *, byte *, byte *),
469                             void (**)( void *, byte *, byte *));
470 #endif /* __riscos__ */
471
472 const char *
473 enum_gnupgext_ciphers( void **enum_context, int *algo,
474                        size_t *keylen, size_t *blocksize, size_t *contextsize,
475                        int  (**setkeyf)( void *c, byte *key, unsigned keylen ),
476                        void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
477                        void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
478                      )
479 {
480     EXTLIST r;
481     ENUMCONTEXT *ctx;
482     const char * (*finfo)(int, size_t*, size_t*, size_t*,
483                           int  (**)( void *, byte *, unsigned),
484                           void (**)( void *, byte *, byte *),
485                           void (**)( void *, byte *, byte *));
486
487     if( !*enum_context ) { /* init context */
488         ctx = m_alloc_clear( sizeof( *ctx ) );
489         ctx->r = extensions;
490         *enum_context = ctx;
491     }
492     else if( !algo ) { /* release the context */
493         m_free(*enum_context);
494         *enum_context = NULL;
495         return NULL;
496     }
497     else
498         ctx = *enum_context;
499
500     for( r = ctx->r; r; r = r->next )  {
501         int class, vers;
502
503         if( r->failed )
504             continue;
505         if( !r->handle && load_extension(r) )
506             continue;
507         /* get a cipher info function */
508         if( ctx->sym )
509             goto inner_loop;
510         while( (ctx->sym = (*r->enumfunc)(20, &ctx->seq1, &class, &vers)) ) {
511             void *sym;
512             /* must check class because enumfunc may be wrong coded */
513             if( vers != 1 || class != 20 )
514                 continue;
515           inner_loop:
516 #ifndef __riscos__
517             finfo = ctx->sym;
518 #else /* __riscos__ */
519             finfo = (CIPHERS_CAST) ctx->sym;
520 #endif /* __riscos__ */
521             while( (sym = (*r->enumfunc)(21, &ctx->seq2, &class, &vers)) ) {
522                 const char *algname;
523                 if( vers != 1 || class != 21 )
524                     continue;
525                 *algo = *(int*)sym;
526                 algname = (*finfo)( *algo, keylen, blocksize, contextsize,
527                                     setkeyf, encryptf, decryptf );
528                 if( algname ) {
529                     ctx->r = r;
530                     return algname;
531                 }
532             }
533             ctx->seq2 = 0;
534         }
535         ctx->seq1 = 0;
536     }
537     ctx->r = r;
538     return NULL;
539 }
540
541 #ifdef __riscos__
542 typedef
543 const char *(*PUBKEYS_CAST)(int, int *, int *, int *, int *, int *,
544                             int (**)(int, unsigned, MPI *, MPI **),
545                             int (**)(int, MPI *),
546                             int (**)(int, MPI *, MPI , MPI *),
547                             int (**)(int, MPI *, MPI *, MPI *),
548                             int (**)(int, MPI *, MPI , MPI *),
549                             int (**)(int, MPI , MPI *, MPI *,
550                                      int (*)(void*,MPI), void *),
551                             unsigned (**)( int , MPI *));
552 #endif /* __riscos__ */
553
554 const char *
555 enum_gnupgext_pubkeys( void **enum_context, int *algo,
556     int *npkey, int *nskey, int *nenc, int *nsig, int *use,
557     int (**generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors ),
558     int (**check_secret_key)( int algo, MPI *skey ),
559     int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey ),
560     int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey ),
561     int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ),
562     int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey,
563                     int (*cmp)(void *, MPI), void *opaquev ),
564     unsigned (**get_nbits)( int algo, MPI *pkey ) )
565 {
566     EXTLIST r;
567     ENUMCONTEXT *ctx;
568     const char * (*finfo)( int, int *, int *, int *, int *, int *,
569                            int (**)( int, unsigned, MPI *, MPI **),
570                            int (**)( int, MPI * ),
571                            int (**)( int, MPI *, MPI , MPI * ),
572                            int (**)( int, MPI *, MPI *, MPI * ),
573                            int (**)( int, MPI *, MPI , MPI * ),
574                            int (**)( int, MPI , MPI *, MPI *,
575                                             int (*)(void*,MPI), void *),
576                            unsigned (**)( int , MPI * ) );
577
578     if( !*enum_context ) { /* init context */
579         ctx = m_alloc_clear( sizeof( *ctx ) );
580         ctx->r = extensions;
581         *enum_context = ctx;
582     }
583     else if( !algo ) { /* release the context */
584         m_free(*enum_context);
585         *enum_context = NULL;
586         return NULL;
587     }
588     else
589         ctx = *enum_context;
590
591     for( r = ctx->r; r; r = r->next )  {
592         int class, vers;
593
594         if( r->failed )
595             continue;
596         if( !r->handle && load_extension(r) )
597             continue;
598         /* get a pubkey info function */
599         if( ctx->sym )
600             goto inner_loop;
601         while( (ctx->sym = (*r->enumfunc)(30, &ctx->seq1, &class, &vers)) ) {
602             void *sym;
603             if( vers != 1 || class != 30 )
604                 continue;
605           inner_loop:
606 #ifndef __riscos__
607             finfo = ctx->sym;
608 #else /* __riscos__ */
609             finfo = (PUBKEYS_CAST) ctx->sym;
610 #endif /* __riscos__ */
611             while( (sym = (*r->enumfunc)(31, &ctx->seq2, &class, &vers)) ) {
612                 const char *algname;
613                 if( vers != 1 || class != 31 )
614                     continue;
615                 *algo = *(int*)sym;
616                 algname = (*finfo)( *algo, npkey, nskey, nenc, nsig, use,
617                                     generate, check_secret_key, encryptf,
618                                     decryptf, sign, verify, get_nbits );
619                 if( algname ) {
620                     ctx->r = r;
621                     return algname;
622                 }
623             }
624             ctx->seq2 = 0;
625         }
626         ctx->seq1 = 0;
627     }
628     ctx->r = r;
629     return NULL;
630 }
631
632
633 int (*
634 dynload_getfnc_gather_random())(void (*)(const void*, size_t, int), int,
635                                                             size_t, int)
636 {
637     EXTLIST r;
638     void *sym;
639
640     for( r = extensions; r; r = r->next )  {
641         int seq, class, vers;
642
643         if( r->failed )
644             continue;
645         if( !r->handle && load_extension(r) )
646             continue;
647         seq = 0;
648         while( (sym = (*r->enumfunc)(40, &seq, &class, &vers)) ) {
649             if( vers != 1 || class != 40 )
650                 continue;
651             return (int (*)(void (*)(const void*, size_t, int), int,
652                                                         size_t, int))sym;
653         }
654     }
655     return NULL;
656 }
657
658
659 void (*
660 dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int), int)
661 {
662     EXTLIST r;
663     void *sym;
664
665     for( r = extensions; r; r = r->next )  {
666         int seq, class, vers;
667
668         if( r->failed )
669             continue;
670         if( !r->handle && load_extension(r) )
671             continue;
672         seq = 0;
673         while( (sym = (*r->enumfunc)(41, &seq, &class, &vers)) ) {
674             if( vers != 1 || class != 41 )
675                 continue;
676             return (void (*)( void (*)(const void*, size_t, int), int))sym;
677         }
678     }
679     return NULL;
680 }
681