Two new functions to write out PKCS#8 private keys. Also fixes for some of

the the PBE code and a new constant PKCS5_DEFAULT_ITER for the default
iteration count if it is passed as zero.
This commit is contained in:
Dr. Stephen Henson 1999-06-10 17:32:52 +00:00
parent d58d092bc9
commit b7d135b353
12 changed files with 85 additions and 5 deletions

View File

@ -4,6 +4,12 @@
Changes between 0.9.3a and 0.9.4
*) Add a new pair of functions PEM_write_PKCS8PrivateKey() and
PEM_write_bio_PKCS8PrivateKey() that are equivalent to
PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
secure PKCS#8 private key format with a high iteration count.
[Steve Henson]
*) Fix determination of Perl interpreter: A perl or perl5
_directory_ in $PATH was also accepted as the interpreter.
[Ralf S. Engelschall]

View File

@ -119,6 +119,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt,
ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE);
return NULL;
}
if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
ASN1_INTEGER_set (pbe->iter, iter);
if (!saltlen) saltlen = PKCS5_SALT_LEN;
if (!(pbe->salt->data = Malloc (saltlen))) {

View File

@ -206,6 +206,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
if (salt) memcpy (osalt->data, salt, saltlen);
else RAND_bytes (osalt->data, saltlen);
if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;
/* Now include salt in kdf structure */

View File

@ -110,6 +110,8 @@ extern "C" {
#define EVP_MAX_IV_LENGTH 8
#define PKCS5_SALT_LEN 8
/* Default PKCS#5 iteration count */
#define PKCS5_DEFAULT_ITER 2048
#ifndef NO_RSA
#include <openssl/rsa.h>

View File

@ -100,7 +100,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
/* Extract useful info from parameter */
pbuf = param->value.sequence->data;
if (!param || (param->type = V_ASN1_SEQUENCE) ||
if (!param || (param->type != V_ASN1_SEQUENCE) ||
!(pbe = d2i_PBEPARAM (NULL, &pbuf, param->value.sequence->length))) {
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
return 0;

View File

@ -67,6 +67,8 @@ extern "C" {
#include <openssl/x509.h>
#include <openssl/pem2.h>
#define PEM_BUFSIZE 1024
#define PEM_OBJ_UNDEF 0
#define PEM_OBJ_X509 1
#define PEM_OBJ_X509_REQ 2
@ -499,6 +501,8 @@ int PEM_write_DSAPrivateKey(FILE *fp,DSA *x,const EVP_CIPHER *enc,
#endif
int PEM_write_PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
unsigned char *kstr,int klen, pem_password_cb *);
int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
unsigned char *kstr,int klen, pem_password_cb *);
int PEM_write_PKCS7(FILE *fp,PKCS7 *x);
#ifndef NO_DH
int PEM_write_DHparams(FILE *fp,DH *x);
@ -548,6 +552,8 @@ int PEM_write_bio_DSAPrivateKey(BIO *fp,DSA *x,const EVP_CIPHER *enc,
#endif
int PEM_write_bio_PrivateKey(BIO *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
unsigned char *kstr,int klen, pem_password_cb *);
int PEM_write_bio_PKCS8PrivateKey(BIO *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
unsigned char *kstr,int klen, pem_password_cb *);
int PEM_write_bio_PKCS7(BIO *bp,PKCS7 *x);
#ifndef NO_DH
int PEM_write_bio_DHparams(BIO *bp,DH *x);
@ -578,6 +584,7 @@ int PEM_write_bio_PKCS8_PRIV_KEY_INFO(BIO *bp,PKCS8_PRIV_KEY_INFO *x);
#define PEM_F_PEM_ASN1_WRITE 104
#define PEM_F_PEM_ASN1_WRITE_BIO 105
#define PEM_F_PEM_DO_HEADER 106
#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118
#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107
#define PEM_F_PEM_READ 108
#define PEM_F_PEM_READ_BIO 109
@ -586,6 +593,7 @@ int PEM_write_bio_PKCS8_PRIV_KEY_INFO(BIO *bp,PKCS8_PRIV_KEY_INFO *x);
#define PEM_F_PEM_SIGNFINAL 112
#define PEM_F_PEM_WRITE 113
#define PEM_F_PEM_WRITE_BIO 114
#define PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY 119
#define PEM_F_PEM_X509_INFO_READ 115
#define PEM_F_PEM_X509_INFO_READ_BIO 116
#define PEM_F_PEM_X509_INFO_WRITE_BIO 117
@ -596,6 +604,7 @@ int PEM_write_bio_PKCS8_PRIV_KEY_INFO(BIO *bp,PKCS8_PRIV_KEY_INFO *x);
#define PEM_R_BAD_END_LINE 102
#define PEM_R_BAD_IV_CHARS 103
#define PEM_R_BAD_PASSWORD_READ 104
#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115
#define PEM_R_NOT_DEK_INFO 105
#define PEM_R_NOT_ENCRYPTED 106
#define PEM_R_NOT_PROC_TYPE 107

View File

@ -72,6 +72,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_PACK(0,PEM_F_PEM_ASN1_WRITE,0), "PEM_ASN1_write"},
{ERR_PACK(0,PEM_F_PEM_ASN1_WRITE_BIO,0), "PEM_ASN1_write_bio"},
{ERR_PACK(0,PEM_F_PEM_DO_HEADER,0), "PEM_do_header"},
{ERR_PACK(0,PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY,0), "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
{ERR_PACK(0,PEM_F_PEM_GET_EVP_CIPHER_INFO,0), "PEM_get_EVP_CIPHER_INFO"},
{ERR_PACK(0,PEM_F_PEM_READ,0), "PEM_read"},
{ERR_PACK(0,PEM_F_PEM_READ_BIO,0), "PEM_read_bio"},
@ -80,6 +81,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_PACK(0,PEM_F_PEM_SIGNFINAL,0), "PEM_SignFinal"},
{ERR_PACK(0,PEM_F_PEM_WRITE,0), "PEM_write"},
{ERR_PACK(0,PEM_F_PEM_WRITE_BIO,0), "PEM_write_bio"},
{ERR_PACK(0,PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY,0), "PEM_write_bio_PKCS8PrivateKey"},
{ERR_PACK(0,PEM_F_PEM_X509_INFO_READ,0), "PEM_X509_INFO_read"},
{ERR_PACK(0,PEM_F_PEM_X509_INFO_READ_BIO,0), "PEM_X509_INFO_read_bio"},
{ERR_PACK(0,PEM_F_PEM_X509_INFO_WRITE_BIO,0), "PEM_X509_INFO_write_bio"},
@ -93,6 +95,7 @@ static ERR_STRING_DATA PEM_str_reasons[]=
{PEM_R_BAD_END_LINE ,"bad end line"},
{PEM_R_BAD_IV_CHARS ,"bad iv chars"},
{PEM_R_BAD_PASSWORD_READ ,"bad password read"},
{PEM_R_ERROR_CONVERTING_PRIVATE_KEY ,"error converting private key"},
{PEM_R_NOT_DEK_INFO ,"not dek info"},
{PEM_R_NOT_ENCRYPTED ,"not encrypted"},
{PEM_R_NOT_PROC_TYPE ,"not proc type"},

View File

@ -272,7 +272,6 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
int i,ret=0;
unsigned char *data=NULL;
const char *objstr=NULL;
#define PEM_BUFSIZE 1024
char buf[PEM_BUFSIZE];
unsigned char *iv=NULL;

View File

@ -72,7 +72,6 @@
const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
#define MIN_LENGTH 4
#define PEM_BUFSIZE 1024
static int def_callback(char *buf, int num, int w);
static int load_iv(unsigned char **fromp,unsigned char *to, int num);
@ -742,3 +741,61 @@ err:
BUF_MEM_free(dataB);
return(0);
}
/* This function writes a private key in PKCS#8 format: it is a "drop in"
* replacement for PEM_write_bio_PrivateKey(). As usual if 'enc' is NULL then
* it uses the unencrypted private key form. It uses PKCS#5 v2.0 password based
* encryption algorithms.
*/
int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen, pem_password_cb *cb)
{
X509_SIG *p8;
PKCS8_PRIV_KEY_INFO *p8inf;
char buf[PEM_BUFSIZE];
int ret;
if(!(p8inf = EVP_PKEY2PKCS8(x))) {
PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY,
PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
return 0;
}
if(enc) {
if(!kstr) {
if(!cb) klen = def_callback(buf, PEM_BUFSIZE, 1);
else klen = cb(buf, PEM_BUFSIZE, 1);
if(klen <= 0) {
PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY,
PEM_R_READ_KEY);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return 0;
}
kstr = buf;
}
p8 = PKCS8_encrypt(-1, enc, kstr, klen, NULL, 0, 0, p8inf);
if(kstr == (unsigned char *)buf) memset(buf, 0, klen);
PKCS8_PRIV_KEY_INFO_free(p8inf);
ret = PEM_write_bio_PKCS8(bp, p8);
X509_SIG_free(p8);
return ret;
} else {
ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
}
int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen, pem_password_cb *cb)
{
BIO *bp;
int ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
PEMerr(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY,ERR_R_BUF_LIB);
return(0);
}
ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, kstr, klen, cb);
BIO_free(bp);
return ret;
}

View File

@ -92,7 +92,7 @@ int PKCS12_PBE_keyivgen (EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
/* Extract useful info from parameter */
pbuf = param->value.sequence->data;
if (!param || (param->type = V_ASN1_SEQUENCE) ||
if (!param || (param->type != V_ASN1_SEQUENCE) ||
!(pbe = d2i_PBEPARAM (NULL, &pbuf, param->value.sequence->length))) {
EVPerr(PKCS12_F_PKCS12_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
return 0;

View File

@ -72,7 +72,7 @@ extern "C" {
/* Default iteration count */
#ifndef PKCS12_DEFAULT_ITER
#define PKCS12_DEFAULT_ITER 2048
#define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER
#endif
#define PKCS12_MAC_KEY_LENGTH 20

View File

@ -1769,3 +1769,5 @@ BIO_s_bio 1793
PKCS5_pbe2_set 1794
PKCS5_PBKDF2_HMAC_SHA1 1795
PKCS5_v2_PBE_keyivgen 1796
PEM_write_bio_PKCS8PrivateKey 1797
PEM_write_PKCS8PrivateKey 1798