Complete support for PKCS#5 v2.0. Still needs extensive testing.
authorDr. Stephen Henson <steve@openssl.org>
Tue, 8 Jun 1999 00:09:51 +0000 (00:09 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 8 Jun 1999 00:09:51 +0000 (00:09 +0000)
CHANGES
apps/pkcs8.c
crypto/asn1/p5_pbev2.c
crypto/evp/p5_crpt.c
crypto/pkcs12/p12_add.c
crypto/pkcs12/pkcs12.h
crypto/x509/x509.h

diff --git a/CHANGES b/CHANGES
index a10452407763278304a2a40f50175d533881c633..6f3d2c99378057133fa75273b68d0483840dfb4c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,14 @@
 
  Changes between 0.9.3a and 0.9.4
 
+  *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
+     used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
+     ciphers. NOTE: although the key derivation function has been verified
+     against some published test vectors it has not been extensively tested
+     yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
+     of v2.0.
+     [Steve Henson]
+
   *) Instead of "mkdir -p", which is not fully portable, use new
      Perl script "util/mkdir-p.pl".
 
index 42d6ba437ca6672c40f1c71e735eb0ec30fdc1d1..9779081734bf36b39e91af38636e70225bf8a9b7 100644 (file)
@@ -71,6 +71,7 @@ int MAIN(int argc, char **argv)
        BIO *in = NULL, *out = NULL;
        int topk8 = 0;
        int pbe_nid = -1;
+       const EVP_CIPHER *cipher = NULL;
        int iter = PKCS12_DEFAULT_ITER;
        int informat, outformat;
        int p8_broken = PKCS8_OK;
@@ -87,7 +88,17 @@ int MAIN(int argc, char **argv)
        SSLeay_add_all_algorithms();
        args = argv + 1;
        while (!badarg && *args && *args[0] == '-') {
-               if (!strcmp(*args,"-inform")) {
+               if (!strcmp(*args,"-v2")) {
+                       if (args[1]) {
+                               args++;
+                               cipher=EVP_get_cipherbyname(*args);
+                               if(!cipher) {
+                                       BIO_printf(bio_err,
+                                                "Unknown cipher %s\n", *args);
+                                       badarg = 1;
+                               }
+                       } else badarg = 1;
+               } else if (!strcmp(*args,"-inform")) {
                        if (args[1]) {
                                args++;
                                informat=str2fmt(*args);
@@ -126,10 +137,11 @@ int MAIN(int argc, char **argv)
                BIO_printf (bio_err, "-nooct     use (broken) no octet form\n");
                BIO_printf (bio_err, "-noiter    use 1 as iteration count\n");
                BIO_printf (bio_err, "-nocrypt   use or expect unencrypted private key\n");
+               BIO_printf (bio_err, "-v2 alg    use PKCS#5 v2.0 and cipher \"alg\"\n");
                return (1);
        }
 
-       if (pbe_nid == -1) pbe_nid = NID_pbeWithMD5AndDES_CBC;
+       if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC;
 
        if (infile) {
                if (!(in = BIO_new_file (infile, "rb"))) {
@@ -153,6 +165,7 @@ int MAIN(int argc, char **argv)
                        ERR_print_errors(bio_err);
                        return (1);
                }
+               BIO_free(in);
                if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
                        BIO_printf (bio_err, "Error converting key\n", outfile);
                        ERR_print_errors(bio_err);
@@ -170,8 +183,9 @@ int MAIN(int argc, char **argv)
                        }
                } else {
                        EVP_read_pw_string(pass, 50, "Enter Encryption Password:", 1);
-                       if (!(p8 = PKCS8_encrypt(pbe_nid, pass, strlen(pass),
-                                        NULL, 0, iter, p8inf))) {
+                       if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
+                                       pass, strlen(pass),
+                                       NULL, 0, iter, p8inf))) {
                                BIO_printf (bio_err, "Error encrypting key\n",
                                                                 outfile);
                                ERR_print_errors(bio_err);
@@ -188,6 +202,8 @@ int MAIN(int argc, char **argv)
                        X509_SIG_free(p8);
                }
                PKCS8_PRIV_KEY_INFO_free (p8inf);
+               EVP_PKEY_free(pkey);
+               BIO_free(out);
                return (0);
        }
 
@@ -217,6 +233,7 @@ int MAIN(int argc, char **argv)
                }
                EVP_read_pw_string(pass, 50, "Enter Password:", 0);
                p8inf = M_PKCS8_decrypt(p8, pass, strlen(pass));
+               X509_SIG_free(p8);
        }
 
        if (!p8inf) {
@@ -248,5 +265,9 @@ int MAIN(int argc, char **argv)
 
        PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL);
 
+       EVP_PKEY_free(pkey);
+       BIO_free(out);
+       BIO_free(in);
+
        return (0);
 }
index 51e587e9231d25ac338fc704b334c8bf93c67ac0..10364a056141a8295bbed99939f0e69f2bc4e9d4 100644 (file)
@@ -153,7 +153,7 @@ PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, unsigned char **pp,
 void PBKDF2PARAM_free (PBKDF2PARAM *a)
 {
        if(a==NULL) return;
-       ASN1_OCTET_STRING_free(a->salt);
+       ASN1_TYPE_free(a->salt);
        ASN1_INTEGER_free(a->iter);
        ASN1_INTEGER_free(a->keylength);
        X509_ALGOR_free(a->prf);
@@ -164,8 +164,8 @@ void PBKDF2PARAM_free (PBKDF2PARAM *a)
  * yes I know this is horrible!
  */
 
-X509_ALGOR *PKCS5_pbe2_set(EVP_CIPHER *cipher, int iter, unsigned char *salt,
-            int saltlen)
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                                unsigned char *salt, int saltlen)
 {
        X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
        int alg_nid;
index 0cf7e9d45e70f250f9a37656e82991c3712d734d..798cbe9b823a63041e4f9803bca9515801f6368f 100644 (file)
@@ -83,6 +83,7 @@ EVP_PBE_alg_add(NID_pbeWithMD2AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md2(),
 EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
                                                         PKCS5_PBE_keyivgen);
 #endif
+EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen);
 }
 
 int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
index b5858d1a109f2e7cf12971e1a52f57e46f03d311..ae3d9de3b4a9de7d690420dcad7e53e096050b04 100644 (file)
@@ -115,7 +115,8 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG (int pbe_nid, const char *pass,
 
        bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
        if (!(bag->value.shkeybag = 
-         PKCS8_encrypt(pbe_nid, pass, passlen, salt, saltlen, iter, p8))) {
+         PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter,
+                                                                        p8))) {
                PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
                return NULL;
        }
@@ -180,9 +181,10 @@ PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen,
        return p7;
 }
 
-X509_SIG *PKCS8_encrypt (int pbe_nid, const char *pass, int passlen,
-            unsigned char *salt, int saltlen, int iter,
-            PKCS8_PRIV_KEY_INFO *p8inf)
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+                        const char *pass, int passlen,
+                        unsigned char *salt, int saltlen, int iter,
+                                               PKCS8_PRIV_KEY_INFO *p8inf)
 {
        X509_SIG *p8;
        X509_ALGOR *pbe;
@@ -192,7 +194,9 @@ X509_SIG *PKCS8_encrypt (int pbe_nid, const char *pass, int passlen,
                return NULL;
        }
 
-       if (!(pbe = PKCS5_pbe_set (pbe_nid, iter, salt, saltlen))) {
+       if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
+       else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+       if(!pbe) {
                PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
                return NULL;
        }
index 1ab91a3c8f4ef5fa6a09e383f52e46f77b20f8d3..5f3b1148fa84bd58d0da8e0226ccd2249f5f4ecb 100644 (file)
@@ -197,7 +197,8 @@ ASN1_seq_unpack((p12)->authsafes->d.data->data, \
 
 PKCS12_SAFEBAG *PKCS12_pack_safebag(char *obj, int (*i2d)(), int nid1, int nid2);
 PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
-X509_SIG *PKCS8_encrypt(int pbe_nid, const char *pass, int passlen,
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, 
+                       const char *pass, int passlen,
                        unsigned char *salt, int saltlen, int iter,
                        PKCS8_PRIV_KEY_INFO *p8);
 PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
index 5030d920e97ba583f64693301efb4bc359cbd4f4..f4718e5411f1ba894fde8801b108ffdb2f701479 100644 (file)
@@ -906,8 +906,8 @@ PBEPARAM *PBEPARAM_new(void);
 PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length);
 void PBEPARAM_free(PBEPARAM *a);
 X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
-X509_ALGOR *PKCS5_pbe2_set(EVP_CIPHER *cipher, int iter, unsigned char *salt,
-                                                                int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                                        unsigned char *salt, int saltlen);
 
 int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp);
 PBKDF2PARAM *PBKDF2PARAM_new(void);