diff --git a/Cargo.lock b/Cargo.lock index 4428fbe046..88c7c02f28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,6 +53,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "aes-kw" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fa2b352dcefb5f7f3a5fb840e02665d311d878955380515e4fd50095dd3d8c" +dependencies = [ + "aes", +] + [[package]] name = "ahash" version = "0.8.11" @@ -1215,7 +1224,7 @@ dependencies = [ "cpufeatures", "curve25519-dalek-derive", "digest", - "fiat-crypto", + "fiat-crypto 0.2.6", "rustc_version", "subtle", "zeroize", @@ -1760,6 +1769,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed448-goldilocks" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87b5fa9e9e3dd5fe1369f380acd3dcdfa766dbd0a1cd5b048fb40e38a6a78e79" +dependencies = [ + "fiat-crypto 0.1.20", + "hex", + "subtle", +] + [[package]] name = "either" version = "1.10.0" @@ -2125,6 +2145,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + [[package]] name = "fiat-crypto" version = "0.2.6" @@ -3095,7 +3121,7 @@ dependencies = [ "netlink-packet-route", "netlink-sys", "netwatch", - "num_enum", + "num_enum 0.7.3", "once_cell", "parking_lot", "pin-project", @@ -3850,13 +3876,34 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + [[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.7.3", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -3865,7 +3912,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 2.0.86", @@ -4162,14 +4209,15 @@ dependencies = [ [[package]] name = "pgp" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6c842436d5fa2b59eac1e9b3d142b50bfff99c1744c816b1f4c2ac55a20754" +checksum = "49bb5f77aaf8ae1ed6fe63387ad513b10cd44716fd053ecc227b9493c096cdb2" dependencies = [ "aes", "aes-gcm", + "aes-kw", "argon2", - "base64 0.22.1", + "base64 0.21.7", "bitfield", "block-padding", "blowfish", @@ -4185,6 +4233,7 @@ dependencies = [ "crc24", "curve25519-dalek", "derive_builder", + "derive_more", "des", "digest", "dsa", @@ -4204,7 +4253,7 @@ dependencies = [ "nom", "num-bigint-dig", "num-traits", - "num_enum", + "num_enum 0.5.11", "ocb3", "p256", "p384", @@ -4221,6 +4270,7 @@ dependencies = [ "thiserror", "twofish", "x25519-dalek", + "x448", "zeroize", ] @@ -4437,7 +4487,7 @@ dependencies = [ "iroh-metrics", "libc", "netwatch", - "num_enum", + "num_enum 0.7.3", "rand 0.8.5", "serde", "smallvec", @@ -4539,13 +4589,23 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + [[package]] name = "proc-macro-crate" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit", + "toml_edit 0.22.20", ] [[package]] @@ -6339,7 +6399,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.20", ] [[package]] @@ -6351,6 +6411,17 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.20" @@ -6361,7 +6432,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.18", ] [[package]] @@ -7095,6 +7166,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.6.18" @@ -7150,6 +7230,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x448" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd07d4fae29e07089dbcacf7077cd52dce7760125ca9a4dd5a35ca603ffebb" +dependencies = [ + "ed448-goldilocks", + "hex", + "rand_core 0.5.1", +] + [[package]] name = "x509-parser" version = "0.16.0" diff --git a/Cargo.toml b/Cargo.toml index b22863e063..5579a0e1a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ num-traits = { workspace = true } once_cell = { workspace = true } parking_lot = "0.12" percent-encoding = "2.3" -pgp = { version = "0.13.2", default-features = false } +pgp = { version = "0.14.0", default-features = false } pin-project = "1" qrcodegen = "1.7.0" quick-xml = "0.37" diff --git a/deny.toml b/deny.toml index b4ab573d68..2a76298bbb 100644 --- a/deny.toml +++ b/deny.toml @@ -33,10 +33,14 @@ skip = [ { name = "event-listener", version = "2.5.3" }, { name = "event-listener", version = "4.0.3" }, { name = "fastrand", version = "1.9.0" }, + { name = "fiat-crypto", version = "0.1.20" }, { name = "futures-lite", version = "1.13.0" }, { name = "getrandom", version = "<0.2" }, { name = "http", version = "0.2.12" }, { name = "nix", version = "0.26.4" }, + { name = "num_enum_derive", version = "0.5.11" }, + { name = "num_enum", version = "0.5.11" }, + { name = "proc-macro-crate", version = "1.3.1" }, { name = "quick-error", version = "<2.0" }, { name = "rand_chacha", version = "<0.3" }, { name = "rand_core", version = "<0.6" }, @@ -47,6 +51,7 @@ skip = [ { name = "sync_wrapper", version = "0.1.2" }, { name = "syn", version = "1.0.109" }, { name = "time", version = "<0.3" }, + { name = "toml_edit", version = "0.19.15" }, { name = "wasi", version = "<0.11" }, { name = "windows_aarch64_gnullvm", version = "<0.52" }, { name = "windows_aarch64_msvc", version = "<0.52" }, @@ -59,6 +64,7 @@ skip = [ { name = "windows_x86_64_gnullvm", version = "<0.52" }, { name = "windows_x86_64_gnu", version = "<0.52" }, { name = "windows_x86_64_msvc", version = "<0.52" }, + { name = "winnow", version = "0.5.40" }, { name = "winreg", version = "0.50.0" }, ] diff --git a/src/contact.rs b/src/contact.rs index 1fa2bea6be..7e925cd1c7 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -1252,15 +1252,15 @@ impl Contact { let fingerprint_self = load_self_public_key(context) .await? - .fingerprint() + .dc_fingerprint() .to_string(); let fingerprint_other_verified = peerstate .peek_key(true) - .map(|k| k.fingerprint().to_string()) + .map(|k| k.dc_fingerprint().to_string()) .unwrap_or_default(); let fingerprint_other_unverified = peerstate .peek_key(false) - .map(|k| k.fingerprint().to_string()) + .map(|k| k.dc_fingerprint().to_string()) .unwrap_or_default(); if addr < peerstate.addr { cat_fingerprint(&mut ret, &addr, &fingerprint_self, ""); diff --git a/src/context.rs b/src/context.rs index ba1784fdfe..40bf95fbd9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -10,6 +10,7 @@ use std::time::Duration; use anyhow::{bail, ensure, Context as _, Result}; use async_channel::{self as channel, Receiver, Sender}; +use pgp::types::PublicKeyTrait; use pgp::SignedPublicKey; use ratelimit::Ratelimit; use tokio::sync::{Mutex, Notify, OnceCell, RwLock}; @@ -781,7 +782,7 @@ impl Context { .count("SELECT COUNT(*) FROM acpeerstates;", ()) .await?; let fingerprint_str = match load_self_public_key(self).await { - Ok(key) => key.fingerprint().hex(), + Ok(key) => key.dc_fingerprint().hex(), Err(err) => format!(""), }; @@ -1177,7 +1178,7 @@ impl Context { EncryptPreference::Mutual, &public_key, ); - let fingerprint = public_key.fingerprint(); + let fingerprint = public_key.dc_fingerprint(); peerstate.set_verified(public_key, fingerprint, "".to_string())?; peerstate.save_to_db(&self.sql).await?; chat_id diff --git a/src/decrypt.rs b/src/decrypt.rs index 2dd7bc35fb..7be616c309 100644 --- a/src/decrypt.rs +++ b/src/decrypt.rs @@ -182,7 +182,7 @@ pub(crate) async fn get_autocrypt_peerstate( // if the fingerprint is verified. peerstate = Peerstate::from_verified_fingerprint_or_addr( context, - &header.public_key.fingerprint(), + &header.public_key.dc_fingerprint(), from, ) .await?; diff --git a/src/e2ee.rs b/src/e2ee.rs index 85d665eb4e..77be8fb173 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -303,12 +303,12 @@ Sent with my Delta Chat Messenger: https://delta.chat"; last_seen_autocrypt: 14, prefer_encrypt, public_key: Some(pub_key.clone()), - public_key_fingerprint: Some(pub_key.fingerprint()), + public_key_fingerprint: Some(pub_key.dc_fingerprint()), gossip_key: Some(pub_key.clone()), gossip_timestamp: 15, - gossip_key_fingerprint: Some(pub_key.fingerprint()), + gossip_key_fingerprint: Some(pub_key.dc_fingerprint()), verified_key: Some(pub_key.clone()), - verified_key_fingerprint: Some(pub_key.fingerprint()), + verified_key_fingerprint: Some(pub_key.dc_fingerprint()), verifier: None, secondary_verified_key: None, secondary_verified_key_fingerprint: None, diff --git a/src/imex.rs b/src/imex.rs index f99115cb6f..07b55df5b0 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -4,7 +4,7 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::pin::Pin; -use ::pgp::types::KeyTrait; +use ::pgp::types::PublicKeyTrait; use anyhow::{bail, ensure, format_err, Context as _, Result}; use futures::TryStreamExt; use futures_lite::FutureExt; @@ -750,7 +750,7 @@ where true => "private", }; let id = id.map_or("default".into(), |i| i.to_string()); - let fp = DcKey::fingerprint(key).hex(); + let fp = key.dc_fingerprint().hex(); format!("{kind}-key-{addr}-{id}-{fp}.asc") }; let path = dir.join(&file_name); @@ -878,7 +878,7 @@ mod tests { .unwrap() .strip_suffix(".asc") .unwrap(); - assert_eq!(fingerprint, DcKey::fingerprint(&key).hex()); + assert_eq!(fingerprint, key.dc_fingerprint().hex()); let blobdir = context.ctx.get_blobdir().to_str().unwrap(); let filename = format!("{blobdir}/{filename}"); let bytes = tokio::fs::read(&filename).await.unwrap(); diff --git a/src/key.rs b/src/key.rs index 0182cd383d..b03d06610d 100644 --- a/src/key.rs +++ b/src/key.rs @@ -11,7 +11,8 @@ use num_traits::FromPrimitive; use pgp::composed::Deserializable; pub use pgp::composed::{SignedPublicKey, SignedSecretKey}; use pgp::ser::Serialize; -use pgp::types::{KeyTrait, SecretKeyTrait}; +use pgp::types::{PublicKeyTrait, SecretKeyTrait}; +use rand::thread_rng; use tokio::runtime::Handle; use crate::config::Config; @@ -26,7 +27,7 @@ use crate::tools::{self, time_elapsed}; /// This trait is implemented for rPGP's [SignedPublicKey] and /// [SignedSecretKey] types and makes working with them a little /// easier in the deltachat world. -pub(crate) trait DcKey: Serialize + Deserializable + KeyTrait + Clone { +pub(crate) trait DcKey: Serialize + Deserializable + PublicKeyTrait + Clone { /// Create a key from some bytes. fn from_slice(bytes: &[u8]) -> Result { Ok(::from_bytes(Cursor::new(bytes))?) @@ -93,8 +94,8 @@ pub(crate) trait DcKey: Serialize + Deserializable + KeyTrait + Clone { fn to_asc(&self, header: Option<(&str, &str)>) -> String; /// The fingerprint for the key. - fn fingerprint(&self) -> Fingerprint { - Fingerprint::new(KeyTrait::fingerprint(self)) + fn dc_fingerprint(&self) -> Fingerprint { + PublicKeyTrait::fingerprint(self).into() } fn is_private() -> bool; @@ -233,7 +234,8 @@ impl DcSecretKey for SignedSecretKey { fn split_public_key(&self) -> Result { self.verify()?; let unsigned_pubkey = SecretKeyTrait::public_key(self); - let signed_pubkey = unsigned_pubkey.sign(self, || "".into())?; + let mut rng = thread_rng(); + let signed_pubkey = unsigned_pubkey.sign(&mut rng, self, || "".into())?; Ok(signed_pubkey) } } @@ -395,6 +397,12 @@ impl Fingerprint { } } +impl From for Fingerprint { + fn from(fingerprint: pgp::types::Fingerprint) -> Fingerprint { + Self::new(fingerprint.as_bytes().into()) + } +} + impl fmt::Debug for Fingerprint { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Fingerprint") diff --git a/src/peerstate.rs b/src/peerstate.rs index 891235790d..d5ff2d6ea2 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -121,7 +121,7 @@ impl Peerstate { last_seen_autocrypt: last_seen, prefer_encrypt, public_key: Some(public_key.clone()), - public_key_fingerprint: Some(public_key.fingerprint()), + public_key_fingerprint: Some(public_key.dc_fingerprint()), gossip_key: None, gossip_key_fingerprint: None, gossip_timestamp: 0, @@ -153,7 +153,7 @@ impl Peerstate { public_key: None, public_key_fingerprint: None, gossip_key: Some(gossip_header.public_key.clone()), - gossip_key_fingerprint: Some(gossip_header.public_key.fingerprint()), + gossip_key_fingerprint: Some(gossip_header.public_key.dc_fingerprint()), gossip_timestamp: message_time, verified_key: None, verified_key_fingerprint: None, @@ -308,7 +308,7 @@ impl Peerstate { pub fn recalc_fingerprint(&mut self) { if let Some(ref public_key) = self.public_key { let old_public_fingerprint = self.public_key_fingerprint.take(); - self.public_key_fingerprint = Some(public_key.fingerprint()); + self.public_key_fingerprint = Some(public_key.dc_fingerprint()); if old_public_fingerprint.is_some() && old_public_fingerprint != self.public_key_fingerprint @@ -319,7 +319,7 @@ impl Peerstate { if let Some(ref gossip_key) = self.gossip_key { let old_gossip_fingerprint = self.gossip_key_fingerprint.take(); - self.gossip_key_fingerprint = Some(gossip_key.fingerprint()); + self.gossip_key_fingerprint = Some(gossip_key.dc_fingerprint()); if old_gossip_fingerprint.is_none() || self.gossip_key_fingerprint.is_none() @@ -506,7 +506,7 @@ impl Peerstate { fingerprint: Fingerprint, verifier: String, ) -> Result<()> { - if key.fingerprint() == fingerprint { + if key.dc_fingerprint() == fingerprint { self.verified_key = Some(key); self.verified_key_fingerprint = Some(fingerprint); self.verifier = Some(verifier); @@ -524,7 +524,7 @@ impl Peerstate { /// do nothing to avoid overwriting secondary verified key /// which may be different. pub fn set_secondary_verified_key(&mut self, gossip_key: SignedPublicKey, verifier: String) { - let fingerprint = gossip_key.fingerprint(); + let fingerprint = gossip_key.dc_fingerprint(); if self.verified_key_fingerprint.as_ref() != Some(&fingerprint) { self.secondary_verified_key = Some(gossip_key); self.secondary_verified_key_fingerprint = Some(fingerprint); @@ -888,12 +888,12 @@ mod tests { last_seen_autocrypt: 11, prefer_encrypt: EncryptPreference::Mutual, public_key: Some(pub_key.clone()), - public_key_fingerprint: Some(pub_key.fingerprint()), + public_key_fingerprint: Some(pub_key.dc_fingerprint()), gossip_key: Some(pub_key.clone()), gossip_timestamp: 12, - gossip_key_fingerprint: Some(pub_key.fingerprint()), + gossip_key_fingerprint: Some(pub_key.dc_fingerprint()), verified_key: Some(pub_key.clone()), - verified_key_fingerprint: Some(pub_key.fingerprint()), + verified_key_fingerprint: Some(pub_key.dc_fingerprint()), verifier: None, secondary_verified_key: None, secondary_verified_key_fingerprint: None, @@ -913,7 +913,7 @@ mod tests { .expect("no peerstate found in the database"); assert_eq!(peerstate, peerstate_new); - let peerstate_new2 = Peerstate::from_fingerprint(&ctx.ctx, &pub_key.fingerprint()) + let peerstate_new2 = Peerstate::from_fingerprint(&ctx.ctx, &pub_key.dc_fingerprint()) .await .expect("failed to load peerstate from db") .expect("no peerstate found in the database"); @@ -932,7 +932,7 @@ mod tests { last_seen_autocrypt: 11, prefer_encrypt: EncryptPreference::Mutual, public_key: Some(pub_key.clone()), - public_key_fingerprint: Some(pub_key.fingerprint()), + public_key_fingerprint: Some(pub_key.dc_fingerprint()), gossip_key: None, gossip_timestamp: 12, gossip_key_fingerprint: None, @@ -969,7 +969,7 @@ mod tests { last_seen_autocrypt: 11, prefer_encrypt: EncryptPreference::Mutual, public_key: Some(pub_key.clone()), - public_key_fingerprint: Some(pub_key.fingerprint()), + public_key_fingerprint: Some(pub_key.dc_fingerprint()), gossip_key: None, gossip_timestamp: 12, gossip_key_fingerprint: None, diff --git a/src/pgp.rs b/src/pgp.rs index 447603232f..f729237d99 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -14,7 +14,7 @@ use pgp::composed::{ use pgp::crypto::ecc_curve::ECCCurve; use pgp::crypto::hash::HashAlgorithm; use pgp::crypto::sym::SymmetricKeyAlgorithm; -use pgp::types::{CompressionAlgorithm, KeyTrait, Mpi, PublicKeyTrait, StringToKey}; +use pgp::types::{CompressionAlgorithm, PublicKeyTrait, SignatureBytes, StringToKey}; use rand::{thread_rng, CryptoRng, Rng}; use tokio::runtime::Handle; @@ -41,8 +41,15 @@ enum SignedPublicKeyOrSubkey<'a> { Subkey(&'a SignedPublicSubKey), } -impl KeyTrait for SignedPublicKeyOrSubkey<'_> { - fn fingerprint(&self) -> Vec { +impl PublicKeyTrait for SignedPublicKeyOrSubkey<'_> { + fn version(&self) -> pgp::types::KeyVersion { + match self { + Self::Key(k) => k.version(), + Self::Subkey(k) => k.version(), + } + } + + fn fingerprint(&self) -> pgp::types::Fingerprint { match self { Self::Key(k) => k.fingerprint(), Self::Subkey(k) => k.fingerprint(), @@ -62,14 +69,26 @@ impl KeyTrait for SignedPublicKeyOrSubkey<'_> { Self::Subkey(k) => k.algorithm(), } } -} -impl PublicKeyTrait for SignedPublicKeyOrSubkey<'_> { + fn created_at(&self) -> &chrono::DateTime { + match self { + Self::Key(k) => k.created_at(), + Self::Subkey(k) => k.created_at(), + } + } + + fn expiration(&self) -> Option { + match self { + Self::Key(k) => k.expiration(), + Self::Subkey(k) => k.expiration(), + } + } + fn verify_signature( &self, hash: HashAlgorithm, data: &[u8], - sig: &[Mpi], + sig: &SignatureBytes, ) -> pgp::errors::Result<()> { match self { Self::Key(k) => k.verify_signature(hash, data, sig), @@ -79,19 +98,27 @@ impl PublicKeyTrait for SignedPublicKeyOrSubkey<'_> { fn encrypt( &self, - rng: &mut R, + rng: R, plain: &[u8], - ) -> pgp::errors::Result> { + typ: pgp::types::EskType, + ) -> pgp::errors::Result { match self { - Self::Key(k) => k.encrypt(rng, plain), - Self::Subkey(k) => k.encrypt(rng, plain), + Self::Key(k) => k.encrypt(rng, plain, typ), + Self::Subkey(k) => k.encrypt(rng, plain, typ), } } - fn to_writer_old(&self, writer: &mut impl io::Write) -> pgp::errors::Result<()> { + fn serialize_for_hashing(&self, writer: &mut impl io::Write) -> pgp::errors::Result<()> { match self { - Self::Key(k) => k.to_writer_old(writer), - Self::Subkey(k) => k.to_writer_old(writer), + Self::Key(k) => k.serialize_for_hashing(writer), + Self::Subkey(k) => k.serialize_for_hashing(writer), + } + } + + fn public_params(&self) -> &pgp::types::PublicParams { + match self { + Self::Key(k) => k.public_params(), + Self::Subkey(k) => k.public_params(), } } } @@ -160,9 +187,10 @@ pub(crate) fn create_keypair(addr: EmailAddress, keygen_type: KeyGenType) -> Res let (signing_key_type, encryption_key_type) = match keygen_type { KeyGenType::Rsa2048 => (PgpKeyType::Rsa(2048), PgpKeyType::Rsa(2048)), KeyGenType::Rsa4096 => (PgpKeyType::Rsa(4096), PgpKeyType::Rsa(4096)), - KeyGenType::Ed25519 | KeyGenType::Default => { - (PgpKeyType::EdDSA, PgpKeyType::ECDH(ECCCurve::Curve25519)) - } + KeyGenType::Ed25519 | KeyGenType::Default => ( + PgpKeyType::EdDSALegacy, + PgpKeyType::ECDH(ECCCurve::Curve25519), + ), }; let user_id = format!("<{addr}>"); @@ -199,10 +227,11 @@ pub(crate) fn create_keypair(addr: EmailAddress, keygen_type: KeyGenType) -> Res .build() .context("failed to build key parameters")?; + let mut rng = thread_rng(); let secret_key = key_params - .generate() + .generate(&mut rng) .context("failed to generate the key")? - .sign(|| "".into()) + .sign(&mut rng, || "".into()) .context("failed to sign secret key")?; secret_key .verify() @@ -261,15 +290,19 @@ pub async fn pk_encrypt( let mut rng = thread_rng(); let encrypted_msg = if let Some(ref skey) = private_key_for_signing { - let signed_msg = lit_msg.sign(skey, || "".into(), HASH_ALGORITHM)?; + let signed_msg = lit_msg.sign(&mut rng, skey, || "".into(), HASH_ALGORITHM)?; let compressed_msg = if compress { signed_msg.compress(CompressionAlgorithm::ZLIB)? } else { signed_msg }; - compressed_msg.encrypt_to_keys(&mut rng, SYMMETRIC_KEY_ALGORITHM, &pkeys_refs)? + compressed_msg.encrypt_to_keys_seipdv1( + &mut rng, + SYMMETRIC_KEY_ALGORITHM, + &pkeys_refs, + )? } else { - lit_msg.encrypt_to_keys(&mut rng, SYMMETRIC_KEY_ALGORITHM, &pkeys_refs)? + lit_msg.encrypt_to_keys_seipdv1(&mut rng, SYMMETRIC_KEY_ALGORITHM, &pkeys_refs)? }; let encoded_msg = encrypted_msg.to_armored_string(Default::default())?; @@ -284,7 +317,9 @@ pub fn pk_calc_signature( plain: &[u8], private_key_for_signing: &SignedSecretKey, ) -> Result { + let mut rng = thread_rng(); let msg = Message::new_literal_bytes("", plain).sign( + &mut rng, private_key_for_signing, || "".into(), HASH_ALGORITHM, @@ -328,7 +363,7 @@ pub fn valid_signature_fingerprints( if let signed_msg @ pgp::composed::Message::Signed { .. } = msg { for pkey in public_keys_for_validation { if signed_msg.verify(&pkey.primary_key).is_ok() { - let fp = DcKey::fingerprint(pkey); + let fp = pkey.dc_fingerprint(); ret_signature_fingerprints.insert(fp); } } @@ -355,7 +390,7 @@ pub fn pk_validate( for pkey in public_keys_for_validation { if standalone_signature.verify(pkey, content).is_ok() { - let fp = DcKey::fingerprint(pkey); + let fp = pkey.dc_fingerprint(); ret.insert(fp); } } @@ -370,8 +405,12 @@ pub async fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result { tokio::task::spawn_blocking(move || { let mut rng = thread_rng(); let s2k = StringToKey::new_default(&mut rng); - let msg = - lit_msg.encrypt_with_password(&mut rng, s2k, SYMMETRIC_KEY_ALGORITHM, || passphrase)?; + let msg = lit_msg.encrypt_with_password_seipdv1( + &mut rng, + s2k, + SYMMETRIC_KEY_ALGORITHM, + || passphrase, + )?; let encoded_msg = msg.to_armored_string(Default::default())?; diff --git a/src/qr.rs b/src/qr.rs index dee84d5329..23baaf3c9b 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -1309,7 +1309,7 @@ mod tests { last_seen_autocrypt: 1, prefer_encrypt: EncryptPreference::Mutual, public_key: Some(pub_key.clone()), - public_key_fingerprint: Some(pub_key.fingerprint()), + public_key_fingerprint: Some(pub_key.dc_fingerprint()), gossip_key: None, gossip_timestamp: 0, gossip_key_fingerprint: None, @@ -1340,7 +1340,10 @@ mod tests { let qr = check_qr( &ctx.ctx, - &format!("OPENPGP4FPR:{}#a=alice@example.org", pub_key.fingerprint()), + &format!( + "OPENPGP4FPR:{}#a=alice@example.org", + pub_key.dc_fingerprint() + ), ) .await?; if let Qr::FprOk { contact_id, .. } = qr { diff --git a/src/securejoin.rs b/src/securejoin.rs index 9106e0cdd7..7118c8db28 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -136,7 +136,7 @@ async fn get_self_fingerprint(context: &Context) -> Result { let key = load_self_public_key(context) .await .context("Failed to load key")?; - Ok(key.fingerprint()) + Ok(key.dc_fingerprint()) } /// Take a scanned QR-code and do the setup-contact/join-group/invite handshake. @@ -298,9 +298,9 @@ pub(crate) async fn handle_securejoin_handshake( if !matches!(step, "vg-request" | "vc-request") { let mut self_found = false; - let self_fingerprint = load_self_public_key(context).await?.fingerprint(); + let self_fingerprint = load_self_public_key(context).await?.dc_fingerprint(); for (addr, key) in &mime_message.gossiped_keys { - if key.fingerprint() == self_fingerprint && context.is_self_addr(addr).await? { + if key.dc_fingerprint() == self_fingerprint && context.is_self_addr(addr).await? { self_found = true; break; } @@ -936,7 +936,10 @@ mod tests { "vc-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = load_self_public_key(&bob.ctx).await.unwrap().fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx) + .await + .unwrap() + .dc_fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() @@ -1106,10 +1109,10 @@ mod tests { last_seen_autocrypt: 10, prefer_encrypt: EncryptPreference::Mutual, public_key: Some(alice_pubkey.clone()), - public_key_fingerprint: Some(alice_pubkey.fingerprint()), + public_key_fingerprint: Some(alice_pubkey.dc_fingerprint()), gossip_key: Some(alice_pubkey.clone()), gossip_timestamp: 10, - gossip_key_fingerprint: Some(alice_pubkey.fingerprint()), + gossip_key_fingerprint: Some(alice_pubkey.dc_fingerprint()), verified_key: None, verified_key_fingerprint: None, verifier: None, @@ -1157,7 +1160,7 @@ mod tests { "vc-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = load_self_public_key(&bob.ctx).await?.fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx).await?.dc_fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() @@ -1320,7 +1323,7 @@ mod tests { "vg-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = load_self_public_key(&bob.ctx).await?.fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx).await?.dc_fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() diff --git a/src/securejoin/bobstate.rs b/src/securejoin/bobstate.rs index 83f71ca311..dbc1573432 100644 --- a/src/securejoin/bobstate.rs +++ b/src/securejoin/bobstate.rs @@ -389,7 +389,7 @@ async fn send_handshake_message( msg.param.set_int(Param::GuaranteeE2ee, 1); // Sends our own fingerprint in the Secure-Join-Fingerprint header. - let bob_fp = load_self_public_key(context).await?.fingerprint(); + let bob_fp = load_self_public_key(context).await?.dc_fingerprint(); msg.param.set(Param::Arg3, bob_fp.hex()); // Sends the grpid in the Secure-Join-Group header.