diff --git a/src/rust/cryptography-keepalive/src/lib.rs b/src/rust/cryptography-keepalive/src/lib.rs index b367687912e2..6c45cf9e81ee 100644 --- a/src/rust/cryptography-keepalive/src/lib.rs +++ b/src/rust/cryptography-keepalive/src/lib.rs @@ -4,7 +4,7 @@ #![deny(rust_2018_idioms, clippy::undocumented_unsafe_blocks)] -use pyo3::pybacked::PyBackedBytes; +use pyo3::pybacked::{PyBackedBytes, PyBackedStr}; use std::cell::UnsafeCell; use std::ops::Deref; @@ -24,6 +24,10 @@ unsafe impl StableDeref for Vec {} // Python are immutable. unsafe impl StableDeref for PyBackedBytes {} +// SAFETY: `PyBackedStr`'s data is on the heap and `str` objects in +// Python are immutable. +unsafe impl StableDeref for PyBackedStr {} + #[allow(clippy::new_without_default)] impl KeepAlive { pub fn new() -> Self { diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 8442587b407f..e0bb14f0f3c5 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -129,7 +129,8 @@ fn sign_and_serialize<'p>( .map(|p| p.raw.borrow_dependent()) .collect::>(); - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_vec = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); for (cert, py_private_key, py_hash_alg, rsa_padding) in py_signers.iter() { let (authenticated_attrs, signature) = if options.contains(&types::PKCS7_NO_ATTRIBUTES.get(py)?)? { @@ -159,7 +160,7 @@ fn sign_and_serialize<'p>( }, ]; - let digest = ka.add(asn1::write_single(&x509::ocsp::hash_data( + let digest = ka_vec.add(asn1::write_single(&x509::ocsp::hash_data( py, py_hash_alg, &data_with_header, @@ -221,7 +222,7 @@ fn sign_and_serialize<'p>( py_hash_alg.clone(), rsa_padding.clone(), )?, - encrypted_digest: signature, + encrypted_digest: ka_bytes.add(signature), unauthenticated_attributes: None, }); } diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 388448133d71..c8a2ac8b4d2f 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -953,7 +953,7 @@ fn create_x509_certificate( let data = asn1::write_single(&cryptography_x509::certificate::Certificate { tbs_cert, signature_alg: sigalg, - signature: asn1::BitString::new(signature, 0).unwrap(), + signature: asn1::BitString::new(&signature, 0).unwrap(), })?; load_der_x509_certificate( py, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 125f67792784..4484efee87bf 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -712,7 +712,7 @@ fn create_x509_crl( let data = asn1::write_single(&crl::CertificateRevocationList { tbs_cert_list, signature_algorithm: sigalg, - signature_value: asn1::BitString::new(signature, 0).unwrap(), + signature_value: asn1::BitString::new(&signature, 0).unwrap(), })?; load_der_x509_crl( py, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 789004a60bb9..1aab9d3a6b96 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -374,7 +374,7 @@ fn create_x509_csr( let data = asn1::write_single(&Csr { csr_info, signature_alg: sigalg, - signature: asn1::BitString::new(signature, 0).unwrap(), + signature: asn1::BitString::new(&signature, 0).unwrap(), })?; load_der_x509_csr( py, diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 929f17ce3575..6d1137c34c56 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -9,6 +9,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509::{certificate, sct}; use crate::{types, x509}; use pyo3::prelude::PyAnyMethods; +use pyo3::pybacked::PyBackedStr; fn encode_general_subtrees<'a>( py: pyo3::Python<'a>, @@ -216,7 +217,8 @@ fn encode_certificate_policies( ext: &pyo3::Bound<'_, pyo3::PyAny>, ) -> CryptographyResult> { let mut policy_informations = vec![]; - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); for py_policy_info in ext.iter()? { let py_policy_info = py_policy_info?; let py_policy_qualifiers = @@ -226,7 +228,8 @@ fn encode_certificate_policies( for py_qualifier in py_policy_qualifiers.iter()? { let py_qualifier = py_qualifier?; let qualifier = if py_qualifier.is_instance_of::() { - let cps_uri = match asn1::IA5String::new(py_qualifier.extract()?) { + let py_qualifier_str = ka_str.add(py_qualifier.extract::()?); + let cps_uri = match asn1::IA5String::new(py_qualifier_str) { Some(s) => s, None => { return Err(pyo3::exceptions::PyValueError::new_err( @@ -247,18 +250,18 @@ fn encode_certificate_policies( .getattr(pyo3::intern!(py, "notice_numbers"))? .iter()? { - let bytes = - ka.add(py_uint_to_big_endian_bytes(ext.py(), py_num?.extract()?)?); + let bytes = ka_bytes + .add(py_uint_to_big_endian_bytes(ext.py(), py_num?.extract()?)?); notice_numbers.push(asn1::BigUint::new(bytes).unwrap()); } - + let py_notice_str = ka_str.add( + py_notice + .getattr(pyo3::intern!(py, "organization"))? + .extract::()?, + ); Some(extensions::NoticeReference { organization: extensions::DisplayText::Utf8String( - asn1::Utf8String::new( - py_notice - .getattr(pyo3::intern!(py, "organization"))? - .extract()?, - ), + asn1::Utf8String::new(py_notice_str), ), notice_numbers: common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(notice_numbers), @@ -270,8 +273,10 @@ fn encode_certificate_policies( let py_explicit_text = py_qualifier.getattr(pyo3::intern!(py, "explicit_text"))?; let explicit_text = if py_explicit_text.is_truthy()? { + let py_explicit_text_str = + ka_str.add(py_explicit_text.extract::()?); Some(extensions::DisplayText::Utf8String(asn1::Utf8String::new( - py_explicit_text.extract()?, + py_explicit_text_str, ))) } else { None diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index e27c5d583afa..4ec133a8e038 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -754,7 +754,7 @@ fn create_ocsp_response( let basic_resp = ocsp_resp::BasicOCSPResponse { tbs_response_data, - signature: asn1::BitString::new(signature, 0).unwrap(), + signature: asn1::BitString::new(&signature, 0).unwrap(), signature_algorithm: sigalg, certs, }; diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 9483a06e5034..b0acbfa39763 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -7,6 +7,7 @@ use std::collections::HashMap; use cryptography_x509::{common, oid}; use once_cell::sync::Lazy; use pyo3::prelude::PyAnyMethods; +use pyo3::pybacked::PyBackedBytes; use crate::asn1::oid_to_py_oid; use crate::error::{CryptographyError, CryptographyResult}; @@ -285,7 +286,7 @@ pub(crate) fn sign_data<'p>( hash_algorithm: pyo3::Bound<'p, pyo3::PyAny>, rsa_padding: pyo3::Bound<'p, pyo3::PyAny>, data: &[u8], -) -> pyo3::PyResult<&'p [u8]> { +) -> pyo3::PyResult { let key_type = identify_key_type(py, private_key.clone())?; let signature = match key_type {