From 9ac80d80c8e2a38f9478acce3696029fce462a01 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Aug 06 2021 14:02:55 +0000 Subject: If an existing cert exists, use it to decrypt the PKCS#7 envelope From the PKCS7_decrypt man page: Although the recipients certificate is not needed to decrypt the data it is needed to locate the appropriate (of possible several) recipients in the PKCS#7 structure. Based heavily on patch contributed by Romain Bezut https://pagure.io/certmonger/issue/202 Signed-off-by: Rob Crittenden --- diff --git a/src/submit-n.c b/src/submit-n.c index 7751ed6..3dcb820 100644 --- a/src/submit-n.c +++ b/src/submit-n.c @@ -82,7 +82,7 @@ cm_submit_n_tag_from_nid(int nid) static SECItem * try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, - SECKEYPrivateKey *privkey) + SECKEYPrivateKey *privkey, X509 *old_cert) { SECOidTag tag; SECItem *ret = NULL, param, *parameters; @@ -291,6 +291,7 @@ cm_submit_n_decrypt_envelope(const unsigned char *envelope, struct cm_pin_cb_data cb_data; int n_tokens, ec; struct cm_submit_decrypt_envelope_args *args = decrypt_userdata; + X509 *old_cert = NULL; util_o_init(); ERR_load_crypto_strings(); @@ -430,6 +431,23 @@ next_slot: break; } } + if (args->entry->cm_cert != NULL) { + BIO *bio = NULL; + cm_log(3, "Parsing existing certificate\n"); + bio = BIO_new_mem_buf(args->entry->cm_cert, -1); + if (bio == NULL) { + cm_log(1, "Out of memory.\n"); + goto done; + } else { + old_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + if (old_cert == NULL) { + cm_log(1, "Error parsing certificate \"%s\".\n", args->entry->cm_cert); + goto done; + } + } + } + cm_log(3, "old_cert is %s\n", old_cert == NULL ? "NULL" : "present"); /* Now that we're logged in, try to decrypt the enveloped data. */ plain = NULL; @@ -445,7 +463,7 @@ next_slot: !PRIVKEY_LIST_END(kle, keylist); kle = PRIVKEY_LIST_NEXT(kle)) { plain = try_to_decode(args->entry, arena, &item, - kle->key); + kle->key, old_cert); if (plain != NULL) { break; } @@ -482,4 +500,7 @@ done: cm_log(1, "Error shutting down NSS.\n"); } } + if (old_cert != NULL) { + X509_free(old_cert); + } } diff --git a/src/submit-o.c b/src/submit-o.c index 45c7300..5bd23af 100644 --- a/src/submit-o.c +++ b/src/submit-o.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -326,6 +327,7 @@ cm_submit_o_decrypt_envelope(const unsigned char *envelope, const unsigned char *u; long error, l; int result = 0; + X509 *old_cert = NULL; if ((args->entry->cm_key_next_marker != NULL) && (strlen(args->entry->cm_key_next_marker) > 0)) { @@ -375,13 +377,47 @@ cm_submit_o_decrypt_envelope(const unsigned char *envelope, cm_log(1, "Out of memory.\n"); goto done; } + if (args->entry->cm_cert != NULL) { + BIO *bio = NULL; + cm_log(3, "Parsing existing certificate\n"); + bio = BIO_new_mem_buf(args->entry->cm_cert, -1); + if (bio == NULL) { + cm_log(1, "Out of memory.\n"); + goto done; + } else { + old_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + if (old_cert == NULL) { + cm_log(1, "Error parsing certificate \"%s\".\n", args->entry->cm_cert); + goto done; + } + } + } + cm_log(3, "old_cert is %s\n", old_cert == NULL ? "NULL" : "present"); if (pkey_next != NULL) { - result = PKCS7_decrypt(p7, pkey_next, NULL, out, 0); + result = PKCS7_decrypt(p7, pkey_next, old_cert, out, 0); if (result == 1) { goto done; + } else { + error = errno; + cm_log(1, "Error decrypting PKCS#7 with pkey_next: %s.\n", + strerror(error)); + while ((error = ERR_get_error()) != 0) { + ERR_error_string_n(error, buf, sizeof(buf)); + cm_log(1, "%s\n", buf); + } + } + } + result = PKCS7_decrypt(p7, pkey, old_cert, out, 0); + if (result == 0) { + error = errno; + cm_log(1, "Error decrypting PKCS#7 with pkey: %s.\n", + strerror(error)); + while ((error = ERR_get_error()) != 0) { + ERR_error_string_n(error, buf, sizeof(buf)); + cm_log(1, "%s\n", buf); } } - result = PKCS7_decrypt(p7, pkey, NULL, out, 0); done: if (result == 1) { p = NULL; @@ -411,4 +447,7 @@ done: if (out != NULL) { BIO_free(out); } + if (old_cert != NULL) { + X509_free(old_cert); + } }