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