1use crate::{ContentInfo, Error, ErrorCode, Octets, Result, SignedData};
10use crate::{attribute::Attribute, enveloped::EncodedValue, signer::required};
11use structured_asn1::memory::{OwnedVec, Work};
12use structured_asn1::{Element, Integer, Oid, Reader, Tag, universal};
13use structured_pkix::AlgorithmIdentifier;
14
15mod process;
16pub mod protection;
17pub use process::{
18 Backend, Cause, Decision, Failure, Fragments, Origin, Plaintext, Source, legacy_password,
19 process,
20};
21
22const FIELD: &str = "personal";
23const DATA: Oid<'static> = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 7, 1]);
24const SIGNED: Oid<'static> = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 7, 2]);
25const ENCRYPTED: Oid<'static> = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 7, 6]);
26
27pub enum Integrity<'a> {
29 Password {
31 safe: Octets<'a>,
33 mac: Option<MacData<'a>>,
35 },
36 Signed(SignedData<'a>),
38}
39
40pub struct Pfx<'a> {
42 integrity: Integrity<'a>,
43 original: EncodedValue<'a>,
44}
45impl<'a> Pfx<'a> {
46 pub fn read(parent: &mut Reader<'a>) -> Result<Self> {
48 let element = required(parent, FIELD)?;
49 let value = Self::read_element(parent, &element)?;
50 end(parent)?;
51 Ok(value)
52 }
53 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
55 let mut inside = sequence(parent, element)?;
56 let version = number(&mut inside)?;
57 if version.as_u64() != Some(3) {
58 return Err(invalid(ErrorCode::UnsupportedVersion, element));
59 }
60 let envelope = required(&mut inside, FIELD)?;
61 let (info, reader) = ContentInfo::read_element(&inside, &envelope)?;
62 let mac = inside
63 .next_element()
64 .map_err(encoding)?
65 .map(|value| MacData::read(&inside, &value))
66 .transpose()?;
67 end(&inside)?;
68 let integrity = if equal_oid(&inside, info.kind(), DATA)? {
69 Integrity::Password {
70 safe: Octets::read(&reader, info.content(), FIELD)?,
71 mac,
72 }
73 } else if equal_oid(&inside, info.kind(), SIGNED)? {
74 if mac.is_some() {
77 return Err(invalid(ErrorCode::FieldOrder, element));
78 }
79 let signed = SignedData::read_element(&reader, info.content())?;
80 if !equal_oid(&reader, signed.content().kind(), DATA)? {
81 return Err(invalid(ErrorCode::UnexpectedContentType, info.content()));
82 }
83 if signed.content().content().is_none() {
84 return Err(invalid(ErrorCode::DetachedContent, info.content()));
85 }
86 Integrity::Signed(signed)
87 } else {
88 return Err(invalid(ErrorCode::UnexpectedContentType, &envelope));
89 };
90 Ok(Self {
91 integrity,
92 original: EncodedValue::new(parent, *element),
93 })
94 }
95 #[must_use]
97 pub fn original(&self) -> &EncodedValue<'a> {
98 &self.original
99 }
100 #[must_use]
102 pub fn integrity(&self) -> &Integrity<'a> {
103 &self.integrity
104 }
105 pub(crate) fn safe(&self) -> &Octets<'a> {
106 match &self.integrity {
107 Integrity::Password { safe, .. } => safe,
108 Integrity::Signed(signed) => signed.content().content().expect("checked attached PFX"),
109 }
110 }
111}
112
113pub struct MacData<'a> {
115 pub algorithm: AlgorithmIdentifier<'a>,
117 pub digest: Octets<'a>,
119 pub salt: Octets<'a>,
121 pub iterations: Option<Integer<'a>>,
124 pub pbmac1: Option<protection::Pair<'a>>,
126}
127impl<'a> MacData<'a> {
128 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
130 let mut inside = sequence(parent, element)?;
131 let digest_info = required(&mut inside, FIELD)?;
132 let mut digest_info = sequence(&inside, &digest_info)?;
133 let algorithm = algorithm(&mut digest_info)?;
134 let value = required(&mut digest_info, FIELD)?;
135 let digest = Octets::read(&digest_info, &value, FIELD)?;
136 end(&digest_info)?;
137 let value = required(&mut inside, FIELD)?;
138 let salt = Octets::read(&inside, &value, FIELD)?;
139 let iterations = if inside.is_empty() {
140 None
141 } else {
142 Some(number(&mut inside)?)
143 };
144 end(&inside)?;
145 if let Some(rounds) = iterations {
148 default_one(parent, rounds, element)?;
149 }
150 let pbmac1 = if equal_oid(parent, algorithm.algorithm(), protection::PBMAC1)? {
151 let pair = protection::Pair::read(algorithm, parent)?;
152 if let Some(width) = protection::hmac_width(pair.scheme, parent)?
153 && digest.len() != width
154 {
155 return Err(invalid(ErrorCode::DigestWidth, element));
156 }
157 if let Some(kdf) = pair.pbkdf2.as_ref()
158 && kdf.key_length.is_none()
159 {
160 return Err(invalid(ErrorCode::MissingField, element));
161 }
162 Some(pair)
163 } else {
164 match structured_pkix::algorithm::digest::algorithm(&algorithm, &parent.execution())
165 .map_err(Error::pkix)?
166 {
167 structured_asn1::digest::Resolution::Supported(hash)
168 if digest.len() != hash.width() =>
169 {
170 return Err(invalid(ErrorCode::DigestWidth, element));
171 }
172 structured_asn1::digest::Resolution::Malformed => {
173 return Err(invalid(ErrorCode::AlgorithmSyntax, element));
174 }
175 _ => {}
176 }
177 if let Some(rounds) = iterations {
178 positive(rounds, element)?;
179 }
180 None
181 };
182 Ok(Self {
183 algorithm,
184 digest,
185 salt,
186 iterations,
187 pbmac1,
188 })
189 }
190}
191
192pub enum Safe<'a> {
194 Data(Octets<'a>),
196 Encrypted(EncryptedData<'a>),
198 Enveloped(crate::enveloped::EnvelopedData<'a>),
200 Other {
202 kind: Oid<'a>,
204 value: EncodedValue<'a>,
206 },
207}
208impl<'a> Safe<'a> {
209 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
211 let (info, reader) = ContentInfo::read_element(parent, element)?;
212 if equal_oid(parent, info.kind(), DATA)? {
213 Ok(Self::Data(Octets::read(&reader, info.content(), FIELD)?))
214 } else if equal_oid(parent, info.kind(), ENCRYPTED)? {
215 Ok(Self::Encrypted(EncryptedData::read(
216 &reader,
217 info.content(),
218 )?))
219 } else if equal_oid(parent, info.kind(), crate::enveloped::IDENTIFIER)? {
220 Ok(Self::Enveloped(
221 crate::enveloped::EnvelopedData::read_element(&reader, info.content())?,
222 ))
223 } else {
224 Ok(Self::Other {
225 kind: info.kind(),
226 value: EncodedValue::new(&reader, *info.content()),
227 })
228 }
229 }
230}
231
232pub struct EncryptedData<'a> {
234 pub content: crate::enveloped::EncryptedContent<'a>,
236 pub attributes: Option<OwnedVec<Attribute<'a>>>,
238 pub protection: protection::Protection<'a>,
240}
241impl<'a> EncryptedData<'a> {
242 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
244 let mut inside = sequence(parent, element)?;
245 let version = number(&mut inside)?;
246 let info = required(&mut inside, FIELD)?;
247 let content = crate::enveloped::encrypted_content(&inside, &info)?;
248 let attributes = inside
249 .next_element()
250 .map_err(encoding)?
251 .map(|set| attributes(&inside, &set, Tag::context(true, 1)))
252 .transpose()?;
253 end(&inside)?;
254 if version.as_u64() != Some(if attributes.is_some() { 2 } else { 0 }) {
255 return Err(invalid(ErrorCode::VersionMismatch, element));
256 }
257 if attributes.as_ref().is_some_and(|a| a.is_empty()) {
258 return Err(invalid(ErrorCode::EmptyAttributes, element));
259 }
260 let protection = protection::Protection::read(content.algorithm, parent)?;
261 Ok(Self {
262 content,
263 attributes,
264 protection,
265 })
266 }
267}
268
269pub struct PrivateKey<'a> {
271 pub original: EncodedValue<'a>,
273 pub version: u64,
275 pub algorithm: AlgorithmIdentifier<'a>,
277 pub secret: Octets<'a>,
279 pub attributes: Option<OwnedVec<Attribute<'a>>>,
281 pub public_key: Option<EncodedValue<'a>>,
283}
284impl<'a> PrivateKey<'a> {
285 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
287 let mut inside = sequence(parent, element)?;
288 let version = number(&mut inside)?
289 .as_u64()
290 .ok_or_else(|| invalid(ErrorCode::ValueTooLarge, element))?;
291 let algorithm = algorithm(&mut inside)?;
292 let value = required(&mut inside, FIELD)?;
293 let secret = Octets::read(&inside, &value, FIELD)?;
294 let mut next = inside.next_element().map_err(encoding)?;
295 let attributes = if let Some(set) = next.filter(|v| v.tag() == Tag::context(true, 0)) {
296 let attributes = attributes(&inside, &set, Tag::context(true, 0))?;
297 next = inside.next_element().map_err(encoding)?;
298 Some(attributes)
299 } else {
300 None
301 };
302 let public_key = if let Some(bits) = next {
303 if bits.tag() != Tag::context(false, 1) && bits.tag() != Tag::context(true, 1) {
304 return Err(invalid(ErrorCode::UnexpectedTag, &bits));
305 }
306 structured_pkix::der::implicit_bit_string(&inside, &bits, FIELD)
307 .map_err(Error::pkix)?;
308 Some(EncodedValue::new(&inside, bits))
309 } else {
310 None
311 };
312 end(&inside)?;
313 if version != u64::from(public_key.is_some()) {
314 return Err(invalid(ErrorCode::VersionMismatch, element));
315 }
316 Ok(Self {
317 original: EncodedValue::new(parent, *element),
318 version,
319 algorithm,
320 secret,
321 attributes,
322 public_key,
323 })
324 }
325}
326
327pub struct ShroudedKey<'a> {
329 pub algorithm: AlgorithmIdentifier<'a>,
331 pub encrypted: Octets<'a>,
333 pub protection: protection::Protection<'a>,
335}
336impl<'a> ShroudedKey<'a> {
337 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
339 let mut inside = sequence(parent, element)?;
340 let algorithm = algorithm(&mut inside)?;
341 let value = required(&mut inside, FIELD)?;
342 let encrypted = Octets::read(&inside, &value, FIELD)?;
343 end(&inside)?;
344 let protection = protection::Protection::read(algorithm, parent)?;
345 Ok(Self {
346 algorithm,
347 encrypted,
348 protection,
349 })
350 }
351}
352
353pub enum BagValue<'a> {
355 Key(PrivateKey<'a>),
357 Shrouded(ShroudedKey<'a>),
359 Certificate(Octets<'a>),
361 Sdsi(Octets<'a>),
363 Crl(Octets<'a>),
365 Secret {
367 kind: Oid<'a>,
369 value: EncodedValue<'a>,
371 },
372 Other {
374 kind: Oid<'a>,
376 value: EncodedValue<'a>,
378 },
379 Contents(EncodedValue<'a>),
381}
382pub struct Bag<'a> {
384 pub kind: Oid<'a>,
386 pub original: EncodedValue<'a>,
388 pub value: BagValue<'a>,
390 pub attributes: Option<OwnedVec<Attribute<'a>>>,
392}
393impl<'a> Bag<'a> {
394 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
397 let mut inside = sequence(parent, element)?;
398 let kind = inside.read_oid().map_err(encoding)?;
399 let wrapper = inside.expect(Tag::context(true, 0)).map_err(encoding)?;
400 let mut explicit = inside.enter(&wrapper).map_err(encoding)?;
401 let value = required(&mut explicit, FIELD)?;
402 end(&explicit)?;
403 let attributes = inside
404 .next_element()
405 .map_err(encoding)?
406 .map(|set| attributes(&inside, &set, Tag::constructed(universal::SET)))
407 .transpose()?;
408 end(&inside)?;
409 let value = if bag_id(parent, kind, 1)? {
411 BagValue::Key(PrivateKey::read(&explicit, &value)?)
412 } else if bag_id(parent, kind, 2)? {
413 BagValue::Shrouded(ShroudedKey::read(&explicit, &value)?)
414 } else if bag_id(parent, kind, 6)? {
415 tag(&value, Tag::constructed(universal::SEQUENCE))?;
416 BagValue::Contents(EncodedValue::new(&explicit, value))
417 } else if bag_id(parent, kind, 3)? || bag_id(parent, kind, 4)? || bag_id(parent, kind, 5)? {
418 let mut typed = sequence(&explicit, &value)?;
419 let inner_kind = typed.read_oid().map_err(encoding)?;
420 let wrapper = typed.expect(Tag::context(true, 0)).map_err(encoding)?;
421 let mut inner = typed.enter(&wrapper).map_err(encoding)?;
422 let content = required(&mut inner, FIELD)?;
423 end(&inner)?;
424 end(&typed)?;
425 let certificate = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 9, 22, 1]);
426 let sdsi = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 9, 22, 2]);
427 let crl = Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 9, 23, 1]);
428 if bag_id(parent, kind, 5)? {
429 structured_pkix::der::conforms(&inner, &content, FIELD).map_err(Error::pkix)?;
430 BagValue::Secret {
431 kind: inner_kind,
432 value: EncodedValue::new(&inner, content),
433 }
434 } else if bag_id(parent, kind, 3)? && equal_oid(parent, inner_kind, certificate)? {
435 BagValue::Certificate(Octets::read(&inner, &content, FIELD)?)
436 } else if bag_id(parent, kind, 3)? && equal_oid(parent, inner_kind, sdsi)? {
437 BagValue::Sdsi(Octets::read_ia5(&inner, &content, FIELD)?)
438 } else if bag_id(parent, kind, 4)? && equal_oid(parent, inner_kind, crl)? {
439 BagValue::Crl(Octets::read(&inner, &content, FIELD)?)
440 } else {
441 structured_pkix::der::conforms(&inner, &content, FIELD).map_err(Error::pkix)?;
442 BagValue::Other {
443 kind: inner_kind,
444 value: EncodedValue::new(&inner, content),
445 }
446 }
447 } else {
448 structured_pkix::der::conforms(&explicit, &value, FIELD).map_err(Error::pkix)?;
449 BagValue::Other {
450 kind,
451 value: EncodedValue::new(&explicit, value),
452 }
453 };
454 Ok(Self {
455 kind,
456 original: EncodedValue::new(parent, *element),
457 value,
458 attributes,
459 })
460 }
461}
462
463fn bag_id(parent: &Reader<'_>, oid: Oid<'_>, last: u8) -> Result<bool> {
464 equal_oid(
465 parent,
466 oid,
467 Oid::from_bytes(&[42, 134, 72, 134, 247, 13, 1, 12, 10, 1, last]),
468 )
469}
470pub(super) fn equal_oid(parent: &Reader<'_>, left: Oid<'_>, right: Oid<'_>) -> Result<bool> {
471 parent.charge(1).map_err(encoding)?;
472 if left.as_bytes().len() != right.as_bytes().len() {
473 return Ok(false);
474 }
475 parent
476 .charge(left.as_bytes().len() as u64)
477 .map_err(encoding)?;
478 Ok(left == right)
479}
480fn attributes<'a>(
481 parent: &Reader<'a>,
482 set: &Element<'a>,
483 expected: Tag,
484) -> Result<OwnedVec<Attribute<'a>>> {
485 tag(set, expected)?;
486 let mut inside = parent.enter(set).map_err(encoding)?;
487 let execution = parent.execution();
488 let mut out = execution.vector();
489 let mut previous = None;
490 while let Some(value) = inside.next_element().map_err(encoding)? {
491 if inside.encoding().is_der() {
492 if let Some(bytes) = previous
493 && !structured_pkix::der::set_ordered(&inside, bytes, &value, FIELD)
494 .map_err(Error::pkix)?
495 {
496 return Err(invalid(ErrorCode::SetOrder, &value));
497 }
498 previous = Some(value.as_bytes());
499 }
500 let attribute = Attribute::read(&inside, &value, FIELD)?;
501 if !inside.encoding().is_der() {
505 for (ordinal, item) in attribute.values().iter().enumerate() {
506 let reader = attribute
507 .value_reader_in(ordinal, &inside, FIELD)?
508 .expect("ordinal comes from this attribute's original values");
509 structured_pkix::der::conforms(&reader, item, FIELD).map_err(Error::pkix)?;
510 }
511 }
512 out.try_push(attribute)
513 .map_err(|e| Error::resource(e, FIELD, value.span().start))?;
514 }
515 Ok(out.into_owned())
516}
517pub(super) fn sequence<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Reader<'a>> {
518 tag(element, Tag::constructed(universal::SEQUENCE))?;
519 parent.enter(element).map_err(encoding)
520}
521pub(super) fn tag(element: &Element<'_>, expected: Tag) -> Result<()> {
522 if element.tag() != expected {
523 return Err(invalid(ErrorCode::UnexpectedTag, element));
524 }
525 Ok(())
526}
527pub(super) fn end(parent: &Reader<'_>) -> Result<()> {
528 if !parent.is_empty() {
529 return Err(Error::schema(
530 ErrorCode::TrailingData,
531 FIELD,
532 parent.offset(),
533 ));
534 }
535 Ok(())
536}
537pub(super) fn number<'a>(parent: &mut Reader<'a>) -> Result<Integer<'a>> {
538 parent.read_integer().map_err(encoding)
539}
540pub(super) fn positive(value: Integer<'_>, element: &Element<'_>) -> Result<()> {
541 if value.is_negative() || value.as_u64() == Some(0) {
542 return Err(invalid(ErrorCode::MalformedValue, element));
543 }
544 Ok(())
545}
546fn default_one(parent: &Reader<'_>, value: Integer<'_>, element: &Element<'_>) -> Result<()> {
547 if parent.encoding().is_der() && value.as_u64() == Some(1) {
548 return Err(invalid(ErrorCode::DefaultWritten, element));
549 }
550 Ok(())
551}
552pub(super) fn algorithm<'a>(parent: &mut Reader<'a>) -> Result<AlgorithmIdentifier<'a>> {
553 let element = required(parent, FIELD)?;
554 structured_pkix::algorithm::read(parent, &element, FIELD).map_err(Error::pkix)
555}
556pub(super) fn invalid(code: ErrorCode, element: &Element<'_>) -> Error {
557 Error::schema(code, FIELD, element.span().start)
558}
559pub(super) fn encoding(error: structured_asn1::Error) -> Error {
560 Error::encoding(error, FIELD)
561}