From 6355d31538fb3d50ba34210e6514cfac1c627243 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 21 May 2015 00:37:39 +0100 Subject: [PATCH] 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 --- apps/pkcs8.c | 20 ++++++++++++---- crypto/pkcs12/p12_p8e.c | 49 +++++++++++++++++++++++++--------------- crypto/pkcs12/pk12err.c | 3 ++- include/openssl/pkcs12.h | 3 +++ 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/apps/pkcs8.c b/apps/pkcs8.c index 55c4eea0aa..36e8333c1a 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -226,18 +226,30 @@ int pkcs8_main(int argc, char **argv) goto end; } } 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) p8pass = passout; else { p8pass = pass; 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; + } } app_RAND_load_file(NULL, 0); - if ((p8 = PKCS8_encrypt(pbe_nid, cipher, - p8pass, strlen(p8pass), - NULL, 0, iter, p8inf)) == NULL) { + p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe); + if (p8 == NULL) { + X509_ALGOR_free(pbe); BIO_printf(bio_err, "Error encrypting key\n"); ERR_print_errors(bio_err); goto end; diff --git a/crypto/pkcs12/p12_p8e.c b/crypto/pkcs12/p12_p8e.c index 46ed78a12f..552f2f0d61 100644 --- a/crypto/pkcs12/p12_p8e.c +++ b/crypto/pkcs12/p12_p8e.c @@ -66,14 +66,9 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8inf) { - X509_SIG *p8; + X509_SIG *p8 = NULL; X509_ALGOR *pbe; - if ((p8 = X509_SIG_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); 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) { PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); - goto err; + return NULL; } - X509_ALGOR_free(p8->algor); - p8->algor = pbe; - ASN1_OCTET_STRING_free(p8->digest); - p8->digest = + p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe); + if (p8 == NULL) { + X509_ALGOR_free(pbe); + return NULL; + } + + return p8; +} + +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + 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 (!p8->digest) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); - goto err; + if (!enckey) { + PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR); + return NULL; } - return p8; + 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; - err: - X509_SIG_free(p8); - return NULL; + return p8; } diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index e58710b253..4e6c7dd57b 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* 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 * 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_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"}, {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"}, + {ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"}, {0, NULL} }; diff --git a/include/openssl/pkcs12.h b/include/openssl/pkcs12.h index e58e55c58a..ba8b9441a9 100644 --- a/include/openssl/pkcs12.h +++ b/include/openssl/pkcs12.h @@ -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, const char *pass, int passlen, unsigned char *salt, 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, int passlen, unsigned char *salt, int saltlen, int iter, @@ -309,6 +311,7 @@ void ERR_load_PKCS12_strings(void); # define PKCS12_F_PKCS12_VERIFY_MAC 126 # define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 # define PKCS12_F_PKCS8_ENCRYPT 125 +# define PKCS12_F_PKCS8_SET0_PBE 132 /* Reason codes. */ # define PKCS12_R_CANT_PACK_STRUCTURE 100 -- 2.40.0