1use bitflags::bitflags;
8use yasna::{ASN1Error, ASN1ErrorKind, ASN1Result, BERReader, DERWriter, BERDecodable, Tag, tags::*};
9use num_integer::Integer;
10use num_bigint::{BigUint, BigInt};
11use std::{borrow::Cow, convert::TryFrom};
12use bit_vec::BitVec;
13use oid;
14
15use DerWrite;
16use types::*;
17use deserialize::FromBer;
18
19use crate::{ToDer, oid::{certificatePolicies, ID_QT_CPS, ID_QT_UNOTICE, ANY_POLICY}};
20
21pub type RsaPkcs15TbsCertificate<'a> = TbsCertificate<BigUint, RsaPkcs15<Sha256>, DerSequence<'a>>;
22pub type RsaPkcs15Certificate<'a> = Certificate<RsaPkcs15TbsCertificate<'a>, RsaPkcs15<Sha256>, BitVec>;
23
24pub type GenericTbsCertificate = TbsCertificate<BigUint, DerSequence<'static>, DerSequence<'static>>;
25
26pub type GenericCertificate = Certificate<GenericTbsCertificate, DerSequence<'static>, BitVec>;
27
28#[derive(Clone, Debug, Eq, PartialEq, Hash)]
29pub struct Certificate<T, A: SignatureAlgorithm, S> {
30 pub tbscert: T,
31 pub sigalg: A,
32 pub sig: S,
33}
34
35impl<T: DerWrite, A: SignatureAlgorithm + DerWrite, S: DerWrite> DerWrite for Certificate<T, A, S> {
36 fn write(&self, writer: DERWriter) {
37 writer.write_sequence(|writer| {
38 self.tbscert.write(writer.next());
39 self.sigalg.write(writer.next());
40 self.sig.write(writer.next());
41 });
42 }
43}
44
45impl<T: BERDecodable, A: SignatureAlgorithm + BERDecodable, S: BERDecodable> BERDecodable for Certificate<T, A, S> {
46 fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
47 reader.read_sequence(|r| {
48 let tbscert = T::decode_ber(r.next())?;
49 let sigalg = A::decode_ber(r.next())?;
50 let sig = S::decode_ber(r.next())?;
51
52 Ok(Certificate { tbscert, sigalg, sig })
53 })
54 }
55}
56
57#[derive(Clone, Debug, Eq, PartialEq, Hash)]
58pub struct TbsCertificate<S: Integer, A: SignatureAlgorithm, K> {
59 pub version: u8,
60 pub serial: S,
61 pub sigalg: A,
62 pub issuer: Name,
63 pub validity_notbefore: DateTime,
64 pub validity_notafter: DateTime,
65 pub subject: Name,
66 pub spki: K,
67 pub extensions: Vec<Extension>,
68}
69
70impl<S: Integer, A: SignatureAlgorithm, K> TbsCertificate<S, A, K> {
71 pub fn get_extension(&self, oid: &ObjectIdentifier) -> Option<Extension> {
74 let mut iter = self.extensions.iter().filter(|e| e.oid == *oid);
75
76 match (iter.next(), iter.next()) {
77 (Some(ext), None) => Some(ext.to_owned()),
78 _ => None,
79 }
80 }
81}
82
83pub const TBS_CERTIFICATE_V1: u8 = 0;
84pub const TBS_CERTIFICATE_V2: u8 = 1;
85pub const TBS_CERTIFICATE_V3: u8 = 2;
86
87impl<S: DerWrite + Integer, A: DerWrite + SignatureAlgorithm, K: DerWrite> DerWrite
88 for TbsCertificate<S, A, K> {
89 fn write(&self, writer: DERWriter) {
90 writer.write_sequence(|writer| {
91 if self.version != TBS_CERTIFICATE_V1 { writer.next().write_tagged(Tag::context(0), |w| self.version.write(w));
93 }
94 self.serial.write(writer.next());
95 self.sigalg.write(writer.next());
96 self.issuer.write(writer.next());
97 writer.next().write_sequence(|writer| {
98 self.validity_notbefore.write(writer.next());
99 self.validity_notafter.write(writer.next());
100 });
101 self.subject.write(writer.next());
102 self.spki.write(writer.next());
103 if !self.extensions.is_empty() {
104 writer.next().write_tagged(Tag::context(3), |w| {
105 w.write_sequence(|writer| {
106 for ext in &self.extensions {
107 ext.write(writer.next())
108 }
109 })
110 });
111 }
112 });
113 }
114}
115
116impl<S: BERDecodable + Integer, A: BERDecodable + SignatureAlgorithm, K: BERDecodable> BERDecodable for TbsCertificate<S, A, K> {
117 fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self> {
118 reader.read_sequence(|r| {
119 let version = r.read_optional(|r| r.read_tagged(Tag::context(0), |r| r.read_u8()))?.unwrap_or(0);
120 match version {
121 TBS_CERTIFICATE_V1 | TBS_CERTIFICATE_V2 | TBS_CERTIFICATE_V3 => { }
122 _ => { return Err(ASN1Error::new(ASN1ErrorKind::Invalid)); }
123 };
124 let serial = S::decode_ber(r.next())?;
125 let sigalg = A::decode_ber(r.next())?;
126 let issuer = Name::decode_ber(r.next())?;
127 let (validity_notbefore,
128 validity_notafter) = r.next().read_sequence(|r| {
129 Ok((DateTime::decode_ber(r.next())?,
130 DateTime::decode_ber(r.next())?))
131 })?;
132 let subject = Name::decode_ber(r.next())?;
133 let spki = K::decode_ber(r.next())?;
134 let extensions = r.read_optional(|r| {
135 if version != TBS_CERTIFICATE_V3 {
136 return Err(ASN1Error::new(ASN1ErrorKind::Invalid));
137 }
138 r.read_tagged(Tag::context(3), |r| {
139 r.read_sequence(|r| {
140 let mut extensions = Vec::<Extension>::new();
141
142 loop {
143 let res = r.read_optional(|r| {
144 Extension::decode_ber(r)
145 });
146 match res {
147 Ok(Some(ext)) => extensions.push(ext),
148 Ok(None) => break,
149 Err(e) => return Err(e),
150 }
151 }
152
153 Ok(extensions)
154 })
155 })
156 })?.unwrap_or(vec![]);
157
158 Ok(TbsCertificate { version, serial, sigalg, issuer, validity_notbefore, validity_notafter,
159 subject, spki, extensions })
160 })
161 }
162}
163
164#[derive(Clone, Debug, Eq, PartialEq, Hash)]
178pub struct SubjectPublicKeyInfo<A: SignatureAlgorithm = DerSequence<'static>> {
179 pub algorithm: A,
181
182 pub subject_public_key: BitVec,
184}
185
186impl<A: SignatureAlgorithm + DerWrite> DerWrite for SubjectPublicKeyInfo<A> {
187 fn write(&self, writer: DERWriter) {
188 writer.write_sequence(|writer| {
189 self.algorithm.write(writer.next());
190 self.subject_public_key.write(writer.next());
191 });
192 }
193}
194
195impl<A: SignatureAlgorithm + BERDecodable> BERDecodable for SubjectPublicKeyInfo<A> {
196 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
197 reader.read_sequence(|reader| {
198 let algorithm = A::decode_ber(reader.next())?;
199 let subject_public_key = BitVec::decode_ber(reader.next())?;
200 Ok(SubjectPublicKeyInfo {
201 algorithm,
202 subject_public_key,
203 })
204 })
205 }
206}
207
208define_version! {
209 Version {
217 V1 = 0,
218 V2 = 1,
219 V3 = 2,
220 }
221}
222
223derive_sequence! {
224 AttributeTypeAndValue {
235 oid: ObjectIdentifier,
236 value: TaggedDerValue,
237 }
238}
239
240pub trait IsCritical {
243 fn is_critical(&self) -> bool;
244}
245
246pub trait ToExtension {
247 fn to_extension(&self) -> Extension;
248}
249
250impl<T: HasOid + IsCritical + ToDer> ToExtension for T {
251 fn to_extension(&self) -> Extension {
252 Extension {
253 oid: T::oid().clone(),
254 critical: self.is_critical(),
255 value: self.to_der(),
256 }
257 }
258}
259
260impl IsCritical for BasicConstraints {
261 fn is_critical(&self) -> bool {
262 true
263 }
264}
265
266#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
268pub struct BasicConstraints {
269 ca: bool,
270 path_len_constraint: Option<u64>,
271}
272
273impl BasicConstraints {
274 pub fn ca(path_len_constraint: Option<u64>) -> Self {
275 BasicConstraints { ca: true, path_len_constraint }
276 }
277
278 pub fn no_ca() -> Self {
279 BasicConstraints { ca: false, path_len_constraint: None }
280 }
281
282 pub fn is_ca(&self) -> bool {
284 self.ca
285 }
286
287 pub fn path_len_constraint(&self) -> Option<u64> {
292 self.path_len_constraint
293 }
294}
295
296impl HasOid for BasicConstraints {
297 fn oid() -> &'static ObjectIdentifier {
298 &oid::basicConstraints
299 }
300}
301
302impl DerWrite for BasicConstraints {
303 fn write(&self, writer: DERWriter) {
304 writer.write_sequence(|writer| {
305 if self.ca { writer.next().write_bool(true);
307 }
308 if let Some(path_len) = self.path_len_constraint {
309 writer.next().write_u64(path_len);
310 }
311 });
312 }
313}
314
315impl BERDecodable for BasicConstraints {
316 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
317 reader.read_sequence(|r| {
318 let ca = r.read_default(false, |r| r.read_bool())?;
319 let path_len_constraint = r.read_optional(|r| r.read_u64())?;
320 Ok(BasicConstraints { ca, path_len_constraint })
321 })
322 }
323}
324
325#[deprecated(since="0.1.3", note="use `SubjectAltName` instead")]
326#[derive(Clone, Debug, Eq, PartialEq, Hash)]
327pub struct DnsAltNames<'a> {
328 pub names: Vec<Cow<'a, str>>,
329}
330
331#[allow(deprecated)]
332impl<'a> DerWrite for DnsAltNames<'a> {
333 fn write(&self, writer: DERWriter) {
334 writer.write_sequence(|writer| {
335 for name in &self.names {
336 writer.next().write_tagged_implicit(Tag::context(2), |w|
337 name.as_bytes().write(w)
338 )
339 }
340 });
341 }
342}
343
344#[allow(deprecated)]
345impl<'a> BERDecodable for DnsAltNames<'a> {
346 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
347 reader.read_sequence(|seq_reader| {
348 let mut names = Vec::<Cow<'a, str>>::new();
349
350 loop {
351 let res = seq_reader.read_optional(|r| {
352 r.read_tagged_implicit(Tag::context(2), |r| {
353 String::from_utf8(r.read_bytes()?).map_err(|_| ASN1Error::new(ASN1ErrorKind::Invalid))
354 })
355 });
356 match res {
357 Ok(Some(s)) => names.push(Cow::Owned(s)),
358 Ok(None) => break,
359 Err(e) => return Err(e),
360 }
361 }
362
363 Ok(DnsAltNames { names })
364 })
365 }
366}
367
368#[derive(Clone, Debug, Eq, PartialEq, Hash)]
369pub struct SubjectAltName<'a> {
370 pub names: GeneralNames<'a>,
371}
372
373impl<'a> HasOid for SubjectAltName<'a> {
374 fn oid() -> &'static ObjectIdentifier {
375 &oid::subjectAltName
376 }
377}
378
379impl<'a> DerWrite for SubjectAltName<'a> {
380 fn write(&self, writer: DERWriter) {
381 self.names.write(writer)
382 }
383}
384
385impl<'a> BERDecodable for SubjectAltName<'a> {
386 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
387 Ok(SubjectAltName { names: GeneralNames::decode_ber(reader)? })
388 }
389}
390
391#[derive(Clone, Debug, Eq, PartialEq, Hash)]
392pub struct IssuerAltName<'a> {
393 pub names: GeneralNames<'a>,
394}
395
396impl<'a> HasOid for IssuerAltName<'a> {
397 fn oid() -> &'static ObjectIdentifier {
398 &oid::issuerAltName
399 }
400}
401
402impl<'a> DerWrite for IssuerAltName<'a> {
403 fn write(&self, writer: DERWriter) {
404 self.names.write(writer)
405 }
406}
407
408impl<'a> BERDecodable for IssuerAltName<'a> {
409 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
410 Ok(IssuerAltName { names: GeneralNames::decode_ber(reader)? })
411 }
412}
413
414
415const KEY_USAGE_MAX_NUM_BITS: usize = 9;
417
418bitflags! {
419 #[repr(transparent)]
420 pub struct KeyUsage: u16 {
421 const DIGITAL_SIGNATURE = 0x8000;
422 const NON_REPUDIATION = 0x4000;
423 const KEY_ENCIPHERMENT = 0x2000;
424 const DATA_ENCIPHERMENT = 0x1000;
425 const KEY_AGREEMENT = 0x0800;
426 const KEY_CERT_SIGN = 0x0400;
427 const CRL_SIGN = 0x0200;
428 const ENCIPHER_ONLY = 0x0100;
429 const DECIPHER_ONLY = 0x0080;
430 }
431}
432
433impl HasOid for KeyUsage {
434 fn oid() -> &'static ObjectIdentifier {
435 &oid::keyUsage
436 }
437}
438
439impl DerWrite for KeyUsage {
440 fn write(&self, writer: DERWriter) {
441 let bytes = self.bits().to_be_bytes();
442 let bit_vec = remove_trailing_zero(&BitVec::from_bytes(&bytes));
443 writer.write_bitvec(&bit_vec);
444 }
445}
446
447pub(crate) fn remove_trailing_zero(bit_vec: &BitVec) -> BitVec {
448 let mut ret = bit_vec.clone();
449 while ret.iter().last() == Some(false) {
450 ret.pop();
451 }
452 ret
453}
454
455impl BERDecodable for KeyUsage {
456 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
457 let mut bit_vec = reader.read_bitvec()?;
458 if bit_vec.len() > KEY_USAGE_MAX_NUM_BITS {
459 bit_vec.split_off(KEY_USAGE_MAX_NUM_BITS);
460 }
461 assert!(KEY_USAGE_MAX_NUM_BITS <= u16::BITS as usize);
462 let mut array = [0u8; 2];
463 let mut bit_bytes = bit_vec.to_bytes();
464 bit_bytes.resize(2, 0);
465 array.copy_from_slice(&bit_bytes[..2]);
466 let flags = u16::from_be_bytes(array);
467 Ok(KeyUsage::from_bits_truncate(flags))
468 }
469}
470
471impl IsCritical for KeyUsage {
472 fn is_critical(&self) -> bool {
473 true
474 }
475}
476
477
478derive_sequence_of!{
479 Attribute<'a> => SubjectDirectoryAttributes<'a>
487}
488
489impl HasOid for SubjectDirectoryAttributes<'_> {
490 fn oid() -> &'static ObjectIdentifier {
491 &oid::subjectDirectoryAttributes
492 }
493}
494
495impl IsCritical for SubjectDirectoryAttributes<'_> {
496 fn is_critical(&self) -> bool {
497 false
498 }
499}
500
501derive_sequence_of! {
502 PolicyInformation => CertificatePolicies
514}
515
516impl HasOid for CertificatePolicies {
517 fn oid() -> &'static ObjectIdentifier {
518 &certificatePolicies
519 }
520}
521
522impl CertificatePolicies {
523 pub fn to_extension(&self, is_critical: bool) -> Extension {
524 Extension {
525 oid: Self::oid().clone(),
526 critical: is_critical,
527 value: self.to_der(),
528 }
529 }
530}
531
532#[derive(Clone, Debug, Eq, PartialEq, Hash)]
545pub struct PolicyInformation {
546 pub policy_identifier: CertPolicyId,
547 pub policy_qualifiers: Option<Vec<PolicyQualifierInfo>>,
548}
549
550pub type CertPolicyId = ObjectIdentifier;
551
552impl BERDecodable for PolicyInformation {
553 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
554 reader.read_sequence(|policy_info_r| {
555 let policy_identifier = CertPolicyId::decode_ber(policy_info_r.next())?;
556 let policy_qualifiers = policy_info_r
557 .read_optional(|qualifiers_r| qualifiers_r.collect_sequence_of(PolicyQualifierInfo::decode_ber))?;
558 Ok(Self {
559 policy_identifier,
560 policy_qualifiers,
561 })
562 })
563 }
564}
565
566impl DerWrite for PolicyInformation {
567 fn write(&self, writer: DERWriter) {
568 writer.write_sequence(|policy_info_w| {
569 self.policy_identifier.write(policy_info_w.next());
570 if let Some(ref qualifiers) = self.policy_qualifiers {
571 policy_info_w.next().write_sequence_of(|qualifiers_w| {
572 for qual in qualifiers {
573 qual.write(qualifiers_w.next());
574 }
575 })
576 }
577 })
578 }
579}
580
581derive_sequence! {
582 PolicyQualifierInfo {
593 policyQualifierId: [_] UNTAGGED REQUIRED: ObjectIdentifier,
594 qualifier: [_] UNTAGGED OPTIONAL: Option<DerAnyOwned>,
595 }
596}
597
598impl From<InternetPolicyQualifier> for PolicyQualifierInfo {
599 fn from(value: InternetPolicyQualifier) -> Self {
600 let oid: &ObjectIdentifier = value.oid();
601 match value {
602 InternetPolicyQualifier::CpsUri(cps_uri) => Self {
603 policyQualifierId: oid.clone(),
604 qualifier: Some(cps_uri.to_der().into()),
605 },
606 InternetPolicyQualifier::UserNotice(user_notice) => Self {
607 policyQualifierId: oid.clone(),
608 qualifier: Some(user_notice.to_der().into()),
609 },
610 }
611 }
612}
613
614#[derive(Clone, Debug, PartialEq, Eq, Hash)]
631pub enum InternetPolicyQualifier {
632 CpsUri(CpsUri),
633 UserNotice(UserNotice),
634}
635
636impl BERDecodable for InternetPolicyQualifier {
637 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
638 match reader.lookahead_tag()? {
639 TAG_IA5STRING => Ok(Self::CpsUri(CpsUri::decode_ber(reader)?)),
640 TAG_SEQUENCE => Ok(Self::UserNotice(UserNotice::decode_ber(reader)?)),
641 _ => Err(ASN1Error::new(ASN1ErrorKind::Invalid)),
642 }
643 }
644}
645
646impl DerWrite for InternetPolicyQualifier {
647 fn write(&self, writer: DERWriter) {
648 match self {
649 InternetPolicyQualifier::CpsUri(cps_uri) => cps_uri.write(writer),
650 InternetPolicyQualifier::UserNotice(user_notice) => user_notice.write(writer),
651 }
652 }
653}
654
655impl InternetPolicyQualifier {
656 pub fn oid(&self) -> &'static ObjectIdentifier {
657 match self {
658 InternetPolicyQualifier::CpsUri(_) => &ID_QT_CPS,
659 InternetPolicyQualifier::UserNotice(_) => &ID_QT_UNOTICE,
660 }
661 }
662}
663
664impl TryFrom<PolicyQualifierInfo> for InternetPolicyQualifier {
665 type Error = ASN1Error;
666
667 fn try_from(value: PolicyQualifierInfo) -> Result<Self, Self::Error> {
668 if value.policyQualifierId == *ID_QT_CPS
669 || value.policyQualifierId == *ID_QT_UNOTICE
670 || value.policyQualifierId == *ANY_POLICY
671 {
672 Ok(Self::from_ber(&value.qualifier.ok_or(ASN1Error::new(ASN1ErrorKind::Eof))?)?)
673 } else {
674 Err(ASN1Error::new(ASN1ErrorKind::Invalid))
675 }
676 }
677}
678
679pub type CpsUri = Ia5String;
687
688derive_sequence! {
689 UserNotice {
700 notice_ref: [_] UNTAGGED OPTIONAL: Option<NoticeReference>,
701 explicit_text: [_] UNTAGGED OPTIONAL: Option<DisplayText>,
702 }
703}
704
705#[derive(Clone, Debug, PartialEq, Eq, Hash)]
715pub struct NoticeReference {
716 pub organization: DisplayText,
717 pub notice_numbers: Vec<BigInt>,
718}
719
720impl BERDecodable for NoticeReference {
721 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
722 reader.read_sequence(|notice_ref_r| {
723 let organization = DisplayText::decode_ber(notice_ref_r.next())?;
724 let notice_numbers = notice_ref_r.next().collect_sequence_of(BigInt::decode_ber)?;
725 Ok(Self {
726 organization,
727 notice_numbers,
728 })
729 })
730 }
731}
732
733impl DerWrite for NoticeReference {
734 fn write(&self, writer: DERWriter) {
735 writer.write_sequence(|notice_ref_w| {
736 self.organization.write(notice_ref_w.next());
737 notice_ref_w.next().write_sequence_of(|notice_num_w| {
738 for number in &self.notice_numbers {
739 number.write(notice_num_w.next());
740 }
741 })
742 })
743 }
744}
745
746#[derive(Clone, Debug, PartialEq, Eq, Hash)]
762pub enum DisplayText {
763 Ia5String(Ia5String),
764 VisibleString(String),
765 BmpString(String),
766 Utf8String(String),
767}
768
769impl BERDecodable for DisplayText {
770 fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
771 match reader.lookahead_tag()? {
772 TAG_IA5STRING => Ok(Self::Ia5String(Ia5String::decode_ber(reader)?)),
773 TAG_VISIBLESTRING => Ok(Self::VisibleString(reader.read_visible_string()?)),
774 TAG_BMPSTRING => Ok(Self::BmpString(reader.read_bmp_string()?)),
775 TAG_UTF8STRING => Ok(Self::Utf8String(reader.read_utf8string()?)),
776 _ => Err(ASN1Error::new(ASN1ErrorKind::Invalid)),
777 }
778 }
779}
780
781impl DerWrite for DisplayText {
782 fn write(&self, writer: DERWriter) {
783 match self {
784 DisplayText::Ia5String(s) => s.write(writer),
785 DisplayText::VisibleString(s) => writer.write_visible_string(s),
786 DisplayText::BmpString(s) => writer.write_bmp_string(s),
787 DisplayText::Utf8String(s) => writer.write_utf8_string(s),
788 }
789 }
790}
791
792derive_sequence_of! {
793 KeyPurposeId => ExtKeyUsageSyntax
807}
808
809pub type KeyPurposeId = ObjectIdentifier;
810
811impl HasOid for ExtKeyUsageSyntax {
812 fn oid() -> &'static ObjectIdentifier {
813 &oid::extKeyUsage
814 }
815}
816
817impl ExtKeyUsageSyntax {
818 pub fn to_extension(&self, is_critical: bool) -> Extension {
819 Extension {
820 oid: Self::oid().clone(),
821 critical: is_critical,
822 value: self.to_der(),
823 }
824 }
825}
826
827#[cfg(test)]
828mod tests {
829 use super::*;
830 use test::test_encode_decode;
831
832 #[test]
833 fn basic_constraints() {
834 let test_values = vec![
835 (BasicConstraints { ca: false, path_len_constraint: None }, vec![0x30, 0x00]),
836 (BasicConstraints { ca: true, path_len_constraint: None }, vec![0x30, 0x03, 0x01, 0x01, 0xFF]),
837 (BasicConstraints { ca: true, path_len_constraint: Some(4) }, vec![0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01, 0x04]),
838 (BasicConstraints { ca: false, path_len_constraint: Some(4) }, vec![0x30, 0x03, 0x02, 0x01, 0x04]),
840 ];
841
842 for (basic_constraint, der) in test_values {
843 test_encode_decode(&basic_constraint, &der);
844 }
845 }
846
847 #[test]
848 #[allow(deprecated)]
849 fn dns_alt_names() {
850 let names = DnsAltNames {
851 names: vec![
852 Cow::Borrowed("www.example.com"),
853 Cow::Borrowed("example.com"),
854 ]
855 };
856
857 let der = &[0x30, 0x1e, 0x82, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x65,
858 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
859 0x6d, 0x82, 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
860 0x65, 0x2e, 0x63, 0x6f, 0x6d];
861
862 test_encode_decode(&names, der);
863 }
864
865 #[test]
866 fn subject_issuer_alt_name() {
867 let subject_alt_name = SubjectAltName {
868 names: GeneralNames(vec![
869 GeneralName::IpAddress(vec![127,0,0,1]),
870 GeneralName::RegisteredID(ObjectIdentifier::new(vec![1,2,3,4]))
871 ]),
872 };
873 let issuer_alt_name = IssuerAltName {
874 names: GeneralNames(vec![
875 GeneralName::IpAddress(vec![127,0,0,1]),
876 GeneralName::RegisteredID(ObjectIdentifier::new(vec![1,2,3,4]))
877 ]),
878 };
879
880 let der = &[
881 0x30, 0x0b, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01,
882 0x88, 0x03, 0x2a, 0x03, 0x04];
883
884 test_encode_decode(&subject_alt_name, der);
885 test_encode_decode(&issuer_alt_name, der);
886 }
887
888 #[test]
889 fn parse_v1_cert() {
890 let der = include_bytes!("../tests/data/v1_cert.der");
891 let cert = yasna::parse_der(der, |r| GenericCertificate::decode_ber(r)).unwrap();
892 assert_eq!(cert.tbscert.version, TBS_CERTIFICATE_V1);
893 assert_eq!(yasna::construct_der(|w| cert.write(w)), der);
894 }
895
896 #[test]
897 fn parse_v3_cert() {
898 let der = include_bytes!("../tests/data/v3_cert.der");
899 let cert = yasna::parse_der(der, |r| GenericCertificate::decode_ber(r)).unwrap();
900 assert_eq!(cert.tbscert.version, TBS_CERTIFICATE_V3);
901 assert_eq!(yasna::construct_der(|w| cert.write(w)), der);
902 }
903}
904
905
906#[cfg(test)]
909mod certificate_extension_tests {
910 use std::convert::TryInto;
911
912 use crate::oid::{
913 attributeTypeRole, ANY_POLICY, ANY_EXTENDED_KEY_USAGE, ID_KP_CLIENT_AUTH, ID_KP_CODE_SIGNING, ID_KP_EMAIL_PROTECTION,
914 ID_KP_OCSP_SIGNING, ID_KP_SERVER_AUTH, ID_KP_TIME_STAMPING
915 };
916 use crate::rfc3281::Role;
917 use crate::yasna::tags::TAG_BITSTRING;
918 use crate::{FromDer, ToDer, FromBer};
919
920 use super::*;
921
922 use b64_ct::{ToBase64, STANDARD};
923
924 #[test]
927 fn key_usage_can_decode_encode_short() {
928 let der = [3, 2, 1, 6];
929 let ret = KeyUsage::from_der(&der).expect("can decode short");
930 assert_eq!(ret, (KeyUsage::KEY_CERT_SIGN | KeyUsage::CRL_SIGN), "KeyUsage not equal");
931 assert_eq!(&der[..], &ret.to_der(), "KeyUsage DER not equal");
932 }
933
934 #[test]
935 fn key_usage_bits() {
936 struct Test {
937 input: KeyUsage,
938 expected_bits: Vec<u8>,
939 }
940 let tests = vec![
941 Test {
942 input: KeyUsage::DIGITAL_SIGNATURE
943 | KeyUsage::DATA_ENCIPHERMENT
944 | KeyUsage::KEY_AGREEMENT
945 | KeyUsage::KEY_CERT_SIGN,
946 expected_bits: vec![
947 TAG_BITSTRING.tag_number as u8,
948 0x2, 0b00000010, 0b10011100, ],
952 },
953 Test {
954 input: KeyUsage::all(),
955 expected_bits: vec![
956 TAG_BITSTRING.tag_number as u8,
957 0x3, 0b00000111, 0b11111111,
960 0b10000000, ],
962 },
963 Test {
964 input: KeyUsage::DECIPHER_ONLY,
965 expected_bits: vec![
966 TAG_BITSTRING.tag_number as u8,
967 0x3, 0b00000111, 0b00000000,
970 0b10000000, ],
972 },
973 Test {
974 input: KeyUsage::CRL_SIGN | KeyUsage::ENCIPHER_ONLY,
975 expected_bits: vec![
976 TAG_BITSTRING.tag_number as u8,
977 0x2, 0b00000000, 0b00000011, ],
981 },
982 ];
983
984 for t in tests {
985 let der = t.input.to_der();
986 assert_eq!(
987 &der, &t.expected_bits,
988 "{:?}, {:02x?} != {:02x?}",
989 t.input, &der, &t.expected_bits
990 );
991 let echo = KeyUsage::from_der(&der).unwrap();
992 assert_eq!(echo, t.input);
993 }
994 }
995
996 const EXAMPLE_DER_WITH_ROLE: &[u8] = &[
997 0x30, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x48, 0x31, 0x0E, 0x30, 0x0C, 0xA1, 0x0A, 0x88, 0x08, 0x2A, 0x03, 0x04,
998 0x05, 0x06, 0x07, 0x08, 0x09,
999 ];
1000
1001 #[test]
1002 fn subject_directory_attributes_decode_encode_with_role() {
1003 let example_role_oid = ObjectIdentifier::from_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9]);
1004 let example_role = Role {
1005 role_authority: None,
1006 role_name: GeneralName::RegisteredID(example_role_oid),
1007 };
1008 let ret = SubjectDirectoryAttributes::from_der(EXAMPLE_DER_WITH_ROLE).expect("can decode");
1009 let attr = ret.0.first().expect("has one attribute");
1010 assert_eq!(&attr.oid, &*attributeTypeRole);
1011 assert_eq!(attr.value.first().unwrap().value, example_role.to_der());
1012 assert_eq!(ret.to_der(), EXAMPLE_DER_WITH_ROLE);
1013 }
1014
1015 #[test]
1016 fn subject_directory_attributes_construct() {
1017 let mut attributes = vec![];
1018 let utf8_string = String::from("a utf8 string");
1019 attributes.push(Attribute {
1020 oid: ObjectIdentifier::from_slice(&[1, 2, 840, 113549, 1, 1]),
1021 value: vec![DerSequence::from_der(
1022 &TaggedDerValue::from_tag_and_bytes(yasna::tags::TAG_UTF8STRING, utf8_string.clone().into_bytes())
1023 .to_der(),
1024 )
1025 .unwrap()],
1026 });
1027 let example = SubjectDirectoryAttributes(attributes);
1028 let der = example.to_der();
1029 let example_decode = SubjectDirectoryAttributes::from_der(&der).expect("from der");
1030 assert_eq!(example_decode, example);
1031 }
1032
1033 #[test]
1034 fn subject_directory_attributes_construct_with_role() {
1035 let mut attributes = vec![];
1036 let example_role_oid = ObjectIdentifier::from_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9]);
1037 let example_role = Role {
1038 role_authority: None,
1039 role_name: GeneralName::RegisteredID(example_role_oid),
1040 };
1041 attributes.push(Attribute {
1042 oid: attributeTypeRole.clone(),
1043 value: vec![DerSequence::from_der(&example_role.to_der()).unwrap()],
1044 });
1045 let example = SubjectDirectoryAttributes(attributes);
1046 let der = example.to_der();
1047 assert_eq!(der, EXAMPLE_DER_WITH_ROLE);
1048 println!("{}", der.to_base64(STANDARD));
1049 let example_decode = SubjectDirectoryAttributes::from_der(&der).expect("from der");
1050 assert_eq!(example_decode, example);
1051 }
1052
1053 #[test]
1057 fn encode_fortanix_policies_smoke_test() {
1058 for policy_identifier in [
1059 vec![1, 3, 6, 1, 4, 1, 49690, 6, 1, 3].into(),
1060 vec![1, 3, 6, 1, 4, 1, 49690, 6, 1, 2].into(),
1061 ] {
1062 let policies = CertificatePolicies(vec![PolicyInformation {
1063 policy_identifier,
1064 policy_qualifiers: None,
1065 }]);
1066 let der = policies.to_der();
1067 let decoded = CertificatePolicies::from_ber(&der).expect("DER should be valid");
1068 assert_eq!(policies, decoded);
1069 }
1070 }
1071
1072 #[test]
1075 fn encode_any_policy_smoke_test() {
1076 for internet_policy_qualifier in [
1077 InternetPolicyQualifier::CpsUri("https://example.com".to_string().into()), InternetPolicyQualifier::UserNotice(UserNotice {
1079 notice_ref: Some(NoticeReference {
1080 organization: DisplayText::Utf8String("Fake Corp".to_string()),
1081 notice_numbers: vec![BigInt::from(1)],
1082 }),
1083 explicit_text: Some(DisplayText::Utf8String("Fake policy".to_string())),
1084 }),
1085 ] {
1086 let policy = PolicyInformation {
1087 policy_identifier: ANY_POLICY.clone(),
1088 policy_qualifiers: Some(vec![internet_policy_qualifier.clone().into()]),
1089 };
1090 let der = policy.to_der();
1091 let decoded = PolicyInformation::from_ber(&der).expect("DER should be valid");
1092 assert_eq!(policy, decoded);
1093 let decoded_internet_policy_qualifier: InternetPolicyQualifier = decoded
1094 .policy_qualifiers
1095 .unwrap()
1096 .first()
1097 .unwrap()
1098 .to_owned()
1099 .try_into()
1100 .unwrap();
1101 assert_eq!(internet_policy_qualifier, decoded_internet_policy_qualifier);
1102 }
1103 }
1104
1105 #[test]
1106 fn encode_internet_policy_qualifiers_smoke_test() {
1107 for internet_policy_qualifier in [
1108 InternetPolicyQualifier::CpsUri("https://example.com".to_string().into()), InternetPolicyQualifier::UserNotice(UserNotice {
1110 notice_ref: Some(NoticeReference {
1111 organization: DisplayText::Utf8String("Fake Corp".to_string()),
1112 notice_numbers: vec![BigInt::from(1)],
1113 }),
1114 explicit_text: Some(DisplayText::Utf8String("Fake policy".to_string())),
1115 }),
1116 ] {
1117 let policy = PolicyInformation {
1118 policy_identifier: internet_policy_qualifier.oid().clone(),
1119 policy_qualifiers: Some(vec![internet_policy_qualifier.clone().into()]),
1120 };
1121 let der = policy.to_der();
1122 let decoded = PolicyInformation::from_ber(&der).expect("DER should be valid");
1123 assert_eq!(policy, decoded);
1124 let decoded_internet_policy_qualifier: InternetPolicyQualifier = decoded
1125 .policy_qualifiers
1126 .unwrap()
1127 .first()
1128 .unwrap()
1129 .to_owned()
1130 .try_into()
1131 .unwrap();
1132 assert_eq!(internet_policy_qualifier, decoded_internet_policy_qualifier);
1133 }
1134 }
1135
1136 static EXAMPLE_CLUSTER_NODE_ENROLLMENT_POLICY_EXT: &[u8] = &[
1146 0x30, 0x18, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x11, 0x30, 0x0F, 0x30, 0x0D, 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01,
1147 0x83, 0x84, 0x1A, 0x06, 0x01, 0x02,
1148 ];
1149
1150 #[test]
1151 fn decode_fortanix_policies_ext_test() {
1152 let ext = Extension::from_ber(EXAMPLE_CLUSTER_NODE_ENROLLMENT_POLICY_EXT).unwrap();
1153 let policies = CertificatePolicies::from_ber(&ext.value).expect("extension value should be valid");
1154 let expected_polices = CertificatePolicies(vec![PolicyInformation {
1155 policy_identifier: vec![1, 3, 6, 1, 4, 1, 49690, 6, 1, 2].into(),
1156 policy_qualifiers: None,
1157 }]);
1158 assert_eq!(expected_polices, policies);
1159 assert_eq!(ext, expected_polices.to_extension(false));
1160 }
1161
1162 #[test]
1165 fn extended_key_usage_encode_decode_round_trip_smoke_test() {
1166 for eku_purposes in [
1167 vec![ANY_EXTENDED_KEY_USAGE.clone()],
1168 vec![ID_KP_CLIENT_AUTH.clone(), ID_KP_SERVER_AUTH.clone()],
1169 vec![ID_KP_CODE_SIGNING.clone()],
1170 vec![ID_KP_EMAIL_PROTECTION.clone()],
1171 vec![ID_KP_OCSP_SIGNING.clone(), ID_KP_TIME_STAMPING.clone()],
1172 vec![vec![1, 3, 6, 1, 4, 1, 49690, 8, 1].into()]
1175 ] {
1176 let eku = ExtKeyUsageSyntax(eku_purposes);
1177 let eku_der = eku.to_der();
1178 let decoded_eku = ExtKeyUsageSyntax::from_ber(&eku_der).expect("DER-encoded EKU extension should be valid");
1179 assert_eq!(decoded_eku, eku);
1180 }
1181 }
1182}