mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
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:
parent
d58d092bc9
commit
b7d135b353
6
CHANGES
6
CHANGES
@ -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]
|
||||
|
@ -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))) {
|
||||
|
@ -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 */
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"},
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user