Add support for some broken PKCS#8 formats.
This commit is contained in:
parent
eb5a6a55c5
commit
66430207a4
4
CHANGES
4
CHANGES
@ -4,6 +4,10 @@
|
||||
|
||||
Changes between 0.9.4 and 0.9.5 [xx XXX 2000]
|
||||
|
||||
*) Add support for various broken PKCS#8 formats, and command line
|
||||
options to produce them.
|
||||
[Steve Henson]
|
||||
|
||||
*) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
|
||||
get temporary BIGNUMs from a BN_CTX.
|
||||
[Ulf Möller]
|
||||
|
19
apps/pkcs8.c
19
apps/pkcs8.c
@ -124,6 +124,8 @@ int MAIN(int argc, char **argv)
|
||||
else if (!strcmp (*args, "-noiter")) iter = 1;
|
||||
else if (!strcmp (*args, "-nocrypt")) nocrypt = 1;
|
||||
else if (!strcmp (*args, "-nooct")) p8_broken = PKCS8_NO_OCTET;
|
||||
else if (!strcmp (*args, "-nsdb")) p8_broken = PKCS8_NS_DB;
|
||||
else if (!strcmp (*args, "-embed")) p8_broken = PKCS8_EMBEDDED_PARAM;
|
||||
else if (!strcmp(*args,"-passin"))
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
@ -183,7 +185,9 @@ int MAIN(int argc, char **argv)
|
||||
BIO_printf(bio_err, "-passout arg input file pass phrase\n");
|
||||
BIO_printf(bio_err, "-envpassout arg environment variable containing input file pass phrase\n");
|
||||
BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
|
||||
BIO_printf(bio_err, "-nooct use (broken) no octet form\n");
|
||||
BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n");
|
||||
BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n");
|
||||
BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\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, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
|
||||
@ -224,12 +228,11 @@ int MAIN(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
BIO_free(in);
|
||||
if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
|
||||
if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) {
|
||||
BIO_printf(bio_err, "Error converting key\n", outfile);
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
PKCS8_set_broken(p8inf, p8_broken);
|
||||
if(nocrypt) {
|
||||
if(outformat == FORMAT_PEM)
|
||||
PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
|
||||
@ -316,7 +319,15 @@ int MAIN(int argc, char **argv)
|
||||
BIO_printf(bio_err, "Warning: broken key encoding: ");
|
||||
switch (p8inf->broken) {
|
||||
case PKCS8_NO_OCTET:
|
||||
BIO_printf(bio_err, "No Octet String\n");
|
||||
BIO_printf(bio_err, "No Octet String in PrivateKey\n");
|
||||
break;
|
||||
|
||||
case PKCS8_EMBEDDED_PARAM:
|
||||
BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
|
||||
break;
|
||||
|
||||
case PKCS8_NS_DB:
|
||||
BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -109,8 +109,6 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a,
|
||||
M_ASN1_D2I_get_IMP_set_opt_type(X509_ATTRIBUTE, ret->attributes,
|
||||
d2i_X509_ATTRIBUTE,
|
||||
X509_ATTRIBUTE_free, 0);
|
||||
if (ASN1_TYPE_get(ret->pkey) == V_ASN1_SEQUENCE)
|
||||
ret->broken = PKCS8_NO_OCTET;
|
||||
M_ASN1_D2I_Finish(a, PKCS8_PRIV_KEY_INFO_free, ASN1_F_D2I_PKCS8_PRIV_KEY_INFO);
|
||||
}
|
||||
|
||||
|
@ -62,19 +62,22 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
|
||||
|
||||
/* Extract a private key from a PKCS8 structure */
|
||||
|
||||
EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
#ifndef NO_RSA
|
||||
RSA *rsa;
|
||||
RSA *rsa = NULL;
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
DSA *dsa;
|
||||
ASN1_INTEGER *dsapriv;
|
||||
STACK *ndsa;
|
||||
BN_CTX *ctx;
|
||||
DSA *dsa = NULL;
|
||||
ASN1_INTEGER *privkey;
|
||||
ASN1_TYPE *t1, *t2, *param = NULL;
|
||||
STACK *ndsa = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
int plen;
|
||||
#endif
|
||||
X509_ALGOR *a;
|
||||
@ -82,21 +85,14 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
|
||||
int pkeylen;
|
||||
char obj_tmp[80];
|
||||
|
||||
switch (p8->broken) {
|
||||
case PKCS8_OK:
|
||||
if(p8->pkey->type == V_ASN1_OCTET_STRING) {
|
||||
p8->broken = PKCS8_OK;
|
||||
p = p8->pkey->value.octet_string->data;
|
||||
pkeylen = p8->pkey->value.octet_string->length;
|
||||
break;
|
||||
|
||||
case PKCS8_NO_OCTET:
|
||||
} else {
|
||||
p8->broken = PKCS8_NO_OCTET;
|
||||
p = p8->pkey->value.sequence->data;
|
||||
pkeylen = p8->pkey->value.sequence->length;
|
||||
break;
|
||||
|
||||
default:
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
if (!(pkey = EVP_PKEY_new())) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
||||
@ -121,65 +117,83 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
|
||||
* be recalculated.
|
||||
*/
|
||||
|
||||
/* Check for broken Netscape Database DSA PKCS#8, UGH! */
|
||||
/* Check for broken DSA PKCS#8, UGH! */
|
||||
if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
|
||||
if(!(ndsa = ASN1_seq_unpack(p, pkeylen,
|
||||
(char *(*)())d2i_ASN1_INTEGER,
|
||||
ASN1_STRING_free))) {
|
||||
(char *(*)())d2i_ASN1_TYPE,
|
||||
ASN1_TYPE_free))) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
if(sk_num(ndsa) != 2 ) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
sk_pop_free(ndsa, ASN1_STRING_free);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
dsapriv = (ASN1_INTEGER *) sk_pop(ndsa);
|
||||
sk_pop_free(ndsa, ASN1_STRING_free);
|
||||
} else if (!(dsapriv=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
|
||||
/* Handle Two broken types:
|
||||
* SEQUENCE {parameters, priv_key}
|
||||
* SEQUENCE {pub_key, priv_key}
|
||||
*/
|
||||
|
||||
t1 = (ASN1_TYPE *)sk_value(ndsa, 0);
|
||||
t2 = (ASN1_TYPE *)sk_value(ndsa, 1);
|
||||
if(t1->type == V_ASN1_SEQUENCE) {
|
||||
p8->broken = PKCS8_EMBEDDED_PARAM;
|
||||
param = t1;
|
||||
} else if(a->parameter->type == V_ASN1_SEQUENCE) {
|
||||
p8->broken = PKCS8_NS_DB;
|
||||
param = a->parameter;
|
||||
} else {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
|
||||
if(t2->type != V_ASN1_INTEGER) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
goto dsaerr;
|
||||
}
|
||||
privkey = t2->value.integer;
|
||||
} else if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
goto dsaerr;
|
||||
}
|
||||
/* Retrieve parameters */
|
||||
if (a->parameter->type != V_ASN1_SEQUENCE) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_NO_DSA_PARAMETERS);
|
||||
return NULL;
|
||||
}
|
||||
p = a->parameter->value.sequence->data;
|
||||
plen = a->parameter->value.sequence->length;
|
||||
p = param->value.sequence->data;
|
||||
plen = param->value.sequence->length;
|
||||
if (!(dsa = d2i_DSAparams (NULL, &p, plen))) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
/* We have parameters now set private key */
|
||||
if (!(dsa->priv_key = ASN1_INTEGER_to_BN(dsapriv, NULL))) {
|
||||
if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
|
||||
DSA_free (dsa);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
/* Calculate public key (ouch!) */
|
||||
if (!(dsa->pub_key = BN_new())) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
||||
DSA_free (dsa);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
if (!(ctx = BN_CTX_new())) {
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
||||
DSA_free (dsa);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
|
||||
if (!BN_mod_exp(dsa->pub_key, dsa->g,
|
||||
dsa->priv_key, dsa->p, ctx)) {
|
||||
|
||||
EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
|
||||
BN_CTX_free (ctx);
|
||||
DSA_free (dsa);
|
||||
return NULL;
|
||||
goto dsaerr;
|
||||
}
|
||||
|
||||
EVP_PKEY_assign_DSA (pkey, dsa);
|
||||
EVP_PKEY_assign_DSA(pkey, dsa);
|
||||
BN_CTX_free (ctx);
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
break;
|
||||
dsaerr:
|
||||
BN_CTX_free (ctx);
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
DSA_free(dsa);
|
||||
EVP_PKEY_free(pkey);
|
||||
return NULL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -193,30 +207,35 @@ EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
|
||||
return pkey;
|
||||
}
|
||||
|
||||
/* Turn a private key into a PKCS8 structure */
|
||||
|
||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
||||
{
|
||||
return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
|
||||
}
|
||||
|
||||
/* Turn a private key into a PKCS8 structure */
|
||||
|
||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
|
||||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8;
|
||||
#ifndef NO_DSA
|
||||
ASN1_INTEGER *dpkey;
|
||||
unsigned char *p, *q;
|
||||
int len;
|
||||
#endif
|
||||
|
||||
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
p8->broken = broken;
|
||||
ASN1_INTEGER_set (p8->version, 0);
|
||||
if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
p8->pkey->type = V_ASN1_OCTET_STRING;
|
||||
switch (EVP_PKEY_type(pkey->type)) {
|
||||
#ifndef NO_RSA
|
||||
case EVP_PKEY_RSA:
|
||||
|
||||
if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
|
||||
|
||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
|
||||
p8->pkeyalg->parameter->type = V_ASN1_NULL;
|
||||
if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey,
|
||||
@ -229,36 +248,11 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
case EVP_PKEY_DSA:
|
||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
|
||||
if(!dsa_pkey2pkcs8(p8, pkey)) {
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get parameters and place in AlgorithmIdentifier */
|
||||
len = i2d_DSAparams (pkey->pkey.dsa, NULL);
|
||||
if (!(p = Malloc(len))) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
q = p;
|
||||
i2d_DSAparams (pkey->pkey.dsa, &q);
|
||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
||||
p8->pkeyalg->parameter->value.sequence = ASN1_STRING_new();
|
||||
ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, len);
|
||||
Free(p);
|
||||
/* Get private key into an integer and pack */
|
||||
if (!(dpkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ASN1_pack_string((char *)dpkey, i2d_ASN1_INTEGER,
|
||||
&p8->pkey->value.octet_string)) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free (dpkey);
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
M_ASN1_INTEGER_free (dpkey);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -266,7 +260,6 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return NULL;
|
||||
}
|
||||
p8->pkey->type = V_ASN1_OCTET_STRING;
|
||||
RAND_add(p8->pkey->value.octet_string->data,
|
||||
p8->pkey->value.octet_string->length, 0);
|
||||
return p8;
|
||||
@ -295,4 +288,112 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_DSA
|
||||
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
|
||||
{
|
||||
ASN1_STRING *params;
|
||||
ASN1_INTEGER *prkey;
|
||||
ASN1_TYPE *ttmp;
|
||||
STACK *ndsa;
|
||||
unsigned char *p, *q;
|
||||
int len;
|
||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
|
||||
len = i2d_DSAparams (pkey->pkey.dsa, NULL);
|
||||
if (!(p = Malloc(len))) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
||||
return 0;
|
||||
}
|
||||
q = p;
|
||||
i2d_DSAparams (pkey->pkey.dsa, &q);
|
||||
params = ASN1_STRING_new();
|
||||
ASN1_STRING_set(params, p, len);
|
||||
Free(p);
|
||||
/* Get private key into integer */
|
||||
if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(p8->broken) {
|
||||
|
||||
case PKCS8_OK:
|
||||
case PKCS8_NO_OCTET:
|
||||
|
||||
if (!ASN1_pack_string((char *)prkey, i2d_ASN1_INTEGER,
|
||||
&p8->pkey->value.octet_string)) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
M_ASN1_INTEGER_free (prkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
M_ASN1_INTEGER_free (prkey);
|
||||
p8->pkeyalg->parameter->value.sequence = params;
|
||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
||||
|
||||
break;
|
||||
|
||||
case PKCS8_NS_DB:
|
||||
|
||||
p8->pkeyalg->parameter->value.sequence = params;
|
||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
||||
ndsa = sk_new_null();
|
||||
ttmp = ASN1_TYPE_new();
|
||||
if (!(ttmp->value.integer = BN_to_ASN1_INTEGER (pkey->pkey.dsa->pub_key, NULL))) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
return 0;
|
||||
}
|
||||
ttmp->type = V_ASN1_INTEGER;
|
||||
sk_push(ndsa, (char *)ttmp);
|
||||
|
||||
ttmp = ASN1_TYPE_new();
|
||||
ttmp->value.integer = prkey;
|
||||
ttmp->type = V_ASN1_INTEGER;
|
||||
sk_push(ndsa, (char *)ttmp);
|
||||
|
||||
p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
|
||||
|
||||
if (!ASN1_seq_pack(ndsa, i2d_ASN1_TYPE,
|
||||
&p8->pkey->value.octet_string->data,
|
||||
&p8->pkey->value.octet_string->length)) {
|
||||
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
M_ASN1_INTEGER_free(prkey);
|
||||
return 0;
|
||||
}
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
break;
|
||||
|
||||
case PKCS8_EMBEDDED_PARAM:
|
||||
|
||||
p8->pkeyalg->parameter->type = V_ASN1_NULL;
|
||||
ndsa = sk_new_null();
|
||||
ttmp = ASN1_TYPE_new();
|
||||
ttmp->value.sequence = params;
|
||||
ttmp->type = V_ASN1_SEQUENCE;
|
||||
sk_push(ndsa, (char *)ttmp);
|
||||
|
||||
ttmp = ASN1_TYPE_new();
|
||||
ttmp->value.integer = prkey;
|
||||
ttmp->type = V_ASN1_INTEGER;
|
||||
sk_push(ndsa, (char *)ttmp);
|
||||
|
||||
p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
|
||||
|
||||
if (!ASN1_seq_pack(ndsa, i2d_ASN1_TYPE,
|
||||
&p8->pkey->value.octet_string->data,
|
||||
&p8->pkey->value.octet_string->length)) {
|
||||
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
M_ASN1_INTEGER_free (prkey);
|
||||
return 0;
|
||||
}
|
||||
sk_pop_free(ndsa, ASN1_TYPE_free);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -433,8 +433,10 @@ X509_ALGOR *prf;
|
||||
typedef struct pkcs8_priv_key_info_st
|
||||
{
|
||||
int broken; /* Flag for various broken formats */
|
||||
#define PKCS8_OK 0
|
||||
#define PKCS8_NO_OCTET 1
|
||||
#define PKCS8_OK 0
|
||||
#define PKCS8_NO_OCTET 1
|
||||
#define PKCS8_EMBEDDED_PARAM 2
|
||||
#define PKCS8_NS_DB 3
|
||||
ASN1_INTEGER *version;
|
||||
X509_ALGOR *pkeyalg;
|
||||
ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
|
||||
@ -1105,6 +1107,7 @@ void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a);
|
||||
|
||||
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
|
||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
|
||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
|
||||
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
|
||||
|
||||
int X509_check_trust(X509 *x, int id, int flags);
|
||||
|
@ -19,6 +19,8 @@ B<openssl> B<pkcs8>
|
||||
[B<-noiter>]
|
||||
[B<-nocrypt>]
|
||||
[B<-nooct>]
|
||||
[B<-embed>]
|
||||
[B<-nsdb>]
|
||||
[B<-v2 alg>]
|
||||
[B<-v1 alg>]
|
||||
|
||||
@ -93,11 +95,24 @@ code signing software used unencrypted private keys.
|
||||
|
||||
=item B<-nooct>
|
||||
|
||||
This option generates private keys in a broken format that some software
|
||||
This option generates RSA private keys in a broken format that some software
|
||||
uses. Specifically the private key should be enclosed in a OCTET STRING
|
||||
but some software just includes the structure itself without the
|
||||
surrounding OCTET STRING.
|
||||
|
||||
=item B<-embed>
|
||||
|
||||
This option generates DSA keys in a broken format. The DSA parameters are
|
||||
embedded inside the PrivateKey structure. In this form the OCTET STRING
|
||||
contains an ASN1 SEQUENCE consisting of two structures: a SEQUENCE containing
|
||||
the parameters and an ASN1 INTEGER containing the private key.
|
||||
|
||||
=item B<-nsdb>
|
||||
|
||||
This option generates DSA keys in a broken format compatible with Netscape
|
||||
private key databases. The PrivateKey contains a SEQUENCE consisting of
|
||||
the public and private keys respectively.
|
||||
|
||||
=item B<-v2 alg>
|
||||
|
||||
This option enables the use of PKCS#5 v2.0 algorithms. Normally PKCS#8
|
||||
@ -202,11 +217,16 @@ Convert a private key from any PKCS#8 format to traditional format:
|
||||
|
||||
=head1 STANDARDS
|
||||
|
||||
Test vectors from this implementation were posted to the pkcs-tng mailing
|
||||
list using triple DES, DES and RC2 with high iteration counts, several
|
||||
people confirmed that they could decrypt the private keys produced and
|
||||
Therefore it can be assumed that the PKCS#5 v2.0 implementation is
|
||||
reasonably accurate at least as far as these algorithms are concerned.
|
||||
Test vectors from this PKCS#5 v2.0 implementation were posted to the
|
||||
pkcs-tng mailing list using triple DES, DES and RC2 with high iteration
|
||||
counts, several people confirmed that they could decrypt the private
|
||||
keys produced and Therefore it can be assumed that the PKCS#5 v2.0
|
||||
implementation is reasonably accurate at least as far as these
|
||||
algorithms are concerned.
|
||||
|
||||
The format of PKCS#8 DSA (and other) private keys is not well documented:
|
||||
it is hidden away in PKCS#11 v2.01, section 11.9. OpenSSL's DSA private
|
||||
key format complies with this standard.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
|
@ -2216,3 +2216,4 @@ BN_is_prime_fasttest 2240
|
||||
BN_CTX_end 2241
|
||||
BN_CTX_start 2242
|
||||
BN_CTX_get 2243
|
||||
EVP_PKEY2PKCS8_broken 2244
|
||||
|
Loading…
Reference in New Issue
Block a user