diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index a2fb8620..5a8888e7 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -65,7 +65,9 @@ static OstreeGpgSignatureAttr all_signature_attrs[] = { OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME, OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, - OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY + OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY, }; static void ostree_gpg_verify_result_initable_iface_init (GInitableIface *iface); @@ -331,7 +333,9 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, { if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL || - attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY) + attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY || + attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP || + attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY) { (void) gpgme_get_key (result->context, signature->fpr, &key, 0); break; @@ -345,6 +349,7 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, GVariant *child; gboolean v_boolean; const char *v_string = NULL; + gint64 v_int64; switch (attrs[ii]) { @@ -423,6 +428,29 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, child = g_variant_new_string (v_string); break; + case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP: + v_int64 = 0; + if (key != NULL) + { + gpgme_subkey_t subkey = key->subkeys; + + while (subkey != NULL && (g_strcmp0 (subkey->fpr, signature->fpr) != 0)) + subkey = subkey->next; + + if (subkey != NULL) + v_int64 = subkey->expires; + } + child = g_variant_new_int64 (v_int64); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY: + if (key != NULL && key->subkeys != NULL) + v_int64 = key->subkeys->expires; + else + v_int64 = 0; + child = g_variant_new_int64 (v_int64); + break; + default: g_critical ("Invalid signature attribute (%d)", attrs[ii]); g_variant_builder_clear (&builder); @@ -581,6 +609,8 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, g_autofree char *formatted_date_time = NULL; gint64 timestamp; gint64 exp_timestamp; + gint64 key_exp_timestamp; + gint64 key_exp_timestamp_primary; const char *type_string; const char *fingerprint; const char *fingerprint_primary; @@ -590,6 +620,7 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, const char *key_id; gboolean valid; gboolean sig_expired; + gboolean key_expired; gboolean key_missing; gsize len; @@ -599,7 +630,7 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, /* Verify the variant's type string. This code is * not prepared to handle just any random GVariant. */ type_string = g_variant_get_type_string (variant); - g_return_if_fail (strcmp (type_string, "(bbbbbsxxsssss)") == 0); + g_return_if_fail (strcmp (type_string, "(bbbbbsxxsssssxx)") == 0); /* The default format roughly mimics the verify output generated by * check_sig_and_print() in gnupg/g10/mainproc.c, though obviously @@ -609,6 +640,8 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, "b", &valid); g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, "b", &sig_expired); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, + "b", &key_expired); g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, "b", &key_missing); g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT, @@ -625,6 +658,10 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, "&s", &user_name); g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, "&s", &user_email); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, + "x", &key_exp_timestamp); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY, + "x", &key_exp_timestamp_primary); len = strlen (fingerprint); key_id = (len > 16) ? fingerprint + len - 16 : fingerprint; @@ -697,6 +734,12 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, if (exp_timestamp > 0) append_expire_info (output_buffer, line_prefix, "Signature", exp_timestamp, sig_expired); + if (key_exp_timestamp > 0) + append_expire_info (output_buffer, line_prefix, "Key", key_exp_timestamp, + key_expired); + if (key_exp_timestamp_primary > 0 && (g_strcmp0 (fingerprint, fingerprint_primary) != 0)) + append_expire_info (output_buffer, line_prefix, "Primary key", + key_exp_timestamp_primary, key_expired); } /** diff --git a/src/libostree/ostree-gpg-verify-result.h b/src/libostree/ostree-gpg-verify-result.h index 0a77ec53..7c71ecdc 100644 --- a/src/libostree/ostree-gpg-verify-result.h +++ b/src/libostree/ostree-gpg-verify-result.h @@ -70,6 +70,14 @@ typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult; * (will be the same as OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT if the * the signature is already from the primary key rather than a subkey, * and will be the empty string if the key is missing.) + * @OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP: + * [#G_VARIANT_TYPE_INT64] Key expiration Unix timestamp (0 if no + * expiration or if the key is missing) + * @OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY: + * [#G_VARIANT_TYPE_INT64] Key expiration Unix timestamp of the signing key's + * primary key (will be the same as OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP + * if the signing key is the primary key and 0 if no expiration or if the key + * is missing) * * Signature attributes available from an #OstreeGpgVerifyResult. * The attribute's #GVariantType is shown in brackets. @@ -88,6 +96,8 @@ typedef enum { OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY, } OstreeGpgSignatureAttr; _OSTREE_PUBLIC diff --git a/tests/test-gpg-verify-result.c b/tests/test-gpg-verify-result.c index 19d6f71e..95de1873 100644 --- a/tests/test-gpg-verify-result.c +++ b/tests/test-gpg-verify-result.c @@ -45,7 +45,8 @@ static OstreeGpgSignatureAttr some_attributes[] = { OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, - OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING + OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, }; static void @@ -174,7 +175,7 @@ test_attribute_basics (TestFixture *fixture, tuple = ostree_gpg_verify_result_get_all (fixture->result, ii); type_string = g_variant_get_type_string (tuple); - g_assert_cmpstr (type_string, ==, "(bbbbbsxxsssss)"); + g_assert_cmpstr (type_string, ==, "(bbbbbsxxsssssxx)"); /* Check attributes which should be common to all signatures. */ @@ -221,24 +222,27 @@ test_valid_signature (TestFixture *fixture, gboolean key_expired; gboolean key_revoked; gboolean key_missing; + gint64 key_exp_timestamp; tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbb)", + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, - &key_missing); + &key_missing, + &key_exp_timestamp); g_assert_true (valid); g_assert_false (sig_expired); g_assert_false (key_expired); g_assert_false (key_revoked); g_assert_false (key_missing); + g_assert_cmpint (key_exp_timestamp, ==, 0); } static void @@ -252,24 +256,27 @@ test_expired_key (TestFixture *fixture, gboolean key_expired; gboolean key_revoked; gboolean key_missing; + gint64 key_exp_timestamp; tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbb)", + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, - &key_missing); + &key_missing, + &key_exp_timestamp); g_assert_false (valid); g_assert_false (sig_expired); g_assert_true (key_expired); g_assert_false (key_revoked); g_assert_false (key_missing); + g_assert_cmpint (key_exp_timestamp, ==, 1426782201); } static void @@ -283,24 +290,27 @@ test_revoked_key (TestFixture *fixture, gboolean key_expired; gboolean key_revoked; gboolean key_missing; + gint64 key_exp_timestamp; tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbb)", + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, - &key_missing); + &key_missing, + &key_exp_timestamp); g_assert_false (valid); g_assert_false (sig_expired); g_assert_false (key_expired); g_assert_true (key_revoked); g_assert_false (key_missing); + g_assert_cmpint (key_exp_timestamp, ==, 0); } static void @@ -314,24 +324,27 @@ test_missing_key (TestFixture *fixture, gboolean key_expired; gboolean key_revoked; gboolean key_missing; + gint64 key_exp_timestamp; tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbb)", + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, - &key_missing); + &key_missing, + &key_exp_timestamp); g_assert_false (valid); g_assert_false (sig_expired); g_assert_false (key_expired); g_assert_false (key_revoked); g_assert_true (key_missing); + g_assert_cmpint (key_exp_timestamp, ==, 0); } static void @@ -345,24 +358,27 @@ test_expired_signature (TestFixture *fixture, gboolean key_expired; gboolean key_revoked; gboolean key_missing; + gint64 key_exp_timestamp; tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbb)", + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, - &key_missing); + &key_missing, + &key_exp_timestamp); g_assert_true (valid); g_assert_true (sig_expired); g_assert_false (key_expired); g_assert_false (key_revoked); g_assert_false (key_missing); + g_assert_cmpint (key_exp_timestamp, ==, 0); } int