paseto_core/paserk/
pie_wrap.rs1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt;
4use core::marker::PhantomData;
5
6use crate::key::{HasKey, Key, KeyInner, SealingKey};
7use crate::version::{Local, Version};
8use crate::{LocalKey, PasetoError};
9
10pub trait PieWrapVersion: Version + HasKey<Local> {
12 fn pie_wrap_key(
14 header: &'static str,
15 wrapping_key: &KeyInner<Self, Local>,
16 key_data: Vec<u8>,
17 ) -> Result<Vec<u8>, PasetoError>;
18
19 fn pie_unwrap_key<'key>(
21 header: &'static str,
22 wrapping_key: &KeyInner<Self, Local>,
23 key_data: &'key mut [u8],
24 ) -> Result<&'key [u8], PasetoError>;
25}
26
27pub struct PieWrappedKey<V: PieWrapVersion, K: SealingKey> {
32 key_data: Box<[u8]>,
33 _version: PhantomData<(V, K)>,
34}
35
36impl<V: PieWrapVersion + HasKey<K>, K: SealingKey> Key<V, K> {
37 pub fn wrap_pie(self, with: &LocalKey<V>) -> Result<PieWrappedKey<V, K>, PasetoError> {
38 V::pie_wrap_key(
39 K::PIE_WRAP_HEADER,
40 &with.0,
41 <V as HasKey<K>>::encode(&self.0).into_vec(),
42 )
43 .map(|key_data| PieWrappedKey {
44 key_data: key_data.into_boxed_slice(),
45 _version: PhantomData,
46 })
47 }
48}
49
50impl<V: PieWrapVersion + HasKey<K>, K: SealingKey> PieWrappedKey<V, K> {
51 pub fn unwrap(mut self, with: &LocalKey<V>) -> Result<Key<V, K>, PasetoError> {
52 V::pie_unwrap_key(K::PIE_WRAP_HEADER, &with.0, &mut self.key_data)
53 .and_then(<V as HasKey<K>>::decode)
54 .map(Key)
55 }
56}
57
58impl<V: PieWrapVersion, K: SealingKey> fmt::Display for PieWrappedKey<V, K> {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.write_str(V::PASERK_HEADER)?;
61 f.write_str(K::PIE_WRAP_HEADER)?;
62 crate::base64::write_to_fmt(&self.key_data, f)
63 }
64}
65
66impl<V: PieWrapVersion, K: SealingKey> core::str::FromStr for PieWrappedKey<V, K> {
67 type Err = PasetoError;
68
69 fn from_str(s: &str) -> Result<Self, Self::Err> {
70 let s = s
71 .strip_prefix(V::PASERK_HEADER)
72 .ok_or(PasetoError::InvalidKey)?;
73 let s = s
74 .strip_prefix(K::PIE_WRAP_HEADER)
75 .ok_or(PasetoError::InvalidKey)?;
76
77 Ok(PieWrappedKey {
78 key_data: crate::base64::decode_vec(s)?.into_boxed_slice(),
79 _version: PhantomData,
80 })
81 }
82}
83
84serde_str!(
85 impl<V, K> PieWrappedKey<V, K>
86 where
87 V: PieWrapVersion,
88 K: SealingKey,
89 {
90 fn expecting() {
91 format_args!(
92 "a {}{} PASERK wrapped key",
93 V::PASERK_HEADER,
94 K::PIE_WRAP_HEADER
95 )
96 }
97 }
98);