Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
85fd7f8
x509: add new extension structure
npmccallum Feb 10, 2022
f7743c7
x509: add ext::pkix::name::DirectoryString
npmccallum Feb 10, 2022
841056a
x509: add ext::pkix::name::EdiPartyName
npmccallum Feb 10, 2022
d000ea7
x509: add ext::pkix::name::OtherName
npmccallum Feb 10, 2022
60e2c45
x509: add ext::pkix::name::GeneralName*
npmccallum Feb 8, 2022
0ec72da
x509: add ext::pkix::name::DistributionPointName
npmccallum Feb 10, 2022
935c9e3
x509: move oids to the pkix module
npmccallum Feb 10, 2022
e4bceb8
x509: move AuthorityKeyIdentifier into the pkix module
npmccallum Feb 10, 2022
5689f81
x509: move SubjectKeyIdentifier into the pkix module
npmccallum Feb 10, 2022
22fffc9
x509: move KeyUsage into the pkix module
npmccallum Feb 10, 2022
0561f13
x509: move CertificatePolicies into the pkix module
npmccallum Feb 10, 2022
90a6dbc
x509: move PolicyMapping* into the pkix module
npmccallum Feb 10, 2022
5eb9dbc
x509: move SubjectAltName into the pkix module
npmccallum Feb 10, 2022
cb7820f
x509: move IssuerAltName into the pkix module
npmccallum Feb 10, 2022
d754a02
x509: move SubjectDirectoryAttributes into the pkix module
npmccallum Feb 10, 2022
3af14ee
x509: move BasicConstraints into the pkix module
npmccallum Feb 10, 2022
ebc7174
x509: move NameConstraints into the pkix module
npmccallum Feb 10, 2022
490eff3
x509: move PolicyConstraints into the pkix module
npmccallum Feb 10, 2022
d5873c8
x509: move ExtendedKeyUsage into the pkix module
npmccallum Feb 10, 2022
46fc96a
x509: move InhibitAnyPolicy into the pkix module
npmccallum Feb 10, 2022
1382e52
x509: move *InfoAccessSyntax into the pkix module
npmccallum Feb 10, 2022
98d11c6
x509: move PrivateKeyUsagePeriod into the pkix module
npmccallum Feb 11, 2022
2313628
x509: move PivNaciIndicator into the ext module
npmccallum Feb 11, 2022
b962ab8
x509: move OcspNoCheck into the ext module
npmccallum Feb 11, 2022
50180bd
x509: move CRL types into the pkix module
npmccallum Feb 10, 2022
8eff67c
Update module conventions to the "new" style
npmccallum Feb 16, 2022
8860860
x509: rearrange top-level types
npmccallum Feb 11, 2022
24e4e36
x509: rename anchor module
npmccallum Feb 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkcs10/tests/certreq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn decode_rsa_2048_der() {
assert_eq!(attribute.values.len(), 1);

// Check the extensions.
let extensions: x509::Extensions = attribute.values.get(0).unwrap().decode_into().unwrap();
let extensions: x509::ext::Extensions = attribute.values.get(0).unwrap().decode_into().unwrap();
for (ext, (oid, val)) in extensions.iter().zip(EXTENSIONS) {
assert_eq!(ext.extn_id, oid.parse().unwrap());
assert_eq!(ext.extn_value, *val);
Expand Down
1 change: 1 addition & 0 deletions x509/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ x501 = { version = "=0.1.0-pre.0", path = "../x501" }

[dev-dependencies]
hex-literal = "0.3"
rstest = "0.12.0"

[features]
std = ["der/std"]
Expand Down
5 changes: 4 additions & 1 deletion x509/src/trust_anchor_format.rs → x509/src/anchor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Trust anchor-related structures as defined in RFC 5914

use crate::{Certificate, CertificatePolicies, Extensions, NameConstraints, TbsCertificate};
use crate::ext::pkix::certpolicy::CertificatePolicies;
use crate::ext::pkix::NameConstraints;
use crate::{ext::Extensions, Certificate, TbsCertificate};

use der::asn1::{OctetString, Utf8String};
use der::{Choice, Enumerated, Sequence};
use flagset::{flags, FlagSet};
Expand Down
72 changes: 13 additions & 59 deletions x509/src/certificate.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//! Certificate [`Certificate`] and TBSCertificate [`TBSCertificate`] as defined in RFC 5280

use der::asn1::{BitString, ObjectIdentifier, UIntBytes};
use der::asn1::{BitString, UIntBytes};
use der::{Enumerated, Sequence};
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
use x501::name::Name;
use x501::time::Validity;
use x501::{name::Name, time::Validity};

/// Certificate `Version` as defined in [RFC 5280 Section 4.1].
///
Expand Down Expand Up @@ -33,7 +30,7 @@ impl Default for Version {
}
}

/// X.509 `TBSCertificate` as defined in [RFC 5280 Section 4.1]
/// X.509 `TbsCertificate` as defined in [RFC 5280 Section 4.1]
///
/// ASN.1 structure containing the names of the subject and issuer, a public
/// key associated with the subject, a validity period, and other associated
Expand All @@ -57,7 +54,7 @@ impl Default for Version {
/// }
/// ```
///
/// [RFC 5280 Section 4.1.2.5]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1
/// [RFC 5280 Section 4.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct TbsCertificate<'a> {
Expand All @@ -77,74 +74,31 @@ pub struct TbsCertificate<'a> {
pub subject: Name<'a>,
pub subject_public_key_info: SubjectPublicKeyInfo<'a>,

#[asn1(context_specific = "1", optional = "true", tag_mode = "IMPLICIT")]
#[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
pub issuer_unique_id: Option<BitString<'a>>,

#[asn1(context_specific = "2", optional = "true", tag_mode = "IMPLICIT")]
#[asn1(context_specific = "2", tag_mode = "IMPLICIT", optional = "true")]
pub subject_unique_id: Option<BitString<'a>>,

#[asn1(context_specific = "3", optional = "true", tag_mode = "EXPLICIT")]
pub extensions: Option<Extensions<'a>>,
#[asn1(context_specific = "3", tag_mode = "EXPLICIT", optional = "true")]
pub extensions: Option<crate::ext::Extensions<'a>>,
}

/// X.509 certificates are defined in [RFC 5280 Section 4.1].
///
/// ASN.1 structure for an X.509 certificate:
///
/// ```text
/// Certificate ::= SEQUENCE {
/// tbsCertificate TBSCertificate,
/// signatureAlgorithm AlgorithmIdentifier,
/// signature BIT STRING }
/// tbsCertificate TBSCertificate,
/// signatureAlgorithm AlgorithmIdentifier,
/// signature BIT STRING
/// }
/// ```
///
/// [RFC 5280 Section 4.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct Certificate<'a> {
/// tbsCertificate TBSCertificate,
pub tbs_certificate: TbsCertificate<'a>,
/// signatureAlgorithm AlgorithmIdentifier,
pub signature_algorithm: AlgorithmIdentifier<'a>,
/// signature BIT STRING
pub signature: BitString<'a>,
}

/// Extension as defined in [RFC 5280 Section 4.1.2.9].
///
/// The ASN.1 definition for Extension objects is below. The extnValue type may be further parsed using a decoder corresponding to the extnID value.
///
/// ```text
/// Extension ::= SEQUENCE {
/// extnID OBJECT IDENTIFIER,
/// critical BOOLEAN DEFAULT FALSE,
/// extnValue OCTET STRING
/// -- contains the DER encoding of an ASN.1 value
/// -- corresponding to the extension type identified
/// -- by extnID
/// }
/// ```
///
/// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
pub struct Extension<'a> {
/// extnID OBJECT IDENTIFIER,
pub extn_id: ObjectIdentifier,

/// critical BOOLEAN DEFAULT FALSE,
#[asn1(default = "Default::default")]
pub critical: bool,

/// extnValue OCTET STRING
#[asn1(type = "OCTET STRING")]
pub extn_value: &'a [u8],
}

/// Extensions as defined in [RFC 5280 Section 4.1.2.9].
///
/// ```text
/// Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
/// ```
///
/// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9
//pub type Extensions<'a> = SequenceOf<Extension<'a>, 10>;
pub type Extensions<'a> = alloc::vec::Vec<Extension<'a>>;
45 changes: 45 additions & 0 deletions x509/src/ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Standardized X.509 Certificate Extensions

use der::Sequence;
use spki::ObjectIdentifier;

pub mod other;
pub mod pkix;

/// Extension as defined in [RFC 5280 Section 4.1.2.9].
///
/// The ASN.1 definition for Extension objects is below. The extnValue type
/// may be further parsed using a decoder corresponding to the extnID value.
///
/// ```text
/// Extension ::= SEQUENCE {
/// extnID OBJECT IDENTIFIER,
/// critical BOOLEAN DEFAULT FALSE,
/// extnValue OCTET STRING
/// -- contains the DER encoding of an ASN.1 value
/// -- corresponding to the extension type identified
/// -- by extnID
/// }
/// ```
///
/// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct Extension<'a> {
pub extn_id: ObjectIdentifier,

#[asn1(default = "Default::default")]
pub critical: bool,

#[asn1(type = "OCTET STRING")]
pub extn_value: &'a [u8],
}

/// Extensions as defined in [RFC 5280 Section 4.1.2.9].
///
/// ```text
/// Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
/// ```
///
/// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9
pub type Extensions<'a> = alloc::vec::Vec<Extension<'a>>;
25 changes: 25 additions & 0 deletions x509/src/ext/other.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! Miscelaneous Extensions

use der::asn1::Null;

/// OcspNoCheck as defined in [RFC 6960 Section 4.2.2.2.1].
///
/// This extension is idenfied by the [`PKIX_OCSP_NOCHECK`](constant.PKIX_OCSP_NOCHECK.html) OID.
///
/// ```text
/// OcspNoCheck ::= NULL
/// ```
///
/// [RFC 6960 Section 4.2.2.2.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.2.2.2.1
pub type OcspNoCheck = Null;

/// NACI-indicator as defined in [FIPS 201-2 Appendix B].
///
/// This extension is identified by the [`PIV_NACI_INDICATOR`](constant.PIV_NACI_INDICATOR.html) OID.
///
/// ```text
/// NACI-indicator ::= BOOLEAN
/// ```
///
/// [FIPS 201-2 Appendix B]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.201-2.pdf
pub type PivNaciIndicator = bool;
83 changes: 83 additions & 0 deletions x509/src/ext/pkix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! PKIX X.509 Certificate Extensions (RFC 5280)

pub mod certpolicy;
pub mod constraints;
pub mod crl;
pub mod name;
pub mod oids;

mod access;
mod authkeyid;
mod keyusage;
mod policymap;

pub use access::{AccessDescription, AuthorityInfoAccessSyntax, SubjectInfoAccessSyntax};
pub use authkeyid::AuthorityKeyIdentifier;
pub use certpolicy::CertificatePolicies;
pub use constraints::{BasicConstraints, NameConstraints, PolicyConstraints};
pub use crl::{
BaseCrlNumber, CrlDistributionPoints, CrlNumber, CrlReason, FreshestCrl,
IssuingDistributionPoint,
};
pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod};
pub use policymap::{PolicyMapping, PolicyMappings};

use alloc::vec::Vec;

use der::asn1::OctetString;
use x501::attr::AttributeTypeAndValue;

/// SubjectKeyIdentifier as defined in [RFC 5280 Section 4.2.1.2].
///
/// This extension is identified by the [`PKIX_CE_SUBJECT_KEY_IDENTIFIER`](constant.PKIX_CE_SUBJECT_KEY_IDENTIFIER.html) OID.
///
/// ```text
/// SubjectKeyIdentifier ::= KeyIdentifier
/// ```
///
/// [RFC 5280 Section 4.2.1.2]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2
pub type SubjectKeyIdentifier<'a> = OctetString<'a>;

/// SubjectAltName as defined in [RFC 5280 Section 4.2.1.6].
///
/// This extension is identified by the [`PKIX_CE_SUBJECT_ALT_NAME`](constant.PKIX_CE_SUBJECT_ALT_NAME.html) OID.
///
/// ```text
/// SubjectAltName ::= GeneralNames
/// ```
///
/// [RFC 5280 Section 4.2.1.6]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6
pub type SubjectAltName<'a> = name::GeneralNames<'a>;

/// IssuerAltName as defined in [RFC 5280 Section 4.2.1.7].
///
/// This extension is identified by the [`PKIX_CE_ISSUER_ALT_NAME`](constant.PKIX_CE_ISSUER_ALT_NAME.html) OID.
///
/// ```text
/// IssuerAltName ::= GeneralNames
/// ```
///
/// [RFC 5280 Section 4.2.1.7]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.7
pub type IssuerAltName<'a> = name::GeneralNames<'a>;

/// SubjectDirectoryAttributes as defined in [RFC 5280 Section 4.2.1.8].
///
/// This extension is identified by the [`PKIX_CE_SUBJECT_DIRECTORY_ATTRIBUTES`](constant.PKIX_CE_SUBJECT_DIRECTORY_ATTRIBUTES.html) OID.
///
/// ```text
/// SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF AttributeSet
/// ```
///
/// [RFC 5280 Section 4.2.1.8]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.8
pub type SubjectDirectoryAttributes<'a> = Vec<AttributeTypeAndValue<'a>>;

/// InhibitAnyPolicy as defined in [RFC 5280 Section 4.2.1.14].
///
/// This extension is identified by the [`PKIX_CE_INHIBIT_ANY_POLICY`](constant.PKIX_CE_INHIBIT_ANY_POLICY.html) OID.
///
/// ```text
/// InhibitAnyPolicy ::= SkipCerts
/// ```
///
/// [RFC 5280 Section 4.2.1.14]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.14
pub type InhibitAnyPolicy = u32;
46 changes: 46 additions & 0 deletions x509/src/ext/pkix/access.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use super::name::GeneralName;

use alloc::vec::Vec;

use der::{asn1::ObjectIdentifier, Sequence};

/// AuthorityInfoAccessSyntax as defined in [RFC 5280 Section 4.2.2.1].
///
/// This extension is identified by the [`PKIX_PE_AUTHORITYINFOACCESS`](constant.PKIX_PE_AUTHORITYINFOACCESS.html) OID.
///
/// ```text
/// AuthorityInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription
/// ```
///
/// [RFC 5280 Section 4.2.2.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.1
pub type AuthorityInfoAccessSyntax<'a> = Vec<AccessDescription<'a>>;

/// SubjectInfoAccessSyntax as defined in [RFC 5280 Section 4.2.2.2].
///
/// This extension is identified by the [`PKIX_PE_SUBJECTINFOACCESS`](constant.PKIX_PE_SUBJECTINFOACCESS.html) OID.
///
/// ```text
/// SubjectInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription
/// ```
///
/// [RFC 5280 Section 4.2.2.2]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.2
pub type SubjectInfoAccessSyntax<'a> = Vec<AccessDescription<'a>>;

/// AccessDescription as defined in [RFC 5280 Section 4.2.2.1].
///
/// ```text
/// AccessDescription ::= SEQUENCE {
/// accessMethod OBJECT IDENTIFIER,
/// accessLocation GeneralName
/// }
/// ```
///
/// [RFC 5280 Section 4.2.2.1]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
pub struct AccessDescription<'a> {
/// accessMethod OBJECT IDENTIFIER,
pub access_method: ObjectIdentifier,

/// accessLocation GeneralName
pub access_location: GeneralName<'a>,
}
Loading