Commit 8eb57af5 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Complete support for PKCS#5 v2.0. Still needs extensive testing.

parent 1aad3392
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -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".


+25 −4
Original line number Original line Diff line number Diff line
@@ -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,7 +183,8 @@ 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,
					pass, strlen(pass),
					NULL, 0, iter, p8inf))) {
					NULL, 0, iter, p8inf))) {
				BIO_printf (bio_err, "Error encrypting key\n",
				BIO_printf (bio_err, "Error encrypting key\n",
								 outfile);
								 outfile);
@@ -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);
}
}
+3 −3
Original line number Original line Diff line number Diff line
@@ -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;
+1 −0
Original line number Original line Diff line number Diff line
@@ -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,
+9 −5
Original line number Original line Diff line number Diff line
@@ -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,7 +181,8 @@ 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,
			 const char *pass, int passlen,
			 unsigned char *salt, int saltlen, int iter,
			 unsigned char *salt, int saltlen, int iter,
						PKCS8_PRIV_KEY_INFO *p8inf)
						PKCS8_PRIV_KEY_INFO *p8inf)
{
{
@@ -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;
	}
	}
Loading