002a84f69295cbb5bba17a1769e0b8b9d7b15d1a
[libgcrypt.git] / src / misc.c
1 /* misc.c
2  * Copyright (C) 1999, 2001, 2002, 2003, 2007,
3  *               2008 Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28
29 #include "g10lib.h"
30 #include "secmem.h"
31 #include "mpi.h"
32
33 static int verbosity_level = 0;
34
35 static void (*fatal_error_handler)(void*,int, const char*) = NULL;
36 static void *fatal_error_handler_value = 0;
37 static void (*log_handler)(void*,int, const char*, va_list) = NULL;
38 static void *log_handler_value = 0;
39
40 static const char *(*user_gettext_handler)( const char * ) = NULL;
41
42 void
43 _gcry_set_gettext_handler (const char *(*f)(const char*))
44 {
45     user_gettext_handler = f;
46 }
47
48
49 const char *
50 _gcry_gettext( const char *key )
51 {
52     if( user_gettext_handler )
53         return user_gettext_handler( key );
54     /* FIXME: switch the domain to gnupg and restore later */
55     return key;
56 }
57
58 void
59 _gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
60 {
61     fatal_error_handler_value = value;
62     fatal_error_handler = fnc;
63 }
64
65 static void
66 write2stderr( const char *s )
67 {
68   /* Dummy variable to silence gcc warning.  */
69   int res = write( 2, s, strlen(s) );
70   (void) res;
71 }
72
73 /*
74  * This function is called for fatal errors.  A caller might want to
75  * set his own handler because this function simply calls abort().
76  */
77 void
78 _gcry_fatal_error (int rc, const char *text)
79 {
80   if ( !text ) /* get a default text */
81     text = gpg_strerror (rc);
82
83   if (fatal_error_handler && !fips_mode () )
84     fatal_error_handler (fatal_error_handler_value, rc, text);
85
86   fips_signal_fatal_error (text);
87   write2stderr("\nFatal error: ");
88   write2stderr(text);
89   write2stderr("\n");
90   _gcry_secmem_term ();
91   abort ();
92 }
93
94 void
95 _gcry_set_log_handler (void (*f)(void*,int, const char*, va_list), void *opaque)
96 {
97     log_handler = f;
98     log_handler_value = opaque;
99 }
100
101 void
102 _gcry_set_log_verbosity( int level )
103 {
104     verbosity_level = level;
105 }
106
107 int
108 _gcry_log_verbosity( int level )
109 {
110     return verbosity_level >= level;
111 }
112
113 /****************
114  * This is our log function which prints all log messages to stderr or
115  * using the function defined with gcry_set_log_handler().
116  */
117 void
118 _gcry_logv( int level, const char *fmt, va_list arg_ptr )
119 {
120   if (log_handler)
121     log_handler (log_handler_value, level, fmt, arg_ptr);
122   else
123     {
124       switch (level)
125         {
126         case GCRY_LOG_CONT:  break;
127         case GCRY_LOG_INFO:  break;
128         case GCRY_LOG_WARN:  break;
129         case GCRY_LOG_ERROR: break;
130         case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
131         case GCRY_LOG_BUG:   fputs("Ohhhh jeeee: ", stderr); break;
132         case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
133         default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
134         }
135       vfprintf(stderr,fmt,arg_ptr) ;
136     }
137
138   if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
139     {
140       fips_signal_fatal_error ("internal error (fatal or bug)");
141       _gcry_secmem_term ();
142       abort ();
143     }
144 }
145
146
147 void
148 _gcry_log( int level, const char *fmt, ... )
149 {
150     va_list arg_ptr ;
151
152     va_start( arg_ptr, fmt ) ;
153     _gcry_logv( level, fmt, arg_ptr );
154     va_end(arg_ptr);
155 }
156
157
158 #if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
159 void
160 _gcry_bug( const char *file, int line, const char *func )
161 {
162     _gcry_log( GCRY_LOG_BUG,
163              ("... this is a bug (%s:%d:%s)\n"), file, line, func );
164     abort(); /* never called, but it makes the compiler happy */
165 }
166 void
167 _gcry_assert_failed (const char *expr, const char *file, int line,
168                      const char *func)
169 {
170   _gcry_log (GCRY_LOG_BUG,
171              ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func );
172   abort(); /* Never called, but it makes the compiler happy. */
173 }
174 #else
175 void
176 _gcry_bug( const char *file, int line )
177 {
178     _gcry_log( GCRY_LOG_BUG,
179              _("you found a bug ... (%s:%d)\n"), file, line);
180     abort(); /* never called, but it makes the compiler happy */
181 }
182 void
183 _gcry_assert_failed (const char *expr, const char *file, int line)
184 {
185   _gcry_log (GCRY_LOG_BUG,
186              ("Assertion `%s' failed (%s:%d)\n"), expr, file, line);
187   abort(); /* Never called, but it makes the compiler happy. */
188 }
189 #endif
190
191 void
192 _gcry_log_info( const char *fmt, ... )
193 {
194     va_list arg_ptr ;
195
196     va_start( arg_ptr, fmt ) ;
197     _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
198     va_end(arg_ptr);
199 }
200
201 void
202 _gcry_log_error( const char *fmt, ... )
203 {
204     va_list arg_ptr ;
205
206     va_start( arg_ptr, fmt ) ;
207     _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
208     va_end(arg_ptr);
209 }
210
211
212 void
213 _gcry_log_fatal( const char *fmt, ... )
214 {
215     va_list arg_ptr ;
216
217     va_start( arg_ptr, fmt ) ;
218     _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
219     va_end(arg_ptr);
220     abort(); /* never called, but it makes the compiler happy */
221 }
222
223 void
224 _gcry_log_bug( const char *fmt, ... )
225 {
226     va_list arg_ptr ;
227
228     va_start( arg_ptr, fmt ) ;
229     _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
230     va_end(arg_ptr);
231     abort(); /* never called, but it makes the compiler happy */
232 }
233
234 void
235 _gcry_log_debug( const char *fmt, ... )
236 {
237     va_list arg_ptr ;
238
239     va_start( arg_ptr, fmt ) ;
240     _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
241     va_end(arg_ptr);
242 }
243
244
245 void
246 _gcry_log_printf (const char *fmt, ...)
247 {
248   va_list arg_ptr;
249
250   if (fmt)
251     {
252       va_start( arg_ptr, fmt ) ;
253       _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
254       va_end(arg_ptr);
255     }
256 }
257
258
259 /* Helper for _gcry_log_printhex and _gcry_log_printmpi.  */
260 static void
261 do_printhex (const char *text, const char *text2,
262              const void *buffer, size_t length)
263 {
264   int wrap = 0;
265   int cnt = 0;
266
267   if (text && *text)
268     {
269       wrap = 1;
270       log_debug ("%s:%s", text, text2);
271       if (text2[1] == '[' && length && buffer)
272         {
273           /* Start with a new line so that we get nice output for
274              opaque MPIS:
275                "value: [31 bit]"
276                "        01020300"  */
277           log_printf ("\n");
278           text2 = " ";
279           log_debug ("%*s  ", (int)strlen(text), "");
280         }
281     }
282   if (length && buffer)
283     {
284       const unsigned char *p = buffer;
285       for (; length--; p++)
286         {
287           log_printf ("%02x", *p);
288           if (wrap && ++cnt == 32 && length)
289             {
290               cnt = 0;
291               log_printf (" \\\n");
292               log_debug ("%*s %*s",
293                          (int)strlen(text), "", (int)strlen(text2), "");
294             }
295         }
296     }
297   if (text)
298     log_printf ("\n");
299 }
300
301
302 /* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
303    dump without any wrappping, with TEXT an empty string, print a
304    trailing linefeed, otherwise print an entire debug line. */
305 void
306 _gcry_log_printhex (const char *text, const void *buffer, size_t length)
307 {
308   do_printhex (text, " ", buffer, length);
309 }
310
311
312 /* Print MPI in hex notation.  To make clear that the output is an MPI
313    a sign is always printed. With TEXT of NULL print just the raw dump
314    without any wrapping, with TEXT an empty string, print a trailing
315    linefeed, otherwise print an entire debug line. */
316 void
317 _gcry_log_printmpi (const char *text, gcry_mpi_t mpi)
318 {
319   unsigned char *rawmpi;
320   unsigned int rawmpilen;
321   int sign;
322
323   if (!mpi)
324     do_printhex (text? text:" ", " (null)", NULL, 0);
325   else if (mpi_is_opaque (mpi))
326     {
327       unsigned int nbits;
328       const unsigned char *p;
329       char prefix[30];
330
331       p = mpi_get_opaque (mpi, &nbits);
332       snprintf (prefix, sizeof prefix, " [%u bit]", nbits);
333       do_printhex (text? text:" ", prefix, p, (nbits+7)/8);
334     }
335   else
336     {
337       rawmpi = _gcry_mpi_get_buffer (mpi, 0, &rawmpilen, &sign);
338       if (!rawmpi)
339         do_printhex (text? text:" ", " [out of core]", NULL, 0);
340       else
341         {
342           if (!rawmpilen)
343             do_printhex (text, sign? "-":"+", "", 1);
344           else
345             do_printhex (text, sign? "-":"+", rawmpi, rawmpilen);
346           xfree (rawmpi);
347         }
348     }
349 }
350
351
352 static int
353 count_closing_parens (const char *p)
354 {
355   int count = 0;
356
357   for (; *p; p++)
358     if (*p == ')')
359       count++;
360     else if (!strchr ("\n \t", *p))
361       return 0;
362
363   return count;
364 }
365
366
367 /* Print SEXP in human readabale format.  With TEXT of NULL print just the raw
368    dump without any wrappping, with TEXT an empty string, print a
369    trailing linefeed, otherwise print the full debug output. */
370 void
371 _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
372 {
373   int with_lf = 0;
374
375   if (text && *text)
376     {
377       if ((with_lf = !!strchr (text, '\n')))
378         log_debug ("%s", text);
379       else
380         log_debug ("%s: ", text);
381     }
382   if (sexp)
383     {
384       int any = 0;
385       int n_closing;
386       char *buf, *pend;
387       const char *p;
388       size_t size;
389
390       size = sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
391       p = buf = xmalloc (size);
392       sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, size);
393
394       do
395         {
396           if (any && !with_lf)
397             log_debug ("%*s  ", text?(int)strlen(text):0, "");
398           else
399             any = 1;
400           pend = strchr (p, '\n');
401           size = pend? (pend - p) : strlen (p);
402           if (with_lf)
403             log_debug ("%.*s", (int)size, p);
404           else
405             log_printf ("%.*s", (int)size, p);
406           if (pend)
407             p = pend + 1;
408           else
409             p += size;
410           n_closing = count_closing_parens (p);
411           if (n_closing)
412             {
413               while (n_closing--)
414                 log_printf (")");
415               p = "";
416             }
417           log_printf ("\n");
418         }
419       while (*p);
420       xfree (buf);
421     }
422   else if (text)
423     log_printf ("\n");
424 }
425
426
427 /*
428  * Tokenize STRING using the set of delimiters in DELIM.  Leading
429  * white spaces are removed from all tokens.  The caller must xfree
430  * the result.
431  *
432  * Returns: A malloced and NULL delimited array with the tokens.  On
433  *          memory error NULL is returned and ERRNO is set.
434  */
435 char **
436 _gcry_strtokenize (const char *string, const char *delim)
437 {
438   const char *s;
439   size_t fields;
440   size_t bytes, n;
441   char *buffer;
442   char *p, *px, *pend;
443   char **result;
444   char const ws[] = " \t\v\f\r\n";
445
446   if (!delim)
447     delim = ws;
448
449   /* Count the number of fields.  */
450   for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
451     fields++;
452   fields++; /* Add one for the terminating NULL.  */
453
454   /* Allocate an array for all fields, a terminating NULL, and space
455      for a copy of the string.  */
456   bytes = fields * sizeof *result;
457   if (bytes / sizeof *result != fields)
458     {
459       gpg_err_set_errno (ENOMEM);
460       return NULL;
461     }
462   n = strlen (string) + 1;
463   bytes += n;
464   if (bytes < n)
465     {
466       gpg_err_set_errno (ENOMEM);
467       return NULL;
468     }
469   result = xtrymalloc (bytes);
470   if (!result)
471     return NULL;
472   buffer = (char*)(result + fields);
473
474   /* Copy and parse the string.  */
475   strcpy (buffer, string);
476   for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
477     {
478       *pend = 0;
479       while (strchr (ws, *(byte*)p))
480         p++;
481       for (px = pend - 1; px >= p && strchr (ws, *(byte*)px); px--)
482         *px = 0;
483       result[n++] = p;
484     }
485   while (*p && strchr (ws, *(byte*)p))
486     p++;
487   for (px = p + strlen (p) - 1; px >= p && strchr (ws, *(byte*)px); px--)
488     *px = 0;
489   /* Traling spaces may result in an empty field.  We do not want to
490      store that.  */
491   result[n++] = *p? p : NULL;
492   result[n] = NULL;
493
494   gcry_assert ((char*)(result + n + 1) == buffer);
495
496   return result;
497 }
498
499
500 void
501 __gcry_burn_stack (unsigned int bytes)
502 {
503 #ifdef HAVE_VLA
504     /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */
505     unsigned int buflen = ((!bytes + bytes) + 63) & ~63;
506     volatile char buf[buflen];
507
508     wipememory (buf, sizeof buf);
509 #else
510     volatile char buf[64];
511
512     wipememory (buf, sizeof buf);
513
514     if (bytes > sizeof buf)
515         _gcry_burn_stack (bytes - sizeof buf);
516 #endif
517 }
518
519 #ifndef HAVE_GCC_ASM_VOLATILE_MEMORY
520 void
521 __gcry_burn_stack_dummy (void)
522 {
523 }
524 #endif
525
526 void
527 _gcry_divide_by_zero (void)
528 {
529     gpg_err_set_errno (EDOM);
530     _gcry_fatal_error (gpg_err_code_from_errno (errno), "divide by zero");
531 }