Crypto libraries can be instantiated and selected at runtime. Add
registration method to the digest functions used to verify
sw-description.
crypto/swupdate_cms_verify_openssl.c | 88 ++++++++++++++++++++++++++--
crypto/swupdate_gpg_verify.c | 56 +++++++++++++++++-
crypto/swupdate_pkcs7_verify.c | 66 ++++++++++++++++++++-
crypto/swupdate_rsa_verify_mbedtls.c | 15 ++++-
crypto/swupdate_rsa_verify_openssl.c | 68 ++++++++++++++++++++-
5 files changed, 280 insertions(+), 13 deletions(-)
diff --git a/crypto/swupdate_cms_verify_openssl.c b/crypto/swupdate_cms_verify_openssl.c
index 15f113b5..22913339 100644
--- a/crypto/swupdate_cms_verify_openssl.c
+++ b/crypto/swupdate_cms_verify_openssl.c
@@ -14,7 +14,7 @@
#include "swupdate.h"
#include "sslapi.h"
#include "util.h"
-#include "swupdate_verify_private.h"
+#include "swupdate_crypto.h"
#if defined(CONFIG_CMS_SKIP_UNKNOWN_SIGNERS)
#define VERIFY_UNKNOWN_SIGNER_FLAGS (CMS_NO_SIGNER_CERT_VERIFY)
@@ -22,8 +22,10 @@
#define VERIFY_UNKNOWN_SIGNER_FLAGS (0)
#endif
+static swupdate_dgst_lib libs;
+
#ifndef CONFIG_CMS_IGNORE_CERTIFICATE_PURPOSE
-int check_code_sign(const X509_PURPOSE *xp, const X509 *crt, int ca)
+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);
@@ -74,7 +76,7 @@ static int cms_verify_callback(int ok, X509_STORE_CTX *ctx) {
return ok;
}
-X509_STORE *load_cert_chain(const char *file)
+static X509_STORE *load_cert_chain(const char *file)
{
X509_STORE *castore = X509_STORE_new();
if (!castore) {
@@ -231,7 +233,77 @@ static int check_verified_signer(CMS_ContentInfo* cms, X509_STORE* store)
}
#endif
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+static int openssl_cms_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
+{
+ struct swupdate_digest *dgst;
+ int ret;
+
+ /*
+ * Check that it was not called before
+ */
+ if (sw->dgst) {
+ return -EBUSY;
+ }
+
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ /*
+ * Load certificate chain
+ */
+ dgst->certs = load_cert_chain(keyfile);
+ if (!dgst->certs) {
+ ERROR("Error loading certificate chain from %s", keyfile);
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+
+#ifndef CONFIG_CMS_IGNORE_CERTIFICATE_PURPOSE
+ {
+ static char code_sign_name[] = "Code signing";
+ static char code_sign_sname[] = "codesign";
+
+ if (!X509_PURPOSE_add(X509_PURPOSE_CODE_SIGN, X509_TRUST_EMAIL,
+ 0, check_code_sign, code_sign_name,
+ code_sign_sname, NULL)) {
+ ERROR("failed to add code sign purpose");
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+ }
+
+ if (!X509_STORE_set_purpose(dgst->certs, sw->cert_purpose)) {
+ ERROR("failed to set purpose");
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+#endif
+
+ /*
+ * Create context
+ */
+ dgst->ctx = EVP_MD_CTX_create();
+ if(dgst->ctx == NULL) {
+ ERROR("EVP_MD_CTX_create failed, error 0x%lx", ERR_get_error());
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ sw->dgst = dgst;
+
+ return 0;
+
+dgst_init_error:
+ if (dgst)
+ free(dgst);
+
+ return ret;
+}
+
+static int openssl_cms_verify_file(struct swupdate_digest *dgst, const char *sigfile,
const char *file, const char *signer_name)
{
int status = -EFAULT;
@@ -303,3 +375,11 @@ out:
}
return status;
}
+
+__attribute__((constructor))
+static void openssl_dgst(void)
+{
+ libs.dgst_init = openssl_cms_dgst_init;
+ libs.verify_file = openssl_cms_verify_file;
+ (void)register_dgstlib("opensslCMS", &libs);
+}
diff --git a/crypto/swupdate_gpg_verify.c b/crypto/swupdate_gpg_verify.c
index 5e1a061d..a44735ec 100644
--- a/crypto/swupdate_gpg_verify.c
+++ b/crypto/swupdate_gpg_verify.c
@@ -15,6 +15,9 @@
#include <errno.h>
#include <locale.h>
#include <gpgme.h>
+#include "swupdate_crypto.h"
+
+static swupdate_dgst_lib libs;
static gpg_error_t
status_cb(void *opaque, const char *keyword, const char *value)
@@ -26,7 +29,50 @@ status_cb(void *opaque, const char *keyword, const char *value)
#define MSGBUF_LEN 256
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+static int gpg_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
+{
+ struct swupdate_digest *dgst;
+ int ret;
+
+ /*
+ * Check that it was not called before
+ */
+ if (sw->dgst) {
+ return -EBUSY;
+ }
+
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ dgst->gpg_home_directory = sw->gpg_home_directory;
+ dgst->gpgme_protocol = sw->gpgme_protocol;
+ dgst->verbose = sw->verbose;
+
+ /*
+ * Create context
+ */
+ dgst->ctx = EVP_MD_CTX_create();
+ if(dgst->ctx == NULL) {
+ ERROR("EVP_MD_CTX_create failed, error 0x%lx", ERR_get_error());
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ sw->dgst = dgst;
+
+ return 0;
+
+dgst_init_error:
+ if (dgst)
+ free(dgst);
+
+ return ret;
+}
+
+static int gpg_verify_file(struct swupdate_digest *dgst, const char *sigfile,
const char *file, const char *signer_name)
{
gpgme_ctx_t ctx;
@@ -169,3 +215,11 @@ int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
return status;
}
+
+__attribute__((constructor))
+static void gpg_dgst(void)
+{
+ libs.dgst_init = gpg_dgst_init;
+ libs.verify_file = gpg_verify_file;
+ (void)register_dgstlib("GPG", &libs);
+}
diff --git a/crypto/swupdate_pkcs7_verify.c b/crypto/swupdate_pkcs7_verify.c
index ce4c4b45..bffd1a91 100644
--- a/crypto/swupdate_pkcs7_verify.c
+++ b/crypto/swupdate_pkcs7_verify.c
@@ -16,7 +16,10 @@
#include "swupdate.h"
#include "sslapi.h"
#include "util.h"
-#include "swupdate_verify_private.h"
+#include "swupdate_crypto.h"
+#include <wolfssl/openssl/pkcs7.h>
+
+static swupdate_dgst_lib libs;
static int store_verify_callback(int ok, X509_STORE_CTX *ctx) {
int cert_error = X509_STORE_CTX_get_error(ctx);
@@ -42,7 +45,7 @@ static int store_verify_callback(int ok, X509_STORE_CTX *ctx) {
return ok;
}
-X509_STORE *load_cert_chain(const char *file)
+static X509_STORE *load_cert_chain(const char *file)
{
X509_STORE *castore = X509_STORE_new();
if (!castore) {
@@ -98,7 +101,56 @@ static int check_signer_name(const char *name)
return 0;
}
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+static int wolfssl_pkcs7_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
+{
+ struct swupdate_digest *dgst;
+ int ret;
+
+ /*
+ * Check that it was not called before
+ */
+ if (sw->dgst) {
+ return -EBUSY;
+ }
+
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ /*
+ * Load certificate chain
+ */
+ dgst->certs = load_cert_chain(keyfile);
+ if (!dgst->certs) {
+ ERROR("Error loading certificate chain from %s", keyfile);
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+
+ /*
+ * Create context
+ */
+ dgst->ctx = EVP_MD_CTX_create();
+ if(dgst->ctx == NULL) {
+ ERROR("EVP_MD_CTX_create failed, error 0x%lx", ERR_get_error());
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ sw->dgst = dgst;
+
+ return 0;
+
+dgst_init_error:
+ if (dgst)
+ free(dgst);
+
+ return ret;
+}
+
+static int wolfssl_pkcs7_verify_file(struct swupdate_digest *dgst, const char *sigfile,
const char *file, const char *signer_name)
{
int status = -EFAULT;
@@ -171,3 +223,11 @@ out:
}
return status;
}
+
+__attribute__((constructor))
+static void wolfssl_dgst(void)
+{
+ libs.dgst_init = wolfssl_pkcs7_dgst_init;
+ libs.verify_file = wolfssl_pkcs7_verify_file;
+ (void)register_dgstlib("pkcs#7WolfSSL", &libs);
+}
diff --git a/crypto/swupdate_rsa_verify_mbedtls.c b/crypto/swupdate_rsa_verify_mbedtls.c
index c145948f..2ddd7d99 100644
--- a/crypto/swupdate_rsa_verify_mbedtls.c
+++ b/crypto/swupdate_rsa_verify_mbedtls.c
@@ -16,6 +16,9 @@
#include "sslapi.h"
#include "util.h"
#include "swupdate.h"
+#include "swupdate_crypto.h"
+
+static swupdate_dgst_lib libs;
static int read_file_into_buffer(uint8_t *buffer, int size, const char *filename)
{
@@ -43,7 +46,7 @@ exit:
return result;
}
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+static int mbedtls_rsa_verify_file(struct swupdate_digest *dgst, const char *sigfile,
const char *file, const char *signer_name)
{
int error;
@@ -90,7 +93,7 @@ int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
);
}
-int swupdate_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
+static int mbedtls_rsa_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
{
struct swupdate_digest *dgst;
@@ -113,3 +116,11 @@ int swupdate_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
sw->dgst = dgst;
return 0;
}
+
+__attribute__((constructor))
+static void mbedtls_rsa_dgst(void)
+{
+ libs.dgst_init = mbedtls_rsa_dgst_init;
+ libs.verify_file = mbedtls_rsa_verify_file;
+ (void)register_dgstlib("mbedTLSRSA", &libs);
+}
diff --git a/crypto/swupdate_rsa_verify_openssl.c b/crypto/swupdate_rsa_verify_openssl.c
index 8df5274c..417921f0 100644
--- a/crypto/swupdate_rsa_verify_openssl.c
+++ b/crypto/swupdate_rsa_verify_openssl.c
@@ -14,11 +14,13 @@
#include "swupdate.h"
#include "sslapi.h"
#include "util.h"
-#include "swupdate_verify_private.h"
+#include "swupdate_crypto.h"
#define BUFSIZE (1024 * 8)
-EVP_PKEY *load_pubkey(const char *file)
+static swupdate_dgst_lib libs;
+
+static EVP_PKEY *load_pubkey(const char *file)
{
BIO *key=NULL;
EVP_PKEY *pkey=NULL;
@@ -103,7 +105,7 @@ static int verify_final(struct swupdate_digest *dgst, unsigned char *sig, unsign
return rc;
}
-int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+static int openssl_rsa_verify_file(struct swupdate_digest *dgst, const char *sigfile,
const char *file, const char *signer_name)
{
FILE *fp = NULL;
@@ -197,5 +199,65 @@ out:
return status;
}
+static int openssl_rsa_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
+{
+ struct swupdate_digest *dgst;
+ int ret;
+
+ /*
+ * Check that it was not called before
+ */
+ if (sw->dgst) {
+ return -EBUSY;
+ }
+
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ /*
+ * Load public key
+ */
+ dgst->pkey = load_pubkey(keyfile);
+ if (!dgst->pkey) {
+ ERROR("Error loading pub key from %s", keyfile);
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+ dgst->ckey = EVP_PKEY_CTX_new(dgst->pkey, NULL);
+ if (!dgst->ckey) {
+ ERROR("Error creating context key for %s", keyfile);
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+
+ /*
+ * Create context
+ */
+ dgst->ctx = EVP_MD_CTX_create();
+ if(dgst->ctx == NULL) {
+ ERROR("EVP_MD_CTX_create failed, error 0x%lx", ERR_get_error());
+ ret = -ENOMEM;
+ goto dgst_init_error;
+ }
+
+ sw->dgst = dgst;
+
+ return 0;
+dgst_init_error:
+ if (dgst)
+ free(dgst);
+ return ret;
+}
+
+__attribute__((constructor))
+static void openssl_dgst(void)
+{
+ libs.dgst_init = openssl_rsa_dgst_init;
+ libs.verify_file = openssl_rsa_verify_file;
+ (void)register_dgstlib("opensslRSA", &libs);
+}
--
2.43.0