mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
Introduce a keepalive abstraction (#10764)
This effectively emulates what pyo3's old GIL pool was doing, but we'll use it in a far more targetted manner.
This commit is contained in:
parent
1d04970f37
commit
0acc56b7d4
5 changed files with 65 additions and 10 deletions
5
src/rust/Cargo.lock
generated
5
src/rust/Cargo.lock
generated
|
|
@ -67,6 +67,10 @@ dependencies = [
|
|||
"pyo3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography-keepalive"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "cryptography-key-parsing"
|
||||
version = "0.1.0"
|
||||
|
|
@ -96,6 +100,7 @@ dependencies = [
|
|||
"asn1",
|
||||
"cfg-if",
|
||||
"cryptography-cffi",
|
||||
"cryptography-keepalive",
|
||||
"cryptography-key-parsing",
|
||||
"cryptography-openssl",
|
||||
"cryptography-x509",
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
@ -37,6 +38,7 @@ overflow-checks = true
|
|||
[workspace]
|
||||
members = [
|
||||
"cryptography-cffi",
|
||||
"cryptography-keepalive",
|
||||
"cryptography-key-parsing",
|
||||
"cryptography-openssl",
|
||||
"cryptography-x509",
|
||||
|
|
|
|||
10
src/rust/cryptography-keepalive/Cargo.toml
Normal file
10
src/rust/cryptography-keepalive/Cargo.toml
Normal file
|
|
@ -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
src/rust/cryptography-keepalive/src/lib.rs
Normal file
40
src/rust/cryptography-keepalive/src/lib.rs
Normal file
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)?)? {
|
||||
(
|
||||
|
|
@ -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(),
|
||||
])),
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue