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.
12pub(crate) struct KeyId(uuid::Uuid);
13
14/// Fixed length identifiers for keys.
15/// These are intended to be unique and constant per-key.
16///
17/// Currently these are randomly generated 16 byte identifiers, which is considered safe to randomly
18/// generate with vanishingly small collision chance. However, the generation of IDs is an internal
19/// concern and may change in the future.
20impl KeyId {
21    /// Creates a new random key ID randomly, sampled from the crates CSPRNG.
22    pub fn make() -> Self {
23        // We do not use the uuid crate's random generation functionality here to make sure the
24        // entropy sampling aligns with the rest of this crates usage of CSPRNGs.
25        let mut random_seed = [0u8; UUID_SEED_SIZE];
26        rand::thread_rng().fill_bytes(&mut random_seed);
27
28        let uuid = uuid::Builder::from_random_bytes(random_seed)
29            .with_version(uuid::Version::Random)
30            .with_variant(uuid::Variant::RFC4122);
31        Self(uuid.into_uuid())
32    }
33}
34
35impl From<KeyId> for [u8; KEY_ID_SIZE] {
36    fn from(key_id: KeyId) -> Self {
37        key_id.0.into_bytes()
38    }
39}
40
41impl From<[u8; KEY_ID_SIZE]> for KeyId {
42    fn from(bytes: [u8; KEY_ID_SIZE]) -> Self {
43        KeyId(Uuid::from_bytes(bytes))
44    }
45}
46
47impl std::fmt::Debug for KeyId {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "KeyId({})", self.0)
50    }
51}