1use 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
18const 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
37impl 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
66impl 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#[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 DirectoryName(Name),
96 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 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 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#[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 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 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 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 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 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 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#[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 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
829 Ok(GeneralizedTime(DateTime::decode_ber(reader)?))
830 }
831}
832
833#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
838pub struct OctetString {
839 inner: Vec<u8>,
841}
842
843impl OctetString {
844 pub const MAX: u32 = MAX_U32;
846
847 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 pub fn as_bytes(&self) -> &[u8] {
859 self.inner.as_slice()
860 }
861
862 pub fn into_bytes(self) -> Vec<u8> {
864 self.inner
865 }
866
867 pub fn len(&self) -> usize {
869 self.inner.len()
870 }
871
872 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#[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 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}