1use {
8 crate::{
9 InMemorySigningKeyPair, KeyAlgorithm, KeyInfoSigner, SignatureAlgorithm,
10 X509CertificateError as Error, algorithm::DigestAlgorithm, asn1time::Time, rfc2986,
11 rfc3280::Name, rfc5280, rfc5652, rfc5958::Attributes, rfc8017::RsaPublicKey, signing::Sign,
12 },
13 aws_lc_rs::signature as ringsig,
14 bcder::{
15 ConstOid, Mode, Oid,
16 decode::Constructed,
17 encode::Values,
18 int::Integer,
19 string::{BitString, OctetString},
20 },
21 bytes::Bytes,
22 chrono::{DateTime, Duration, Utc},
23 der::{Decode, Document},
24 signature::Signer,
25 spki::EncodePublicKey,
26 std::{
27 cmp::Ordering,
28 collections::HashSet,
29 fmt::{Debug, Formatter},
30 hash::{Hash, Hasher},
31 io::Write,
32 ops::{Deref, DerefMut},
33 },
34};
35
36const OID_EXTENSION_KEY_USAGE: ConstOid = Oid(&[85, 29, 15]);
40
41const OID_EXTENSION_BASIC_CONSTRAINTS: ConstOid = Oid(&[85, 29, 19]);
45
46#[derive(Clone, Debug, Eq, PartialEq)]
66pub struct X509Certificate(rfc5280::Certificate);
67
68impl X509Certificate {
69 pub fn from_der(data: impl AsRef<[u8]>) -> Result<Self, Error> {
71 let cert = Constructed::decode(data.as_ref(), Mode::Der, |cons| {
72 rfc5280::Certificate::take_from(cons)
73 })?;
74
75 Ok(Self(cert))
76 }
77
78 pub fn from_ber(data: impl AsRef<[u8]>) -> Result<Self, Error> {
84 let cert = Constructed::decode(data.as_ref(), Mode::Ber, |cons| {
85 rfc5280::Certificate::take_from(cons)
86 })?;
87
88 Ok(Self(cert))
89 }
90
91 pub fn from_pem(data: impl AsRef<[u8]>) -> Result<Self, Error> {
96 let data = pem::parse(data.as_ref()).map_err(Error::PemDecode)?;
97
98 Self::from_der(data.contents())
99 }
100
101 pub fn from_pem_multiple(data: impl AsRef<[u8]>) -> Result<Vec<Self>, Error> {
108 Self::from_pem_multiple_tags(data, &["CERTIFICATE"])
109 }
110
111 pub fn from_pem_multiple_tags(
116 data: impl AsRef<[u8]>,
117 tags: &[&str],
118 ) -> Result<Vec<Self>, Error> {
119 let pem = pem::parse_many(data.as_ref()).map_err(Error::PemDecode)?;
120
121 pem.into_iter()
122 .filter(|pem| tags.contains(&pem.tag()))
123 .map(|pem| Self::from_der(pem.contents()))
124 .collect::<Result<_, _>>()
125 }
126
127 pub fn serial_number_asn1(&self) -> &Integer {
129 &self.0.tbs_certificate.serial_number
130 }
131
132 pub fn subject_name(&self) -> &Name {
134 &self.0.tbs_certificate.subject
135 }
136
137 pub fn subject_common_name(&self) -> Option<String> {
139 self.0
140 .tbs_certificate
141 .subject
142 .iter_common_name()
143 .next()
144 .and_then(|cn| cn.to_string().ok())
145 }
146
147 pub fn issuer_name(&self) -> &Name {
149 &self.0.tbs_certificate.issuer
150 }
151
152 pub fn issuer_common_name(&self) -> Option<String> {
154 self.0
155 .tbs_certificate
156 .issuer
157 .iter_common_name()
158 .next()
159 .and_then(|cn| cn.to_string().ok())
160 }
161
162 pub fn iter_extensions(&self) -> impl Iterator<Item = &crate::rfc5280::Extension> {
164 self.0.iter_extensions()
165 }
166
167 pub fn encode_der_to(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
175 self.0.encode_ref().write_encoded(Mode::Der, fh)
176 }
177
178 pub fn encode_ber_to(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
180 self.0.encode_ref().write_encoded(Mode::Ber, fh)
181 }
182
183 pub fn encode_der(&self) -> Result<Vec<u8>, std::io::Error> {
185 let mut buffer = Vec::<u8>::new();
186 self.encode_der_to(&mut buffer)?;
187
188 Ok(buffer)
189 }
190
191 pub fn encode_ber(&self) -> Result<Vec<u8>, std::io::Error> {
193 let mut buffer = Vec::<u8>::new();
194 self.encode_ber_to(&mut buffer)?;
195
196 Ok(buffer)
197 }
198
199 pub fn write_pem(&self, fh: &mut impl Write) -> Result<(), std::io::Error> {
206 let encoded = pem::Pem::new("CERTIFICATE", self.encode_der()?).to_string();
207
208 fh.write_all(encoded.as_bytes())
209 }
210
211 pub fn encode_pem(&self) -> Result<String, std::io::Error> {
213 Ok(pem::Pem::new("CERTIFICATE", self.encode_der()?).to_string())
214 }
215
216 pub fn key_algorithm(&self) -> Option<KeyAlgorithm> {
221 KeyAlgorithm::try_from(&self.0.tbs_certificate.subject_public_key_info.algorithm).ok()
222 }
223
224 pub fn key_algorithm_oid(&self) -> &Oid {
226 &self
227 .0
228 .tbs_certificate
229 .subject_public_key_info
230 .algorithm
231 .algorithm
232 }
233
234 pub fn signature_algorithm(&self) -> Option<SignatureAlgorithm> {
239 SignatureAlgorithm::try_from(&self.0.tbs_certificate.signature.algorithm).ok()
240 }
241
242 pub fn signature_algorithm_oid(&self) -> &Oid {
244 &self.0.tbs_certificate.signature.algorithm
245 }
246
247 pub fn signature_signature_algorithm(&self) -> Option<SignatureAlgorithm> {
252 SignatureAlgorithm::try_from(&self.0.signature_algorithm).ok()
253 }
254
255 pub fn signature_signature_algorithm_oid(&self) -> &Oid {
257 &self.0.signature_algorithm.algorithm
258 }
259
260 pub fn public_key_data(&self) -> Bytes {
264 self.0
265 .tbs_certificate
266 .subject_public_key_info
267 .subject_public_key
268 .octet_bytes()
269 }
270
271 pub fn rsa_public_key_data(&self) -> Result<RsaPublicKey, Error> {
277 let der = self.public_key_data();
278
279 Ok(Constructed::decode(
280 der.as_ref(),
281 Mode::Der,
282 RsaPublicKey::take_from,
283 )?)
284 }
285
286 pub fn compare_issuer(&self, other: &Self) -> Ordering {
298 if self.0.tbs_certificate.subject == self.0.tbs_certificate.issuer {
300 Ordering::Equal
301 } else if self.0.tbs_certificate.issuer == other.0.tbs_certificate.subject {
303 Ordering::Greater
304 } else if self.0.tbs_certificate.subject == other.0.tbs_certificate.issuer {
305 Ordering::Less
307 } else {
308 Ordering::Equal
309 }
310 }
311
312 pub fn subject_is_issuer(&self) -> bool {
319 self.0.tbs_certificate.subject == self.0.tbs_certificate.issuer
320 }
321
322 pub fn fingerprint(
324 &self,
325 algorithm: DigestAlgorithm,
326 ) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
327 let raw = self.encode_der()?;
328
329 let mut h = algorithm.digester();
330 h.update(&raw);
331
332 Ok(h.finish())
333 }
334
335 pub fn sha1_fingerprint(&self) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
337 self.fingerprint(DigestAlgorithm::Sha1)
338 }
339
340 pub fn sha256_fingerprint(&self) -> Result<aws_lc_rs::digest::Digest, std::io::Error> {
342 self.fingerprint(DigestAlgorithm::Sha256)
343 }
344
345 pub fn tbs_certificate(&self) -> &rfc5280::TbsCertificate {
347 &self.0.tbs_certificate
348 }
349
350 pub fn validity_not_before(&self) -> DateTime<Utc> {
352 self.0.tbs_certificate.validity.not_before.clone().into()
353 }
354
355 pub fn validity_not_after(&self) -> DateTime<Utc> {
357 self.0.tbs_certificate.validity.not_after.clone().into()
358 }
359
360 pub fn time_constraints_valid(&self, compare_time: Option<DateTime<Utc>>) -> bool {
369 let compare_time = compare_time.unwrap_or(Utc::now());
370
371 compare_time >= self.validity_not_before() && compare_time <= self.validity_not_after()
372 }
373}
374
375impl From<rfc5280::Certificate> for X509Certificate {
376 fn from(v: rfc5280::Certificate) -> Self {
377 Self(v)
378 }
379}
380
381impl From<X509Certificate> for rfc5280::Certificate {
382 fn from(v: X509Certificate) -> Self {
383 v.0
384 }
385}
386
387impl AsRef<rfc5280::Certificate> for X509Certificate {
388 fn as_ref(&self) -> &rfc5280::Certificate {
389 &self.0
390 }
391}
392
393impl AsMut<rfc5280::Certificate> for X509Certificate {
394 fn as_mut(&mut self) -> &mut rfc5280::Certificate {
395 &mut self.0
396 }
397}
398
399impl EncodePublicKey for X509Certificate {
400 fn to_public_key_der(&self) -> spki::Result<Document> {
401 let mut data = vec![];
402
403 self.0
404 .tbs_certificate
405 .subject_public_key_info
406 .encode_ref()
407 .write_encoded(Mode::Der, &mut data)
408 .map_err(|_| spki::Error::Asn1(der::Error::new(der::ErrorKind::Failed, 0u8.into())))?;
409
410 Document::from_der(&data).map_err(spki::Error::Asn1)
411 }
412}
413
414#[derive(Clone, Eq, PartialEq)]
415enum OriginalData {
416 Ber(Vec<u8>),
417 Der(Vec<u8>),
418}
419
420impl Debug for OriginalData {
421 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
422 f.write_fmt(format_args!(
423 "{}({})",
424 match self {
425 Self::Ber(_) => "Ber",
426 Self::Der(_) => "Der",
427 },
428 match self {
429 Self::Ber(data) => hex::encode(data),
430 Self::Der(data) => hex::encode(data),
431 }
432 ))
433 }
434}
435
436#[derive(Clone, Debug)]
444pub struct CapturedX509Certificate {
445 original: OriginalData,
446 inner: X509Certificate,
447}
448
449impl CapturedX509Certificate {
450 pub fn from_der(data: impl Into<Vec<u8>>) -> Result<Self, Error> {
456 let der_data = data.into();
457
458 let inner = X509Certificate::from_der(&der_data)?;
459
460 Ok(Self {
461 original: OriginalData::Der(der_data),
462 inner,
463 })
464 }
465
466 pub fn from_ber(data: impl Into<Vec<u8>>) -> Result<Self, Error> {
472 let data = data.into();
473
474 let inner = X509Certificate::from_ber(&data)?;
475
476 Ok(Self {
477 original: OriginalData::Ber(data),
478 inner,
479 })
480 }
481
482 pub fn from_pem(data: impl AsRef<[u8]>) -> Result<Self, Error> {
487 let data = pem::parse(data.as_ref()).map_err(Error::PemDecode)?;
488
489 Self::from_der(data.contents())
490 }
491
492 pub fn from_pem_multiple(data: impl AsRef<[u8]>) -> Result<Vec<Self>, Error> {
499 Self::from_pem_multiple_tags(data, &["CERTIFICATE"])
500 }
501
502 pub fn from_pem_multiple_tags(
507 data: impl AsRef<[u8]>,
508 tags: &[&str],
509 ) -> Result<Vec<Self>, Error> {
510 let pem = pem::parse_many(data.as_ref()).map_err(Error::PemDecode)?;
511
512 pem.into_iter()
513 .filter(|pem| tags.contains(&pem.tag()))
514 .map(|pem| Self::from_der(pem.contents()))
515 .collect::<Result<_, _>>()
516 }
517
518 pub fn constructed_data(&self) -> &[u8] {
523 match &self.original {
524 OriginalData::Ber(data) => data,
525 OriginalData::Der(data) => data,
526 }
527 }
528
529 pub fn encode_pem(&self) -> String {
531 pem::Pem::new("CERTIFICATE", self.constructed_data()).to_string()
532 }
533
534 pub fn verify_signed_by_certificate(
544 &self,
545 other: impl AsRef<X509Certificate>,
546 ) -> Result<(), Error> {
547 let public_key = other
548 .as_ref()
549 .0
550 .tbs_certificate
551 .subject_public_key_info
552 .subject_public_key
553 .octet_bytes();
554 let key_algorithm = KeyAlgorithm::try_from(
555 &other
556 .as_ref()
557 .0
558 .tbs_certificate
559 .subject_public_key_info
560 .algorithm,
561 )?;
562 self.verify_signed_by_public_key_and_algorithm(public_key, key_algorithm)
563 }
564
565 pub fn verify_signed_data(
573 &self,
574 signed_data: impl AsRef<[u8]>,
575 signature: impl AsRef<[u8]>,
576 ) -> Result<(), Error> {
577 let key_algorithm = KeyAlgorithm::try_from(self.key_algorithm_oid())?;
578 let signature_algorithm = SignatureAlgorithm::try_from(self.signature_algorithm_oid())?;
579 let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
580
581 self.verify_signed_data_with_algorithm(signed_data, signature, verify_algorithm)
582 }
583
584 pub fn verify_signed_data_with_algorithm(
590 &self,
591 signed_data: impl AsRef<[u8]>,
592 signature: impl AsRef<[u8]>,
593 verify_algorithm: &'static dyn ringsig::VerificationAlgorithm,
594 ) -> Result<(), Error> {
595 let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, self.public_key_data());
596
597 public_key
598 .verify(signed_data.as_ref(), signature.as_ref())
599 .map_err(|_| Error::CertificateSignatureVerificationFailed)
600 }
601
602 pub fn verify_signed_by_public_key(
613 &self,
614 public_key_data: impl AsRef<[u8]>,
615 ) -> Result<(), Error> {
616 let key_algorithm =
617 KeyAlgorithm::try_from(&self.0.tbs_certificate.subject_public_key_info.algorithm)?;
618 self.verify_signed_by_public_key_and_algorithm(public_key_data, key_algorithm)
619 }
620
621 pub fn verify_signed_by_public_key_and_algorithm(
626 &self,
627 public_key_data: impl AsRef<[u8]>,
628 public_key_algorithm: KeyAlgorithm,
629 ) -> Result<(), Error> {
630 let this_cert = match &self.original {
634 OriginalData::Ber(data) => X509Certificate::from_ber(data),
635 OriginalData::Der(data) => X509Certificate::from_der(data),
636 }
637 .expect("certificate re-parse should never fail");
638
639 let signed_data = this_cert
640 .0
641 .tbs_certificate
642 .raw_data
643 .as_ref()
644 .expect("original certificate data should have persisted as part of re-parse");
645 let signature = this_cert.0.signature.octet_bytes();
646
647 let signature_algorithm = SignatureAlgorithm::try_from(&this_cert.0.signature_algorithm)?;
648
649 let verify_algorithm =
650 signature_algorithm.resolve_verification_algorithm(public_key_algorithm)?;
651
652 let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, public_key_data);
653
654 public_key
655 .verify(signed_data, &signature)
656 .map_err(|_| Error::CertificateSignatureVerificationFailed)
657 }
658
659 pub fn find_signing_certificate<'a>(
668 &self,
669 mut certs: impl Iterator<Item = &'a Self>,
670 ) -> Option<&'a Self> {
671 certs.find(|candidate| self.verify_signed_by_certificate(candidate).is_ok())
672 }
673
674 pub fn resolve_signing_chain<'a>(
694 &self,
695 certs: impl Iterator<Item = &'a Self>,
696 ) -> Vec<&'a Self> {
697 #[allow(clippy::mutable_key_type)]
701 let mut seen = HashSet::new();
702 let mut remaining = vec![];
703
704 for cert in certs {
705 if cert == self || seen.contains(cert) {
706 continue;
707 } else {
708 remaining.push(cert);
709 seen.insert(cert);
710 }
711 }
712
713 drop(seen);
714
715 let mut chain = vec![];
716
717 let mut last_cert = self;
718 while let Some(issuer) = last_cert.find_signing_certificate(remaining.iter().copied()) {
719 chain.push(issuer);
720 last_cert = issuer;
721
722 remaining = remaining
723 .drain(..)
724 .filter(|cert| *cert != issuer)
725 .collect::<Vec<_>>();
726 }
727
728 chain
729 }
730}
731
732impl PartialEq for CapturedX509Certificate {
733 fn eq(&self, other: &Self) -> bool {
734 self.constructed_data() == other.constructed_data()
735 }
736}
737
738impl Eq for CapturedX509Certificate {}
739
740impl Hash for CapturedX509Certificate {
741 fn hash<H: Hasher>(&self, state: &mut H) {
742 state.write(self.constructed_data());
743 }
744}
745
746impl Deref for CapturedX509Certificate {
747 type Target = X509Certificate;
748
749 fn deref(&self) -> &Self::Target {
750 &self.inner
751 }
752}
753
754impl AsRef<X509Certificate> for CapturedX509Certificate {
755 fn as_ref(&self) -> &X509Certificate {
756 &self.inner
757 }
758}
759
760impl AsRef<rfc5280::Certificate> for CapturedX509Certificate {
761 fn as_ref(&self) -> &rfc5280::Certificate {
762 self.inner.as_ref()
763 }
764}
765
766impl TryFrom<&X509Certificate> for CapturedX509Certificate {
767 type Error = Error;
768
769 fn try_from(cert: &X509Certificate) -> Result<Self, Self::Error> {
770 let mut buffer = Vec::<u8>::new();
771 cert.encode_der_to(&mut buffer)?;
772
773 Self::from_der(buffer)
774 }
775}
776
777impl TryFrom<X509Certificate> for CapturedX509Certificate {
778 type Error = Error;
779
780 fn try_from(cert: X509Certificate) -> Result<Self, Self::Error> {
781 let mut buffer = Vec::<u8>::new();
782 cert.encode_der_to(&mut buffer)?;
783
784 Self::from_der(buffer)
785 }
786}
787
788impl From<CapturedX509Certificate> for rfc5280::Certificate {
789 fn from(cert: CapturedX509Certificate) -> Self {
790 cert.inner.0
791 }
792}
793
794#[derive(Clone, Debug, Eq, PartialEq)]
802pub struct MutableX509Certificate(CapturedX509Certificate);
803
804impl Deref for MutableX509Certificate {
805 type Target = X509Certificate;
806
807 fn deref(&self) -> &Self::Target {
808 &self.0.inner
809 }
810}
811
812impl DerefMut for MutableX509Certificate {
813 fn deref_mut(&mut self) -> &mut Self::Target {
814 &mut self.0.inner
815 }
816}
817
818impl From<CapturedX509Certificate> for MutableX509Certificate {
819 fn from(cert: CapturedX509Certificate) -> Self {
820 Self(cert)
821 }
822}
823
824pub fn certificate_is_subset_of(
829 a_serial: &Integer,
830 a_name: &Name,
831 b_serial: &Integer,
832 b_name: &Name,
833) -> bool {
834 if a_serial != b_serial {
835 return false;
836 }
837
838 let Name::RdnSequence(a_sequence) = &a_name;
839 let Name::RdnSequence(b_sequence) = &b_name;
840
841 a_sequence.iter().all(|rdn| b_sequence.contains(rdn))
842}
843
844pub enum KeyUsage {
858 DigitalSignature,
859 NonRepudiation,
860 KeyEncipherment,
861 DataEncipherment,
862 KeyAgreement,
863 KeyCertSign,
864 CrlSign,
865}
866
867impl From<KeyUsage> for u8 {
868 fn from(ku: KeyUsage) -> Self {
869 match ku {
870 KeyUsage::DigitalSignature => 0,
871 KeyUsage::NonRepudiation => 1,
872 KeyUsage::KeyEncipherment => 2,
873 KeyUsage::DataEncipherment => 3,
874 KeyUsage::KeyAgreement => 4,
875 KeyUsage::KeyCertSign => 5,
876 KeyUsage::CrlSign => 6,
877 }
878 }
879}
880
881pub struct X509CertificateBuilder {
897 subject: Name,
898 issuer: Option<Name>,
899 extensions: rfc5280::Extensions,
900 serial_number: i64,
901 not_before: chrono::DateTime<Utc>,
902 not_after: chrono::DateTime<Utc>,
903 csr_attributes: Attributes,
904}
905
906impl Default for X509CertificateBuilder {
907 fn default() -> Self {
908 let not_before = Utc::now();
909 let not_after = not_before + Duration::hours(1);
910
911 Self {
912 subject: Name::default(),
913 issuer: None,
914 extensions: rfc5280::Extensions::default(),
915 serial_number: 1,
916 not_before,
917 not_after,
918 csr_attributes: Attributes::default(),
919 }
920 }
921}
922
923impl X509CertificateBuilder {
924 #[deprecated]
926 pub fn new() -> Self {
927 Self::default()
928 }
929
930 pub fn subject(&mut self) -> &mut Name {
934 &mut self.subject
935 }
936
937 pub fn issuer(&mut self) -> &mut Name {
941 self.issuer.get_or_insert_with(Name::default)
942 }
943
944 pub fn serial_number(&mut self, value: i64) {
946 self.serial_number = value;
947 }
948
949 pub fn extensions(&self) -> &rfc5280::Extensions {
951 &self.extensions
952 }
953
954 pub fn extensions_mut(&mut self) -> &mut rfc5280::Extensions {
956 &mut self.extensions
957 }
958
959 pub fn add_extension_der_data(&mut self, oid: Oid, critical: bool, data: impl AsRef<[u8]>) {
961 self.extensions.push(rfc5280::Extension {
962 id: oid,
963 critical: Some(critical),
964 value: OctetString::new(Bytes::copy_from_slice(data.as_ref())),
965 });
966 }
967
968 pub fn validity_duration(&mut self, duration: Duration) {
970 self.not_after = self.not_before + duration;
971 }
972
973 pub fn constraint_not_ca(&mut self) {
975 self.extensions.push(rfc5280::Extension {
976 id: Oid(OID_EXTENSION_BASIC_CONSTRAINTS.as_ref().into()),
977 critical: Some(true),
978 value: OctetString::new(Bytes::copy_from_slice(&[0x30, 00])),
979 });
980 }
981
982 pub fn key_usage(&mut self, key_usage: KeyUsage) {
984 let value: u8 = key_usage.into();
985
986 self.extensions.push(rfc5280::Extension {
987 id: Oid(OID_EXTENSION_KEY_USAGE.as_ref().into()),
988 critical: Some(true),
989 value: OctetString::new(Bytes::copy_from_slice(&[3, 2, 7, 128 | value])),
991 });
992 }
993
994 pub fn add_csr_attribute(&mut self, attribute: rfc5652::Attribute) {
999 self.csr_attributes.push(attribute);
1000 }
1001
1002 pub fn create_with_key_pair(
1004 &self,
1005 key_pair: &InMemorySigningKeyPair,
1006 ) -> Result<CapturedX509Certificate, Error> {
1007 let key_pair_signature_algorithm = key_pair.signature_algorithm();
1008
1009 let issuer = if let Some(issuer) = &self.issuer {
1010 issuer
1011 } else {
1012 &self.subject
1013 };
1014
1015 let tbs_certificate = rfc5280::TbsCertificate {
1016 version: Some(rfc5280::Version::V3),
1017 serial_number: self.serial_number.into(),
1018 signature: key_pair_signature_algorithm?.into(),
1019 issuer: issuer.clone(),
1020 validity: rfc5280::Validity {
1021 not_before: Time::from(self.not_before),
1022 not_after: Time::from(self.not_after),
1023 },
1024 subject: self.subject.clone(),
1025 subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1026 algorithm: key_pair
1027 .key_algorithm()
1028 .expect("InMemorySigningKeyPair always has known key algorithm")
1029 .into(),
1030 subject_public_key: BitString::new(0, key_pair.public_key_data()),
1031 },
1032 issuer_unique_id: None,
1033 subject_unique_id: None,
1034 extensions: if self.extensions.is_empty() {
1035 None
1036 } else {
1037 Some(self.extensions.clone())
1038 },
1039 raw_data: None,
1040 };
1041
1042 let mut tbs_der = Vec::<u8>::new();
1045 tbs_certificate
1046 .encode_ref()
1047 .write_encoded(Mode::Der, &mut tbs_der)?;
1048
1049 let signature = key_pair.try_sign(&tbs_der)?;
1050 let signature_algorithm = key_pair.signature_algorithm()?;
1051
1052 let cert = rfc5280::Certificate {
1053 tbs_certificate,
1054 signature_algorithm: signature_algorithm.into(),
1055 signature: BitString::new(0, Bytes::copy_from_slice(signature.as_ref())),
1056 };
1057
1058 let cert = X509Certificate::from(cert);
1059 let cert_der = cert.encode_der()?;
1060
1061 CapturedX509Certificate::from_der(cert_der)
1062 }
1063
1064 pub fn create_with_random_keypair(
1066 &self,
1067 key_algorithm: KeyAlgorithm,
1068 ) -> Result<(CapturedX509Certificate, InMemorySigningKeyPair), Error> {
1069 let key_pair = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1070 let cert = self.create_with_key_pair(&key_pair)?;
1071
1072 Ok((cert, key_pair))
1073 }
1074
1075 pub fn create_certificate_signing_request(
1082 &self,
1083 signer: &dyn KeyInfoSigner,
1084 ) -> Result<rfc2986::CertificationRequest, Error> {
1085 let info = rfc2986::CertificationRequestInfo {
1086 version: rfc2986::Version::V1,
1087 subject: self.subject.clone(),
1088 subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1089 algorithm: signer
1090 .key_algorithm()
1091 .ok_or_else(|| {
1092 Error::UnknownKeyAlgorithm(
1093 "OID not available due to API limitations".into(),
1094 )
1095 })?
1096 .into(),
1097 subject_public_key: BitString::new(0, signer.public_key_data()),
1098 },
1099 attributes: self.csr_attributes.clone(),
1100 };
1101
1102 let mut info_der = vec![];
1105 info.write_encoded(Mode::Der, &mut info_der)?;
1106
1107 let signature = signer.try_sign(&info_der)?;
1108 let signature_algorithm = signer.signature_algorithm()?;
1109
1110 let request = rfc2986::CertificationRequest {
1111 certificate_request_info: info,
1112 signature_algorithm: signature_algorithm.into(),
1113 signature: BitString::new(0, signature.into()),
1114 };
1115
1116 Ok(request)
1117 }
1118}
1119
1120#[cfg(test)]
1121mod test {
1122 use {
1123 super::*,
1124 crate::{EcdsaCurve, X509CertificateError},
1125 };
1126
1127 #[test]
1128 fn builder_ed25519_default() {
1129 let builder = X509CertificateBuilder::default();
1130 builder
1131 .create_with_random_keypair(KeyAlgorithm::Ed25519)
1132 .unwrap();
1133 }
1134
1135 #[test]
1136 fn build_ecdsa_default() {
1137 for curve in EcdsaCurve::all() {
1138 let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1139
1140 let builder = X509CertificateBuilder::default();
1141 builder.create_with_random_keypair(key_algorithm).unwrap();
1142 }
1143 }
1144
1145 #[test]
1146 fn build_subject_populate() {
1147 let mut builder = X509CertificateBuilder::default();
1148 builder
1149 .subject()
1150 .append_common_name_utf8_string("My Name")
1151 .unwrap();
1152 builder
1153 .subject()
1154 .append_country_utf8_string("Wakanda")
1155 .unwrap();
1156
1157 builder
1158 .create_with_random_keypair(KeyAlgorithm::Ed25519)
1159 .unwrap();
1160 }
1161
1162 #[test]
1163 fn builder_csr_ecdsa() -> Result<(), Error> {
1164 for curve in EcdsaCurve::all() {
1165 let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1166
1167 let key = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1168
1169 let builder = X509CertificateBuilder::default();
1170
1171 let csr = builder.create_certificate_signing_request(&key)?;
1172
1173 assert_eq!(
1174 csr.certificate_request_info
1175 .subject_public_key_info
1176 .algorithm,
1177 key_algorithm.into()
1178 );
1179 }
1180
1181 Ok(())
1182 }
1183
1184 #[test]
1185 fn ecdsa_p256_sha256_self_signed() {
1186 let der = include_bytes!("testdata/ecdsa-p256-sha256-self-signed.cer");
1187
1188 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1189 cert.verify_signed_by_certificate(&cert).unwrap();
1190
1191 cert.to_public_key_der().unwrap();
1192 }
1193
1194 #[test]
1195 fn ecdsa_p384_sha256_self_signed() {
1196 let der = include_bytes!("testdata/ecdsa-p384-sha256-self-signed.cer");
1197
1198 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1199 cert.verify_signed_by_certificate(&cert).unwrap();
1200 cert.to_public_key_der().unwrap();
1201 }
1202
1203 #[test]
1204 fn ecdsa_p512_sha256_self_signed() {
1205 let der = include_bytes!("testdata/ecdsa-p512-sha256-self-signed.cer");
1206
1207 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1210 cert.to_public_key_der().unwrap();
1211
1212 assert!(matches!(
1213 cert.verify_signed_by_certificate(&cert),
1214 Err(Error::UnknownEllipticCurve(_))
1215 ));
1216 }
1217
1218 #[test]
1219 fn ecdsa_prime256v1_cert_validation() -> Result<(), X509CertificateError> {
1220 let root = include_bytes!("testdata/ecdsa-prime256v1-root.der");
1221 let signed = include_bytes!("testdata/ecdsa-prime256v1-signed.der");
1222
1223 let root = CapturedX509Certificate::from_der(root.as_ref())?;
1224 let signed = CapturedX509Certificate::from_der(signed.as_ref())?;
1225
1226 root.verify_signed_by_certificate(&root)?;
1227 signed.verify_signed_by_certificate(&root)?;
1228
1229 Ok(())
1230 }
1231}