| Index: openssl/crypto/evp/evp_pbe.c
|
| ===================================================================
|
| --- openssl/crypto/evp/evp_pbe.c (revision 105093)
|
| +++ openssl/crypto/evp/evp_pbe.c (working copy)
|
| @@ -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
|
| @@ -59,79 +59,253 @@
|
| #include <stdio.h>
|
| #include "cryptlib.h"
|
| #include <openssl/evp.h>
|
| +#include <openssl/pkcs12.h>
|
| #include <openssl/x509.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 */
|
|
|
| -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;
|
|
|
| +static const EVP_PBE_CTL builtin_pbe[] =
|
| + {
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
|
| + NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
|
| + NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
|
| + NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
|
| +
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
|
| + NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
|
| + NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
|
| + NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
|
| + NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
|
| + NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
|
| + NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
|
| +
|
| +#ifndef OPENSSL_NO_HMAC
|
| + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
|
| +#endif
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
|
| + NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
|
| + NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
|
| + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
|
| + NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
|
| +
|
| +
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
|
| + {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
|
| + };
|
| +
|
| +#ifdef TEST
|
| +int main(int argc, char **argv)
|
| + {
|
| + int i, nid_md, nid_cipher;
|
| + EVP_PBE_CTL *tpbe, *tpbe2;
|
| + /*OpenSSL_add_all_algorithms();*/
|
| +
|
| + for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
|
| + {
|
| + tpbe = builtin_pbe + i;
|
| + fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
|
| + OBJ_nid2sn(tpbe->pbe_nid));
|
| + if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
|
| + &nid_cipher ,&nid_md,0))
|
| + fprintf(stderr, "Found %s %s\n",
|
| + OBJ_nid2sn(nid_cipher),
|
| + OBJ_nid2sn(nid_md));
|
| + else
|
| + fprintf(stderr, "Find ERROR!!\n");
|
| + }
|
| +
|
| + return 0;
|
| + }
|
| +#endif
|
| +
|
| +
|
| +
|
| 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;
|
| + 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 (!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))
|
| + {
|
| 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);
|
| -}
|
| +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)
|
| + {
|
| + int ret = pbe1->pbe_type - pbe2->pbe_type;
|
| + if (ret)
|
| + return ret;
|
| + else
|
| + return pbe1->pbe_nid - pbe2->pbe_nid;
|
| + }
|
| +
|
| +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)
|
| + {
|
| + int ret = (*a)->pbe_type - (*b)->pbe_type;
|
| + if (ret)
|
| + return ret;
|
| + else
|
| + return (*a)->pbe_nid - (*b)->pbe_nid;
|
| + }
|
| +
|
| /* Add a PBE algorithm */
|
|
|
| -int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
|
| - EVP_PBE_KEYGEN *keygen)
|
| -{
|
| +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)))) {
|
| - EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
|
| + if (!pbe_algs)
|
| + 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);
|
| 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);
|
| +
|
| +
|
| + 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)
|
| + {
|
| + 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 = NULL, pbelu;
|
| + int i;
|
| + if (pbe_nid == NID_undef)
|
| + return 0;
|
| +
|
| + pbelu.pbe_type = type;
|
| + pbelu.pbe_nid = pbe_nid;
|
| +
|
| + if (pbe_algs)
|
| + {
|
| + i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
|
| + if (i != -1)
|
| + pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
|
| + }
|
| + if (pbetmp == NULL)
|
| + {
|
| + pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
|
| + sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
|
| + }
|
| + if (pbetmp == NULL)
|
| + return 0;
|
| + if (pcnid)
|
| + *pcnid = pbetmp->cipher_nid;
|
| + if (pmnid)
|
| + *pmnid = pbetmp->md_nid;
|
| + if (pkeygen)
|
| + *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;
|
| -}
|
| + }
|
|
|