bitwarden_crypto/
content_format.rs1use bitwarden_encoding::B64;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 CryptoError, EncString, KeyEncryptable, KeyEncryptableWithContentType, KeyIds, KeyStoreContext,
6 PrimitiveEncryptable, SymmetricCryptoKey, traits::PrimitiveEncryptableWithContentType,
7};
8
9#[derive(Clone, Copy, Debug, PartialEq)]
16pub(crate) enum ContentFormat {
17 Utf8,
19 Pkcs8PrivateKey,
21 SPKIPublicKeyDer,
23 CoseKey,
25 CoseSign1,
27 BitwardenLegacyKey,
33 OctetStream,
35}
36
37mod private {
38 pub trait Sealed {}
41}
42
43pub trait ConstContentFormat: private::Sealed {
48 #[allow(private_interfaces)]
50 fn content_format() -> ContentFormat;
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct Bytes<C: ConstContentFormat> {
59 inner: Vec<u8>,
60 _marker: std::marker::PhantomData<C>,
61}
62
63impl<C: ConstContentFormat> From<Vec<u8>> for Bytes<C> {
64 fn from(inner: Vec<u8>) -> Self {
65 Self {
66 inner,
67 _marker: std::marker::PhantomData,
68 }
69 }
70}
71
72impl<C: ConstContentFormat> From<&[u8]> for Bytes<C> {
73 fn from(inner: &[u8]) -> Self {
74 Self::from(inner.to_vec())
75 }
76}
77
78impl<C: ConstContentFormat + FromB64ContentFormat> From<&B64> for Bytes<C> {
79 fn from(val: &B64) -> Self {
80 Self::from(val.as_bytes())
81 }
82}
83
84impl<C: ConstContentFormat + FromB64ContentFormat> From<Bytes<C>> for B64 {
85 fn from(val: Bytes<C>) -> Self {
86 B64::from(val.as_ref())
87 }
88}
89
90impl<C: ConstContentFormat> AsRef<[u8]> for Bytes<C> {
91 fn as_ref(&self) -> &[u8] {
92 &self.inner
93 }
94}
95
96impl<C: ConstContentFormat> Bytes<C> {
97 pub fn to_vec(&self) -> Vec<u8> {
99 self.inner.clone()
100 }
101}
102
103#[derive(PartialEq, Eq, Clone, Debug)]
105pub(crate) struct Utf8ContentFormat;
106impl private::Sealed for Utf8ContentFormat {}
107impl ConstContentFormat for Utf8ContentFormat {
108 fn content_format() -> ContentFormat {
109 ContentFormat::Utf8
110 }
111}
112pub(crate) type Utf8Bytes = Bytes<Utf8ContentFormat>;
115
116#[derive(PartialEq, Eq, Clone, Debug)]
118pub struct OctetStreamContentFormat;
119impl private::Sealed for OctetStreamContentFormat {}
120impl ConstContentFormat for OctetStreamContentFormat {
121 #[allow(private_interfaces)]
122 fn content_format() -> ContentFormat {
123 ContentFormat::OctetStream
124 }
125}
126pub type OctetStreamBytes = Bytes<OctetStreamContentFormat>;
129
130#[derive(PartialEq, Eq, Clone, Debug)]
132pub struct Pkcs8PrivateKeyDerContentFormat;
133impl private::Sealed for Pkcs8PrivateKeyDerContentFormat {}
134impl ConstContentFormat for Pkcs8PrivateKeyDerContentFormat {
135 #[allow(private_interfaces)]
136 fn content_format() -> ContentFormat {
137 ContentFormat::Pkcs8PrivateKey
138 }
139}
140pub type Pkcs8PrivateKeyBytes = Bytes<Pkcs8PrivateKeyDerContentFormat>;
143
144#[derive(PartialEq, Eq, Clone, Debug)]
146pub struct SpkiPublicKeyDerContentFormat;
147impl private::Sealed for SpkiPublicKeyDerContentFormat {}
148impl ConstContentFormat for SpkiPublicKeyDerContentFormat {
149 #[allow(private_interfaces)]
150 fn content_format() -> ContentFormat {
151 ContentFormat::SPKIPublicKeyDer
152 }
153}
154impl FromB64ContentFormat for SpkiPublicKeyDerContentFormat {}
155pub type SpkiPublicKeyBytes = Bytes<SpkiPublicKeyDerContentFormat>;
158
159pub trait CoseContentFormat {}
161
162pub trait FromB64ContentFormat {}
164
165#[derive(PartialEq, Eq, Clone, Debug)]
167pub struct CoseKeyContentFormat;
168impl private::Sealed for CoseKeyContentFormat {}
169impl ConstContentFormat for CoseKeyContentFormat {
170 #[allow(private_interfaces)]
171 fn content_format() -> ContentFormat {
172 ContentFormat::CoseKey
173 }
174}
175impl CoseContentFormat for CoseKeyContentFormat {}
176impl FromB64ContentFormat for CoseKeyContentFormat {}
177pub type CoseKeyBytes = Bytes<CoseKeyContentFormat>;
180
181#[derive(PartialEq, Eq, Clone, Debug)]
183pub struct BitwardenLegacyKeyContentFormat;
184impl private::Sealed for BitwardenLegacyKeyContentFormat {}
185impl ConstContentFormat for BitwardenLegacyKeyContentFormat {
186 #[allow(private_interfaces)]
187 fn content_format() -> ContentFormat {
188 ContentFormat::BitwardenLegacyKey
189 }
190}
191impl FromB64ContentFormat for BitwardenLegacyKeyContentFormat {}
192pub type BitwardenLegacyKeyBytes = Bytes<BitwardenLegacyKeyContentFormat>;
196
197#[derive(PartialEq, Eq, Clone, Debug)]
199pub struct CoseSign1ContentFormat;
200impl private::Sealed for CoseSign1ContentFormat {}
201impl ConstContentFormat for CoseSign1ContentFormat {
202 #[allow(private_interfaces)]
203 fn content_format() -> ContentFormat {
204 ContentFormat::CoseSign1
205 }
206}
207impl CoseContentFormat for CoseSign1ContentFormat {}
208impl FromB64ContentFormat for CoseSign1ContentFormat {}
209pub type CoseSign1Bytes = Bytes<CoseSign1ContentFormat>;
212
213impl<Ids: KeyIds, T: ConstContentFormat> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString>
214 for Bytes<T>
215{
216 fn encrypt(
217 &self,
218 ctx: &mut KeyStoreContext<Ids>,
219 key: Ids::Symmetric,
220 ) -> Result<EncString, CryptoError> {
221 self.inner.encrypt(ctx, key, T::content_format())
222 }
223}
224
225impl<T: ConstContentFormat> KeyEncryptable<SymmetricCryptoKey, EncString> for &Bytes<T> {
226 fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<EncString, CryptoError> {
227 self.as_ref().encrypt_with_key(key, T::content_format())
228 }
229}
230
231impl From<String> for Bytes<Utf8ContentFormat> {
232 fn from(val: String) -> Self {
233 Bytes::from(val.into_bytes())
234 }
235}
236
237impl From<&str> for Bytes<Utf8ContentFormat> {
238 fn from(val: &str) -> Self {
239 Bytes::from(val.as_bytes().to_vec())
240 }
241}