summaryrefslogtreecommitdiffstats
path: root/crypto/store
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2017-02-11 01:18:29 +0100
committerRichard Levitte <levitte@openssl.org>2017-06-29 11:55:32 +0200
commit7ad2ef366c3e96747dabee232a10b33d8fd2262a (patch)
tree23951db778a3e5fbcafb5e5e8362715ef357b9bc /crypto/store
parent1aabc2445b126f951707b287db9a9145b003f2ca (diff)
STORE 'file' scheme loader: Add handler for encrypted PKCS#8 data
Add a separate handler for encrypted PKCS#8 data. This uses the new restart functionality. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3542)
Diffstat (limited to 'crypto/store')
-rw-r--r--crypto/store/loader_file.c82
-rw-r--r--crypto/store/store_err.c4
2 files changed, 82 insertions, 4 deletions
diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c
index 472e8197f8..0ec264bf16 100644
--- a/crypto/store/loader_file.c
+++ b/crypto/store/loader_file.c
@@ -272,6 +272,69 @@ static FILE_HANDLER PKCS12_handler = {
1 /* repeatable */
};
+static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
+ const char *pem_header,
+ const unsigned char *blob,
+ size_t len, void **pctx,
+ const UI_METHOD *ui_method,
+ void *ui_data)
+{
+ X509_SIG *p8 = NULL;
+ char kbuf[PEM_BUFSIZE];
+ char *pass = NULL;
+ const X509_ALGOR *dalg = NULL;
+ const ASN1_OCTET_STRING *doct = NULL;
+ OSSL_STORE_INFO *store_info = NULL;
+ BUF_MEM *mem = NULL;
+ unsigned char *new_data = NULL;
+ int new_data_len;
+
+ if (pem_name != NULL && strcmp(pem_name, PEM_STRING_PKCS8) != 0)
+ return NULL;
+
+ if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL)
+ return NULL;
+
+ if ((mem = BUF_MEM_new()) == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
+ ERR_R_MALLOC_FAILURE);
+ goto nop8;
+ }
+
+ if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE,
+ "PKCS8 decrypt password", ui_data)) == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
+ OSSL_STORE_R_BAD_PASSWORD_READ);
+ goto nop8;
+ }
+
+ X509_SIG_get0(p8, &dalg, &doct);
+ if (!PKCS12_pbe_crypt(dalg, pass, strlen(pass), doct->data, doct->length,
+ &new_data, &new_data_len, 0))
+ goto nop8;
+
+ mem->data = (char *)new_data;
+ mem->max = mem->length = (size_t)new_data_len;
+ X509_SIG_free(p8);
+
+ store_info = ossl_store_info_new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
+ if (store_info == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
+ ERR_R_MALLOC_FAILURE);
+ goto nop8;
+ }
+
+ return store_info;
+ nop8:
+ X509_SIG_free(p8);
+ BUF_MEM_free(mem);
+ return NULL;
+}
+static FILE_HANDLER PKCS8Encrypted_handler = {
+ "PKCS8Encrypted",
+ try_decode_PKCS8Encrypted
+};
+
int pem_check_suffix(const char *pem_str, const char *suffix);
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
const char *pem_header,
@@ -285,11 +348,21 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
if (pem_name != NULL) {
- int slen;
+ if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) {
+ PKCS8_PRIV_KEY_INFO *p8inf =
+ d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);
- if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
- && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL)
- pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
+ if (p8inf != NULL)
+ pkey = EVP_PKCS82PKEY(p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ } else {
+ int slen;
+
+ if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
+ && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
+ slen)) != NULL)
+ pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
+ }
} else {
int i;
@@ -468,6 +541,7 @@ static FILE_HANDLER X509CRL_handler = {
static const FILE_HANDLER *file_handlers[] = {
&PKCS12_handler,
+ &PKCS8Encrypted_handler,
&X509Certificate_handler,
&X509CRL_handler,
&params_handler,
diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c
index 57627ebdec..9117576bd8 100644
--- a/crypto/store/store_err.c
+++ b/crypto/store/store_err.c
@@ -63,12 +63,16 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
"try_decode_params"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS12, 0),
"try_decode_PKCS12"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, 0),
+ "try_decode_PKCS8Encrypted"},
{0, NULL}
};
static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = {
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE),
"ambiguous content type"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_BAD_PASSWORD_READ),
+ "bad password read"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC),
"error verifying pkcs12 mac"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_INVALID_SCHEME),