summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Nicholson <nicholson@endlessm.com>2019-06-15 09:56:44 -0500
committerDan Nicholson <nicholson@endlessm.com>2020-01-24 13:02:17 -0700
commit0fbfc0b2079f32b919ae6b804bda40332e03b618 (patch)
treeb1d4eb254f500dcbd14a948b6b231748e1f6363d
parent2c24f28ce45fe9c416650f004e30bcb97c76e0f0 (diff)
downloadostree-0fbfc0b2079f32b919ae6b804bda40332e03b618.tar.gz
lib/gpg: Add more specific OstreeGpgError codes
Currently `ostree_gpg_verify_result_require_valid_signature` always returns an error that the key used for the signature is missing from the keyring. However, all that's been determined is that there are no valid signatures. The error could also be from an expired signature, an expired key, a revoked key or an invalid signature. Provide values for these missing errors and return them from `ostree_gpg_verify_result_require_valid_signature`. The description of each result is appended to the error message, but since the result can contain more than one signature but only a single error can be returned, the status of the last signature is used for the error code. See the comment for rationale. Related: flatpak/flatpak#1450
-rw-r--r--src/libostree/ostree-gpg-verify-result.c54
-rw-r--r--src/libostree/ostree-gpg-verify-result.h8
-rwxr-xr-xtests/test-pull-summary-sigs.sh2
-rwxr-xr-xtests/test-remote-gpg-import.sh6
4 files changed, 64 insertions, 6 deletions
diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c
index 63c3394a..67270c82 100644
--- a/src/libostree/ostree-gpg-verify-result.c
+++ b/src/libostree/ostree-gpg-verify-result.c
@@ -769,8 +769,58 @@ ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result,
if (ostree_gpg_verify_result_count_valid (result) == 0)
{
- g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY,
- "GPG signatures found, but none are in trusted keyring");
+ /*
+ * Join the description of each failed signature for the error message.
+ * Only one error code can be returned, so if there was more than one
+ * signature, use the error of the last one under the assumption that
+ * it's the most recent and hopefully most likely to be made with a
+ * valid key.
+ */
+ gint code = OSTREE_GPG_ERROR_NO_SIGNATURE;
+ g_autoptr(GString) buffer = g_string_sized_new (256);
+ guint nsigs = ostree_gpg_verify_result_count_all (result);
+
+ if (nsigs == 0)
+ /* In case an empty result was passed in */
+ g_string_append (buffer, "No GPG signatures found");
+ else
+ {
+ for (int i = nsigs - 1; i >= 0; i--)
+ {
+ g_autoptr(GVariant) info = ostree_gpg_verify_result_get_all (result, i);
+ ostree_gpg_verify_result_describe_variant (info, buffer, "",
+ OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
+
+ if (i == nsigs - 1)
+ {
+ gboolean key_missing, key_revoked, key_expired, sig_expired;
+ g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING,
+ "b", &key_missing);
+ g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED,
+ "b", &key_revoked);
+ g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED,
+ "b", &key_expired);
+ g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED,
+ "b", &sig_expired);
+
+ if (key_missing)
+ code = OSTREE_GPG_ERROR_MISSING_KEY;
+ else if (key_revoked)
+ code = OSTREE_GPG_ERROR_REVOKED_KEY;
+ else if (key_expired)
+ code = OSTREE_GPG_ERROR_EXPIRED_KEY;
+ else if (sig_expired)
+ code = OSTREE_GPG_ERROR_EXPIRED_SIGNATURE;
+ else
+ /* Assume any other issue is a bad signature */
+ code = OSTREE_GPG_ERROR_INVALID_SIGNATURE;
+ }
+ }
+ }
+
+ /* Strip any trailing newlines */
+ g_strchomp (buffer->str);
+ g_set_error_literal (error, OSTREE_GPG_ERROR, code, buffer->str);
return FALSE;
}
diff --git a/src/libostree/ostree-gpg-verify-result.h b/src/libostree/ostree-gpg-verify-result.h
index 7c71ecdc..f71ab981 100644
--- a/src/libostree/ostree-gpg-verify-result.h
+++ b/src/libostree/ostree-gpg-verify-result.h
@@ -159,6 +159,11 @@ gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult
* @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found.
* @OSTREE_GPG_ERROR_INVALID_SIGNATURE: A signature was malformed.
* @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the configured keyrings.
+ * @OSTREE_GPG_ERROR_EXPIRED_SIGNATURE: A signature was expired. Since: 2019.7.
+ * @OSTREE_GPG_ERROR_EXPIRED_KEY: A signature was found, but the key used to
+ * sign it has expired. Since: 2019.7.
+ * @OSTREE_GPG_ERROR_REVOKED_KEY: A signature was found, but the key used to
+ * sign it has been revoked. Since: 2019.7.
*
* Errors returned by signature creation and verification operations in OSTree.
* These may be returned by any API which creates or verifies signatures.
@@ -169,6 +174,9 @@ typedef enum {
OSTREE_GPG_ERROR_NO_SIGNATURE = 0,
OSTREE_GPG_ERROR_INVALID_SIGNATURE,
OSTREE_GPG_ERROR_MISSING_KEY,
+ OSTREE_GPG_ERROR_EXPIRED_SIGNATURE,
+ OSTREE_GPG_ERROR_EXPIRED_KEY,
+ OSTREE_GPG_ERROR_REVOKED_KEY,
} OstreeGpgError;
/**
diff --git a/tests/test-pull-summary-sigs.sh b/tests/test-pull-summary-sigs.sh
index 821ae953..401e88c9 100755
--- a/tests/test-pull-summary-sigs.sh
+++ b/tests/test-pull-summary-sigs.sh
@@ -189,7 +189,7 @@ cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.2,}
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
assert_not_reached "Successful pull with old summary"
fi
-assert_file_has_content err.txt "none are in trusted keyring"
+assert_file_has_content err.txt "BAD signature"
assert_has_file repo/tmp/cache/summaries/origin
assert_has_file repo/tmp/cache/summaries/origin.sig
cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2
diff --git a/tests/test-remote-gpg-import.sh b/tests/test-remote-gpg-import.sh
index 4d73fa11..b8673852 100755
--- a/tests/test-remote-gpg-import.sh
+++ b/tests/test-remote-gpg-import.sh
@@ -163,7 +163,7 @@ ${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/key1.asc,${test_tmp
if ${OSTREE} pull R8:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling with different key"
fi
-assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring"
+assert_file_has_content err.txt "public key not found"
# Test gpgkeypath success with directory containing a valid key
${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/ R9 $(cat httpd-address)/ostree/gnomerepo
@@ -243,7 +243,7 @@ ${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/key2.asc R6 $(cat h
if ${OSTREE} pull R6:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling with different key"
fi
-assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring"
+assert_file_has_content err.txt "public key not found"
echo "ok"
@@ -269,7 +269,7 @@ newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo rev-par
if ${OSTREE} pull --require-static-deltas R1:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling commit signed with untrusted key"
fi
-assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring"
+assert_file_has_content err.txt "public key not found"
echo "ok gpg untrusted signed commit for delta upgrades"