 crypto/srp/srp_vfy.c | 50 ++++++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c
index a3f1a8a..e166080 100644
--- a/crypto/srp/srp_vfy.c
+++ b/crypto/srp/srp_vfy.c
@@ -270,15 +270,6 @@ SRP_VBASE *SRP_VBASE_new(char *seed_key)
     return vb;
 }
 
-int SRP_VBASE_free(SRP_VBASE *vb)
-{
-    sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
-    sk_SRP_gN_cache_free(vb->gN_cache);
-    OPENSSL_free(vb->seed_key);
-    OPENSSL_free(vb);
-    return 0;
-}
-
 static SRP_gN_cache *SRP_gN_new_init(const char *ch)
 {
     unsigned char tmp[MAX_LEN];
@@ -302,7 +293,7 @@ static SRP_gN_cache *SRP_gN_new_init(const char *ch)
     return NULL;
 }
 
-static void SRP_gN_free(SRP_gN_cache *gN_cache)
+static void SRP_gN_cache_free(SRP_gN_cache *gN_cache)
 {
     if (gN_cache == NULL)
         return;
@@ -311,6 +302,25 @@ static void SRP_gN_free(SRP_gN_cache *gN_cache)
     OPENSSL_free(gN_cache);
 }
 
+static void SRP_gN_free(SRP_gN *gN)
+{
+    if (gN == NULL)
+        return;
+    OPENSSL_free(gN->id);
+    BN_free(gN->g);
+    BN_free(gN->N);
+    OPENSSL_free(gN);
+}
+
+int SRP_VBASE_free(SRP_VBASE *vb)
+{
+    sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
+    sk_SRP_gN_cache_pop_free(vb->gN_cache, SRP_gN_cache_free);
+    OPENSSL_free(vb->seed_key);
+    OPENSSL_free(vb);
+    return 0;
+}
+
 static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
 {
     int i;
@@ -343,7 +353,7 @@ static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
         if (newgN) {
             if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0)
                 return newgN->bn;
-            SRP_gN_free(newgN);
+            SRP_gN_cache_free(newgN);
         }
     }
     return NULL;
@@ -394,6 +404,7 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
             if ((gN = (SRP_gN *) OPENSSL_malloc(sizeof(SRP_gN))) == NULL)
                 goto err;
 
+            memset( gN, 0, sizeof(SRP_gN) );
             if (!(gN->id = BUF_strdup(pp[DB_srpid]))
                 || !(gN->N =
                      SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier]))
@@ -445,16 +456,7 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
     error_code = SRP_NO_ERROR;
 
  err:
-    /*
-     * there may be still some leaks to fix, if this fails, the application
-     * terminates most likely
-     */
-
-    if (gN != NULL) {
-        OPENSSL_free(gN->id);
-        OPENSSL_free(gN);
-    }
-
+    SRP_gN_free( gN );
     SRP_user_pwd_free(user_pwd);
 
     if (tmpdb)
@@ -462,7 +464,11 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
     if (in)
         BIO_free_all(in);
 
-    sk_SRP_gN_free(SRP_gN_tab);
+    for (i=0; i < sk_SRP_gN_num( SRP_gN_tab ); i++) {
+        OPENSSL_free( sk_SRP_gN_value( SRP_gN_tab, i )->id );
+        OPENSSL_free( sk_SRP_gN_value( SRP_gN_tab, i ));
+    }
+    sk_SRP_gN_free(SRP_gN_tab );
 
     return error_code;
 
