1use alloc::vec::Vec;
3
4use crate::error::{Error, Result};
5
6pub const MAX_ID_LEN: usize = 256;
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10#[repr(u8)]
11pub enum SessionKind {
12 Keygen = 0x01,
13 Sign = 0x02,
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct Ssid {
19 sid: [u8; 32],
20 server_id: Vec<u8>,
21 client_id: Vec<u8>,
22 kind: SessionKind,
23 tail: Vec<u8>,
24}
25
26impl Ssid {
27 fn new(
28 sid: [u8; 32],
29 server_id: &[u8],
30 client_id: &[u8],
31 kind: SessionKind,
32 tail: Vec<u8>,
33 ) -> Result<Self> {
34 if server_id.len() > MAX_ID_LEN || client_id.len() > MAX_ID_LEN {
35 return Err(Error::OutOfRange);
36 }
37 Ok(Self {
38 sid,
39 server_id: server_id.to_vec(),
40 client_id: client_id.to_vec(),
41 kind,
42 tail,
43 })
44 }
45
46 pub fn keygen(
48 sid: [u8; 32],
49 server_id: &[u8],
50 client_id: &[u8],
51 kg_nonce: &[u8; 32],
52 ) -> Result<Self> {
53 Self::new(
54 sid,
55 server_id,
56 client_id,
57 SessionKind::Keygen,
58 kg_nonce.to_vec(),
59 )
60 }
61
62 pub fn sign(
65 sid: [u8; 32],
66 server_id: &[u8],
67 client_id: &[u8],
68 key_id: &[u8; 32],
69 digest: &[u8; 32],
70 r2: &[u8; 33],
71 signing_key: &[u8; 33],
72 ) -> Result<Self> {
73 let mut tail = Vec::with_capacity(32 + 32 + 33 + 33);
74 tail.extend_from_slice(key_id);
75 tail.extend_from_slice(digest);
76 tail.extend_from_slice(r2);
77 tail.extend_from_slice(signing_key);
78 Self::new(sid, server_id, client_id, SessionKind::Sign, tail)
79 }
80
81 pub fn kind(&self) -> SessionKind {
82 self.kind
83 }
84 pub fn server_id(&self) -> &[u8] {
85 &self.server_id
86 }
87 pub fn client_id(&self) -> &[u8] {
88 &self.client_id
89 }
90
91 pub fn encode(&self) -> Vec<u8> {
93 let mut out = Vec::with_capacity(
94 32 + 8 + self.server_id.len() + self.client_id.len() + 1 + self.tail.len(),
95 );
96 out.extend_from_slice(&self.sid);
97 out.extend_from_slice(&(self.server_id.len() as u32).to_be_bytes());
98 out.extend_from_slice(&self.server_id);
99 out.extend_from_slice(&(self.client_id.len() as u32).to_be_bytes());
100 out.extend_from_slice(&self.client_id);
101 out.push(self.kind as u8);
102 out.extend_from_slice(&self.tail);
103 out
104 }
105}