From 31de2267ec849cd8f269cd8bf25b8590f2d93e1d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 3 Feb 2004 16:24:37 +0000 Subject: [PATCH] * findkey.c (agent_key_from_file): Extra paranoid wipe. * protect.c (agent_unprotect): Ditto. (merge_lists): Ditto. Add arg RESULTLEN. * pkdecrypt.c (agent_pkdecrypt): Don't show the secret key even in debug mode. * protect.c: Add DSA and Elgamal description. --- agent/ChangeLog | 10 ++++++++++ agent/findkey.c | 8 ++++---- agent/pkdecrypt.c | 12 ++++++------ agent/protect.c | 26 +++++++++++++++++++------- agent/query.c | 2 +- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/agent/ChangeLog b/agent/ChangeLog index 4cdaadef6..01a3c90f5 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,13 @@ +2004-02-03 Werner Koch + + * findkey.c (agent_key_from_file): Extra paranoid wipe. + * protect.c (agent_unprotect): Ditto. + (merge_lists): Ditto. Add arg RESULTLEN. + * pkdecrypt.c (agent_pkdecrypt): Don't show the secret key even in + debug mode. + + * protect.c: Add DSA and Elgamal description. + 2004-01-29 Werner Koch * agent.h (server_control_s): Add connection_fd field. diff --git a/agent/findkey.c b/agent/findkey.c index a9566a2c7..f145daef1 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -154,7 +154,7 @@ unprotect (CTRL ctrl, sprintf (hexgrip+2*i, "%02X", grip[i]); hexgrip[40] = 0; - /* first try to get it from the cache - if there is none or we can't + /* First try to get it from the cache - if there is none or we can't unprotect it, we fall back to ask the user */ if (!ignore_cache) { @@ -329,9 +329,9 @@ agent_key_from_file (CTRL ctrl, return rc; } - /* Arggg FIXME: does scan support secure memory? */ - rc = gcry_sexp_sscan (&s_skey, &erroff, - buf, gcry_sexp_canon_len (buf, 0, NULL, NULL)); + buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL); + rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); + wipememory (buf, buflen); xfree (buf); if (rc) { diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index cc3a2f33f..72f81778e 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -93,12 +93,12 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, putc (0, outfp); } else - { /* no smartcard, but a private key */ - if (DBG_CRYPTO) - { - log_debug ("skey: "); - gcry_sexp_dump (s_skey); - } + { /* No smartcard, but a private key */ +/* if (DBG_CRYPTO ) */ +/* { */ +/* log_debug ("skey: "); */ +/* gcry_sexp_dump (s_skey); */ +/* } */ rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey); if (rc) diff --git a/agent/protect.c b/agent/protect.c index df8a9bfe7..2de5e97c5 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -46,6 +46,8 @@ static struct { int prot_from, prot_to; } protect_info[] = { { "rsa", "nedpqu", 2, 5 }, + { "dsa", "pqgyx", 4, 4 }, + { "elg", "pgyx", 3, 3 }, { NULL } }; @@ -432,13 +434,13 @@ do_decryption (const unsigned char *protected, size_t protectedlen, xfree (outbuf); return rc; } - /* do a quick check first */ + /* Do a quick check first. */ if (*outbuf != '(' && outbuf[1] != '(') { xfree (outbuf); return gpg_error (GPG_ERR_BAD_PASSPHRASE); } - /* check that we have a consistent S-Exp */ + /* Check that we have a consistent S-Exp. */ reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL); if (!reallen || (reallen + blklen < protectedlen) ) { @@ -458,7 +460,8 @@ static int merge_lists (const unsigned char *protectedkey, size_t replacepos, const unsigned char *cleartext, - unsigned char *sha1hash, unsigned char **result) + unsigned char *sha1hash, + unsigned char **result, size_t *resultlen) { size_t n, newlistlen; unsigned char *newlist, *p; @@ -559,13 +562,16 @@ merge_lists (const unsigned char *protectedkey, /* ready */ *result = newlist; + *resultlen = newlistlen; return 0; failure: + wipememory (newlist, newlistlen); xfree (newlist); return rc; invalid_sexp: + wipememory (newlist, newlistlen); xfree (newlist); return gpg_error (GPG_ERR_INV_SEXP); } @@ -589,6 +595,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, const unsigned char *prot_begin; unsigned char *cleartext; unsigned char *final; + size_t finallen; s = protectedkey; if (*s != '(') @@ -612,7 +619,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, if (!protect_info[infidx].algo) return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - /* now find the list with the protected information. Here is an + /* Now find the list with the protected information. Here is an example for such a list: (protected openpgp-s2k3-sha1-aes-cbc ((sha1 ) ) @@ -669,7 +676,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, s++; /* skip list end */ n = snext (&s); - if (n != 16) /* Wrong blocksize for IV (we support ony aes-128) */ + if (n != 16) /* Wrong blocksize for IV (we support only aes-128). */ return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); iv = s; s += n; @@ -688,7 +695,11 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, return rc; rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext, - sha1hash, &final); + sha1hash, &final, &finallen); + /* Albeit cleartext has been allocated in secure memory and thus + xfree will wipe it out, we do an extra wipe just in case + somethings goes badly wrong. */ + wipememory (cleartext, prot_begin-protectedkey); xfree (cleartext); if (rc) return rc; @@ -698,6 +709,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION); if (rc) { + wipememory (final, finallen); xfree (final); return rc; } @@ -954,7 +966,7 @@ agent_get_shadow_info (const unsigned char *shadowkey, depth--; s++; } - /* found the shadowed list, s points to the protocol */ + /* Found the shadowed list, S points to the protocol */ n = snext (&s); if (!n) return gpg_error (GPG_ERR_INV_SEXP); diff --git a/agent/query.c b/agent/query.c index a3a773380..28873775a 100644 --- a/agent/query.c +++ b/agent/query.c @@ -1,5 +1,5 @@ /* query.c - fork of the pinentry to query stuff from the user - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. *