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