1use heapless::Vec;
2use serde::{Deserialize, Serialize};
3use serde_indexed::{DeserializeIndexed, SerializeIndexed};
4use zeroize::Zeroize;
5
6pub use crate::Bytes;
7use crate::{
8 Error,
9 config::{MAX_KEY_MATERIAL_LENGTH, MAX_SERIALIZED_KEY_LENGTH},
10};
11
12pub type Material = Vec<u8, {MAX_KEY_MATERIAL_LENGTH}>;
13pub type SerializedKeyBytes = Vec<u8, {MAX_SERIALIZED_KEY_LENGTH}>;
14
15#[derive(Clone, Debug, Eq, PartialEq, Zeroize)]
25pub struct Key {
26 pub flags: Flags,
27 pub kind: Kind,
28 pub material: Material,
29}
30
31#[derive(Clone, Debug, Eq, PartialEq, Zeroize)]
32pub struct Info {
33 pub flags: Flags,
34 pub kind: Kind,
35}
36
37impl Info {
38 pub fn with_local_flag(mut self) -> Self {
39 self.flags |= Flags::LOCAL;
40 self
41 }
42}
43
44impl From<Kind> for Info {
45 fn from(kind: Kind) -> Self {
46 Self { flags: Default::default(), kind }
47 }
48}
49
50#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Zeroize)]
53#[repr(u16)]
54pub enum Kind {
55 Shared(usize),
58 Symmetric(usize),
61 Symmetric32Nonce(usize),
63 Ed255,
64 P256,
65 X255,
66}
67
68bitflags::bitflags! {
69 #[derive(DeserializeIndexed, SerializeIndexed, Zeroize)]
70 pub struct Flags: u16 {
75 const LOCAL = 1 << 0;
76 const SENSITIVE = 1 << 1;
77 }
78}
79
80#[derive(Copy, Clone, Debug, Eq, PartialEq)]
81pub enum Secrecy {
85 Public,
87 Secret,
88}
89
90impl Key {
91 pub fn serialize(&self) -> SerializedKeyBytes {
92 let mut buffer = SerializedKeyBytes::new();
93 buffer.extend_from_slice(&self.flags.bits().to_be_bytes()).unwrap();
96 buffer.extend_from_slice(&(self.kind.code()).to_be_bytes()).unwrap();
97 buffer.extend_from_slice(&self.material).unwrap();
99 buffer
100 }
101
102 pub fn try_deserialize(bytes: &[u8]) -> Result<Self, Error> {
103 if bytes.len() < 4 {
104 return Err(Error::InvalidSerializedKey);
105 }
106 let (info, material) = bytes.split_at(4);
107 let flags_bits = u16::from_be_bytes([info[0], info[1]]);
108 let flags = Flags::from_bits(flags_bits).ok_or(Error::InvalidSerializedKey)?;
109
110 let kind_bits = u16::from_be_bytes([info[2], info[3]]);
111 let kind = Kind::try_from(kind_bits, material.len()).map_err(|_| Error::InvalidSerializedKey)?;
112
113 Ok(Key {
114 flags,
115 kind,
116 material: Material::from_slice(material).map_err(|_| Error::InvalidSerializedKey)?,
117 })
118 }
119}
120
121impl Default for Flags {
122 fn default() -> Self {
126 Flags::SENSITIVE
127 }
128}
129
130impl Kind {
131 pub fn code(self) -> u16 {
132 match self {
133 Kind::Shared(_) => 1,
134 Kind::Symmetric(_) => 2,
135 Kind::Symmetric32Nonce(_) => 3,
136 Kind::Ed255 => 4,
137 Kind::P256 => 5,
138 Kind::X255 => 6,
139 }
140 }
141
142 pub fn try_from(code: u16, length: usize) -> Result<Self, Error> {
143 Ok(match code {
144 1 => Self::Shared(length),
145 2 => Self::Symmetric(length),
146 3 => Self::Symmetric32Nonce(length - 32),
147 4 => Self::Ed255,
148 5 => Self::P256,
149 6 => Self::X255,
150 _ => return Err(Error::InvalidSerializedKey),
151 })
152 }
153}