Browse Source

PuTTY EC curve memory leak

Source commit: 9fd3f9816d2f3c3daa3ac3cbe3179ef93965c60e
Martin Prikryl 9 years ago
parent
commit
a6251535e7
3 changed files with 105 additions and 0 deletions
  1. 1 0
      source/core/PuttyIntf.cpp
  2. 4 0
      source/putty/puttyexp.h
  3. 100 0
      source/putty/sshecc.c

+ 1 - 0
source/core/PuttyIntf.cpp

@@ -62,6 +62,7 @@ void __fastcall PuttyFinalize()
   sk_cleanup();
   win_misc_cleanup();
   win_secur_cleanup();
+  ec_cleanup();
   DeleteCriticalSection(&putty_section);
 }
 //---------------------------------------------------------------------------

+ 4 - 0
source/putty/puttyexp.h

@@ -85,4 +85,8 @@ const char * get_putty_version();
 
 void win_secur_cleanup(void);
 
+// from sshecc.c
+
+void ec_cleanup(void);
+
 #endif

+ 100 - 0
source/putty/sshecc.c

@@ -37,6 +37,45 @@
 
 #include "ssh.h"
 
+#ifdef MPEXT
+int ec_curve_cleanup = 0;
+
+static void finalize_ec_point(struct ec_point *point)
+{
+    if (point->x != NULL) freebn(point->x);
+    if (point->y != NULL) freebn(point->y);
+    if (point->z != NULL) freebn(point->z);
+}
+
+static void finalize_wcurve(struct ec_curve *curve)
+{
+    if (curve->p != NULL) freebn(curve->p);
+
+    if (curve->w.a != NULL) freebn(curve->w.a);
+    if (curve->w.b != NULL) freebn(curve->w.b);
+    if (curve->w.n != NULL) freebn(curve->w.n);
+    finalize_ec_point(&curve->w.G);
+}
+
+static void finalize_mcurve(struct ec_curve *curve)
+{
+    if (curve->p != NULL) freebn(curve->p);
+
+    if (curve->m.a != NULL) freebn(curve->m.a);
+    if (curve->m.b != NULL) freebn(curve->m.b);
+    finalize_ec_point(&curve->m.G);
+}
+
+static void finalize_ecurve(struct ec_curve *curve)
+{
+    if (curve->p != NULL) freebn(curve->p);
+
+    if (curve->e.l != NULL) freebn(curve->e.l);
+    if (curve->e.d != NULL) freebn(curve->e.d);
+    finalize_ec_point(&curve->e.B);
+}
+#endif
+
 /* ----------------------------------------------------------------------
  * Elliptic curve definitions
  */
@@ -121,6 +160,15 @@ static struct ec_curve *ec_p256(void)
     static struct ec_curve curve = { 0 };
     static unsigned char initialised = 0;
 
+    #ifdef MPEXT
+    if (ec_curve_cleanup)
+    {
+        if (initialised) finalize_wcurve(&curve);
+        initialised = 0;
+        return NULL;
+    }
+    #endif
+
     if (!initialised)
     {
         static const unsigned char p[] = {
@@ -175,6 +223,15 @@ static struct ec_curve *ec_p384(void)
     static struct ec_curve curve = { 0 };
     static unsigned char initialised = 0;
 
+    #ifdef MPEXT
+    if (ec_curve_cleanup)
+    {
+        if (initialised) finalize_wcurve(&curve);
+        initialised = 0;
+        return NULL;
+    }
+    #endif
+
     if (!initialised)
     {
         static const unsigned char p[] = {
@@ -241,6 +298,15 @@ static struct ec_curve *ec_p521(void)
     static struct ec_curve curve = { 0 };
     static unsigned char initialised = 0;
 
+    #ifdef MPEXT
+    if (ec_curve_cleanup)
+    {
+        if (initialised) finalize_wcurve(&curve);
+        initialised = 0;
+        return NULL;
+    }
+    #endif
+
     if (!initialised)
     {
         static const unsigned char p[] = {
@@ -325,6 +391,15 @@ static struct ec_curve *ec_curve25519(void)
     static struct ec_curve curve = { 0 };
     static unsigned char initialised = 0;
 
+    #ifdef MPEXT
+    if (ec_curve_cleanup)
+    {
+        if (initialised) finalize_mcurve(&curve);
+        initialised = 0;
+        return NULL;
+    }
+    #endif
+
     if (!initialised)
     {
         static const unsigned char p[] = {
@@ -370,6 +445,15 @@ static struct ec_curve *ec_ed25519(void)
     static struct ec_curve curve = { 0 };
     static unsigned char initialised = 0;
 
+    #ifdef MPEXT
+    if (ec_curve_cleanup)
+    {
+        if (initialised) finalize_ecurve(&curve);
+        initialised = 0;
+        return NULL;
+    }
+    #endif
+
     if (!initialised)
     {
         static const unsigned char q[] = {
@@ -2965,3 +3049,19 @@ const int ec_ed_alg_and_curve_by_bits(int bits,
     *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();
     return TRUE;
 }
+
+#ifdef MPEXT
+
+void ec_cleanup(void)
+{
+  ec_curve_cleanup = 1;
+  ec_p256();
+  ec_p384();
+  ec_p521();
+  ec_curve25519();
+  ec_ed25519();
+  // in case we want to restart (unlikely)
+  ec_curve_cleanup = 0;
+}
+
+#endif