mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 18:32:42 +00:00
Reject invalid utf-8 characters during encryption (#1928)
## Issue Addressed Closes #1889 ## Proposed Changes - Error when passwords which use invalid UTF-8 characters during encryption. - Add some tests ## Additional Info I've decided to error when bad characters are used to create/encrypt a keystore but think we should allow them during decryption since either the keystore was created - with invalid UTF-8 characters (possibly by another client or someone whose password is random bytes) in which case we'd want them to be able to decrypt their keystore using the right key. - without invalid characters then the password checksum would almost certainly fail. Happy to add them to decryption if we want to make the decryption more trigger happy 😋 , it would only be a one line change and would tell the user which character index is causing the issue. See https://eips.ethereum.org/EIPS/eip-2335#password-requirements
This commit is contained in:
@@ -59,6 +59,7 @@ pub const HASH_SIZE: usize = 32;
|
||||
pub enum Error {
|
||||
InvalidSecretKeyLen { len: usize, expected: usize },
|
||||
InvalidPassword,
|
||||
InvalidPasswordCharacter { character: u8, index: usize },
|
||||
InvalidSecretKeyBytes(bls::Error),
|
||||
PublicKeyMismatch,
|
||||
EmptyPassword,
|
||||
@@ -158,6 +159,8 @@ impl Keystore {
|
||||
path: String,
|
||||
description: String,
|
||||
) -> Result<Self, Error> {
|
||||
validate_password_utf8_characters(password)?;
|
||||
|
||||
let secret: ZeroizeHash = keypair.sk.serialize();
|
||||
|
||||
let (cipher_text, checksum) = encrypt(secret.as_bytes(), password, &kdf, &cipher)?;
|
||||
@@ -322,7 +325,8 @@ pub fn default_kdf(salt: Vec<u8>) -> Kdf {
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// - The `kdf` is badly formed (e.g., has some values set to zero).
|
||||
/// - If `kdf` is badly formed (e.g., has some values set to zero).
|
||||
/// - If `password` uses utf-8 control characters.
|
||||
pub fn encrypt(
|
||||
plain_text: &[u8],
|
||||
password: &[u8],
|
||||
@@ -384,6 +388,36 @@ pub fn decrypt(password: &[u8], crypto: &Crypto) -> Result<PlainText, Error> {
|
||||
Ok(plain_text)
|
||||
}
|
||||
|
||||
/// Verifies that a password does not contain UTF-8 control characters.
|
||||
pub fn validate_password_utf8_characters(password: &[u8]) -> Result<(), Error> {
|
||||
for (i, char) in password.iter().enumerate() {
|
||||
// C0 - 0x00 to 0x1F
|
||||
if *char <= 0x1F {
|
||||
return Err(Error::InvalidPasswordCharacter {
|
||||
character: *char,
|
||||
index: i,
|
||||
});
|
||||
}
|
||||
|
||||
// C1 - 0x80 to 0x9F
|
||||
if *char >= 0x80 && *char <= 0x9F {
|
||||
return Err(Error::InvalidPasswordCharacter {
|
||||
character: *char,
|
||||
index: i,
|
||||
});
|
||||
}
|
||||
|
||||
// Backspace
|
||||
if *char == 0x7F {
|
||||
return Err(Error::InvalidPasswordCharacter {
|
||||
character: *char,
|
||||
index: i,
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Generates a checksum to indicate that the `derived_key` is associated with the
|
||||
/// `cipher_message`.
|
||||
fn generate_checksum(derived_key: &DerivedKey, cipher_message: &[u8]) -> [u8; HASH_SIZE] {
|
||||
|
||||
Reference in New Issue
Block a user