Skip to content

Commit

Permalink
Introduce a keepalive abstraction (#10764)
Browse files Browse the repository at this point in the history
This effectively emulates what pyo3's old GIL pool was doing, but we'll use it in a far more targetted manner.
  • Loading branch information
alex authored Apr 12, 2024
1 parent 1d04970 commit 0acc56b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cfg-if = "1"
pyo3 = { version = "0.21.1", features = ["abi3", "gil-refs"] }
asn1 = { version = "0.16.1", default-features = false }
cryptography-cffi = { path = "cryptography-cffi" }
cryptography-keepalive = { path = "cryptography-keepalive" }
cryptography-key-parsing = { path = "cryptography-key-parsing" }
cryptography-x509 = { path = "cryptography-x509" }
cryptography-x509-verification = { path = "cryptography-x509-verification" }
Expand All @@ -37,6 +38,7 @@ overflow-checks = true
[workspace]
members = [
"cryptography-cffi",
"cryptography-keepalive",
"cryptography-key-parsing",
"cryptography-openssl",
"cryptography-x509",
Expand Down
10 changes: 10 additions & 0 deletions src/rust/cryptography-keepalive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "cryptography-keepalive"
version = "0.1.0"
authors = ["The cryptography developers <cryptography-dev@python.org>"]
edition = "2021"
publish = false
# This specifies the MSRV
rust-version = "1.65.0"

[dependencies]
40 changes: 40 additions & 0 deletions src/rust/cryptography-keepalive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This file is dual licensed under the terms of the Apache License, Version
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

#![deny(rust_2018_idioms, clippy::undocumented_unsafe_blocks)]

use std::cell::UnsafeCell;
use std::ops::Deref;

pub struct KeepAlive<T: StableDeref> {
values: UnsafeCell<Vec<T>>,
}

/// # Safety
/// Implementors of this trait must ensure that the value returned by
/// `deref()` must remain valid, even if `self` is moved.
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> {}

#[allow(clippy::new_without_default)]
impl<T: StableDeref> KeepAlive<T> {
pub fn new() -> Self {
KeepAlive {
values: UnsafeCell::new(vec![]),
}
}

pub fn add(&self, v: T) -> &T::Target {
// SAFETY: We only ever append to `self.values`, which, when combined
// with the invariants of `StableDeref`, means that the result of
// `deref()` will always be valid for the lifetime of `&self`.
unsafe {
let values = &mut *self.values.get();
values.push(v);
values.last().unwrap().deref()
}
}
}
18 changes: 8 additions & 10 deletions src/rust/src/pkcs7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,8 @@ fn sign_and_serialize<'p>(
.map(|p| p.raw.borrow_dependent())
.collect::<Vec<_>>();

let mut digests = vec![];
if !options.contains(&types::PKCS7_NO_ATTRIBUTES.get_bound(py)?)? {
for (_, _, py_hash_alg, _) in &py_signers {
let digest =
asn1::write_single(&x509::ocsp::hash_data(py, py_hash_alg, &data_with_header)?)?;
digests.push(digest);
}
}
for (i, (cert, py_private_key, py_hash_alg, rsa_padding)) in py_signers.iter().enumerate() {
let ka = 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_bound(py)?)? {
(
Expand Down Expand Up @@ -166,10 +159,15 @@ fn sign_and_serialize<'p>(
},
];

let digest = ka.add(asn1::write_single(&x509::ocsp::hash_data(
py,
py_hash_alg,
&data_with_header,
)?)?);
authenticated_attrs.push(Attribute {
type_id: PKCS7_MESSAGE_DIGEST_OID,
values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([
asn1::parse_single(&digests[i]).unwrap(),
asn1::parse_single(digest).unwrap(),
])),
});

Expand Down

0 comments on commit 0acc56b

Please sign in to comment.