pkix/
types.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7use yasna::{ASN1Error, ASN1ErrorKind, ASN1Result, BERReader, DERWriter, BERDecodable, PCBit, Tag};
8use yasna::tags::*;
9pub use yasna::models::{ObjectIdentifier, ParseOidError, TaggedDerValue};
10use std::borrow::Cow;
11use std::str;
12use std::fmt;
13use std::ops::{Deref, DerefMut};
14use chrono::{self, Utc, Datelike, Timelike, TimeZone};
15use {DerWrite, FromDer, oid};
16use crate::serialize::WriteIa5StringSafe;
17
18/// Maximum length as a `u32` (256 MiB).
19const MAX_U32: u32 = 0xfff_ffff;
20
21pub trait HasOid {
22    fn oid() -> &'static ObjectIdentifier;
23}
24
25pub trait SignatureAlgorithm {}
26
27#[derive(Clone, Debug, Eq, PartialEq, Hash)]
28pub struct RsaPkcs15<H>(pub H);
29
30impl<H> SignatureAlgorithm for RsaPkcs15<H> {}
31
32impl<'a> SignatureAlgorithm for DerSequence<'a> {}
33
34#[derive(Clone, Debug, Eq, PartialEq, Hash)]
35pub struct Sha256;
36
37/// sha256WithRSAEncryption
38impl DerWrite for RsaPkcs15<Sha256> {
39    fn write(&self, writer: DERWriter) {
40        writer.write_sequence(|writer| {
41            writer.next().write_oid(&oid::sha256WithRSAEncryption);
42            writer.next().write_null();
43        })
44    }
45}
46
47impl BERDecodable for RsaPkcs15<Sha256> {
48    fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
49        reader.read_sequence(|seq_reader| {
50            let oid = ObjectIdentifier::decode_ber(seq_reader.next())?;
51            seq_reader.next().read_null()?;
52            if oid == *oid::sha256WithRSAEncryption {
53                Ok(RsaPkcs15(Sha256))
54            } else {
55                Err(ASN1Error::new(ASN1ErrorKind::Invalid))
56            }
57        })
58    }
59}
60
61#[derive(Clone, Debug, Eq, PartialEq, Hash)]
62pub struct EcdsaX962<H>(pub H);
63
64impl<H> SignatureAlgorithm for EcdsaX962<H> {}
65
66/// ecdsaWithSHA256
67impl DerWrite for EcdsaX962<Sha256> {
68    fn write(&self, writer: DERWriter) {
69        writer.write_sequence(|writer| {
70            writer.next().write_oid(&oid::ecdsaWithSHA256);
71        })
72    }
73}
74
75impl BERDecodable for EcdsaX962<Sha256> {
76    fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
77        reader.read_sequence(|seq_reader| {
78            let oid = ObjectIdentifier::decode_ber(seq_reader.next())?;
79            if oid == *oid::ecdsaWithSHA256 {
80                Ok(EcdsaX962(Sha256))
81            } else {
82                Err(ASN1Error::new(ASN1ErrorKind::Invalid))
83            }
84        })
85    }
86}
87
88/// The GeneralName type, as defined in [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280#appendix-A.2).
89#[derive(Clone, Debug, Eq, PartialEq, Hash)]
90pub enum GeneralName<'a> {
91    OtherName(ObjectIdentifier, TaggedDerValue),
92    Rfc822Name(Cow<'a, str>),
93    DnsName(Cow<'a, str>),
94    // x400Address is not supported
95    DirectoryName(Name),
96    // ediPartyName is not supported
97    UniformResourceIdentifier(Cow<'a, str>),
98    IpAddress(Vec<u8>),
99    RegisteredID(ObjectIdentifier),
100}
101
102impl<'a> GeneralName<'a> {
103    const TAG_OTHER_NAME: u64 = 0;
104    const TAG_RFC822_NAME: u64 = 1;
105    const TAG_DNS_NAME: u64 = 2;
106    const TAG_DIRECTORY_NAME: u64 = 4;
107    const TAG_UNIFORM_RESOURCE_IDENTIFIER: u64 = 6;
108    const TAG_IP_ADDRESS: u64 = 7;
109    const TAG_REGISTERED_ID: u64 = 8;
110
111    pub fn is_other_name(&self) -> bool {
112        match *self {
113            GeneralName::OtherName(..) => true,
114            _ => false,
115        }
116    }
117
118    pub fn as_other_name(&self) -> Option<(&ObjectIdentifier, &TaggedDerValue)> {
119        match self {
120            GeneralName::OtherName(oid, tdv) => Some((oid, tdv)),
121            _ => None,
122        }
123    }
124
125    pub fn into_other_name(self) -> Option<(ObjectIdentifier, TaggedDerValue)> {
126        match self {
127            GeneralName::OtherName(oid, tdv) => Some((oid, tdv)),
128            _ => None,
129        }
130    }
131
132    pub fn is_rfc822_name(&self) -> bool {
133        match *self {
134            GeneralName::Rfc822Name(..) => true,
135            _ => false,
136        }
137    }
138
139    pub fn as_rfc822_name(&self) -> Option<&Cow<'a, str>> {
140        match self {
141            GeneralName::Rfc822Name(name) => Some(name),
142            _ => None,
143        }
144    }
145
146    pub fn into_rfc822_name(self) -> Option<Cow<'a, str>> {
147        match self {
148            GeneralName::Rfc822Name(name) => Some(name),
149            _ => None,
150        }
151    }
152
153    pub fn is_dns_name(&self) -> bool {
154        match *self {
155            GeneralName::DnsName(..) => true,
156            _ => false,
157        }
158    }
159
160    pub fn as_dns_name(&self) -> Option<&Cow<'a, str>> {
161        match self {
162            GeneralName::DnsName(name) => Some(name),
163            _ => None,
164        }
165    }
166
167    pub fn into_dns_name(self) -> Option<Cow<'a, str>> {
168        match self {
169            GeneralName::DnsName(name) => Some(name),
170            _ => None,
171        }
172    }
173
174    pub fn is_directory_name(&self) -> bool {
175        match *self {
176            GeneralName::DirectoryName(..) => true,
177            _ => false,
178        }
179    }
180
181    pub fn as_directory_name(&self) -> Option<&Name> {
182        match self {
183            GeneralName::DirectoryName(name) => Some(name),
184            _ => None,
185        }
186    }
187
188    pub fn into_directory_name(self) -> Option<Name> {
189        match self {
190            GeneralName::DirectoryName(name) => Some(name),
191            _ => None,
192        }
193    }
194
195    pub fn is_uniform_resource_identifier(&self) -> bool {
196        match *self {
197            GeneralName::UniformResourceIdentifier(..) => true,
198            _ => false,
199        }
200    }
201
202    pub fn as_uniform_resource_identifier(&self) -> Option<&Cow<'a, str>> {
203        match self {
204            GeneralName::UniformResourceIdentifier(name) => Some(name),
205            _ => None,
206        }
207    }
208
209    pub fn into_uniform_resource_identifier(self) -> Option<Cow<'a, str>> {
210        match self {
211            GeneralName::UniformResourceIdentifier(name) => Some(name),
212            _ => None,
213        }
214    }
215
216    pub fn is_ip_address(&self) -> bool {
217        match *self {
218            GeneralName::IpAddress(..) => true,
219            _ => false,
220        }
221    }
222
223    pub fn as_ip_address(&self) -> Option<&Vec<u8>> {
224        match self {
225            GeneralName::IpAddress(ip) => Some(ip),
226            _ => None,
227        }
228    }
229
230    pub fn into_ip_address(self) -> Option<Vec<u8>> {
231        match self {
232            GeneralName::IpAddress(ip) => Some(ip),
233            _ => None,
234        }
235    }
236
237    pub fn is_registered_id(&self) -> bool {
238        match *self {
239            GeneralName::RegisteredID(..) => true,
240            _ => false,
241        }
242    }
243
244    pub fn as_registered_id(&self) -> Option<&ObjectIdentifier> {
245        match self {
246            GeneralName::RegisteredID(oid) => Some(oid),
247            _ => None,
248        }
249    }
250
251    pub fn into_registered_id(self) -> Option<ObjectIdentifier> {
252        match self {
253            GeneralName::RegisteredID(oid) => Some(oid),
254            _ => None,
255        }
256    }
257}
258
259impl<'a> DerWrite for GeneralName<'a> {
260    fn write(&self, writer: DERWriter) {
261        match self {
262            GeneralName::OtherName(oid, tdv) =>
263                writer.write_tagged_implicit(
264                    Tag::context(Self::TAG_OTHER_NAME),
265                    |w| w.write_sequence(|w| {
266                        oid.write(w.next());
267                        w.next().write_tagged(Tag::context(0), |w| tdv.write(w));
268                    })),
269            GeneralName::Rfc822Name(s) =>
270                writer.write_tagged_implicit(
271                    Tag::context(Self::TAG_RFC822_NAME),
272                    |w| w.write_ia5_string_safe(&s)
273                ),
274            GeneralName::DnsName(s) =>
275                writer.write_tagged_implicit(
276                    Tag::context(Self::TAG_DNS_NAME),
277                    |w| w.write_ia5_string_safe(&s)
278                ),
279            GeneralName::DirectoryName(n) =>
280                // explicit tagging because Name is an untagged CHOICE (X.680-0207 clause 30.6.c)
281                writer.write_tagged(
282                    Tag::context(Self::TAG_DIRECTORY_NAME),
283                    |w| n.write(w)
284                ),
285            GeneralName::UniformResourceIdentifier(s) =>
286                writer.write_tagged_implicit(
287                    Tag::context(Self::TAG_UNIFORM_RESOURCE_IDENTIFIER),
288                    |w| w.write_ia5_string_safe(&s)
289                ),
290            GeneralName::IpAddress(a) =>
291                writer.write_tagged_implicit(
292                    Tag::context(Self::TAG_IP_ADDRESS),
293                    |w| a.write(w)
294                ),
295            GeneralName::RegisteredID(oid) =>
296                writer.write_tagged_implicit(
297                    Tag::context(Self::TAG_REGISTERED_ID),
298                    |w| oid.write(w)
299                ),
300        }
301    }
302}
303
304impl<'a> BERDecodable for GeneralName<'a> {
305    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
306        let tag_number = reader.lookahead_tag()?.tag_number;
307        if tag_number == Self::TAG_DIRECTORY_NAME {
308            // explicit tagging because Name is an untagged CHOICE (X.680-0207 clause 30.6.c)
309            reader.read_tagged(Tag::context(tag_number), |r| {
310                Ok(GeneralName::DirectoryName(Name::decode_ber(r)?))
311            })
312        } else {
313            reader.read_tagged_implicit(Tag::context(tag_number), |r| {
314                match tag_number {
315                    Self::TAG_OTHER_NAME => {
316                        r.read_sequence(|r| {
317                            let oid = ObjectIdentifier::decode_ber(r.next())?;
318                            let value = r.next().read_tagged(Tag::context(0), |r| TaggedDerValue::decode_ber(r))?;
319                            Ok(GeneralName::OtherName(oid, value))
320                        })
321                    },
322                    Self::TAG_RFC822_NAME => Ok(GeneralName::Rfc822Name(r.read_ia5_string()?.into())),
323                    Self::TAG_DNS_NAME => Ok(GeneralName::DnsName(r.read_ia5_string()?.into())),
324                    Self::TAG_UNIFORM_RESOURCE_IDENTIFIER => Ok(GeneralName::UniformResourceIdentifier(r.read_ia5_string()?.into())),
325                    Self::TAG_IP_ADDRESS => Ok(GeneralName::IpAddress(r.read_bytes()?)),
326                    Self::TAG_REGISTERED_ID => Ok(GeneralName::RegisteredID(ObjectIdentifier::decode_ber(r)?)),
327                    _ => Err(ASN1Error::new(ASN1ErrorKind::Invalid)),
328                }
329            })
330        }
331    }
332}
333
334
335/// GeneralNames as defined in [RFC 5280 Section 4.2.1.6].
336///
337/// ```text
338/// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
339/// ```
340///
341/// [RFC 5280 Section 4.2.1.6]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6
342#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
343pub struct GeneralNames<'a>(pub Vec<GeneralName<'a>>);
344
345impl<'a> DerWrite for GeneralNames<'a> {
346    fn write(&self, writer: DERWriter) {
347        writer.write_sequence_of(|w| {
348            for general_name in &self.0 {
349                general_name.write(w.next())
350            }
351        })
352    }
353}
354
355impl<'a> BERDecodable for GeneralNames<'a> {
356    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
357        Ok(GeneralNames(reader.collect_sequence_of(GeneralName::decode_ber)?))
358    }
359}
360
361impl<'a> Deref for GeneralNames<'a> {
362    type Target = Vec<GeneralName<'a>>;
363
364    fn deref(&self) -> &Self::Target {
365        &self.0
366    }
367}
368
369impl<'a> DerefMut for GeneralNames<'a> {
370    fn deref_mut(&mut self) -> &mut Self::Target {
371        &mut self.0
372    }
373}
374
375impl<'a> From<Vec<GeneralName<'a>>> for GeneralNames<'a> {
376    fn from(names: Vec<GeneralName<'a>>) -> GeneralNames<'a> {
377        GeneralNames(names)
378    }
379}
380
381impl<'a> From<GeneralNames<'a>> for Vec<GeneralName<'a>> {
382    fn from(general_names: GeneralNames<'a>) -> Vec<GeneralName<'a>> {
383        general_names.0
384    }
385}
386
387#[derive(Clone, Debug, Eq, PartialEq, Hash)]
388pub struct Name {
389    // The actual ASN.1 type is Vec<HashSet<(ObjectIdentifier, TaggedDerValue)>>.
390    // However, having more than one element in the set is extremely uncommon.
391    //
392    // On deserialization, we flatten the structure. This results in
393    // technically non-compliant equality testing (RFC 5280, ยง7.1). On
394    // serialization, we always put each `AttributeTypeAndValue` in its own
395    // set.
396    //
397    // Additional discussion in https://github.com/zmap/zlint/issues/220
398    pub value: Vec<(ObjectIdentifier, TaggedDerValue)>,
399}
400
401impl Name {
402    pub fn get(&self, oid: &ObjectIdentifier) -> Option<&TaggedDerValue> {
403        self.value.iter().find(|v| v.0 == *oid).map(|v| &v.1)
404    }
405}
406
407impl fmt::Display for Name {
408    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409        for (i,v) in self.value.iter().enumerate() {
410            if i > 0 {
411                write!(f, ", ")?;
412            }
413
414            // print key (oid)
415            if let Some(o) = oid::OID_TO_NAME.get(&v.0) {
416                write!(f, "{}", o)?;
417            } else {
418                for (j,c) in v.0.components().iter().enumerate() {
419                    if j > 0 {
420                        write!(f, ".")?;
421                    }
422                    write!(f, "{}", c)?;
423                }
424            }
425            write!(f, "=")?;
426
427            // print value
428            match (v.1.pcbit(), v.1.tag()) {
429                (PCBit::Primitive, TAG_NUMERICSTRING) | (PCBit::Primitive, TAG_PRINTABLESTRING) | (PCBit::Primitive, TAG_IA5STRING) | (PCBit::Primitive, TAG_UTF8STRING) =>
430                    write!(f, "{}", String::from_utf8_lossy(&v.1.value()))?,
431                _ => for &byte in v.1.value() {
432                    write!(f, "{:x}", byte)?;
433                },
434            }
435        }
436        Ok(())
437    }
438}
439
440impl From<Vec<(ObjectIdentifier, TaggedDerValue)>> for Name {
441    fn from(b: Vec<(ObjectIdentifier, TaggedDerValue)>) -> Name {
442        Name { value: b }
443    }
444}
445
446impl DerWrite for Name {
447    fn write(&self, writer: DERWriter) {
448        writer.write_sequence(|writer| {
449            for &(ref oid, ref value) in &self.value {
450                writer.next().write_set(|writer| {
451                    writer.next().write_sequence(|writer| {
452                        oid.write(writer.next());
453                        value.write(writer.next());
454                    });
455                });
456            }
457        });
458    }
459}
460
461impl BERDecodable for Name {
462    fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
463        reader.read_sequence(|seq_reader| {
464            let mut vals = Vec::<(ObjectIdentifier, TaggedDerValue)>::new();
465
466            loop {
467                let res = seq_reader.read_optional(|r| {
468                    r.read_set_of(|r| {
469                        let val = r.read_sequence(|r| {
470                            let oid = ObjectIdentifier::decode_ber(r.next())?;
471                            let value = TaggedDerValue::decode_ber(r.next())?;
472                            Ok((oid, value))
473                        })?;
474                        vals.push(val);
475                        Ok(())
476                    })
477                });
478                match res {
479                    Ok(Some(())) => {},
480                    Ok(None) => break,
481                    Err(e) => return Err(e),
482                }
483            }
484
485            Ok(Name { value: vals })
486        })
487    }
488}
489
490#[derive(Debug, Clone)]
491pub enum NameComponent {
492    Str(String),
493    Bytes(Vec<u8>)
494}
495
496impl NameComponent {
497    pub fn bytes(&self) -> Option<&[u8]> {
498        match *self {
499            NameComponent::Bytes(ref v) => Some(&v),
500            _ => None,
501        }
502    }
503}
504
505impl From<String> for NameComponent {
506    fn from(s: String) -> NameComponent {
507        NameComponent::Str(s)
508    }
509}
510
511impl From<Vec<u8>> for NameComponent {
512    fn from(b: Vec<u8>) -> NameComponent {
513        NameComponent::Bytes(b)
514    }
515}
516
517impl From<NameComponent> for TaggedDerValue {
518    fn from(nc: NameComponent) -> TaggedDerValue {
519        match nc {
520            NameComponent::Str(str) => TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, str.into_bytes()),
521            NameComponent::Bytes(mut val) => {
522                // mbedTLS does not support OCTET STRING in any name component. It does
523                // support BIT STRING, however, so we always use that. The first byte of
524                // a bit string is the number of unused bits. Since we start from a Vec<u8>,
525                // we always have a multiple of 8 bits and hence no bits are unused.
526                val.insert(0, 0);
527                TaggedDerValue::from_tag_and_bytes(TAG_BITSTRING, val)
528            }
529        }
530    }
531}
532
533#[derive(Clone, Debug, Eq, PartialEq, Hash)]
534pub struct Extensions(pub Vec<Extension>);
535
536impl DerWrite for Extensions {
537    fn write(&self, writer: DERWriter) {
538        writer.write_sequence_of(|w| {
539            for extension in &self.0 {
540                extension.write(w.next());
541            }
542        });
543    }
544}
545
546impl BERDecodable for Extensions {
547    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
548        Ok(Extensions(reader.collect_sequence_of(Extension::decode_ber)?))
549    }
550}
551
552impl Deref for Extensions {
553    type Target = Vec<Extension>;
554
555    fn deref(&self) -> &Self::Target {
556        &self.0
557    }
558}
559
560impl DerefMut for Extensions {
561    fn deref_mut(&mut self) -> &mut Self::Target {
562        &mut self.0
563    }
564}
565
566impl From<Vec<Extension>> for Extensions {
567    fn from(extensions: Vec<Extension>) -> Extensions {
568        Extensions(extensions)
569    }
570}
571
572impl From<Extensions> for Vec<Extension> {
573    fn from(extensions: Extensions) -> Vec<Extension> {
574        extensions.0
575    }
576}
577
578impl Extensions {
579    pub fn get_extension<T: FromDer + HasOid>(&self) -> Option<T> {
580        let oid = T::oid();
581
582        // We reject extensions that appear multiple times.
583        let mut iter = self.0.iter().filter(|a| a.oid == *oid);
584        match (iter.next(), iter.next()) {
585            (Some(attr), None) => T::from_der(&attr.value).ok(),
586            _ => None,
587        }
588    }
589}
590
591#[derive(Clone, Debug, Eq, PartialEq, Hash)]
592pub struct Extension {
593    pub oid: ObjectIdentifier,
594    pub critical: bool,
595    pub value: Vec<u8>,
596}
597
598impl DerWrite for Extension {
599    fn write(&self, writer: DERWriter) {
600        writer.write_sequence(|writer| {
601            self.oid.write(writer.next());
602            if self.critical {
603                true.write(writer.next());
604            }
605            self.value.write(writer.next());
606        });
607    }
608}
609
610impl BERDecodable for Extension {
611    fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
612        reader.read_sequence(|seq_reader| {
613            let oid = ObjectIdentifier::decode_ber(seq_reader.next())?;
614            let critical = seq_reader.read_default(false, |r| bool::decode_ber(r))?;
615            let value = seq_reader.next().read_bytes()?;
616            Ok(Extension { oid, critical, value })
617        })
618    }
619}
620
621#[derive(Clone, Debug, Eq, PartialEq, Hash)]
622pub struct Attribute<'a> {
623    pub oid: ObjectIdentifier,
624    pub value: Vec<DerSequence<'a>>,
625}
626
627impl<'a> DerWrite for Attribute<'a> {
628    fn write(&self, writer: DERWriter) {
629        writer.write_sequence(|writer| {
630            self.oid.write(writer.next());
631            writer.next().write_set(|writer| {
632                for value in &self.value {
633                    value.write(writer.next());
634                }
635            });
636        });
637    }
638}
639
640impl<'a> BERDecodable for Attribute<'a> {
641    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
642        reader.read_sequence(|seq_reader| {
643            let oid = ObjectIdentifier::decode_ber(seq_reader.next())?;
644
645            let mut value = Vec::new();
646            seq_reader.next().read_set_of(|r| {
647                value.push(DerSequence::decode_ber(r)?);
648                Ok(())
649            })?;
650
651            Ok(Attribute { oid, value })
652        })
653    }
654}
655
656#[derive(Clone, Debug, Eq, PartialEq, Hash)]
657pub struct DateTime(chrono::DateTime<Utc>);
658
659impl From<chrono::DateTime<Utc>> for DateTime {
660    fn from(datetime: chrono::DateTime<Utc>) -> Self {
661        DateTime(datetime)
662    }
663}
664
665impl Into<chrono::DateTime<Utc>> for DateTime {
666    fn into(self) -> chrono::DateTime<Utc> {
667        self.0
668    }
669}
670
671impl DateTime {
672    pub fn new(year: u16, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> Option<Self> {
673        Utc.with_ymd_and_hms(year.into(), month.into(), day.into(), hour.into(), minute.into(), second.into())
674            .earliest()
675            .map(Self)
676    }
677
678    pub fn from_seconds_since_epoch(seconds: i64) -> Option<Self> {
679        Utc.timestamp_opt(seconds, 0)
680            .earliest()
681            .map(Self)
682    }
683
684    pub fn to_seconds_since_epoch(&self) -> i64 {
685        self.0.timestamp()
686    }
687}
688
689impl DerWrite for DateTime {
690    fn write(&self, writer: DERWriter) {
691        let offset = match self.0.year() {
692            1950..=1999 => 1900,
693            2000..=2049 => 2000,
694            _ => 0,
695        };
696        if offset != 0 {
697            let t = format!("{:02}{:02}{:02}{:02}{:02}{:02}Z",
698                            self.0.year() - offset,
699                            self.0.month(),
700                            self.0.day(),
701                            self.0.hour(),
702                            self.0.minute(),
703                            self.0.second());
704            writer.write_tagged_implicit(TAG_UTCTIME, |w| t.as_bytes().write(w));
705        } else {
706            let t = format!("{:04}{:02}{:02}{:02}{:02}{:02}Z",
707                            self.0.year(),
708                            self.0.month(),
709                            self.0.day(),
710                            self.0.hour(),
711                            self.0.minute(),
712                            self.0.second());
713            writer.write_tagged_implicit(TAG_GENERALIZEDTIME, |w| t.as_bytes().write(w));
714        }
715    }
716}
717
718impl BERDecodable for DateTime {
719    /// This code only accepts dates including seconds and in UTC "Z" time zone.
720    /// These restrictions are imposed by RFC5280.
721    fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
722        let tv = reader.read_tagged_der()?;
723        let tag = tv.tag();
724        let value = tv.value();
725        let (year, rest, tz) = match tag {
726            TAG_UTCTIME => {
727                let (date, tz) = value.split_at(12);
728                let (year, rest) = date.split_at(2);
729
730                let year = str::from_utf8(&year).ok().and_then(|s| u16::from_str_radix(s, 10).ok())
731                    .ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
732                let year = if year < 50 { 2000 + year } else { 1900 + year };
733
734                (year, rest, tz)
735            }
736            TAG_GENERALIZEDTIME => {
737                let (date, tz) = value.split_at(14);
738                let (year, rest) = date.split_at(4);
739
740                let year = str::from_utf8(&year).ok().and_then(|s| u16::from_str_radix(s, 10).ok())
741                    .ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
742
743                (year, rest, tz)
744            }
745            _ => return Err(ASN1Error::new(ASN1ErrorKind::Invalid)),
746        };
747
748        if tz != b"Z" {
749            return Err(ASN1Error::new(ASN1ErrorKind::Invalid));
750        }
751
752        let mut iter = rest.chunks(2).filter_map(|v| {
753            str::from_utf8(&v).ok().and_then(|s| u8::from_str_radix(s, 10).ok())
754        });
755
756        let month = iter.next().ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
757        let day = iter.next().ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
758        let hour = iter.next().ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
759        let minute = iter.next().ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
760        let second = iter.next().ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))?;
761
762        DateTime::new(year, month, day, hour, minute, second)
763            .ok_or(ASN1Error::new(ASN1ErrorKind::Invalid))
764    }
765}
766
767pub type DerAnyOwned = DerSequence<'static>;
768pub type DerAny<'a> = DerSequence<'a>;
769
770#[derive(Clone, Debug, Eq, PartialEq, Hash)]
771pub struct DerSequence<'a> {
772    pub value: Cow<'a, [u8]>,
773}
774
775impl<'a> DerWrite for DerSequence<'a> {
776    fn write(&self, writer: DERWriter) {
777        writer.write_der(&self.value)
778    }
779}
780
781impl<'a> From<&'a [u8]> for DerSequence<'a> {
782    fn from(b: &'a [u8]) -> DerSequence<'a> {
783        DerSequence { value: Cow::Borrowed(b) }
784    }
785}
786
787impl From<Vec<u8>> for DerSequence<'static> {
788    fn from(b: Vec<u8>) -> DerSequence<'static> {
789        DerSequence { value: Cow::Owned(b) }
790    }
791}
792
793impl<'a> AsRef<[u8]> for DerSequence<'a> {
794    fn as_ref(&self) -> &[u8] {
795        self.value.as_ref()
796    }
797}
798
799impl<'a> BERDecodable for DerSequence<'a> {
800    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
801        Ok(reader.read_der()?.into())
802    }
803}
804
805/// A wrapper to ensure DateTime is always encoded as GeneralizedTime
806#[derive(Clone, Debug, Eq, PartialEq, Hash)]
807pub struct GeneralizedTime(pub DateTime);
808
809impl DerWrite for GeneralizedTime {
810    fn write(&self, writer: DERWriter) {
811        let chrono_time: chrono::DateTime<chrono::offset::Utc> = self.0.clone().into();
812        let t = format!(
813            "{:04}{:02}{:02}{:02}{:02}{:02}Z",
814            chrono_time.year(),
815            chrono_time.month(),
816            chrono_time.day(),
817            chrono_time.hour(),
818            chrono_time.minute(),
819            chrono_time.second()
820        );
821        writer.write_tagged_implicit(TAG_GENERALIZEDTIME, |w| t.as_bytes().write(w));
822    }
823}
824
825impl BERDecodable for GeneralizedTime {
826    /// This code only accepts dates including seconds and in UTC "Z" time zone.
827    /// These restrictions are imposed by RFC5280.
828    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
829        Ok(GeneralizedTime(DateTime::decode_ber(reader)?))
830    }
831}
832
833/// ASN.1 `OCTET STRING` type: owned form..
834///
835/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
836///
837#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
838pub struct OctetString {
839    /// Bitstring represented as a slice of bytes.
840    inner: Vec<u8>,
841}
842
843impl OctetString {
844    /// Maximum length currently supported: 256 MiB
845    pub const MAX: u32 = MAX_U32;
846
847    /// Create a new ASN.1 `OCTET STRING`.
848    pub fn new(bytes: impl Into<Vec<u8>>) -> ASN1Result<Self> {
849        let inner: Vec<u8> = bytes.into();
850        if inner.len() > Self::MAX as usize {
851            Err(ASN1Error::new(ASN1ErrorKind::IntegerOverflow))
852        } else {
853            Ok(Self { inner })
854        }
855    }
856
857    /// Borrow the inner byte slice.
858    pub fn as_bytes(&self) -> &[u8] {
859        self.inner.as_slice()
860    }
861
862    /// Take ownership of the octet string.
863    pub fn into_bytes(self) -> Vec<u8> {
864        self.inner
865    }
866
867    /// Get the length of the inner byte slice.
868    pub fn len(&self) -> usize {
869        self.inner.len()
870    }
871
872    /// Is the inner byte slice empty?
873    pub fn is_empty(&self) -> bool {
874        self.inner.is_empty()
875    }
876}
877
878impl DerWrite for OctetString {
879    fn write(&self, writer: DERWriter) {
880        writer.write_bytes(&self.inner);
881    }
882}
883
884impl BERDecodable for OctetString {
885    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
886        OctetString::new(reader.read_bytes()?)
887    }
888}
889
890impl AsRef<[u8]> for OctetString {
891    fn as_ref(&self) -> &[u8] {
892        &self.inner
893    }
894}
895
896/// ASN.1 `IA5String` type.
897///
898/// Supports the [International Alphabet No. 5 (IA5)] character encoding, i.e.
899/// the lower 128 characters of the ASCII alphabet. (Note: IA5 is now
900/// technically known as the International Reference Alphabet or IRA as
901/// specified in the ITU-T's T.50 recommendation).
902///
903/// For UTF-8, use [`String`][`alloc::string::String`].
904///
905/// [International Alphabet No. 5 (IA5)]: https://en.wikipedia.org/wiki/T.50_%28standard%29
906#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
907pub struct Ia5String(pub String);
908
909impl BERDecodable for Ia5String {
910    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
911        Ok(Ia5String(reader.read_ia5_string()?))
912    }
913}
914
915impl DerWrite for Ia5String {
916    fn write(&self, writer: DERWriter) {
917        writer.write_ia5_string_safe(&self.0)
918    }
919}
920
921impl From<String> for Ia5String {
922    fn from(value: String) -> Self {
923        Self(value)
924    }
925}
926
927
928derive_sequence!{
929    /// X.509 `AlgorithmIdentifier` as defined in [RFC 5280 Section 4.1.1.2].
930    ///
931    /// ```text
932    /// AlgorithmIdentifier  ::=  SEQUENCE  {
933    ///      algorithm               OBJECT IDENTIFIER,
934    ///      parameters              ANY DEFINED BY algorithm OPTIONAL  }
935    /// ```
936    ///
937    /// [RFC 5280 Section 4.1.1.2]: https://tools.ietf.org/html/rfc5280#section-4.1.1.2
938    AlgorithmIdentifierOwned {
939        oid: [_] UNTAGGED REQUIRED: ObjectIdentifier,
940        parameters: [_] UNTAGGED OPTIONAL: Option<DerAnyOwned>
941    }
942}
943
944#[cfg(test)]
945mod tests {
946    use super::*;
947    use crate::test::test_encode_decode;
948    use yasna;
949    use yasna::tags::TAG_UTF8STRING;
950
951    #[test]
952    fn name() {
953        let name = Name {
954            value: vec![
955                (oid::commonName.clone(),
956                 TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test name".to_vec())),
957                (oid::description.clone(),
958                 TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test description".to_vec())),
959            ]
960        };
961
962        let der = vec![0x30, 0x2f, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09,
963                       0x54, 0x65, 0x73, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x31, 0x19, 0x30, 0x17,
964                       0x06, 0x03, 0x55, 0x04, 0x0d, 0x0c, 0x10, 0x54, 0x65, 0x73, 0x74, 0x20, 0x64,
965                       0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e];
966        test_encode_decode(&name, &der);
967    }
968
969    #[test]
970    fn name_format() {
971        let name = Name {
972            value: vec![
973                (oid::commonName.clone(),
974                 TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test name".to_vec())),
975                (ObjectIdentifier::new(vec![1,2,3,4]),
976                 TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Custom DN".to_vec())),
977                (ObjectIdentifier::new(vec![2, 5, 4, 34]),
978                 TaggedDerValue::from_tag_and_bytes(TAG_NUMERICSTRING, b"23".to_vec())),
979            ]
980        };
981
982        assert_eq!(format!("{}", name), "CN=Test name, 1.2.3.4=Custom DN, seeAlso=23");
983    }
984
985    #[test]
986    fn name_multi_value_rdn() {
987        let ber = b"0\x82\x01\xca1\x82\x01]0\x1c\x06\x03U\x04\x0b\x13\x15opc-certtype:instance0r\x06\x03U\x04\x0b\x13kopc-instance:ocid1.instance.oc1.eu-frankfurt-1.abtheljrfsguhltfu6r2y6gwhthevlmgl2ijdl4ozpm34ejr6vgalufakjzq0f\x06\x03U\x04\x0b\x13_opc-compartment:ocid1.tenancy.oc1..aaaaaaaafruudnficveu7ajrk346ilmbdwjzumqe6zn7uoap77awgnpnjoea0a\x06\x03U\x04\x0b\x13Zopc-tenant:ocid1.tenancy.oc1..aaaaaaaafruudnficveu7ajrk346ilmbdwjzumqe6zn7uoap77awgnpnjoea1g0e\x06\x03U\x04\x03\x13^ocid1.instance.oc1.eu-frankfurt-1.abtheljrfsguhltfu6r2y6gwhthevlmgl2ijdl4ozpm34ejr6vgalufakjzq";
988
989        let parsed = yasna::parse_ber(&ber[..], |r| Name::decode_ber(r)).unwrap();
990        assert_eq!(parsed.value.len(), 5);
991    }
992
993    #[test]
994    fn extensions() {
995        let extensions = Extensions(vec![
996            Extension {
997                oid: oid::basicConstraints.clone(),
998                critical: true,
999                value: vec![0x30, 0x00],
1000            },
1001            Extension {
1002                oid: oid::keyUsage.clone(),
1003                critical: true,
1004                value: vec![0x03, 0x03, 0x07, 0x80, 0x00],
1005            },
1006        ]);
1007
1008        let der = &[
1009            0x30, 0x1f, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
1010            0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
1011            0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
1012            0x01, 0xff, 0x04, 0x05, 0x03, 0x03, 0x07, 0x80,
1013            0x00];
1014
1015        test_encode_decode(&extensions, der);
1016    }
1017
1018    #[test]
1019    fn general_name_other_name() {
1020        let general_name = GeneralName::OtherName(
1021            ObjectIdentifier::new(vec![1,2,3,4]),
1022            TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test name".to_vec())
1023        );
1024
1025        let der = &[
1026            0xa0, 0x12, 0x06, 0x03, 0x2a, 0x03, 0x04, 0xa0,
1027            0x0b, 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20,
1028            0x6e, 0x61, 0x6d, 0x65];
1029
1030        test_encode_decode(&general_name, der);
1031    }
1032
1033    #[test]
1034    fn general_name_rfc822_name() {
1035        let general_name = GeneralName::Rfc822Name("Test name".into());
1036        let der = &[
1037            0x81, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x6e,
1038            0x61, 0x6d, 0x65];
1039
1040        test_encode_decode(&general_name, der);
1041    }
1042
1043    #[test]
1044    fn general_name_dns_name() {
1045        let general_name = GeneralName::DnsName("Test name".into());
1046        let der = &[
1047            0x82, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x6e,
1048            0x61, 0x6d, 0x65];
1049
1050        test_encode_decode(&general_name, der);
1051    }
1052
1053    #[test]
1054    fn general_name_directory_name() {
1055        let general_name = GeneralName::DirectoryName(
1056            Name {
1057                value: vec![
1058                    (oid::commonName.clone(),
1059                     TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test name".to_vec())),
1060                    (oid::description.clone(),
1061                     TaggedDerValue::from_tag_and_bytes(TAG_UTF8STRING, b"Test description".to_vec())),
1062                ]
1063            }
1064        );
1065
1066        let der = &[
1067            0xa4, 0x31, 0x30, 0x2f, 0x31, 0x12, 0x30, 0x10,
1068            0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x54,
1069            0x65, 0x73, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65,
1070            0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04,
1071            0x0d, 0x0c, 0x10, 0x54, 0x65, 0x73, 0x74, 0x20,
1072            0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
1073            0x69, 0x6f, 0x6e];
1074
1075        test_encode_decode(&general_name, der);
1076    }
1077
1078    #[test]
1079    fn general_name_uniform_resource_identifier() {
1080        let general_name = GeneralName::UniformResourceIdentifier("Test name".into());
1081        let der = &[
1082            0x86, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x6e,
1083            0x61, 0x6d, 0x65];
1084
1085        test_encode_decode(&general_name, der);
1086    }
1087
1088    #[test]
1089    fn general_name_ip_address() {
1090        let general_name = GeneralName::IpAddress(vec![127,0,0,1]);
1091        let der = &[0x87, 0x04, 0x7f, 0x00, 0x00, 0x01];
1092        test_encode_decode(&general_name, der);
1093    }
1094
1095    #[test]
1096    fn general_name_registered_id() {
1097        let general_name = GeneralName::RegisteredID(ObjectIdentifier::new(vec![1,2,3,4]));
1098        let der = &[0x88, 0x03, 0x2a, 0x03, 0x04];
1099        test_encode_decode(&general_name, der);
1100    }
1101
1102    #[test]
1103    fn general_names() {
1104        let general_names = GeneralNames(vec![
1105            GeneralName::IpAddress(vec![127,0,0,1]),
1106            GeneralName::RegisteredID(ObjectIdentifier::new(vec![1,2,3,4]))
1107        ]);
1108
1109        let der = &[
1110            0x30, 0x0b, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01,
1111            0x88, 0x03, 0x2a, 0x03, 0x04];
1112
1113        test_encode_decode(&general_names, der);
1114    }
1115
1116    #[test]
1117    fn attribute() {
1118        let attr = Attribute {
1119            oid: oid::extensionRequest.clone(),
1120            value: vec![
1121                b"\x04\x06Hello!".to_vec().into(),
1122                b"\x04\x06Hello!".to_vec().into(),
1123            ],
1124        };
1125
1126        let der = vec![0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e,
1127                       0x31, 0x10, 0x04, 0x06, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0x04, 0x06, 0x48,
1128                       0x65, 0x6c, 0x6c, 0x6f, 0x21];
1129
1130        test_encode_decode(&attr, &der);
1131    }
1132
1133    #[test]
1134    fn datetime() {
1135        let datetime = DateTime::new(2017, 5, 19, 12, 34, 56).unwrap();
1136
1137        let der = vec![0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x31, 0x39, 0x31, 0x32, 0x33, 0x34,
1138                       0x35, 0x36, 0x5a];
1139
1140        test_encode_decode(&datetime, &der);
1141    }
1142}