提交 69cbf468 编写于 作者: D Dr. Stephen Henson

Rewrite PBE handling read to support PKCS#5 v2.0 and update the function

list for Win32.
上级 095ce353
......@@ -5,6 +5,17 @@
Changes between 0.9.3a and 0.9.4
*) Rewrite the way password based encryption (PBE) is handled. It used to
assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
the 'parameter' field of the AlgorithmIdentifier is passed to the
underlying key generation function so it must do its own ASN1 parsing.
This has also changed the EVP_PBE_CipherInit() function which now has a
'parameter' argument instead of literal salt and iteration count values
and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
[Steve Henson]
*) Support for PKCS#5 v1.5 compatible password based encryption algorithms
and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
......
......@@ -396,7 +396,7 @@ typedef struct evp_Encode_Ctx_st
/* Password based encryption function */
typedef int (EVP_PBE_KEYGEN)(const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter, EVP_CIPHER *cipher,
ASN1_TYPE *param, EVP_CIPHER *cipher,
EVP_MD *md, unsigned char *key, unsigned char *iv);
#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
......@@ -635,12 +635,18 @@ int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
/* PKCS5 password based encryption */
int PKCS5_PBE_keyivgen(const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, EVP_CIPHER *cipher, EVP_MD *md,
int PKCS5_PBE_keyivgen(const char *pass, int passlen, ASN1_TYPE *param,
EVP_CIPHER *cipher, EVP_MD *md,
unsigned char *key, unsigned char *iv);
void PKCS5_PBE_add(void);
int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
int EVP_PBE_alg_add(int nid, EVP_CIPHER *cipher, EVP_MD *md,
EVP_PBE_KEYGEN *keygen);
void EVP_PBE_cleanup(void);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
......@@ -653,9 +659,9 @@ void PKCS5_PBE_add(void);
#define EVP_F_EVP_DECRYPTFINAL 101
#define EVP_F_EVP_MD_CTX_COPY 110
#define EVP_F_EVP_OPENINIT 102
#define EVP_F_EVP_PBE_ALGOR_CIPHERINIT 114
#define EVP_F_EVP_PBE_ALG_ADD 115
#define EVP_F_EVP_PBE_CIPHERINIT 116
#define EVP_F_EVP_PKCS5_PBE_KEYIVGEN 117
#define EVP_F_EVP_PKCS82PKEY 111
#define EVP_F_EVP_PKCS8_SET_BROKEN 112
#define EVP_F_EVP_PKEY2PKCS8 113
......
......@@ -69,9 +69,9 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_PACK(0,EVP_F_EVP_DECRYPTFINAL,0), "EVP_DecryptFinal"},
{ERR_PACK(0,EVP_F_EVP_MD_CTX_COPY,0), "EVP_MD_CTX_copy"},
{ERR_PACK(0,EVP_F_EVP_OPENINIT,0), "EVP_OpenInit"},
{ERR_PACK(0,EVP_F_EVP_PBE_ALGOR_CIPHERINIT,0), "EVP_PBE_ALGOR_CipherInit"},
{ERR_PACK(0,EVP_F_EVP_PBE_ALG_ADD,0), "EVP_PBE_alg_add"},
{ERR_PACK(0,EVP_F_EVP_PBE_CIPHERINIT,0), "EVP_PBE_CipherInit"},
{ERR_PACK(0,EVP_F_EVP_PKCS5_PBE_KEYIVGEN,0), "EVP_PKCS5_PBE_KEYIVGEN"},
{ERR_PACK(0,EVP_F_EVP_PKCS82PKEY,0), "EVP_PKCS82PKEY"},
{ERR_PACK(0,EVP_F_EVP_PKCS8_SET_BROKEN,0), "EVP_PKCS8_SET_BROKEN"},
{ERR_PACK(0,EVP_F_EVP_PKEY2PKCS8,0), "EVP_PKEY2PKCS8"},
......
......@@ -75,8 +75,7 @@ EVP_PBE_KEYGEN *keygen;
} EVP_PBE_CTL;
int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter, EVP_CIPHER_CTX *ctx,
int en_de)
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
{
EVP_PBE_CTL *pbetmp, pbelu;
......@@ -96,8 +95,8 @@ int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
}
if (passlen == -1) passlen = strlen(pass);
pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
i = (*pbetmp->keygen)(pass, passlen, salt, saltlen, iter,
pbetmp->cipher, pbetmp->md, key, iv);
i = (*pbetmp->keygen)(pass, passlen, param, pbetmp->cipher,
pbetmp->md, key, iv);
if (!i) {
EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
return 0;
......@@ -106,39 +105,6 @@ int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
return 1;
}
/* Setup a PBE algorithm but take most parameters from AlgorithmIdentifier */
int EVP_PBE_ALGOR_CipherInit (X509_ALGOR *algor, const char *pass,
int passlen, EVP_CIPHER_CTX *ctx, int en_de)
{
PBEPARAM *pbe;
int saltlen, iter;
unsigned char *salt, *pbuf;
/* Extract useful info from algor */
pbuf = algor->parameter->value.sequence->data;
if (!(pbe = d2i_PBEPARAM (NULL, &pbuf,
algor->parameter->value.sequence->length))) {
EVPerr(EVP_F_EVP_PBE_ALGOR_CIPHERINIT,EVP_R_DECODE_ERROR);
return 0;
}
if (!pbe->iter) iter = 1;
else iter = ASN1_INTEGER_get (pbe->iter);
salt = pbe->salt->data;
saltlen = pbe->salt->length;
if (!(EVP_PBE_CipherInit (algor->algorithm, pass, passlen, salt,
saltlen, iter, ctx, en_de))) {
EVPerr(EVP_F_EVP_PBE_ALGOR_CIPHERINIT,EVP_R_EVP_PBE_CIPHERINIT_ERROR);
PBEPARAM_free(pbe);
return 0;
}
PBEPARAM_free(pbe);
return 1;
}
static int pbe_cmp (EVP_PBE_CTL **pbe1, EVP_PBE_CTL **pbe2)
{
return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid);
......
......@@ -85,16 +85,34 @@ EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
#endif
}
int PKCS5_PBE_keyivgen(const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, EVP_CIPHER *cipher, EVP_MD *md,
int PKCS5_PBE_keyivgen(const char *pass, int passlen, ASN1_TYPE *param,
EVP_CIPHER *cipher, EVP_MD *md,
unsigned char *key, unsigned char *iv)
{
EVP_MD_CTX ctx;
unsigned char md_tmp[EVP_MAX_MD_SIZE];
int i;
PBEPARAM *pbe;
int saltlen, iter;
unsigned char *salt, *pbuf;
/* Extract useful info from parameter */
pbuf = param->value.sequence->data;
if (!(pbe = d2i_PBEPARAM (NULL, &pbuf,
param->value.sequence->length))) {
EVPerr(EVP_F_EVP_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
return 0;
}
if (!pbe->iter) iter = 1;
else iter = ASN1_INTEGER_get (pbe->iter);
salt = pbe->salt->data;
saltlen = pbe->salt->length;
EVP_DigestInit (&ctx, md);
EVP_DigestUpdate (&ctx, pass, passlen);
EVP_DigestUpdate (&ctx, salt, saltlen);
PBEPARAM_free(pbe);
EVP_DigestFinal (&ctx, md_tmp, NULL);
for (i = 1; i < iter; i++) {
EVP_DigestInit(&ctx, md);
......
......@@ -82,19 +82,38 @@ EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(),
#endif
}
int PKCS12_PBE_keyivgen (const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, EVP_CIPHER *cipher, EVP_MD *md,
int PKCS12_PBE_keyivgen (const char *pass, int passlen, ASN1_TYPE *param,
EVP_CIPHER *cipher, EVP_MD *md,
unsigned char *key, unsigned char *iv)
{
PBEPARAM *pbe;
int saltlen, iter;
unsigned char *salt, *pbuf;
/* Extract useful info from parameter */
pbuf = param->value.sequence->data;
if (!(pbe = d2i_PBEPARAM (NULL, &pbuf,
param->value.sequence->length))) {
EVPerr(PKCS12_F_PKCS12_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
return 0;
}
if (!pbe->iter) iter = 1;
else iter = ASN1_INTEGER_get (pbe->iter);
salt = pbe->salt->data;
saltlen = pbe->salt->length;
if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID,
iter, EVP_CIPHER_key_length(cipher), key, md)) {
PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID,
iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_IV_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
PBEPARAM_free(pbe);
return 1;
}
......@@ -82,7 +82,8 @@ unsigned char * PKCS12_pbe_crypt (X509_ALGOR *algor, const char *pass,
}
/* Decrypt data */
if (!EVP_PBE_ALGOR_CipherInit (algor, pass, passlen, &ctx, en_de)) {
if (!EVP_PBE_CipherInit (algor->algorithm, pass, passlen,
algor->parameter, &ctx, en_de)) {
PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
return NULL;
}
......
......@@ -230,13 +230,17 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type);
int PKCS12_PBE_keyivgen(const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_CIPHER *cipher, EVP_MD *md_type, unsigned char *key, unsigned char *iv);
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen);
int PKCS12_PBE_keyivgen(const char *pass, int passlen, ASN1_TYPE *param,
EVP_CIPHER *cipher, EVP_MD *md_type,
unsigned char *key, unsigned char *iv);
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *mac, unsigned int *maclen);
int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
EVP_MD *md_type);
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, EVP_MD *md_type);
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
int saltlen, EVP_MD *md_type);
unsigned char *asc2uni(const char *asc, unsigned char **uni, int *unilen);
char *uni2asc(unsigned char *uni, int unilen);
int i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **pp);
......@@ -249,17 +253,21 @@ PKCS12 *PKCS12_new(void);
void PKCS12_free(PKCS12 *a);
int i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **pp);
PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void);
PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, unsigned char **pp, long length);
PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, unsigned char **pp,
long length);
void PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a);
int i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **pp);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_new(void);
PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, unsigned char **pp, long length);
PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, unsigned char **pp,
long length);
void PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a);
void ERR_load_PKCS12_strings(void);
void PKCS12_PBE_add(void);
int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
STACK **ca);
PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype);
PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
STACK *ca, int nid_key, int nid_cert, int iter,
int mac_iter, int keytype);
int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
......
......@@ -929,17 +929,6 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
/* Password based encryption routines */
int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter, EVP_CIPHER_CTX *ctx,
int en_de);
int EVP_PBE_ALGOR_CipherInit(X509_ALGOR *algor, const char *pass,
int passlen, EVP_CIPHER_CTX *ctx, int en_de);
int EVP_PBE_alg_add(int nid, EVP_CIPHER *cipher, EVP_MD *md,
EVP_PBE_KEYGEN *keygen);
void EVP_PBE_cleanup(void);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
......
......@@ -1747,3 +1747,21 @@ sk_X509_LOOKUP_delete_ptr 1771
sk_X509_LOOKUP_set 1772
sk_PKCS7_RECIP_INFO_find 1773
sk_PKCS7_RECIP_INFO_delete 1774
PKCS5_PBE_add 1775
PEM_write_bio_PKCS8 1776
i2d_PKCS8_fp 1777
PEM_read_bio_PKCS8_PRIV_KEY_INFO 1778
d2i_PKCS8_bio 1779
d2i_PKCS8_PRIV_KEY_INFO_fp 1780
PEM_write_bio_PKCS8_PRIV_KEY_INFO 1781
PEM_read_PKCS8 1782
d2i_PKCS8_PRIV_KEY_INFO_bio 1783
d2i_PKCS8_fp 1784
PEM_write_PKCS8 1785
PEM_read_PKCS8_PRIV_KEY_INFO 1786
PEM_read_bio_PKCS8 1787
PEM_write_PKCS8_PRIV_KEY_INFO 1788
PKCS5_PBE_keyivgen 1789
i2d_PKCS8_bio 1790
i2d_PKCS8_PRIV_KEY_INFO_fp 1791
i2d_PKCS8_PRIV_KEY_INFO_bio 1792
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册