summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES11
-rw-r--r--crypto/evp/evp.h14
-rw-r--r--crypto/evp/evp_err.c2
-rw-r--r--crypto/evp/evp_pbe.c40
-rw-r--r--crypto/evp/p5_crpt.c22
-rw-r--r--crypto/pkcs12/p12_crpt.c23
-rw-r--r--crypto/pkcs12/p12_decr.c3
-rw-r--r--crypto/pkcs12/pkcs12.h20
-rw-r--r--crypto/x509/x509.h11
-rwxr-xr-xutil/libeay.num18
10 files changed, 100 insertions, 64 deletions
diff --git a/CHANGES b/CHANGES
index 0c6d47cfda..93a7739a9e 100644
--- a/CHANGES
+++ b/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
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index 3d5b27f389..5e12b21f9c 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -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
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index 63ce3ae17d..cd00af8b77 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -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"},
diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c
index 848edddd8c..abc4d0683c 100644
--- a/crypto/evp/evp_pbe.c
+++ b/crypto/evp/evp_pbe.c
@@ -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);
diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c
index 11bf88b96d..857835bc74 100644
--- a/crypto/evp/p5_crpt.c
+++ b/crypto/evp/p5_crpt.c
@@ -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);
diff --git a/crypto/pkcs12/p12_crpt.c b/crypto/pkcs12/p12_crpt.c
index 9e37436c92..cb65c42000 100644
--- a/crypto/pkcs12/p12_crpt.c
+++ b/crypto/pkcs12/p12_crpt.c
@@ -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;
}
diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c
index 53fb8aad0f..8f502fae7f 100644
--- a/crypto/pkcs12/p12_decr.c
+++ b/crypto/pkcs12/p12_decr.c
@@ -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;
}
diff --git a/crypto/pkcs12/pkcs12.h b/crypto/pkcs12/pkcs12.h
index 459962c1a3..12ef0e5146 100644
--- a/crypto/pkcs12/pkcs12.h
+++ b/crypto/pkcs12/pkcs12.h
@@ -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);
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index 0ed0494d21..5106f2e592 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -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.
diff --git a/util/libeay.num b/util/libeay.num
index 3a2dd41a17..f3aaa2dc13 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -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