1#![allow(non_snake_case)]
10use crate::{error::Format, format::schema};
11
12use super::error;
13#[cfg(feature = "pem")]
14use ed25519_dalek::pkcs8::DecodePrivateKey;
15use ed25519_dalek::*;
16
17use nom::Finish;
18use rand_core::{CryptoRng, RngCore};
19use std::{convert::TryInto, fmt::Display, hash::Hash, ops::Drop, str::FromStr};
20use zeroize::Zeroize;
21
22#[derive(Debug)]
24pub struct KeyPair {
25 pub(crate) kp: ed25519_dalek::SigningKey,
26}
27
28impl KeyPair {
29 pub fn new() -> Self {
30 Self::new_with_rng(&mut rand::rngs::OsRng)
31 }
32
33 pub fn new_with_rng<T: RngCore + CryptoRng>(rng: &mut T) -> Self {
34 let kp = ed25519_dalek::SigningKey::generate(rng);
35
36 KeyPair { kp }
37 }
38
39 pub fn from(key: &PrivateKey) -> Self {
40 KeyPair {
41 kp: ed25519_dalek::SigningKey::from_bytes(&key.0),
42 }
43 }
44
45 #[cfg(feature = "pem")]
46 pub fn from_private_key_der(bytes: &[u8]) -> Result<Self, error::Format> {
47 let kp = SigningKey::from_pkcs8_der(bytes)
48 .map_err(|e| error::Format::InvalidKey(e.to_string()))?;
49 Ok(KeyPair { kp })
50 }
51
52 #[cfg(feature = "pem")]
53 pub fn from_private_key_pem(str: &str) -> Result<Self, error::Format> {
54 let kp = SigningKey::from_pkcs8_pem(str)
55 .map_err(|e| error::Format::InvalidKey(e.to_string()))?;
56 Ok(KeyPair { kp })
57 }
58
59 pub fn private(&self) -> PrivateKey {
60 let secret = self.kp.to_bytes();
61 PrivateKey(secret)
62 }
63
64 pub fn public(&self) -> PublicKey {
65 PublicKey(self.kp.verifying_key())
66 }
67}
68
69impl std::default::Default for KeyPair {
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75#[derive(Debug)]
77pub struct PrivateKey(pub(crate) ed25519_dalek::SecretKey);
78
79impl PrivateKey {
80 pub fn to_bytes(&self) -> [u8; 32] {
82 self.0
83 }
84
85 pub fn to_bytes_hex(&self) -> String {
87 hex::encode(self.to_bytes())
88 }
89
90 pub fn from_bytes(bytes: &[u8]) -> Result<Self, error::Format> {
92 let bytes: [u8; 32] = bytes
93 .try_into()
94 .map_err(|_| Format::InvalidKeySize(bytes.len()))?;
95 Ok(PrivateKey(bytes))
96 }
97
98 pub fn from_bytes_hex(str: &str) -> Result<Self, error::Format> {
100 let bytes = hex::decode(str).map_err(|e| error::Format::InvalidKey(e.to_string()))?;
101 Self::from_bytes(&bytes)
102 }
103
104 pub fn public(&self) -> PublicKey {
106 PublicKey(SigningKey::from_bytes(&self.0).verifying_key())
107 }
108}
109
110impl std::clone::Clone for PrivateKey {
111 fn clone(&self) -> Self {
112 PrivateKey::from_bytes(&self.to_bytes()).unwrap()
113 }
114}
115
116impl Drop for PrivateKey {
117 fn drop(&mut self) {
118 self.0.zeroize();
119 }
120}
121
122#[derive(Debug, Clone, Copy, Eq)]
124pub struct PublicKey(pub(crate) ed25519_dalek::VerifyingKey);
125
126impl PublicKey {
127 pub fn to_bytes(&self) -> [u8; 32] {
129 self.0.to_bytes()
130 }
131
132 pub fn to_bytes_hex(&self) -> String {
134 hex::encode(self.to_bytes())
135 }
136
137 pub fn from_bytes(bytes: &[u8]) -> Result<Self, error::Format> {
139 let bytes: [u8; 32] = bytes
140 .try_into()
141 .map_err(|_| Format::InvalidKeySize(bytes.len()))?;
142
143 ed25519_dalek::VerifyingKey::from_bytes(&bytes)
144 .map(PublicKey)
145 .map_err(|s| s.to_string())
146 .map_err(Format::InvalidKey)
147 }
148
149 pub fn from_bytes_hex(str: &str) -> Result<Self, error::Format> {
151 let bytes = hex::decode(str).map_err(|e| error::Format::InvalidKey(e.to_string()))?;
152 Self::from_bytes(&bytes)
153 }
154
155 pub fn from_proto(key: &schema::PublicKey) -> Result<Self, error::Format> {
156 if key.algorithm != schema::public_key::Algorithm::Ed25519 as i32 {
157 return Err(error::Format::DeserializationError(format!(
158 "deserialization error: unexpected key algorithm {}",
159 key.algorithm
160 )));
161 }
162
163 PublicKey::from_bytes(&key.key)
164 }
165
166 pub fn to_proto(&self) -> schema::PublicKey {
167 schema::PublicKey {
168 algorithm: schema::public_key::Algorithm::Ed25519 as i32,
169 key: self.to_bytes().to_vec(),
170 }
171 }
172
173 pub fn print(&self) -> String {
174 self.to_string()
175 }
176}
177
178impl PartialEq for PublicKey {
179 fn eq(&self, other: &Self) -> bool {
180 self.0.to_bytes() == other.0.to_bytes()
181 }
182}
183
184impl Hash for PublicKey {
185 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
186 (crate::format::schema::public_key::Algorithm::Ed25519 as i32).hash(state);
187 self.0.to_bytes().hash(state);
188 }
189}
190
191impl FromStr for PublicKey {
192 type Err = error::Token;
193
194 fn from_str(s: &str) -> Result<Self, Self::Err> {
195 let (_, bytes) = biscuit_parser::parser::public_key(s)
196 .finish()
197 .map_err(biscuit_parser::error::LanguageError::from)?;
198 Ok(PublicKey::from_bytes(&bytes)?)
199 }
200}
201
202impl Display for PublicKey {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 write!(f, "ed25519/{}", hex::encode(self.to_bytes()))
205 }
206}
207
208#[derive(Clone, Debug)]
209pub struct Block {
210 pub(crate) data: Vec<u8>,
211 pub(crate) next_key: PublicKey,
212 pub signature: ed25519_dalek::Signature,
213 pub external_signature: Option<ExternalSignature>,
214}
215
216#[derive(Clone, Debug)]
217pub struct ExternalSignature {
218 pub(crate) public_key: PublicKey,
219 pub(crate) signature: ed25519_dalek::Signature,
220}
221
222#[derive(Clone, Debug)]
223pub struct Token {
224 pub root: PublicKey,
225 pub blocks: Vec<Block>,
226 pub next: TokenNext,
227}
228
229#[derive(Clone, Debug)]
230pub enum TokenNext {
231 Secret(PrivateKey),
232 Seal(ed25519_dalek::Signature),
233}
234
235pub fn sign(
236 keypair: &KeyPair,
237 next_key: &KeyPair,
238 message: &[u8],
239) -> Result<Signature, error::Token> {
240 let mut to_sign = message.to_vec();
242 to_sign.extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
243 to_sign.extend(&next_key.public().to_bytes());
244
245 let signature = keypair
246 .kp
247 .try_sign(&to_sign)
248 .map_err(|s| s.to_string())
249 .map_err(error::Signature::InvalidSignatureGeneration)
250 .map_err(error::Format::Signature)?;
251
252 Ok(signature)
253}
254
255pub fn verify_block_signature(block: &Block, public_key: &PublicKey) -> Result<(), error::Format> {
256 let mut to_verify = block.data.to_vec();
258
259 if let Some(signature) = block.external_signature.as_ref() {
260 to_verify.extend_from_slice(&signature.signature.to_bytes());
261 }
262 to_verify.extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
263 to_verify.extend(&block.next_key.to_bytes());
264
265 public_key
266 .0
267 .verify_strict(&to_verify, &block.signature)
268 .map_err(|s| s.to_string())
269 .map_err(error::Signature::InvalidSignature)
270 .map_err(error::Format::Signature)?;
271
272 if let Some(external_signature) = block.external_signature.as_ref() {
273 let mut to_verify = block.data.to_vec();
274 to_verify
275 .extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
276 to_verify.extend(&public_key.to_bytes());
277
278 external_signature
279 .public_key
280 .0
281 .verify_strict(&to_verify, &external_signature.signature)
282 .map_err(|s| s.to_string())
283 .map_err(error::Signature::InvalidSignature)
284 .map_err(error::Format::Signature)?;
285 }
286
287 Ok(())
288}
289
290impl Token {
291 #[allow(dead_code)]
292 pub fn new<T: RngCore + CryptoRng>(
293 keypair: &KeyPair,
294 next_key: &KeyPair,
295 message: &[u8],
296 ) -> Result<Self, error::Token> {
297 let signature = sign(keypair, next_key, message)?;
298
299 let block = Block {
300 data: message.to_vec(),
301 next_key: next_key.public(),
302 signature,
303 external_signature: None,
304 };
305
306 Ok(Token {
307 root: keypair.public(),
308 blocks: vec![block],
309 next: TokenNext::Secret(next_key.private()),
310 })
311 }
312
313 #[allow(dead_code)]
314 pub fn append<T: RngCore + CryptoRng>(
315 &self,
316 next_key: &KeyPair,
317 message: &[u8],
318 external_signature: Option<ExternalSignature>,
319 ) -> Result<Self, error::Token> {
320 let keypair = match self.next.keypair() {
321 Err(error::Token::AlreadySealed) => Err(error::Token::AppendOnSealed),
322 other => other,
323 }?;
324
325 let signature = sign(&keypair, next_key, message)?;
326
327 let block = Block {
328 data: message.to_vec(),
329 next_key: next_key.public(),
330 signature,
331 external_signature,
332 };
333
334 let mut t = Token {
335 root: self.root,
336 blocks: self.blocks.clone(),
337 next: TokenNext::Secret(next_key.private()),
338 };
339
340 t.blocks.push(block);
341
342 Ok(t)
343 }
344
345 #[allow(dead_code)]
346 pub fn verify(&self, root: PublicKey) -> Result<(), error::Token> {
347 let mut current_pub = root;
349
350 for block in &self.blocks {
351 verify_block_signature(block, ¤t_pub)?;
352 current_pub = block.next_key;
353 }
354
355 match &self.next {
356 TokenNext::Secret(private) => {
357 if current_pub != private.public() {
358 return Err(error::Format::Signature(error::Signature::InvalidSignature(
359 "the last public key does not match the private key".to_string(),
360 ))
361 .into());
362 }
363 }
364 TokenNext::Seal(signature) => {
365 let mut to_verify = Vec::new();
367 for block in &self.blocks {
368 to_verify.extend(&block.data);
369 to_verify.extend(&block.next_key.to_bytes());
370 }
371
372 current_pub
373 .0
374 .verify_strict(&to_verify, signature)
375 .map_err(|s| s.to_string())
376 .map_err(error::Signature::InvalidSignature)
377 .map_err(error::Format::Signature)?;
378 }
379 }
380
381 Ok(())
382 }
383}
384
385impl TokenNext {
386 pub fn keypair(&self) -> Result<KeyPair, error::Token> {
387 match &self {
388 TokenNext::Seal(_) => Err(error::Token::AlreadySealed),
389 TokenNext::Secret(private) => Ok(KeyPair::from(private)),
390 }
391 }
392
393 pub fn is_sealed(&self) -> bool {
394 match &self {
395 TokenNext::Seal(_) => true,
396 TokenNext::Secret(_) => false,
397 }
398 }
399}
400
401#[cfg(test)]
402mod tests {
403 }