Skip to content

Commit

Permalink
x509-ocsp: add support for parsing profiles
Browse files Browse the repository at this point in the history
This allows an x509 validator to check for ocsp signature of
RFC5280-invalid certificates.
  • Loading branch information
baloo committed May 12, 2024
1 parent 16fb786 commit 3ea61c6
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 19 deletions.
6 changes: 3 additions & 3 deletions x509-cert/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use der::{
/// [`Profile`] allows the consumer of this crate to customize the behavior when parsing
/// certificates.
/// By default, parsing will be made in a rfc5280-compliant manner.
pub trait Profile: PartialEq + Debug + Eq + Clone {
pub trait Profile: PartialEq + Debug + Eq + Clone + Default {
/// Checks to run when parsing serial numbers
fn check_serial_number(serial: &SerialNumber<Self>) -> der::Result<()> {
// See the note in `SerialNumber::new`: we permit lengths of 21 bytes here,
Expand All @@ -32,15 +32,15 @@ pub trait Profile: PartialEq + Debug + Eq + Clone {
}

#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, Default)]
/// Parse certificates with rfc5280-compliant checks
pub struct Rfc5280;

impl Profile for Rfc5280 {}

#[cfg(feature = "hazmat")]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, Default)]
/// Parse raw x509 certificate and disable all the checks
pub struct Raw;

Expand Down
3 changes: 2 additions & 1 deletion x509-ocsp/src/builder/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rand_core::CryptoRngCore;
use signature::{RandomizedSigner, Signer};
use spki::{DynSignatureAlgorithmIdentifier, SignatureBitStringEncoding};
use x509_cert::{
certificate::Rfc5280,
ext::{pkix::name::GeneralName, AsExtension},
name::Name,
Certificate,
Expand Down Expand Up @@ -59,7 +60,7 @@ use x509_cert::{
/// ```
#[derive(Clone, Debug, Default)]
pub struct OcspRequestBuilder {
tbs: TbsRequest,
tbs: TbsRequest<Rfc5280>,
}

impl OcspRequestBuilder {
Expand Down
9 changes: 6 additions & 3 deletions x509-ocsp/src/cert_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
use der::{asn1::OctetString, Sequence};
use spki::AlgorithmIdentifierOwned;
use x509_cert::serial_number::SerialNumber;
use x509_cert::{
certificate::{Profile, Rfc5280},
serial_number::SerialNumber,
};

/// CertID structure as defined in [RFC 6960 Section 4.1.1].
///
Expand All @@ -17,11 +20,11 @@ use x509_cert::serial_number::SerialNumber;
/// [RFC 6960 Section 4.1.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.1.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct CertId {
pub struct CertId<P: Profile + 'static = Rfc5280> {
pub hash_algorithm: AlgorithmIdentifierOwned,
pub issuer_name_hash: OctetString,
pub issuer_key_hash: OctetString,
pub serial_number: SerialNumber,
pub serial_number: SerialNumber<P>,
}

impl From<&CertId> for CertId {
Expand Down
18 changes: 9 additions & 9 deletions x509-ocsp/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use core::{default::Default, option::Option};
use der::{asn1::BitString, Decode, Sequence};
use spki::AlgorithmIdentifierOwned;
use x509_cert::{
certificate::Certificate,
certificate::{CertificateInner, Profile, Rfc5280},
ext::{pkix::name::GeneralName, Extensions},
};

Expand All @@ -22,8 +22,8 @@ use x509_cert::{
/// [RFC 6960 Section 4.1.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.1.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct OcspRequest {
pub tbs_request: TbsRequest,
pub struct OcspRequest<P: Profile + 'static = Rfc5280> {
pub tbs_request: TbsRequest<P>,

#[asn1(context_specific = "0", optional = "true", tag_mode = "EXPLICIT")]
pub optional_signature: Option<Signature>,
Expand All @@ -50,7 +50,7 @@ impl OcspRequest {
/// [RFC 6960 Section 4.1.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.1.1
#[derive(Clone, Debug, Default, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct TbsRequest {
pub struct TbsRequest<P: Profile + 'static = Rfc5280> {
#[asn1(
context_specific = "0",
default = "Default::default",
Expand All @@ -61,7 +61,7 @@ pub struct TbsRequest {
#[asn1(context_specific = "1", optional = "true", tag_mode = "EXPLICIT")]
pub requestor_name: Option<GeneralName>,

pub request_list: Vec<Request>,
pub request_list: Vec<Request<P>>,

#[asn1(context_specific = "2", optional = "true", tag_mode = "EXPLICIT")]
pub request_extensions: Option<Extensions>,
Expand Down Expand Up @@ -96,12 +96,12 @@ impl TbsRequest {
/// [RFC 6960 Section 4.1.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.1.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct Signature {
pub struct Signature<P: Profile + 'static = Rfc5280> {
pub signature_algorithm: AlgorithmIdentifierOwned,
pub signature: BitString,

#[asn1(context_specific = "0", optional = "true", tag_mode = "EXPLICIT")]
pub certs: Option<Vec<Certificate>>,
pub certs: Option<Vec<CertificateInner<P>>>,
}

/// Request structure as defined in [RFC 6960 Section 4.1.1].
Expand All @@ -115,8 +115,8 @@ pub struct Signature {
/// [RFC 6960 Section 4.1.1]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.1.1
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct Request {
pub req_cert: CertId,
pub struct Request<P: Profile + 'static = Rfc5280> {
pub req_cert: CertId<P>,

#[asn1(context_specific = "0", optional = "true", tag_mode = "EXPLICIT")]
pub single_request_extensions: Option<Extensions>,
Expand Down
6 changes: 3 additions & 3 deletions x509-ocsp/tests/ocsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use const_oid::db::rfc6960::ID_PKIX_OCSP_BASIC;
use der::asn1::{Null, ObjectIdentifier};
use der::{Decode, Encode};
use hex_literal::hex;
use x509_cert::ext::pkix::CrlReason;
use x509_cert::{certificate::Rfc5280, ext::pkix::CrlReason};
use x509_ocsp::Version::V1;
use x509_ocsp::*;

Expand All @@ -16,7 +16,7 @@ fn decode_ocsp_req_ca_signed() {
pub const PKIXALG_SHA1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");

let ocsp_req =
OcspRequest::from_der(&hex!("3051304F304D304B3049300906052B0E03021A05000414A87E303106E4E88565CFE952598FA6DA7C00532F0414246E2B2DD06A925151256901AA9A47A689E7402002100E4239AB85E2E6A27C52C6DE9B9078D9")[..]).unwrap();
OcspRequest::<Rfc5280>::from_der(&hex!("3051304F304D304B3049300906052B0E03021A05000414A87E303106E4E88565CFE952598FA6DA7C00532F0414246E2B2DD06A925151256901AA9A47A689E7402002100E4239AB85E2E6A27C52C6DE9B9078D9")[..]).unwrap();
assert_eq!(ocsp_req.tbs_request.version, V1);
//assert!(ocsp_req.tbs_request.requestor_name.is_none());
assert_eq!(ocsp_req.tbs_request.request_list.len(), 1);
Expand Down Expand Up @@ -172,7 +172,7 @@ fn decode_ocsp_req_delegated() {
pub const PKIXALG_SHA1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");

let ocsp_req =
OcspRequest::from_der(&hex!("304530433041303F303D300906052B0E03021A050004140F0D5890F551D42ACF5431B7F42A321F7B74A4730414771441A65D9526D01DFF953B628CEAB7B55D3B92020401017467")[..]).unwrap();
OcspRequest::<Rfc5280>::from_der(&hex!("304530433041303F303D300906052B0E03021A050004140F0D5890F551D42ACF5431B7F42A321F7B74A4730414771441A65D9526D01DFF953B628CEAB7B55D3B92020401017467")[..]).unwrap();
assert_eq!(ocsp_req.tbs_request.version, V1);
//assert!(ocsp_req.tbs_request.requestor_name.is_none());
assert_eq!(ocsp_req.tbs_request.request_list.len(), 1);
Expand Down

0 comments on commit 3ea61c6

Please sign in to comment.