Skip to content

Commit a39c8c8

Browse files
committed
x509-cert: accept rfc5280-invalid certificates as trustanchor
This commit brings the profiles introduced in RustCrypto#987 to `TrustAnchorChoice` and `Crl`. This is intended for the support of invalid certificates in https://github.com/carl-wallace/rust-pki/tree/main/certval
1 parent cde2991 commit a39c8c8

File tree

4 files changed

+33
-24
lines changed

4 files changed

+33
-24
lines changed

x509-cert/src/anchor.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Trust anchor-related structures as defined in RFC 5914
22
3+
use crate::certificate::{CertificateInner, Profile, Rfc5280, TbsCertificateInner};
34
use crate::ext::pkix::{certpolicy::CertificatePolicies, NameConstraints};
45
use crate::{ext::Extensions, name::Name};
5-
use crate::{Certificate, TbsCertificate};
66

77
use alloc::string::String;
88
use der::asn1::OctetString;
@@ -37,7 +37,7 @@ pub enum Version {
3737
/// ```
3838
#[derive(Clone, Debug, PartialEq, Eq, Sequence)]
3939
#[allow(missing_docs)]
40-
pub struct TrustAnchorInfo {
40+
pub struct TrustAnchorInfo<P: Profile + 'static = Rfc5280> {
4141
#[asn1(default = "Default::default")]
4242
pub version: Version,
4343

@@ -49,7 +49,7 @@ pub struct TrustAnchorInfo {
4949
pub ta_title: Option<String>,
5050

5151
#[asn1(optional = "true")]
52-
pub cert_path: Option<CertPathControls>,
52+
pub cert_path: Option<CertPathControls<P>>,
5353

5454
#[asn1(context_specific = "1", tag_mode = "EXPLICIT", optional = "true")]
5555
pub extensions: Option<Extensions>,
@@ -70,11 +70,11 @@ pub struct TrustAnchorInfo {
7070
/// ```
7171
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
7272
#[allow(missing_docs)]
73-
pub struct CertPathControls {
73+
pub struct CertPathControls<P: Profile + 'static = Rfc5280> {
7474
pub ta_name: Name,
7575

7676
#[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")]
77-
pub certificate: Option<Certificate>,
77+
pub certificate: Option<CertificateInner<P>>,
7878

7979
#[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
8080
pub policy_set: Option<CertificatePolicies>,
@@ -114,22 +114,27 @@ flags! {
114114
/// [RFC 5280 Section 4.2.1.13]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.13
115115
pub type CertPolicyFlags = FlagSet<CertPolicies>;
116116

117+
/// TrustAnchorInfo allows for the representation of a single trust anchor.
118+
/// Defined in [RFC 5914 Section 3].
119+
///
117120
/// ```text
118121
/// TrustAnchorChoice ::= CHOICE {
119122
/// certificate Certificate,
120123
/// tbsCert [1] EXPLICIT TBSCertificate,
121124
/// taInfo [2] EXPLICIT TrustAnchorInfo
122125
/// }
123126
/// ```
127+
///
128+
/// [RFC 5914 Section 3]: https://www.rfc-editor.org/rfc/rfc5914#section-3
124129
#[derive(Clone, Debug, PartialEq, Eq, Choice)]
125130
#[allow(clippy::large_enum_variant)]
126131
#[allow(missing_docs)]
127-
pub enum TrustAnchorChoice {
128-
Certificate(Certificate),
132+
pub enum TrustAnchorChoice<P: Profile + 'static = Rfc5280> {
133+
Certificate(CertificateInner<P>),
129134

130135
#[asn1(context_specific = "1", tag_mode = "EXPLICIT", constructed = "true")]
131-
TbsCertificate(TbsCertificate),
136+
TbsCertificate(TbsCertificateInner<P>),
132137

133138
#[asn1(context_specific = "2", tag_mode = "EXPLICIT", constructed = "true")]
134-
TaInfo(TrustAnchorInfo),
139+
TaInfo(TrustAnchorInfo<P>),
135140
}

x509-cert/src/crl.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Certificate Revocation List types
22
3+
use crate::certificate::{Profile, Rfc5280};
34
use crate::ext::Extensions;
45
use crate::name::Name;
56
use crate::serial_number::SerialNumber;
@@ -25,8 +26,8 @@ use spki::AlgorithmIdentifierOwned;
2526
/// [RFC 5280 Section 5.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-5.1
2627
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
2728
#[allow(missing_docs)]
28-
pub struct CertificateList {
29-
pub tbs_cert_list: TbsCertList,
29+
pub struct CertificateList<P: Profile + 'static = Rfc5280> {
30+
pub tbs_cert_list: TbsCertList<P>,
3031
pub signature_algorithm: AlgorithmIdentifierOwned,
3132
pub signature: BitString,
3233
}
@@ -47,8 +48,8 @@ pub struct CertificateList {
4748
/// [RFC 5280 Section 5.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-5.1
4849
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
4950
#[allow(missing_docs)]
50-
pub struct RevokedCert {
51-
pub serial_number: SerialNumber,
51+
pub struct RevokedCert<P: Profile + 'static = Rfc5280> {
52+
pub serial_number: SerialNumber<P>,
5253
pub revocation_date: Time,
5354
pub crl_entry_extensions: Option<Extensions>,
5455
}
@@ -74,13 +75,13 @@ pub struct RevokedCert {
7475
/// [RFC 5280 Section 5.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-5.1
7576
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
7677
#[allow(missing_docs)]
77-
pub struct TbsCertList {
78+
pub struct TbsCertList<P: Profile + 'static = Rfc5280> {
7879
pub version: Version,
7980
pub signature: AlgorithmIdentifierOwned,
8081
pub issuer: Name,
8182
pub this_update: Time,
8283
pub next_update: Option<Time>,
83-
pub revoked_certificates: Option<Vec<RevokedCert>>,
84+
pub revoked_certificates: Option<Vec<RevokedCert<P>>>,
8485

8586
#[asn1(context_specific = "0", tag_mode = "EXPLICIT", optional = "true")]
8687
pub crl_extensions: Option<Extensions>,

x509-cert/tests/crl.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
use der::Decode;
2-
use x509_cert::crl::CertificateList;
2+
use x509_cert::{certificate::Rfc5280, crl::CertificateList};
33

44
#[test]
55
fn decode_crl() {
66
// vanilla CRL from PKITS
77
let der_encoded_cert = include_bytes!("examples/GoodCACRL.crl");
8-
let crl = CertificateList::from_der(der_encoded_cert).unwrap();
8+
let crl = CertificateList::<Rfc5280>::from_der(der_encoded_cert).unwrap();
99
assert_eq!(2, crl.tbs_cert_list.crl_extensions.unwrap().len());
1010
assert_eq!(2, crl.tbs_cert_list.revoked_certificates.unwrap().len());
1111

1212
// CRL with an entry with no entry extensions
1313
let der_encoded_cert = include_bytes!("examples/tscpbcasha256.crl");
14-
let crl = CertificateList::from_der(der_encoded_cert).unwrap();
14+
let crl = CertificateList::<Rfc5280>::from_der(der_encoded_cert).unwrap();
1515
assert_eq!(2, crl.tbs_cert_list.crl_extensions.unwrap().len());
1616
assert_eq!(4, crl.tbs_cert_list.revoked_certificates.unwrap().len());
1717
}

x509-cert/tests/trust_anchor_format.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ use der::{
33
Decode, Encode, SliceReader,
44
};
55
use hex_literal::hex;
6-
use x509_cert::anchor::{CertPolicies, TrustAnchorChoice};
7-
use x509_cert::ext::pkix::name::GeneralName;
6+
use x509_cert::{
7+
anchor::{CertPolicies, TrustAnchorChoice},
8+
certificate::Rfc5280,
9+
ext::pkix::name::GeneralName,
10+
};
811

912
#[test]
1013
fn decode_ta1() {
@@ -14,7 +17,7 @@ fn decode_ta1() {
1417
let der_encoded_cert = include_bytes!("examples/eca.der");
1518

1619
let mut decoder = SliceReader::new(der_encoded_tac).unwrap();
17-
let tac = TrustAnchorChoice::decode(&mut decoder).unwrap();
20+
let tac = TrustAnchorChoice::<Rfc5280>::decode(&mut decoder).unwrap();
1821
let reencoded_tac = tac.to_der().unwrap();
1922
println!("Original : {:02X?}", der_encoded_cert);
2023
println!("Reencoded: {:02X?}", reencoded_tac);
@@ -143,7 +146,7 @@ fn decode_ta2() {
143146
let der_encoded_cert = include_bytes!("examples/entrust.der");
144147

145148
let mut decoder = SliceReader::new(der_encoded_tac).unwrap();
146-
let tac = TrustAnchorChoice::decode(&mut decoder).unwrap();
149+
let tac = TrustAnchorChoice::<Rfc5280>::decode(&mut decoder).unwrap();
147150
let reencoded_tac = tac.to_der().unwrap();
148151
println!("Original : {:02X?}", der_encoded_cert);
149152
println!("Reencoded: {:02X?}", reencoded_tac);
@@ -263,7 +266,7 @@ fn decode_ta3() {
263266
let der_encoded_cert = include_bytes!("examples/exostar.der");
264267

265268
let mut decoder = SliceReader::new(der_encoded_tac).unwrap();
266-
let tac = TrustAnchorChoice::decode(&mut decoder).unwrap();
269+
let tac = TrustAnchorChoice::<Rfc5280>::decode(&mut decoder).unwrap();
267270
let reencoded_tac = tac.to_der().unwrap();
268271
println!("Original : {:02X?}", der_encoded_cert);
269272
println!("Reencoded: {:02X?}", reencoded_tac);
@@ -390,7 +393,7 @@ fn decode_ta4() {
390393
let der_encoded_cert = include_bytes!("examples/raytheon.der");
391394

392395
let mut decoder = SliceReader::new(der_encoded_tac).unwrap();
393-
let tac = TrustAnchorChoice::decode(&mut decoder).unwrap();
396+
let tac = TrustAnchorChoice::<Rfc5280>::decode(&mut decoder).unwrap();
394397
let reencoded_tac = tac.to_der().unwrap();
395398
println!("Original : {:02X?}", der_encoded_cert);
396399
println!("Reencoded: {:02X?}", reencoded_tac);

0 commit comments

Comments
 (0)