bitwarden_crypto/
content_format.rs1use serde::{Deserialize, Serialize};
2
3use crate::{
4 traits::PrimitiveEncryptableWithContentType, CryptoError, EncString, KeyEncryptable,
5 KeyEncryptableWithContentType, KeyIds, KeyStoreContext, PrimitiveEncryptable,
6 SymmetricCryptoKey,
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> AsRef<[u8]> for Bytes<C> {
79 fn as_ref(&self) -> &[u8] {
80 &self.inner
81 }
82}
83
84impl<C: ConstContentFormat> Bytes<C> {
85 pub fn to_vec(&self) -> Vec<u8> {
87 self.inner.clone()
88 }
89}
90
91#[derive(PartialEq, Eq, Clone, Debug)]
93pub(crate) struct Utf8ContentFormat;
94impl private::Sealed for Utf8ContentFormat {}
95impl ConstContentFormat for Utf8ContentFormat {
96 fn content_format() -> ContentFormat {
97 ContentFormat::Utf8
98 }
99}
100pub(crate) type Utf8Bytes = Bytes<Utf8ContentFormat>;
103
104#[derive(PartialEq, Eq, Clone, Debug)]
106pub struct OctetStreamContentFormat;
107impl private::Sealed for OctetStreamContentFormat {}
108impl ConstContentFormat for OctetStreamContentFormat {
109 #[allow(private_interfaces)]
110 fn content_format() -> ContentFormat {
111 ContentFormat::OctetStream
112 }
113}
114pub type OctetStreamBytes = Bytes<OctetStreamContentFormat>;
117
118#[derive(PartialEq, Eq, Clone, Debug)]
120pub struct Pkcs8PrivateKeyDerContentFormat;
121impl private::Sealed for Pkcs8PrivateKeyDerContentFormat {}
122impl ConstContentFormat for Pkcs8PrivateKeyDerContentFormat {
123 #[allow(private_interfaces)]
124 fn content_format() -> ContentFormat {
125 ContentFormat::Pkcs8PrivateKey
126 }
127}
128pub type Pkcs8PrivateKeyBytes = Bytes<Pkcs8PrivateKeyDerContentFormat>;
131
132#[derive(PartialEq, Eq, Clone, Debug)]
134pub struct SpkiPublicKeyDerContentFormat;
135impl private::Sealed for SpkiPublicKeyDerContentFormat {}
136impl ConstContentFormat for SpkiPublicKeyDerContentFormat {
137 #[allow(private_interfaces)]
138 fn content_format() -> ContentFormat {
139 ContentFormat::SPKIPublicKeyDer
140 }
141}
142pub type SpkiPublicKeyBytes = Bytes<SpkiPublicKeyDerContentFormat>;
145
146pub trait CoseContentFormat {}
148
149#[derive(PartialEq, Eq, Clone, Debug)]
151pub struct CoseKeyContentFormat;
152impl private::Sealed for CoseKeyContentFormat {}
153impl ConstContentFormat for CoseKeyContentFormat {
154 #[allow(private_interfaces)]
155 fn content_format() -> ContentFormat {
156 ContentFormat::CoseKey
157 }
158}
159impl CoseContentFormat for CoseKeyContentFormat {}
160pub type CoseKeyBytes = Bytes<CoseKeyContentFormat>;
163
164#[derive(PartialEq, Eq, Clone, Debug)]
166pub struct BitwardenLegacyKeyContentFormat;
167impl private::Sealed for BitwardenLegacyKeyContentFormat {}
168impl ConstContentFormat for BitwardenLegacyKeyContentFormat {
169 #[allow(private_interfaces)]
170 fn content_format() -> ContentFormat {
171 ContentFormat::BitwardenLegacyKey
172 }
173}
174pub type BitwardenLegacyKeyBytes = Bytes<BitwardenLegacyKeyContentFormat>;
178
179#[derive(PartialEq, Eq, Clone, Debug)]
181pub struct CoseSign1ContentFormat;
182impl private::Sealed for CoseSign1ContentFormat {}
183impl ConstContentFormat for CoseSign1ContentFormat {
184 #[allow(private_interfaces)]
185 fn content_format() -> ContentFormat {
186 ContentFormat::CoseSign1
187 }
188}
189impl CoseContentFormat for CoseSign1ContentFormat {}
190pub type CoseSign1Bytes = Bytes<CoseSign1ContentFormat>;
193
194impl<Ids: KeyIds, T: ConstContentFormat> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString>
195 for Bytes<T>
196{
197 fn encrypt(
198 &self,
199 ctx: &mut KeyStoreContext<Ids>,
200 key: Ids::Symmetric,
201 ) -> Result<EncString, CryptoError> {
202 self.inner.encrypt(ctx, key, T::content_format())
203 }
204}
205
206impl<T: ConstContentFormat> KeyEncryptable<SymmetricCryptoKey, EncString> for &Bytes<T> {
207 fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<EncString, CryptoError> {
208 self.as_ref().encrypt_with_key(key, T::content_format())
209 }
210}
211
212impl From<String> for Bytes<Utf8ContentFormat> {
213 fn from(val: String) -> Self {
214 Bytes::from(val.into_bytes())
215 }
216}
217
218impl From<&str> for Bytes<Utf8ContentFormat> {
219 fn from(val: &str) -> Self {
220 Bytes::from(val.as_bytes().to_vec())
221 }
222}