1use crate::AlgorithmIdentifierRef;
6use der::{
7 asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
8 Decode, DecodeValue, Encode, EncodeValue, ErrorKind, Length, Reader, Sequence, Tag, Writer,
9};
10
11pub const PBE_WITH_MD2_AND_DES_CBC_OID: ObjectIdentifier =
13 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.1");
14
15pub const PBE_WITH_MD2_AND_RC2_CBC_OID: ObjectIdentifier =
17 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.4");
18
19pub const PBE_WITH_MD5_AND_DES_CBC_OID: ObjectIdentifier =
21 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.3");
22
23pub const PBE_WITH_MD5_AND_RC2_CBC_OID: ObjectIdentifier =
25 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.6");
26
27pub const PBE_WITH_SHA1_AND_DES_CBC_OID: ObjectIdentifier =
29 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.10");
30
31pub const PBE_WITH_SHA1_AND_RC2_CBC_OID: ObjectIdentifier =
33 ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.11");
34
35pub const SALT_LENGTH: usize = 8;
37
38#[derive(Clone, Debug, Eq, PartialEq)]
54pub struct Algorithm {
55 pub encryption: EncryptionScheme,
57
58 pub parameters: Parameters,
60}
61
62impl Algorithm {
63 pub fn oid(&self) -> ObjectIdentifier {
65 self.encryption.oid()
66 }
67}
68
69impl<'a> DecodeValue<'a> for Algorithm {
70 fn decode_value<R: Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
71 AlgorithmIdentifierRef::decode_value(reader, header)?.try_into()
72 }
73}
74
75impl EncodeValue for Algorithm {
76 fn value_len(&self) -> der::Result<Length> {
77 self.encryption.encoded_len()? + self.parameters.encoded_len()?
78 }
79
80 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
81 self.encryption.encode(writer)?;
82 self.parameters.encode(writer)?;
83 Ok(())
84 }
85}
86
87impl Sequence<'_> for Algorithm {}
88
89impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for Algorithm {
90 type Error = der::Error;
91
92 fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
93 let encryption = EncryptionScheme::try_from(alg.oid)
95 .map_err(|_| der::Tag::ObjectIdentifier.value_error())?;
96
97 let parameters = alg
98 .parameters
99 .ok_or_else(|| Tag::OctetString.value_error())?
100 .try_into()?;
101
102 Ok(Self {
103 encryption,
104 parameters,
105 })
106 }
107}
108
109#[derive(Clone, Debug, Eq, PartialEq)]
119pub struct Parameters {
120 pub salt: [u8; SALT_LENGTH],
122
123 pub iteration_count: u16,
125}
126
127impl<'a> DecodeValue<'a> for Parameters {
128 fn decode_value<R: Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
129 AnyRef::decode_value(reader, header)?.try_into()
130 }
131}
132
133impl EncodeValue for Parameters {
134 fn value_len(&self) -> der::Result<Length> {
135 OctetStringRef::new(&self.salt)?.encoded_len()? + self.iteration_count.encoded_len()?
136 }
137
138 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
139 OctetStringRef::new(&self.salt)?.encode(writer)?;
140 self.iteration_count.encode(writer)?;
141 Ok(())
142 }
143}
144
145impl Sequence<'_> for Parameters {}
146
147impl TryFrom<AnyRef<'_>> for Parameters {
148 type Error = der::Error;
149
150 fn try_from(any: AnyRef<'_>) -> der::Result<Parameters> {
151 any.sequence(|reader| {
152 Ok(Parameters {
153 salt: OctetStringRef::decode(reader)?
154 .as_bytes()
155 .try_into()
156 .map_err(|_| der::Tag::OctetString.value_error())?,
157 iteration_count: reader.decode()?,
158 })
159 })
160 }
161}
162
163#[derive(Copy, Clone, Debug, Eq, PartialEq)]
167pub enum EncryptionScheme {
168 PbeWithMd2AndDesCbc,
170
171 PbeWithMd2AndRc2Cbc,
173
174 PbeWithMd5AndDesCbc,
176
177 PbeWithMd5AndRc2Cbc,
179
180 PbeWithSha1AndDesCbc,
182
183 PbeWithSha1AndRc2Cbc,
185}
186
187impl TryFrom<ObjectIdentifier> for EncryptionScheme {
188 type Error = der::Error;
189
190 fn try_from(oid: ObjectIdentifier) -> der::Result<Self> {
191 match oid {
192 PBE_WITH_MD2_AND_DES_CBC_OID => Ok(Self::PbeWithMd2AndDesCbc),
193 PBE_WITH_MD2_AND_RC2_CBC_OID => Ok(Self::PbeWithMd2AndRc2Cbc),
194 PBE_WITH_MD5_AND_DES_CBC_OID => Ok(Self::PbeWithMd5AndDesCbc),
195 PBE_WITH_MD5_AND_RC2_CBC_OID => Ok(Self::PbeWithMd5AndRc2Cbc),
196 PBE_WITH_SHA1_AND_DES_CBC_OID => Ok(Self::PbeWithSha1AndDesCbc),
197 PBE_WITH_SHA1_AND_RC2_CBC_OID => Ok(Self::PbeWithSha1AndRc2Cbc),
198 _ => Err(ErrorKind::OidUnknown { oid }.into()),
199 }
200 }
201}
202
203impl EncryptionScheme {
204 pub fn cipher(self) -> SymmetricCipher {
206 match self {
207 Self::PbeWithMd2AndDesCbc => SymmetricCipher::DesCbc,
208 Self::PbeWithMd2AndRc2Cbc => SymmetricCipher::Rc2Cbc,
209 Self::PbeWithMd5AndDesCbc => SymmetricCipher::DesCbc,
210 Self::PbeWithMd5AndRc2Cbc => SymmetricCipher::Rc2Cbc,
211 Self::PbeWithSha1AndDesCbc => SymmetricCipher::DesCbc,
212 Self::PbeWithSha1AndRc2Cbc => SymmetricCipher::Rc2Cbc,
213 }
214 }
215
216 pub fn digest(self) -> DigestAlgorithm {
218 match self {
219 Self::PbeWithMd2AndDesCbc => DigestAlgorithm::Md2,
220 Self::PbeWithMd2AndRc2Cbc => DigestAlgorithm::Md2,
221 Self::PbeWithMd5AndDesCbc => DigestAlgorithm::Md5,
222 Self::PbeWithMd5AndRc2Cbc => DigestAlgorithm::Md5,
223 Self::PbeWithSha1AndDesCbc => DigestAlgorithm::Sha1,
224 Self::PbeWithSha1AndRc2Cbc => DigestAlgorithm::Sha1,
225 }
226 }
227
228 pub fn oid(self) -> ObjectIdentifier {
230 match self {
231 Self::PbeWithMd2AndDesCbc => PBE_WITH_MD2_AND_DES_CBC_OID,
232 Self::PbeWithMd2AndRc2Cbc => PBE_WITH_MD2_AND_RC2_CBC_OID,
233 Self::PbeWithMd5AndDesCbc => PBE_WITH_MD5_AND_DES_CBC_OID,
234 Self::PbeWithMd5AndRc2Cbc => PBE_WITH_MD5_AND_RC2_CBC_OID,
235 Self::PbeWithSha1AndDesCbc => PBE_WITH_SHA1_AND_DES_CBC_OID,
236 Self::PbeWithSha1AndRc2Cbc => PBE_WITH_SHA1_AND_RC2_CBC_OID,
237 }
238 }
239}
240
241impl Encode for EncryptionScheme {
242 fn encoded_len(&self) -> der::Result<Length> {
243 self.oid().encoded_len()
244 }
245
246 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
247 self.oid().encode(writer)
248 }
249}
250
251#[derive(Copy, Clone, Debug, Eq, PartialEq)]
253pub enum DigestAlgorithm {
254 Md2,
256
257 Md5,
259
260 Sha1,
262}
263
264#[derive(Copy, Clone, Debug, Eq, PartialEq)]
266pub enum SymmetricCipher {
267 DesCbc,
269
270 Rc2Cbc,
272}