chore: update rPGP from 0.19.0 to 0.20.0

This commit is contained in:
link2xt
2026-06-24 02:42:51 +00:00
committed by l
parent b38277c294
commit 09d5d0bddf
5 changed files with 75 additions and 34 deletions

52
Cargo.lock generated
View File

@@ -1710,7 +1710,7 @@ dependencies = [
"libc", "libc",
"option-ext", "option-ext",
"redox_users", "redox_users",
"windows-sys 0.59.0", "windows-sys 0.61.1",
] ]
[[package]] [[package]]
@@ -2733,7 +2733,7 @@ dependencies = [
"hyper", "hyper",
"libc", "libc",
"pin-project-lite", "pin-project-lite",
"socket2 0.5.9", "socket2 0.6.3",
"tokio", "tokio",
"tower-service", "tower-service",
"tracing", "tracing",
@@ -3154,7 +3154,7 @@ dependencies = [
"iroh-metrics-derive", "iroh-metrics-derive",
"itoa", "itoa",
"serde", "serde",
"snafu", "snafu 0.8.5",
"tracing", "tracing",
] ]
@@ -3524,9 +3524,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]] [[package]]
name = "mime" name = "mime"
@@ -3792,7 +3792,7 @@ dependencies = [
"netlink-proto", "netlink-proto",
"netlink-sys", "netlink-sys",
"serde", "serde",
"snafu", "snafu 0.8.5",
"socket2 0.5.9", "socket2 0.5.9",
"time", "time",
"tokio", "tokio",
@@ -3880,7 +3880,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.61.1",
] ]
[[package]] [[package]]
@@ -4284,9 +4284,9 @@ dependencies = [
[[package]] [[package]]
name = "pgp" name = "pgp"
version = "0.19.0" version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaffe1ec22db286599c30ae6be75b37493b558735d86c8e59ec5c38794415fe4" checksum = "1cfa4743b28656065ff4c0ba09e46b357a65e8c00fc2341e89084b82f87cbdf1"
dependencies = [ dependencies = [
"aead", "aead",
"aes", "aes",
@@ -4325,6 +4325,7 @@ dependencies = [
"k256", "k256",
"log", "log",
"md-5", "md-5",
"memchr",
"ml-dsa", "ml-dsa",
"ml-kem", "ml-kem",
"nom 8.0.0", "nom 8.0.0",
@@ -4336,7 +4337,6 @@ dependencies = [
"p384", "p384",
"p521", "p521",
"rand 0.8.6", "rand 0.8.6",
"regex",
"replace_with", "replace_with",
"ripemd", "ripemd",
"rsa", "rsa",
@@ -4347,7 +4347,8 @@ dependencies = [
"signature", "signature",
"slh-dsa", "slh-dsa",
"smallvec", "smallvec",
"snafu", "snafu 0.9.1",
"subtle",
"twofish", "twofish",
"x25519-dalek", "x25519-dalek",
"zeroize", "zeroize",
@@ -4586,7 +4587,7 @@ dependencies = [
"rand 0.8.6", "rand 0.8.6",
"serde", "serde",
"smallvec", "smallvec",
"snafu", "snafu 0.8.5",
"socket2 0.5.9", "socket2 0.5.9",
"time", "time",
"tokio", "tokio",
@@ -5281,7 +5282,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.12.1", "linux-raw-sys 0.12.1",
"windows-sys 0.52.0", "windows-sys 0.61.1",
] ]
[[package]] [[package]]
@@ -5849,7 +5850,16 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019"
dependencies = [ dependencies = [
"snafu-derive", "snafu-derive 0.8.5",
]
[[package]]
name = "snafu"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1a012328be2e3f5d5f6f3218147ca02588cea4cb865e876849ab6debcf36522"
dependencies = [
"snafu-derive 0.9.1",
] ]
[[package]] [[package]]
@@ -5864,6 +5874,18 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "snafu-derive"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f103c50866b8743da9429b8a581d81a27c2d3a9c4ac7df8f8571c1dd7896eda"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.9" version = "0.5.9"
@@ -6147,7 +6169,7 @@ dependencies = [
"getrandom 0.3.3", "getrandom 0.3.3",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"windows-sys 0.52.0", "windows-sys 0.61.1",
] ]
[[package]] [[package]]

View File

@@ -78,7 +78,7 @@ num-derive = "0.4"
num-traits = { workspace = true } num-traits = { workspace = true }
parking_lot = "0.12.4" parking_lot = "0.12.4"
percent-encoding = "2.3" percent-encoding = "2.3"
pgp = { version = "0.19.0", features = ["draft-pqc"], default-features = false } pgp = { version = "0.20.0", features = ["draft-pqc"], default-features = false }
pin-project = "1" pin-project = "1"
qrcodegen = "1.7.0" qrcodegen = "1.7.0"
quick-xml = { version = "0.39", features = ["escape-html"] } quick-xml = { version = "0.39", features = ["escape-html"] }

View File

@@ -83,6 +83,8 @@ skip = [
{ name = "rustix", version = "0.38.44" }, { name = "rustix", version = "0.38.44" },
{ name = "rustls-webpki", version = "0.102.8" }, { name = "rustls-webpki", version = "0.102.8" },
{ name = "serdect", version = "0.2.0" }, { name = "serdect", version = "0.2.0" },
{ name = "snafu-derive", version = "0.8.5" },
{ name = "snafu", version = "0.8.5" },
{ name = "socket2", version = "0.5.9" }, { name = "socket2", version = "0.5.9" },
{ name = "spin", version = "0.9.8" }, { name = "spin", version = "0.9.8" },
{ name = "strum_macros", version = "0.26.2" }, { name = "strum_macros", version = "0.26.2" },

View File

@@ -6,13 +6,16 @@ use std::io::Cursor;
use anyhow::{Context as _, Result, bail}; use anyhow::{Context as _, Result, bail};
use mailparse::ParsedMail; use mailparse::ParsedMail;
use pgp::composed::DecryptionOptions;
use pgp::composed::Esk; use pgp::composed::Esk;
use pgp::composed::Message; use pgp::composed::Message;
use pgp::composed::PlainSessionKey; use pgp::composed::PlainSessionKey;
use pgp::composed::SignedSecretKey; use pgp::composed::SignedSecretKey;
use pgp::composed::TheRing;
use pgp::composed::decrypt_session_key_with_password; use pgp::composed::decrypt_session_key_with_password;
use pgp::packet::SymKeyEncryptedSessionKey; use pgp::packet::SymKeyEncryptedSessionKey;
use pgp::types::Password; use pgp::types::Password;
use pgp::types::Seipdv1ReadMode;
use pgp::types::StringToKey; use pgp::types::StringToKey;
use crate::chat::ChatId; use crate::chat::ChatId;
@@ -48,6 +51,15 @@ pub(crate) async fn decrypt(
}; };
let expected_sender_fingerprint: Option<String>; let expected_sender_fingerprint: Option<String>;
let abort_early = true;
// Use streaming mode for SEIPDv1 decryption to save memory.
// This was the default in rPGP 0.19.0
// and requires explicitly changing the mode in rPGP 0.20.0.
// SEPIDv2 is decrypted in streaming mode in any case.
let decrypt_options =
DecryptionOptions::new().set_seipdv1_read_mode(Seipdv1ReadMode::Streaming);
let plain = if let Message::Encrypted { esk, .. } = &*msg let plain = if let Message::Encrypted { esk, .. } = &*msg
// We only allow one ESK for symmetrically encrypted messages // We only allow one ESK for symmetrically encrypted messages
// to avoid dealing with messages that are encrypted to multiple symmetric keys // to avoid dealing with messages that are encrypted to multiple symmetric keys
@@ -61,9 +73,15 @@ pub(crate) async fn decrypt(
expected_sender_fingerprint = fingerprint; expected_sender_fingerprint = fingerprint;
tokio::task::spawn_blocking(move || -> Result<Message<'_>> { tokio::task::spawn_blocking(move || -> Result<Message<'_>> {
let plain = msg let ring = TheRing {
.decrypt_with_session_key(psk) session_keys: vec![psk],
.context("decrypt_with_session_key")?; decrypt_options,
..Default::default()
};
let (plain, _ring_result) = msg
.decrypt_the_ring(ring, abort_early)
.context("decrypt_the_ring")?;
let plain: Message<'static> = plain.decompress()?; let plain: Message<'static> = plain.decompress()?;
Ok(plain) Ok(plain)
@@ -75,11 +93,15 @@ pub(crate) async fn decrypt(
expected_sender_fingerprint = None; expected_sender_fingerprint = None;
tokio::task::spawn_blocking(move || -> Result<Message<'_>> { tokio::task::spawn_blocking(move || -> Result<Message<'_>> {
let empty_pw = Password::empty();
let secret_keys: Vec<&SignedSecretKey> = secret_keys.iter().collect(); let secret_keys: Vec<&SignedSecretKey> = secret_keys.iter().collect();
let plain = msg let ring = TheRing {
.decrypt_with_keys(vec![&empty_pw], secret_keys) secret_keys,
.context("decrypt_with_keys")?; decrypt_options,
..Default::default()
};
let (plain, _ring_result) = msg
.decrypt_the_ring(ring, abort_early)
.context("decrypt_the_ring")?;
let plain: Message<'static> = plain.decompress()?; let plain: Message<'static> = plain.decompress()?;
Ok(plain) Ok(plain)

View File

@@ -34,7 +34,7 @@ const SYMMETRIC_KEY_ALGORITHM: SymmetricKeyAlgorithm = SymmetricKeyAlgorithm::AE
/// as [described in the Autocrypt standard](https://autocrypt.org/level1.html#openpgp-based-key-data). /// as [described in the Autocrypt standard](https://autocrypt.org/level1.html#openpgp-based-key-data).
pub(crate) fn create_keypair(addr: EmailAddress) -> Result<SignedSecretKey> { pub(crate) fn create_keypair(addr: EmailAddress) -> Result<SignedSecretKey> {
let signing_key_type = PgpKeyType::Ed25519Legacy; let signing_key_type = PgpKeyType::Ed25519Legacy;
let encryption_key_type = PgpKeyType::ECDH(ECCCurve::Curve25519); let encryption_key_type = PgpKeyType::ECDH(ECCCurve::Curve25519Legacy);
let user_id = format!("<{addr}>"); let user_id = format!("<{addr}>");
let key_params = SecretKeyParamsBuilder::default() let key_params = SecretKeyParamsBuilder::default()
@@ -371,10 +371,7 @@ pub fn merge_openpgp_certificates(
.into_iter() .into_iter()
.chain(new_direct_signatures) .chain(new_direct_signatures)
.filter(|x: &Signature| x.verify_key(&old_primary_key).is_ok()) .filter(|x: &Signature| x.verify_key(&old_primary_key).is_ok())
.max_by_key(|x: &Signature| .max_by_key(|x: &Signature| x.created());
// Converting to seconds because `Ord` is not derived for `Timestamp`:
// <https://github.com/rpgp/rpgp/issues/737>
x.created().map_or(0, |ts| ts.as_secs()));
let direct_signatures: Vec<Signature> = best_direct_key_signature.into_iter().collect(); let direct_signatures: Vec<Signature> = best_direct_key_signature.into_iter().collect();
// Select at most one User ID. // Select at most one User ID.
@@ -396,12 +393,10 @@ pub fn merge_openpgp_certificates(
.verify_certification(&old_primary_key, pgp::types::Tag::UserId, &id) .verify_certification(&old_primary_key, pgp::types::Tag::UserId, &id)
.is_ok() .is_ok()
}) })
.max_by_key(|signature: &Signature| { .max_by_key(|signature: &Signature| signature.created());
signature.created().map_or(0, |ts| ts.as_secs())
});
best_user_signature.map(|signature| (id, signature)) best_user_signature.map(|signature| (id, signature))
}) })
.max_by_key(|(_id, signature)| signature.created().map_or(0, |ts| ts.as_secs())) .max_by_key(|(_id, signature)| signature.created())
.map(|(id, signature)| SignedUser { .map(|(id, signature)| SignedUser {
id, id,
signatures: vec![signature], signatures: vec![signature],
@@ -707,7 +702,7 @@ mod tests {
// This error message is actually not great, // This error message is actually not great,
// but grepping for it will lead to the correct code // but grepping for it will lead to the correct code
test_dont_decrypt_expensive_message_ex(s2k, true, Some("decrypt_with_keys: missing key")) test_dont_decrypt_expensive_message_ex(s2k, true, Some("decrypt_the_ring: missing key"))
.await .await
} }
@@ -790,7 +785,7 @@ mod tests {
.await .await
.unwrap_err(); .unwrap_err();
assert_eq!(format!("{error:#}"), "decrypt_with_keys: missing key"); assert_eq!(format!("{error:#}"), "decrypt_the_ring: missing key");
Ok(()) Ok(())
} }