diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-05-14 18:40:53 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-05-14 18:40:53 +0000 |
commit | 856640b54f3d22a34d6565e9c78c441a15222577 (patch) | |
tree | 35a38e34a4e988d6ef7f8d369a99297baedb3112 /crypto/evp/evp_pbe.c | |
parent | 76240b3a394c116a4307b7234ca57eea8e2d412d (diff) | |
download | openssl-856640b54f3d22a34d6565e9c78c441a15222577.tar.gz |
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.c | 138 |
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; -} + } |