summaryrefslogtreecommitdiffstats
path: root/crypto/evp/evp_pbe.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-05-14 18:40:53 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-05-14 18:40:53 +0000
commit856640b54f3d22a34d6565e9c78c441a15222577 (patch)
tree35a38e34a4e988d6ef7f8d369a99297baedb3112 /crypto/evp/evp_pbe.c
parent76240b3a394c116a4307b7234ca57eea8e2d412d (diff)
Extend PBE code to support non default PKCS#5 v2.0 PRFs.
Diffstat (limited to 'crypto/evp/evp_pbe.c')
-rw-r--r--crypto/evp/evp_pbe.c138
1 files changed, 101 insertions, 37 deletions
diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c
index c26d2de0f3..c634e1b643 100644
--- a/crypto/evp/evp_pbe.c
+++ b/crypto/evp/evp_pbe.c
@@ -3,7 +3,7 @@
* project 1999.
*/
/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -67,71 +67,135 @@ static STACK *pbe_algs;
/* Setup a cipher context from a PBE algorithm */
-typedef struct {
-int pbe_nid;
-const EVP_CIPHER *cipher;
-const EVP_MD *md;
-EVP_PBE_KEYGEN *keygen;
-} EVP_PBE_CTL;
+typedef struct
+ {
+ int pbe_type;
+ int pbe_nid;
+ int cipher_nid;
+ int md_nid;
+ EVP_PBE_KEYGEN *keygen;
+ } EVP_PBE_CTL;
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
-{
+ {
+ const EVP_CIPHER *cipher;
+ const EVP_MD *md;
+ int cipher_nid, md_nid;
+ EVP_PBE_KEYGEN *keygen;
- EVP_PBE_CTL *pbetmp, pbelu;
- int i;
- pbelu.pbe_nid = OBJ_obj2nid(pbe_obj);
- if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu);
- else i = -1;
-
- if (i == -1) {
+ if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+ &cipher_nid, &md_nid, &keygen))
+ {
char obj_tmp[80];
EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
ERR_add_error_data(2, "TYPE=", obj_tmp);
return 0;
- }
- if(!pass) passlen = 0;
- else if (passlen == -1) passlen = strlen(pass);
- pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
- i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
- pbetmp->md, en_de);
- if (!i) {
+ }
+
+ if(!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+
+ if (cipher_nid == -1)
+ cipher = NULL;
+ else
+ cipher = EVP_get_cipherbynid(cipher_nid);
+
+ if (md_nid == -1)
+ md = NULL;
+ else
+ md = EVP_get_digestbynid(md_nid);
+
+ if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
+ {
EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
return 0;
- }
+ }
return 1;
}
static int pbe_cmp(const char * const *a, const char * const *b)
-{
+ {
const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a,
* const *pbe2 = (const EVP_PBE_CTL * const *)b;
- return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid);
-}
+ int ret = (*pbe1)->pbe_type - (*pbe2)->pbe_type;
+ if (ret)
+ return ret;
+ else
+ return (*pbe1)->pbe_nid - (*pbe2)->pbe_nid;
+ }
/* Add a PBE algorithm */
-int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
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)))) {
+ 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;
- pbe_tmp->cipher = cipher;
- pbe_tmp->md = md;
+ }
+ pbe_tmp->pbe_type = pbe_type;
+ pbe_tmp->pbe_nid = pbe_nid;
+ pbe_tmp->cipher_nid = cipher_nid;
+ pbe_tmp->md_nid = md_nid;
pbe_tmp->keygen = keygen;
+
+
sk_push (pbe_algs, (char *)pbe_tmp);
return 1;
-}
+ }
+
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+ EVP_PBE_KEYGEN *keygen)
+ {
+ int cipher_nid, md_nid;
+ if (cipher)
+ cipher_nid = EVP_CIPHER_type(cipher);
+ else
+ cipher_nid = -1;
+ if (md)
+ md_nid = EVP_MD_type(md);
+ else
+ md_nid = -1;
+
+ return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+ cipher_nid, md_nid, keygen);
+ }
+
+int EVP_PBE_find(int type, int pbe_nid,
+ int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+ {
+ EVP_PBE_CTL *pbetmp, pbelu;
+ int i;
+ if (pbe_nid == NID_undef)
+ return 0;
+ pbelu.pbe_type = type;
+ pbelu.pbe_nid = pbe_nid;
+ i = sk_find(pbe_algs, (char *)&pbelu);
+ if (i == -1)
+ return 0;
+ pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
+ if (pcnid)
+ *pcnid = pbetmp->cipher_nid;
+ if (pmnid)
+ *pmnid = pbetmp->md_nid;
+ if (pkeygen)
+ *pkeygen = pbetmp->keygen;
+ return 1;
+ }
+
+
void EVP_PBE_cleanup(void)
-{
+ {
sk_pop_free(pbe_algs, OPENSSL_freeFunc);
pbe_algs = NULL;
-}
+ }