diff mbox series

Allow to pass a CA and split code for verification

Message ID 20190130154025.977-1-sbabic@denx.de
State Accepted
Headers show
Series Allow to pass a CA and split code for verification | expand

Commit Message

Stefano Babic Jan. 30, 2019, 3:40 p.m. UTC
A CA public certificate can be used to verify the SWU via CMS.
Additionally, split code related verification in separate files.
SWUpdate does not support both RSA and CMS at the same time and it is
more readable to have the related code in separate files.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---
 core/swupdate.c                   |   5 +-
 corelib/Makefile                  |   3 +
 corelib/swupdate_cms_verify.c     | 247 ++++++++++++++++++
 corelib/swupdate_rsa_verify.c     | 181 ++++++++++++++
 corelib/swupdate_verify_private.h |  26 ++
 corelib/verify_signature.c        | 399 +-----------------------------
 6 files changed, 463 insertions(+), 398 deletions(-)
 create mode 100644 corelib/swupdate_cms_verify.c
 create mode 100644 corelib/swupdate_rsa_verify.c
 create mode 100644 corelib/swupdate_verify_private.h
diff mbox series

Patch

diff --git a/core/swupdate.c b/core/swupdate.c
index 61e6dc0..4f3d9d6 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -81,6 +81,7 @@  static struct option long_options[] = {
 	{"no-downgrading", required_argument, NULL, 'N'},
 #ifdef CONFIG_SIGNED_IMAGES
 	{"key", required_argument, NULL, 'k'},
+	{"ca-path", required_argument, NULL, 'k'},
 	{"cert-purpose", required_argument, NULL, '1'},
 	{"forced-signer-name", required_argument, NULL, '2'},
 #endif
@@ -131,6 +132,7 @@  static void usage(char *programname)
 		"     --cert-purpose <purpose>   : set expected certificate purpose\n"
 		"                                  [emailProtection|codeSigning] (default: emailProtection)\n"
 		"     --forced-signer-name <cn>  : set expected common name of signer certificate\n"
+		"     --ca-path                  : path to the Certificate Authority (PEM)\n"
 #endif
 #ifdef CONFIG_ENCRYPTED_IMAGES
 		" -K, --key-aes <key file>       : the file contains the symmetric key to be used\n"
@@ -327,7 +329,6 @@  static int install_from_file(char *fname, int check)
 		exit(EXIT_FAILURE);
 	}
 
-
 	if (check_hw_compatibility(&swcfg)) {
 		ERROR("SW not compatible with hardware");
 		exit(EXIT_FAILURE);
@@ -490,6 +491,8 @@  static int read_globals_settings(void *elem, void *data)
 
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"public-key-file", sw->globals.publickeyfname);
+	GET_FIELD_STRING(LIBCFG_PARSER, elem,
+				"ca-path", sw->globals.publickeyfname);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"aes-key-file", sw->globals.aeskeyfname);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
diff --git a/corelib/Makefile b/corelib/Makefile
index 4b30f9c..d6edf65 100644
--- a/corelib/Makefile
+++ b/corelib/Makefile
@@ -18,3 +18,6 @@  lib-$(CONFIG_LIBCONFIG)		+= swupdate_settings.o \
 				   parsing_library_libconfig.o
 lib-$(CONFIG_JSON)		+= parsing_library_libjson.o
 lib-$(CONFIG_CHANNEL_CURL)	+= channel_curl.o
+lib-$(CONFIG_SIGALG_RAWRSA)	+= swupdate_rsa_verify.o
+lib-$(CONFIG_SIGALG_CMS)	+= swupdate_cms_verify.o
+
diff --git a/corelib/swupdate_cms_verify.c b/corelib/swupdate_cms_verify.c
new file mode 100644
index 0000000..774a904
--- /dev/null
+++ b/corelib/swupdate_cms_verify.c
@@ -0,0 +1,247 @@ 
+/*
+ * (C) Copyright 2019
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * SPDX-License-Identifier:     GPL-2.0-or-later
+ *
+ * Code mostly taken from openssl examples
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+#include "swupdate_verify_private.h"
+
+int check_code_sign(const X509_PURPOSE *xp, const X509 *crt, int ca)
+{
+	X509 *x = (X509 *)crt;
+	uint32_t ex_flags = SSL_X509_get_extension_flags(x);
+	uint32_t ex_xkusage = SSL_X509_get_extended_key_usage(x);
+
+	(void)xp;
+
+	if (ca) {
+		int idx;
+		const X509_PURPOSE *pt;
+
+		if ((ex_flags & EXFLAG_XKUSAGE) && !(ex_xkusage & XKU_CODE_SIGN))
+			return 0;
+
+		idx = X509_PURPOSE_get_by_id(X509_PURPOSE_OCSP_HELPER);
+		if (idx == -1)
+			return 0;
+
+		pt = X509_PURPOSE_get0(idx);
+		return pt->check_purpose(pt, x, ca);
+	}
+
+	return (ex_flags & EXFLAG_XKUSAGE) && (ex_xkusage & XKU_CODE_SIGN);
+}
+
+static int cms_verify_callback(int ok, X509_STORE_CTX *ctx) {
+	int cert_error = X509_STORE_CTX_get_error(ctx);
+
+	if (!ok) {
+		switch (cert_error) {
+#if defined(CONFIG_CMS_IGNORE_EXPIRED_CERTIFICATE)
+		case X509_V_ERR_CERT_HAS_EXPIRED:
+		case X509_V_ERR_CERT_NOT_YET_VALID:
+			ok = 1;
+			break;
+#endif
+#if defined(CONFIG_CMS_IGNORE_CERTIFICATE_PURPOSE)
+		case X509_V_ERR_INVALID_PURPOSE:
+			ok = 1;
+			break;
+#endif
+		default:
+			break;
+		}
+	}
+
+	return ok;
+}
+
+X509_STORE *load_cert_chain(const char *file)
+{
+	X509_STORE *castore = X509_STORE_new();
+	if (!castore) {
+		return NULL;
+	}
+
+	/*
+	 * Set error callback function for verification of CRTs and CRLs in order
+	 * to ignore some errors depending on configuration
+	 */
+	X509_STORE_set_verify_cb(castore, cms_verify_callback);
+
+	BIO *castore_bio = BIO_new_file(file, "r");
+	if (!castore_bio) {
+		TRACE("failed: BIO_new_file(%s)", file);
+		return NULL;
+	}
+
+	int crt_count = 0;
+	X509 *crt = NULL;
+	do {
+		crt = PEM_read_bio_X509(castore_bio, NULL, 0, NULL);
+		if (crt) {
+			crt_count++;
+			char *subj = X509_NAME_oneline(X509_get_subject_name(crt), NULL, 0);
+			char *issuer = X509_NAME_oneline(X509_get_issuer_name(crt), NULL, 0);
+			TRACE("Read PEM #%d: %s %s", crt_count, issuer, subj);
+			free(subj);
+			free(issuer);
+			if (X509_STORE_add_cert(castore, crt) == 0) {
+				TRACE("Adding certificate to X509_STORE failed");
+				BIO_free(castore_bio);
+				X509_STORE_free(castore);
+				return NULL;
+			}
+		}
+	} while (crt);
+	BIO_free(castore_bio);
+
+	if (crt_count == 0) {
+		X509_STORE_free(castore);
+		return NULL;
+	}
+
+	return castore;
+}
+
+static inline int next_common_name(X509_NAME *subject, int i)
+{
+	return X509_NAME_get_index_by_NID(subject, NID_commonName, i);
+}
+
+static int check_common_name(X509_NAME *subject, const char *name)
+{
+	int i = -1, ret = 1;
+
+	while ((i = next_common_name(subject, i)) > -1) {
+		X509_NAME_ENTRY *e = X509_NAME_get_entry(subject, i);
+		ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
+		unsigned char *cn;
+		size_t len = strlen(name);
+		bool matches = (ASN1_STRING_to_UTF8(&cn, d) == (int)len)
+				&& (strncmp(name, (const char *)cn, len) == 0);
+
+		OPENSSL_free(cn);
+		if (!matches) {
+			char *subj = X509_NAME_oneline(subject, NULL, 0);
+
+			ERROR("common name of '%s' does not match expected '%s'",
+				subj, name);
+			OPENSSL_free(subj);
+			return 2;
+		} else {
+			ret = 0;
+		}
+	}
+
+	if (ret == 0) {
+		char *subj = X509_NAME_oneline(subject, NULL, 0);
+
+		TRACE("verified signer cert: %s", subj);
+		OPENSSL_free(subj);
+	}
+
+	return ret;
+}
+
+static int check_signer_name(CMS_ContentInfo *cms, const char *name)
+{
+	STACK_OF(CMS_SignerInfo) *infos = CMS_get0_SignerInfos(cms);
+	STACK_OF(X509) *crts;
+	int i, ret = 1;
+
+	if ((name == NULL) || (name[0] == '\0'))
+		return 0;
+
+	crts = CMS_get1_certs(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(infos); ++i) {
+		CMS_SignerInfo *si = sk_CMS_SignerInfo_value(infos, i);
+		int j;
+
+		for (j = 0; j < sk_X509_num(crts); ++j) {
+			X509 *crt = sk_X509_value(crts, j);
+
+			if (CMS_SignerInfo_cert_cmp(si, crt) == 0) {
+				ret = check_common_name(
+					X509_get_subject_name(crt), name);
+			}
+		}
+	}
+	sk_X509_pop_free(crts, X509_free);
+
+	return ret;
+}
+
+int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+		const char *file, const char *signer_name)
+{
+	int status = -EFAULT;
+	CMS_ContentInfo *cms = NULL;
+	BIO *content_bio = NULL;
+
+	/* Open CMS blob that needs to be checked */
+	BIO *sigfile_bio = BIO_new_file(sigfile, "rb");
+	if (!sigfile_bio) {
+		ERROR("%s cannot be opened", sigfile);
+		status = -EBADF;
+		goto out;
+	}
+
+	/* Parse the DER-encoded CMS message */
+	cms = d2i_CMS_bio(sigfile_bio, NULL);
+	if (!cms) {
+		ERROR("%s cannot be parsed as DER-encoded CMS signature blob", sigfile);
+		status = -EFAULT;
+		goto out;
+	}
+
+	if (check_signer_name(cms, signer_name)) {
+		ERROR("failed to verify signer name");
+		status = -EFAULT;
+		goto out;
+	}
+
+	/* Open the content file (data which was signed) */
+	content_bio = BIO_new_file(file, "rb");
+	if (!content_bio) {
+		ERROR("%s cannot be opened", file);
+		status = -EBADF;
+		goto out;
+	}
+
+	/* Then try to verify signature */
+	if (!CMS_verify(cms, NULL, dgst->certs, content_bio,
+			NULL, CMS_BINARY)) {
+		ERR_print_errors_fp(stderr);
+		ERROR("Signature verification failed");
+		status = -EBADMSG;
+		goto out;
+	}
+
+	TRACE("Verified OK");
+
+	/* Signature is valid */
+	status = 0;
+out:
+
+	if (cms) {
+		CMS_ContentInfo_free(cms);
+	}
+	if (content_bio) {
+		BIO_free(content_bio);
+	}
+	if (sigfile_bio) {
+		BIO_free(sigfile_bio);
+	}
+	return status;
+}
diff --git a/corelib/swupdate_rsa_verify.c b/corelib/swupdate_rsa_verify.c
new file mode 100644
index 0000000..6231a70
--- /dev/null
+++ b/corelib/swupdate_rsa_verify.c
@@ -0,0 +1,181 @@ 
+/*
+ * (C) Copyright 2019
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * SPDX-License-Identifier:     GPL-2.0-or-later
+ *
+ * Code mostly taken from openssl examples
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+#include "swupdate_verify_private.h"
+
+#define BUFSIZE	(1024 * 8)
+
+EVP_PKEY *load_pubkey(const char *file)
+{
+	BIO *key=NULL;
+	EVP_PKEY *pkey=NULL;
+
+	if (file == NULL)
+	{
+		ERROR("no keyfile specified");
+		goto end;
+	}
+
+	key=BIO_new(BIO_s_file());
+	if (key == NULL)
+	{
+		goto end;
+	}
+
+	if (BIO_read_filename(key, file) <= 0)
+	{
+		printf("Error opening %s \n", file);
+		goto end;
+	}
+
+	pkey=PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
+end:
+	if (key != NULL) BIO_free(key);
+	if (pkey == NULL)
+		ERROR("unable to load key filename %s", file);
+	return(pkey);
+}
+
+static int dgst_verify_init(struct swupdate_digest *dgst)
+{
+	int rc;
+
+	rc = EVP_DigestVerifyInit(dgst->ctx, NULL, EVP_sha256(), NULL, dgst->pkey);
+	if (rc != 1) {
+		ERROR("EVP_DigestVerifyInit failed, error 0x%lx", ERR_get_error());
+		return -EFAULT; /* failed */
+	}
+
+	return 0;
+}
+
+static int verify_update(struct swupdate_digest *dgst, char *msg, unsigned int mlen)
+{
+	int rc;
+
+	rc = EVP_DigestVerifyUpdate(dgst->ctx, msg, mlen);
+	if(rc != 1) {
+		ERROR("EVP_DigestVerifyUpdate failed, error 0x%lx", ERR_get_error());
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int verify_final(struct swupdate_digest *dgst, unsigned char *sig, unsigned int slen)
+{
+	unsigned int rc;
+
+	/* Clear any errors for the call below */
+	ERR_clear_error();
+	rc = EVP_DigestVerifyFinal(dgst->ctx, sig, slen);
+	if(rc != 1) {
+		ERROR("EVP_DigestVerifyFinal failed, error 0x%lx %d", ERR_get_error(), rc);
+		return -1;
+	}
+
+	return rc;
+}
+
+int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+		const char *file, const char *signer_name)
+{
+	FILE *fp = NULL;
+	BIO *sigbio;
+	int siglen = 0;
+	int i;
+	unsigned char *sigbuf = NULL;
+	char *msg = NULL;
+	int size;
+	size_t rbytes;
+	int status = 0;
+
+	(void)signer_name;
+	if (!dgst) {
+		ERROR("Wrong crypto initialization: did you pass the key ?");
+		status = -ENOKEY;
+		goto out;
+	}
+
+	msg = malloc(BUFSIZE);
+	if (!msg) {
+		status = -ENOMEM;
+		goto out;
+	}
+
+	sigbio = BIO_new_file(sigfile, "rb");
+	siglen = EVP_PKEY_size(dgst->pkey);
+	sigbuf = OPENSSL_malloc(siglen);
+
+	siglen = BIO_read(sigbio, sigbuf, siglen);
+	BIO_free(sigbio);
+
+	if(siglen <= 0) {
+		ERROR("Error reading signature file %s", sigfile);
+		status = -ENOKEY;
+		goto out;
+	}
+
+	if ((dgst_init(dgst, EVP_sha256()) < 0) || (dgst_verify_init(dgst) < 0)) {
+		status = -ENOKEY;
+		goto out;
+	}
+
+	fp = fopen(file, "r");
+	if (!fp) {
+		ERROR("%s cannot be opened", file);
+		status = -EBADF;
+		goto out;
+	}
+
+	size = 0;
+	for (;;) {
+		rbytes = fread(msg, 1, BUFSIZE, fp);
+		if (rbytes > 0) {
+			size += rbytes;
+			if (verify_update(dgst, msg, rbytes) < 0)
+				break;
+		}
+		if (feof(fp))
+			break;
+	}
+
+	TRACE("Verify signed image: Read %d bytes", size);
+	i = verify_final(dgst, sigbuf, (unsigned int)siglen);
+	if(i > 0) {
+		TRACE("Verified OK");
+		status = 0;
+	} else if(i == 0) {
+		TRACE("Verification Failure");
+		status = -EBADMSG;
+	} else {
+		TRACE("Error Verifying Data");
+		status = -EFAULT;
+	}
+
+out:
+	if (fp)
+		fclose(fp);
+	if (msg)
+		free(msg);
+	if (sigbuf)
+		OPENSSL_free(sigbuf);
+
+	return status;
+}
+
+
+
diff --git a/corelib/swupdate_verify_private.h b/corelib/swupdate_verify_private.h
new file mode 100644
index 0000000..e16f2ce
--- /dev/null
+++ b/corelib/swupdate_verify_private.h
@@ -0,0 +1,26 @@ 
+/*
+ * (C) Copyright 2019
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * SPDX-License-Identifier:     GPL-2.0-or-later
+ */
+
+#ifndef _SWUPDATE_VERIFY_H
+#define _SWUPDATE_VERIFY_H
+
+#include <openssl/evp.h>
+
+struct swupdate_digest;
+int dgst_init(struct swupdate_digest *dgst, const EVP_MD *md);
+
+#if defined(CONFIG_SIGALG_RAWRSA)
+EVP_PKEY *load_pubkey(const char *file);
+#endif
+
+#ifdef CONFIG_SIGALG_CMS
+#include <openssl/cms.h>
+int check_code_sign(const X509_PURPOSE *xp, const X509 *crt, int ca);
+X509_STORE *load_cert_chain(const char *file);
+#endif
+
+#endif
diff --git a/corelib/verify_signature.c b/corelib/verify_signature.c
index dc3fe6d..d08d657 100644
--- a/corelib/verify_signature.c
+++ b/corelib/verify_signature.c
@@ -14,10 +14,9 @@ 
 #include "swupdate.h"
 #include "sslapi.h"
 #include "util.h"
+#include "swupdate_verify_private.h"
 
-#define BUFSIZE	(1024 * 8)
-
-static int dgst_init(struct swupdate_digest *dgst, const EVP_MD *md)
+int dgst_init(struct swupdate_digest *dgst, const EVP_MD *md)
 {
 	int rc;
 
@@ -31,400 +30,6 @@  static int dgst_init(struct swupdate_digest *dgst, const EVP_MD *md)
 	return 0;
 }
 
-/*
- * depending on the algorithm, load a RSA public key
- * or a certificate
- */
-#if defined(CONFIG_SIGALG_RAWRSA)
-static EVP_PKEY *load_pubkey(const char *file)
-{
-	BIO *key=NULL;
-	EVP_PKEY *pkey=NULL;
-
-	if (file == NULL)
-	{
-		ERROR("no keyfile specified");
-		goto end;
-	}
-
-	key=BIO_new(BIO_s_file());
-	if (key == NULL)
-	{
-		goto end;
-	}
-
-	if (BIO_read_filename(key, file) <= 0)
-	{
-		printf("Error opening %s \n", file);
-		goto end;
-	}
-
-	pkey=PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
-end:
-	if (key != NULL) BIO_free(key);
-	if (pkey == NULL)
-		ERROR("unable to load key filename %s", file);
-	return(pkey);
-}
-
-static int dgst_verify_init(struct swupdate_digest *dgst)
-{
-	int rc;
-
-	rc = EVP_DigestVerifyInit(dgst->ctx, NULL, EVP_sha256(), NULL, dgst->pkey);
-	if (rc != 1) {
-		ERROR("EVP_DigestVerifyInit failed, error 0x%lx", ERR_get_error());
-		return -EFAULT; /* failed */
-	}
-
-	return 0;
-}
-
-static int verify_update(struct swupdate_digest *dgst, char *msg, unsigned int mlen)
-{
-	int rc;
-
-	rc = EVP_DigestVerifyUpdate(dgst->ctx, msg, mlen);
-	if(rc != 1) {
-		ERROR("EVP_DigestVerifyUpdate failed, error 0x%lx", ERR_get_error());
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int verify_final(struct swupdate_digest *dgst, unsigned char *sig, unsigned int slen)
-{
-	unsigned int rc;
-
-	/* Clear any errors for the call below */
-	ERR_clear_error();
-	rc = EVP_DigestVerifyFinal(dgst->ctx, sig, slen);
-	if(rc != 1) {
-		ERROR("EVP_DigestVerifyFinal failed, error 0x%lx %d", ERR_get_error(), rc);
-		return -1;
-	}
-
-	return rc;
-}
-
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
-		const char *file, const char *signer_name)
-{
-	FILE *fp = NULL;
-	BIO *sigbio;
-	int siglen = 0;
-	int i;
-	unsigned char *sigbuf = NULL;
-	char *msg = NULL;
-	int size;
-	size_t rbytes;
-	int status = 0;
-
-	(void)signer_name;
-	if (!dgst) {
-		ERROR("Wrong crypto initialization: did you pass the key ?");
-		status = -ENOKEY;
-		goto out;
-	}
-
-	msg = malloc(BUFSIZE);
-	if (!msg) {
-		status = -ENOMEM;
-		goto out;
-	}
-
-	sigbio = BIO_new_file(sigfile, "rb");
-	siglen = EVP_PKEY_size(dgst->pkey);
-	sigbuf = OPENSSL_malloc(siglen);
-
-	siglen = BIO_read(sigbio, sigbuf, siglen);
-	BIO_free(sigbio);
-
-	if(siglen <= 0) {
-		ERROR("Error reading signature file %s", sigfile);
-		status = -ENOKEY;
-		goto out;
-	}
-
-	if ((dgst_init(dgst, EVP_sha256()) < 0) || (dgst_verify_init(dgst) < 0)) {
-		status = -ENOKEY;
-		goto out;
-	}
-
-	fp = fopen(file, "r");
-	if (!fp) {
-		ERROR("%s cannot be opened", file);
-		status = -EBADF;
-		goto out;
-	}
-
-	size = 0;
-	for (;;) {
-		rbytes = fread(msg, 1, BUFSIZE, fp);
-		if (rbytes > 0) {
-			size += rbytes;
-			if (verify_update(dgst, msg, rbytes) < 0)
-				break;
-		}
-		if (feof(fp))
-			break;
-	}
-
-	TRACE("Verify signed image: Read %d bytes", size);
-	i = verify_final(dgst, sigbuf, (unsigned int)siglen);
-	if(i > 0) {
-		TRACE("Verified OK");
-		status = 0;
-	} else if(i == 0) {
-		TRACE("Verification Failure");
-		status = -EBADMSG;
-	} else {
-		TRACE("Error Verifying Data");
-		status = -EFAULT;
-	}
-
-out:
-	if (fp)
-		fclose(fp);
-	if (msg)
-		free(msg);
-	if (sigbuf)
-		OPENSSL_free(sigbuf);
-
-	return status;
-}
-
-#elif defined(CONFIG_SIGALG_CMS)
-static int check_code_sign(const X509_PURPOSE *xp, const X509 *crt, int ca)
-{
-	X509 *x = (X509 *)crt;
-	uint32_t ex_flags = SSL_X509_get_extension_flags(x);
-	uint32_t ex_xkusage = SSL_X509_get_extended_key_usage(x);
-
-	(void)xp;
-
-	if (ca) {
-		int idx;
-		const X509_PURPOSE *pt;
-
-		if ((ex_flags & EXFLAG_XKUSAGE) && !(ex_xkusage & XKU_CODE_SIGN))
-			return 0;
-
-		idx = X509_PURPOSE_get_by_id(X509_PURPOSE_OCSP_HELPER);
-		if (idx == -1)
-			return 0;
-
-		pt = X509_PURPOSE_get0(idx);
-		return pt->check_purpose(pt, x, ca);
-	}
-
-	return (ex_flags & EXFLAG_XKUSAGE) && (ex_xkusage & XKU_CODE_SIGN);
-}
-
-static int cms_verify_callback(int ok, X509_STORE_CTX *ctx) {
-	int cert_error = X509_STORE_CTX_get_error(ctx);
-
-	if (!ok) {
-		switch (cert_error) {
-#if defined(CONFIG_CMS_IGNORE_EXPIRED_CERTIFICATE)
-		case X509_V_ERR_CERT_HAS_EXPIRED:
-		case X509_V_ERR_CERT_NOT_YET_VALID:
-			ok = 1;
-			break;
-#endif
-#if defined(CONFIG_CMS_IGNORE_CERTIFICATE_PURPOSE)
-		case X509_V_ERR_INVALID_PURPOSE:
-			ok = 1;
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-	return ok;
-}
-static X509_STORE *load_cert_chain(const char *file)
-{
-	X509_STORE *castore = X509_STORE_new();
-	if (!castore) {
-		return NULL;
-	}
-
-	/*
-	 * Set error callback function for verification of CRTs and CRLs in order
-	 * to ignore some errors depending on configuration
-	 */
-	X509_STORE_set_verify_cb(castore, cms_verify_callback);
-
-	BIO *castore_bio = BIO_new_file(file, "r");
-	if (!castore_bio) {
-		TRACE("failed: BIO_new_file(%s)", file);
-		return NULL;
-	}
-
-	int crt_count = 0;
-	X509 *crt = NULL;
-	do {
-		crt = PEM_read_bio_X509(castore_bio, NULL, 0, NULL);
-		if (crt) {
-			crt_count++;
-			char *subj = X509_NAME_oneline(X509_get_subject_name(crt), NULL, 0);
-			char *issuer = X509_NAME_oneline(X509_get_issuer_name(crt), NULL, 0);
-			TRACE("Read PEM #%d: %s %s", crt_count, issuer, subj);
-			free(subj);
-			free(issuer);
-			if (X509_STORE_add_cert(castore, crt) == 0) {
-				TRACE("Adding certificate to X509_STORE failed");
-				BIO_free(castore_bio);
-				X509_STORE_free(castore);
-				return NULL;
-			}
-		}
-	} while (crt);
-	BIO_free(castore_bio);
-
-	if (crt_count == 0) {
-		X509_STORE_free(castore);
-		return NULL;
-	}
-
-	return castore;
-}
-
-static inline int next_common_name(X509_NAME *subject, int i)
-{
-	return X509_NAME_get_index_by_NID(subject, NID_commonName, i);
-}
-
-static int check_common_name(X509_NAME *subject, const char *name)
-{
-	int i = -1, ret = 1;
-
-	while ((i = next_common_name(subject, i)) > -1) {
-		X509_NAME_ENTRY *e = X509_NAME_get_entry(subject, i);
-		ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
-		unsigned char *cn;
-		size_t len = strlen(name);
-		bool matches = (ASN1_STRING_to_UTF8(&cn, d) == (int)len)
-				&& (strncmp(name, (const char *)cn, len) == 0);
-
-		OPENSSL_free(cn);
-		if (!matches) {
-			char *subj = X509_NAME_oneline(subject, NULL, 0);
-
-			ERROR("common name of '%s' does not match expected '%s'",
-				subj, name);
-			OPENSSL_free(subj);
-			return 2;
-		} else {
-			ret = 0;
-		}
-	}
-
-	if (ret == 0) {
-		char *subj = X509_NAME_oneline(subject, NULL, 0);
-
-		TRACE("verified signer cert: %s", subj);
-		OPENSSL_free(subj);
-	}
-
-	return ret;
-}
-
-static int check_signer_name(CMS_ContentInfo *cms, const char *name)
-{
-	STACK_OF(CMS_SignerInfo) *infos = CMS_get0_SignerInfos(cms);
-	STACK_OF(X509) *crts;
-	int i, ret = 1;
-
-	if ((name == NULL) || (name[0] == '\0'))
-		return 0;
-
-	crts = CMS_get1_certs(cms);
-	for (i = 0; i < sk_CMS_SignerInfo_num(infos); ++i) {
-		CMS_SignerInfo *si = sk_CMS_SignerInfo_value(infos, i);
-		int j;
-
-		for (j = 0; j < sk_X509_num(crts); ++j) {
-			X509 *crt = sk_X509_value(crts, j);
-
-			if (CMS_SignerInfo_cert_cmp(si, crt) == 0) {
-				ret = check_common_name(
-					X509_get_subject_name(crt), name);
-			}
-		}
-	}
-	sk_X509_pop_free(crts, X509_free);
-
-	return ret;
-}
-
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
-		const char *file, const char *signer_name)
-{
-	int status = -EFAULT;
-	CMS_ContentInfo *cms = NULL;
-	BIO *content_bio = NULL;
-
-	/* Open CMS blob that needs to be checked */
-	BIO *sigfile_bio = BIO_new_file(sigfile, "rb");
-	if (!sigfile_bio) {
-		ERROR("%s cannot be opened", sigfile);
-		status = -EBADF;
-		goto out;
-	}
-
-	/* Parse the DER-encoded CMS message */
-	cms = d2i_CMS_bio(sigfile_bio, NULL);
-	if (!cms) {
-		ERROR("%s cannot be parsed as DER-encoded CMS signature blob", sigfile);
-		status = -EFAULT;
-		goto out;
-	}
-
-	if (check_signer_name(cms, signer_name)) {
-		ERROR("failed to verify signer name");
-		status = -EFAULT;
-		goto out;
-	}
-
-	/* Open the content file (data which was signed) */
-	content_bio = BIO_new_file(file, "rb");
-	if (!content_bio) {
-		ERROR("%s cannot be opened", file);
-		status = -EBADF;
-		goto out;
-	}
-
-	/* Then try to verify signature */
-	if (!CMS_verify(cms, NULL, dgst->certs, content_bio,
-			NULL, CMS_BINARY)) {
-		ERR_print_errors_fp(stderr);
-		ERROR("Signature verification failed");
-		status = -EBADMSG;
-		goto out;
-	}
-
-	TRACE("Verified OK");
-
-	/* Signature is valid */
-	status = 0;
-out:
-
-	if (cms) {
-		CMS_ContentInfo_free(cms);
-	}
-	if (content_bio) {
-		BIO_free(content_bio);
-	}
-	if (sigfile_bio) {
-		BIO_free(sigfile_bio);
-	}
-	return status;
-}
-#endif
 struct swupdate_digest *swupdate_HASH_init(const char *SHAlength)
 {
 	struct swupdate_digest *dgst;