Check for bad keys when setting public/private keys.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 5 Jul 2000 06:08:19 +0000 (06:08 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 5 Jul 2000 06:08:19 +0000 (06:08 +0000)
lib/silccrypt/rsa.c

index c185adb97f799f0c5057e0ff2ee1888d6add7f51..6779fa3f5861bcb8e17f4e22cdb675b32d4d5712 100644 (file)
@@ -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);