feat: libpaket: use secrecy on packstation credentials
This commit is contained in:
parent
afcfe0c9ef
commit
d7e905f7eb
2 changed files with 43 additions and 30 deletions
|
@ -1,41 +1,53 @@
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use rand::prelude::*;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use ed25519_dalek::SigningKey;
|
|
||||||
use ed25519_dalek::Signer;
|
use ed25519_dalek::Signer;
|
||||||
|
use ed25519_dalek::SigningKey;
|
||||||
|
use rand::prelude::*;
|
||||||
|
use secrecy::zeroize::Zeroize;
|
||||||
|
use secrecy::ExposeSecret;
|
||||||
|
use secrecy::SecretBox;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct CustomerKeySeed {
|
pub struct CustomerKeySeed {
|
||||||
pub postnumber: String,
|
pub postnumber: String,
|
||||||
pub seed: Seed,
|
pub seed: SecretBox<Seed>,
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
pub device_id: Option<String>,
|
pub device_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Seed {
|
impl Zeroize for CustomerKeySeed {
|
||||||
bytes: Vec<u8>,
|
fn zeroize(&mut self) {
|
||||||
|
self.postnumber.zeroize();
|
||||||
|
self.seed.zeroize();
|
||||||
|
self.uuid.into_bytes().zeroize();
|
||||||
|
self.device_id.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Seed(Vec<u8>);
|
||||||
|
impl Zeroize for Seed {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.0.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<u8>> for Seed {
|
||||||
|
fn from(value: Vec<u8>) -> Self {
|
||||||
|
assert_eq!(value.len(), 32);
|
||||||
|
Seed(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Seed {
|
impl Seed {
|
||||||
pub(self) fn from_bytes(bytes: Vec<u8>) -> Self {
|
|
||||||
assert_eq!(bytes.len(), 32);
|
|
||||||
Seed {
|
|
||||||
bytes: bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn random() -> Self {
|
pub fn random() -> Self {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
let mut bytes: Vec<u8> = vec![0; 32];
|
let mut bytes: Vec<u8> = vec![0; 32];
|
||||||
|
|
||||||
rng.fill_bytes(bytes.as_mut_slice());
|
rng.fill_bytes(bytes.as_mut_slice());
|
||||||
|
Seed (bytes)
|
||||||
Seed { bytes: bytes }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_bytes(&self) -> &[u8; 32] {
|
pub fn as_bytes(&self) -> &[u8; 32] {
|
||||||
(&self.bytes[..]).try_into().unwrap()
|
(&self.0[..]).try_into().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +55,7 @@ impl CustomerKeySeed {
|
||||||
pub fn new(postnumber: String) -> Self {
|
pub fn new(postnumber: String) -> Self {
|
||||||
CustomerKeySeed {
|
CustomerKeySeed {
|
||||||
postnumber,
|
postnumber,
|
||||||
seed: Seed::random(),
|
seed: SecretBox::new(Box::new(Seed::random())),
|
||||||
uuid: uuid::Uuid::new_v4(),
|
uuid: uuid::Uuid::new_v4(),
|
||||||
device_id: None,
|
device_id: None,
|
||||||
}
|
}
|
||||||
|
@ -52,7 +64,7 @@ impl CustomerKeySeed {
|
||||||
pub fn from(postnumber: &String, seed: Vec<u8>, uuid: &Uuid, device_id: String) -> Self {
|
pub fn from(postnumber: &String, seed: Vec<u8>, uuid: &Uuid, device_id: String) -> Self {
|
||||||
CustomerKeySeed {
|
CustomerKeySeed {
|
||||||
postnumber: postnumber.clone(),
|
postnumber: postnumber.clone(),
|
||||||
seed: Seed::from_bytes(seed),
|
seed: SecretBox::new(Box::new(Seed::from(seed))),
|
||||||
uuid: uuid.clone(),
|
uuid: uuid.clone(),
|
||||||
device_id: Some(device_id),
|
device_id: Some(device_id),
|
||||||
}
|
}
|
||||||
|
@ -65,17 +77,15 @@ impl CustomerKeySeed {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn sign(&self, message: &[u8]) -> String {
|
pub(crate) fn sign(&self, message: &[u8]) -> String {
|
||||||
let signing_key = SigningKey::from_bytes(self.seed.as_bytes());
|
let signing_key = SigningKey::from_bytes(self.seed.expose_secret().as_bytes());
|
||||||
|
|
||||||
let signature = signing_key.sign(message);
|
let signature = signing_key.sign(message);
|
||||||
|
|
||||||
let sig_str = general_purpose::STANDARD.encode(signature.to_bytes());
|
let sig_str = general_purpose::STANDARD.encode(signature.to_bytes());
|
||||||
|
|
||||||
format!("{}.{}", self.uuid.to_string(), sig_str)
|
format!("{}.{}", self.uuid.to_string(), sig_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_public_key(&self) -> String {
|
pub(crate) fn get_public_key(&self) -> String {
|
||||||
let signing_key = SigningKey::from_bytes(self.seed.as_bytes());
|
let signing_key = SigningKey::from_bytes(self.seed.expose_secret().as_bytes());
|
||||||
let public_bytes = signing_key.verifying_key().to_bytes();
|
let public_bytes = signing_key.verifying_key().to_bytes();
|
||||||
let public_str = general_purpose::STANDARD.encode(public_bytes);
|
let public_str = general_purpose::STANDARD.encode(public_bytes);
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@ use sha2::Sha256;
|
||||||
|
|
||||||
use crate::{LibraryResult, LibraryError};
|
use crate::{LibraryResult, LibraryError};
|
||||||
|
|
||||||
pub struct RegToken {
|
pub struct RegToken(Vec<u8>);
|
||||||
token: Vec<u8>,
|
impl secrecy::zeroize::Zeroize for RegToken {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.0.zeroize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegToken {
|
impl RegToken {
|
||||||
|
@ -32,15 +35,15 @@ impl RegToken {
|
||||||
token.extend(vec![0; 32 - token.len()].iter())
|
token.extend(vec![0; 32 - token.len()].iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(RegToken { token })
|
Ok(RegToken(token))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn customer_password(&self) -> String {
|
pub fn customer_password(&self) -> String {
|
||||||
general_purpose::STANDARD.encode(&self.token[32..])
|
general_purpose::STANDARD.encode(&self.0[32..])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hmac(&self) -> SimpleHmac<Sha256> {
|
pub fn hmac(&self) -> SimpleHmac<Sha256> {
|
||||||
let mac = SimpleHmac::<Sha256>::new_from_slice(&self.token[0..32])
|
let mac = SimpleHmac::<Sha256>::new_from_slice(&self.0[0..32])
|
||||||
.expect("HMAC can take key of any size");
|
.expect("HMAC can take key of any size");
|
||||||
|
|
||||||
mac
|
mac
|
||||||
|
|
Loading…
Reference in a new issue