From a199a7bf18268d98cdbc830ca8abaea12206ac72 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 5 Jul 2000 06:08:19 +0000 Subject: [PATCH] Check for bad keys when setting public/private keys. --- lib/silccrypt/rsa.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/silccrypt/rsa.c b/lib/silccrypt/rsa.c index c185adb9..6779fa3f 100644 --- a/lib/silccrypt/rsa.c +++ b/lib/silccrypt/rsa.c @@ -110,7 +110,7 @@ SILC_PKCS_API_GET_PUBLIC_KEY(rsa) { RsaKey *key = (RsaKey *)context; unsigned char *e, *n, *ret; - unsigned int e_len, n_len; + unsigned short e_len, n_len; unsigned char tmp[2]; e_len = silc_mp_sizeinbase(&key->e, 16); @@ -155,7 +155,7 @@ SILC_PKCS_API_GET_PRIVATE_KEY(rsa) { RsaKey *key = (RsaKey *)context; unsigned char *e, *n, *d, *ret; - unsigned int e_len, n_len, d_len; + unsigned short e_len, n_len, d_len; unsigned char tmp[2]; e_len = silc_mp_sizeinbase(&key->e, 16); @@ -211,13 +211,18 @@ SILC_PKCS_API_SET_PUBLIC_KEY(rsa) { RsaKey *key = (RsaKey *)context; unsigned char *e, *n, tmp[2]; - unsigned int e_len, n_len; + unsigned short e_len, n_len; silc_mp_init(&key->e); silc_mp_init(&key->n); memcpy(tmp, key_data, 2); e_len = ((unsigned int)tmp[0] << 8) | ((unsigned int)tmp[1]); + if (e_len > key_len) { + silc_mp_clear(&key->e); + silc_mp_clear(&key->n); + return FALSE; + } e = silc_calloc(e_len + 1, sizeof(unsigned char)); memcpy(e, key_data + 2, e_len); @@ -225,6 +230,13 @@ SILC_PKCS_API_SET_PUBLIC_KEY(rsa) memcpy(tmp, key_data + 2 + e_len, 2); n_len = ((unsigned int)tmp[0] << 8) | ((unsigned int)tmp[1]); + if (e_len + n_len > key_len) { + memset(e, 0, e_len); + silc_free(e); + silc_mp_clear(&key->e); + silc_mp_clear(&key->n); + return FALSE; + } n = silc_calloc(n_len + 1, sizeof(unsigned char)); memcpy(n, key_data + 2 + e_len + 2, n_len); @@ -246,7 +258,7 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa) { RsaKey *key = (RsaKey *)context; unsigned char *e, *n, *d, tmp[2]; - unsigned int e_len, n_len, d_len; + unsigned short e_len, n_len, d_len; silc_mp_init(&key->e); silc_mp_init(&key->n); @@ -254,6 +266,11 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa) memcpy(tmp, key_data, 2); e_len = ((unsigned int)tmp[0] << 8) | ((unsigned int)tmp[1]); + if (e_len > key_len) { + silc_mp_clear(&key->e); + silc_mp_clear(&key->n); + return FALSE; + } e = silc_calloc(e_len + 1, sizeof(unsigned char)); memcpy(e, key_data + 2, e_len); @@ -261,6 +278,13 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa) memcpy(tmp, key_data + 2 + e_len, 2); n_len = ((unsigned int)tmp[0] << 8) | ((unsigned int)tmp[1]); + if (e_len + n_len > key_len) { + memset(e, 0, e_len); + silc_free(e); + silc_mp_clear(&key->e); + silc_mp_clear(&key->n); + return FALSE; + } n = silc_calloc(n_len + 1, sizeof(unsigned char)); memcpy(n, key_data + 2 + e_len + 2, n_len); @@ -268,6 +292,15 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa) memcpy(tmp, key_data + 2 + e_len + 2 + n_len, 2); d_len = ((unsigned int)tmp[0] << 8) | ((unsigned int)tmp[1]); + if (e_len + n_len + d_len > key_len) { + memset(n, 0, n_len); + silc_free(n); + memset(e, 0, e_len); + silc_free(e); + silc_mp_clear(&key->e); + silc_mp_clear(&key->n); + return FALSE; + } d = silc_calloc(d_len + 1, sizeof(unsigned char)); memcpy(d, key_data + 2 + e_len + 2 + n_len + 2, d_len); -- 2.24.0