See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
[libgcrypt.git] / src / global.c
1 /* global.c  -  global control functions
2  *      Copyright (C) 1998 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 <stdarg.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include "g10lib.h"
30 #include "stdmem.h" /* our own memory allocator */
31 #include "secmem.h" /* our own secmem allocator */
32
33 /****************
34  * flag bits: 0 : general cipher debug
35  *            1 : general MPI debug
36  */
37 static unsigned int debug_flags;
38 static int last_ec; /* fixme: make thread safe */
39
40 static void *(*alloc_func)(size_t n) = NULL;
41 static void *(*alloc_secure_func)(size_t n) = NULL;
42 static int   (*is_secure_func)(const void*) = NULL;
43 static void *(*realloc_func)(void *p, size_t n) = NULL;
44 static void (*free_func)(void*) = NULL;
45 static int (*outofcore_handler)( void*, size_t, unsigned int ) = NULL;
46 static void *outofcore_handler_value = NULL;
47
48 static const char*
49 parse_version_number( const char *s, int *number )
50 {
51     int val = 0;
52
53     if( *s == '0' && isdigit(s[1]) )
54         return NULL; /* leading zeros are not allowed */
55     for ( ; isdigit(*s); s++ ) {
56         val *= 10;
57         val += *s - '0';
58     }
59     *number = val;
60     return val < 0? NULL : s;
61 }
62
63
64 static const char *
65 parse_version_string( const char *s, int *major, int *minor, int *micro )
66 {
67     s = parse_version_number( s, major );
68     if( !s || *s != '.' )
69         return NULL;
70     s++;
71     s = parse_version_number( s, minor );
72     if( !s || *s != '.' )
73         return NULL;
74     s++;
75     s = parse_version_number( s, micro );
76     if( !s )
77         return NULL;
78     return s; /* patchlevel */
79 }
80
81 /****************
82  * Check that the the version of the library is at minimum the requested one
83  * and return the version string; return NULL if the condition is not
84  * satisfied.  If a NULL is passed to this function, no check is done,
85  * but the version string is simply returned.
86  */
87 const char *
88 gcry_check_version( const char *req_version )
89 {
90     const char *ver = VERSION;
91     int my_major, my_minor, my_micro;
92     int rq_major, rq_minor, rq_micro;
93     const char *my_plvl, *rq_plvl;
94
95     if ( !req_version )
96         return ver;
97
98     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
99     if ( !my_plvl )
100         return NULL;  /* very strange our own version is bogus */
101     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
102                                                                 &rq_micro );
103     if ( !rq_plvl )
104         return NULL;  /* req version string is invalid */
105
106     if ( my_major > rq_major
107         || (my_major == rq_major && my_minor > rq_minor)
108         || (my_major == rq_major && my_minor == rq_minor
109                                  && my_micro > rq_micro)
110         || (my_major == rq_major && my_minor == rq_minor
111                                  && my_micro == rq_micro
112                                  && strcmp( my_plvl, rq_plvl ) >= 0) ) {
113         return ver;
114     }
115     return NULL;
116 }
117
118
119 int
120 gcry_control( enum gcry_ctl_cmds cmd, ... )
121 {
122     va_list arg_ptr ;
123
124     va_start( arg_ptr, cmd ) ;
125     switch( cmd ) {
126      #if 0
127       case GCRYCTL_NO_MEM_IS_FATAL:
128         break;
129       case GCRYCTL_SET_FATAL_FNC:
130         break;
131      #endif
132
133       case GCRYCTL_ENABLE_M_GUARD:
134         g10_private_enable_m_guard();
135         break;
136
137       case GCRYCTL_DUMP_RANDOM_STATS:
138         random_dump_stats();
139         break;
140
141       case GCRYCTL_DUMP_MEMORY_STATS:
142         /*m_print_stats("[fixme: prefix]");*/
143         break;
144
145       case GCRYCTL_DUMP_SECMEM_STATS:
146         secmem_dump_stats();
147         break;
148
149       case GCRYCTL_DROP_PRIVS:
150         secmem_init( 0 );
151         break;
152
153       case GCRYCTL_INIT_SECMEM:
154         secmem_init( va_arg( arg_ptr, unsigned int ) );
155         break;
156
157       case GCRYCTL_TERM_SECMEM:
158         secmem_term();
159         break;
160
161       case GCRYCTL_DISABLE_SECMEM_WARN:
162         secmem_set_flags( secmem_get_flags() | 1 );
163         break;
164
165       case GCRYCTL_SUSPEND_SECMEM_WARN:
166         secmem_set_flags( secmem_get_flags() | 2 );
167         break;
168
169       case GCRYCTL_RESUME_SECMEM_WARN:
170         secmem_set_flags( secmem_get_flags() & ~2 );
171         break;
172
173       case GCRYCTL_USE_SECURE_RNDPOOL:
174         secure_random_alloc(); /* put random number into secure memory */
175         break;
176
177       case GCRYCTL_SET_VERBOSITY:
178         g10_set_log_verbosity( va_arg( arg_ptr, int ) );
179         break;
180
181       case GCRYCTL_SET_DEBUG_FLAGS:
182         debug_flags |= va_arg( arg_ptr, unsigned int );
183         break;
184
185       case GCRYCTL_CLEAR_DEBUG_FLAGS:
186         debug_flags &= ~va_arg( arg_ptr, unsigned int );
187         break;
188
189       default:
190         va_end(arg_ptr);
191         return GCRYERR_INV_OP;
192     }
193     va_end(arg_ptr);
194     return 0;
195 }
196
197 int
198 gcry_errno()
199 {
200     return last_ec;
201 }
202
203 const char*
204 gcry_strerror( int ec )
205 {
206     const char *s;
207     static char buf[20];
208
209     if( ec == -1 )
210         ec = gcry_errno();
211   #define X(n,a) case GCRYERR_##n : s = a; break;
212     switch( ec ) {
213       X(SUCCESS,        N_("no error"))
214       X(GENERAL,        N_("general error"))
215       X(INV_OP,         N_("invalid operation code or ctl command"))
216       X(NO_MEM,         N_("out of core"))
217       X(INV_ARG,        N_("invalid argument"))
218       X(INTERNAL,       N_("internal error"))
219       X(EOF,            N_("EOF"))
220       X(TOO_SHORT,      N_("provided buffer too short"))
221       X(TOO_LARGE,      N_("object is too large"))
222       X(INV_OBJ,        N_("an object is not valid"))
223       X(WEAK_KEY,       N_("weak encryption key"))
224       X(INV_PK_ALGO,    N_("invalid public key algorithm"))
225       X(INV_CIPHER_ALGO,N_("invalid cipher algorithm"))
226       X(INV_MD_ALGO,    N_("invalid hash algorithm"))
227       X(WRONG_PK_ALGO,  N_("unusable public key algorithm"))
228       X(CONFLICT,       N_("conflict"))
229       default:
230         sprintf( buf, "ec=%d", ec );
231         s = buf;
232     }
233   #undef X
234     return s;
235 }
236
237
238 int
239 set_lasterr( int ec )
240 {
241     if( ec )
242         last_ec = ec == -1 ? GCRYERR_EOF : ec;
243     return ec;
244 }
245
246
247
248 /****************
249  * NOTE: All 5 functions should be set.
250  */
251 void
252 gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n),
253                              void *(*new_alloc_secure_func)(size_t n),
254                              int (*new_is_secure_func)(const void*),
255                              void *(*new_realloc_func)(void *p, size_t n),
256                              void (*new_free_func)(void*) )
257 {
258     alloc_func        = new_alloc_func;
259     alloc_secure_func = new_alloc_secure_func;
260     is_secure_func    = new_is_secure_func;
261     realloc_func      = new_realloc_func;
262     free_func         = new_free_func;
263 }
264
265
266
267 /****************
268  * Set an optional handler which is called in case the xmalloc functions
269  * ran out of memory.  This handler may do one of these things:
270  *   o free some memory and return true, so that the xmalloc function
271  *     tries again.
272  *   o Do whatever it like and return false, so that the xmalloc functions
273  *     use the default fatal error handler.
274  *   o Terminate the program and don't return.
275  *
276  * The handler function is called with 3 arguments:  The opaque value set with
277  * this function, the requested memory size, and a flag with these bits
278  * currently defined:
279  *      bit 0 set = secure memory has been requested.
280  */
281 void
282 gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
283                                                         void *value )
284 {
285     outofcore_handler = f;
286     outofcore_handler_value = value;
287 }
288
289
290
291 void *
292 g10_malloc( size_t n )
293 {
294     if( alloc_func )
295         return alloc_func( n ) ;
296     return g10_private_malloc( n );
297 }
298
299 void *
300 g10_malloc_secure( size_t n )
301 {
302     if( alloc_secure_func )
303         return alloc_secure_func( n ) ;
304     return g10_private_malloc_secure( n );
305 }
306
307 int
308 g10_is_secure( const void *a )
309 {
310     if( is_secure_func )
311         return is_secure_func( a ) ;
312     return g10_private_is_secure( a );
313 }
314
315 void
316 g10_check_heap( const void *a )
317 {
318     /* FIXME: implement this*/
319   #if 0
320     if( some_handler )
321         some_handler(a)
322     else
323         g10_private_check_heap(a)
324   #endif
325 }
326
327 void *
328 g10_realloc( void *a, size_t n )
329 {
330     /* FIXME: Make sure that the realloced memory is cleared out */
331
332     if( realloc_func )
333         return realloc_func( a, n ) ;
334     return g10_private_realloc( a, n );
335 }
336
337 void
338 g10_free( void *p )
339 {
340     if( !p )
341         return;
342
343     if( free_func )
344         free_func( p );
345     else
346         g10_private_free( p );
347 }
348
349 void *
350 g10_calloc( size_t n, size_t m )
351 {
352     void *p = g10_malloc( n*m );
353     if( p )
354         memset( p, 0, n*m );
355     return p;
356 }
357
358 void *
359 g10_calloc_secure( size_t n, size_t m )
360 {
361     void *p = g10_malloc_secure( n*m );
362     if( p )
363         memset( p, 0, n*m );
364     return p;
365 }
366
367
368 void *
369 g10_xmalloc( size_t n )
370 {
371     void *p;
372
373     while ( !(p = g10_malloc( n )) ) {
374         if( !outofcore_handler
375             || !outofcore_handler( outofcore_handler_value, n, 0 ) ) {
376             g10_fatal_error(GCRYERR_NO_MEM, NULL );
377         }
378     }
379     return p;
380 }
381
382 void *
383 g10_xrealloc( void *a, size_t n )
384 {
385     void *p;
386
387     while ( !(p = g10_realloc( a, n )) ) {
388         if( !outofcore_handler
389             || !outofcore_handler( outofcore_handler_value, n, 2 ) ) {
390             g10_fatal_error(GCRYERR_NO_MEM, NULL );
391         }
392     }
393     return p;
394 }
395
396 void *
397 g10_xmalloc_secure( size_t n )
398 {
399     void *p;
400
401     while ( !(p = g10_malloc_secure( n )) ) {
402         if( !outofcore_handler
403             || !outofcore_handler( outofcore_handler_value, n, 1 ) ) {
404             g10_fatal_error(GCRYERR_NO_MEM,
405                              _("out of core in secure memory"));
406         }
407     }
408     return p;
409 }
410
411 void *
412 g10_xcalloc( size_t n, size_t m )
413 {
414     void *p = g10_xmalloc( n*m );
415     memset( p, 0, n*m );
416     return p;
417 }
418
419 void *
420 g10_xcalloc_secure( size_t n, size_t m )
421 {
422     void *p = g10_xmalloc_secure( n* m );
423     memset( p, 0, n*m );
424     return p;
425 }
426
427 char *
428 g10_xstrdup( const char *string )
429 {
430     void *p = g10_xmalloc( strlen(string)+1 );
431     strcpy( p, string );
432     return p;
433 }
434
435
436 int
437 g10_get_debug_flag( unsigned int mask )
438 {
439     return debug_flags & mask;
440 }
441
442