1#[cfg(test)]
4#[path = "../../tests/certificate/server.rs"]
5mod tests;
6
7use std::fmt::Debug;
8#[cfg(any(feature = "full_software", feature = "full_hardware"))]
9use std::fmt::{Formatter, Result as FmtResult};
10use std::fs::File;
11use std::io::{Read, Write};
12use std::net::SocketAddr;
13use std::path::Path;
14use std::sync::Arc;
15
16use cfg_if::cfg_if;
17use classic_mceliece_rust::{PublicKey as McEliecePublicKey, SecretKey, keypair_boxed};
18use ed25519_dalek::SigningKey;
19use rand::RngCore;
20
21cfg_if! {
22 if #[cfg(any(feature = "full_software", feature = "full_hardware"))] {
23 use x25519_dalek::{PublicKey as X25519PublicKey, StaticSecret};
24 use super::utils::X25519_BYTES;
25 }
26}
27use super::client::ClientCertificate;
28use super::utils::{CertificateError, ED25519_BYTES, EPK_BYTES, ESK_BYTES, ObfuscationBufferContainer, TYPE_SERVER, read_header, write_header};
29use crate::bytes::FixedByteBuffer;
30use crate::utils::random::get_rng;
31
32#[cfg(any(feature = "full_software", feature = "full_hardware"))]
36pub(crate) struct ServerSecret<'a> {
37 pub esk: SecretKey<'a>,
38 pub vsk: SigningKey,
39 pub opk: X25519PublicKey,
40 pub osk: StaticSecret,
41}
42
43#[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
45pub(crate) struct ServerSecret<'a> {
46 pub esk: SecretKey<'a>,
47 pub vsk: SigningKey,
48 pub obfs: FixedByteBuffer<ED25519_BYTES>,
49}
50
51impl ObfuscationBufferContainer for ServerSecret<'_> {
52 #[cfg(any(feature = "full_software", feature = "full_hardware"))]
53 #[inline]
54 fn obfuscation_buffer(&self) -> FixedByteBuffer<ED25519_BYTES> {
55 FixedByteBuffer::from(self.opk.as_bytes())
56 }
57
58 #[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
59 #[inline]
60 fn obfuscation_buffer(&self) -> FixedByteBuffer<ED25519_BYTES> {
61 self.obfs
62 }
63}
64
65#[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
74#[derive(Debug)]
75pub struct ServerKeyPair {
76 epk: Arc<McEliecePublicKey<'static>>,
77 esk: SecretKey<'static>,
78 vsk: SigningKey,
79 obfs: FixedByteBuffer<ED25519_BYTES>,
80}
81
82#[cfg(any(feature = "full_software", feature = "full_hardware"))]
89pub struct ServerKeyPair {
90 epk: Arc<McEliecePublicKey<'static>>,
91 esk: SecretKey<'static>,
92 vsk: SigningKey,
93 opk: X25519PublicKey,
94 osk: StaticSecret,
95}
96
97impl ServerKeyPair {
98 #[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
100 pub fn generate() -> Self {
101 let rng = &mut get_rng();
102 let (pk, sk) = keypair_boxed(rng);
103 let mut vsk_bytes = [0u8; ED25519_BYTES];
104 rng.fill_bytes(&mut vsk_bytes);
105 let vsk = SigningKey::from_bytes(&vsk_bytes);
106 let mut obfs_bytes = [0u8; ED25519_BYTES];
107 rng.fill_bytes(&mut obfs_bytes);
108 Self {
109 epk: Arc::new(pk),
110 esk: sk,
111 vsk,
112 obfs: FixedByteBuffer::from(obfs_bytes),
113 }
114 }
115
116 #[cfg(any(feature = "full_software", feature = "full_hardware"))]
118 pub fn generate() -> Self {
119 let rng = &mut get_rng();
120 let (pk, sk) = keypair_boxed(rng);
121 let mut vsk_bytes = [0u8; ED25519_BYTES];
122 rng.fill_bytes(&mut vsk_bytes);
123 let vsk = SigningKey::from_bytes(&vsk_bytes);
124 let osk = StaticSecret::random_from_rng(rng);
125 let opk = X25519PublicKey::from(&osk);
126 Self {
127 epk: Arc::new(pk),
128 esk: sk,
129 vsk,
130 opk,
131 osk,
132 }
133 }
134
135 #[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
137 pub fn to_client_certificate(&self, addresses: Vec<SocketAddr>) -> ClientCertificate {
138 ClientCertificate {
139 epk: self.epk.clone(),
140 vpk: self.vsk.verifying_key(),
141 obfs: self.obfs,
142 addresses,
143 }
144 }
145
146 #[cfg(any(feature = "full_software", feature = "full_hardware"))]
148 pub fn to_client_certificate(&self, addresses: Vec<SocketAddr>) -> ClientCertificate {
149 ClientCertificate {
150 epk: self.epk.clone(),
151 vpk: self.vsk.verifying_key(),
152 opk: self.opk,
153 addresses,
154 }
155 }
156
157 #[cfg(all(feature = "server", any(feature = "fast_software", feature = "fast_hardware")))]
159 pub(crate) fn into_server_secret(self) -> ServerSecret<'static> {
160 ServerSecret {
161 esk: self.esk,
162 vsk: self.vsk,
163 obfs: self.obfs,
164 }
165 }
166
167 #[cfg(all(feature = "server", any(feature = "full_software", feature = "full_hardware")))]
169 pub(crate) fn into_server_secret(self) -> ServerSecret<'static> {
170 ServerSecret {
171 esk: self.esk,
172 vsk: self.vsk,
173 opk: self.opk,
174 osk: self.osk,
175 }
176 }
177
178 #[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
191 pub fn save(&self, path: impl AsRef<Path>) -> Result<(), CertificateError> {
192 let mut f = File::create(path)?;
193 write_header(&mut f, TYPE_SERVER)?;
194 f.write_all(self.epk.as_array())?;
195 f.write_all(self.esk.as_array())?;
196 f.write_all(&self.vsk.to_bytes())?;
197 f.write_all(self.obfs.as_ref())?;
198 Ok(())
199 }
200
201 #[cfg(any(feature = "full_software", feature = "full_hardware"))]
215 pub fn save(&self, path: impl AsRef<Path>) -> Result<(), CertificateError> {
216 let mut f = File::create(path)?;
217 write_header(&mut f, TYPE_SERVER)?;
218 f.write_all(self.epk.as_array())?;
219 f.write_all(self.esk.as_array())?;
220 f.write_all(&self.vsk.to_bytes())?;
221 f.write_all(self.opk.as_bytes())?;
222 f.write_all(self.osk.as_bytes())?;
223 Ok(())
224 }
225
226 #[cfg(any(feature = "fast_software", feature = "fast_hardware"))]
228 pub fn load(path: impl AsRef<Path>) -> Result<Self, CertificateError> {
229 let mut f = File::open(path)?;
230 read_header(&mut f, TYPE_SERVER)?;
231 let mut epk_buf = Box::new([0u8; EPK_BYTES]);
232 f.read_exact(epk_buf.as_mut())?;
233 let mut esk_buf = Box::new([0u8; ESK_BYTES]);
234 f.read_exact(esk_buf.as_mut())?;
235 let mut vsk_arr = [0u8; ED25519_BYTES];
236 f.read_exact(&mut vsk_arr)?;
237 let vsk = SigningKey::from_bytes(&vsk_arr);
238 let mut obfs_arr = [0u8; ED25519_BYTES];
239 f.read_exact(&mut obfs_arr)?;
240 Ok(Self {
241 epk: Arc::new(McEliecePublicKey::from(epk_buf)),
242 esk: SecretKey::from(esk_buf),
243 vsk,
244 obfs: FixedByteBuffer::from(obfs_arr),
245 })
246 }
247
248 #[cfg(any(feature = "full_software", feature = "full_hardware"))]
250 pub fn load(path: impl AsRef<Path>) -> Result<Self, CertificateError> {
251 let mut f = File::open(path)?;
252 read_header(&mut f, TYPE_SERVER)?;
253 let mut epk_buf = Box::new([0u8; EPK_BYTES]);
254 f.read_exact(epk_buf.as_mut())?;
255 let mut esk_buf = Box::new([0u8; ESK_BYTES]);
256 f.read_exact(esk_buf.as_mut())?;
257 let mut vsk_arr = [0u8; ED25519_BYTES];
258 f.read_exact(&mut vsk_arr)?;
259 let vsk = SigningKey::from_bytes(&vsk_arr);
260 let mut opk_arr = [0u8; X25519_BYTES];
261 f.read_exact(&mut opk_arr)?;
262 let mut osk_arr = [0u8; X25519_BYTES];
263 f.read_exact(&mut osk_arr)?;
264 Ok(Self {
265 epk: Arc::new(McEliecePublicKey::from(epk_buf)),
266 esk: SecretKey::from(esk_buf),
267 vsk,
268 opk: X25519PublicKey::from(opk_arr),
269 osk: StaticSecret::from(osk_arr),
270 })
271 }
272}
273
274#[cfg(any(feature = "full_software", feature = "full_hardware"))]
278impl Debug for ServerKeyPair {
279 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
280 f.debug_struct("ServerKeyPair").field("epk", &"<McEliece public key>").field("esk", &"<McEliece secret key>").field("vsk", &self.vsk).field("opk", &self.opk).field("osk", &"<X25519 static secret>").finish()
281 }
282}