diff --git a/src/key.rs b/src/key.rs index ff088a1c5..1f9febb9e 100644 --- a/src/key.rs +++ b/src/key.rs @@ -131,7 +131,13 @@ pub(crate) fn secret_key_to_public_key( relay_addrs: &str, ) -> Result { info!(context, "Converting secret key to public key."); - let timestamp = pgp::types::Timestamp::from_secs(timestamp); + + // Make sure timestamp of created signatures + // is not in the past compared to the primary key timestamp. + let timestamp = std::cmp::max( + signed_secret_key.primary_key.created_at(), + pgp::types::Timestamp::from_secs(timestamp), + ); // Subpackets that we want to share between DKS and User ID signature. let common_subpackets = || -> Result> { @@ -650,10 +656,12 @@ impl std::str::FromStr for Fingerprint { #[cfg(test)] mod tests { use std::sync::{Arc, LazyLock}; + use std::time::Duration; use super::*; use crate::config::Config; - use crate::test_utils::{TestContext, alice_keypair}; + use crate::test_utils::{TestContext, TestContextManager, alice_keypair}; + use crate::tools::SystemTime; static KEYPAIR: LazyLock = LazyLock::new(alice_keypair); @@ -874,6 +882,25 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD assert_eq!(nrows().await, 1); } + /// Tests that key signature timestamp + /// is not in the past compared to the primary key creation timestamp. + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_signature_not_in_the_past() -> Result<()> { + let mut tcm = TestContextManager::new(); + + let t = &tcm.unconfigured().await; + t.configure_addr("foo@example.org").await; + + SystemTime::shift(Duration::from_secs(600)); + + let key = load_self_public_key(t).await?; + assert!( + key.details.direct_signatures[0].created().unwrap() >= key.primary_key.created_at() + ); + + Ok(()) + } + #[test] fn test_fingerprint_from_str() { let res = Fingerprint::new(vec![