@@ -5,8 +5,8 @@ use std::io::Write;
55use std:: { fs:: File , io:: Read } ;
66
77use age:: {
8- DecryptError as RageDecryptError , EncryptError as RageEncryptError , Encryptor , Identity ,
9- Recipient ,
8+ armor :: ArmoredReader , armor :: ArmoredWriter , armor :: Format , DecryptError as RageDecryptError ,
9+ EncryptError as RageEncryptError , Encryptor , Identity , Recipient ,
1010} ;
1111use age_core:: format:: { FileKey , Stanza } ;
1212use pyo3:: {
@@ -136,10 +136,12 @@ impl<'source> FromPyObject<'source> for Box<dyn PyrageIdentity> {
136136create_exception ! ( pyrage, EncryptError , PyException ) ;
137137
138138#[ pyfunction]
139+ #[ pyo3( signature = ( plaintext, recipients, armored=false ) ) ]
139140fn encrypt < ' p > (
140141 py : Python < ' p > ,
141142 plaintext : & [ u8 ] ,
142143 recipients : Vec < Box < dyn PyrageRecipient > > ,
144+ armored : bool ,
143145) -> PyResult < Bound < ' p , PyBytes > > {
144146 // This turns each `dyn PyrageRecipient` into a `dyn Recipient`, which
145147 // is what the underlying `age` API expects.
@@ -151,13 +153,25 @@ fn encrypt<'p>(
151153 let encryptor = Encryptor :: with_recipients ( recipients. iter ( ) . map ( |r| r. as_ref ( ) ) )
152154 . map_err ( |_| EncryptError :: new_err ( "expected at least one recipient" ) ) ?;
153155 let mut encrypted = vec ! [ ] ;
154- let mut writer = encryptor
155- . wrap_output ( & mut encrypted)
156- . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
156+
157+ let mut writer = match armored {
158+ true => encryptor
159+ . wrap_output ( ArmoredWriter :: wrap_output (
160+ & mut encrypted,
161+ Format :: AsciiArmor ,
162+ ) ?)
163+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
164+ false => encryptor
165+ . wrap_output ( ArmoredWriter :: wrap_output ( & mut encrypted, Format :: Binary ) ?)
166+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
167+ } ;
168+
157169 writer
158170 . write_all ( plaintext)
159171 . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
160172 writer
173+ . finish ( )
174+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?
161175 . finish ( )
162176 . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
163177
@@ -166,10 +180,12 @@ fn encrypt<'p>(
166180}
167181
168182#[ pyfunction]
183+ #[ pyo3( signature = ( infile, outfile, recipients, armored=false ) ) ]
169184fn encrypt_file (
170185 infile : String ,
171186 outfile : String ,
172187 recipients : Vec < Box < dyn PyrageRecipient > > ,
188+ armored : bool ,
173189) -> PyResult < ( ) > {
174190 // This turns each `dyn PyrageRecipient` into a `dyn Recipient`, which
175191 // is what the underlying `age` API expects.
@@ -186,13 +202,21 @@ fn encrypt_file(
186202
187203 let encryptor = Encryptor :: with_recipients ( recipients. iter ( ) . map ( |r| r. as_ref ( ) ) )
188204 . map_err ( |_| EncryptError :: new_err ( "expected at least one recipient" ) ) ?;
189- let mut writer = encryptor
190- . wrap_output ( & mut writer)
191- . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
205+
206+ let mut writer = match armored {
207+ true => encryptor
208+ . wrap_output ( ArmoredWriter :: wrap_output ( & mut writer, Format :: AsciiArmor ) ?)
209+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
210+ false => encryptor
211+ . wrap_output ( ArmoredWriter :: wrap_output ( & mut writer, Format :: Binary ) ?)
212+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
213+ } ;
192214
193215 std:: io:: copy ( & mut reader, & mut writer) . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
194216
195217 writer
218+ . finish ( )
219+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?
196220 . finish ( )
197221 . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
198222
@@ -209,8 +233,8 @@ fn decrypt<'p>(
209233) -> PyResult < Bound < ' p , PyBytes > > {
210234 let identities = identities. iter ( ) . map ( |pi| pi. as_ref ( ) . as_identity ( ) ) ;
211235
212- let decryptor =
213- age :: Decryptor :: new ( ciphertext ) . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
236+ let decryptor = age :: Decryptor :: new ( ArmoredReader :: new ( ciphertext ) )
237+ . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
214238
215239 let mut decrypted = vec ! [ ] ;
216240 let mut reader = decryptor
@@ -238,8 +262,8 @@ fn decrypt_file(
238262 let reader = std:: io:: BufReader :: new ( reader) ;
239263 let mut writer = std:: io:: BufWriter :: new ( writer) ;
240264
241- let decryptor =
242- age :: Decryptor :: new_buffered ( reader ) . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
265+ let decryptor = age :: Decryptor :: new_buffered ( ArmoredReader :: new ( reader ) )
266+ . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
243267
244268 let mut reader = decryptor
245269 . decrypt ( identities)
@@ -256,10 +280,12 @@ fn from_pyobject(file: PyObject, read_only: bool) -> PyResult<PyFileLikeObject>
256280}
257281
258282#[ pyfunction]
283+ #[ pyo3( signature = ( reader, writer, recipients, armored=false ) ) ]
259284fn encrypt_io (
260285 reader : PyObject ,
261286 writer : PyObject ,
262287 recipients : Vec < Box < dyn PyrageRecipient > > ,
288+ armored : bool ,
263289) -> PyResult < ( ) > {
264290 // This turns each `dyn PyrageRecipient` into a `dyn Recipient`, which
265291 // is what the underlying `age` API expects.
@@ -271,15 +297,27 @@ fn encrypt_io(
271297 let writer = from_pyobject ( writer, false ) ?;
272298 let mut reader = std:: io:: BufReader :: new ( reader) ;
273299 let mut writer = std:: io:: BufWriter :: new ( writer) ;
300+
274301 let encryptor = Encryptor :: with_recipients ( recipients. iter ( ) . map ( |r| r. as_ref ( ) ) )
275302 . map_err ( |_| EncryptError :: new_err ( "expected at least one recipient" ) ) ?;
276- let mut writer = encryptor
277- . wrap_output ( & mut writer)
278- . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
303+
304+ let mut writer = match armored {
305+ true => encryptor
306+ . wrap_output ( ArmoredWriter :: wrap_output ( & mut writer, Format :: AsciiArmor ) ?)
307+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
308+ false => encryptor
309+ . wrap_output ( ArmoredWriter :: wrap_output ( & mut writer, Format :: Binary ) ?)
310+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?,
311+ } ;
312+
279313 std:: io:: copy ( & mut reader, & mut writer) . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
314+
280315 writer
316+ . finish ( )
317+ . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?
281318 . finish ( )
282319 . map_err ( |e| EncryptError :: new_err ( e. to_string ( ) ) ) ?;
320+
283321 Ok ( ( ) )
284322}
285323
@@ -294,8 +332,8 @@ fn decrypt_io(
294332 let writer = from_pyobject ( writer, false ) ?;
295333 let reader = std:: io:: BufReader :: new ( reader) ;
296334 let mut writer = std:: io:: BufWriter :: new ( writer) ;
297- let decryptor =
298- age :: Decryptor :: new_buffered ( reader ) . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
335+ let decryptor = age :: Decryptor :: new_buffered ( ArmoredReader :: new ( reader ) )
336+ . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
299337 let mut reader = decryptor
300338 . decrypt ( identities)
301339 . map_err ( |e| DecryptError :: new_err ( e. to_string ( ) ) ) ?;
0 commit comments