diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index a9229587b1ef8..8fafedd8e1367 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.65.0" [dependencies] once_cell = "1" cfg-if = "1" -pyo3 = { version = "0.21.1", features = ["abi3", "gil-refs"] } +pyo3 = { version = "0.21.1", features = ["abi3"] } asn1 = { version = "0.16.1", default-features = false } cryptography-cffi = { path = "cryptography-cffi" } cryptography-keepalive = { path = "cryptography-keepalive" } diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 548c810a8db86..f33da5c22cf12 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -101,12 +101,13 @@ fn encode_name_bytes<'p>( pub(crate) fn encode_general_names<'a>( py: pyo3::Python<'_>, - ka: &'a cryptography_keepalive::KeepAlive, + ka_bytes: &'a cryptography_keepalive::KeepAlive, + ka_str: &'a cryptography_keepalive::KeepAlive, py_gns: &pyo3::Bound<'a, pyo3::PyAny>, ) -> Result>, CryptographyError> { let mut gns = vec![]; for el in py_gns.iter()? { - let gn = encode_general_name(py, ka, &el?)?; + let gn = encode_general_name(py, ka_bytes, ka_str, &el?)?; gns.push(gn); } Ok(gns) @@ -114,7 +115,8 @@ pub(crate) fn encode_general_names<'a>( pub(crate) fn encode_general_name<'a>( py: pyo3::Python<'_>, - ka: &'a cryptography_keepalive::KeepAlive, + ka_bytes: &'a cryptography_keepalive::KeepAlive, + ka_str: &'a cryptography_keepalive::KeepAlive, gn: &pyo3::Bound<'a, pyo3::PyAny>, ) -> Result, CryptographyError> { let gn_type = gn.get_type(); @@ -122,20 +124,20 @@ pub(crate) fn encode_general_name<'a>( if gn_type.is(&types::DNS_NAME.get(py)?) { Ok(GeneralName::DNSName(UnvalidatedIA5String( - gn_value.extract::<&str>()?, + ka_str.add(gn_value.extract()?), ))) } else if gn_type.is(&types::RFC822_NAME.get(py)?) { Ok(GeneralName::RFC822Name(UnvalidatedIA5String( - gn_value.extract::<&str>()?, + ka_str.add(gn_value.extract()?), ))) } else if gn_type.is(&types::DIRECTORY_NAME.get(py)?) { - let name = encode_name(py, ka, &gn_value)?; + let name = encode_name(py, ka_bytes, &gn_value)?; Ok(GeneralName::DirectoryName(name)) } else if gn_type.is(&types::OTHER_NAME.get(py)?) { let py_oid = gn.getattr(pyo3::intern!(py, "type_id"))?; Ok(GeneralName::OtherName(OtherName { type_id: py_oid_to_oid(py_oid)?, - value: asn1::parse_single(gn_value.extract::<&[u8]>()?).map_err(|e| { + value: asn1::parse_single(ka_bytes.add(gn_value.extract()?)).map_err(|e| { pyo3::exceptions::PyValueError::new_err(format!( "OtherName value must be valid DER: {e:?}" )) @@ -143,13 +145,12 @@ pub(crate) fn encode_general_name<'a>( })) } else if gn_type.is(&types::UNIFORM_RESOURCE_IDENTIFIER.get(py)?) { Ok(GeneralName::UniformResourceIdentifier( - UnvalidatedIA5String(gn_value.extract::<&str>()?), + UnvalidatedIA5String(ka_str.add(gn_value.extract()?)), )) } else if gn_type.is(&types::IP_ADDRESS.get(py)?) { - Ok(GeneralName::IPAddress( - gn.call_method0(pyo3::intern!(py, "_packed"))? - .extract::<&[u8]>()?, - )) + Ok(GeneralName::IPAddress(ka_bytes.add( + gn.call_method0(pyo3::intern!(py, "_packed"))?.extract()?, + ))) } else if gn_type.is(&types::REGISTERED_ID.get(py)?) { let oid = py_oid_to_oid(gn_value)?; Ok(GeneralName::RegisteredID(oid)) @@ -165,13 +166,14 @@ pub(crate) fn encode_access_descriptions<'a>( py_ads: &pyo3::Bound<'a, pyo3::PyAny>, ) -> CryptographyResult> { let mut ads = vec![]; - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); for py_ad in py_ads.iter()? { let py_ad = py_ad?; let py_oid = py_ad.getattr(pyo3::intern!(py, "access_method"))?; let access_method = py_oid_to_oid(py_oid)?; let py_access_location = py_ad.getattr(pyo3::intern!(py, "access_location"))?; - let access_location = encode_general_name(py, &ka, &py_access_location)?; + let access_location = encode_general_name(py, &ka_bytes, &ka_str, &py_access_location)?; ads.push(AccessDescription { access_method, access_location, diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index ab5f6d06b8475..8a54b49f39e26 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -13,7 +13,8 @@ use pyo3::pybacked::PyBackedStr; fn encode_general_subtrees<'a>( py: pyo3::Python<'_>, - ka: &'a cryptography_keepalive::KeepAlive, + ka_bytes: &'a cryptography_keepalive::KeepAlive, + ka_str: &'a cryptography_keepalive::KeepAlive, subtrees: &pyo3::Bound<'a, pyo3::PyAny>, ) -> Result>, CryptographyError> { if subtrees.is_none() { @@ -21,7 +22,7 @@ fn encode_general_subtrees<'a>( } else { let mut subtree_seq = vec![]; for name in subtrees.iter()? { - let gn = x509::common::encode_general_name(py, ka, &name?)?; + let gn = x509::common::encode_general_name(py, ka_bytes, ka_str, &name?)?; subtree_seq.push(extensions::GeneralSubtree { base: gn, minimum: 0, @@ -46,9 +47,11 @@ pub(crate) fn encode_authority_key_identifier<'a>( } let aki = py_aki.extract::>()?; - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); let authority_cert_issuer = if let Some(authority_cert_issuer) = aki.authority_cert_issuer { - let gns = x509::common::encode_general_names(py, &ka, &authority_cert_issuer)?; + let gns = + x509::common::encode_general_names(py, &ka_bytes, &ka_str, &authority_cert_issuer)?; Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(gns), )) @@ -82,13 +85,14 @@ pub(crate) fn encode_distribution_points<'p>( reasons: Option>, } - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); let mut dps = vec![]; for py_dp in py_dps.iter()? { let py_dp = py_dp?.extract::>()?; let crl_issuer = if let Some(py_crl_issuer) = py_dp.crl_issuer { - let gns = x509::common::encode_general_names(py, &ka, &py_crl_issuer)?; + let gns = x509::common::encode_general_names(py, &ka_bytes, &ka_str, &py_crl_issuer)?; Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(gns), )) @@ -96,14 +100,18 @@ pub(crate) fn encode_distribution_points<'p>( None }; let distribution_point = if let Some(py_full_name) = py_dp.full_name { - let gns = x509::common::encode_general_names(py, &ka, &py_full_name)?; + let gns = x509::common::encode_general_names(py, &ka_bytes, &ka_str, &py_full_name)?; Some(extensions::DistributionPointName::FullName( common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), )) } else if let Some(py_relative_name) = py_dp.relative_name { let mut name_entries = vec![]; for py_name_entry in py_relative_name.iter()? { - name_entries.push(x509::common::encode_name_entry(py, &ka, &py_name_entry?)?); + name_entries.push(x509::common::encode_name_entry( + py, + &ka_bytes, + &py_name_entry?, + )?); } Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), @@ -317,7 +325,8 @@ fn encode_issuing_distribution_point( py: pyo3::Python<'_>, ext: &pyo3::Bound<'_, pyo3::PyAny>, ) -> CryptographyResult> { - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); let only_some_reasons = if ext .getattr(pyo3::intern!(py, "only_some_reasons"))? @@ -331,7 +340,7 @@ fn encode_issuing_distribution_point( }; let distribution_point = if ext.getattr(pyo3::intern!(py, "full_name"))?.is_truthy()? { let py_full_name = ext.getattr(pyo3::intern!(py, "full_name"))?; - let gns = x509::common::encode_general_names(ext.py(), &ka, &py_full_name)?; + let gns = x509::common::encode_general_names(ext.py(), &ka_bytes, &ka_str, &py_full_name)?; Some(extensions::DistributionPointName::FullName( common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), )) @@ -341,7 +350,7 @@ fn encode_issuing_distribution_point( { let mut name_entries = vec![]; for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? { - let name_entry = x509::common::encode_name_entry(ext.py(), &ka, &py_name_entry?)?; + let name_entry = x509::common::encode_name_entry(ext.py(), &ka_bytes, &py_name_entry?)?; name_entries.push(name_entry); } Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( @@ -454,13 +463,24 @@ pub(crate) fn encode_extension( Ok(Some(asn1::write_single(&pc)?)) } &oid::NAME_CONSTRAINTS_OID => { - let ka = cryptography_keepalive::KeepAlive::new(); + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); let permitted = ext.getattr(pyo3::intern!(py, "permitted_subtrees"))?; let excluded = ext.getattr(pyo3::intern!(py, "excluded_subtrees"))?; let nc = extensions::NameConstraints { - permitted_subtrees: encode_general_subtrees(ext.py(), &ka, &permitted)?, - excluded_subtrees: encode_general_subtrees(ext.py(), &ka, &excluded)?, + permitted_subtrees: encode_general_subtrees( + ext.py(), + &ka_bytes, + &ka_str, + &permitted, + )?, + excluded_subtrees: encode_general_subtrees( + ext.py(), + &ka_bytes, + &ka_str, + &excluded, + )?, }; Ok(Some(asn1::write_single(&nc)?)) } @@ -475,8 +495,9 @@ pub(crate) fn encode_extension( )?)) } &oid::ISSUER_ALTERNATIVE_NAME_OID | &oid::SUBJECT_ALTERNATIVE_NAME_OID => { - let ka = cryptography_keepalive::KeepAlive::new(); - let gns = x509::common::encode_general_names(ext.py(), &ka, ext)?; + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); + let gns = x509::common::encode_general_names(ext.py(), &ka_bytes, &ka_str, ext)?; Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?)) } &oid::AUTHORITY_KEY_IDENTIFIER_OID => { @@ -506,8 +527,9 @@ pub(crate) fn encode_extension( Ok(Some(asn1::write_single(&asn1::Enumerated::new(value))?)) } &oid::CERTIFICATE_ISSUER_OID => { - let ka = cryptography_keepalive::KeepAlive::new(); - let gns = x509::common::encode_general_names(ext.py(), &ka, ext)?; + let ka_bytes = cryptography_keepalive::KeepAlive::new(); + let ka_str = cryptography_keepalive::KeepAlive::new(); + let gns = x509::common::encode_general_names(ext.py(), &ka_bytes, &ka_str, ext)?; Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?)) } &oid::INVALIDITY_DATE_OID => {