@@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
33
44use anyhow:: Context ;
55use pyo3:: prelude:: * ;
6- use sequoia_openpgp:: crypto:: { Decryptor , SessionKey } ;
6+ use sequoia_openpgp:: crypto:: { Decryptor , Password , SessionKey } ;
77use sequoia_openpgp:: packet:: { PKESK , SKESK } ;
88use sequoia_openpgp:: parse:: { stream:: * , Parse } ;
99use sequoia_openpgp:: policy:: StandardPolicy as P ;
@@ -14,24 +14,30 @@ use crate::verify::PyVerifier;
1414use crate :: { Decrypted , ValidSig } ;
1515
1616#[ pyclass( from_py_object) ]
17- #[ derive( Clone ) ]
17+ #[ derive( Clone , Default ) ]
1818pub struct PyDecryptor {
19- inner : Arc < Mutex < Box < dyn Decryptor + Send + Sync + ' static > > > ,
19+ inner : Option < Arc < Mutex < Box < dyn Decryptor + Send + Sync + ' static > > > > ,
2020 verifier : Option < PyVerifier > ,
21+ passwords : Vec < Password > ,
2122}
2223
2324impl PyDecryptor {
2425 pub fn new ( inner : Box < dyn Decryptor + Send + Sync + ' static > ) -> Self {
2526 Self {
26- inner : Arc :: new ( Mutex :: new ( inner) ) ,
27+ inner : Some ( Arc :: new ( Mutex :: new ( inner) ) ) ,
2728 verifier : None ,
29+ passwords : Vec :: new ( ) ,
2830 }
2931 }
3032
3133 pub fn set_verifier ( & mut self , verifier : impl Into < Option < PyVerifier > > ) {
3234 self . verifier = verifier. into ( ) ;
3335 }
3436
37+ pub fn set_passwords ( & mut self , passwords : Vec < String > ) {
38+ self . passwords = passwords. into_iter ( ) . map ( Into :: into) . collect ( ) ;
39+ }
40+
3541 pub fn valid_sigs ( self ) -> Vec < ValidSig > {
3642 if let Some ( verifier) = self . verifier {
3743 verifier. valid_sigs ( )
@@ -42,15 +48,25 @@ impl PyDecryptor {
4248}
4349
4450#[ pyfunction]
45- #[ pyo3( signature = ( decryptor , bytes , store=None ) ) ]
51+ #[ pyo3( signature = ( bytes , decryptor= None , store=None , passwords=vec! [ ] ) ) ]
4652pub fn decrypt (
47- mut decryptor : PyDecryptor ,
4853 bytes : & [ u8 ] ,
54+ decryptor : Option < PyDecryptor > ,
4955 store : Option < Py < PyAny > > ,
56+ passwords : Vec < String > ,
5057) -> PyResult < Decrypted > {
58+ if decryptor. is_none ( ) && passwords. is_empty ( ) {
59+ return Err ( anyhow:: anyhow!(
60+ "Either `decryptor` or `passwords` parameter should be given and non-empty."
61+ )
62+ . into ( ) ) ;
63+ }
64+ let mut decryptor = decryptor. unwrap_or_default ( ) ;
65+ decryptor. set_passwords ( passwords) ;
5166 if let Some ( store) = store {
5267 decryptor. set_verifier ( PyVerifier :: from_callback ( store) ) ;
5368 }
69+
5470 let policy = & P :: new ( ) ;
5571
5672 let mut decryptor =
@@ -66,13 +82,22 @@ pub fn decrypt(
6682}
6783
6884#[ pyfunction]
69- #[ pyo3( signature = ( decryptor , input, output, store=None ) ) ]
85+ #[ pyo3( signature = ( input, output, decryptor= None , store=None , passwords=vec! [ ] ) ) ]
7086pub fn decrypt_file (
71- mut decryptor : PyDecryptor ,
7287 input : PathBuf ,
7388 output : PathBuf ,
89+ decryptor : Option < PyDecryptor > ,
7490 store : Option < Py < PyAny > > ,
91+ passwords : Vec < String > ,
7592) -> PyResult < Decrypted > {
93+ if decryptor. is_none ( ) && passwords. is_empty ( ) {
94+ return Err ( anyhow:: anyhow!(
95+ "Either `decryptor` or `passwords` parameter should be given and non-empty."
96+ )
97+ . into ( ) ) ;
98+ }
99+ let mut decryptor = decryptor. unwrap_or_default ( ) ;
100+ decryptor. set_passwords ( passwords) ;
76101 if let Some ( store) = store {
77102 decryptor. set_verifier ( PyVerifier :: from_callback ( store) ) ;
78103 }
@@ -113,19 +138,31 @@ impl DecryptionHelper for PyDecryptor {
113138 fn decrypt (
114139 & mut self ,
115140 pkesks : & [ PKESK ] ,
116- _skesks : & [ SKESK ] ,
141+ skesks : & [ SKESK ] ,
117142 sym_algo : Option < SymmetricAlgorithm > ,
118143 decrypt : & mut dyn FnMut ( Option < SymmetricAlgorithm > , & SessionKey ) -> bool ,
119144 ) -> sequoia_openpgp:: Result < Option < cert:: Cert > > {
120- let pair = & mut * self . inner . lock ( ) . unwrap ( ) ;
121-
122- for pkesk in pkesks. iter ( ) {
123- if pkesk
124- . decrypt ( pair, sym_algo)
125- . map ( |( algo, session_key) | decrypt ( algo, & session_key) )
126- . is_some ( )
127- {
128- return Ok ( None ) ;
145+ for skesk in skesks. iter ( ) {
146+ for password in self . passwords . iter ( ) {
147+ if let Ok ( ( algo, session_key) ) = skesk. decrypt ( password) {
148+ if decrypt ( algo, & session_key) {
149+ return Ok ( None ) ;
150+ }
151+ }
152+ }
153+ }
154+
155+ if let Some ( inner) = & mut self . inner {
156+ let pair = & mut * inner. lock ( ) . unwrap ( ) ;
157+
158+ for pkesk in pkesks. iter ( ) {
159+ if pkesk
160+ . decrypt ( pair, sym_algo)
161+ . map ( |( algo, session_key) | decrypt ( algo, & session_key) )
162+ . is_some ( )
163+ {
164+ return Ok ( None ) ;
165+ }
129166 }
130167 }
131168
0 commit comments