twizzler_security/
flags.rs

1use core::fmt::{Debug, Display};
2
3use bitflags::bitflags;
4
5use crate::SecurityError;
6
7#[derive(PartialEq, Copy, Clone, Eq, Ord, PartialOrd)]
8/// Flags pertaining to a `Cap`
9/// Currently only used to set which hashing scheme to
10/// use when forming a capability.
11pub struct CapFlags(u16);
12
13bitflags! {
14    impl CapFlags: u16 {
15        /// The Blake3 Hashing Algorithm was used
16        const Blake3 = 1;
17        /// The SHA256 Hashing Algorithm was used
18        const Sha256 = 2;
19    }
20}
21
22impl Display for CapFlags {
23    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24        f.write_str("CapFlags {")?;
25        for flag in self.iter() {
26            match flag {
27                CapFlags::Blake3 => f.write_str(" Blake3 ")?,
28                CapFlags::Sha256 => f.write_str(" SHA256 ")?,
29                _ => (),
30            };
31        }
32
33        f.write_str("}")?;
34
35        Ok(())
36    }
37}
38
39impl Debug for CapFlags {
40    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41        f.debug_struct("CapFlags")
42            .field("blake3", &self.contains(CapFlags::Blake3))
43            .field("sha256", &self.contains(CapFlags::Sha256))
44            .field("bits", &self.bits())
45            .finish()
46    }
47}
48
49#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
50/// The signing scheme used when creating a `Cap`
51pub enum SigningScheme {
52    #[default]
53    /// Use the ECDSA signing scheme
54    Ecdsa,
55}
56
57#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
58/// The hashing algorithm used when creating a `Cap`
59pub enum HashingAlgo {
60    #[default]
61    /// Use the Blake3 Hashing Algorithm
62    Blake3,
63    /// Use the SHA256 Hashing Algorithm
64    Sha256,
65}
66
67impl TryFrom<CapFlags> for HashingAlgo {
68    type Error = SecurityError;
69    fn try_from(value: CapFlags) -> Result<Self, Self::Error> {
70        let mut result = None;
71
72        for flag in value.iter() {
73            if let Some(algo) = match flag {
74                CapFlags::Sha256 => Some(HashingAlgo::Sha256),
75                CapFlags::Blake3 => Some(HashingAlgo::Blake3),
76                _ => None,
77            } {
78                if result.is_some() {
79                    return Err(SecurityError::InvalidScheme);
80                }
81
82                result = Some(algo);
83            }
84        }
85
86        result.ok_or(SecurityError::InvalidScheme)
87    }
88}
89
90impl From<HashingAlgo> for CapFlags {
91    fn from(value: HashingAlgo) -> Self {
92        match value {
93            HashingAlgo::Blake3 => CapFlags::Blake3,
94            HashingAlgo::Sha256 => CapFlags::Sha256,
95        }
96    }
97}