Complete support for PKCS#5 v2.0. Still needs extensive testing.
This commit is contained in:
parent
1aad3392e5
commit
8eb57af5fe
8
CHANGES
8
CHANGES
@ -5,6 +5,14 @@
|
|||||||
|
|
||||||
Changes between 0.9.3a and 0.9.4
|
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
|
*) Instead of "mkdir -p", which is not fully portable, use new
|
||||||
Perl script "util/mkdir-p.pl".
|
Perl script "util/mkdir-p.pl".
|
||||||
|
|
||||||
|
29
apps/pkcs8.c
29
apps/pkcs8.c
@ -71,6 +71,7 @@ int MAIN(int argc, char **argv)
|
|||||||
BIO *in = NULL, *out = NULL;
|
BIO *in = NULL, *out = NULL;
|
||||||
int topk8 = 0;
|
int topk8 = 0;
|
||||||
int pbe_nid = -1;
|
int pbe_nid = -1;
|
||||||
|
const EVP_CIPHER *cipher = NULL;
|
||||||
int iter = PKCS12_DEFAULT_ITER;
|
int iter = PKCS12_DEFAULT_ITER;
|
||||||
int informat, outformat;
|
int informat, outformat;
|
||||||
int p8_broken = PKCS8_OK;
|
int p8_broken = PKCS8_OK;
|
||||||
@ -87,7 +88,17 @@ int MAIN(int argc, char **argv)
|
|||||||
SSLeay_add_all_algorithms();
|
SSLeay_add_all_algorithms();
|
||||||
args = argv + 1;
|
args = argv + 1;
|
||||||
while (!badarg && *args && *args[0] == '-') {
|
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]) {
|
if (args[1]) {
|
||||||
args++;
|
args++;
|
||||||
informat=str2fmt(*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, "-nooct use (broken) no octet form\n");
|
||||||
BIO_printf (bio_err, "-noiter use 1 as iteration count\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, "-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);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pbe_nid == -1) pbe_nid = NID_pbeWithMD5AndDES_CBC;
|
if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC;
|
||||||
|
|
||||||
if (infile) {
|
if (infile) {
|
||||||
if (!(in = BIO_new_file (infile, "rb"))) {
|
if (!(in = BIO_new_file (infile, "rb"))) {
|
||||||
@ -153,6 +165,7 @@ int MAIN(int argc, char **argv)
|
|||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
BIO_free(in);
|
||||||
if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
|
if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
|
||||||
BIO_printf (bio_err, "Error converting key\n", outfile);
|
BIO_printf (bio_err, "Error converting key\n", outfile);
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
@ -170,8 +183,9 @@ int MAIN(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EVP_read_pw_string(pass, 50, "Enter Encryption Password:", 1);
|
EVP_read_pw_string(pass, 50, "Enter Encryption Password:", 1);
|
||||||
if (!(p8 = PKCS8_encrypt(pbe_nid, pass, strlen(pass),
|
if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
|
||||||
NULL, 0, iter, p8inf))) {
|
pass, strlen(pass),
|
||||||
|
NULL, 0, iter, p8inf))) {
|
||||||
BIO_printf (bio_err, "Error encrypting key\n",
|
BIO_printf (bio_err, "Error encrypting key\n",
|
||||||
outfile);
|
outfile);
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
@ -188,6 +202,8 @@ int MAIN(int argc, char **argv)
|
|||||||
X509_SIG_free(p8);
|
X509_SIG_free(p8);
|
||||||
}
|
}
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8inf);
|
PKCS8_PRIV_KEY_INFO_free (p8inf);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
BIO_free(out);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +233,7 @@ int MAIN(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
EVP_read_pw_string(pass, 50, "Enter Password:", 0);
|
EVP_read_pw_string(pass, 50, "Enter Password:", 0);
|
||||||
p8inf = M_PKCS8_decrypt(p8, pass, strlen(pass));
|
p8inf = M_PKCS8_decrypt(p8, pass, strlen(pass));
|
||||||
|
X509_SIG_free(p8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p8inf) {
|
if (!p8inf) {
|
||||||
@ -248,5 +265,9 @@ int MAIN(int argc, char **argv)
|
|||||||
|
|
||||||
PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL);
|
PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL);
|
||||||
|
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
BIO_free(out);
|
||||||
|
BIO_free(in);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, unsigned char **pp,
|
|||||||
void PBKDF2PARAM_free (PBKDF2PARAM *a)
|
void PBKDF2PARAM_free (PBKDF2PARAM *a)
|
||||||
{
|
{
|
||||||
if(a==NULL) return;
|
if(a==NULL) return;
|
||||||
ASN1_OCTET_STRING_free(a->salt);
|
ASN1_TYPE_free(a->salt);
|
||||||
ASN1_INTEGER_free(a->iter);
|
ASN1_INTEGER_free(a->iter);
|
||||||
ASN1_INTEGER_free(a->keylength);
|
ASN1_INTEGER_free(a->keylength);
|
||||||
X509_ALGOR_free(a->prf);
|
X509_ALGOR_free(a->prf);
|
||||||
@ -164,8 +164,8 @@ void PBKDF2PARAM_free (PBKDF2PARAM *a)
|
|||||||
* yes I know this is horrible!
|
* yes I know this is horrible!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
X509_ALGOR *PKCS5_pbe2_set(EVP_CIPHER *cipher, int iter, unsigned char *salt,
|
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
|
||||||
int saltlen)
|
unsigned char *salt, int saltlen)
|
||||||
{
|
{
|
||||||
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
|
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
|
||||||
int alg_nid;
|
int alg_nid;
|
||||||
|
@ -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(),
|
EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
|
||||||
PKCS5_PBE_keyivgen);
|
PKCS5_PBE_keyivgen);
|
||||||
#endif
|
#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,
|
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
|
||||||
|
@ -115,7 +115,8 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG (int pbe_nid, const char *pass,
|
|||||||
|
|
||||||
bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
|
bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
|
||||||
if (!(bag->value.shkeybag =
|
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);
|
PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -180,9 +181,10 @@ PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen,
|
|||||||
return p7;
|
return p7;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_SIG *PKCS8_encrypt (int pbe_nid, const char *pass, int passlen,
|
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
|
||||||
unsigned char *salt, int saltlen, int iter,
|
const char *pass, int passlen,
|
||||||
PKCS8_PRIV_KEY_INFO *p8inf)
|
unsigned char *salt, int saltlen, int iter,
|
||||||
|
PKCS8_PRIV_KEY_INFO *p8inf)
|
||||||
{
|
{
|
||||||
X509_SIG *p8;
|
X509_SIG *p8;
|
||||||
X509_ALGOR *pbe;
|
X509_ALGOR *pbe;
|
||||||
@ -192,7 +194,9 @@ X509_SIG *PKCS8_encrypt (int pbe_nid, const char *pass, int passlen,
|
|||||||
return NULL;
|
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);
|
PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -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_pack_safebag(char *obj, int (*i2d)(), int nid1, int nid2);
|
||||||
PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
|
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,
|
unsigned char *salt, int saltlen, int iter,
|
||||||
PKCS8_PRIV_KEY_INFO *p8);
|
PKCS8_PRIV_KEY_INFO *p8);
|
||||||
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
|
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
|
||||||
|
@ -906,8 +906,8 @@ PBEPARAM *PBEPARAM_new(void);
|
|||||||
PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length);
|
PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length);
|
||||||
void PBEPARAM_free(PBEPARAM *a);
|
void PBEPARAM_free(PBEPARAM *a);
|
||||||
X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
|
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,
|
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
|
||||||
int saltlen);
|
unsigned char *salt, int saltlen);
|
||||||
|
|
||||||
int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp);
|
int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp);
|
||||||
PBKDF2PARAM *PBKDF2PARAM_new(void);
|
PBKDF2PARAM *PBKDF2PARAM_new(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user