diff --git a/apps/pkcs12.c b/apps/pkcs12.c index b4aabb2b86..5ed2122da6 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -660,7 +660,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, p8 = PKCS12_SAFEBAG_get0_p8inf(bag); if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) return 0; - print_attribs(out, p8->attributes, "Key Attributes"); + print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; @@ -682,7 +682,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, PKCS8_PRIV_KEY_INFO_free(p8); return 0; } - print_attribs(out, p8->attributes, "Key Attributes"); + print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); diff --git a/apps/pkcs8.c b/apps/pkcs8.c index 0968fef946..8a4d5423d1 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -67,7 +67,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, - OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, OPT_NOOCT, OPT_NSDB, OPT_EMBED, + OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, #ifndef OPENSSL_NO_SCRYPT OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P, #endif @@ -83,10 +83,6 @@ OPTIONS pkcs8_options[] = { {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, - {"nooct", OPT_NOOCT, '-', "Use (nonstandard) no octet format"}, - {"nsdb", OPT_NSDB, '-', "Use (nonstandard) DSA Netscape DB format"}, - {"embed", OPT_EMBED, '-', - "Use (nonstandard) embedded DSA parameters format"}, {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, {"v2prf", OPT_V2PRF, 's'}, @@ -117,7 +113,7 @@ int pkcs8_main(int argc, char **argv) char *passinarg = NULL, *passoutarg = NULL, *prog; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; OPTION_CHOICE o; - int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER, p8_broken = PKCS8_OK; + int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER; int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; int private = 0; #ifndef OPENSSL_NO_SCRYPT @@ -159,15 +155,6 @@ int pkcs8_main(int argc, char **argv) case OPT_NOCRYPT: nocrypt = 1; break; - case OPT_NOOCT: - p8_broken = PKCS8_NO_OCTET; - break; - case OPT_NSDB: - p8_broken = PKCS8_NS_DB; - break; - case OPT_EMBED: - p8_broken = PKCS8_EMBEDDED_PARAM; - break; case OPT_V2: if (!opt_cipher(opt_arg(), &cipher)) goto opthelp; @@ -249,7 +236,7 @@ int pkcs8_main(int argc, char **argv) pkey = load_key(infile, informat, 1, passin, e, "key"); if (!pkey) goto end; - if ((p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)) == NULL) { + if ((p8inf = EVP_PKEY2PKCS8(pkey)) == NULL) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; @@ -362,31 +349,6 @@ int pkcs8_main(int argc, char **argv) goto end; } - if (p8inf->broken) { - BIO_printf(bio_err, "Warning: broken key encoding: "); - switch (p8inf->broken) { - case PKCS8_NO_OCTET: - 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; - - case PKCS8_NEG_PRIVKEY: - BIO_printf(bio_err, "DSA private key value is negative\n"); - break; - - default: - BIO_printf(bio_err, "Unknown broken type\n"); - break; - } - } - assert(private); if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); diff --git a/crypto/asn1/p8_pkey.c b/crypto/asn1/p8_pkey.c index 59f1cd167a..1e062a9ee9 100644 --- a/crypto/asn1/p8_pkey.c +++ b/crypto/asn1/p8_pkey.c @@ -60,6 +60,7 @@ #include "internal/cryptlib.h" #include #include +#include "internal/x509_int.h" /* Minor tweak to operation: zero private key data */ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -68,10 +69,8 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ if (operation == ASN1_OP_FREE_PRE) { PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; - if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING - && key->pkey->value.octet_string != NULL) - OPENSSL_cleanse(key->pkey->value.octet_string->data, - key->pkey->value.octet_string->length); + if (key->pkey) + OPENSSL_cleanse(key->pkey->data, key->pkey->length); } return 1; } @@ -79,7 +78,7 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING), ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) @@ -89,32 +88,14 @@ int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, int ptype, void *pval, unsigned char *penc, int penclen) { - unsigned char **ppenc = NULL; if (version >= 0) { if (!ASN1_INTEGER_set(priv->version, version)) return 0; } - if (penc) { - int pmtype; - ASN1_OCTET_STRING *oct; - oct = ASN1_OCTET_STRING_new(); - if (oct == NULL) - return 0; - oct->data = penc; - ppenc = &oct->data; - oct->length = penclen; - if (priv->broken == PKCS8_NO_OCTET) - pmtype = V_ASN1_SEQUENCE; - else - pmtype = V_ASN1_OCTET_STRING; - ASN1_TYPE_set(priv->pkey, pmtype, oct); - } - if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { - /* If call fails do not swallow 'enc' */ - if (ppenc) - *ppenc = NULL; + if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) return 0; - } + if (penc) + ASN1_STRING_set0(priv->pkey, penc, penclen); return 1; } @@ -124,21 +105,24 @@ int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, { if (ppkalg) *ppkalg = p8->pkeyalg->algorithm; - if (p8->pkey->type == V_ASN1_OCTET_STRING) { - p8->broken = PKCS8_OK; - if (pk) { - *pk = p8->pkey->value.octet_string->data; - *ppklen = p8->pkey->value.octet_string->length; - } - } else if (p8->pkey->type == V_ASN1_SEQUENCE) { - p8->broken = PKCS8_NO_OCTET; - if (pk) { - *pk = p8->pkey->value.sequence->data; - *ppklen = p8->pkey->value.sequence->length; - } - } else - return 0; + if (pk) { + *pk = ASN1_STRING_data(p8->pkey); + *ppklen = ASN1_STRING_length(p8->pkey); + } if (pa) *pa = p8->pkeyalg; return 1; } + +STACK_OF(X509_ATTRIBUTE) *PKCS8_pkey_get0_attrs(PKCS8_PRIV_KEY_INFO *p8) +{ + return p8->attributes; +} + +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&p8->attributes, nid, type, bytes, len) != NULL) + return 1; + return 0; +} diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index add74cadd3..3b77e3b864 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -102,8 +102,7 @@ static ERR_STRING_DATA EVP_str_functs[] = { {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, {ERR_FUNC(EVP_F_EVP_PBE_SCRYPT), "EVP_PBE_scrypt"}, {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, - {ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"}, - {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, + {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8), "EVP_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c index 530f724033..a44d972925 100644 --- a/crypto/evp/evp_pkey.c +++ b/crypto/evp/evp_pkey.c @@ -63,6 +63,7 @@ #include #include "internal/asn1_int.h" #include "internal/evp_int.h" +#include "internal/x509_int.h" /* Extract a private key from a PKCS8 structure */ @@ -104,66 +105,37 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) return NULL; } -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 *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { - PKCS8_PRIV_KEY_INFO *p8; - - if ((p8 = PKCS8_PRIV_KEY_INFO_new()) == NULL) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); + PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new(); + if (p8 == NULL) { + EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return NULL; } - p8->broken = broken; if (pkey->ameth) { if (pkey->ameth->priv_encode) { if (!pkey->ameth->priv_encode(p8, pkey)) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, - EVP_R_PRIVATE_KEY_ENCODE_ERROR); + EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR); goto error; } } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); + EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED); goto error; } } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, - EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); goto error; } - RAND_add(p8->pkey->value.octet_string->data, - p8->pkey->value.octet_string->length, 0.0); + RAND_add(p8->pkey->data, p8->pkey->length, 0.0); return p8; error: PKCS8_PRIV_KEY_INFO_free(p8); return NULL; } -PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) -{ - switch (broken) { - - case PKCS8_OK: - p8->broken = PKCS8_OK; - return p8; - - case PKCS8_NO_OCTET: - p8->broken = PKCS8_NO_OCTET; - p8->pkey->type = V_ASN1_SEQUENCE; - return p8; - - default: - EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); - return NULL; - } -} - /* EVP_PKEY attribute functions */ int EVP_PKEY_get_attr_count(const EVP_PKEY *key) diff --git a/crypto/include/internal/x509_int.h b/crypto/include/internal/x509_int.h index fa51d351d7..e6e7ed141a 100644 --- a/crypto/include/internal/x509_int.h +++ b/crypto/include/internal/x509_int.h @@ -213,3 +213,12 @@ struct x509_st { unsigned char sha1_hash[SHA_DIGEST_LENGTH]; X509_CERT_AUX *aux; } /* X509 */ ; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st { + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_OCTET_STRING *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c index fba35cd63b..994f3868d0 100644 --- a/crypto/pkcs12/p12_attr.c +++ b/crypto/pkcs12/p12_attr.c @@ -77,13 +77,9 @@ int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) { - unsigned char us_val; - us_val = (unsigned char)usage; - if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage, - V_ASN1_BIT_STRING, &us_val, 1)) - return 1; - else - return 0; + unsigned char us_val = (unsigned char)usage; + return PKCS8_pkey_add1_attr_by_NID(p8, NID_key_usage, + V_ASN1_BIT_STRING, &us_val, 1); } /* Add a friendlyname to a safebag */ diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c index 57e2bf43df..ffdf22ded2 100644 --- a/crypto/pkcs12/p12_sbag.c +++ b/crypto/pkcs12/p12_sbag.c @@ -69,7 +69,7 @@ ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(PKCS12_SAFEBAG *bag, int attr_nid) ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid) { - return PKCS12_get_attr_gen(p8->attributes, attr_nid); + return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid); } PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(PKCS12_SAFEBAG *bag) diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 1b26bb1f9b..aef43f411b 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1508,8 +1508,7 @@ void ERR_load_EVP_strings(void); # define EVP_F_EVP_PBE_CIPHERINIT 116 # define EVP_F_EVP_PBE_SCRYPT 181 # define EVP_F_EVP_PKCS82PKEY 111 -# define EVP_F_EVP_PKCS82PKEY_BROKEN 136 -# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +# define EVP_F_EVP_PKEY2PKCS8 113 # define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 # define EVP_F_EVP_PKEY_CTX_CTRL 137 # define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 06fc99ef30..c5f4ecc5b5 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -376,23 +376,6 @@ typedef struct PBKDF2PARAM_st { X509_ALGOR *prf; } PBKDF2PARAM; -/* PKCS#8 private key info structure */ - -struct pkcs8_priv_key_info_st { - /* Flag for various broken formats */ - int broken; -# define PKCS8_OK 0 -# define PKCS8_NO_OCTET 1 -# define PKCS8_EMBEDDED_PARAM 2 -# define PKCS8_NS_DB 3 -# define PKCS8_NEG_PRIVKEY 4 - ASN1_INTEGER *version; - X509_ALGOR *pkeyalg; - /* Should be OCTET STRING but some are broken */ - ASN1_TYPE *pkey; - STACK_OF(X509_ATTRIBUTE) *attributes; -}; - #ifdef __cplusplus } #endif @@ -1040,8 +1023,6 @@ DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) 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 PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, int ptype, void *pval, @@ -1050,6 +1031,10 @@ int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); +STACK_OF(X509_ATTRIBUTE) *PKCS8_pkey_get0_attrs(PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); + int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype, void *pval, unsigned char *penc, int penclen);