WIP: add checksum to shard
This commit is contained in:
parent
64c75085f4
commit
739921d915
|
@ -25,7 +25,7 @@ use keyfork_prompt::{
|
||||||
},
|
},
|
||||||
Message as PromptMessage, PromptHandler,
|
Message as PromptMessage, PromptHandler,
|
||||||
};
|
};
|
||||||
use sha2::Sha256;
|
use sha2::{Digest, Sha256};
|
||||||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||||
|
|
||||||
const PLAINTEXT_LENGTH: u8 = 32 // shard
|
const PLAINTEXT_LENGTH: u8 = 32 // shard
|
||||||
|
@ -59,6 +59,21 @@ impl std::fmt::Display for RetryScanMnemonic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_checksum(slice: &[u8]) -> Vec<u8> {
|
||||||
|
// generate a verification checksum
|
||||||
|
// this checksum should be expensive to calculate
|
||||||
|
let mut payload = vec![];
|
||||||
|
for _ in 0..1_000_000 {
|
||||||
|
payload.extend(slice);
|
||||||
|
let mut hasher = Sha256::new();
|
||||||
|
hasher.update(&payload);
|
||||||
|
let result = hasher.finalize();
|
||||||
|
payload.clear();
|
||||||
|
payload.extend(result);
|
||||||
|
}
|
||||||
|
payload
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "openpgp")]
|
#[cfg(feature = "openpgp")]
|
||||||
pub mod openpgp;
|
pub mod openpgp;
|
||||||
|
|
||||||
|
@ -273,14 +288,23 @@ pub trait Format {
|
||||||
.expect(bug!(POISONED_MUTEX))
|
.expect(bug!(POISONED_MUTEX))
|
||||||
.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
|
.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
|
||||||
loop {
|
loop {
|
||||||
if let Ok(Some(qrcode_content)) = keyfork_qrcode::scan_camera(
|
if let Ok(Some(qrcode_content)) =
|
||||||
std::time::Duration::from_secs(*QRCODE_TIMEOUT),
|
keyfork_qrcode::scan_camera(std::time::Duration::from_secs(*QRCODE_TIMEOUT), 0)
|
||||||
0,
|
{
|
||||||
) {
|
|
||||||
let decoded_data = BASE64_STANDARD
|
let decoded_data = BASE64_STANDARD
|
||||||
.decode(qrcode_content)
|
.decode(qrcode_content)
|
||||||
.expect(bug!("qrcode should contain base64 encoded data"));
|
.expect(bug!("qrcode should contain base64 encoded data"));
|
||||||
pubkey_data = Some(decoded_data.try_into().map_err(|_| InvalidData)?);
|
let data: [u8; 32] = decoded_data.try_into().map_err(|_| InvalidData)?;
|
||||||
|
let checksum = calculate_checksum(&data);
|
||||||
|
let small_sum = &checksum[..8];
|
||||||
|
let small_mnemonic = Mnemonic::from_raw_bytes(small_sum);
|
||||||
|
|
||||||
|
let mut prompt = prompt.lock().expect(bug!(POISONED_MUTEX));
|
||||||
|
prompt.prompt_message(PromptMessage::Text(format!(
|
||||||
|
"Is THIS your card???? If not, press ctrl+c!: {small_mnemonic}"
|
||||||
|
)))?;
|
||||||
|
|
||||||
|
pubkey_data = Some(data);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
let mut prompt = prompt.lock().expect(bug!(POISONED_MUTEX));
|
let mut prompt = prompt.lock().expect(bug!(POISONED_MUTEX));
|
||||||
|
@ -535,15 +559,21 @@ pub fn remote_decrypt(w: &mut impl Write) -> Result<(), Box<dyn std::error::Erro
|
||||||
&BASE64_STANDARD.encode(qrcode_data),
|
&BASE64_STANDARD.encode(qrcode_data),
|
||||||
ErrorCorrection::Highest,
|
ErrorCorrection::Highest,
|
||||||
) {
|
) {
|
||||||
|
let checksum = calculate_checksum(key_mnemonic.as_bytes());
|
||||||
|
let small_sum = &checksum[..8];
|
||||||
|
let small_mnemonic = Mnemonic::from_raw_bytes(small_sum);
|
||||||
pm.prompt_message(PromptMessage::Text(format!(
|
pm.prompt_message(PromptMessage::Text(format!(
|
||||||
concat!(
|
concat!(
|
||||||
"QR code #{iter} will be displayed after this prompt. ",
|
"QR code #{iter} will be displayed after this prompt. ",
|
||||||
"Send the QR code to the next shardholder. ",
|
"Send the QR code to the next shardholder. ",
|
||||||
"Only the next shardholder should scan the QR code."
|
"Only the next shardholder should scan the QR code. ",
|
||||||
),
|
),
|
||||||
iter = iter
|
iter = iter,
|
||||||
)))?;
|
)))?;
|
||||||
pm.prompt_message(PromptMessage::Data(qrcode))?;
|
pm.prompt_message(PromptMessage::Data(qrcode))?;
|
||||||
|
pm.prompt_message(PromptMessage::Text(format!(
|
||||||
|
"The following should be sent to verify the QR code: {small_mnemonic}"
|
||||||
|
)))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,10 +592,9 @@ pub fn remote_decrypt(w: &mut impl Write) -> Result<(), Box<dyn std::error::Erro
|
||||||
{
|
{
|
||||||
pm.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
|
pm.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
|
||||||
loop {
|
loop {
|
||||||
if let Ok(Some(qrcode_content)) = keyfork_qrcode::scan_camera(
|
if let Ok(Some(qrcode_content)) =
|
||||||
std::time::Duration::from_secs(*QRCODE_TIMEOUT),
|
keyfork_qrcode::scan_camera(std::time::Duration::from_secs(*QRCODE_TIMEOUT), 0)
|
||||||
0,
|
{
|
||||||
) {
|
|
||||||
let decoded_data = BASE64_STANDARD
|
let decoded_data = BASE64_STANDARD
|
||||||
.decode(qrcode_content)
|
.decode(qrcode_content)
|
||||||
.expect(bug!("qrcode should contain base64 encoded data"));
|
.expect(bug!("qrcode should contain base64 encoded data"));
|
||||||
|
|
Loading…
Reference in New Issue