diff --git a/.gitattributes b/.gitattributes index 26f7e3d9b1..1359bb5fc6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,7 +4,7 @@ # This directory contains email messages verbatim, and changing CRLF to # LF will corrupt them. -test-data/* text=false +test-data/** text=false # binary files should be detected by git, however, to be sure, you can add them here explicitly *.png binary diff --git a/CHANGELOG.md b/CHANGELOG.md index d5b707b9d1..3c54f2b5c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Fix cargo clippy and doc errors after Rust update to 1.66 #3850 - Don't send GroupNameChanged message if the group name doesn't change in terms of improve_single_line_input() #3852 +- Prefer encryption for the peer if the message is encrypted or signed with the known key #3849 ## 1.103.0 diff --git a/src/decrypt.rs b/src/decrypt.rs index 457af68515..c01be46ce1 100644 --- a/src/decrypt.rs +++ b/src/decrypt.rs @@ -31,7 +31,7 @@ pub async fn try_decrypt( decryption_info: &DecryptionInfo, ) -> Result, HashSet)>> { // Possibly perform decryption - let public_keyring_for_validate = keyring_from_peerstate(&decryption_info.peerstate); + let public_keyring_for_validate = keyring_from_peerstate(decryption_info.peerstate.as_ref()); let encrypted_data_part = match get_autocrypt_mime(mail) .or_else(|| get_mixed_up_mime(mail)) @@ -251,7 +251,7 @@ fn has_decrypted_pgp_armor(input: &[u8]) -> bool { /// /// Returns `None` if the part is not a Multipart/Signed part, otherwise retruns the set of key /// fingerprints for which there is a valid signature. -fn validate_detached_signature( +pub(crate) fn validate_detached_signature( mail: &ParsedMail<'_>, public_keyring_for_validate: &Keyring, ) -> Result, HashSet)>> { @@ -272,9 +272,9 @@ fn validate_detached_signature( } } -fn keyring_from_peerstate(peerstate: &Option) -> Keyring { +pub(crate) fn keyring_from_peerstate(peerstate: Option<&Peerstate>) -> Keyring { let mut public_keyring_for_validate: Keyring = Keyring::new(); - if let Some(ref peerstate) = *peerstate { + if let Some(peerstate) = peerstate { if let Some(key) = &peerstate.public_key { public_keyring_for_validate.add(key.clone()); } else if let Some(key) = &peerstate.gossip_key { diff --git a/src/mimeparser.rs b/src/mimeparser.rs index e85c95246b..c96129e333 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -18,7 +18,10 @@ use crate::blob::BlobObject; use crate::constants::{DC_DESIRED_TEXT_LINES, DC_DESIRED_TEXT_LINE_LEN}; use crate::contact::{addr_cmp, addr_normalize, ContactId}; use crate::context::Context; -use crate::decrypt::{prepare_decryption, try_decrypt, DecryptionInfo}; +use crate::decrypt::{ + keyring_from_peerstate, prepare_decryption, try_decrypt, validate_detached_signature, + DecryptionInfo, +}; use crate::dehtml::dehtml; use crate::events::EventType; use crate::format_flowed::unformat_flowed; @@ -64,7 +67,8 @@ pub struct MimeMessage { /// If a message is not encrypted or the signature is not valid, /// this set is empty. pub signatures: HashSet, - + /// Whether the message is encrypted in a domestic (not Autocrypt) sense + pub encrypted: bool, /// The set of mail recipient addresses for which gossip headers were applied, regardless of /// whether they modified any peerstates. pub gossiped_addr: HashSet, @@ -232,91 +236,95 @@ impl MimeMessage { hop_info += &decryption_info.dkim_results.to_string(); // `signatures` is non-empty exactly if the message was encrypted and correctly signed. - let (mail, signatures, warn_empty_signature) = - match try_decrypt(context, &mail, &decryption_info).await { - Ok(Some((raw, signatures))) => { - // Encrypted, but maybe unsigned message. Only if - // `signatures` set is non-empty, it is a valid - // autocrypt message. - - mail_raw = raw; - let decrypted_mail = mailparse::parse_mail(&mail_raw)?; - if std::env::var(crate::DCC_MIME_DEBUG).is_ok() { - info!(context, "decrypted message mime-body:"); - println!("{}", String::from_utf8_lossy(&mail_raw)); - } + let (mail, signatures, encrypted) = match try_decrypt(context, &mail, &decryption_info) + .await + { + Ok(Some((raw, signatures))) => { + // Encrypted, but maybe unsigned message. Only if + // `signatures` set is non-empty, it is a valid + // autocrypt message. + + mail_raw = raw; + let decrypted_mail = mailparse::parse_mail(&mail_raw)?; + if std::env::var(crate::DCC_MIME_DEBUG).is_ok() { + info!(context, "decrypted message mime-body:"); + println!("{}", String::from_utf8_lossy(&mail_raw)); + } - // Handle any gossip headers if the mail was encrypted. See section - // "3.6 Key Gossip" of - // but only if the mail was correctly signed: - if !signatures.is_empty() { - let gossip_headers = - decrypted_mail.headers.get_all_values("Autocrypt-Gossip"); - gossiped_addr = - update_gossip_peerstates(context, message_time, &mail, gossip_headers) - .await?; - } + // Handle any gossip headers if the mail was encrypted. See section + // "3.6 Key Gossip" of + // but only if the mail was correctly signed: + if !signatures.is_empty() { + let gossip_headers = decrypted_mail.headers.get_all_values("Autocrypt-Gossip"); + gossiped_addr = update_gossip_peerstates( + context, + message_time, + &from.addr, + &mail, + gossip_headers, + ) + .await?; + } - // let known protected headers from the decrypted - // part override the unencrypted top-level + // let known protected headers from the decrypted + // part override the unencrypted top-level - // Signature was checked for original From, so we - // do not allow overriding it. - let mut signed_from = None; + // Signature was checked for original From, so we + // do not allow overriding it. + let mut signed_from = None; - // We do not want to allow unencrypted subject in encrypted emails because the user might falsely think that the subject is safe. - // See . - headers.remove("subject"); + // We do not want to allow unencrypted subject in encrypted emails because the user might falsely think that the subject is safe. + // See . + headers.remove("subject"); - MimeMessage::merge_headers( - context, - &mut headers, - &mut recipients, - &mut signed_from, - &mut list_post, - &mut chat_disposition_notification_to, - &decrypted_mail.headers, - ); - if let Some(signed_from) = signed_from { - if addr_cmp(&signed_from.addr, &from.addr) { - from_is_signed = true; - } else { - // There is a From: header in the encrypted & - // signed part, but it doesn't match the outer one. - // This _might_ be because the sender's mail server - // replaced the sending address, e.g. in a mailing list. - // Or it's because someone is doing some replay attack - // - OTOH, I can't come up with an attack scenario - // where this would be useful. - warn!( - context, - "From header in signed part does't match the outer one" - ); - } + MimeMessage::merge_headers( + context, + &mut headers, + &mut recipients, + &mut signed_from, + &mut list_post, + &mut chat_disposition_notification_to, + &decrypted_mail.headers, + ); + if let Some(signed_from) = signed_from { + if addr_cmp(&signed_from.addr, &from.addr) { + from_is_signed = true; + } else { + // There is a From: header in the encrypted & + // signed part, but it doesn't match the outer one. + // This _might_ be because the sender's mail server + // replaced the sending address, e.g. in a mailing list. + // Or it's because someone is doing some replay attack + // - OTOH, I can't come up with an attack scenario + // where this would be useful. + warn!( + context, + "From header in signed part does't match the outer one", + ); } - - (Ok(decrypted_mail), signatures, true) } - Ok(None) => { - // Message was not encrypted. - // If it is not a read receipt, degrade encryption. - if let Some(peerstate) = &mut decryption_info.peerstate { - if message_time > peerstate.last_seen_autocrypt - && mail.ctype.mimetype != "multipart/report" - // Disallowing keychanges is disabled for now: - // && decryption_info.dkim_results.allow_keychange - { - peerstate.degrade_encryption(message_time); - peerstate.save_to_db(&context.sql).await?; - } + + (Ok(decrypted_mail), signatures, true) + } + Ok(None) => { + // Message was not encrypted. + // If it is not a read receipt, degrade encryption. + if let Some(peerstate) = &mut decryption_info.peerstate { + if message_time > peerstate.last_seen_autocrypt + && mail.ctype.mimetype != "multipart/report" + // Disallowing keychanges is disabled for now: + // && decryption_info.dkim_results.allow_keychange + { + peerstate.degrade_encryption(message_time); } - (Ok(mail), HashSet::new(), false) - } - Err(err) => { - warn!(context, "decryption failed: {}", err); - (Err(err), HashSet::new(), true) } - }; + (Ok(mail), HashSet::new(), false) + } + Err(err) => { + warn!(context, "decryption failed: {}", err); + (Err(err), HashSet::new(), true) + } + }; let mut parser = MimeMessage { parts: Vec::new(), @@ -331,6 +339,7 @@ impl MimeMessage { // only non-empty if it was a valid autocrypt message signatures, + encrypted, gossiped_addr, is_forwarded: false, mdn_reports: Vec::new(), @@ -385,7 +394,7 @@ impl MimeMessage { // part.error = Some("Seems like DKIM failed, this either is an attack or (more likely) a bug in Authentication-Results checking. Please tell us about this at https://support.delta.chat.".to_string()); // } // } - if warn_empty_signature && parser.signatures.is_empty() { + if encrypted && parser.signatures.is_empty() { for part in parser.parts.iter_mut() { part.error = Some("No valid signature".to_string()); } @@ -400,6 +409,13 @@ impl MimeMessage { peerstate .handle_fingerprint_change(context, message_time) .await?; + // When peerstate is set to Mutual, it's saved immediately to not lose that fact in case + // of an error. Otherwise we don't save peerstate until get here to reduce the number of + // calls to save_to_db() and not to degrade encryption if a mail wasn't parsed + // successfully. + if peerstate.prefer_encrypt != EncryptPreference::Mutual { + peerstate.save_to_db(&context.sql).await?; + } } Ok(parser) @@ -852,6 +868,26 @@ impl MimeMessage { .parse_mime_recursive(context, first, is_related) .await?; } + if let Some(peerstate) = &mut self.decryption_info.peerstate { + let keyring = keyring_from_peerstate(Some(peerstate)); + match validate_detached_signature(mail, &keyring) { + Ok(Some((_, fprints))) => { + if fprints.is_empty() { + warn!(context, "signed message is not signed with a known key"); + } else if peerstate.prefer_encrypt != EncryptPreference::Mutual { + info!( + context, + "message is signed with the known key, setting \ + prefer-encrypt=mutual for '{}'", + peerstate.addr, + ); + Self::upgrade_to_mutual_encryption(context, peerstate).await?; + } + } + Ok(None) => warn!(context, "not a 'multipart/signed' part??"), + Err(err) => warn!(context, "signed message validation failed: {}", err), + } + } } (mime::MULTIPART, "report") => { /* RFC 6522: the first part is for humans, the second for machines */ @@ -929,6 +965,17 @@ impl MimeMessage { Ok(any_part_added) } + async fn upgrade_to_mutual_encryption( + context: &Context, + peerstate: &mut Peerstate, + ) -> Result<()> { + if peerstate.public_key.is_none() { + peerstate.public_key = peerstate.gossip_key.take(); + } + peerstate.prefer_encrypt = EncryptPreference::Mutual; + peerstate.save_to_db(&context.sql).await + } + /// Returns true if any part was added, false otherwise. async fn add_single_part_if_known( &mut self, @@ -1106,7 +1153,13 @@ impl MimeMessage { if peerstate.prefer_encrypt != EncryptPreference::Mutual && mime_type.type_() == mime::APPLICATION && mime_type.subtype().as_str() == "pgp-keys" - && Self::try_set_peer_key_from_file_part(context, peerstate, decoded_data).await? + && Self::try_set_peer_key_from_file_part( + context, + peerstate, + decoded_data, + self.encrypted, + ) + .await? { return Ok(()); } @@ -1196,6 +1249,7 @@ impl MimeMessage { context: &Context, peerstate: &mut Peerstate, decoded_data: &[u8], + mail_is_encrypted: bool, ) -> Result { let key = match str::from_utf8(decoded_data) { Err(err) => { @@ -1240,13 +1294,23 @@ impl MimeMessage { return Ok(false); } } - info!( - context, - "will use attached PGP key for peer '{}' with mutual encryption", peerstate.addr, - ); peerstate.public_key = Some(key); - peerstate.prefer_encrypt = EncryptPreference::Mutual; - peerstate.save_to_db(&context.sql).await?; + if mail_is_encrypted { + info!( + context, + "using attached PGP key for peer '{}' with prefer-encrypt=mutual as the mail is \ + encrypted", + peerstate.addr, + ); + peerstate.prefer_encrypt = EncryptPreference::Mutual; + peerstate.save_to_db(&context.sql).await?; + } else { + info!( + context, + "using attached PGP key for peer '{}'", peerstate.addr, + ); + peerstate.prefer_encrypt = EncryptPreference::NoPreference; + } Ok(true) } @@ -1624,6 +1688,7 @@ impl MimeMessage { async fn update_gossip_peerstates( context: &Context, message_time: i64, + from: &str, mail: &mailparse::ParsedMail<'_>, gossip_headers: Vec, ) -> Result> { @@ -1641,7 +1706,7 @@ async fn update_gossip_peerstates( if !get_recipients(&mail.headers) .iter() - .any(|info| info.addr == header.addr.to_lowercase()) + .any(|info| addr_cmp(&info.addr, &header.addr)) { warn!( context, @@ -1649,6 +1714,14 @@ async fn update_gossip_peerstates( ); continue; } + if addr_cmp(from, &header.addr) { + // Non-standard, but anyway we can't update the cached peerstate here. + warn!( + context, + "Ignoring gossiped \"{}\" as it equals the From address", &header.addr, + ); + continue; + } let peerstate; if let Some(mut p) = Peerstate::from_addr(context, &header.addr).await? { diff --git a/src/peerstate.rs b/src/peerstate.rs index 9318919297..ab6d527a3a 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -806,7 +806,6 @@ mod tests { verified_key_fingerprint: None, fingerprint_changed: false, }; - assert_eq!(peerstate.prefer_encrypt, EncryptPreference::NoPreference); peerstate.apply_header(&header, 100); assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Mutual); diff --git a/src/receive_imf.rs b/src/receive_imf.rs index b477d86868..a1711018e3 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -5359,7 +5359,13 @@ Reply from different address let raw = include_bytes!("../test-data/message/thunderbird_with_autocrypt_unencrypted.eml"); receive_imf(&t, raw, false).await?; + let peerstate = Peerstate::from_addr(&t, "alice@example.org") + .await? + .unwrap(); + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Mutual); + let raw = include_bytes!("../test-data/message/thunderbird_signed_unencrypted.eml"); + receive_imf(&t, raw, false).await?; let peerstate = Peerstate::from_addr(&t, "alice@example.org") .await? .unwrap(); diff --git a/test-data/message/thunderbird_signed_unencrypted.eml b/test-data/message/thunderbird_signed_unencrypted.eml new file mode 100644 index 0000000000..ec9646050b --- /dev/null +++ b/test-data/message/thunderbird_signed_unencrypted.eml @@ -0,0 +1,56 @@ +From - Thu, 15 Dec 2022 14:45:17 GMT +X-Mozilla-Status: 0801 +X-Mozilla-Status2: 00000000 +Message-ID: +Date: Thu, 15 Dec 2022 11:45:16 -0300 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.5.1 +Content-Language: en-US +To: bob@example.net +From: Alice +Subject: test message 15:53 +X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0; + attachmentreminder=0; deliveryformat=0 +X-Identity-Key: id3 +Fcc: imap://alice%40example.org@in.example.org/Sent +Content-Type: multipart/signed; micalg=pgp-sha256; + protocol="application/pgp-signature"; + boundary="------------iX39J1p7DOgblwacjo0e7jX7" + +This is an OpenPGP/MIME signed message (RFC 4880 and 3156) +--------------iX39J1p7DOgblwacjo0e7jX7 +Content-Type: multipart/mixed; boundary="------------WD4DG7TcI4p4lbzyM4toRaDw"; + protected-headers="v1" +From: Alice +To: bob@example.net +Message-ID: +Subject: test message 15:53 + +--------------WD4DG7TcI4p4lbzyM4toRaDw +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: base64 + +DQo= + +--------------WD4DG7TcI4p4lbzyM4toRaDw-- + +--------------iX39J1p7DOgblwacjo0e7jX7 +Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename="OpenPGP_signature" + +-----BEGIN PGP SIGNATURE----- + +wsD5BAABCAAjFiEEFKs/ZfwnS721+naMJfAHJFnkeuIFAmObMvwFAwAAAAAACgkQJfAHJFnkeuLM +TgwAnAADX93HE5vXmuBcAbRN2HKIwMzBtRtUF4FNPKchffUvvhSNpHkW2jW7A4hOHNgVSDQdqIUn ++62NgkaKrT1bZqozOZNHXMECHtKBwXWTkIAVqcBdvscCztVIgGby56OPnzZ5y09BsRaqqE5AhDgN +wGCLa6ipu5FYSF6+KzdO0GIPMY5aGRgVhtl4N01v4S3+r/Yu60MkN87nd15Eaqsrs60P9RmKJTt4 +hDie35kKvHnPzLNs8+xLfqPuO/P7ZbPQgkgCwMAMsMDRUYOv+k5c/bL3PKiOENuDpQ7dkKJ2OzSn +nTcg8qhDf17vWe26C/QBhFiGEsrHNBQ1KW5by+cqjIUBJgXElFnPl35S5L3fn6JHZLcz6q+wQuJu +vGT1mJuP//jLFkMHSexukFIVXzn41rWPLd05rBqMgwRcOHMIyzE9zaO1aa8MF2TirPaZ5lH9rx/y +9DCU/d2sqbbYt8TGqj4hM3pqg5K22eq4KT1W7y8+28I5QfjZumLLrHBdYTnR +=6JTB +-----END PGP SIGNATURE----- + +--------------iX39J1p7DOgblwacjo0e7jX7-- diff --git a/test-data/message/thunderbird_with_autocrypt_unencrypted.eml b/test-data/message/thunderbird_with_autocrypt_unencrypted.eml index a8654024ac..201044751a 100644 --- a/test-data/message/thunderbird_with_autocrypt_unencrypted.eml +++ b/test-data/message/thunderbird_with_autocrypt_unencrypted.eml @@ -1,142 +1,142 @@ -From - Fri, 09 Dec 2022 13:16:11 GMT -X-Mozilla-Status: 0801 -X-Mozilla-Status2: 00000000 -Message-ID: <0c8e3ffc-99ae-eb68-15b5-15c4d85a5c12@example.org> -Date: Fri, 9 Dec 2022 10:16:11 -0300 -MIME-Version: 1.0 -User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 - Thunderbird/102.5.1 -Content-Language: en-US -To: bob@example.net -From: Alice -Subject: test message 10:15 -Autocrypt: addr=alice@example.org; keydata= - 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 - rhEBN10sGyg93A== -X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0; - attachmentreminder=0; deliveryformat=0 -X-Identity-Key: id3 -Fcc: imap://alice%40example.org@in.example.org/Sent -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; - boundary="------------FFBOG29BVxcOkoFV1hnc0RaY" - -This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ---------------FFBOG29BVxcOkoFV1hnc0RaY -Content-Type: multipart/mixed; boundary="------------4cwiD0i5NnTXNSfPNpFwrv6V"; - protected-headers="v1" -From: Alice -To: bob@example.net -Message-ID: <0c8e3ffc-99ae-eb68-15b5-15c4d85a5c12@example.org> -Subject: test message 10:15 - ---------------4cwiD0i5NnTXNSfPNpFwrv6V -Content-Type: multipart/mixed; boundary="------------fbNEFvfS22YOKnkTd1oAl0ak" - ---------------fbNEFvfS22YOKnkTd1oAl0ak -Content-Type: text/plain; charset=UTF-8; format=flowed -Content-Transfer-Encoding: base64 - -MTIzDQoNCg== ---------------fbNEFvfS22YOKnkTd1oAl0ak -Content-Type: application/pgp-keys; name="OpenPGP_0xE0D506661947F47C.asc" -Content-Disposition: attachment; filename="OpenPGP_0xE0D506661947F47C.asc" -Content-Description: OpenPGP public key -Content-Transfer-Encoding: quoted-printable - ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -rhEBN10sGyg93A=3D=3D -=3DDPMe ------END PGP PUBLIC KEY BLOCK----- - ---------------fbNEFvfS22YOKnkTd1oAl0ak-- - ---------------4cwiD0i5NnTXNSfPNpFwrv6V-- - ---------------FFBOG29BVxcOkoFV1hnc0RaY -Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" -Content-Description: OpenPGP digital signature -Content-Disposition: attachment; filename="OpenPGP_signature" - ------BEGIN PGP SIGNATURE----- - -wsD5BAABCAAjFiEEvtjufiR1TFlamixB4NUGZhlH9HwFAmOTNRsFAwAAAAAACgkQ4NUGZhlH9Hzw -Iwv/dNC7LDvRGmZ71IaivkUkSTbpGgg0gnCNOuf+B8OxUBQlWPkBmLxyrXbkxsTghFogDsVQeZQQ -DJ182KMgeC//rUN5DPJNrh95YZnav0nUpzW1mkFZjK+PdhbfdXKoXhJIqcw/7lpy/povRYZ20Igg -tIHLa1NlqPPhSx/o2dsEqWeAtXF4e8T/jQSA5+ZQtVrdcTCNQG6zbqlHZuJ7bF1bwuHPgLgDhJ5k -+T2ny80ZtkfLXJl5tQdblAomhBPfEOj+AeLCKsrJFO3WFZOvsuoKMPZpwW1wEh7+QYLABX/lRvqx -IxjH1Tc26vttlOrVH13FKGSeWJELun+b2dP1LPiBQ7DOsrrFNs3fp56Nb7Y+exH5ld0jz0kJZTUD -yPqZpJXTsWkFPE7x1tbH/7goiH8f9DbQrvmqQ2fnCjzf3UJR3ZhG/13YAUEdLVkVzwMItEd6yisg -MP8mlbwm4aDeCiGXO/xhOoBVl6bn1HVSxo7mb0chHVyD1NOfd7qsxem0L/A2 -=MOQB ------END PGP SIGNATURE----- - ---------------FFBOG29BVxcOkoFV1hnc0RaY-- +From - Wed, 14 Dec 2022 18:53:03 GMT +X-Mozilla-Status: 0801 +X-Mozilla-Status2: 00000000 +Message-ID: <87d75c7e-0f52-1335-e437-af605c09f954@example.org> +Date: Wed, 14 Dec 2022 15:53:03 -0300 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.5.1 +Content-Language: en-US +To: bob@example.net +From: Alice +Subject: test message 15:52 +Autocrypt: addr=alice@example.org; keydata= + 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 + /qMLjKwBpKEd/w== +X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0; + attachmentreminder=0; deliveryformat=0 +X-Identity-Key: id3 +Fcc: imap://alice%40example.org@in.example.org/Sent +Content-Type: multipart/signed; micalg=pgp-sha256; + protocol="application/pgp-signature"; + boundary="------------x6XEHrf0vHmVgEo6f9bMGGUy" + +This is an OpenPGP/MIME signed message (RFC 4880 and 3156) +--------------x6XEHrf0vHmVgEo6f9bMGGUy +Content-Type: multipart/mixed; boundary="------------pePWGfS6inyAJsaJRFnx5r9s"; + protected-headers="v1" +From: Alice +To: bob@example.net +Message-ID: <87d75c7e-0f52-1335-e437-af605c09f954@example.org> +Subject: test message 15:52 + +--------------pePWGfS6inyAJsaJRFnx5r9s +Content-Type: multipart/mixed; boundary="------------bG3L0s709hFHGhT5ybFZLKLf" + +--------------bG3L0s709hFHGhT5ybFZLKLf +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: base64 + +DQo= +--------------bG3L0s709hFHGhT5ybFZLKLf +Content-Type: application/pgp-keys; name="OpenPGP_0x25F0072459E47AE2.asc" +Content-Disposition: attachment; filename="OpenPGP_0x25F0072459E47AE2.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +/qMLjKwBpKEd/w=3D=3D +=3DE1VA +-----END PGP PUBLIC KEY BLOCK----- + +--------------bG3L0s709hFHGhT5ybFZLKLf-- + +--------------pePWGfS6inyAJsaJRFnx5r9s-- + +--------------x6XEHrf0vHmVgEo6f9bMGGUy +Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename="OpenPGP_signature" + +-----BEGIN PGP SIGNATURE----- + +wsD5BAABCAAjFiEEFKs/ZfwnS721+naMJfAHJFnkeuIFAmOaG48FAwAAAAAACgkQJfAHJFnkeuJx +1Av/SkGIP18ql7cImI4/t49MvZdIWNuqyKuHZr+7hCPDq0i3muKuy04e8AsGvhHRS8/aSSFkkCgf +OM5JYwHjOVj7DLTGSfbGM9GGpbu4fP6wa+rCm/WHgRr2H/T4ggy6jNv4rBOMcSNXhpO+J/28Zjoi +47Dl1eH6B8HyiwqHSPixRqWAf0d8dIp5S7Wf4asb+cFA+rM/7UlZqidJP5ihtHA3A6C1SNRnMBk/ +g3ABR45srubkgXu5QN4PsUalE0N4I00aCgR6WiPggJE2Zf1kslj5M7az3Az+dp0apRilxrlP4J4Y +KxEzim2X8tJbqvq8G7295NcNDH3YCx3sOT8utXM5NL9how+4c2iylD2m7Oczz3bv0TYDU/4ksWmO +zwiMm+47+45UNLWjQ2sGTpui6nXFC7ZuGxzKjUrbpfvkFDIeFgO1XVw812YDoMHKMaEzr8fDhoKD +LD14JUpwC47XsDlB4ZAMizcCYiK3MvTk1w/5I5ijzJmMiMIpPNxzYxIm82F3 +=wlaI +-----END PGP SIGNATURE----- + +--------------x6XEHrf0vHmVgEo6f9bMGGUy--