diff mbox series

core: Add CRL support for OpenSSL

Message ID 20250212145621.27104-1-gb@hadiko.de
State New
Delegated to: Stefano Babic
Headers show
Series core: Add CRL support for OpenSSL | expand

Commit Message

Franz Heger Feb. 12, 2025, 2:56 p.m. UTC
Introduces a new command-line option --crl-path to specify the path
to a Certificate Revocation List (CRL) file when using OpenSSL.
The file is loaded and contained CRLs are added to the CA store,
setting flags to trigger consideration during downstream validation.

Signed-off-by: Franz Heger <gb@hadiko.de>
---
 core/swupdate.c                   | 11 +++++++++++
 corelib/swupdate_cms_verify.c     | 31 +++++++++++++++++++++++++++++++
 corelib/swupdate_verify_private.h |  1 +
 corelib/verify_signature.c        |  9 +++++++++
 include/swupdate.h                |  1 +
 5 files changed, 53 insertions(+)

--
2.39.5

Comments

Franz Heger June 5, 2025, 11:36 a.m. UTC | #1
Hi all,

Any feedback, comments, or thoughts would be appreciated. Thank you very 
much in advance!

Kind regards,
Franz
Stefano Babic June 6, 2025, 8:59 a.m. UTC | #2
Hi Franz,

On 6/5/25 13:36, Franz Heger wrote:
> Hi all,
> 
> Any feedback, comments, or thoughts would be appreciated. Thank you very 
> much in advance!

Your patch is related to the security subsystem in SWUpdate, and well, 
there were several discussion about this. I am quite unhappy with the 
current status, because it is a sum of growing patches and not modular. 
You see my answer here:

https://groups.google.com/g/swupdate/c/BTYSVgxlqpw/m/3IwhxehsEQAJ

I supposed to do (at least part of it) in my freetime, but at the end it 
requires more effort ad initial thought. Any patch to the current crypto 
system is just adding mess to mess, and this I want to avoid. So patches 
regarding crypto/algorithms/verification/etc. are just put on stand-by 
until the required cleanup work is not completed.

Best regards,
Stefano
Franz Heger June 24, 2025, 11:52 a.m. UTC | #3
Hi Stefano,

I see. Still, I appreciate you taking the time to reply.

Best regards,
Franz
diff mbox series

Patch

diff --git a/core/swupdate.c b/core/swupdate.c
index 0e3c667..d712b86 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -101,6 +101,9 @@  static struct option long_options[] = {
 #if defined(CONFIG_SIGALG_CMS) && !defined(CONFIG_SSL_IMPL_WOLFSSL)
 	{"forced-signer-name", required_argument, NULL, '2'},
 #endif
+#if defined(CONFIG_SIGALG_CMS) && defined(CONFIG_SSL_IMPL_OPENSSL)
+	{"crl-path", required_argument, NULL, '4'},
+#endif
 #endif
 #ifdef CONFIG_ENCRYPTED_IMAGES
 	{"key-aes", required_argument, NULL, 'K'},
@@ -163,6 +166,9 @@  static void usage(char *programname)
 		"     --forced-signer-name <cn>  : set expected common name of signer certificate\n"
 #endif
 		"     --ca-path                  : path to the Certificate Authority (PEM)\n"
+#if defined(CONFIG_SIGALG_CMS) && defined(CONFIG_SSL_IMPL_OPENSSL)
+		"     --crl-path                 : path to the Certificate Revocation List (CRL)\n"
+#endif
 #endif
 #endif
 #ifdef CONFIG_ENCRYPTED_IMAGES
@@ -313,6 +319,8 @@  static int read_globals_settings(void *elem, void *data)
 				"public-key-file", sw->publickeyfname);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"ca-path", sw->publickeyfname);
+	GET_FIELD_STRING(LIBCFG_PARSER, elem,
+				"crl-path", sw->crlfname);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"aes-key-file", sw->aeskeyfname);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
@@ -680,6 +688,9 @@  int main(int argc, char **argv)
 			strlcpy(swcfg.maximum_version, optarg,
 				sizeof(swcfg.maximum_version));
 			break;
+		case '4':
+			strlcpy(swcfg.crlfname, optarg, sizeof(swcfg.crlfname));
+			break;
 #ifdef CONFIG_ENCRYPTED_IMAGES
 		case 'K':
 			strlcpy(swcfg.aeskeyfname,
diff --git a/corelib/swupdate_cms_verify.c b/corelib/swupdate_cms_verify.c
index 15f113b..e5e15ae 100644
--- a/corelib/swupdate_cms_verify.c
+++ b/corelib/swupdate_cms_verify.c
@@ -122,6 +122,37 @@  X509_STORE *load_cert_chain(const char *file)
 	return castore;
 }

+int add_crl_to_store(X509_STORE *castore, const char *crl_file)
+{
+	BIO *fp = BIO_new_file(crl_file, "r");
+	if (!fp) {
+		TRACE("Unable to open CRL file %s", crl_file);
+		return 0;
+	}
+
+	X509_CRL *crl = NULL;
+	while ((crl = PEM_read_bio_X509_CRL(fp, NULL, NULL, NULL)) != NULL) {
+		if (X509_STORE_add_crl(castore, crl) != 1)
+		{
+			TRACE("Error adding CRL to store");
+			X509_CRL_free(crl);
+			BIO_free(fp);
+			return 0;
+		}
+
+		X509_CRL_free(crl);
+	}
+	BIO_free(fp);
+
+	// Set the flags for CRL checking
+	if(!X509_STORE_set_flags(castore, X509_V_FLAG_CRL_CHECK)) {
+		TRACE("Error setting CRL flags");
+		return 0;
+	}
+
+	return 1;
+}
+
 static inline int next_common_name(X509_NAME *subject, int i)
 {
 	return X509_NAME_get_index_by_NID(subject, NID_commonName, i);
diff --git a/corelib/swupdate_verify_private.h b/corelib/swupdate_verify_private.h
index 1717ba3..80bc4e7 100644
--- a/corelib/swupdate_verify_private.h
+++ b/corelib/swupdate_verify_private.h
@@ -20,6 +20,7 @@  EVP_PKEY *load_pubkey(const char *file);
 int check_code_sign(const X509_PURPOSE *xp, const X509 *crt, int ca);
 #endif
 X509_STORE *load_cert_chain(const char *file);
+int add_crl_to_store(X509_STORE *castore, const char *crl_file);
 #endif

 #endif
diff --git a/corelib/verify_signature.c b/corelib/verify_signature.c
index 0eed7e8..bfba7fb 100644
--- a/corelib/verify_signature.c
+++ b/corelib/verify_signature.c
@@ -153,6 +153,15 @@  int swupdate_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
 		goto dgst_init_error;
 	}

+	if (strlen(sw->crlfname)) {
+		TRACE("Loading CRL from %s", sw->crlfname);
+		if (!add_crl_to_store(dgst->certs, sw->crlfname)) {
+			ERROR("Error loading CRL from %s", sw->crlfname);
+			ret = -EINVAL;
+			goto dgst_init_error;
+		}
+	}
+
 #ifndef CONFIG_CMS_IGNORE_CERTIFICATE_PURPOSE
 	{
 		static char code_sign_name[] = "Code signing";
diff --git a/include/swupdate.h b/include/swupdate.h
index a36ffb8..5527c86 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -51,6 +51,7 @@  struct swupdate_cfg {
 	char output[SWUPDATE_GENERAL_STRING_SIZE];
 	char output_swversions[SWUPDATE_GENERAL_STRING_SIZE];
 	char publickeyfname[SWUPDATE_GENERAL_STRING_SIZE];
+	char crlfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];
 	char preupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];