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".
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;
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);
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"))) {
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);
}
} 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);
X509_SIG_free(p8);
}
PKCS8_PRIV_KEY_INFO_free (p8inf);
+ EVP_PKEY_free(pkey);
+ BIO_free(out);
return (0);
}
}
EVP_read_pw_string(pass, 50, "Enter Password:", 0);
p8inf = M_PKCS8_decrypt(p8, pass, strlen(pass));
+ X509_SIG_free(p8);
}
if (!p8inf) {
PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL);
+ EVP_PKEY_free(pkey);
+ BIO_free(out);
+ BIO_free(in);
+
return (0);
}
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);
* 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;
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,
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;
}
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;
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;
}
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,
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);