22//!
33//! A JSON "`crypto`" object as defined in
44//! [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335#json-schema), with an additional optional
5- //! "`pubKey`" property containing the public key as encoded by [`public::to_base64`].
5+ //! "`pubkey`" property containing the public key as encoded by [`public::to_base64`].
6+ //!
7+ //! For backward compatibility, the property name "`pubKey`" (capital K) is also accepted when
8+ //! deserializing, but new keys will be generated with "`pubkey`" (lowercase).
69//!
710//! Example structure:
811//!
3033//! "salt": "..."
3134//! }
3235//! },
33- //! "pubKey ": "..."
36+ //! "pubkey ": "..."
3437//! }
3538//! ```
3639use eth2_keystore:: {
@@ -52,7 +55,7 @@ use crate::{ConversionError, public};
5255pub struct EncryptedKey {
5356 #[ serde( default ) ]
5457 #[ serde( skip_serializing_if = "Option::is_none" ) ]
55- #[ serde( rename = "pubKey" ) ]
58+ #[ serde( alias = "pubKey" ) ]
5659 pubkey : Option < String > ,
5760 kdf : KdfModule ,
5861 checksum : ChecksumModule ,
@@ -92,8 +95,9 @@ impl EncryptedKey {
9295
9396 /// Decrypt the private key from the keystore.
9497 ///
95- /// If the pubkey was provided along the encrypted key in a "pubKey" attribute, it is verified
96- /// whether the encrypted key matches the public key.
98+ /// If the pubkey was provided along the encrypted key in a "pubkey" attribute, it is verified
99+ /// whether the encrypted key matches the public key. "pubKey" is also accepted for backwards
100+ /// compatibility with legacy keys.
97101 pub fn decrypt ( & self , password : & str ) -> Result < Rsa < Private > , DecryptionError > {
98102 let pem = eth2_keystore:: decrypt ( password. as_ref ( ) , & self . as_crypto ( ) )
99103 . map_err ( DecryptionError :: Keystore ) ?;
@@ -190,4 +194,24 @@ mod tests {
190194 . unwrap ( ) ;
191195 encrypted. decrypt ( password) . unwrap ( ) ;
192196 }
197+
198+ #[ test]
199+ fn test_decrypt_legacy ( ) {
200+ let password = "what" ;
201+ let encrypted = EncryptedKey :: try_from ( include_str ! (
202+ "../test_keys/encrypted_private_key_legacy.json"
203+ ) )
204+ . unwrap ( ) ;
205+ encrypted. decrypt ( password) . unwrap ( ) ;
206+ }
207+
208+ #[ test]
209+ fn test_encrypt_uses_lowercase_pubkey ( ) {
210+ let key = Rsa :: generate ( 2048 ) . unwrap ( ) ;
211+ let password = "test" ;
212+ let encrypted = EncryptedKey :: encrypt ( & key, password) . unwrap ( ) ;
213+ let json = serde_json:: to_string ( & encrypted) . unwrap ( ) ;
214+ assert ! ( json. contains( r#""pubkey":"# ) ) ;
215+ assert ! ( !json. contains( r#""pubKey":"# ) ) ;
216+ }
193217}
0 commit comments