Rewrite PBE handling read to support PKCS#5 v2.0 and update the function
authorDr. Stephen Henson <steve@openssl.org>
Sun, 6 Jun 1999 13:07:13 +0000 (13:07 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 6 Jun 1999 13:07:13 +0000 (13:07 +0000)
list for Win32.

CHANGES
crypto/evp/evp.h
crypto/evp/evp_err.c
crypto/evp/evp_pbe.c
crypto/evp/p5_crpt.c
crypto/pkcs12/p12_crpt.c
crypto/pkcs12/p12_decr.c
crypto/pkcs12/pkcs12.h
crypto/x509/x509.h
util/libeay.num

diff --git a/CHANGES b/CHANGES
index 0c6d47cfda342ae4f67bdd64a3340a639e7986d2..93a7739a9ea053e2a385ddc5511b079ecae2b91a 100644 (file)
--- 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
index 3d5b27f389a3ac5670765eef60e3d7c2ac63e2a9..5e12b21f9c5e901115e8c22ce996d17a53e13420 100644 (file)
@@ -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
index 63ce3ae17d3c7fdfd41bd4c0ee937a87ee0d1e61..cd00af8b77da458a221e47dee2a418bc4c2a4e59 100644 (file)
@@ -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"},
index 848edddd8c9257e7393fac30ba838162ca94a5d4..abc4d0683c1e70f38010c8200d7074966fede6de 100644 (file)
@@ -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);
index 11bf88b96d84e64bb23e7622ef6dda4855748b63..857835bc74358ce5b2c7413a21509a9003223b7e 100644 (file)
@@ -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);
index 9e37436c925e02e29c0f275abce9101f70947e0d..cb65c4200079b2263369d027df2b7e6e1a8c4982 100644 (file)
@@ -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;
 }
index 53fb8aad0fe7940bf2b920b4eff2b63cd7af4eba..8f502fae7fe6c1df3435be72bb83e4dde3fec9ba 100644 (file)
@@ -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;
        }
index 459962c1a35f725cee585f3189a5a8ff86174bae..12ef0e5146b572590cc4ab9186f5fa1372ce3ff3 100644 (file)
@@ -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);
index 0ed0494d21d94c5cb21b1085003e71832767db3b..5106f2e5921d68153293454f571d04f51bdf10ab 100644 (file)
@@ -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.
index 3a2dd41a17ea2219847d9c5b2eead248895b1002..f3aaa2dc13fea4c368532e8ff56aa3ead4835529 100755 (executable)
@@ -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