paseto_core/paserk/
pke.rs1use alloc::boxed::Box;
2use core::fmt;
3use core::marker::PhantomData;
4
5use crate::key::{HasKey, Key, KeyInner};
6use crate::version::{Local, PkePublic, PkeSecret, Version};
7use crate::{LocalKey, PasetoError};
8
9pub trait PkeSealingVersion: Version + HasKey<Local> + HasKey<PkePublic> {
11 fn seal_key(
13 sealing_key: &KeyInner<Self, PkePublic>,
14 key: KeyInner<Self, Local>,
15 ) -> Result<Box<[u8]>, PasetoError>;
16}
17
18pub trait PkeUnsealingVersion: Version + HasKey<Local> + HasKey<PkeSecret> {
20 fn unseal_key(
22 sealing_key: &KeyInner<Self, PkeSecret>,
23 key_data: Box<[u8]>,
24 ) -> Result<KeyInner<Self, Local>, PasetoError>;
25}
26
27pub struct SealedKey<V: Version> {
32 key_data: Box<[u8]>,
33 _version: PhantomData<V>,
34}
35
36impl<V: Version> Clone for SealedKey<V> {
37 fn clone(&self) -> Self {
38 Self {
39 key_data: self.key_data.clone(),
40 _version: self._version,
41 }
42 }
43}
44
45impl<V: Version> fmt::Display for SealedKey<V> {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.write_str(V::PASERK_HEADER)?;
48 f.write_str(".seal.")?;
49 crate::base64::write_to_fmt(&self.key_data, f)
50 }
51}
52
53impl<V: Version> core::str::FromStr for SealedKey<V> {
54 type Err = PasetoError;
55
56 fn from_str(s: &str) -> Result<Self, Self::Err> {
57 let s = s
58 .strip_prefix(V::PASERK_HEADER)
59 .ok_or(PasetoError::InvalidKey)?;
60 let s = s.strip_prefix(".seal.").ok_or(PasetoError::InvalidKey)?;
61
62 Ok(SealedKey {
63 key_data: crate::base64::decode_vec(s)?.into_boxed_slice(),
64 _version: PhantomData,
65 })
66 }
67}
68
69impl<V: PkeSealingVersion> LocalKey<V> {
70 pub fn seal(self, with: &Key<V, PkePublic>) -> Result<SealedKey<V>, PasetoError> {
72 V::seal_key(&with.0, self.0).map(|key_data| SealedKey {
73 key_data,
74 _version: PhantomData,
75 })
76 }
77}
78
79impl<V: PkeUnsealingVersion> SealedKey<V> {
80 pub fn unseal(self, with: &Key<V, PkeSecret>) -> Result<LocalKey<V>, PasetoError> {
82 V::unseal_key(&with.0, self.key_data).map(Key)
83 }
84}
85
86serde_str!(
87 impl<V> SealedKey<V>
88 where
89 V: PkeSealingVersion,
90 {
91 fn expecting() {
92 format_args!("a {}.seal. PASERK sealed key", V::PASERK_HEADER)
93 }
94 }
95);