1use {
8 crate::{
9 algorithm::DigestAlgorithm, asn1time::Time, rfc2986, rfc3280::Name, rfc5280, rfc5652,
10 rfc5958::Attributes, rfc8017::RsaPublicKey, signing::Sign, InMemorySigningKeyPair,
11 KeyAlgorithm, KeyInfoSigner, SignatureAlgorithm, X509CertificateError as Error,
12 },
13 bcder::{
14 decode::Constructed,
15 encode::Values,
16 int::Integer,
17 string::{BitString, OctetString},
18 ConstOid, Mode, Oid,
19 },
20 bytes::Bytes,
21 chrono::{DateTime, Duration, Utc},
22 der::{Decode, Document},
23 ring::signature as ringsig,
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<ring::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<ring::digest::Digest, std::io::Error> {
337 self.fingerprint(DigestAlgorithm::Sha1)
338 }
339
340 pub fn sha256_fingerprint(&self) -> Result<ring::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
555 self.verify_signed_by_public_key(public_key)
556 }
557
558 pub fn verify_signed_data(
566 &self,
567 signed_data: impl AsRef<[u8]>,
568 signature: impl AsRef<[u8]>,
569 ) -> Result<(), Error> {
570 let key_algorithm = KeyAlgorithm::try_from(self.key_algorithm_oid())?;
571 let signature_algorithm = SignatureAlgorithm::try_from(self.signature_algorithm_oid())?;
572 let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
573
574 self.verify_signed_data_with_algorithm(signed_data, signature, verify_algorithm)
575 }
576
577 pub fn verify_signed_data_with_algorithm(
583 &self,
584 signed_data: impl AsRef<[u8]>,
585 signature: impl AsRef<[u8]>,
586 verify_algorithm: &'static dyn ringsig::VerificationAlgorithm,
587 ) -> Result<(), Error> {
588 let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, self.public_key_data());
589
590 public_key
591 .verify(signed_data.as_ref(), signature.as_ref())
592 .map_err(|_| Error::CertificateSignatureVerificationFailed)
593 }
594
595 pub fn verify_signed_by_public_key(
606 &self,
607 public_key_data: impl AsRef<[u8]>,
608 ) -> Result<(), Error> {
609 let this_cert = match &self.original {
613 OriginalData::Ber(data) => X509Certificate::from_ber(data),
614 OriginalData::Der(data) => X509Certificate::from_der(data),
615 }
616 .expect("certificate re-parse should never fail");
617
618 let signed_data = this_cert
619 .0
620 .tbs_certificate
621 .raw_data
622 .as_ref()
623 .expect("original certificate data should have persisted as part of re-parse");
624 let signature = this_cert.0.signature.octet_bytes();
625
626 let key_algorithm = KeyAlgorithm::try_from(
627 &this_cert
628 .0
629 .tbs_certificate
630 .subject_public_key_info
631 .algorithm,
632 )?;
633 let signature_algorithm = SignatureAlgorithm::try_from(&this_cert.0.signature_algorithm)?;
634
635 let verify_algorithm = signature_algorithm.resolve_verification_algorithm(key_algorithm)?;
636
637 let public_key = ringsig::UnparsedPublicKey::new(verify_algorithm, public_key_data);
638
639 public_key
640 .verify(signed_data, &signature)
641 .map_err(|_| Error::CertificateSignatureVerificationFailed)
642 }
643
644 pub fn find_signing_certificate<'a>(
653 &self,
654 mut certs: impl Iterator<Item = &'a Self>,
655 ) -> Option<&'a Self> {
656 certs.find(|candidate| self.verify_signed_by_certificate(candidate).is_ok())
657 }
658
659 pub fn resolve_signing_chain<'a>(
679 &self,
680 certs: impl Iterator<Item = &'a Self>,
681 ) -> Vec<&'a Self> {
682 #[allow(clippy::mutable_key_type)]
686 let mut seen = HashSet::new();
687 let mut remaining = vec![];
688
689 for cert in certs {
690 if cert == self || seen.contains(cert) {
691 continue;
692 } else {
693 remaining.push(cert);
694 seen.insert(cert);
695 }
696 }
697
698 drop(seen);
699
700 let mut chain = vec![];
701
702 let mut last_cert = self;
703 while let Some(issuer) = last_cert.find_signing_certificate(remaining.iter().copied()) {
704 chain.push(issuer);
705 last_cert = issuer;
706
707 remaining = remaining
708 .drain(..)
709 .filter(|cert| *cert != issuer)
710 .collect::<Vec<_>>();
711 }
712
713 chain
714 }
715}
716
717impl PartialEq for CapturedX509Certificate {
718 fn eq(&self, other: &Self) -> bool {
719 self.constructed_data() == other.constructed_data()
720 }
721}
722
723impl Eq for CapturedX509Certificate {}
724
725impl Hash for CapturedX509Certificate {
726 fn hash<H: Hasher>(&self, state: &mut H) {
727 state.write(self.constructed_data());
728 }
729}
730
731impl Deref for CapturedX509Certificate {
732 type Target = X509Certificate;
733
734 fn deref(&self) -> &Self::Target {
735 &self.inner
736 }
737}
738
739impl AsRef<X509Certificate> for CapturedX509Certificate {
740 fn as_ref(&self) -> &X509Certificate {
741 &self.inner
742 }
743}
744
745impl AsRef<rfc5280::Certificate> for CapturedX509Certificate {
746 fn as_ref(&self) -> &rfc5280::Certificate {
747 self.inner.as_ref()
748 }
749}
750
751impl TryFrom<&X509Certificate> for CapturedX509Certificate {
752 type Error = Error;
753
754 fn try_from(cert: &X509Certificate) -> Result<Self, Self::Error> {
755 let mut buffer = Vec::<u8>::new();
756 cert.encode_der_to(&mut buffer)?;
757
758 Self::from_der(buffer)
759 }
760}
761
762impl TryFrom<X509Certificate> for CapturedX509Certificate {
763 type Error = Error;
764
765 fn try_from(cert: X509Certificate) -> Result<Self, Self::Error> {
766 let mut buffer = Vec::<u8>::new();
767 cert.encode_der_to(&mut buffer)?;
768
769 Self::from_der(buffer)
770 }
771}
772
773impl From<CapturedX509Certificate> for rfc5280::Certificate {
774 fn from(cert: CapturedX509Certificate) -> Self {
775 cert.inner.0
776 }
777}
778
779#[derive(Clone, Debug, Eq, PartialEq)]
787pub struct MutableX509Certificate(CapturedX509Certificate);
788
789impl Deref for MutableX509Certificate {
790 type Target = X509Certificate;
791
792 fn deref(&self) -> &Self::Target {
793 &self.0.inner
794 }
795}
796
797impl DerefMut for MutableX509Certificate {
798 fn deref_mut(&mut self) -> &mut Self::Target {
799 &mut self.0.inner
800 }
801}
802
803impl From<CapturedX509Certificate> for MutableX509Certificate {
804 fn from(cert: CapturedX509Certificate) -> Self {
805 Self(cert)
806 }
807}
808
809pub fn certificate_is_subset_of(
814 a_serial: &Integer,
815 a_name: &Name,
816 b_serial: &Integer,
817 b_name: &Name,
818) -> bool {
819 if a_serial != b_serial {
820 return false;
821 }
822
823 let Name::RdnSequence(a_sequence) = &a_name;
824 let Name::RdnSequence(b_sequence) = &b_name;
825
826 a_sequence.iter().all(|rdn| b_sequence.contains(rdn))
827}
828
829pub enum KeyUsage {
843 DigitalSignature,
844 NonRepudiation,
845 KeyEncipherment,
846 DataEncipherment,
847 KeyAgreement,
848 KeyCertSign,
849 CrlSign,
850}
851
852impl From<KeyUsage> for u8 {
853 fn from(ku: KeyUsage) -> Self {
854 match ku {
855 KeyUsage::DigitalSignature => 0,
856 KeyUsage::NonRepudiation => 1,
857 KeyUsage::KeyEncipherment => 2,
858 KeyUsage::DataEncipherment => 3,
859 KeyUsage::KeyAgreement => 4,
860 KeyUsage::KeyCertSign => 5,
861 KeyUsage::CrlSign => 6,
862 }
863 }
864}
865
866pub struct X509CertificateBuilder {
882 subject: Name,
883 issuer: Option<Name>,
884 extensions: rfc5280::Extensions,
885 serial_number: i64,
886 not_before: chrono::DateTime<Utc>,
887 not_after: chrono::DateTime<Utc>,
888 csr_attributes: Attributes,
889}
890
891impl Default for X509CertificateBuilder {
892 fn default() -> Self {
893 let not_before = Utc::now();
894 let not_after = not_before + Duration::hours(1);
895
896 Self {
897 subject: Name::default(),
898 issuer: None,
899 extensions: rfc5280::Extensions::default(),
900 serial_number: 1,
901 not_before,
902 not_after,
903 csr_attributes: Attributes::default(),
904 }
905 }
906}
907
908impl X509CertificateBuilder {
909 #[deprecated]
911 pub fn new() -> Self {
912 Self::default()
913 }
914
915 pub fn subject(&mut self) -> &mut Name {
919 &mut self.subject
920 }
921
922 pub fn issuer(&mut self) -> &mut Name {
926 self.issuer.get_or_insert_with(Name::default)
927 }
928
929 pub fn serial_number(&mut self, value: i64) {
931 self.serial_number = value;
932 }
933
934 pub fn extensions(&self) -> &rfc5280::Extensions {
936 &self.extensions
937 }
938
939 pub fn extensions_mut(&mut self) -> &mut rfc5280::Extensions {
941 &mut self.extensions
942 }
943
944 pub fn add_extension_der_data(&mut self, oid: Oid, critical: bool, data: impl AsRef<[u8]>) {
946 self.extensions.push(rfc5280::Extension {
947 id: oid,
948 critical: Some(critical),
949 value: OctetString::new(Bytes::copy_from_slice(data.as_ref())),
950 });
951 }
952
953 pub fn validity_duration(&mut self, duration: Duration) {
955 self.not_after = self.not_before + duration;
956 }
957
958 pub fn constraint_not_ca(&mut self) {
960 self.extensions.push(rfc5280::Extension {
961 id: Oid(OID_EXTENSION_BASIC_CONSTRAINTS.as_ref().into()),
962 critical: Some(true),
963 value: OctetString::new(Bytes::copy_from_slice(&[0x30, 00])),
964 });
965 }
966
967 pub fn key_usage(&mut self, key_usage: KeyUsage) {
969 let value: u8 = key_usage.into();
970
971 self.extensions.push(rfc5280::Extension {
972 id: Oid(OID_EXTENSION_KEY_USAGE.as_ref().into()),
973 critical: Some(true),
974 value: OctetString::new(Bytes::copy_from_slice(&[3, 2, 7, 128 | value])),
976 });
977 }
978
979 pub fn add_csr_attribute(&mut self, attribute: rfc5652::Attribute) {
984 self.csr_attributes.push(attribute);
985 }
986
987 pub fn create_with_key_pair(
989 &self,
990 key_pair: &InMemorySigningKeyPair,
991 ) -> Result<CapturedX509Certificate, Error> {
992 let key_pair_signature_algorithm = key_pair.signature_algorithm();
993
994 let issuer = if let Some(issuer) = &self.issuer {
995 issuer
996 } else {
997 &self.subject
998 };
999
1000 let tbs_certificate = rfc5280::TbsCertificate {
1001 version: Some(rfc5280::Version::V3),
1002 serial_number: self.serial_number.into(),
1003 signature: key_pair_signature_algorithm?.into(),
1004 issuer: issuer.clone(),
1005 validity: rfc5280::Validity {
1006 not_before: Time::from(self.not_before),
1007 not_after: Time::from(self.not_after),
1008 },
1009 subject: self.subject.clone(),
1010 subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1011 algorithm: key_pair
1012 .key_algorithm()
1013 .expect("InMemorySigningKeyPair always has known key algorithm")
1014 .into(),
1015 subject_public_key: BitString::new(0, key_pair.public_key_data()),
1016 },
1017 issuer_unique_id: None,
1018 subject_unique_id: None,
1019 extensions: if self.extensions.is_empty() {
1020 None
1021 } else {
1022 Some(self.extensions.clone())
1023 },
1024 raw_data: None,
1025 };
1026
1027 let mut tbs_der = Vec::<u8>::new();
1030 tbs_certificate
1031 .encode_ref()
1032 .write_encoded(Mode::Der, &mut tbs_der)?;
1033
1034 let signature = key_pair.try_sign(&tbs_der)?;
1035 let signature_algorithm = key_pair.signature_algorithm()?;
1036
1037 let cert = rfc5280::Certificate {
1038 tbs_certificate,
1039 signature_algorithm: signature_algorithm.into(),
1040 signature: BitString::new(0, Bytes::copy_from_slice(signature.as_ref())),
1041 };
1042
1043 let cert = X509Certificate::from(cert);
1044 let cert_der = cert.encode_der()?;
1045
1046 CapturedX509Certificate::from_der(cert_der)
1047 }
1048
1049 pub fn create_with_random_keypair(
1051 &self,
1052 key_algorithm: KeyAlgorithm,
1053 ) -> Result<(CapturedX509Certificate, InMemorySigningKeyPair), Error> {
1054 let key_pair = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1055 let cert = self.create_with_key_pair(&key_pair)?;
1056
1057 Ok((cert, key_pair))
1058 }
1059
1060 pub fn create_certificate_signing_request(
1067 &self,
1068 signer: &dyn KeyInfoSigner,
1069 ) -> Result<rfc2986::CertificationRequest, Error> {
1070 let info = rfc2986::CertificationRequestInfo {
1071 version: rfc2986::Version::V1,
1072 subject: self.subject.clone(),
1073 subject_public_key_info: rfc5280::SubjectPublicKeyInfo {
1074 algorithm: signer
1075 .key_algorithm()
1076 .ok_or_else(|| {
1077 Error::UnknownKeyAlgorithm(
1078 "OID not available due to API limitations".into(),
1079 )
1080 })?
1081 .into(),
1082 subject_public_key: BitString::new(0, signer.public_key_data()),
1083 },
1084 attributes: self.csr_attributes.clone(),
1085 };
1086
1087 let mut info_der = vec![];
1090 info.write_encoded(Mode::Der, &mut info_der)?;
1091
1092 let signature = signer.try_sign(&info_der)?;
1093 let signature_algorithm = signer.signature_algorithm()?;
1094
1095 let request = rfc2986::CertificationRequest {
1096 certificate_request_info: info,
1097 signature_algorithm: signature_algorithm.into(),
1098 signature: BitString::new(0, signature.into()),
1099 };
1100
1101 Ok(request)
1102 }
1103}
1104
1105#[cfg(test)]
1106mod test {
1107 use {
1108 super::*,
1109 crate::{EcdsaCurve, X509CertificateError},
1110 };
1111
1112 #[test]
1113 fn builder_ed25519_default() {
1114 let builder = X509CertificateBuilder::default();
1115 builder
1116 .create_with_random_keypair(KeyAlgorithm::Ed25519)
1117 .unwrap();
1118 }
1119
1120 #[test]
1121 fn build_ecdsa_default() {
1122 for curve in EcdsaCurve::all() {
1123 let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1124
1125 let builder = X509CertificateBuilder::default();
1126 builder.create_with_random_keypair(key_algorithm).unwrap();
1127 }
1128 }
1129
1130 #[test]
1131 fn build_subject_populate() {
1132 let mut builder = X509CertificateBuilder::default();
1133 builder
1134 .subject()
1135 .append_common_name_utf8_string("My Name")
1136 .unwrap();
1137 builder
1138 .subject()
1139 .append_country_utf8_string("Wakanda")
1140 .unwrap();
1141
1142 builder
1143 .create_with_random_keypair(KeyAlgorithm::Ed25519)
1144 .unwrap();
1145 }
1146
1147 #[test]
1148 fn builder_csr_ecdsa() -> Result<(), Error> {
1149 for curve in EcdsaCurve::all() {
1150 let key_algorithm = KeyAlgorithm::Ecdsa(*curve);
1151
1152 let key = InMemorySigningKeyPair::generate_random(key_algorithm)?;
1153
1154 let builder = X509CertificateBuilder::default();
1155
1156 let csr = builder.create_certificate_signing_request(&key)?;
1157
1158 assert_eq!(
1159 csr.certificate_request_info
1160 .subject_public_key_info
1161 .algorithm,
1162 key_algorithm.into()
1163 );
1164 }
1165
1166 Ok(())
1167 }
1168
1169 #[test]
1170 fn ecdsa_p256_sha256_self_signed() {
1171 let der = include_bytes!("testdata/ecdsa-p256-sha256-self-signed.cer");
1172
1173 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1174 cert.verify_signed_by_certificate(&cert).unwrap();
1175
1176 cert.to_public_key_der().unwrap();
1177 }
1178
1179 #[test]
1180 fn ecdsa_p384_sha256_self_signed() {
1181 let der = include_bytes!("testdata/ecdsa-p384-sha256-self-signed.cer");
1182
1183 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1184 cert.verify_signed_by_certificate(&cert).unwrap();
1185 cert.to_public_key_der().unwrap();
1186 }
1187
1188 #[test]
1189 fn ecdsa_p512_sha256_self_signed() {
1190 let der = include_bytes!("testdata/ecdsa-p512-sha256-self-signed.cer");
1191
1192 let cert = CapturedX509Certificate::from_der(der.to_vec()).unwrap();
1195 cert.to_public_key_der().unwrap();
1196
1197 assert!(matches!(
1198 cert.verify_signed_by_certificate(&cert),
1199 Err(Error::UnknownEllipticCurve(_))
1200 ));
1201 }
1202
1203 #[test]
1204 fn ecdsa_prime256v1_cert_validation() -> Result<(), X509CertificateError> {
1205 let root = include_bytes!("testdata/ecdsa-prime256v1-root.der");
1206 let signed = include_bytes!("testdata/ecdsa-prime256v1-signed.der");
1207
1208 let root = CapturedX509Certificate::from_der(root.as_ref())?;
1209 let signed = CapturedX509Certificate::from_der(signed.as_ref())?;
1210
1211 root.verify_signed_by_certificate(&root)?;
1212 signed.verify_signed_by_certificate(&root)?;
1213
1214 Ok(())
1215 }
1216}