Import wallet fix (#1820)

* fixed importing presale wallet with encseed longer than 96 bytes

* fixed incorrect pkcs unpadding in decrypting presale wallet
This commit is contained in:
Marek Kotewicz 2016-08-03 15:24:09 +02:00 committed by Gav Wood
parent 9fb5623569
commit 6ba1e66d32
3 changed files with 14 additions and 11 deletions

View File

@ -138,7 +138,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
let ok = store.change_password(&address, &old_pwd, &new_pwd).is_ok(); let ok = store.change_password(&address, &old_pwd, &new_pwd).is_ok();
Ok(format!("{}", ok)) Ok(format!("{}", ok))
} else if args.cmd_list { } else if args.cmd_list {
let accounts = store.accounts(); let accounts = try!(store.accounts());
Ok(format_accounts(&accounts)) Ok(format_accounts(&accounts))
} else if args.cmd_import { } else if args.cmd_import {
let src = try!(key_dir(&args.flag_src)); let src = try!(key_dir(&args.flag_src));

View File

@ -68,7 +68,7 @@ pub mod aes {
use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding}; use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding};
use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor}; use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor};
use rcrypto::symmetriccipher::{Encryptor, Decryptor, SymmetricCipherError}; use rcrypto::symmetriccipher::{Encryptor, Decryptor, SymmetricCipherError};
use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer}; use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer, WriteBuffer};
/// Encrypt a message /// Encrypt a message
pub fn encrypt(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) { pub fn encrypt(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) {
@ -83,10 +83,12 @@ pub mod aes {
} }
/// Decrypt a message using cbc mode /// Decrypt a message using cbc mode
pub fn decrypt_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmetricCipherError> { pub fn decrypt_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<usize, SymmetricCipherError> {
let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec()); let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec());
try!(encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)); let len = dest.len();
Ok(()) let mut buffer = RefWriteBuffer::new(dest);
try!(encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true));
Ok(len - buffer.remaining())
} }
} }

View File

@ -10,7 +10,7 @@ use {crypto, Error};
pub struct PresaleWallet { pub struct PresaleWallet {
iv: [u8; 16], iv: [u8; 16],
ciphertext: [u8; 80], ciphertext: Vec<u8>,
address: Address, address: Address,
} }
@ -19,8 +19,8 @@ impl From<json::PresaleWallet> for PresaleWallet {
let mut iv = [0u8; 16]; let mut iv = [0u8; 16];
iv.copy_from_slice(&wallet.encseed[..16]); iv.copy_from_slice(&wallet.encseed[..16]);
let mut ciphertext = [0u8; 80]; let mut ciphertext = vec![];
ciphertext.copy_from_slice(&wallet.encseed[16..]); ciphertext.extend_from_slice(&wallet.encseed[16..]);
PresaleWallet { PresaleWallet {
iv: iv, iv: iv,
@ -42,10 +42,11 @@ impl PresaleWallet {
let mut derived_key = vec![0u8; 16]; let mut derived_key = vec![0u8; 16];
pbkdf2(&mut h_mac, password.as_bytes(), 2000, &mut derived_key); pbkdf2(&mut h_mac, password.as_bytes(), 2000, &mut derived_key);
let mut key = [0u8; 64]; let mut key = vec![0; self.ciphertext.len()];
try!(crypto::aes::decrypt_cbc(&derived_key, &self.iv, &self.ciphertext, &mut key).map_err(|_| Error::InvalidPassword)); let len = try!(crypto::aes::decrypt_cbc(&derived_key, &self.iv, &self.ciphertext, &mut key).map_err(|_| Error::InvalidPassword));
let unpadded = &key[..len];
let secret = Secret::from(key.keccak256()); let secret = Secret::from(unpadded.keccak256());
if let Ok(kp) = KeyPair::from_secret(secret) { if let Ok(kp) = KeyPair::from_secret(secret) {
if kp.address() == self.address { if kp.address() == self.address {
return Ok(kp) return Ok(kp)