pull: Do GPG verify commit objects when using deltas
The fact that we weren't doing this is at best an oversight, and for some deployment models a security vulnerability. Having both `gpg-verify` and `gpg-verify-summary` shows that we were intending them to be orthogonal/independent. Lately I've been advocating moving towards pinned TLS instead of gpg-signed summaries, and if we follow that path, performing GPG verification of commit objects even if using deltas is more important, as it provides an at-rest verifiable authenticity and integrity mechanism. Content providers which are signing their summary files and/or using TLS (particularly pinned TLS) for transport should treat this as a nice-to-have. However, for providers which are serving content over plain HTTP and relying on GPG, this is a critical update. Closes: https://github.com/ostreedev/ostree/issues/517 Closes: #589 Approved by: jlebon
This commit is contained in:
1 parent
cb57338a12
commit
41ef2aeb38
2 files changed
+94
-14
No files matched your search
@@ -1027,6 +1027,57 @@ static_deltapart_fetch_on_complete (GObject *object,
|
||||
fetch_static_delta_data_free (fetch_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_verify_result (OtPullData *pull_data,
|
||||
const char *checksum,
|
||||
OstreeGpgVerifyResult *result,
|
||||
GError **error)
|
||||
{
|
||||
if (result == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Allow callers to output the results immediately. */
|
||||
g_signal_emit_by_name (pull_data->repo,
|
||||
"gpg-verify-result",
|
||||
checksum, result);
|
||||
|
||||
return ostree_gpg_verify_result_require_valid_signature (result, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gpg_verify_unwritten_commit (OtPullData *pull_data,
|
||||
const char *checksum,
|
||||
GVariant *commit,
|
||||
GVariant *detached_metadata,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
if (pull_data->gpg_verify)
|
||||
{
|
||||
glnx_unref_object OstreeGpgVerifyResult *result = NULL;
|
||||
g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit);
|
||||
|
||||
if (!detached_metadata)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No detached metadata found for GPG verification");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
result = _ostree_repo_gpg_verify_with_metadata (pull_data->repo,
|
||||
signed_data,
|
||||
detached_metadata,
|
||||
pull_data->remote_name,
|
||||
NULL, NULL,
|
||||
cancellable,
|
||||
error);
|
||||
if (!process_verify_result (pull_data, checksum, result, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scan_commit_object (OtPullData *pull_data,
|
||||
const char *checksum,
|
||||
@@ -1075,16 +1126,7 @@ scan_commit_object (OtPullData *pull_data,
|
||||
pull_data->remote_name,
|
||||
cancellable,
|
||||
error);
|
||||
|
||||
if (result == NULL)
|
||||
goto out;
|
||||
|
||||
/* Allow callers to output the results immediately. */
|
||||
g_signal_emit_by_name (pull_data->repo,
|
||||
"gpg-verify-result",
|
||||
checksum, result);
|
||||
|
||||
if (!ostree_gpg_verify_result_require_valid_signature (result, error))
|
||||
if (!process_verify_result (pull_data, checksum, result, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1563,7 +1605,6 @@ process_one_static_delta (OtPullData *pull_data,
|
||||
{
|
||||
g_autoptr(GVariant) to_csum_v = NULL;
|
||||
g_autofree char *to_checksum = NULL;
|
||||
g_autoptr(GVariant) to_commit = NULL;
|
||||
gboolean have_to_commit;
|
||||
|
||||
to_csum_v = g_variant_get_child_value (delta_superblock, 3);
|
||||
@@ -1578,10 +1619,16 @@ process_one_static_delta (OtPullData *pull_data,
|
||||
if (!have_to_commit)
|
||||
{
|
||||
FetchObjectData *fetch_data;
|
||||
g_autoptr(GVariant) to_commit = g_variant_get_child_value (delta_superblock, 4);
|
||||
g_autofree char *detached_path = _ostree_get_relative_static_delta_path (from_revision, to_revision, "commitmeta");
|
||||
g_autoptr(GVariant) detached_data = NULL;
|
||||
|
||||
detached_data = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE("a{sv}"));
|
||||
|
||||
if (!gpg_verify_unwritten_commit (pull_data, to_revision, to_commit, detached_data,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (detached_data && !ostree_repo_write_commit_detached_metadata (pull_data->repo,
|
||||
to_revision,
|
||||
detached_data,
|
||||
@@ -1595,8 +1642,6 @@ process_one_static_delta (OtPullData *pull_data,
|
||||
fetch_data->is_detached_meta = FALSE;
|
||||
fetch_data->object_is_stored = FALSE;
|
||||
|
||||
to_commit = g_variant_get_child_value (delta_superblock, 4);
|
||||
|
||||
ostree_repo_write_metadata_async (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, to_checksum,
|
||||
to_commit,
|
||||
pull_data->cancellable,
|
||||
|
||||
Reference in new issue
Block a user