From 14047d7d24b9990036fec49e0c99f91e15ac0552 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Fri, 18 Aug 2017 10:58:47 +0100 Subject: [PATCH] trivial: Split up the keyring setup and public key adding --- data/pki/LVFS-CA.pem | 27 +++++++++++++++++++++++++ src/fu-engine.c | 8 ++++++-- src/fu-keyring-gpg.c | 21 ++++++++++++++------ src/fu-keyring-pkcs7.c | 45 +++++++++++++++++++++++++----------------- src/fu-keyring.c | 14 ++++++++++--- src/fu-keyring.h | 8 ++++++-- src/fu-self-test.c | 11 +++++++++-- 7 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 data/pki/LVFS-CA.pem diff --git a/data/pki/LVFS-CA.pem b/data/pki/LVFS-CA.pem new file mode 100644 index 000000000..8b82d3141 --- /dev/null +++ b/data/pki/LVFS-CA.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpzCCAw+gAwIBAgIBATANBgkqhkiG9w0BAQsFADA6MRAwDgYDVQQDEwdMVkZT +IENBMSYwJAYDVQQKEx1MaW51eCBWZW5kb3IgRmlybXdhcmUgUHJvamVjdDAeFw0x +NzA4MTgwOTA4NDNaFw0xODA4MTgwOTA4NDNaMDoxEDAOBgNVBAMTB0xWRlMgQ0Ex +JjAkBgNVBAoTHUxpbnV4IFZlbmRvciBGaXJtd2FyZSBQcm9qZWN0MIIBojANBgkq +hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA1Pgc6P9S15B3nFNWKcZm6DHGlve2q7M9 ++78Q/E0X6JwkFShC4RHxrc73TL8f9tV+F0CyZwsgb7BvurR7jAIBwby/T1feYZqo +McNmB7CkUeBlVC7pMV46h/1gkZDteGRzkwA4YRoSbDTcKzZQSqVEyFSnGCa7RsqH +MshEfYWZl7gxy6I2KhYAfOl9fUDfxeuvjvGDy55ilGEkabfHXy9q5TAT7rp/Rrvb +H/mq4iUbU9mvj9Khl96thvTewc7HA3hfYw+CUJPRUSvGMehgxwkCbbVWkA7B2E5z +mCblTqv0duy4+2664Jnm7CVJXQlJX2yPQOm/PF247iL9n7mjU8MlgYEcDEeGoRwQ +3FYgfU3gTRUKLBtzTWjQ1RXnLnCS51gXE95a0lPma5QaSQE7GReaHUEGKzglnrc/ +6dD7Wh/gE7WsGe6d3j2xwjYqR10+DB6z0DT7bm3miSkibQrGSeKRcKWD1liGlXIP +P4d9KFpN9dIDCWKvlcY5NakMtM/6/4yNAgMBAAGjgbcwgbQwDwYDVR0TAQH/BAUw +AwEB/zAwBgNVHREEKTAnhhVodHRwOi8vd3d3LmZ3dXBkLm9yZy+BDnNpZ25AZnd1 +cGQub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA8GA1UdDwEB/wQFAwMHBgAwHQYD +VR0OBBYEFDZoHeKph3x3vO5MXdOyLbbdInxWMCoGA1UdHwQjMCEwH6AdoBuGGWh0 +dHA6Ly93d3cuZnd1cGQub3JnL3BraS8wDQYJKoZIhvcNAQELBQADggGBAJaRJy8D +ayuBwSE/TVcyEv4h6s+1ou54ruZjkEWDLDqbBrwNbTzm52pKQ03HDR0OLrK+ndZH +xwC2ar7MyNe2CFgUFr/RaYD10DEYW/qWUjZLvAbE37AaoG0CevJSSd0KnSJzJU7t +T+ztHvSn9q8AJ20xVsP7OcAqBN3qx2yrj6qs70mtn2UjsqIOz6VOs81J24wk7nnl +LAOln7elsLGdOI2mg4jbJZGf1YnKYn+oCye7OCAX8LqQnMGkHj+ZyBGLgl4lJ+Oi +oaaf/xAf2BRT6iKqx5tTNkYUZSZcEJMgk2HWI2XoZCjPfQfwn+Mbt40JcBwqQ28b +l1fAe6lqC+8t1KmjgywvpyzsssaRJXFjnlgoSjnnQYfmmKoURxpX87NcVtwfV60Q +HC4ZyT+zlhgQASBDMrkwGQ8/F0h5WG+OxdM7tg62Y9gcpb/q3x5fttxut9MmQOCC +vgzuugW+pyW75+cg7UpLOM8eAudAmFtEteUb7H9FW+KyBEMfUboCOCVF5w== +-----END CERTIFICATE----- diff --git a/src/fu-engine.c b/src/fu-engine.c index 9839052cd..5eeca8dd3 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -364,7 +364,9 @@ fu_engine_get_release_trust_flags (AsRelease *release, kr = fu_engine_get_keyring_for_kind (keyring_kind, error); if (kr == NULL) return FALSE; - if (!fu_keyring_setup (kr, pki_dir, error)) + if (!fu_keyring_setup (kr, error)) + return FALSE; + if (!fu_keyring_add_public_keys (kr, pki_dir, error)) return FALSE; kr_result = fu_keyring_verify_data (kr, blob_payload, blob_signature, &error_local); if (kr_result == NULL) { @@ -1524,7 +1526,9 @@ fu_engine_update_metadata (FuEngine *self, const gchar *remote_id, kr = fu_engine_get_keyring_for_kind (keyring_kind, error); if (kr == NULL) return FALSE; - if (!fu_keyring_setup (kr, "/etc/pki/fwupd-metadata", error)) + if (!fu_keyring_setup (kr, error)) + return FALSE; + if (!fu_keyring_add_public_keys (kr, "/etc/pki/fwupd-metadata", error)) return FALSE; kr_result = fu_keyring_verify_data (kr, bytes_raw, bytes_sig, error); if (kr_result == NULL) diff --git a/src/fu-keyring-gpg.c b/src/fu-keyring-gpg.c index a24e26853..3e58edfcd 100644 --- a/src/fu-keyring-gpg.c +++ b/src/fu-keyring-gpg.c @@ -92,13 +92,11 @@ fu_keyring_gpg_add_public_key (FuKeyringGpg *self, } static gboolean -fu_keyring_gpg_setup (FuKeyring *keyring, const gchar *public_key_dir, GError **error) +fu_keyring_gpg_setup (FuKeyring *keyring, GError **error) { FuKeyringGpg *self = FU_KEYRING_GPG (keyring); - const gchar *fn_tmp; gpgme_error_t rc; g_autofree gchar *gpg_home = NULL; - g_autoptr(GDir) dir = NULL; if (self->ctx != NULL) return TRUE; @@ -166,20 +164,30 @@ fu_keyring_gpg_setup (FuKeyring *keyring, const gchar *public_key_dir, GError ** /* enable armor mode */ gpgme_set_armor (self->ctx, TRUE); + return TRUE; +} + +static gboolean +fu_keyring_gpg_add_public_keys (FuKeyring *keyring, + const gchar *path, + GError **error) +{ + FuKeyringGpg *self = FU_KEYRING_GPG (keyring); + const gchar *fn_tmp; + g_autoptr(GDir) dir = NULL; /* search all the public key files */ - dir = g_dir_open (public_key_dir, 0, error); + dir = g_dir_open (path, 0, error); if (dir == NULL) return FALSE; while ((fn_tmp = g_dir_read_name (dir)) != NULL) { g_autofree gchar *path_tmp = NULL; if (!g_str_has_prefix (fn_tmp, "GPG-KEY-")) continue; - path_tmp = g_build_filename (public_key_dir, fn_tmp, NULL); + path_tmp = g_build_filename (path, fn_tmp, NULL); if (!fu_keyring_gpg_add_public_key (self, path_tmp, error)) return FALSE; } - return TRUE; } @@ -327,6 +335,7 @@ fu_keyring_gpg_class_init (FuKeyringGpgClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); FuKeyringClass *klass_app = FU_KEYRING_CLASS (klass); klass_app->setup = fu_keyring_gpg_setup; + klass_app->add_public_keys = fu_keyring_gpg_add_public_keys; klass_app->verify_data = fu_keyring_gpg_verify_data; object_class->finalize = fu_keyring_gpg_finalize; } diff --git a/src/fu-keyring-pkcs7.c b/src/fu-keyring-pkcs7.c index 0503c4e37..00c8a477b 100644 --- a/src/fu-keyring-pkcs7.c +++ b/src/fu-keyring-pkcs7.c @@ -74,34 +74,21 @@ fu_keyring_pkcs7_add_public_key (FuKeyringPkcs7 *self, } static gboolean -fu_keyring_pkcs7_setup (FuKeyring *keyring, const gchar *public_key_dir, GError **error) +fu_keyring_pkcs7_add_public_keys (FuKeyring *keyring, + const gchar *path, + GError **error) { FuKeyringPkcs7 *self = FU_KEYRING_PKCS7 (keyring); const gchar *fn_tmp; - int rc; g_autoptr(GDir) dir = NULL; - if (self->tl != NULL) - return TRUE; - - /* create trust list, a bit like a keyring */ - rc = gnutls_x509_trust_list_init (&self->tl, 0); - if (rc != GNUTLS_E_SUCCESS) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_SIGNATURE_INVALID, - "failed to create trust list: %s [%i]", - gnutls_strerror (rc), rc); - return FALSE; - } - /* search all the public key files */ - dir = g_dir_open (public_key_dir, 0, error); + dir = g_dir_open (path, 0, error); if (dir == NULL) return FALSE; while ((fn_tmp = g_dir_read_name (dir)) != NULL) { g_autofree gchar *path_tmp = NULL; - path_tmp = g_build_filename (public_key_dir, fn_tmp, NULL); + path_tmp = g_build_filename (path, fn_tmp, NULL); if (g_str_has_suffix (fn_tmp, ".pem")) { if (!fu_keyring_pkcs7_add_public_key (self, path_tmp, GNUTLS_X509_FMT_PEM, @@ -117,7 +104,28 @@ fu_keyring_pkcs7_setup (FuKeyring *keyring, const gchar *public_key_dir, GError return FALSE; } } + return TRUE; +} +static gboolean +fu_keyring_pkcs7_setup (FuKeyring *keyring, GError **error) +{ + FuKeyringPkcs7 *self = FU_KEYRING_PKCS7 (keyring); + int rc; + + if (self->tl != NULL) + return TRUE; + + /* create trust list, a bit like a keyring */ + rc = gnutls_x509_trust_list_init (&self->tl, 0); + if (rc != GNUTLS_E_SUCCESS) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_SIGNATURE_INVALID, + "failed to create trust list: %s [%i]", + gnutls_strerror (rc), rc); + return FALSE; + } return TRUE; } @@ -260,6 +268,7 @@ fu_keyring_pkcs7_class_init (FuKeyringPkcs7Class *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); FuKeyringClass *klass_app = FU_KEYRING_CLASS (klass); klass_app->setup = fu_keyring_pkcs7_setup; + klass_app->add_public_keys = fu_keyring_pkcs7_add_public_keys; klass_app->verify_data = fu_keyring_pkcs7_verify_data; object_class->finalize = fu_keyring_pkcs7_finalize; } diff --git a/src/fu-keyring.c b/src/fu-keyring.c index 430da53df..0aabb164d 100644 --- a/src/fu-keyring.c +++ b/src/fu-keyring.c @@ -33,12 +33,20 @@ G_DEFINE_TYPE_WITH_PRIVATE (FuKeyring, fu_keyring, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fu_keyring_get_instance_private (o)) gboolean -fu_keyring_setup (FuKeyring *keyring, const gchar *public_key_dir, GError **error) +fu_keyring_setup (FuKeyring *keyring, GError **error) { FuKeyringClass *klass = FU_KEYRING_GET_CLASS (keyring); g_return_val_if_fail (FU_IS_KEYRING (keyring), FALSE); - g_return_val_if_fail (public_key_dir != NULL, FALSE); - return klass->setup (keyring, public_key_dir, error); + return klass->setup (keyring, error); +} + +gboolean +fu_keyring_add_public_keys (FuKeyring *keyring, const gchar *path, GError **error) +{ + FuKeyringClass *klass = FU_KEYRING_GET_CLASS (keyring); + g_return_val_if_fail (FU_IS_KEYRING (keyring), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + return klass->add_public_keys (keyring, path, error); } FuKeyringResult * diff --git a/src/fu-keyring.h b/src/fu-keyring.h index 103e6c587..43e8037a9 100644 --- a/src/fu-keyring.h +++ b/src/fu-keyring.h @@ -36,7 +36,9 @@ struct _FuKeyringClass { GObjectClass parent_class; gboolean (*setup) (FuKeyring *keyring, - const gchar *public_key_dir, + GError **error); + gboolean (*add_public_keys) (FuKeyring *keyring, + const gchar *path, GError **error); FuKeyringResult *(*verify_data) (FuKeyring *keyring, GBytes *payload, @@ -45,7 +47,9 @@ struct _FuKeyringClass }; gboolean fu_keyring_setup (FuKeyring *keyring, - const gchar *public_key_dir, + GError **error); +gboolean fu_keyring_add_public_keys (FuKeyring *keyring, + const gchar *path, GError **error); FuKeyringResult *fu_keyring_verify_data (FuKeyring *keyring, GBytes *blob, diff --git a/src/fu-self-test.c b/src/fu-self-test.c index fb47878c0..9bce8dfb9 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -405,8 +405,12 @@ fu_keyring_gpg_func (void) /* add keys to keyring */ keyring = fu_keyring_gpg_new (); + ret = fu_keyring_setup (keyring, &error); + g_assert_no_error (error); + g_assert_true (ret); pki_dir = fu_test_get_filename (TESTDATADIR, "pki"); - ret = fu_keyring_setup (keyring, pki_dir, &error); + g_assert_nonnull (pki_dir); + ret = fu_keyring_add_public_keys (keyring, pki_dir, &error); g_assert_no_error (error); g_assert_true (ret); @@ -458,9 +462,12 @@ fu_keyring_pkcs7_func (void) /* add keys to keyring */ keyring = fu_keyring_pkcs7_new (); + ret = fu_keyring_setup (keyring, &error); + g_assert_no_error (error); + g_assert_true (ret); pki_dir = fu_test_get_filename (TESTDATADIR_DST, "pki"); g_assert_nonnull (pki_dir); - ret = fu_keyring_setup (keyring, pki_dir, &error); + ret = fu_keyring_add_public_keys (keyring, pki_dir, &error); g_assert_no_error (error); g_assert_true (ret);