Skip to content

Commit ec38f43

Browse files
committed
Rollback to pyo3 = { version = "0.16.6", features = ["abi3"] }
In order to avoid `ImportError: PyO3 modules compiled for CPython 3.8 or older may only be initialized once per interpreter process` introduced since pyo3 >= 0.17.0, which only allow each `#[pymodule]` to be initialized once, this PR temporarily rollback to pyo3 = 0.16.6. It also remove the use of `PyUserWarning` which introduced since pyo3 > 0.18.0. See PyO3/pyo3@78ba70d See PyO3/pyo3@1d20f2a Fixes pyca#694 Signed-off-by: Wong Hoi Sing Edison <[email protected]>
1 parent 35e5a6f commit ec38f43

File tree

4 files changed

+24
-70
lines changed

4 files changed

+24
-70
lines changed

src/_bcrypt/Cargo.lock

+16-41
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/_bcrypt/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2018"
66
publish = false
77

88
[dependencies]
9-
pyo3 = { version = "0.21", features = ["abi3"] }
9+
pyo3 = { version = "0.16.6", features = ["abi3"] }
1010
bcrypt = "0.15"
1111
bcrypt-pbkdf = "0.10.0"
1212
base64 = "0.22.1"

src/_bcrypt/src/lib.rs

+7-23
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#![deny(rust_2018_idioms)]
1414

1515
use base64::Engine;
16-
use pyo3::prelude::PyBytesMethods;
1716
use pyo3::PyTypeInfo;
1817
use std::convert::TryInto;
1918
use std::io::Write;
@@ -29,7 +28,7 @@ fn gensalt<'p>(
2928
py: pyo3::Python<'p>,
3029
rounds: Option<u16>,
3130
prefix: Option<&[u8]>,
32-
) -> pyo3::PyResult<pyo3::Bound<'p, pyo3::types::PyBytes>> {
31+
) -> pyo3::PyResult<&'p pyo3::types::PyBytes> {
3332
let rounds = rounds.unwrap_or(12);
3433
let prefix = prefix.unwrap_or(b"2b");
3534

@@ -48,7 +47,7 @@ fn gensalt<'p>(
4847

4948
let encoded_salt = BASE64_ENGINE.encode(salt);
5049

51-
pyo3::types::PyBytes::new_bound_with(
50+
pyo3::types::PyBytes::new_with(
5251
py,
5352
1 + prefix.len() + 1 + 2 + 1 + encoded_salt.len(),
5453
|mut b| {
@@ -69,7 +68,7 @@ fn hashpw<'p>(
6968
py: pyo3::Python<'p>,
7069
password: &[u8],
7170
salt: &[u8],
72-
) -> pyo3::PyResult<pyo3::Bound<'p, pyo3::types::PyBytes>> {
71+
) -> pyo3::PyResult<&'p pyo3::types::PyBytes> {
7372
// bcrypt originally suffered from a wraparound bug:
7473
// http://www.openwall.com/lists/oss-security/2012/01/02/4
7574
// This bug was corrected in the OpenBSD source by truncating inputs to 72
@@ -113,7 +112,7 @@ fn hashpw<'p>(
113112
let hashed = py
114113
.allow_threads(|| bcrypt::hash_with_salt(password, cost, raw_salt))
115114
.map_err(|_| pyo3::exceptions::PyValueError::new_err("Invalid salt"))?;
116-
Ok(pyo3::types::PyBytes::new_bound(
115+
Ok(pyo3::types::PyBytes::new(
117116
py,
118117
hashed.format_for_version(version).as_bytes(),
119118
))
@@ -135,7 +134,7 @@ fn kdf<'p>(
135134
desired_key_bytes: usize,
136135
rounds: u32,
137136
ignore_few_rounds: Option<bool>,
138-
) -> pyo3::PyResult<pyo3::Bound<'p, pyo3::types::PyBytes>> {
137+
) -> pyo3::PyResult<&'p pyo3::types::PyBytes> {
139138
let ignore_few_rounds = ignore_few_rounds.unwrap_or(false);
140139

141140
if password.is_empty() || salt.is_empty() {
@@ -156,19 +155,7 @@ fn kdf<'p>(
156155
));
157156
}
158157

159-
if rounds < 50 && !ignore_few_rounds {
160-
// They probably think bcrypt.kdf()'s rounds parameter is logarithmic,
161-
// expecting this value to be slow enough (it probably would be if this
162-
// were bcrypt). Emit a warning.
163-
pyo3::PyErr::warn_bound(
164-
py,
165-
&pyo3::exceptions::PyUserWarning::type_object_bound(py),
166-
&format!("Warning: bcrypt.kdf() called with only {rounds} round(s). This few is not secure: the parameter is linear, like PBKDF2."),
167-
3
168-
)?;
169-
}
170-
171-
pyo3::types::PyBytes::new_bound_with(py, desired_key_bytes, |output| {
158+
pyo3::types::PyBytes::new_with(py, desired_key_bytes, |output| {
172159
py.allow_threads(|| {
173160
bcrypt_pbkdf::bcrypt_pbkdf(password, salt, rounds, output).unwrap();
174161
});
@@ -177,10 +164,7 @@ fn kdf<'p>(
177164
}
178165

179166
#[pyo3::prelude::pymodule]
180-
fn _bcrypt(
181-
_py: pyo3::Python<'_>,
182-
m: &pyo3::Bound<'_, pyo3::types::PyModule>,
183-
) -> pyo3::PyResult<()> {
167+
fn _bcrypt(_py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
184168
m.add_function(pyo3::wrap_pyfunction!(gensalt, m)?)?;
185169
m.add_function(pyo3::wrap_pyfunction!(hashpw, m)?)?;
186170
m.add_function(pyo3::wrap_pyfunction!(checkpw, m)?)?;

tests/test_bcrypt.py

-5
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,6 @@ def test_kdf_no_warn_rounds():
462462
bcrypt.kdf(b"password", b"salt", 10, 10, True)
463463

464464

465-
def test_kdf_warn_rounds():
466-
with pytest.warns(UserWarning):
467-
bcrypt.kdf(b"password", b"salt", 10, 10)
468-
469-
470465
@pytest.mark.parametrize(
471466
("password", "salt", "desired_key_bytes", "rounds", "error"),
472467
[

0 commit comments

Comments
 (0)