Skip to content

Commit

Permalink
Fixed two lifetime errors in common.rs with gil-refs disabled (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Apr 14, 2024
1 parent f61fc10 commit 0fb841d
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 46 deletions.
2 changes: 0 additions & 2 deletions src/rust/cryptography-keepalive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ pub unsafe trait StableDeref: Deref {}
// SAFETY: `Vec`'s data is on the heap, so as long as it's not mutated, the
// slice returned by `deref` remains valid.
unsafe impl<T> StableDeref for Vec<T> {}

// SAFETY: `PyBackedBytes`'s data is on the heap and `bytes` objects in
// 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 {}
Expand Down
7 changes: 5 additions & 2 deletions src/rust/src/x509/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -922,19 +922,22 @@ fn create_x509_certificate(
let ka_bytes = cryptography_keepalive::KeepAlive::new();

let serial_bytes = py_uint_to_big_endian_bytes(py, py_serial)?;

let ka = cryptography_keepalive::KeepAlive::new();

let tbs_cert = cryptography_x509::certificate::TbsCertificate {
version: builder
.getattr(pyo3::intern!(py, "_version"))?
.getattr(pyo3::intern!(py, "value"))?
.extract()?,
serial: asn1::BigInt::new(&serial_bytes).unwrap(),
signature_alg: sigalg.clone(),
issuer: x509::common::encode_name(py, &py_issuer_name)?,
issuer: x509::common::encode_name(py, &ka, &py_issuer_name)?,
validity: cryptography_x509::certificate::Validity {
not_before: time_from_py(py, &py_not_before)?,
not_after: time_from_py(py, &py_not_after)?,
},
subject: x509::common::encode_name(py, &py_subject_name)?,
subject: x509::common::encode_name(py, &ka, &py_subject_name)?,
spki: asn1::parse_single(&spki_bytes)?,
issuer_unique_id: None,
subject_unique_id: None,
Expand Down
63 changes: 35 additions & 28 deletions src/rust/src/x509/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ pub(crate) fn find_in_pem(
}

pub(crate) fn encode_name<'p>(
py: pyo3::Python<'p>,
py_name: &pyo3::Bound<'p, pyo3::PyAny>,
py: pyo3::Python<'_>,
ka: &'p cryptography_keepalive::KeepAlive<pyo3::pybacked::PyBackedBytes>,
py_name: &pyo3::Bound<'_, pyo3::PyAny>,
) -> pyo3::PyResult<Name<'p>> {
let mut rdns = vec![];

Expand All @@ -42,7 +43,7 @@ pub(crate) fn encode_name<'p>(
let mut attrs = vec![];

for py_attr in py_rdn.iter()? {
attrs.push(encode_name_entry(py, &py_attr?)?);
attrs.push(encode_name_entry(py, ka, &py_attr?)?);
}
rdns.push(asn1::SetOfWriter::new(attrs));
}
Expand All @@ -52,36 +53,38 @@ pub(crate) fn encode_name<'p>(
}

pub(crate) fn encode_name_entry<'p>(
py: pyo3::Python<'p>,
py_name_entry: &pyo3::Bound<'p, pyo3::PyAny>,
py: pyo3::Python<'_>,
ka: &'p cryptography_keepalive::KeepAlive<pyo3::pybacked::PyBackedBytes>,
py_name_entry: &pyo3::Bound<'_, pyo3::PyAny>,
) -> CryptographyResult<AttributeTypeValue<'p>> {
let attr_type = py_name_entry.getattr(pyo3::intern!(py, "_type"))?;
let tag = attr_type
.getattr(pyo3::intern!(py, "value"))?
.extract::<u8>()?;
let value: &[u8] = if !attr_type.is(&types::ASN1_TYPE_BIT_STRING.get(py)?) {
let encoding = if attr_type.is(&types::ASN1_TYPE_BMP_STRING.get(py)?) {
"utf_16_be"
} else if attr_type.is(&types::ASN1_TYPE_UNIVERSAL_STRING.get(py)?) {
"utf_32_be"
let value: pyo3::pybacked::PyBackedBytes =
if !attr_type.is(&types::ASN1_TYPE_BIT_STRING.get(py)?) {
let encoding = if attr_type.is(&types::ASN1_TYPE_BMP_STRING.get(py)?) {
"utf_16_be"
} else if attr_type.is(&types::ASN1_TYPE_UNIVERSAL_STRING.get(py)?) {
"utf_32_be"
} else {
"utf8"
};
py_name_entry
.getattr(pyo3::intern!(py, "value"))?
.call_method1(pyo3::intern!(py, "encode"), (encoding,))?
.extract()?
} else {
"utf8"
py_name_entry
.getattr(pyo3::intern!(py, "value"))?
.extract()?
};
py_name_entry
.getattr(pyo3::intern!(py, "value"))?
.call_method1(pyo3::intern!(py, "encode"), (encoding,))?
.extract()?
} else {
py_name_entry
.getattr(pyo3::intern!(py, "value"))?
.extract()?
};
let py_oid = py_name_entry.getattr(pyo3::intern!(py, "oid"))?;
let oid = py_oid_to_oid(py_oid)?;

Ok(AttributeTypeValue {
type_id: oid,
value: RawTlv::new(asn1::Tag::from_bytes(&[tag])?.0, value),
value: RawTlv::new(asn1::Tag::from_bytes(&[tag])?.0, ka.add(value)),
})
}

Expand All @@ -90,25 +93,28 @@ fn encode_name_bytes<'p>(
py: pyo3::Python<'p>,
py_name: &pyo3::Bound<'p, pyo3::PyAny>,
) -> CryptographyResult<pyo3::Bound<'p, pyo3::types::PyBytes>> {
let name = encode_name(py, py_name)?;
let ka = cryptography_keepalive::KeepAlive::new();
let name = encode_name(py, &ka, py_name)?;
let result = asn1::write_single(&name)?;
Ok(pyo3::types::PyBytes::new_bound(py, &result))
}

pub(crate) fn encode_general_names<'a>(
py: pyo3::Python<'a>,
py: pyo3::Python<'_>,
ka: &'a cryptography_keepalive::KeepAlive<pyo3::pybacked::PyBackedBytes>,
py_gns: &pyo3::Bound<'a, pyo3::PyAny>,
) -> Result<Vec<GeneralName<'a>>, CryptographyError> {
let mut gns = vec![];
for el in py_gns.iter()? {
let gn = encode_general_name(py, &el?)?;
let gn = encode_general_name(py, ka, &el?)?;
gns.push(gn);
}
Ok(gns)
}

pub(crate) fn encode_general_name<'a>(
py: pyo3::Python<'a>,
py: pyo3::Python<'_>,
ka: &'a cryptography_keepalive::KeepAlive<pyo3::pybacked::PyBackedBytes>,
gn: &pyo3::Bound<'a, pyo3::PyAny>,
) -> Result<GeneralName<'a>, CryptographyError> {
let gn_type = gn.get_type();
Expand All @@ -123,7 +129,7 @@ pub(crate) fn encode_general_name<'a>(
gn_value.extract::<&str>()?,
)))
} else if gn_type.is(&types::DIRECTORY_NAME.get(py)?) {
let name = encode_name(py, &gn_value)?;
let name = encode_name(py, ka, &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"))?;
Expand Down Expand Up @@ -159,12 +165,13 @@ pub(crate) fn encode_access_descriptions<'a>(
py_ads: &pyo3::Bound<'a, pyo3::PyAny>,
) -> CryptographyResult<Vec<u8>> {
let mut ads = vec![];
let ka = 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 access_location =
encode_general_name(py, &py_ad.getattr(pyo3::intern!(py, "access_location"))?)?;
let py_access_location = py_ad.getattr(pyo3::intern!(py, "access_location"))?;
let access_location = encode_general_name(py, &ka, &py_access_location)?;
ads.push(AccessDescription {
access_method,
access_location,
Expand Down
4 changes: 3 additions & 1 deletion src/rust/src/x509/crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,13 +681,15 @@ fn create_x509_crl(
});
}

let ka = cryptography_keepalive::KeepAlive::new();

let py_issuer_name = builder.getattr(pyo3::intern!(py, "_issuer_name"))?;
let py_this_update = builder.getattr(pyo3::intern!(py, "_last_update"))?;
let py_next_update = builder.getattr(pyo3::intern!(py, "_next_update"))?;
let tbs_cert_list = crl::TBSCertList {
version: Some(1),
signature: sigalg.clone(),
issuer: x509::common::encode_name(py, &py_issuer_name)?,
issuer: x509::common::encode_name(py, &ka, &py_issuer_name)?,
this_update: x509::certificate::time_from_py(py, &py_this_update)?,
next_update: Some(x509::certificate::time_from_py(py, &py_next_update)?),
revoked_certificates: if revoked_certs.is_empty() {
Expand Down
4 changes: 3 additions & 1 deletion src/rust/src/x509/csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,11 @@ fn create_x509_csr(

let py_subject_name = builder.getattr(pyo3::intern!(py, "_subject_name"))?;

let ka = cryptography_keepalive::KeepAlive::new();

let csr_info = CertificationRequestInfo {
version: 0,
subject: x509::common::encode_name(py, &py_subject_name)?,
subject: x509::common::encode_name(py, &ka, &py_subject_name)?,
spki: asn1::parse_single(&spki_bytes)?,
attributes: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(attrs)),
};
Expand Down
35 changes: 23 additions & 12 deletions src/rust/src/x509/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ use pyo3::prelude::PyAnyMethods;
use pyo3::pybacked::PyBackedStr;

fn encode_general_subtrees<'a>(
py: pyo3::Python<'a>,
py: pyo3::Python<'_>,
ka: &'a cryptography_keepalive::KeepAlive<pyo3::pybacked::PyBackedBytes>,
subtrees: &pyo3::Bound<'a, pyo3::PyAny>,
) -> Result<Option<extensions::SequenceOfSubtrees<'a>>, CryptographyError> {
if subtrees.is_none() {
Ok(None)
} else {
let mut subtree_seq = vec![];
for name in subtrees.iter()? {
let gn = x509::common::encode_general_name(py, &name?)?;
let gn = x509::common::encode_general_name(py, ka, &name?)?;
subtree_seq.push(extensions::GeneralSubtree {
base: gn,
minimum: 0,
Expand All @@ -44,8 +45,10 @@ pub(crate) fn encode_authority_key_identifier<'a>(
authority_cert_serial_number: Option<pyo3::Bound<'a, pyo3::types::PyLong>>,
}
let aki = py_aki.extract::<PyAuthorityKeyIdentifier<'_>>()?;

let ka = 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, &authority_cert_issuer)?;
let gns = x509::common::encode_general_names(py, &ka, &authority_cert_issuer)?;
Some(common::Asn1ReadableOrWritable::new_write(
asn1::SequenceOfWriter::new(gns),
))
Expand Down Expand Up @@ -79,27 +82,28 @@ pub(crate) fn encode_distribution_points<'p>(
reasons: Option<pyo3::Bound<'a, pyo3::PyAny>>,
}

let ka = cryptography_keepalive::KeepAlive::new();
let mut dps = vec![];
for py_dp in py_dps.iter()? {
let py_dp = py_dp?.extract::<PyDistributionPoint<'_>>()?;

let crl_issuer = if let Some(py_crl_issuer) = py_dp.crl_issuer {
let gns = x509::common::encode_general_names(py, &py_crl_issuer)?;
let gns = x509::common::encode_general_names(py, &ka, &py_crl_issuer)?;
Some(common::Asn1ReadableOrWritable::new_write(
asn1::SequenceOfWriter::new(gns),
))
} else {
None
};
let distribution_point = if let Some(py_full_name) = py_dp.full_name {
let gns = x509::common::encode_general_names(py, &py_full_name)?;
let gns = x509::common::encode_general_names(py, &ka, &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, &py_name_entry?)?);
name_entries.push(x509::common::encode_name_entry(py, &ka, &py_name_entry?)?);
}
Some(extensions::DistributionPointName::NameRelativeToCRLIssuer(
common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)),
Expand Down Expand Up @@ -313,6 +317,8 @@ fn encode_issuing_distribution_point(
py: pyo3::Python<'_>,
ext: &pyo3::Bound<'_, pyo3::PyAny>,
) -> CryptographyResult<Vec<u8>> {
let ka = cryptography_keepalive::KeepAlive::new();

let only_some_reasons = if ext
.getattr(pyo3::intern!(py, "only_some_reasons"))?
.is_truthy()?
Expand All @@ -325,7 +331,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(), &py_full_name)?;
let gns = x509::common::encode_general_names(ext.py(), &ka, &py_full_name)?;
Some(extensions::DistributionPointName::FullName(
common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)),
))
Expand All @@ -335,7 +341,8 @@ fn encode_issuing_distribution_point(
{
let mut name_entries = vec![];
for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? {
name_entries.push(x509::common::encode_name_entry(ext.py(), &py_name_entry?)?);
let name_entry = x509::common::encode_name_entry(ext.py(), &ka, &py_name_entry?)?;
name_entries.push(name_entry);
}
Some(extensions::DistributionPointName::NameRelativeToCRLIssuer(
common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)),
Expand Down Expand Up @@ -447,11 +454,13 @@ pub(crate) fn encode_extension(
Ok(Some(asn1::write_single(&pc)?))
}
&oid::NAME_CONSTRAINTS_OID => {
let ka = 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(), &permitted)?,
excluded_subtrees: encode_general_subtrees(ext.py(), &excluded)?,
permitted_subtrees: encode_general_subtrees(ext.py(), &ka, &permitted)?,
excluded_subtrees: encode_general_subtrees(ext.py(), &ka, &excluded)?,
};
Ok(Some(asn1::write_single(&nc)?))
}
Expand All @@ -466,7 +475,8 @@ pub(crate) fn encode_extension(
)?))
}
&oid::ISSUER_ALTERNATIVE_NAME_OID | &oid::SUBJECT_ALTERNATIVE_NAME_OID => {
let gns = x509::common::encode_general_names(ext.py(), ext)?;
let ka = cryptography_keepalive::KeepAlive::new();
let gns = x509::common::encode_general_names(ext.py(), &ka, ext)?;
Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?))
}
&oid::AUTHORITY_KEY_IDENTIFIER_OID => {
Expand Down Expand Up @@ -496,7 +506,8 @@ pub(crate) fn encode_extension(
Ok(Some(asn1::write_single(&asn1::Enumerated::new(value))?))
}
&oid::CERTIFICATE_ISSUER_OID => {
let gns = x509::common::encode_general_names(ext.py(), ext)?;
let ka = cryptography_keepalive::KeepAlive::new();
let gns = x509::common::encode_general_names(ext.py(), &ka, ext)?;
Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?))
}
&oid::INVALIDITY_DATE_OID => {
Expand Down

0 comments on commit 0fb841d

Please sign in to comment.