diff --git a/.gitignore b/.gitignore index 048903d6..3d779c37 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,7 @@ pip-log.txt #Translations *.mo + +.cargo/ +vendor/ +.pybuild/ diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 00000000..59720fda --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,6 @@ +*.substvars +*debhelper* +.debhelper +files +python3-bcrypt +tmp diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000..2076b4b4 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +python-bcrypt (100:4.2.1-1) UNRELEASED; urgency=medium + + * https://github.com/pyca/bcrypt/releases/tag/4.2.1 + + -- Wong Hoi Sing Edison Wed, 20 Nov 2024 07:48:29 +0800 diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..6b16315f --- /dev/null +++ b/debian/control @@ -0,0 +1,31 @@ +Source: python-bcrypt +Section: python +Priority: optional +Standards-Version: 4.5.0 +Maintainer: Wong Hoi Sing Edison +Homepage: https://github.com/pyca/bcrypt/tags +Vcs-Browser: https://github.com/alvistack/pyca-bcrypt +Vcs-Git: https://github.com/alvistack/pyca-bcrypt.git +Build-Depends: + cargo, + cython3, + debhelper, + debhelper-compat (= 10), + dh-python, + fdupes, + python3-dev, + python3-pip, + python3-pycparser, + python3-setuptools (>= 42.0.0), + python3-setuptools-rust (>= 1.7.0), + rustc (>= 1.64.0), + +Package: python3-bcrypt +Architecture: amd64 +Description: Modern(-ish) password hashing for your software and your servers + Good password hashing for your software and your servers. +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + ${python3:Depends}, + python3, diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 00000000..12900b41 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,21 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: debian/* +Copyright: 2024 Wong Hoi Sing Edison +License: Apache-2.0 + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + The complete text of the Apache version 2.0 license + can be found in "/usr/share/common-licenses/Apache-2.0". diff --git a/debian/python3-bcrypt.install b/debian/python3-bcrypt.install new file mode 100644 index 00000000..e3da3e75 --- /dev/null +++ b/debian/python3-bcrypt.install @@ -0,0 +1 @@ +usr/lib/python*/*-packages/* diff --git a/debian/python3-bcrypt.lintian-overrides b/debian/python3-bcrypt.lintian-overrides new file mode 100644 index 00000000..1b0a6375 --- /dev/null +++ b/debian/python3-bcrypt.lintian-overrides @@ -0,0 +1,4 @@ +python3-bcrypt: copyright-without-copyright-notice +python3-bcrypt: initial-upload-closes-no-bugs +python3-bcrypt: no-manual-page +python3-bcrypt: zero-byte-file-in-doc-directory diff --git a/debian/rules b/debian/rules new file mode 100755 index 00000000..1f63af55 --- /dev/null +++ b/debian/rules @@ -0,0 +1,31 @@ +#!/usr/bin/make -f + +SHELL := /bin/bash + +override_dh_auto_configure: + +override_dh_auto_build: + pip wheel \ + --no-deps \ + --no-build-isolation \ + --wheel-dir=dist \ + . + +override_dh_auto_install: + pip install \ + --no-deps \ + --ignore-installed \ + --root=debian/tmp \ + --prefix=/usr \ + dist/*.whl + mv debian/tmp/usr/local/* debian/tmp/usr/ || echo $$? + rm -rf debian/tmp/usr/local || echo $$? + find debian/tmp/usr/lib/python*/*-packages -type f -name '*.pyc' -exec rm -rf {} \; + fdupes -qnrps debian/tmp/usr/lib/python*/*-packages + +override_dh_auto_test: + +override_dh_auto_clean: + +%: + dh $@ --with python3 diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides new file mode 100644 index 00000000..52ff17b1 --- /dev/null +++ b/debian/source/lintian-overrides @@ -0,0 +1,5 @@ +python-bcrypt source: file-without-copyright-information +python-bcrypt source: no-debian-changes +python-bcrypt source: source-contains-prebuilt-windows-binary +python-bcrypt source: source-package-encodes-python-version +python-bcrypt source: unpack-message-for-orig diff --git a/python-bcrypt.spec b/python-bcrypt.spec new file mode 100644 index 00000000..67806dfe --- /dev/null +++ b/python-bcrypt.spec @@ -0,0 +1,103 @@ +# Copyright 2024 Wong Hoi Sing Edison +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +%global debug_package %{nil} + +%global source_date_epoch_from_changelog 0 + +Name: python-bcrypt +Epoch: 100 +Version: 4.2.1 +Release: 1%{?dist} +Summary: Modern(-ish) password hashing for your software and your servers +License: Apache-2.0 +URL: https://github.com/pyca/bcrypt/tags +Source0: %{name}_%{version}.orig.tar.gz +BuildRequires: cargo +BuildRequires: fdupes +BuildRequires: gcc +BuildRequires: python3-Cython3 +BuildRequires: python3-devel +BuildRequires: python3-pip +BuildRequires: python3-pycparser +BuildRequires: python3-setuptools >= 42.0.0 +BuildRequires: python3-setuptools-rust >= 1.7.0 +BuildRequires: python-rpm-macros +BuildRequires: rust >= 1.64.0 + +%description +Good password hashing for your software and your servers. + +%prep +%autosetup -T -c -n %{name}_%{version}-%{release} +tar -zx -f %{S:0} --strip-components=1 -C . + +%build +pip wheel \ + --no-deps \ + --no-build-isolation \ + --wheel-dir=dist \ + . + +%install +pip install \ + --no-deps \ + --ignore-installed \ + --root=%{buildroot} \ + --prefix=%{_prefix} \ + dist/*.whl +find %{buildroot}%{python3_sitearch} -type f -name '*.pyc' -exec rm -rf {} \; +fdupes -qnrps %{buildroot}%{python3_sitearch} + +%check + +%if 0%{?suse_version} > 1500 +%package -n python%{python3_version_nodots}-bcrypt +Summary: Modern(-ish) password hashing for your software and your servers +Requires: python3 +Provides: python3-bcrypt = %{epoch}:%{version}-%{release} +Provides: python3dist(bcrypt) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-bcrypt = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(bcrypt) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-bcrypt = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(bcrypt) = %{epoch}:%{version}-%{release} + +%description -n python%{python3_version_nodots}-bcrypt +Good password hashing for your software and your servers. + +%files -n python%{python3_version_nodots}-bcrypt +%license LICENSE +%{python3_sitearch}/* +%endif + +%if !(0%{?suse_version} > 1500) +%package -n python3-bcrypt +Summary: Modern(-ish) password hashing for your software and your servers +Requires: python3 +Provides: python3-bcrypt = %{epoch}:%{version}-%{release} +Provides: python3dist(bcrypt) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}-bcrypt = %{epoch}:%{version}-%{release} +Provides: python%{python3_version}dist(bcrypt) = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}-bcrypt = %{epoch}:%{version}-%{release} +Provides: python%{python3_version_nodots}dist(bcrypt) = %{epoch}:%{version}-%{release} + +%description -n python3-bcrypt +Good password hashing for your software and your servers. + +%files -n python3-bcrypt +%license LICENSE +%{python3_sitearch}/* +%endif + +%changelog diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..8bfd5a12 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[egg_info] +tag_build = +tag_date = 0 + diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..8bf1ba93 --- /dev/null +++ b/setup.py @@ -0,0 +1,2 @@ +from setuptools import setup +setup() diff --git a/src/_bcrypt/Cargo.lock b/src/_bcrypt/Cargo.lock index ba2cc350..2768427a 100644 --- a/src/_bcrypt/Cargo.lock +++ b/src/_bcrypt/Cargo.lock @@ -16,9 +16,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bcrypt" -version = "0.16.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b1866ecef4f2d06a0bb77880015fdf2b89e25a1c2e5addacb87e459c86dc67e" +checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" dependencies = [ "base64", "blowfish", @@ -50,6 +50,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "block-buffer" version = "0.10.4" @@ -142,17 +148,11 @@ dependencies = [ "wasi", ] -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "indoc" -version = "2.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "inout" @@ -170,12 +170,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] -name = "memoffset" -version = "0.9.1" +name = "lock_api" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", + "scopeguard", ] [[package]] @@ -184,6 +185,29 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "pbkdf2" version = "0.12.2" @@ -193,12 +217,6 @@ dependencies = [ "digest", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "proc-macro2" version = "1.0.89" @@ -210,16 +228,14 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.23.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebb0c0cc0de9678e53be9ccf8a2ab53045e6e3a8be03393ceccc5e7396ccb40" +checksum = "0220c44442c9b239dd4357aa856ac468a4f5e1f0df19ddb89b2522952eb4c6ca" dependencies = [ "cfg-if", "indoc", "libc", - "memoffset", - "once_cell", - "portable-atomic", + "parking_lot", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", @@ -228,9 +244,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.23.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e3ce69c4ec34476534b490e412b871ba03a82e35604c3dfb95fcb6bfb60c09" +checksum = "9c819d397859445928609d0ec5afc2da5204e0d0f73d6bf9e153b04e83c9cdc2" dependencies = [ "once_cell", "target-lexicon", @@ -238,9 +254,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.23.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09f311c76b36dfd6dd6f7fa6f9f18e7e46a1c937110d283e80b12ba2468a75" +checksum = "ca882703ab55f54702d7bfe1189b41b0af10272389f04cae38fe4cd56c65f75f" dependencies = [ "libc", "pyo3-build-config", @@ -248,9 +264,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.23.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4f74086536d1e1deaff99ec0387481fb3325c82e4e48be0e75ab3d3fcb487a" +checksum = "568749402955ad7be7bad9a09b8593851cd36e549ac90bfd44079cea500f3f21" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -260,13 +276,11 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.23.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e77dfeb76b32bbf069144a5ea0a36176ab59c8db9ce28732d0f06f096bbfbc8" +checksum = "611f64e82d98f447787e82b8e7b0ebc681e1eb78fc1252668b2c605ffb4e1eb8" dependencies = [ - "heck", "proc-macro2", - "pyo3-build-config", "quote", "syn", ] @@ -280,6 +294,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sha2" version = "0.10.8" @@ -291,6 +320,12 @@ dependencies = [ "digest", ] +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "subtle" version = "2.6.1" @@ -299,9 +334,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.87" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -328,9 +363,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unindent" -version = "0.2.3" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" +checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" [[package]] name = "version_check" @@ -344,6 +379,70 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "zeroize" version = "1.8.1" diff --git a/src/_bcrypt/Cargo.toml b/src/_bcrypt/Cargo.toml index 826d2c1c..7d256328 100644 --- a/src/_bcrypt/Cargo.toml +++ b/src/_bcrypt/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" publish = false [dependencies] -pyo3 = { version = "0.23", features = ["abi3"] } -bcrypt = "0.16" +pyo3 = { version = "0.16.6", features = ["abi3"] } +bcrypt = "0.15" bcrypt-pbkdf = "0.10.0" base64 = "0.22.1" subtle = "2.6" diff --git a/src/_bcrypt/src/lib.rs b/src/_bcrypt/src/lib.rs index 2da2b021..ffa12c48 100644 --- a/src/_bcrypt/src/lib.rs +++ b/src/_bcrypt/src/lib.rs @@ -13,10 +13,8 @@ #![deny(rust_2018_idioms)] use base64::Engine; -use pyo3::types::PyBytesMethods; use pyo3::PyTypeInfo; use std::convert::TryInto; -use std::ffi::CString; use std::io::Write; use subtle::ConstantTimeEq; @@ -25,13 +23,12 @@ pub const BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::Genera base64::engine::general_purpose::NO_PAD, ); -#[pyo3::pyfunction] -#[pyo3(signature = (rounds=None, prefix=None))] +#[pyo3::prelude::pyfunction] fn gensalt<'p>( py: pyo3::Python<'p>, rounds: Option, prefix: Option<&[u8]>, -) -> pyo3::PyResult> { +) -> pyo3::PyResult<&'p pyo3::types::PyBytes> { let rounds = rounds.unwrap_or(12); let prefix = prefix.unwrap_or(b"2b"); @@ -66,12 +63,12 @@ fn gensalt<'p>( ) } -#[pyo3::pyfunction] +#[pyo3::prelude::pyfunction] fn hashpw<'p>( py: pyo3::Python<'p>, password: &[u8], salt: &[u8], -) -> pyo3::PyResult> { +) -> pyo3::PyResult<&'p pyo3::types::PyBytes> { // bcrypt originally suffered from a wraparound bug: // http://www.openwall.com/lists/oss-security/2012/01/02/4 // This bug was corrected in the OpenBSD source by truncating inputs to 72 @@ -121,7 +118,7 @@ fn hashpw<'p>( )) } -#[pyo3::pyfunction] +#[pyo3::prelude::pyfunction] fn checkpw(py: pyo3::Python<'_>, password: &[u8], hashed_password: &[u8]) -> pyo3::PyResult { Ok(hashpw(py, password, hashed_password)? .as_bytes() @@ -129,16 +126,17 @@ fn checkpw(py: pyo3::Python<'_>, password: &[u8], hashed_password: &[u8]) -> pyo .into()) } -#[pyo3::pyfunction] -#[pyo3(signature = (password, salt, desired_key_bytes, rounds, ignore_few_rounds=false))] +#[pyo3::prelude::pyfunction] fn kdf<'p>( py: pyo3::Python<'p>, password: &[u8], salt: &[u8], desired_key_bytes: usize, rounds: u32, - ignore_few_rounds: bool, -) -> pyo3::PyResult> { + ignore_few_rounds: Option, +) -> pyo3::PyResult<&'p pyo3::types::PyBytes> { + let ignore_few_rounds = ignore_few_rounds.unwrap_or(false); + if password.is_empty() || salt.is_empty() { return Err(pyo3::exceptions::PyValueError::new_err( "password and salt must not be empty", @@ -157,18 +155,6 @@ fn kdf<'p>( )); } - if rounds < 50 && !ignore_few_rounds { - // They probably think bcrypt.kdf()'s rounds parameter is logarithmic, - // expecting this value to be slow enough (it probably would be if this - // were bcrypt). Emit a warning. - pyo3::PyErr::warn( - py, - &pyo3::exceptions::PyUserWarning::type_object(py), - &CString::new(format!("Warning: bcrypt.kdf() called with only {rounds} round(s). This few is not secure: the parameter is linear, like PBKDF2.")).unwrap(), - 3 - )?; - } - pyo3::types::PyBytes::new_with(py, desired_key_bytes, |output| { py.allow_threads(|| { bcrypt_pbkdf::bcrypt_pbkdf(password, salt, rounds, output).unwrap(); @@ -177,35 +163,31 @@ fn kdf<'p>( }) } -#[pyo3::pymodule] -mod _bcrypt { - use pyo3::types::PyModuleMethods; - - #[pymodule_export] - use super::{checkpw, gensalt, hashpw, kdf}; - - // Not yet possible to add constants declaratively. - #[pymodule_init] - fn init(m: &pyo3::Bound<'_, pyo3::types::PyModule>) -> pyo3::PyResult<()> { - m.add("__title__", "bcrypt")?; - m.add( - "__summary__", - "Modern(-ish) password hashing for your software and your servers", - )?; - m.add("__uri__", "https://github.com/pyca/bcrypt/")?; - - // When updating this, also update pyproject.toml - // This isn't named __version__ because passlib treats the existence of - // that attribute as proof that we're a different module - m.add("__version_ex__", "4.2.1")?; - - let author = "The Python Cryptographic Authority developers"; - m.add("__author__", author)?; - m.add("__email__", "cryptography-dev@python.org")?; - - m.add("__license__", "Apache License, Version 2.0")?; - m.add("__copyright__", format!("Copyright 2013-2024 {author}"))?; - - Ok(()) - } +#[pyo3::prelude::pymodule] +fn _bcrypt(_py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { + m.add_function(pyo3::wrap_pyfunction!(gensalt, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(hashpw, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(checkpw, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(kdf, m)?)?; + + m.add("__title__", "bcrypt")?; + m.add( + "__summary__", + "Modern(-ish) password hashing for your software and your servers", + )?; + m.add("__uri__", "https://github.com/pyca/bcrypt/")?; + + // When updating this, also update pyproject.toml + // This isn't named __version__ because passlib treats the existence of + // that attribute as proof that we're a different module + m.add("__version_ex__", "4.2.0")?; + + let author = "The Python Cryptographic Authority developers"; + m.add("__author__", author)?; + m.add("__email__", "cryptography-dev@python.org")?; + + m.add("__license__", "Apache License, Version 2.0")?; + m.add("__copyright__", format!("Copyright 2013-2024 {author}"))?; + + Ok(()) } diff --git a/tests/test_bcrypt.py b/tests/test_bcrypt.py index 68c00fb4..01a12a2f 100644 --- a/tests/test_bcrypt.py +++ b/tests/test_bcrypt.py @@ -462,11 +462,6 @@ def test_kdf_no_warn_rounds(): bcrypt.kdf(b"password", b"salt", 10, 10, True) -def test_kdf_warn_rounds(): - with pytest.warns(UserWarning): - bcrypt.kdf(b"password", b"salt", 10, 10) - - @pytest.mark.parametrize( ("password", "salt", "desired_key_bytes", "rounds", "error"), [