From 11af60a0087ccac0a169dc6a34024b484655bbd2 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 8 Mar 2026 14:45:58 +0200 Subject: [PATCH 1/4] x509/ocsp_req: cache issuer_name_hash getter result Store the Python bytes object in a PyOnceLock so that repeated accesses return the same object without re-traversing the ASN.1 structure. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Alexander Bokovoy --- src/rust/src/x509/ocsp_req.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index c972c0cc98de..0c4031adaa12 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -44,6 +44,7 @@ pub(crate) fn load_der_ocsp_request( Ok(OCSPRequest { raw, cached_extensions: pyo3::sync::PyOnceLock::new(), + cached_issuer_name_hash: pyo3::sync::PyOnceLock::new(), }) } @@ -52,6 +53,7 @@ pub(crate) struct OCSPRequest { raw: OwnedOCSPRequest, cached_extensions: pyo3::sync::PyOnceLock>, + cached_issuer_name_hash: pyo3::sync::PyOnceLock>, } impl OCSPRequest { @@ -71,8 +73,21 @@ impl OCSPRequest { #[pyo3::pymethods] impl OCSPRequest { #[getter] - fn issuer_name_hash(&self) -> &[u8] { - self.cert_id().issuer_name_hash + fn issuer_name_hash<'p>( + &self, + py: pyo3::Python<'p>, + ) -> pyo3::PyResult> { + Ok(self + .cached_issuer_name_hash + .get_or_try_init(py, || -> pyo3::PyResult> { + Ok( + pyo3::types::PyBytes::new(py, self.cert_id().issuer_name_hash) + .into_any() + .unbind(), + ) + })? + .bind(py) + .clone()) } #[getter] From 65abd9ecbe7ae63e1b73e16014a49443b27e46a6 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 8 Mar 2026 14:47:06 +0200 Subject: [PATCH 2/4] x509/ocsp_req: cache issuer_key_hash getter result Store the Python bytes object in a PyOnceLock so that repeated accesses return the same object without re-traversing the ASN.1 structure. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Alexander Bokovoy --- src/rust/src/x509/ocsp_req.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 0c4031adaa12..fba4cb4e8f29 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -45,6 +45,7 @@ pub(crate) fn load_der_ocsp_request( raw, cached_extensions: pyo3::sync::PyOnceLock::new(), cached_issuer_name_hash: pyo3::sync::PyOnceLock::new(), + cached_issuer_key_hash: pyo3::sync::PyOnceLock::new(), }) } @@ -54,6 +55,7 @@ pub(crate) struct OCSPRequest { cached_extensions: pyo3::sync::PyOnceLock>, cached_issuer_name_hash: pyo3::sync::PyOnceLock>, + cached_issuer_key_hash: pyo3::sync::PyOnceLock>, } impl OCSPRequest { @@ -91,8 +93,21 @@ impl OCSPRequest { } #[getter] - fn issuer_key_hash(&self) -> &[u8] { - self.cert_id().issuer_key_hash + fn issuer_key_hash<'p>( + &self, + py: pyo3::Python<'p>, + ) -> pyo3::PyResult> { + Ok(self + .cached_issuer_key_hash + .get_or_try_init(py, || -> pyo3::PyResult> { + Ok( + pyo3::types::PyBytes::new(py, self.cert_id().issuer_key_hash) + .into_any() + .unbind(), + ) + })? + .bind(py) + .clone()) } #[getter] From 9828ab9ce91977dbf8350b448526702a0a426a06 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 8 Mar 2026 14:47:49 +0200 Subject: [PATCH 3/4] x509/ocsp_req: cache hash_algorithm getter result Store the computed hash-algorithm object in a PyOnceLock so that repeated accesses avoid re-traversing the ASN.1 structure and re-constructing the Python hash object. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Alexander Bokovoy --- src/rust/src/x509/ocsp_req.rs | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index fba4cb4e8f29..9a5774367d85 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -46,6 +46,7 @@ pub(crate) fn load_der_ocsp_request( cached_extensions: pyo3::sync::PyOnceLock::new(), cached_issuer_name_hash: pyo3::sync::PyOnceLock::new(), cached_issuer_key_hash: pyo3::sync::PyOnceLock::new(), + cached_hash_algorithm: pyo3::sync::PyOnceLock::new(), }) } @@ -56,6 +57,7 @@ pub(crate) struct OCSPRequest { cached_extensions: pyo3::sync::PyOnceLock>, cached_issuer_name_hash: pyo3::sync::PyOnceLock>, cached_issuer_key_hash: pyo3::sync::PyOnceLock>, + cached_hash_algorithm: pyo3::sync::PyOnceLock>, } impl OCSPRequest { @@ -115,17 +117,26 @@ impl OCSPRequest { &self, py: pyo3::Python<'p>, ) -> Result, CryptographyError> { - let cert_id = self.cert_id(); - - match ocsp::ALGORITHM_PARAMETERS_TO_HASH.get(&cert_id.hash_algorithm.params) { - Some(alg_name) => Ok(types::HASHES_MODULE.get(py)?.getattr(*alg_name)?.call0()?), - None => Err(CryptographyError::from( - exceptions::UnsupportedAlgorithm::new_err(format!( - "Signature algorithm OID: {} not recognized", - cert_id.hash_algorithm.oid() - )), - )), - } + Ok(self + .cached_hash_algorithm + .get_or_try_init(py, || { + let cert_id = self.cert_id(); + match ocsp::ALGORITHM_PARAMETERS_TO_HASH.get(&cert_id.hash_algorithm.params) { + Some(alg_name) => Ok(types::HASHES_MODULE + .get(py)? + .getattr(*alg_name)? + .call0()? + .unbind()), + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + cert_id.hash_algorithm.oid() + )), + )), + } + })? + .bind(py) + .clone()) } #[getter] From 2a7e8461f6cafc71383943e910a582dd36e7f982 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 8 Mar 2026 14:48:38 +0200 Subject: [PATCH 4/4] x509/ocsp_req: cache serial_number getter result Store the Python integer in a PyOnceLock so that repeated accesses avoid re-parsing the ASN.1 integer bytes. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Alexander Bokovoy --- src/rust/src/x509/ocsp_req.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 9a5774367d85..d4a410749ef1 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -47,6 +47,7 @@ pub(crate) fn load_der_ocsp_request( cached_issuer_name_hash: pyo3::sync::PyOnceLock::new(), cached_issuer_key_hash: pyo3::sync::PyOnceLock::new(), cached_hash_algorithm: pyo3::sync::PyOnceLock::new(), + cached_serial_number: pyo3::sync::PyOnceLock::new(), }) } @@ -58,6 +59,7 @@ pub(crate) struct OCSPRequest { cached_issuer_name_hash: pyo3::sync::PyOnceLock>, cached_issuer_key_hash: pyo3::sync::PyOnceLock>, cached_hash_algorithm: pyo3::sync::PyOnceLock>, + cached_serial_number: pyo3::sync::PyOnceLock>, } impl OCSPRequest { @@ -144,8 +146,19 @@ impl OCSPRequest { &self, py: pyo3::Python<'p>, ) -> Result, CryptographyError> { - let bytes = self.cert_id().serial_number.as_bytes(); - Ok(big_byte_slice_to_py_int(py, bytes)?) + Ok(self + .cached_serial_number + .get_or_try_init( + py, + || -> Result, CryptographyError> { + Ok( + big_byte_slice_to_py_int(py, self.cert_id().serial_number.as_bytes())? + .unbind(), + ) + }, + )? + .bind(py) + .clone()) } #[getter]