/* evp_pbe.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
+#include "evp_locl.h"
/* Password based encryption (PBE) functions */
-static STACK *pbe_algs;
+DECLARE_STACK_OF(EVP_PBE_CTL)
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
/* Setup a cipher context from a PBE algorithm */
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
- ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+ ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
{
const EVP_CIPHER *cipher;
const EVP_MD *md;
if (cipher_nid == -1)
cipher = NULL;
else
+ {
cipher = EVP_get_cipherbynid(cipher_nid);
+ if (!cipher)
+ {
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
+ return 0;
+ }
+ }
if (md_nid == -1)
md = NULL;
else
+ {
md = EVP_get_digestbynid(md_nid);
+ if (!md)
+ {
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
+ return 0;
+ }
+ }
if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
{
return 1;
}
-static int pbe_cmp2(const void *a, const void *b)
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
{
- const EVP_PBE_CTL *pbe1 = a;
- const EVP_PBE_CTL *pbe2 = b;
int ret = pbe1->pbe_type - pbe2->pbe_type;
if (ret)
return ret;
return pbe1->pbe_nid - pbe2->pbe_nid;
}
-static int pbe_cmp(const char * const *a, const char * const *b)
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
{
- const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a,
- * const *pbe2 = (const EVP_PBE_CTL * const *)b;
- int ret = (*pbe1)->pbe_type - (*pbe2)->pbe_type;
+ int ret = (*a)->pbe_type - (*b)->pbe_type;
if (ret)
return ret;
else
- return (*pbe1)->pbe_nid - (*pbe2)->pbe_nid;
+ return (*a)->pbe_nid - (*b)->pbe_nid;
}
/* Add a PBE algorithm */
int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
- EVP_PBE_KEYGEN *keygen)
+ EVP_PBE_KEYGEN *keygen)
{
EVP_PBE_CTL *pbe_tmp;
if (!pbe_algs)
- pbe_algs = sk_new(pbe_cmp);
+ pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
{
EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
pbe_tmp->keygen = keygen;
- sk_push (pbe_algs, (char *)pbe_tmp);
+ sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
return 1;
}
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
- EVP_PBE_KEYGEN *keygen)
+ EVP_PBE_KEYGEN *keygen)
{
int cipher_nid, md_nid;
if (cipher)
}
int EVP_PBE_find(int type, int pbe_nid,
- int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+ int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
{
EVP_PBE_CTL *pbetmp = NULL, pbelu;
int i;
if (pbe_algs)
{
- i = sk_find(pbe_algs, (char *)&pbelu);
+ i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
if (i != -1)
- pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
+ pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
}
if (pbetmp == NULL)
{
- pbetmp = (EVP_PBE_CTL *) OBJ_bsearch((char *)&pbelu,
- (char *)builtin_pbe,
- sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL),
- sizeof(EVP_PBE_CTL),
- pbe_cmp2);
+ pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
+ sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
}
if (pbetmp == NULL)
return 0;
*pkeygen = pbetmp->keygen;
return 1;
}
-
+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+ {
+ OPENSSL_freeFunc(pbe);
+ }
void EVP_PBE_cleanup(void)
{
- sk_pop_free(pbe_algs, OPENSSL_freeFunc);
+ sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
pbe_algs = NULL;
}