mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
Rewrite PBE handling read to support PKCS#5 v2.0 and update the function
list for Win32.
This commit is contained in:
parent
095ce35378
commit
69cbf46811
11
CHANGES
11
CHANGES
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user