1use {
8 crate::{asn1time::*, rfc3280::*},
9 bcder::{
10 decode::{BytesSource, Constructed, DecodeError, IntoSource, Source},
11 encode,
12 encode::{PrimitiveContent, Values},
13 BitString, Captured, Integer, Mode, OctetString, Oid, Tag,
14 },
15 bytes::Bytes,
16 std::{
17 fmt::{Debug, Formatter},
18 io::Write,
19 ops::{Deref, DerefMut},
20 },
21};
22
23#[derive(Clone, Eq, PartialEq)]
31pub struct AlgorithmIdentifier {
32 pub algorithm: Oid,
33 pub parameters: Option<AlgorithmParameter>,
34}
35
36impl Debug for AlgorithmIdentifier {
37 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38 let mut s = f.debug_struct("AlgorithmIdentifier");
39 s.field("algorithm", &format_args!("{}", self.algorithm));
40 s.field("parameters", &self.parameters);
41 s.finish()
42 }
43}
44
45impl AlgorithmIdentifier {
46 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
47 cons.take_sequence(|cons| Self::take_sequence(cons))
48 }
49
50 pub fn take_opt_from<S: Source>(
51 cons: &mut Constructed<S>,
52 ) -> Result<Option<Self>, DecodeError<S::Error>> {
53 cons.take_opt_sequence(|cons| Self::take_sequence(cons))
54 }
55
56 fn take_sequence<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
57 let algorithm = Oid::take_from(cons)?;
58 let parameters = cons.capture_all()?;
59
60 let parameters = if parameters.is_empty() {
61 None
62 } else {
63 Some(AlgorithmParameter(parameters))
64 };
65
66 Ok(Self {
67 algorithm,
68 parameters,
69 })
70 }
71
72 fn encoded_values(&self, mode: Mode) -> impl Values + '_ {
73 let captured = if let Some(params) = self.parameters.as_ref() {
78 params.clone()
79 } else {
80 AlgorithmParameter(Captured::from_values(mode, ().encode_as(Tag::NULL)))
81 };
82
83 encode::sequence((self.algorithm.clone().encode(), captured))
84 }
85}
86
87impl Values for AlgorithmIdentifier {
88 fn encoded_len(&self, mode: Mode) -> usize {
89 self.encoded_values(mode).encoded_len(mode)
90 }
91
92 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
93 self.encoded_values(mode).write_encoded(mode, target)
94 }
95}
96
97#[derive(Clone, Debug)]
102pub struct AlgorithmParameter(Captured);
103
104impl AlgorithmParameter {
105 pub fn from_captured(captured: Captured) -> Self {
106 Self(captured)
107 }
108
109 pub fn from_oid(oid: Oid) -> Self {
111 let captured = Captured::from_values(Mode::Der, oid.encode());
112
113 Self(captured)
114 }
115
116 pub fn decode_oid(&self) -> Result<Oid, DecodeError<<BytesSource as Source>::Error>> {
118 let source = BytesSource::new(Bytes::copy_from_slice(self.0.as_slice()));
119
120 Constructed::decode(source, Mode::Der, Oid::take_from)
121 }
122}
123
124impl Deref for AlgorithmParameter {
125 type Target = Captured;
126
127 fn deref(&self) -> &Self::Target {
128 &self.0
129 }
130}
131
132impl DerefMut for AlgorithmParameter {
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.0
135 }
136}
137
138impl PartialEq for AlgorithmParameter {
139 fn eq(&self, other: &Self) -> bool {
140 self.0.as_slice() == other.0.as_slice()
141 }
142}
143
144impl Eq for AlgorithmParameter {}
145
146impl Values for AlgorithmParameter {
147 fn encoded_len(&self, mode: Mode) -> usize {
148 self.0.encoded_len(mode)
149 }
150
151 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
152 self.0.write_encoded(mode, target)
153 }
154}
155
156#[derive(Clone, Eq, PartialEq)]
167pub struct Certificate {
168 pub tbs_certificate: TbsCertificate,
169 pub signature_algorithm: AlgorithmIdentifier,
170 pub signature: BitString,
171}
172
173impl Debug for Certificate {
174 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
175 let mut s = f.debug_struct("Certificate");
176 s.field("tbs_certificate", &self.tbs_certificate);
177 s.field("signature_algorithm", &self.signature_algorithm);
178 s.field(
179 "signature",
180 &format_args!(
181 "{} (unused {})",
182 hex::encode(self.signature.octet_bytes()),
183 self.signature.unused()
184 ),
185 );
186 s.finish()
187 }
188}
189
190impl Certificate {
191 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
192 cons.take_sequence(|cons| Self::from_sequence(cons))
193 }
194
195 pub fn from_sequence<S: Source>(
196 cons: &mut Constructed<S>,
197 ) -> Result<Self, DecodeError<S::Error>> {
198 let tbs_certificate = TbsCertificate::take_from(cons)?;
199 let signature_algorithm = AlgorithmIdentifier::take_from(cons)?;
200 let signature = BitString::take_from(cons)?;
201
202 Ok(Self {
203 tbs_certificate,
204 signature_algorithm,
205 signature,
206 })
207 }
208
209 pub fn encode_ref(&self) -> impl Values + '_ {
210 encode::sequence((
211 self.tbs_certificate.encode_ref(),
212 &self.signature_algorithm,
213 self.signature.encode_ref(),
214 ))
215 }
216
217 pub fn iter_extensions(&self) -> impl Iterator<Item = &Extension> {
219 self.tbs_certificate
220 .extensions
221 .iter()
222 .flat_map(|x| x.iter())
223 }
224}
225
226#[derive(Clone, Eq, PartialEq)]
247pub struct TbsCertificate {
248 pub version: Option<Version>,
249 pub serial_number: CertificateSerialNumber,
250 pub signature: AlgorithmIdentifier,
251 pub issuer: Name,
252 pub validity: Validity,
253 pub subject: Name,
254 pub subject_public_key_info: SubjectPublicKeyInfo,
255 pub issuer_unique_id: Option<UniqueIdentifier>,
256 pub subject_unique_id: Option<UniqueIdentifier>,
257 pub extensions: Option<Extensions>,
258
259 pub raw_data: Option<Vec<u8>>,
263}
264
265impl Debug for TbsCertificate {
266 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
267 let mut s = f.debug_struct("TbsCertificate");
268 s.field("version", &self.version);
269 s.field("serial_number", &self.serial_number);
270 s.field("signature", &self.signature);
271 s.field("issuer", &self.issuer);
272 s.field("validity", &self.validity);
273 s.field("subject", &self.subject);
274 s.field("subject_public_key_info", &self.subject_public_key_info);
275 s.field("issuer_unique_id", &self.issuer_unique_id);
276 s.field("subject_unique_id", &self.subject_unique_id);
277 s.field("extensions", &self.extensions);
278 s.field(
279 "raw_data",
280 &format_args!("{:?}", self.raw_data.as_ref().map(hex::encode)),
281 );
282 s.finish()
283 }
284}
285
286impl TbsCertificate {
287 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
288 let mut res = None;
292
293 let captured = cons.capture(|cons| {
294 cons.take_sequence(|cons| {
295 let version = cons.take_opt_constructed_if(Tag::CTX_0, Version::take_from)?;
296 let serial_number = CertificateSerialNumber::take_from(cons)?;
297 let signature = AlgorithmIdentifier::take_from(cons)?;
298 let issuer = Name::take_from(cons)?;
299 let validity = Validity::take_from(cons)?;
300 let subject = Name::take_from(cons)?;
301 let subject_public_key_info = SubjectPublicKeyInfo::take_from(cons)?;
302 let issuer_unique_id = cons.take_opt_constructed_if(Tag::CTX_1, |cons| {
303 UniqueIdentifier::take_from(cons)
304 })?;
305 let subject_unique_id = cons.take_opt_constructed_if(Tag::CTX_2, |cons| {
306 UniqueIdentifier::take_from(cons)
307 })?;
308 let extensions =
309 cons.take_opt_constructed_if(Tag::CTX_3, Extensions::take_from)?;
310
311 res = Some(Self {
312 version,
313 serial_number,
314 signature,
315 issuer,
316 validity,
317 subject,
318 subject_public_key_info,
319 issuer_unique_id,
320 subject_unique_id,
321 extensions,
322 raw_data: None,
323 });
324
325 Ok(())
326 })
327 })?;
328
329 let mut res = res.unwrap();
330 res.raw_data = Some(captured.to_vec());
331
332 Ok(res)
333 }
334
335 pub fn encode_ref(&self) -> impl Values + '_ {
336 encode::sequence((
337 self.version
338 .as_ref()
339 .map(|v| encode::Constructed::new(Tag::CTX_0, u8::from(*v).encode())),
340 (&self.serial_number).encode(),
341 &self.signature,
342 self.issuer.encode_ref(),
343 self.validity.encode_ref(),
344 self.subject.encode_ref(),
345 self.subject_public_key_info.encode_ref(),
346 self.issuer_unique_id
347 .as_ref()
348 .map(|id| id.encode_ref_as(Tag::CTX_1)),
349 self.subject_unique_id
350 .as_ref()
351 .map(|id| id.encode_ref_as(Tag::CTX_2)),
352 self.extensions
353 .as_ref()
354 .map(|extensions| encode::Constructed::new(Tag::CTX_3, extensions.encode_ref())),
355 ))
356 }
357}
358
359#[derive(Clone, Copy, Debug, Eq, PartialEq)]
360pub enum Version {
361 V1 = 0,
362 V2 = 1,
363 V3 = 2,
364}
365
366impl Version {
367 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
368 match cons.take_primitive_if(Tag::INTEGER, Integer::i8_from_primitive)? {
369 0 => Ok(Self::V1),
370 1 => Ok(Self::V2),
371 2 => Ok(Self::V3),
372 _ => Err(cons.content_err("unexpected Version value")),
373 }
374 }
375
376 pub fn take_opt_from<S: Source>(
377 cons: &mut Constructed<S>,
378 ) -> Result<Option<Self>, DecodeError<S::Error>> {
379 match cons.take_opt_primitive_if(Tag::INTEGER, Integer::i8_from_primitive)? {
380 Some(0) => Ok(Some(Self::V1)),
381 Some(1) => Ok(Some(Self::V2)),
382 Some(2) => Ok(Some(Self::V3)),
383 _ => Err(cons.content_err("unexpected Version value")),
384 }
385 }
386
387 pub fn encode(self) -> impl Values {
388 u8::from(self).encode()
389 }
390}
391
392impl From<Version> for u8 {
393 fn from(v: Version) -> Self {
394 match v {
395 Version::V1 => 0,
396 Version::V2 => 1,
397 Version::V3 => 2,
398 }
399 }
400}
401
402pub type CertificateSerialNumber = Integer;
403
404#[derive(Clone, Debug, Eq, PartialEq)]
405pub struct Validity {
406 pub not_before: Time,
407 pub not_after: Time,
408}
409
410impl Validity {
411 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
412 cons.take_sequence(|cons| {
413 let not_before = Time::take_from(cons)?;
414 let not_after = Time::take_from(cons)?;
415
416 Ok(Self {
417 not_before,
418 not_after,
419 })
420 })
421 }
422
423 pub fn encode_ref(&self) -> impl Values + '_ {
424 encode::sequence((self.not_before.encode_ref(), self.not_after.encode_ref()))
425 }
426}
427
428pub type UniqueIdentifier = BitString;
429
430#[derive(Clone, Eq, PartialEq)]
438pub struct SubjectPublicKeyInfo {
439 pub algorithm: AlgorithmIdentifier,
440 pub subject_public_key: BitString,
441}
442
443impl Debug for SubjectPublicKeyInfo {
444 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
445 let mut s = f.debug_struct("SubjectPublicKeyInfo");
446 s.field("algorithm", &self.algorithm);
447 s.field(
448 "subject_public_key",
449 &format_args!(
450 "{} (unused {})",
451 hex::encode(self.subject_public_key.octet_bytes().as_ref()),
452 self.subject_public_key.unused()
453 ),
454 );
455 s.finish()
456 }
457}
458
459impl SubjectPublicKeyInfo {
460 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
461 cons.take_sequence(|cons| {
462 let algorithm = AlgorithmIdentifier::take_from(cons)?;
463 let subject_public_key = BitString::take_from(cons)?;
464
465 Ok(Self {
466 algorithm,
467 subject_public_key,
468 })
469 })
470 }
471
472 pub fn encode_ref(&self) -> impl Values + '_ {
473 encode::sequence((&self.algorithm, self.subject_public_key.encode_ref()))
474 }
475}
476
477#[derive(Clone, Debug, Default, Eq, PartialEq)]
483pub struct Extensions(Vec<Extension>);
484
485impl Extensions {
486 pub fn take_opt_from<S: Source>(
487 cons: &mut Constructed<S>,
488 ) -> Result<Option<Self>, DecodeError<S::Error>> {
489 cons.take_opt_sequence(|cons| Self::from_sequence(cons))
490 }
491
492 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
493 cons.take_sequence(|cons| Self::from_sequence(cons))
494 }
495
496 pub fn from_sequence<S: Source>(
497 cons: &mut Constructed<S>,
498 ) -> Result<Self, DecodeError<S::Error>> {
499 let mut extensions = Vec::new();
500
501 while let Some(extension) = Extension::take_opt_from(cons)? {
502 extensions.push(extension);
503 }
504
505 Ok(Self(extensions))
506 }
507
508 pub fn encode_ref(&self) -> impl Values + '_ {
509 encode::sequence(&self.0)
510 }
511
512 pub fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ {
513 encode::sequence_as(tag, &self.0)
514 }
515}
516
517impl Deref for Extensions {
518 type Target = Vec<Extension>;
519
520 fn deref(&self) -> &Self::Target {
521 &self.0
522 }
523}
524
525impl DerefMut for Extensions {
526 fn deref_mut(&mut self) -> &mut Self::Target {
527 &mut self.0
528 }
529}
530
531#[derive(Clone, Eq, PartialEq)]
544pub struct Extension {
545 pub id: Oid,
546 pub critical: Option<bool>,
547 pub value: OctetString,
548}
549
550impl Debug for Extension {
551 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
552 let mut s = f.debug_struct("Extension");
553 s.field("id", &format_args!("{}", self.id));
554 s.field("critical", &self.critical);
555 s.field(
556 "value",
557 &format_args!("{}", hex::encode(self.value.clone().into_bytes().as_ref())),
558 );
559 s.finish()
560 }
561}
562
563impl Extension {
564 pub fn take_opt_from<S: Source>(
565 cons: &mut Constructed<S>,
566 ) -> Result<Option<Self>, DecodeError<S::Error>> {
567 cons.take_opt_sequence(|cons| Self::from_sequence(cons))
568 }
569
570 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
571 cons.take_sequence(|cons| Self::from_sequence(cons))
572 }
573
574 fn from_sequence<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
575 let id = Oid::take_from(cons)?;
576 let critical = cons.take_opt_bool()?;
577 let value = OctetString::take_from(cons)?;
578
579 Ok(Self {
580 id,
581 critical,
582 value,
583 })
584 }
585
586 pub fn encode_ref(&self) -> impl Values + '_ {
587 encode::sequence((
588 self.id.encode_ref(),
589 if self.critical == Some(true) {
590 Some(true.encode())
591 } else {
592 None
593 },
594 self.value.encode_ref(),
595 ))
596 }
597
598 pub fn try_decode_sequence_single_oid(&self) -> Option<Oid> {
602 Constructed::decode(self.value.clone().into_source(), Mode::Der, |cons| {
603 cons.take_sequence(Oid::take_from)
604 })
605 .ok()
606 }
607}
608
609impl Values for Extension {
610 fn encoded_len(&self, mode: Mode) -> usize {
611 self.encode_ref().encoded_len(mode)
612 }
613
614 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> {
615 self.encode_ref().write_encoded(mode, target)
616 }
617}
618
619#[derive(Clone, Debug, Eq, PartialEq)]
628pub struct CertificateList {
629 pub tbs_cert_list: TbsCertList,
630 pub signature_algorithm: AlgorithmIdentifier,
631 pub signature: BitString,
632}
633
634impl CertificateList {
635 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
636 cons.take_sequence(|cons| Self::from_sequence(cons))
637 }
638
639 pub fn take_opt_from<S: Source>(
640 cons: &mut Constructed<S>,
641 ) -> Result<Option<Self>, DecodeError<S::Error>> {
642 cons.take_opt_sequence(|cons| Self::from_sequence(cons))
643 }
644
645 pub fn from_sequence<S: Source>(
646 cons: &mut Constructed<S>,
647 ) -> Result<Self, DecodeError<S::Error>> {
648 let tbs_cert_list = TbsCertList::take_from(cons)?;
649 let signature_algorithm = AlgorithmIdentifier::take_from(cons)?;
650 let signature = BitString::take_from(cons)?;
651
652 Ok(Self {
653 tbs_cert_list,
654 signature_algorithm,
655 signature,
656 })
657 }
658}
659
660#[derive(Clone, Debug, Eq, PartialEq)]
680pub struct TbsCertList {
681 pub version: Option<Version>,
682 pub signature: AlgorithmIdentifier,
683 pub issuer: Name,
684 pub this_update: Time,
685 pub next_update: Option<Time>,
686 pub revoked_certificates: Vec<(CertificateSerialNumber, Time, Option<Extensions>)>,
687 pub crl_extensions: Option<Extensions>,
688}
689
690impl TbsCertList {
691 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
692 let version = Version::take_opt_from(cons)?;
693 let signature = AlgorithmIdentifier::take_from(cons)?;
694 let issuer = Name::take_from(cons)?;
695 let this_update = Time::take_from(cons)?;
696 let next_update = Time::take_opt_from(cons)?;
697 let revoked_certificates = Vec::new();
698 let crl_extensions = None::<Extensions>;
699
700 Ok(Self {
701 version,
702 signature,
703 issuer,
704 this_update,
705 next_update,
706 revoked_certificates,
707 crl_extensions,
708 })
709 }
710}