mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
fix: ensure public key signatures are not in the past compared to the public key
We use the timestamp of the latest transport modification as the timestamp of the Direct Key Signature. However, first transport is created before the public key and existing transports may even have zero timestamp if they were created before migration 142. For interoperability with Sequoia-PGP, make sure signatures always have a timestamp that is not in the past compared to the timestamp of the primary key.
This commit is contained in:
31
src/key.rs
31
src/key.rs
@@ -131,7 +131,13 @@ pub(crate) fn secret_key_to_public_key(
|
||||
relay_addrs: &str,
|
||||
) -> Result<SignedPublicKey> {
|
||||
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<Vec<Subpacket>> {
|
||||
@@ -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<SignedSecretKey> = 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![
|
||||
|
||||
Reference in New Issue
Block a user