diff options
-rw-r--r-- | src/ChangeLog | 11 | ||||
-rw-r--r-- | src/secmem.c | 5 | ||||
-rw-r--r-- | src/sexp.c | 117 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/tsexp.c | 25 |
5 files changed, 133 insertions, 29 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7d56a299..e2f50c29 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2004-02-03 Werner Koch <wk@gnupg.org> + + * secmem.c (_gcry_secmem_init): Do not print the "not locked into + core warning" if the NO_WARNING flag has been set. + + * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER + is in secure memory. Switch to secure memory for the a secure %b + format item. Extra paranoid wipe on error. + (gcry_sexp_release): Added paranoid wiping for securely allocated + S-expressions. + 2004-01-25 Moritz Schulte <mo@g10code.com> * ath.h: Include <config.h>. diff --git a/src/secmem.c b/src/secmem.c index c5772834..a7b5fcc1 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -1,5 +1,6 @@ /* secmem.c - memory allocation from a secure heap - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, + * 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -457,7 +458,7 @@ _gcry_secmem_init (size_t n) init_pool (n); if (! geteuid ()) lock_pool (pool, n); - else + else if (!no_warning) log_info ("Secure memory is not locked into core\n"); } else @@ -1,5 +1,6 @@ /* sexp.c - S-Expression handling - * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 1999, 2000, 2001, 2002, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -245,7 +246,39 @@ gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length, void gcry_sexp_release( gcry_sexp_t sexp ) { - gcry_free ( sexp ); + if (sexp) + { + if (gcry_is_secure (sexp)) + { + /* Extra paranoid wiping. */ + const byte *p = sexp->d; + int type; + + while ( (type = *p) != ST_STOP ) + { + p++; + switch ( type ) + { + case ST_OPEN: + break; + case ST_CLOSE: + break; + case ST_DATA: + { + DATALEN n; + memcpy ( &n, p, sizeof n ); + p += sizeof n; + p += n; + } + break; + default: + break; + } + } + wipememory (sexp->d, p - sexp->d); + } + gcry_free ( sexp ); + } } @@ -257,22 +290,24 @@ gcry_sexp_release( gcry_sexp_t sexp ) gcry_sexp_t gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b ) { - /* NYI: Implementation should be quite easy with our new data representation */ - BUG (); - return NULL; + /* NYI: Implementation should be quite easy with our new data + representation */ + BUG (); + return NULL; } /**************** * Make a list from all items in the array the end of the array is marked - * with a NULL. y a NULL + * with a NULL. */ gcry_sexp_t gcry_sexp_alist( const gcry_sexp_t *array ) { - /* NYI: Implementaion should be quite easy with our new data representation */ - BUG (); - return NULL; + /* NYI: Implementation should be quite easy with our new data + representation. */ + BUG (); + return NULL; } /**************** @@ -281,9 +316,10 @@ gcry_sexp_alist( const gcry_sexp_t *array ) gcry_sexp_t gcry_sexp_vlist( const gcry_sexp_t a, ... ) { - /* NYI: Implementaion should be quite easy with our new data representation */ - BUG (); - return NULL; + /* NYI: Implementation should be quite easy with our new data + representation. */ + BUG (); + return NULL; } @@ -294,17 +330,19 @@ gcry_sexp_vlist( const gcry_sexp_t a, ... ) gcry_sexp_t gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n ) { - /* NYI: Implementaion should be quite easy with our new data representation */ - BUG (); - return NULL; + /* NYI: Implementation should be quite easy with our new data + representation. */ + BUG (); + return NULL; } gcry_sexp_t gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n ) { - /* NYI: Implementaion should be quite easy with our new data representation */ - BUG (); - return NULL; + /* NYI: Implementation should be quite easy with our new data + representation. */ + BUG (); + return NULL; } @@ -831,7 +869,7 @@ unquote_string (const unsigned char *string, size_t length, unsigned char *buf) * FIXME: We should find a way to store the secure-MPIs not in the string * but as reference to somewhere - this can help us to save huge amounts * of secure memory. The problem is, that if only one element is secure, all - * other elements are automagicaly copied to secure meory too, so the most + * other elements are automagicaly copied to secure memory too, so the most * common operation gcry_sexp_cdr_mpi() will always return a secure MPI * regardless whether it is needed or not. */ @@ -841,10 +879,10 @@ sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, va_list arg_ptr, void **arg_list) { gcry_err_code_t err = GPG_ERR_NO_ERROR; - static const char tokenchars[] = "\ -abcdefghijklmnopqrstuvwxyz\ -ABCDEFGHIJKLMNOPQRSTUVWXYZ\ -0123456789-./_:*+="; + static const char tokenchars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789-./_:*+="; const char *p; size_t n; const char *digptr = NULL; @@ -891,7 +929,10 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ * than the provided one. However, we add space for one extra datalen * so that the code which does the ST_CLOSE can use MAKE_SPACE */ c.allocated = length + sizeof(DATALEN); - c.sexp = gcry_xmalloc (sizeof *c.sexp + c.allocated - 1); + if (buffer && length && gcry_is_secure (buffer)) + c.sexp = gcry_xmalloc_secure (sizeof *c.sexp + c.allocated - 1); + else + c.sexp = gcry_xmalloc (sizeof *c.sexp + c.allocated - 1); c.pos = c.sexp->d; for (p = buffer, n = length; n; p++, n--) @@ -982,8 +1023,8 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ quoted_esc = 1; else if (*p == '\"') { - /* keep it easy - we know that the unquoted string will - never be larger */ + /* Keep it easy - we know that the unquoted string will + never be larger. */ char *save; size_t len; @@ -1141,6 +1182,23 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ ARG_NEXT (astr, const char *); MAKE_SPACE (alen); + if (alen + && !gcry_is_secure (c.sexp->d) + && gcry_is_secure (astr)) + { + /* We have to switch to secure allocation. */ + gcry_sexp_t newsexp; + byte *newhead; + + newsexp = gcry_xmalloc_secure (sizeof *newsexp + + c.allocated - 1); + newhead = newsexp->d; + memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); + c.pos = newhead + (c.pos - c.sexp->d); + gcry_free (c.sexp); + c.sexp = newsexp; + } + *c.pos++ = ST_DATA; STORE_LEN (c.pos, alen); memcpy (c.pos, astr, alen); @@ -1275,7 +1333,12 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ { /* Error -> deallocate. */ if (c.sexp) - gcry_free (c.sexp); + { + /* Extra paranoid wipe on error. */ + if (gcry_is_secure (c.sexp)) + wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1); + gcry_free (c.sexp); + } /* This might be expected by existing code... */ *retsexp = NULL; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 9bfa32f7..8d1656b5 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2004-02-03 Werner Koch <wk@gnupg.org> + + * tsexp.c (basic): New pass to check secure memory switching. + 2004-01-12 Moritz Schulte <mo@g10code.com> * ac.c (check_one): Adjust to new ac API. diff --git a/tests/tsexp.c b/tests/tsexp.c index 78aeb4e1..195b84ae 100644 --- a/tests/tsexp.c +++ b/tests/tsexp.c @@ -62,6 +62,8 @@ basic (void) int pass; gcry_sexp_t sexp; int idx; + char *secure_buffer; + size_t secure_buffer_len; const char *string; static struct { const char *token; @@ -78,6 +80,10 @@ basic (void) info ("doing some pretty pointless tests\n"); + secure_buffer_len = 99; + secure_buffer = gcry_xmalloc_secure (secure_buffer_len); + memset (secure_buffer, 'G', secure_buffer_len); + for (pass=0;;pass++) { switch (pass) @@ -106,6 +112,21 @@ basic (void) return; } break; + + case 2: + string = ("(public-key (dsa (p #41424344#) (y silly_y_value) " + "(q %b) (g %m)))"); + + if ( gcry_sexp_build (&sexp, NULL, string, + secure_buffer_len, secure_buffer, + gcry_mpi_set_ui (NULL, 17)) ) + { + fail (" scanning `%s' failed\n", string); + return; + } + if (!gcry_is_secure (sexp)) + fail ("gcry_sexp_build did not switch to secure memory\n"); + break; default: return; /* Ready. */ @@ -186,6 +207,7 @@ basic (void) gcry_sexp_release (sexp); sexp = NULL; } + gcry_free (secure_buffer); } @@ -355,6 +377,9 @@ main (int argc, char **argv) if (argc > 1 && !strcmp (argv[1], "-v")) verbose = 1; + gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + basic (); canon_len (); back_and_forth (); |