Skip to main content

core_crypto_keystore/
database_key.rs

1use std::{fmt, ops::Deref};
2
3use sha2::{Digest as _, Sha256};
4use zeroize::{Zeroize, ZeroizeOnDrop};
5
6use crate::CryptoKeystoreError;
7
8/// The key used to encrypt the database.
9#[derive(Clone, Zeroize, ZeroizeOnDrop, derive_more::From, PartialEq, Eq)]
10pub struct DatabaseKey([u8; Self::LEN]);
11
12impl DatabaseKey {
13    pub const LEN: usize = 32;
14
15    pub fn generate() -> DatabaseKey {
16        DatabaseKey(rand::random::<[u8; Self::LEN]>())
17    }
18}
19
20impl fmt::Debug for DatabaseKey {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
22        f.write_str("DatabaseKey(hash=")?;
23        for x in Sha256::digest(self).as_slice().iter().take(10) {
24            fmt::LowerHex::fmt(x, f)?
25        }
26        f.write_str("...)")
27    }
28}
29
30impl AsRef<[u8; DatabaseKey::LEN]> for DatabaseKey {
31    fn as_ref(&self) -> &[u8; DatabaseKey::LEN] {
32        &self.0
33    }
34}
35
36impl AsRef<[u8]> for DatabaseKey {
37    fn as_ref(&self) -> &[u8] {
38        &self.0
39    }
40}
41
42impl Deref for DatabaseKey {
43    type Target = [u8];
44
45    fn deref(&self) -> &Self::Target {
46        &self.0
47    }
48}
49
50impl TryFrom<&[u8]> for DatabaseKey {
51    type Error = CryptoKeystoreError;
52
53    fn try_from(buf: &[u8]) -> Result<Self, Self::Error> {
54        if buf.len() != Self::LEN {
55            Err(CryptoKeystoreError::InvalidDbKeySize {
56                expected: Self::LEN,
57                actual: buf.len(),
58            })
59        } else {
60            Ok(Self(buf.try_into().unwrap()))
61        }
62    }
63}
64
65impl TryFrom<Vec<u8>> for DatabaseKey {
66    type Error = CryptoKeystoreError;
67
68    fn try_from(buf: Vec<u8>) -> Result<Self, Self::Error> {
69        if buf.len() != Self::LEN {
70            Err(CryptoKeystoreError::InvalidDbKeySize {
71                expected: Self::LEN,
72                actual: buf.len(),
73            })
74        } else {
75            Ok(Self(buf.try_into().unwrap()))
76        }
77    }
78}