-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PoC: Make it possible to write code that interacts with OpenSSL in Rust #6695
Conversation
src/rust/build.rs
Outdated
if line.starts_with("cargo:") { | ||
println!("{}", line); | ||
} else if line.starts_with("include:") { | ||
include = line.replace("include:", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking the PYO3_PYTHON
above and this include
from sysconfig
should be obtained from pyo3-build-config
crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds good to me!
I'm having trouble understand why this fails with tox. Does tox have a cli option to ask it not to delete everything after failure? |
Hmm, I don't think tox should be deleting anything, all the files should still be in |
Here is the same error on my local machine, looks like tox put files a in temp dir.
|
Oh no :-/ this isn't tox itself, it's pip's |
I also tried |
I'm very confused by what's happening with |
Ok, this might be because we need |
Ok, this fixes it, it's because of diff --git a/src/rust/build.rs b/src/rust/build.rs
index 60d28131..0dfc2534 100644
--- a/src/rust/build.rs
+++ b/src/rust/build.rs
@@ -6,12 +6,24 @@ fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
// FIXME: maybe pyo3-build-config should provide a way to do this?
let python = env::var("PYO3_PYTHON").unwrap_or("python3".to_string());
+ println!("cargo:rerun-if-changed=../_cffi_src/");
+ let python_path = match env::var("PYTHONPATH") {
+ Ok(mut val) => {
+ val.push_str(":../");
+ val
+ },
+ Err(_) => {
+ "../".to_string()
+ }
+ };
let output = Command::new(&python)
- .env("PYTHONPATH", "../")
+ .env("PYTHONPATH", python_path)
.env("OUT_DIR", &out_dir)
.arg("../_cffi_src/build_openssl.py")
.output()
.expect("failed to execute build_openssl.py");
+ assert!(output.status.success());
+
let stdout = String::from_utf8(output.stdout).unwrap();
let mut include = String::new();
for line in stdout.lines() { |
Right now we specify our OpenSSL with CFLAGS/LDFLAGS, I guess we'll need to update to use |
Some of the test matrix passed, hooray! Debugging unfamiliar CI failure is time consuming, so please feel free to push to my branch to experiment. |
Sent pyca/infra#380 to install pkg-config
which should help on the linux distros.
…On Sun, Dec 12, 2021 at 9:17 PM messense ***@***.***> wrote:
@messense commented on this pull request.
________________________________
In src/rust/src/lib.rs:
> @@ -91,6 +96,11 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()>
crate::x509::ocsp_resp::add_to_module(ocsp_mod)?;
m.add_submodule(ocsp_mod)?;
+ let openssl_mod = unsafe {
+ let ptr = PyInit__openssl();
+ pyo3::types::PyModule::from_owned_ptr(py, ptr)
+ };
+ m.add_submodule(openssl_mod)?;
I can do this after building and testing on CI works. But I'm not sure how to deal with these Python files in https://github.com/pyca/cryptography/tree/main/src/cryptography/hazmat/bindings/openssl
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
--
All that is necessary for evil to succeed is for good people to do nothing.
|
Ok, next build should reflect that.
…On Sun, Dec 12, 2021 at 9:21 PM Alex Gaynor ***@***.***> wrote:
Sent pyca/infra#380 to install pkg-config
which should help on the linux distros.
On Sun, Dec 12, 2021 at 9:17 PM messense ***@***.***> wrote:
>
> @messense commented on this pull request.
>
> ________________________________
>
> In src/rust/src/lib.rs:
>
> > @@ -91,6 +96,11 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()>
> crate::x509::ocsp_resp::add_to_module(ocsp_mod)?;
> m.add_submodule(ocsp_mod)?;
>
> + let openssl_mod = unsafe {
> + let ptr = PyInit__openssl();
> + pyo3::types::PyModule::from_owned_ptr(py, ptr)
> + };
> + m.add_submodule(openssl_mod)?;
>
> I can do this after building and testing on CI works. But I'm not sure how to deal with these Python files in https://github.com/pyca/cryptography/tree/main/src/cryptography/hazmat/bindings/openssl
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub, or unsubscribe.
> Triage notifications on the go with GitHub Mobile for iOS or Android.
--
All that is necessary for evil to succeed is for good people to do nothing.
--
All that is necessary for evil to succeed is for good people to do nothing.
|
ff8663b
to
0db7bf6
Compare
Where can I download this |
We don't put them anywhere, they're just built ephemerally in CI. |
Looks like openssl-sys is expecting libs in
|
How fun, putting it in |
Yes OpenSSL switched to using |
Opened sfackler/rust-openssl#1581 |
0447f78
to
11dcf48
Compare
There are two errors I don't quite understand:
|
Could this be that the pre-compiled OpenSSL is built on macOS 11 but we're using it on macOS 10.15? |
This is interesting. root@5b52dbd4d5c2:/io# readelf -s /io/src/cryptography/hazmat/bindings/_rust.pypy38-pp73-aarch64-linux-gnu.so | grep PyInit
11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND PyInit__openssl
148: 0000000000115290 32 FUNC GLOBAL DEFAULT 11 PyInit__rust
52405: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND PyInit__openssl
52520: 0000000000115290 32 FUNC GLOBAL DEFAULT 11 PyInit__rust V.S. the root@5b52dbd4d5c2:/io# readelf -s src/cryptography/hazmat/bindings/_openssl.pypy38-pp73-aarch64-linux-gnu.so | grep PyInit
root@5b52dbd4d5c2:/io# readelf -s src/cryptography/hazmat/bindings/_openssl.pypy38-pp73-aarch64-linux-gnu.so | grep _cffi_pypyinit
709: 0000000000025fa0 32 FUNC GLOBAL DEFAULT 11 _cffi_pypyinit__openssl
1407: 0000000000025fa0 32 FUNC GLOBAL DEFAULT 11 _cffi_pypyinit__openssl The only useful information I can find is pypa/auditwheel#93 Looking at the generated #ifdef PYPY_VERSION
PyMODINIT_FUNC
_cffi_pypyinit__openssl(const void *p[])
{
p[0] = (const void *)0x2601;
p[1] = &_cffi_type_context;
#if PY_MAJOR_VERSION >= 3
return NULL;
#endif
}
# ifdef _MSC_VER
PyMODINIT_FUNC
# if PY_MAJOR_VERSION >= 3
PyInit__openssl(void) { return NULL; }
# else
init_openssl(void) { }
# endif
# endif
#elif PY_MAJOR_VERSION >= 3
PyMODINIT_FUNC
PyInit__openssl(void)
{
return _cffi_init("_openssl", 0x2601, &_cffi_type_context);
}
#else
PyMODINIT_FUNC
init_openssl(void)
{
_cffi_init("_openssl", 0x2601, &_cffi_type_context);
}
#endif It seems that we need to define |
a04b63f
to
1377cee
Compare
// Enable abi3 mode if we're not using PyPy. | ||
if python_impl != "PyPy" { | ||
// cp36 | ||
// build.define("Py_LIMITED_API", "0x030600f0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unable to get cffi embedding to compile with Py_LIMITED_API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof :-/ Maybe we need to do the embedding way on PyPy and the "normal" way on CPython? PyPy already doesn't support Py_LIMITED_API
.
// let ptr = PyInit__openssl(); | ||
// pyo3::types::PyModule::from_owned_ptr(py, ptr) | ||
make_cryptography_openssl_module(); | ||
pyo3::types::PyModule::import(py, "_openssl")? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also makes import _openssl
work after importing cryptography, could this be a problem for end users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. Maybe we should name it _cryptography_openssl
or something to ensure no one accidentally uses it?
It's not building on Windows, I'm not sure why and I don't have a Windows machine, help appreciated! Edit: Tried to include #ifndef _MSC_VER
/* --- Assuming a GCC not infinitely old --- */
# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n)
# define cffi_write_barrier() __sync_synchronize()
# if !defined(__amd64__) && !defined(__x86_64__) && \
!defined(__i386__) && !defined(__i386)
# define cffi_read_barrier() __sync_synchronize()
# else
# define cffi_read_barrier() (void)0
# endif
#else
/* --- Windows threads version --- */
# include <Windows.h>
# define cffi_compare_and_swap(l,o,n) \
(InterlockedCompareExchangePointer(l,n,o) == (o))
# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0)
# define cffi_read_barrier() (void)0
static volatile LONG _cffi_dummy;
#endif Looks like cffi embedding includes |
2ad5294
to
0b7abc6
Compare
0b7abc6
to
50a751a
Compare
Unfortunately looks like PyPy tests are hanging with the cffi embedding approach. Debugged it locally ( >>>> from cryptography.hazmat.bindings import _rust
Fatal RPython error: a thread is trying to wait for the GIL, but the GIL was not initialized
(For PyPy, see https://bitbucket.org/pypy/pypy/issues/2274)
Aborted |
Looks like that issue is already closed, I'd suggest either opening a new one or including a comment on the cffi thread we have open. (Sorry I was slow to look at this!) |
c_file = os.path.join(out_dir, module_name + source_extension) | ||
ffi.embedding_api( | ||
""" | ||
extern "Python" void _this_is_not_used(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment explaining what this is for?
@@ -73,6 +73,12 @@ def build_ffi( | |||
verify_source += '\n#define CRYPTOGRAPHY_PACKAGE_VERSION "{}"'.format( | |||
about["__version__"] | |||
) | |||
verify_source += r""" | |||
|
|||
int make_cryptography_openssl_module(void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's name this Cryptography_make_openssl_module()
, which is the prefix we generally use.
ffi = _openssl.ffi # type: ignore | ||
lib = _openssl.lib # type: ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What actually uses these? Theoretically everything should go through a Binding
instance.
// Enable abi3 mode if we're not using PyPy. | ||
if python_impl != "PyPy" { | ||
// cp36 | ||
// build.define("Py_LIMITED_API", "0x030600f0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof :-/ Maybe we need to do the embedding way on PyPy and the "normal" way on CPython? PyPy already doesn't support Py_LIMITED_API
.
// let ptr = PyInit__openssl(); | ||
// pyo3::types::PyModule::from_owned_ptr(py, ptr) | ||
make_cryptography_openssl_module(); | ||
pyo3::types::PyModule::import(py, "_openssl")? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. Maybe we should name it _cryptography_openssl
or something to ensure no one accidentally uses it?
Sorry I'm busy recently and unable to make progress on this. I'll come back to this maybe after Chinese lunar new year. In the meantime, feel free to take over. |
Thank you for all your work on this!
…On Thu, Jan 20, 2022 at 9:11 AM messense ***@***.***> wrote:
Sorry I'm busy recently and unable to make progress on this. I'll come back to this maybe after Chinese lunar new year. In the meantime, feel free to take over.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you were mentioned.Message ID: ***@***.***>
--
All that is necessary for evil to succeed is for good people to do nothing.
|
I'm attempting to take over this PR in #7164. Thanks for all your work on this! Still stuck on the PyPy hangs! |
Implements #6634
TODO:
Py_LIMITED_API