@@ -23,7 +23,6 @@ use std::{
2323 collections:: { hash_map:: DefaultHasher , BTreeMap } ,
2424 future:: Future ,
2525 hash:: { Hash , Hasher } ,
26- pin:: Pin ,
2726 sync:: { Arc , Mutex } ,
2827} ;
2928
@@ -38,6 +37,8 @@ use melib::{
3837 parser:: BytesExt ,
3938} ;
4039
40+ use super :: AttachmentBoxFuture ;
41+
4142pub async fn decrypt ( raw : Vec < u8 > ) -> Result < ( melib_pgp:: DecryptionMetadata , Vec < u8 > ) > {
4243 let mut ctx = Context :: new ( ) ?;
4344 let cipher = ctx. new_data_mem ( & raw ) ?;
@@ -88,31 +89,47 @@ pub fn sign_filter(
8889 Box :: pin ( async move {
8990 if let Some ( default_key) = default_key {
9091 let mut ctx = Context :: new ( ) ?;
91- let data = ctx. new_data_mem ( & melib_pgp:: convert_attachment_to_rfc_spec (
92- a. into_raw ( ) . as_bytes ( ) ,
93- ) ) ?;
94- let sig_attachment = Attachment :: new (
95- ContentType :: PGPSignature ,
96- Default :: default ( ) ,
97- ctx. sign ( sign_keys, data) ?. await ?,
98- ) ;
99- let a: AttachmentBuilder = a. into ( ) ;
100- let parts = vec ! [ a, sig_attachment. into( ) ] ;
101- let boundary = ContentType :: make_boundary ( & parts) ;
102- Ok ( Attachment :: new (
103- ContentType :: Multipart {
104- boundary : boundary. into_bytes ( ) ,
105- kind : MultipartType :: Signed ,
106- parts : parts. into_iter ( ) . map ( |a| a. into ( ) ) . collect :: < Vec < _ > > ( ) ,
107- parameters : vec ! [ ] ,
108- } ,
109- Default :: default ( ) ,
110- vec ! [ ] ,
111- )
112- . into ( ) )
113- } )
114- } ,
115- )
92+ ctx. set_auto_key_locate ( LocateKey :: LOCAL ) ?;
93+ let keys = ctx. keylist ( false , Some ( default_key. clone ( ) ) ) ?. await ?;
94+ if keys. is_empty ( ) {
95+ return Err ( Error :: new ( format ! (
96+ "Could not locate sign key with ID `{}`" ,
97+ default_key
98+ ) ) ) ;
99+ }
100+ sign_keys. extend ( keys) ;
101+ }
102+ if sign_keys. is_empty ( ) {
103+ return Err ( Error :: new (
104+ "No key was selected for signing; please select one." ,
105+ ) ) ;
106+ }
107+ let a: Attachment = a. into ( ) ;
108+ let mut ctx = Context :: new ( ) ?;
109+ let data = ctx. new_data_mem ( & melib_pgp:: convert_attachment_to_rfc_spec (
110+ a. into_raw ( ) . as_bytes ( ) ,
111+ ) ) ?;
112+ let sig_attachment = Attachment :: new (
113+ ContentType :: PGPSignature ,
114+ Default :: default ( ) ,
115+ ctx. sign ( sign_keys, data) ?. await ?,
116+ ) ;
117+ let a: AttachmentBuilder = a. into ( ) ;
118+ let parts = vec ! [ a, sig_attachment. into( ) ] ;
119+ let boundary = ContentType :: make_boundary ( & parts) ;
120+ Ok ( Attachment :: new (
121+ ContentType :: Multipart {
122+ boundary : boundary. into_bytes ( ) ,
123+ kind : MultipartType :: Signed ,
124+ parts : parts. into_iter ( ) . map ( |a| a. into ( ) ) . collect :: < Vec < _ > > ( ) ,
125+ parameters : vec ! [ ] ,
126+ } ,
127+ Default :: default ( ) ,
128+ vec ! [ ] ,
129+ )
130+ . into ( ) )
131+ } )
132+ } )
116133}
117134
118135pub fn encrypt_filter (
@@ -166,37 +183,62 @@ pub fn encrypt_filter(
166183 }
167184 if let Some ( encrypt_for_self) = encrypt_for_self {
168185 let mut ctx = Context :: new ( ) ?;
169- let data = ctx. new_data_mem (
170- a. into_raw ( ) . as_bytes ( )
171- ) ?;
172-
173- let sig_attachment = {
174- let mut a = Attachment :: new (
175- ContentType :: OctetStream { name : None , parameters : vec ! [ ] } ,
176- Default :: default ( ) ,
177- ctx. encrypt ( sign_keys, encrypt_keys, data) ?. await ?,
178- ) ;
179- a. content_disposition = ContentDisposition :: from ( br#"attachment; filename="msg.asc""# ) ;
180- a
181- } ;
182- let mut a: AttachmentBuilder = AttachmentBuilder :: new ( b"Version: 1\n " ) ;
186+ ctx. set_auto_key_locate ( LocateKey :: LOCAL ) ?;
187+ let keys = ctx
188+ . keylist ( false , Some ( encrypt_for_self. to_string ( ) ) ) ?
189+ . await ?;
190+ if keys. is_empty ( ) {
191+ return Err ( Error :: new ( format ! (
192+ "Could not locate personal encryption key for address `{}`" ,
193+ encrypt_for_self
194+ ) ) ) ;
195+ }
196+ for key in keys {
197+ if !encrypt_keys. contains ( & key) {
198+ encrypt_keys. push ( key) ;
199+ }
200+ }
201+ }
202+ let a: Attachment = a. into ( ) ;
203+ log:: trace!(
204+ "main attachment is {:?} sign_keys = {:?} encrypt_keys = {:?}" ,
205+ & a,
206+ & sign_keys,
207+ & encrypt_keys
208+ ) ;
209+ let mut ctx = Context :: new ( ) ?;
210+ let data = ctx. new_data_mem ( a. into_raw ( ) . as_bytes ( ) ) ?;
183211
184- a. set_content_type_from_bytes ( b"application/pgp-encrypted" ) ;
185- a. set_content_disposition ( ContentDisposition :: from ( b"attachment" ) ) ;
186- let parts = vec ! [ a, sig_attachment. into( ) ] ;
187- let boundary = ContentType :: make_boundary ( & parts) ;
188- Ok ( Attachment :: new (
189- ContentType :: Multipart {
190- boundary : boundary. into_bytes ( ) ,
191- kind : MultipartType :: Encrypted ,
192- parts : parts. into_iter ( ) . map ( |a| a. into ( ) ) . collect :: < Vec < _ > > ( ) ,
212+ let enc_attachment = {
213+ let mut a = Attachment :: new (
214+ ContentType :: OctetStream {
215+ name : None ,
193216 parameters : vec ! [ ] ,
194217 } ,
195218 Default :: default ( ) ,
196- vec ! [ ] ,
197- )
198- . into ( ) )
199- } )
200- } ,
201- )
219+ ctx. encrypt ( sign_keys, encrypt_keys, data) ?. await ?,
220+ ) ;
221+ a. content_disposition =
222+ ContentDisposition :: from ( br#"attachment; filename="msg.asc""# ) ;
223+ a
224+ } ;
225+ let mut a: AttachmentBuilder = AttachmentBuilder :: new ( b"Version: 1\n " ) ;
226+
227+ a. set_content_type_from_bytes ( b"application/pgp-encrypted" ) ;
228+ a. set_content_disposition ( ContentDisposition :: from ( b"attachment" ) ) ;
229+ let parts = vec ! [ a, enc_attachment. into( ) ] ;
230+ let boundary = ContentType :: make_boundary ( & parts) ;
231+ Ok ( Attachment :: new (
232+ ContentType :: Multipart {
233+ boundary : boundary. into_bytes ( ) ,
234+ kind : MultipartType :: Encrypted ,
235+ parts : parts. into_iter ( ) . map ( |a| a. into ( ) ) . collect :: < Vec < _ > > ( ) ,
236+ parameters : vec ! [ ] ,
237+ } ,
238+ Default :: default ( ) ,
239+ vec ! [ ] ,
240+ )
241+ . into ( ) )
242+ } )
243+ } )
202244}
0 commit comments