prototypes fixed
[libgcrypt.git] / src / global.c
1 /* global.c  -  global control functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt 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 Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License 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 <stdarg.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include "g10lib.h"
30 #include "../cipher/random.h"
31 #include "stdmem.h" /* our own memory allocator */
32 #include "secmem.h" /* our own secmem allocator */
33
34
35 /****************
36  * flag bits: 0 : general cipher debug
37  *            1 : general MPI debug
38  */
39 static unsigned int debug_flags;
40 static int last_ec; /* fixme: make thread safe */
41
42 static void *(*alloc_func)(size_t n) = NULL;
43 static void *(*alloc_secure_func)(size_t n) = NULL;
44 static int   (*is_secure_func)(const void*) = NULL;
45 static void *(*realloc_func)(void *p, size_t n) = NULL;
46 static void (*free_func)(void*) = NULL;
47 static int (*outofcore_handler)( void*, size_t, unsigned int ) = NULL;
48 static void *outofcore_handler_value = NULL;
49 static int no_internal_locking = 0;
50 static int no_secure_memory = 0;
51 static int any_init_done = 0;
52
53 static const char*
54 parse_version_number( const char *s, int *number )
55 {
56     int val = 0;
57
58     if( *s == '0' && isdigit(s[1]) )
59         return NULL; /* leading zeros are not allowed */
60     for ( ; isdigit(*s); s++ ) {
61         val *= 10;
62         val += *s - '0';
63     }
64     *number = val;
65     return val < 0? NULL : s;
66 }
67
68
69 static const char *
70 parse_version_string( const char *s, int *major, int *minor, int *micro )
71 {
72     s = parse_version_number( s, major );
73     if( !s || *s != '.' )
74         return NULL;
75     s++;
76     s = parse_version_number( s, minor );
77     if( !s || *s != '.' )
78         return NULL;
79     s++;
80     s = parse_version_number( s, micro );
81     if( !s )
82         return NULL;
83     return s; /* patchlevel */
84 }
85
86 /****************
87  * Check that the the version of the library is at minimum the requested one
88  * and return the version string; return NULL if the condition is not
89  * satisfied.  If a NULL is passed to this function, no check is done,
90  * but the version string is simply returned.
91  */
92 const char *
93 gcry_check_version( const char *req_version )
94 {
95     const char *ver = VERSION;
96     int my_major, my_minor, my_micro;
97     int rq_major, rq_minor, rq_micro;
98     const char *my_plvl, *rq_plvl;
99
100     if ( !req_version )
101         return ver;
102
103     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
104     if ( !my_plvl )
105         return NULL;  /* very strange our own version is bogus */
106     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
107                                                                 &rq_micro );
108     if ( !rq_plvl )
109         return NULL;  /* req version string is invalid */
110
111     if ( my_major > rq_major
112         || (my_major == rq_major && my_minor > rq_minor)
113         || (my_major == rq_major && my_minor == rq_minor
114                                  && my_micro > rq_micro)
115         || (my_major == rq_major && my_minor == rq_minor
116                                  && my_micro == rq_micro
117                                  && strcmp( my_plvl, rq_plvl ) >= 0) ) {
118         return ver;
119     }
120     return NULL;
121 }
122
123
124 int
125 gcry_control( enum gcry_ctl_cmds cmd, ... )
126 {
127     static int init_finished = 0;
128     va_list arg_ptr ;
129
130     va_start( arg_ptr, cmd ) ;
131     switch( cmd ) {
132      #if 0
133       case GCRYCTL_NO_MEM_IS_FATAL:
134         break;
135       case GCRYCTL_SET_FATAL_FNC:
136         break;
137      #endif
138
139       case GCRYCTL_ENABLE_M_GUARD:
140         _gcry_private_enable_m_guard();
141         break;
142
143       case GCRYCTL_DUMP_RANDOM_STATS:
144         _gcry_random_dump_stats();
145         break;
146
147       case GCRYCTL_DUMP_MEMORY_STATS:
148         /*m_print_stats("[fixme: prefix]");*/
149         break;
150
151       case GCRYCTL_DUMP_SECMEM_STATS:
152         _gcry_secmem_dump_stats();
153         break;
154
155       case GCRYCTL_DROP_PRIVS:
156         any_init_done = 1;
157         _gcry_secmem_init( 0 );
158         break;
159
160       case GCRYCTL_DISABLE_SECMEM:
161         any_init_done = 1;
162         no_secure_memory = 1;
163         break;    
164
165       case GCRYCTL_INIT_SECMEM:
166         any_init_done = 1;
167         _gcry_secmem_init( va_arg( arg_ptr, unsigned int ) );
168         break;
169
170       case GCRYCTL_TERM_SECMEM:
171         any_init_done = 1;
172         _gcry_secmem_term();
173         break;
174
175       case GCRYCTL_DISABLE_SECMEM_WARN:
176         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() | 1) );
177         break;
178
179       case GCRYCTL_SUSPEND_SECMEM_WARN:
180         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() | 2) );
181         break;
182
183       case GCRYCTL_RESUME_SECMEM_WARN:
184         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() & ~2) );
185         break;
186
187       case GCRYCTL_USE_SECURE_RNDPOOL:
188         any_init_done = 1;
189         _gcry_secure_random_alloc(); /* put random number into secure memory */
190         break;
191
192       case GCRYCTL_SET_VERBOSITY:
193         _gcry_set_log_verbosity( va_arg( arg_ptr, int ) );
194         break;
195
196       case GCRYCTL_SET_DEBUG_FLAGS:
197         debug_flags |= va_arg( arg_ptr, unsigned int );
198         break;
199
200       case GCRYCTL_CLEAR_DEBUG_FLAGS:
201         debug_flags &= ~va_arg( arg_ptr, unsigned int );
202         break;
203
204       case GCRYCTL_DISABLE_INTERNAL_LOCKING:
205         any_init_done = 1;
206         no_internal_locking = 1;
207         break;
208
209       case GCRYCTL_ANY_INITIALIZATION_P:
210         va_end(arg_ptr);
211         return any_init_done? -1 : 0;
212
213       case GCRYCTL_INITIALIZATION_FINISHED_P:
214         va_end(arg_ptr);
215         return init_finished? -1 : 0;
216
217       case GCRYCTL_INITIALIZATION_FINISHED:
218         /* This is a hook which should be used by an application after
219            all intialization has been done and right before any
220            threads are started.  It is not really needed but the only
221            way to be really sure that all initialization for
222            thread-safety has been done. */
223         if (!init_finished) {
224             any_init_done = 1;
225             /* fixme: we should initialize the various mutexs here */
226             init_finished = 1;
227         }
228         break;
229
230       default:
231         va_end(arg_ptr);
232         return GCRYERR_INV_OP;
233     }
234     va_end(arg_ptr);
235     return 0;
236 }
237
238 int
239 gcry_errno()
240 {
241     return last_ec;
242 }
243
244 const char*
245 gcry_strerror( int ec )
246 {
247     const char *s;
248     static char buf[20];
249
250     if( ec == -1 )
251         ec = gcry_errno();
252   #define X(n,a) case GCRYERR_##n : s = a; break;
253     switch( ec ) {
254       X(SUCCESS,        N_("no error"))
255       X(GENERAL,        N_("general error"))
256
257       X(INV_PK_ALGO,    N_("invalid public key algorithm"))
258       X(INV_MD_ALGO,    N_("invalid hash algorithm"))
259       X(BAD_PUBLIC_KEY ,N_("bad public key"))
260       X(BAD_SECRET_KEY ,N_("bad secret key"))
261       X(BAD_SIGNATURE , N_("bad signature"))
262
263       X(INV_CIPHER_ALGO,N_("invalid cipher algorithm"))
264       X(BAD_MPI,        N_("bad big integer"))
265       X(WRONG_PK_ALGO,  N_("unusable public key algorithm"))
266       X(WEAK_KEY,       N_("weak encryption key"))
267       X(INV_KEYLEN,     N_("invalid key length"))
268       X(INV_ARG,        N_("invalid argument"))
269       X(SELFTEST,       N_("selftest failed"))
270
271       X(INV_OP,         N_("invalid operation code or ctl command"))
272       X(NO_MEM,         N_("out of core"))
273       X(INTERNAL,       N_("internal error"))
274       X(EOF,            N_("EOF"))
275       X(INV_OBJ,        N_("an object is not valid"))
276       X(TOO_SHORT,      N_("provided buffer too short"))
277       X(TOO_LARGE,      N_("object is too large"))
278       X(NO_OBJ,         N_("no object"))
279       X(NOT_IMPL,       N_("not implemented"))
280       X(CONFLICT,       N_("conflict"))
281       X(INV_CIPHER_MODE,N_("invalid cipher mode"))
282
283         X(SEXP_INV_LEN_SPEC   ,N_("invalid length specification")) 
284         X(SEXP_STRING_TOO_LONG,N_("string too long")) 
285         X(SEXP_UNMATCHED_PAREN,N_("unmatched parenthesis")) 
286         X(SEXP_NOT_CANONICAL  ,N_("not a canonical S-expression")) 
287         X(SEXP_BAD_CHARACTER  ,N_("bad character")) 
288         X(SEXP_BAD_QUOTATION  ,N_("invalid hex/octal value or bad quotation")) 
289         X(SEXP_ZERO_PREFIX    ,N_("a length may not begin with zero")) 
290         X(SEXP_NESTED_DH      ,N_("nested display hints")) 
291         X(SEXP_UNMATCHED_DH   ,N_("unmatched display hint close")) 
292         X(SEXP_UNEXPECTED_PUNC,N_("unexpected reserved punctuation")) 
293         X(SEXP_BAD_HEX_CHAR,   N_("invalid hex character"))
294         X(SEXP_ODD_HEX_NUMBERS,N_("odd number of hex characters"))
295         X(SEXP_BAD_OCT_CHAR,   N_("invalid octal character"))
296
297       default:
298         sprintf( buf, "ec=%d", ec );
299         s = buf;
300     }
301   #undef X
302     return s;
303 }
304
305
306 int
307 _gcry_set_lasterr( int ec )
308 {
309     if( ec )
310         last_ec = ec == -1 ? GCRYERR_EOF : ec;
311     return ec;
312 }
313
314
315
316 /****************
317  * NOTE: All 5 functions should be set.  */
318 void
319 gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n),
320                              void *(*new_alloc_secure_func)(size_t n),
321                              int (*new_is_secure_func)(const void*),
322                              void *(*new_realloc_func)(void *p, size_t n),
323                              void (*new_free_func)(void*) )
324 {
325     any_init_done = 1;
326
327     alloc_func        = new_alloc_func;
328     alloc_secure_func = new_alloc_secure_func;
329     is_secure_func    = new_is_secure_func;
330     realloc_func      = new_realloc_func;
331     free_func         = new_free_func;
332 }
333
334
335
336 /****************
337  * Set an optional handler which is called in case the xmalloc functions
338  * ran out of memory.  This handler may do one of these things:
339  *   o free some memory and return true, so that the xmalloc function
340  *     tries again.
341  *   o Do whatever it like and return false, so that the xmalloc functions
342  *     use the default fatal error handler.
343  *   o Terminate the program and don't return.
344  *
345  * The handler function is called with 3 arguments:  The opaque value set with
346  * this function, the requested memory size, and a flag with these bits
347  * currently defined:
348  *      bit 0 set = secure memory has been requested.
349  */
350 void
351 gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
352                                                         void *value )
353 {
354     any_init_done = 1;
355
356     outofcore_handler = f;
357     outofcore_handler_value = value;
358 }
359
360
361
362 void *
363 gcry_malloc( size_t n )
364 {
365     if( alloc_func )
366         return alloc_func( n ) ;
367     return _gcry_private_malloc( n );
368 }
369
370 void *
371 gcry_malloc_secure( size_t n )
372 {
373   if (no_secure_memory)
374     return gcry_malloc (n);
375   if (alloc_secure_func)
376     return alloc_secure_func (n) ;
377   return _gcry_private_malloc_secure (n);
378 }
379
380 int
381 gcry_is_secure( const void *a )
382 {
383   if (no_secure_memory)
384     return 0;
385   if (is_secure_func)
386     return is_secure_func (a) ;
387   return _gcry_private_is_secure (a);
388 }
389
390 void
391 _gcry_check_heap( const void *a )
392 {
393     /* FIXME: implement this*/
394   #if 0
395     if( some_handler )
396         some_handler(a)
397     else
398         _gcry_private_check_heap(a)
399   #endif
400 }
401
402 void *
403 gcry_realloc( void *a, size_t n )
404 {
405     /* FIXME: Make sure that the realloced memory is cleared out */
406
407     if( realloc_func )
408         return realloc_func( a, n ) ;
409     return _gcry_private_realloc( a, n );
410 }
411
412 void
413 gcry_free( void *p )
414 {
415     if( !p )
416         return;
417
418     if( free_func )
419         free_func( p );
420     else
421         _gcry_private_free( p );
422 }
423
424 void *
425 gcry_calloc( size_t n, size_t m )
426 {
427     void *p = gcry_malloc( n*m );
428     if( p )
429         memset( p, 0, n*m );
430     return p;
431 }
432
433 void *
434 gcry_calloc_secure( size_t n, size_t m )
435 {
436     void *p = gcry_malloc_secure( n*m );
437     if( p )
438         memset( p, 0, n*m );
439     return p;
440 }
441
442
443 char *
444 gcry_strdup( const char *string )
445 {
446     void *p = gcry_malloc( strlen(string)+1 );
447     strcpy( p, string );
448     return p;
449 }
450
451
452 void *
453 gcry_xmalloc( size_t n )
454 {
455     void *p;
456
457     while ( !(p = gcry_malloc( n )) ) {
458         if( !outofcore_handler
459             || !outofcore_handler( outofcore_handler_value, n, 0 ) ) {
460             _gcry_fatal_error(GCRYERR_NO_MEM, NULL );
461         }
462     }
463     return p;
464 }
465
466 void *
467 gcry_xrealloc( void *a, size_t n )
468 {
469     void *p;
470
471     while ( !(p = gcry_realloc( a, n )) ) {
472         if( !outofcore_handler
473             || !outofcore_handler( outofcore_handler_value, n, 2 ) ) {
474             _gcry_fatal_error(GCRYERR_NO_MEM, NULL );
475         }
476     }
477     return p;
478 }
479
480 void *
481 gcry_xmalloc_secure( size_t n )
482 {
483     void *p;
484
485     while ( !(p = gcry_malloc_secure( n )) ) {
486         if( !outofcore_handler
487             || !outofcore_handler( outofcore_handler_value, n, 1 ) ) {
488             _gcry_fatal_error(GCRYERR_NO_MEM,
489                              _("out of core in secure memory"));
490         }
491     }
492     return p;
493 }
494
495 void *
496 gcry_xcalloc( size_t n, size_t m )
497 {
498     void *p = gcry_xmalloc( n*m );
499     memset( p, 0, n*m );
500     return p;
501 }
502
503 void *
504 gcry_xcalloc_secure( size_t n, size_t m )
505 {
506     void *p = gcry_xmalloc_secure( n* m );
507     memset( p, 0, n*m );
508     return p;
509 }
510
511 char *
512 gcry_xstrdup( const char *string )
513 {
514     void *p = gcry_xmalloc( strlen(string)+1 );
515     strcpy( p, string );
516     return p;
517 }
518
519
520 int
521 _gcry_get_debug_flag( unsigned int mask )
522 {
523     return debug_flags & mask;
524 }
525
526 int 
527 _gcry_no_internal_locking (void)
528 {
529   return no_internal_locking;
530 }
531
532 \f
533 /* It is often useful to get some feedback of long running operations.
534    This function may be used to register a handler for this. 
535    The callback function CB is used as:
536
537    void cb (void *opaque, const char *what, int printchar,
538            int current, int total);
539
540    Where WHAT is a string identifying the the type of the progress
541    output, PRINTCHAR the character usually printed, CURRENT the amount
542    of progress currently done and TOTAL the expected amount of
543    progress.  A value of 0 for TOTAL indicates that there is no
544    estimation available.
545 */
546 void
547 gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
548                            void *cb_data)
549 {
550   _gcry_register_pk_dsa_progress (cb, cb_data);
551   _gcry_register_pk_elg_progress (cb, cb_data);
552   _gcry_register_primegen_progress (cb, cb_data);
553 }
554
555