fix so it is safe to repeatedly add PBE algorithms
authorDr. Stephen Henson <steve@openssl.org>
Sat, 26 Jun 2010 12:55:01 +0000 (12:55 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 26 Jun 2010 12:55:01 +0000 (12:55 +0000)
CHANGES
crypto/evp/evp_pbe.c

diff --git a/CHANGES b/CHANGES
index fd178b9398a19ef98f6215fb4e2b87145486495f..4b72bf85d93928edb78a66a11a58dfd31911138d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,7 +4,11 @@
 
  Changes between 0.9.8o and 0.9.8p [xx XXX xxxx]
 
-  *)
+  *) Don't repeatedly append PBE algorithms to table if they already exist.
+     Sort table on each new add. This effectively makes the table read only
+     after all algorithms are added and subsequent calls to PKCS12_pbe_add
+     etc are non-op.
+     [Steve Henson]
 
  Changes between 0.9.8n and 0.9.8o [01 Jun 2010]
 
index 5e830be65fff7c58848e7e0d376ed58cd47c9e37..278f4858c4c30499d58b0cf356e54d8d2222dc2e 100644 (file)
@@ -116,17 +116,52 @@ static int pbe_cmp(const char * const *a, const char * const *b)
 int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
             EVP_PBE_KEYGEN *keygen)
 {
-       EVP_PBE_CTL *pbe_tmp;
-       if (!pbe_algs) pbe_algs = sk_new(pbe_cmp);
-       if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) {
-               EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
-               return 0;
-       }
-       pbe_tmp->pbe_nid = nid;
+       EVP_PBE_CTL *pbe_tmp, pbelu;
+       int i;
+       if (!pbe_algs)
+               {
+               pbe_algs = sk_new(pbe_cmp);
+               if (!pbe_algs)
+                       {
+                       EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
+                       return 0;
+                       }
+               }
+       else
+               {
+               /* Check if already present */
+               pbelu.pbe_nid = nid;
+               i = sk_find(pbe_algs, (char *)&pbelu);
+               if (i >= 0)
+                       {
+                       pbe_tmp = (EVP_PBE_CTL *)sk_value(pbe_algs, i);
+                       /* If everything identical leave alone */
+                       if (pbe_tmp->cipher == cipher
+                               && pbe_tmp->md == md
+                               && pbe_tmp->keygen == keygen)
+                               return 1;
+                       }
+               else
+                       pbe_tmp = NULL;
+               }
+
+       if (!pbe_tmp)
+               {
+               pbe_tmp = OPENSSL_malloc (sizeof(EVP_PBE_CTL));
+               if (!pbe_tmp)
+                       {
+                       EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
+                       return 0;
+                       }
+               /* If adding a new PBE, set nid, append and sort */
+               pbe_tmp->pbe_nid = nid;
+               sk_push (pbe_algs, (char *)pbe_tmp);
+               sk_sort(pbe_algs);
+               }
+               
        pbe_tmp->cipher = cipher;
        pbe_tmp->md = md;
        pbe_tmp->keygen = keygen;
-       sk_push (pbe_algs, (char *)pbe_tmp);
        return 1;
 }