Add function PKCS8_set0_pbe
This adds a new function which will encrypt a private key using PKCS#8 based on an X509_ALGOR structure and reimplements PKCS8_encrypt to use it. Update pkcs8 utlity to use PKCS8_set0_pbe. Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
parent
fef034f85e
commit
6355d31538
4 changed files with 54 additions and 25 deletions
20
apps/pkcs8.c
20
apps/pkcs8.c
|
@ -226,18 +226,30 @@ int pkcs8_main(int argc, char **argv)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
X509_ALGOR *pbe;
|
||||||
|
if (cipher)
|
||||||
|
pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, pbe_nid);
|
||||||
|
else
|
||||||
|
pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
|
||||||
|
if (pbe == NULL) {
|
||||||
|
BIO_printf(bio_err, "Error setting PBE algorithm\n");
|
||||||
|
ERR_print_errors(bio_err);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
if (passout)
|
if (passout)
|
||||||
p8pass = passout;
|
p8pass = passout;
|
||||||
else {
|
else {
|
||||||
p8pass = pass;
|
p8pass = pass;
|
||||||
if (EVP_read_pw_string
|
if (EVP_read_pw_string
|
||||||
(pass, sizeof pass, "Enter Encryption Password:", 1))
|
(pass, sizeof pass, "Enter Encryption Password:", 1)) {
|
||||||
|
X509_ALGOR_free(pbe);
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
app_RAND_load_file(NULL, 0);
|
app_RAND_load_file(NULL, 0);
|
||||||
if ((p8 = PKCS8_encrypt(pbe_nid, cipher,
|
p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
|
||||||
p8pass, strlen(p8pass),
|
if (p8 == NULL) {
|
||||||
NULL, 0, iter, p8inf)) == NULL) {
|
X509_ALGOR_free(pbe);
|
||||||
BIO_printf(bio_err, "Error encrypting key\n");
|
BIO_printf(bio_err, "Error encrypting key\n");
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -66,14 +66,9 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
|
||||||
unsigned char *salt, int saltlen, int iter,
|
unsigned char *salt, int saltlen, int iter,
|
||||||
PKCS8_PRIV_KEY_INFO *p8inf)
|
PKCS8_PRIV_KEY_INFO *p8inf)
|
||||||
{
|
{
|
||||||
X509_SIG *p8;
|
X509_SIG *p8 = NULL;
|
||||||
X509_ALGOR *pbe;
|
X509_ALGOR *pbe;
|
||||||
|
|
||||||
if ((p8 = X509_SIG_new()) == NULL) {
|
|
||||||
PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pbe_nid == -1)
|
if (pbe_nid == -1)
|
||||||
pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
|
pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
|
||||||
else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
|
else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
|
||||||
|
@ -84,22 +79,40 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
|
||||||
}
|
}
|
||||||
if (!pbe) {
|
if (!pbe) {
|
||||||
PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
|
PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
|
||||||
goto err;
|
return NULL;
|
||||||
}
|
}
|
||||||
X509_ALGOR_free(p8->algor);
|
p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
|
||||||
p8->algor = pbe;
|
if (p8 == NULL) {
|
||||||
ASN1_OCTET_STRING_free(p8->digest);
|
X509_ALGOR_free(pbe);
|
||||||
p8->digest =
|
return NULL;
|
||||||
PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
|
|
||||||
pass, passlen, p8inf, 1);
|
|
||||||
if (!p8->digest) {
|
|
||||||
PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p8;
|
return p8;
|
||||||
|
}
|
||||||
err:
|
|
||||||
X509_SIG_free(p8);
|
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
|
||||||
return NULL;
|
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
|
||||||
|
{
|
||||||
|
X509_SIG *p8;
|
||||||
|
ASN1_OCTET_STRING *enckey;
|
||||||
|
|
||||||
|
enckey =
|
||||||
|
PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
|
||||||
|
pass, passlen, p8inf, 1);
|
||||||
|
if (!enckey) {
|
||||||
|
PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(p8 = X509_SIG_new())) {
|
||||||
|
PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
|
||||||
|
ASN1_OCTET_STRING_free(enckey);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
X509_ALGOR_free(p8->algor);
|
||||||
|
ASN1_OCTET_STRING_free(p8->digest);
|
||||||
|
p8->algor = pbe;
|
||||||
|
p8->digest = enckey;
|
||||||
|
|
||||||
|
return p8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* crypto/pkcs12/pk12err.c */
|
/* crypto/pkcs12/pk12err.c */
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
|
* Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -101,6 +101,7 @@ static ERR_STRING_DATA PKCS12_str_functs[] = {
|
||||||
{ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
|
{ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
|
||||||
{ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"},
|
{ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"},
|
||||||
{ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
|
{ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
|
||||||
|
{ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,8 @@ PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
|
||||||
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
|
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
|
||||||
const char *pass, int passlen, unsigned char *salt,
|
const char *pass, int passlen, unsigned char *salt,
|
||||||
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
|
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
|
||||||
|
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
|
||||||
|
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
|
||||||
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
|
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
|
||||||
int passlen, unsigned char *salt,
|
int passlen, unsigned char *salt,
|
||||||
int saltlen, int iter,
|
int saltlen, int iter,
|
||||||
|
@ -309,6 +311,7 @@ void ERR_load_PKCS12_strings(void);
|
||||||
# define PKCS12_F_PKCS12_VERIFY_MAC 126
|
# define PKCS12_F_PKCS12_VERIFY_MAC 126
|
||||||
# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124
|
# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124
|
||||||
# define PKCS12_F_PKCS8_ENCRYPT 125
|
# define PKCS12_F_PKCS8_ENCRYPT 125
|
||||||
|
# define PKCS12_F_PKCS8_SET0_PBE 132
|
||||||
|
|
||||||
/* Reason codes. */
|
/* Reason codes. */
|
||||||
# define PKCS12_R_CANT_PACK_STRUCTURE 100
|
# define PKCS12_R_CANT_PACK_STRUCTURE 100
|
||||||
|
|
Loading…
Reference in a new issue