diff mbox series

[V2,06/10] Add support for asymmetric file decryption with CMS

Message ID 20231204100620.27789-7-Michael.Glembotzki@iris-sensing.com
State Changes Requested
Headers show
Series [V2,01/10] util: BUG: set_aes_key does not fail on invalid aes key or ivt | expand

Commit Message

Michael Glembotzki Dec. 4, 2023, 10:05 a.m. UTC
Signed-off-by: Michael Glembotzki <Michael.Glembotzki@iris-sensing.com>
---
 corelib/Makefile               |   3 +
 corelib/swupdate_cms_decrypt.c | 112 +++++++++++++++++++++++++++++++++
 include/sslapi.h               |   5 ++
 3 files changed, 120 insertions(+)
 create mode 100644 corelib/swupdate_cms_decrypt.c
diff mbox series

Patch

diff --git a/corelib/Makefile b/corelib/Makefile
index c9ca4aa..06690d8 100644
--- a/corelib/Makefile
+++ b/corelib/Makefile
@@ -18,6 +18,9 @@  endif
 lib-$(CONFIG_SIGALG_RAWRSA)	+= swupdate_rsa_verify.o
 lib-$(CONFIG_SIGALG_RSAPSS)	+= swupdate_rsa_verify.o
 endif
+ifeq ($(CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION),y)
+lib-$(CONFIG_ENCRYPTED_IMAGES)	+= swupdate_cms_decrypt.o
+endif
 ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
 lib-$(CONFIG_SIGALG_CMS)	+= swupdate_cms_verify.o
 endif
diff --git a/corelib/swupdate_cms_decrypt.c b/corelib/swupdate_cms_decrypt.c
new file mode 100644
index 0000000..5af2508
--- /dev/null
+++ b/corelib/swupdate_cms_decrypt.c
@@ -0,0 +1,112 @@ 
+/*
+ * (C) Copyright 2023
+ * Michael Glembotzki, iris-GmbH infrared & intelligent sensors, michael.glembotzki@iris-sensing.com.
+ *
+ * SPDX-License-Identifier:     GPL-2.0-only
+ *
+ * Code mostly taken from openssl examples
+ */
+#include <sys/stat.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+
+int swupdate_dgst_add_recipient_keypair(struct swupdate_cfg *sw, const char *keypair_file) {
+	X509 *rcert = NULL;
+	EVP_PKEY *rkey = NULL;
+	struct swupdate_digest *dgst = sw->dgst;
+	int ret = 0;
+
+	if (!dgst) {
+		dgst = calloc(1, sizeof(*dgst));
+		if (!dgst) {
+			ret = 1;
+			goto err;
+		}
+	}
+
+	BIO *tbio = BIO_new_file(keypair_file, "r");
+	if (!tbio) {
+		ERROR("%s cannot be opened", keypair_file);
+		ret = 1;
+		goto err;
+	}
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+	if (!rcert) {
+		WARN("Recipient cert not found");
+	}
+	BIO_reset(tbio);
+
+	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+	BIO_free(tbio);
+	if (!rkey) {
+		ERROR("Recipient private key not found");
+		ret = 1;
+		goto err;
+	}
+
+	dgst->rcert = rcert;
+	dgst->rkey = rkey;
+
+	return ret;
+
+err:
+	if (dgst) {
+		free(dgst);
+	}
+	return ret;
+}
+
+int swupdate_decrypt_file(struct swupdate_digest *dgst, const char *infile, const char *outfile) {
+	BIO *in = NULL, *out = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 0;
+
+	if (!dgst || !infile || !outfile) {
+		return 1;
+	}
+
+	/* Open CMS message to decrypt */
+	in = BIO_new_file(infile, "rb");
+	if (!in) {
+		ERROR("%s cannot be opened", infile);
+		ret = 1;
+		goto err;
+	}
+
+	/* Parse message */
+	cms = d2i_CMS_bio(in, NULL);
+	if (!cms) {
+		ERROR("%s cannot be parsed as DER-encoded CMS blob", infile);
+		ret = 1;
+		goto err;
+	}
+
+	out = BIO_new_file(outfile, "wb");
+	if (!out) {
+		ERROR("%s cannot be opened", outfile);
+		ret = 1;
+		goto err;
+	}
+
+	if (chmod(outfile, S_IRUSR | S_IWUSR)) {
+		ERROR("Setting file permissions");
+		ret = 1;
+		goto err;
+	}
+
+	/* Decrypt CMS message */
+	if (!CMS_decrypt(cms, dgst->rkey, dgst->rcert, NULL, out, 0)) {
+		ERR_print_errors_fp(stderr);
+		ERROR("Decrypting %s failed", infile);
+		ret = 1;
+		goto err;
+	}
+
+err:
+	BIO_free(in);
+	BIO_free(out);
+	CMS_ContentInfo_free(cms);
+	return ret;
+}
diff --git a/include/sslapi.h b/include/sslapi.h
index de86695..0330b31 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -221,6 +221,11 @@  UNUSED static inline struct swupdate_digest *swupdate_DECRYPT_init(
 #define swupdate_DECRYPT_cleanup(p)
 #endif
 
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+int swupdate_dgst_add_recipient_keypair(struct swupdate_cfg *sw, const char *keypair_file);
+int swupdate_decrypt_file(struct swupdate_digest *dgst, const char *infile, const char *outfile);
+#endif
+
 #ifndef SSL_PURPOSE_DEFAULT
 #define SSL_PURPOSE_EMAIL_PROT -1
 #define SSL_PURPOSE_CODE_SIGN  -1