bitwarden_crypto/keys/key_id.rs
1use rand::RngCore;
2use uuid::Uuid;
3
4const UUID_SEED_SIZE: usize = 16;
5
6/// Since `KeyId` is a wrapper around UUIDs, this is statically 16 bytes.
7pub(crate) const KEY_ID_SIZE: usize = 16;
8
9/// A key id is a unique identifier for a single key. There is a 1:1 mapping between key ID and key
10/// bytes, so something like a user key rotation is replacing the key with ID A with a new key with
11/// ID B.
12#[derive(Clone)]
13pub(crate) struct KeyId(Uuid);
14
15/// Fixed length identifiers for keys.
16/// These are intended to be unique and constant per-key.
17///
18/// Currently these are randomly generated 16 byte identifiers, which is considered safe to randomly
19/// generate with vanishingly small collision chance. However, the generation of IDs is an internal
20/// concern and may change in the future.
21impl KeyId {
22 /// Creates a new random key ID randomly, sampled from the crates CSPRNG.
23 pub fn make() -> Self {
24 // We do not use the uuid crate's random generation functionality here to make sure the
25 // entropy sampling aligns with the rest of this crates usage of CSPRNGs.
26 let mut random_seed = [0u8; UUID_SEED_SIZE];
27 rand::thread_rng().fill_bytes(&mut random_seed);
28
29 let uuid = uuid::Builder::from_random_bytes(random_seed)
30 .with_version(uuid::Version::Random)
31 .with_variant(uuid::Variant::RFC4122);
32 Self(uuid.into_uuid())
33 }
34}
35
36impl From<KeyId> for [u8; KEY_ID_SIZE] {
37 fn from(key_id: KeyId) -> Self {
38 key_id.0.into_bytes()
39 }
40}
41
42impl From<&KeyId> for Vec<u8> {
43 fn from(key_id: &KeyId) -> Self {
44 key_id.0.as_bytes().to_vec()
45 }
46}
47
48impl From<[u8; KEY_ID_SIZE]> for KeyId {
49 fn from(bytes: [u8; KEY_ID_SIZE]) -> Self {
50 KeyId(Uuid::from_bytes(bytes))
51 }
52}
53
54impl std::fmt::Debug for KeyId {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 write!(f, "KeyId({})", self.0)
57 }
58}