summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2013-03-15 18:11:24 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2013-03-15 18:11:33 +0100
commit5b657dd28315526325ed42e98a457612b5660302 (patch)
tree0b289175d8d684283f6f8074a92da160f0193ee3
parent3fe6727da2a5c61d5285f4cee3bc87fa13a68923 (diff)
downloadgnutls-5b657dd28315526325ed42e98a457612b5660302.tar.gz
Private key parameters are overwritten with zeros on deinitialization.
-rw-r--r--NEWS2
-rw-r--r--lib/crypto-backend.h2
-rw-r--r--lib/gnutls_mpi.h39
-rw-r--r--lib/gnutls_pk.c10
-rw-r--r--lib/nettle/mpi.c48
-rw-r--r--lib/openpgp/privkey.c5
-rw-r--r--lib/x509/privkey.c10
7 files changed, 78 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index fcab4fc86f..4af9ce67cc 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ support AES with PKCS #12.
** configure: Trust store file must be explicitly set or unset when
cross compiling.
+** libgnutls: Private keys are overwritten on deinitialization.
+
** API and ABI modifications:
gnutls_x509_crt_get_issuer_dn2: Added
gnutls_x509_crt_get_dn2: Added
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index 745f7b90de..ba18e50023 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -117,6 +117,7 @@
{
bigint_t (*bigint_new) (int nbits);
void (*bigint_release) (bigint_t n);
+ void (*bigint_clear) (bigint_t n); /* zeros the int */
/* 0 for equality, > 0 for m1>m2, < 0 for m1<m2 */
int (*bigint_cmp) (const bigint_t m1, const bigint_t m2);
/* as bigint_cmp */
@@ -194,6 +195,7 @@
void gnutls_pk_params_release (gnutls_pk_params_st * p);
+ void gnutls_pk_params_clear (gnutls_pk_params_st * p);
void gnutls_pk_params_init (gnutls_pk_params_st * p);
diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h
index c4c67809ac..c905356db6 100644
--- a/lib/gnutls_mpi.h
+++ b/lib/gnutls_mpi.h
@@ -33,26 +33,27 @@ extern gnutls_crypto_bigint_st _gnutls_mpi_ops;
bigint_t _gnutls_mpi_randomize (bigint_t, unsigned int bits,
gnutls_rnd_level_t level);
-#define _gnutls_mpi_new(x) _gnutls_mpi_ops.bigint_new(x)
-#define _gnutls_mpi_cmp(x,y) _gnutls_mpi_ops.bigint_cmp(x,y)
-#define _gnutls_mpi_cmp_ui(x,y) _gnutls_mpi_ops.bigint_cmp_ui(x,y)
-#define _gnutls_mpi_mod(x,y) _gnutls_mpi_ops.bigint_mod(x,y)
-#define _gnutls_mpi_set(x,y) _gnutls_mpi_ops.bigint_set(x,y)
-#define _gnutls_mpi_set_ui(x,y) _gnutls_mpi_ops.bigint_set_ui(x,y)
-#define _gnutls_mpi_get_nbits(x) _gnutls_mpi_ops.bigint_get_nbits(x)
+#define _gnutls_mpi_new _gnutls_mpi_ops.bigint_new
+#define _gnutls_mpi_clear _gnutls_mpi_ops.bigint_clear
+#define _gnutls_mpi_cmp _gnutls_mpi_ops.bigint_cmp
+#define _gnutls_mpi_cmp_ui _gnutls_mpi_ops.bigint_cmp_ui
+#define _gnutls_mpi_mod _gnutls_mpi_ops.bigint_mod
+#define _gnutls_mpi_set _gnutls_mpi_ops.bigint_set
+#define _gnutls_mpi_set_ui _gnutls_mpi_ops.bigint_set_ui
+#define _gnutls_mpi_get_nbits _gnutls_mpi_ops.bigint_get_nbits
#define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x))
-#define _gnutls_mpi_powm(x,y,z,w) _gnutls_mpi_ops.bigint_powm(x,y,z,w)
-#define _gnutls_mpi_addm(x,y,z,w) _gnutls_mpi_ops.bigint_addm(x,y,z,w)
-#define _gnutls_mpi_subm(x,y,z,w) _gnutls_mpi_ops.bigint_subm(x,y,z,w)
-#define _gnutls_mpi_mulm(x,y,z,w) _gnutls_mpi_ops.bigint_mulm(x,y,z,w)
-#define _gnutls_mpi_add(x,y,z) _gnutls_mpi_ops.bigint_add(x,y,z)
-#define _gnutls_mpi_sub(x,y,z) _gnutls_mpi_ops.bigint_sub(x,y,z)
-#define _gnutls_mpi_mul(x,y,z) _gnutls_mpi_ops.bigint_mul(x,y,z)
-#define _gnutls_mpi_div(x,y,z) _gnutls_mpi_ops.bigint_div(x,y,z)
-#define _gnutls_mpi_add_ui(x,y,z) _gnutls_mpi_ops.bigint_add_ui(x,y,z)
-#define _gnutls_mpi_sub_ui(x,y,z) _gnutls_mpi_ops.bigint_sub_ui(x,y,z)
-#define _gnutls_mpi_mul_ui(x,y,z) _gnutls_mpi_ops.bigint_mul_ui(x,y,z)
-#define _gnutls_prime_check(z) _gnutls_mpi_ops.bigint_prime_check(z)
+#define _gnutls_mpi_powm _gnutls_mpi_ops.bigint_powm
+#define _gnutls_mpi_addm _gnutls_mpi_ops.bigint_addm
+#define _gnutls_mpi_subm _gnutls_mpi_ops.bigint_subm
+#define _gnutls_mpi_mulm _gnutls_mpi_ops.bigint_mulm
+#define _gnutls_mpi_add _gnutls_mpi_ops.bigint_add
+#define _gnutls_mpi_sub _gnutls_mpi_ops.bigint_sub
+#define _gnutls_mpi_mul _gnutls_mpi_ops.bigint_mul
+#define _gnutls_mpi_div _gnutls_mpi_ops.bigint_div
+#define _gnutls_mpi_add_ui _gnutls_mpi_ops.bigint_add_ui
+#define _gnutls_mpi_sub_ui _gnutls_mpi_ops.bigint_sub_ui
+#define _gnutls_mpi_mul_ui _gnutls_mpi_ops.bigint_mul_ui
+#define _gnutls_prime_check _gnutls_mpi_ops.bigint_prime_check
#define _gnutls_mpi_print(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_USG)
#define _gnutls_mpi_print_lz(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_STD)
#define _gnutls_mpi_print_pgp(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_PGP)
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c
index 71781dc82c..16e96f90b7 100644
--- a/lib/gnutls_pk.c
+++ b/lib/gnutls_pk.c
@@ -214,6 +214,16 @@ gnutls_pk_params_release (gnutls_pk_params_st * p)
p->params_nr = 0;
}
+void
+gnutls_pk_params_clear (gnutls_pk_params_st * p)
+{
+ unsigned int i;
+ for (i = 0; i < p->params_nr; i++)
+ {
+ _gnutls_mpi_clear (p->params[i]);
+ }
+}
+
int
_gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk,
gnutls_pk_params_st* params,
diff --git a/lib/nettle/mpi.c b/lib/nettle/mpi.c
index aa95843bd2..61729b94b6 100644
--- a/lib/nettle/mpi.c
+++ b/lib/nettle/mpi.c
@@ -94,7 +94,10 @@ wrap_nettle_mpi_new (int nbits)
gnutls_assert ();
return NULL;
}
- mpz_init2 (*p, nbits);
+ if (nbits == 0)
+ mpz_init(*p);
+ else
+ mpz_init2 (*p, nbits);
return p;
}
@@ -201,16 +204,22 @@ wrap_nettle_mpi_set_ui (bigint_t w, unsigned long u)
static unsigned int
wrap_nettle_mpi_get_nbits (bigint_t a)
{
- return mpz_sizeinbase (*((mpz_t *) a), 2);
+ return mpz_sizeinbase (TOMPZ( a), 2);
}
static void
wrap_nettle_mpi_release (bigint_t a)
{
- mpz_clear (*((mpz_t *) a));
+ mpz_clear (TOMPZ( a));
gnutls_free (a);
}
+static void
+wrap_nettle_mpi_clear (bigint_t a)
+{
+ memset(TOMPZ(a)[0]._mp_d, 0, TOMPZ(a)[0]._mp_alloc*sizeof(mp_limb_t));
+}
+
static bigint_t
wrap_nettle_mpi_mod (const bigint_t a, const bigint_t b)
{
@@ -219,7 +228,7 @@ wrap_nettle_mpi_mod (const bigint_t a, const bigint_t b)
if (r == NULL)
return NULL;
- mpz_mod (*((mpz_t *) r), *((mpz_t *) a), *((mpz_t *) b));
+ mpz_mod (TOMPZ( r), TOMPZ( a), TOMPZ( b));
return r;
}
@@ -234,7 +243,7 @@ wrap_nettle_mpi_powm (bigint_t w, const bigint_t b, const bigint_t e,
if (w == NULL)
return NULL;
- mpz_powm (*((mpz_t *) w), *((mpz_t *) b), *((mpz_t *) e), *((mpz_t *) m));
+ mpz_powm (TOMPZ( w), TOMPZ( b), TOMPZ( e), TOMPZ( m));
return w;
}
@@ -249,8 +258,8 @@ wrap_nettle_mpi_addm (bigint_t w, const bigint_t a, const bigint_t b,
if (w == NULL)
return NULL;
- mpz_add (*((mpz_t *) w), *((mpz_t *) b), *((mpz_t *) a));
- mpz_fdiv_r (*((mpz_t *) w), *((mpz_t *) w), *((mpz_t *) m));
+ mpz_add (TOMPZ( w), TOMPZ( b), TOMPZ( a));
+ mpz_fdiv_r (TOMPZ( w), TOMPZ( w), TOMPZ( m));
return w;
}
@@ -265,8 +274,8 @@ wrap_nettle_mpi_subm (bigint_t w, const bigint_t a, const bigint_t b,
if (w == NULL)
return NULL;
- mpz_sub (*((mpz_t *) w), *((mpz_t *) a), *((mpz_t *) b));
- mpz_fdiv_r (*((mpz_t *) w), *((mpz_t *) w), *((mpz_t *) m));
+ mpz_sub (TOMPZ( w), TOMPZ( a), TOMPZ( b));
+ mpz_fdiv_r (TOMPZ( w), TOMPZ( w), TOMPZ( m));
return w;
}
@@ -281,8 +290,8 @@ wrap_nettle_mpi_mulm (bigint_t w, const bigint_t a, const bigint_t b,
if (w == NULL)
return NULL;
- mpz_mul (*((mpz_t *) w), *((mpz_t *) a), *((mpz_t *) b));
- mpz_fdiv_r (*((mpz_t *) w), *((mpz_t *) w), *((mpz_t *) m));
+ mpz_mul (TOMPZ( w), TOMPZ( a), TOMPZ( b));
+ mpz_fdiv_r (TOMPZ( w), TOMPZ( w), TOMPZ( m));
return w;
}
@@ -296,7 +305,7 @@ wrap_nettle_mpi_add (bigint_t w, const bigint_t a, const bigint_t b)
if (w == NULL)
return NULL;
- mpz_add (*((mpz_t *) w), *((mpz_t *) a), *((mpz_t *) b));
+ mpz_add (TOMPZ( w), TOMPZ( a), TOMPZ( b));
return w;
}
@@ -310,7 +319,7 @@ wrap_nettle_mpi_sub (bigint_t w, const bigint_t a, const bigint_t b)
if (w == NULL)
return NULL;
- mpz_sub (*((mpz_t *) w), *((mpz_t *) a), *((mpz_t *) b));
+ mpz_sub (TOMPZ( w), TOMPZ( a), TOMPZ( b));
return w;
}
@@ -324,7 +333,7 @@ wrap_nettle_mpi_mul (bigint_t w, const bigint_t a, const bigint_t b)
if (w == NULL)
return NULL;
- mpz_mul (*((mpz_t *) w), *((mpz_t *) a), *((mpz_t *) b));
+ mpz_mul (TOMPZ( w), TOMPZ( a), TOMPZ( b));
return w;
}
@@ -339,7 +348,7 @@ wrap_nettle_mpi_div (bigint_t q, const bigint_t a, const bigint_t b)
if (q == NULL)
return NULL;
- mpz_cdiv_q (*((mpz_t *) q), *((mpz_t *) a), *((mpz_t *) b));
+ mpz_cdiv_q (TOMPZ( q), TOMPZ( a), TOMPZ( b));
return q;
}
@@ -353,7 +362,7 @@ wrap_nettle_mpi_add_ui (bigint_t w, const bigint_t a, unsigned long b)
if (w == NULL)
return NULL;
- mpz_add_ui (*((mpz_t *) w), *((mpz_t *) a), b);
+ mpz_add_ui (TOMPZ( w), TOMPZ( a), b);
return w;
}
@@ -367,7 +376,7 @@ wrap_nettle_mpi_sub_ui (bigint_t w, const bigint_t a, unsigned long b)
if (w == NULL)
return NULL;
- mpz_sub_ui (*((mpz_t *) w), *((mpz_t *) a), b);
+ mpz_sub_ui (TOMPZ( w), TOMPZ( a), b);
return w;
@@ -382,7 +391,7 @@ wrap_nettle_mpi_mul_ui (bigint_t w, const bigint_t a, unsigned long b)
if (w == NULL)
return NULL;
- mpz_mul_ui (*((mpz_t *) w), *((mpz_t *) a), b);
+ mpz_mul_ui (TOMPZ( w), TOMPZ( a), b);
return w;
@@ -392,7 +401,7 @@ static int
wrap_nettle_prime_check (bigint_t pp)
{
int ret;
- ret = mpz_probab_prime_p (*((mpz_t *) pp), PRIME_CHECK_PARAM);
+ ret = mpz_probab_prime_p (TOMPZ( pp), PRIME_CHECK_PARAM);
if (ret > 0)
{
@@ -636,6 +645,7 @@ gnutls_crypto_bigint_st _gnutls_mpi_ops = {
.bigint_div = wrap_nettle_mpi_div,
.bigint_prime_check = wrap_nettle_prime_check,
.bigint_release = wrap_nettle_mpi_release,
+ .bigint_clear = wrap_nettle_mpi_clear,
.bigint_print = wrap_nettle_mpi_print,
.bigint_scan = wrap_nettle_mpi_scan,
.bigint_generate_group = wrap_nettle_generate_group
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
index 03488b2247..6f2d558a26 100644
--- a/lib/openpgp/privkey.c
+++ b/lib/openpgp/privkey.c
@@ -853,6 +853,7 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
return 0;
error:
+ gnutls_pk_params_clear(params);
gnutls_pk_params_release(params);
return result;
@@ -962,6 +963,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
ret = 0;
cleanup:
+ gnutls_pk_params_clear(&params);
gnutls_pk_params_release(&params);
return ret;
}
@@ -1061,6 +1063,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
ret = 0;
cleanup:
+ gnutls_pk_params_clear(&params);
gnutls_pk_params_release(&params);
return ret;
}
@@ -1378,6 +1381,7 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
result =
_gnutls_pk_sign (pk_algorithm, signature, hash, &params);
+ gnutls_pk_params_clear(&params);
gnutls_pk_params_release(&params);
if (result < 0)
@@ -1454,6 +1458,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, &params);
+ gnutls_pk_params_clear(&params);
gnutls_pk_params_release(&params);
if (result < 0)
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 9c0863d32a..61fd52304e 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -70,6 +70,7 @@ gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
if (!key)
return;
+ gnutls_pk_params_clear(&key->params);
gnutls_pk_params_release(&key->params);
asn1_delete_structure (&key->key);
gnutls_free (key);
@@ -224,6 +225,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
error:
asn1_delete_structure (&pkey_asn);
+ gnutls_pk_params_clear (&pkey->params);
gnutls_pk_params_release (&pkey->params);
return NULL;
@@ -331,6 +333,7 @@ _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key,
error:
asn1_delete_structure (&pkey_asn);
+ gnutls_pk_params_clear (&pkey->params);
gnutls_pk_params_release (&pkey->params);
return NULL;
@@ -401,6 +404,7 @@ decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
error:
asn1_delete_structure (&dsa_asn);
+ gnutls_pk_params_clear(&pkey->params);
gnutls_pk_params_release(&pkey->params);
return NULL;
@@ -838,6 +842,7 @@ gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
return 0;
cleanup:
+ gnutls_pk_params_clear(&key->params);
gnutls_pk_params_release(&key->params);
return ret;
@@ -929,6 +934,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
return 0;
cleanup:
+ gnutls_pk_params_clear(&key->params);
gnutls_pk_params_release(&key->params);
return ret;
@@ -1001,6 +1007,7 @@ gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key,
return 0;
cleanup:
+ gnutls_pk_params_clear(&key->params);
gnutls_pk_params_release(&key->params);
return ret;
@@ -1393,6 +1400,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
}
}
+ gnutls_pk_params_clear(&pk_params);
gnutls_pk_params_release (&pk_params);
return 0;
@@ -1403,6 +1411,7 @@ error:
_gnutls_free_datum (e);
_gnutls_free_datum (p);
_gnutls_free_datum (q);
+ gnutls_pk_params_clear(&pk_params);
gnutls_pk_params_release (&pk_params);
return ret;
@@ -1545,6 +1554,7 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
cleanup:
key->pk_algorithm = GNUTLS_PK_UNKNOWN;
+ gnutls_pk_params_clear(&key->params);
gnutls_pk_params_release(&key->params);
return ret;