Skip to content

Commit

Permalink
Introduce new GAT based Asn1 Read/Write (#12011)
Browse files Browse the repository at this point in the history
This replaces the runtime based Asn1ReadableOrWritable.

Adopts it for IssuingDistributionPoint, DistributionPoint
  • Loading branch information
alex authored Nov 22, 2024
1 parent a93d194 commit 750f34e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 21 deletions.
14 changes: 14 additions & 0 deletions src/rust/cryptography-x509/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,20 @@ impl<T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleAsn1W
}
}

pub trait Asn1Operation {
type OwnedBitString<'a>;
}

pub struct Asn1Read;
pub struct Asn1Write;

impl Asn1Operation for Asn1Read {
type OwnedBitString<'a> = asn1::BitString<'a>;
}
impl Asn1Operation for Asn1Write {
type OwnedBitString<'a> = asn1::OwnedBitString;
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct DssSignature<'a> {
pub r: asn1::BigUint<'a>,
Expand Down
8 changes: 4 additions & 4 deletions src/rust/cryptography-x509/src/crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::common::Asn1Operation;
use crate::{common, extensions, name};

pub type ReasonFlags<'a> =
Option<common::Asn1ReadableOrWritable<asn1::BitString<'a>, asn1::OwnedBitString>>;
pub type ReasonFlags<'a, Op> = Option<<Op as Asn1Operation>::OwnedBitString<'a>>;

#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash)]
pub struct CertificateRevocationList<'a> {
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct RevokedCertificate<'a> {
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct IssuingDistributionPoint<'a> {
pub struct IssuingDistributionPoint<'a, Op: Asn1Operation> {
#[explicit(0)]
pub distribution_point: Option<extensions::DistributionPointName<'a>>,

Expand All @@ -54,7 +54,7 @@ pub struct IssuingDistributionPoint<'a> {
pub only_contains_ca_certs: bool,

#[implicit(3)]
pub only_some_reasons: ReasonFlags<'a>,
pub only_some_reasons: ReasonFlags<'a, Op>,

#[implicit(4)]
#[default(false)]
Expand Down
5 changes: 3 additions & 2 deletions src/rust/cryptography-x509/src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use std::collections::HashSet;

use crate::common;
use crate::common::Asn1Operation;
use crate::crl;
use crate::name;

Expand Down Expand Up @@ -183,12 +184,12 @@ pub struct MSCertificateTemplate {
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct DistributionPoint<'a> {
pub struct DistributionPoint<'a, Op: Asn1Operation> {
#[explicit(0)]
pub distribution_point: Option<DistributionPointName<'a>>,

#[implicit(1)]
pub reasons: crl::ReasonFlags<'a>,
pub reasons: crl::ReasonFlags<'a, Op>,

#[implicit(2)]
pub crl_issuer: Option<name::SequenceOfGeneralName<'a>>,
Expand Down
8 changes: 4 additions & 4 deletions src/rust/src/x509/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

use cryptography_x509::certificate::Certificate as RawCertificate;
use cryptography_x509::common::Asn1Read;
use cryptography_x509::common::{AlgorithmParameters, Asn1ReadableOrWritable};
use cryptography_x509::extensions::{
Admission, Admissions, AuthorityKeyIdentifier, BasicConstraints, DisplayText,
Expand Down Expand Up @@ -602,14 +603,13 @@ pub(crate) fn parse_distribution_point_name<'p>(

fn parse_distribution_point<'p>(
py: pyo3::Python<'p>,
dp: DistributionPoint<'p>,
dp: DistributionPoint<'p, Asn1Read>,
) -> CryptographyResult<pyo3::Bound<'p, pyo3::PyAny>> {
let (full_name, relative_name) = match dp.distribution_point {
Some(data) => parse_distribution_point_name(py, data)?,
None => (py.None().into_bound(py), py.None().into_bound(py)),
};
let reasons =
parse_distribution_point_reasons(py, dp.reasons.as_ref().map(|v| v.unwrap_read()))?;
let reasons = parse_distribution_point_reasons(py, dp.reasons.as_ref())?;
let crl_issuer = match dp.crl_issuer {
Some(aci) => x509::parse_general_names(py, aci.unwrap_read())?,
None => py.None().into_bound(py),
Expand All @@ -623,7 +623,7 @@ pub(crate) fn parse_distribution_points<'p>(
py: pyo3::Python<'p>,
ext: &Extension<'_>,
) -> CryptographyResult<pyo3::Bound<'p, pyo3::PyAny>> {
let dps = ext.value::<asn1::SequenceOf<'_, DistributionPoint<'_>>>()?;
let dps = ext.value::<asn1::SequenceOf<'_, DistributionPoint<'_, Asn1Read>>>()?;
let py_dps = pyo3::types::PyList::empty(py);
for dp in dps {
let py_dp = parse_distribution_point(py, dp)?;
Expand Down
9 changes: 3 additions & 6 deletions src/rust/src/x509/crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::sync::Arc;

use cryptography_x509::extensions::{Extension, IssuerAlternativeName};
use cryptography_x509::{
common,
common::{self, Asn1Read},
crl::{
self, CertificateRevocationList as RawCertificateRevocationList,
RevokedCertificate as RawRevokedCertificate,
Expand Down Expand Up @@ -350,16 +350,13 @@ impl CertificateRevocationList {
Ok(Some(certificate::parse_authority_key_identifier(py, ext)?))
}
oid::ISSUING_DISTRIBUTION_POINT_OID => {
let idp = ext.value::<crl::IssuingDistributionPoint<'_>>()?;
let idp = ext.value::<crl::IssuingDistributionPoint<'_, Asn1Read>>()?;
let (full_name, relative_name) = match idp.distribution_point {
Some(data) => certificate::parse_distribution_point_name(py, data)?,
None => (py.None().into_bound(py), py.None().into_bound(py)),
};
let py_reasons = if let Some(reasons) = idp.only_some_reasons {
certificate::parse_distribution_point_reasons(
py,
Some(reasons.unwrap_read()),
)?
certificate::parse_distribution_point_reasons(py, Some(&reasons))?
} else {
py.None().into_bound(py)
};
Expand Down
13 changes: 8 additions & 5 deletions src/rust/src/x509/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use cryptography_x509::{common, crl, extensions, oid};
use cryptography_x509::{
common::{self, Asn1Write},
crl, extensions, oid,
};

use crate::asn1::{py_oid_to_oid, py_uint_to_big_endian_bytes};
use crate::error::{CryptographyError, CryptographyResult};
Expand Down Expand Up @@ -118,11 +121,11 @@ pub(crate) fn encode_distribution_points<'p>(
};
let reasons = if let Some(py_reasons) = py_dp.reasons {
let reasons = certificate::encode_distribution_point_reasons(py, &py_reasons)?;
Some(common::Asn1ReadableOrWritable::new_write(reasons))
Some(reasons)
} else {
None
};
dps.push(extensions::DistributionPoint {
dps.push(extensions::DistributionPoint::<Asn1Write> {
crl_issuer,
distribution_point,
reasons,
Expand Down Expand Up @@ -331,7 +334,7 @@ fn encode_issuing_distribution_point(
{
let py_reasons = ext.getattr(pyo3::intern!(py, "only_some_reasons"))?;
let reasons = certificate::encode_distribution_point_reasons(ext.py(), &py_reasons)?;
Some(common::Asn1ReadableOrWritable::new_write(reasons))
Some(reasons)
} else {
None
};
Expand Down Expand Up @@ -360,7 +363,7 @@ fn encode_issuing_distribution_point(
None
};

let idp = crl::IssuingDistributionPoint {
let idp = crl::IssuingDistributionPoint::<Asn1Write> {
distribution_point,
indirect_crl: ext.getattr(pyo3::intern!(py, "indirect_crl"))?.extract()?,
only_contains_attribute_certs: ext
Expand Down

0 comments on commit 750f34e

Please sign in to comment.