From aa23cf249a39b776b336bf11595f269e1a342733 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 17 Nov 2024 11:27:21 -0500 Subject: [PATCH] Attempt to convert OCSP Request types to GATs This does currently work because GATs cause a type to be invariant --- src/rust/cryptography-x509/src/common.rs | 11 +++++++++++ src/rust/cryptography-x509/src/ocsp_req.rs | 12 +++++------- src/rust/src/x509/ocsp_req.rs | 22 +++++++--------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 5e73a6bb29e0..7f09f9a34f08 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -267,6 +267,9 @@ impl asn1::SimpleAsn1W } pub trait Asn1Operation { + type SequenceOf<'a, T> + where + T: 'a; type SequenceOfVec<'a, T> where T: 'a; @@ -280,6 +283,10 @@ pub struct Asn1Read; pub struct Asn1Write; impl Asn1Operation for Asn1Read { + type SequenceOf<'a, T> + = asn1::SequenceOf<'a, T> + where + T: 'a; type SequenceOfVec<'a, T> = asn1::SequenceOf<'a, T> where @@ -291,6 +298,10 @@ impl Asn1Operation for Asn1Read { type OwnedBitString<'a> = asn1::BitString<'a>; } impl Asn1Operation for Asn1Write { + type SequenceOf<'a, T> + = asn1::SequenceOfWriter<'a, T> + where + T: 'a; type SequenceOfVec<'a, T> = asn1::SequenceOfWriter<'a, T, Vec> where diff --git a/src/rust/cryptography-x509/src/ocsp_req.rs b/src/rust/cryptography-x509/src/ocsp_req.rs index 163c40fa38b0..2ea5b0db9480 100644 --- a/src/rust/cryptography-x509/src/ocsp_req.rs +++ b/src/rust/cryptography-x509/src/ocsp_req.rs @@ -2,19 +2,17 @@ // 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}; #[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub struct TBSRequest<'a> { +pub struct TBSRequest<'a, Op: Asn1Operation> { #[explicit(0)] #[default(0)] pub version: u8, #[explicit(1)] pub requestor_name: Option>, - pub request_list: common::Asn1ReadableOrWritable< - asn1::SequenceOf<'a, Request<'a>>, - asn1::SequenceOfWriter<'a, Request<'a>>, - >, + pub request_list: Op::SequenceOf<'a, Request<'a>>, #[explicit(2)] pub raw_request_extensions: Option>, } @@ -35,8 +33,8 @@ pub struct CertID<'a> { } #[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub struct OCSPRequest<'a> { - pub tbs_request: TBSRequest<'a>, +pub struct OCSPRequest<'a, Op: Asn1Operation> { + pub tbs_request: TBSRequest<'a, Op>, // Parsing out the full structure, which includes the entirety of a // certificate is more trouble than it's worth, since it's not in the // Python API. diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index c49d21aa931d..825369895365 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -2,8 +2,9 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use cryptography_x509::common::{Asn1Read, Asn1Write}; use cryptography_x509::ocsp_req::{self, OCSPRequest as RawOCSPRequest}; -use cryptography_x509::{common, oid}; +use cryptography_x509::oid; use pyo3::types::{PyAnyMethods, PyListMethods}; use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, py_uint_to_big_endian_bytes}; @@ -11,11 +12,12 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509::{extensions, ocsp}; use crate::{exceptions, types, x509}; +type ReadRawOCSPRequest<'a> = RawOCSPRequest<'a, Asn1Read>; self_cell::self_cell!( struct OwnedOCSPRequest { owner: pyo3::Py, #[covariant] - dependent: RawOCSPRequest, + dependent: ReadRawOCSPRequest, } ); @@ -26,14 +28,7 @@ pub(crate) fn load_der_ocsp_request( ) -> CryptographyResult { let raw = OwnedOCSPRequest::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; - if raw - .borrow_dependent() - .tbs_request - .request_list - .unwrap_read() - .len() - != 1 - { + if raw.borrow_dependent().tbs_request.request_list.len() != 1 { return Err(CryptographyError::from( pyo3::exceptions::PyNotImplementedError::new_err( "OCSP request contains more than one request", @@ -60,7 +55,6 @@ impl OCSPRequest { .borrow_dependent() .tbs_request .request_list - .unwrap_read() .clone() .next() .unwrap() @@ -211,13 +205,11 @@ pub(crate) fn create_ocsp_request( req_cert, single_request_extensions: None, }]; - let ocsp_req = ocsp_req::OCSPRequest { + let ocsp_req = ocsp_req::OCSPRequest:: { tbs_request: ocsp_req::TBSRequest { version: 0, requestor_name: None, - request_list: common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( - &reqs, - )), + request_list: asn1::SequenceOfWriter::new(&reqs), raw_request_extensions: extensions, }, optional_signature: None,