diff --git a/.github/actions/fetch-vectors/action.yml b/.github/actions/fetch-vectors/action.yml index 5f1307cf7afe..fa8a07b82231 100644 --- a/.github/actions/fetch-vectors/action.yml +++ b/.github/actions/fetch-vectors/action.yml @@ -16,5 +16,5 @@ runs: with: repository: "C2SP/x509-limbo" path: "x509-limbo" - # Latest commit on the x509-limbo main branch, as of Sep 06, 2024. - ref: "ec0fc56b5ac4a1713dae4a0c62904395000fbfbf" # x509-limbo-ref + # Latest commit on the x509-limbo main branch, as of Sep 11, 2024. + ref: "c9d011c6b696074a5a636c7cd40df8e4bd3cd67b" # x509-limbo-ref diff --git a/.github/requirements/publish-requirements.in b/.github/requirements/publish-requirements.in index 1b92e685d4ab..adfe8ec15086 100644 --- a/.github/requirements/publish-requirements.in +++ b/.github/requirements/publish-requirements.in @@ -1,5 +1,8 @@ twine requests -# WARN: changing the requirements here DOES NOT update the dependencies used for publishing at the github workflow, as the process used publish-requirements.txt -# To update publish-requirements.txt according to the dependencies here, run pip-compile --allow-unsafe --generate-hashes publish-requirements.in \ No newline at end of file +# WARN: changing the requirements here DOES NOT update the dependencies used +# for publishing at the github workflow, as the process uses +# `publish-requirements.txt`. +# To update `publish-requirements.txt`, run the command indicated in the +# header of that file. diff --git a/.github/requirements/publish-requirements.txt b/.github/requirements/publish-requirements.txt index 7f2e95cd5a31..e1e6d2844589 100644 --- a/.github/requirements/publish-requirements.txt +++ b/.github/requirements/publish-requirements.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --generate-hashes publish-requirements.in -# +# This file was autogenerated by uv via the following command: +# uv pip compile --universal -p 3.11 --generate-hashes .github/requirements/publish-requirements.in backports-tarfile==1.2.0 \ --hash=sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34 \ --hash=sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991 @@ -246,9 +242,9 @@ mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -more-itertools==10.4.0 \ - --hash=sha256:0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27 \ - --hash=sha256:fe0e63c4ab068eac62410ab05cccca2dc71ec44ba8ef29916a0090df061cf923 +more-itertools==10.5.0 \ + --hash=sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef \ + --hash=sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6 # via # jaraco-classes # jaraco-functools @@ -303,9 +299,9 @@ rfc3986==2.0.0 \ --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \ --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c # via twine -rich==13.8.0 \ - --hash=sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc \ - --hash=sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4 +rich==13.8.1 \ + --hash=sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06 \ + --hash=sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a # via twine secretstorage==3.3.3 \ --hash=sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77 \ diff --git a/.github/requirements/uv-requirements.txt b/.github/requirements/uv-requirements.txt new file mode 100644 index 000000000000..4e3ad4916a3b --- /dev/null +++ b/.github/requirements/uv-requirements.txt @@ -0,0 +1,21 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --universal -p 3.8 --generate-hashes - +uv==0.4.8 \ + --hash=sha256:0c4e4b5ec8aa789cbf4ec2a16494215ebb448aeecf5a2c43a31a904f9fecd327 \ + --hash=sha256:1e7329b862540a3a3987e79781acc2c7b0f4eb89d3f43930e21e7b85e4716bf0 \ + --hash=sha256:23dcb8c866dab0f7565c8e88e2c2ba185ab17182706260d53e9c640a96918818 \ + --hash=sha256:3ad38a03d1007152b9e7a4d262b81c24b95184f8921514d3475a4db6d84fdc78 \ + --hash=sha256:3dbff364ca85e8d52cbeae3bc9050d4e3080636b009bd577f58628a4b9561a26 \ + --hash=sha256:461597ddfd2132e2dea6779758e6e22cd39aaab8d86809f01e3fe45c29152f9a \ + --hash=sha256:484965360638a3ce422d2b61df52de94600d2cfce88eb1ca2dbcf4c8e60e5b37 \ + --hash=sha256:5487a86207edef7464cf78e52adb2bbe369332f3cea6043d1f0c8ee90dda90b3 \ + --hash=sha256:5e7c0428afdd90280f3f32272f0520430e93539c54ae806021c2b7c55caae908 \ + --hash=sha256:6ac13a6fa4f7d78fd44229ffcc5023a1a6627f142e00c896d7e28b041d9ff910 \ + --hash=sha256:7b4364b27dca2e11d99d7f1822a4650d48c5ec6d7f3332f2bc344d6262575ae9 \ + --hash=sha256:8e09e8e39548c7f9fb2c6e073eea6e4c3861539634ef768aa23e1ded10d41ca7 \ + --hash=sha256:a14de914254edce926c5c9afa0ddbfb45d0043c583a928fb614f9c5225f480c3 \ + --hash=sha256:a4e9b042cd1fdce94fa3ccbc79578b239ba1f186f296505e272d44e080892c18 \ + --hash=sha256:bfa6c08501d6c3b7355854a2d56f493ba89b126eb87090fcc31f79c81754d366 \ + --hash=sha256:cdf4b6afc99b0ff0ab1416fbcb25ac704bcf161b7c8d3d92a031097f60a60321 \ + --hash=sha256:e7ec102f9f3e9bd788dc94d271c7cfc7b0a968f799ab2cd9ba9d250563a28f81 \ + --hash=sha256:faa70d7f20adf457d8c584206da7b86b1ed0e0b0e286c19ba000795db8e8a06c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccee4d68f56c..53cfa2c3121d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,10 +44,10 @@ jobs: - {VERSION: "3.12", NOXSESSION: "rust,tests", OPENSSL: {TYPE: "libressl", VERSION: "3.8.4"}} - {VERSION: "3.12", NOXSESSION: "rust,tests", OPENSSL: {TYPE: "libressl", VERSION: "3.9.2"}} - {VERSION: "3.12", NOXSESSION: "tests-randomorder"} - # Latest commit on the BoringSSL master branch, as of Sep 07, 2024. - - {VERSION: "3.12", NOXSESSION: "rust,tests", OPENSSL: {TYPE: "boringssl", VERSION: "01e1ae3687e391a076fe470471f096db1f6d6bb4"}} - # Latest commit on the OpenSSL master branch, as of Sep 07, 2024. - - {VERSION: "3.12", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "5c82588173d33222b33693f698bc9c7614675e9f"}} + # Latest commit on the BoringSSL master branch, as of Sep 11, 2024. + - {VERSION: "3.12", NOXSESSION: "rust,tests", OPENSSL: {TYPE: "boringssl", VERSION: "6abe18402eb2a5e9b00158c6459646a948c53060"}} + # Latest commit on the OpenSSL master branch, as of Sep 11, 2024. + - {VERSION: "3.12", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "2478d3b7f5c4c2da9828e05308b34a4b078035f8"}} # Builds with various Rust versions. Includes MSRV and next # potential future MSRV. - {VERSION: "3.12", NOXSESSION: "rust,tests", RUST: "1.65.0"} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 7e34db123a93..1643b22b26a6 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -21,6 +21,7 @@ on: env: BUILD_REQUIREMENTS_PATH: .github/requirements/build-requirements.txt + UV_REQUIREMENTS_PATH: .github/requirements/uv-requirements.txt jobs: sdist: @@ -33,7 +34,7 @@ jobs: ref: ${{ github.event.inputs.version || github.ref }} persist-credentials: false - - run: python -m pip install uv + - run: python -m pip install -r $UV_REQUIREMENTS_PATH - name: Make sdist (cryptography) run: uv build --build-constraint=$BUILD_REQUIREMENTS_PATH --require-hashes --sdist @@ -195,6 +196,7 @@ jobs: persist-credentials: false sparse-checkout: | ${{ env.BUILD_REQUIREMENTS_PATH }} + ${{ env.UV_REQUIREMENTS_PATH }} sparse-checkout-cone-mode: false - name: Setup python run: | @@ -222,46 +224,41 @@ jobs: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) target: aarch64-apple-darwin - - run: ${{ matrix.PYTHON.BIN_PATH }} -m venv venv - - name: Install Python dependencies - run: venv/bin/pip install --require-hashes -r ${{ env.BUILD_REQUIREMENTS_PATH }} - - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: cryptography-sdist + + - run: ${{ matrix.PYTHON.BIN_PATH }} -m pip install -r ${{ env.UV_REQUIREMENTS_PATH }} - run: mkdir wheelhouse - name: Build the wheel run: | if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then - PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }} --no-build-isolation" + PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }}" fi - # `maturin` has a binary that needs to be on the $PATH, so we - # activate the venv. - source venv/bin/activate OPENSSL_DIR="$(readlink -f ../openssl-macos-universal2/)" \ OPENSSL_STATIC=1 \ - venv/bin/python -m pip wheel -v --no-deps $PY_LIMITED_API cryptograph*.tar.gz -w dist/ - mv dist/cryptography*.whl wheelhouse + uv build --wheel --require-hashes --build-constraint=$BUILD_REQUIREMENTS_PATH $PY_LIMITED_API cryptography*.tar.gz -o wheelhouse/ env: MACOSX_DEPLOYMENT_TARGET: ${{ matrix.PYTHON.DEPLOYMENT_TARGET }} ARCHFLAGS: ${{ matrix.PYTHON.ARCHFLAGS }} _PYTHON_HOST_PLATFORM: ${{ matrix.PYTHON._PYTHON_HOST_PLATFORM }} - - run: venv/bin/pip install -f wheelhouse/ --no-index cryptography + + - run: uv venv + - run: uv pip install --require-hashes -r $BUILD_REQUIREMENTS_PATH + - run: uv pip install cryptography --no-index -f wheelhouse/ - name: Show the wheel's minimum macOS SDK and architectures run: | - find venv/lib/*/site-packages/cryptography/hazmat/bindings -name '*.so' -exec vtool -show {} \; + find .venv/lib/*/site-packages/cryptography/hazmat/bindings -name '*.so' -exec vtool -show {} \; - run: | - venv/bin/python -c "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" + echo "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" | uv run - - - run: mkdir cryptography-wheelhouse - - run: mv wheelhouse/cryptography*.whl cryptography-wheelhouse/ - run: | - echo "CRYPTOGRAPHY_WHEEL_NAME=$(basename $(ls cryptography-wheelhouse/cryptography*.whl))" >> $GITHUB_ENV + echo "CRYPTOGRAPHY_WHEEL_NAME=$(basename $(ls wheelhouse/cryptography*.whl))" >> $GITHUB_ENV - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: "${{ env.CRYPTOGRAPHY_WHEEL_NAME }}" - path: cryptography-wheelhouse/ + path: wheelhouse/ windows: needs: [sdist] @@ -290,6 +287,7 @@ jobs: persist-credentials: false sparse-checkout: | ${{ env.BUILD_REQUIREMENTS_PATH }} + ${{ env.UV_REQUIREMENTS_PATH }} sparse-checkout-cone-mode: false - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -320,25 +318,25 @@ jobs: echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV echo "OPENSSL_STATIC=1" >> $GITHUB_ENV shell: bash - - name: Install Python dependencies - run: python -m pip install --require-hashes -r ${{ env.BUILD_REQUIREMENTS_PATH }} + + - run: pip install -r ${{ env.UV_REQUIREMENTS_PATH }} - run: mkdir wheelhouse - run: | if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then - PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }} --no-build-isolation" + PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }}" fi - python -m pip wheel -v --no-deps cryptography*.tar.gz $PY_LIMITED_API -w dist/ - mv dist/cryptography*.whl wheelhouse/ + uv build --wheel --require-hashes --build-constraint=$BUILD_REQUIREMENTS_PATH cryptography*.tar.gz $PY_LIMITED_API -o wheelhouse/ shell: bash - - run: pip install -f wheelhouse --no-index cryptography + + - run: uv venv + - run: uv pip install --require-hashes -r ${{ env.BUILD_REQUIREMENTS_PATH }} + - run: uv pip install cryptography --no-index -f wheelhouse/ - name: Print the OpenSSL we built and linked against run: | - python -c "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" + echo "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" | uv run - - - run: mkdir cryptography-wheelhouse - - run: move wheelhouse\cryptography*.whl cryptography-wheelhouse\ - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: "cryptography-${{ github.event.inputs.version }}-${{ matrix.WINDOWS.WINDOWS }}-${{ matrix.PYTHON.VERSION }}-${{ matrix.PYTHON.ABI_VERSION }}" - path: cryptography-wheelhouse\ + path: wheelhouse\ diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 04f7993764e1..30596a38a069 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -1,76 +1,134 @@ -# This is named ambigiously, but it's a pip constraints file, named like a -# requirements file so dependabot will update the pins. -# It was originally generated with; -# pip-compile --extra=docs --extra=docstest --extra=pep8test --extra=test --extra=test-randomorder --extra=nox --extra=sdist --resolver=backtracking --strip-extras --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools pyproject.toml -# and then manually massaged to add version specifiers to packages whose -# versions vary by Python version - -alabaster==1.0.0 +# This file was autogenerated by uv via the following command: +# uv pip compile --universal -p 3.7 --extra=docs --extra=docstest --extra=pep8test --extra=test --extra=test-randomorder --extra=nox --extra=sdist --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools --unsafe-package=cryptography-vectors pyproject.toml +alabaster==0.7.13 ; python_full_version < '3.10' + # via sphinx +alabaster==1.0.0 ; python_full_version >= '3.10' # via sphinx -argcomplete==3.5.0; python_version >= "3.8" +argcomplete==3.1.2 ; python_full_version < '3.8' + # via nox +argcomplete==3.5.0 ; python_full_version >= '3.8' # via nox -babel==2.16.0 +babel==2.14.0 ; python_full_version < '3.8' # via sphinx -build==1.2.1 +babel==2.16.0 ; python_full_version >= '3.8' + # via sphinx +bleach==6.0.0 ; python_full_version < '3.8' + # via readme-renderer +build==1.1.1 ; python_full_version < '3.8' + # via cryptography (pyproject.toml) +build==1.2.2 ; python_full_version >= '3.8' # via - # check-sdist # cryptography (pyproject.toml) + # check-sdist certifi==2024.8.30 - # via requests + # via + # cryptography (pyproject.toml) + # requests charset-normalizer==3.3.2 # via requests -check-sdist==0.1.3 +check-sdist==0.1.3 ; python_full_version >= '3.8' # via cryptography (pyproject.toml) click==8.1.7 # via cryptography (pyproject.toml) +colorama==0.4.6 ; (platform_system != 'Windows' and sys_platform == 'win32') or platform_system == 'Windows' or os_name == 'nt' + # via + # build + # click + # colorlog + # pytest + # sphinx colorlog==6.8.2 # via nox -coverage==7.6.1; python_version >= "3.8" - # via - # coverage - # pytest-cov +coverage==7.2.7 ; python_full_version < '3.8' + # via pytest-cov +coverage==7.6.1 ; python_full_version >= '3.8' + # via pytest-cov distlib==0.3.8 # via virtualenv -docutils==0.21.2 +docutils==0.19 ; python_full_version < '3.8' + # via + # readme-renderer + # sphinx +docutils==0.20.1 ; python_full_version >= '3.8' and python_full_version < '3.10' # via # readme-renderer # sphinx # sphinx-rtd-theme -exceptiongroup==1.2.2 +docutils==0.21.2 ; python_full_version >= '3.10' + # via + # readme-renderer + # sphinx + # sphinx-rtd-theme +exceptiongroup==1.2.2 ; python_full_version < '3.11' # via pytest -execnet==2.1.1; python_version >= "3.8" +execnet==2.0.2 ; python_full_version < '3.8' # via pytest-xdist -filelock==3.15.4; python_version >= "3.8" +execnet==2.1.1 ; python_full_version >= '3.8' + # via pytest-xdist +filelock==3.12.2 ; python_full_version < '3.8' + # via virtualenv +filelock==3.16.0 ; python_full_version >= '3.8' # via virtualenv idna==3.8 # via requests imagesize==1.4.1 # via sphinx +importlib-metadata==6.7.0 ; python_full_version < '3.8' + # via + # argcomplete + # build + # click + # nox + # pluggy + # pytest + # pytest-randomly + # sphinx + # sphinxcontrib-spelling + # virtualenv +importlib-metadata==8.4.0 ; python_full_version >= '3.8' and python_full_version < '3.10.2' + # via + # build + # pytest-randomly + # sphinx +importlib-resources==6.4.5 ; python_full_version == '3.8.*' + # via check-sdist iniconfig==2.0.0 # via pytest jinja2==3.1.4 # via sphinx markupsafe==2.1.5 # via jinja2 -mypy==1.11.2 +mypy==1.4.1 ; python_full_version < '3.8' + # via cryptography (pyproject.toml) +mypy==1.11.2 ; python_full_version >= '3.8' # via cryptography (pyproject.toml) mypy-extensions==1.0.0 # via mypy -nh3==0.2.18 +nh3==0.2.18 ; python_full_version >= '3.8' # via readme-renderer nox==2024.4.15 # via cryptography (pyproject.toml) -packaging==24.1; python_version >= "3.8" +packaging==24.0 ; python_full_version < '3.8' + # via + # build + # nox + # pytest + # sphinx +packaging==24.1 ; python_full_version >= '3.8' # via # build # nox # pytest # sphinx -pathspec==0.12.1 +pathspec==0.12.1 ; python_full_version >= '3.8' # via check-sdist -platformdirs==4.2.2; python_version >= "3.8" +platformdirs==4.0.0 ; python_full_version < '3.8' + # via virtualenv +platformdirs==4.3.2 ; python_full_version >= '3.8' # via virtualenv -pluggy==1.5.0; python_version >= "3.8" +pluggy==1.2.0 ; python_full_version < '3.8' + # via pytest +pluggy==1.5.0 ; python_full_version >= '3.8' # via pytest pretend==1.0.9 # via cryptography (pyproject.toml) @@ -80,13 +138,24 @@ pyenchant==3.2.2 # via # cryptography (pyproject.toml) # sphinxcontrib-spelling -pygments==2.18.0 +pygments==2.17.2 ; python_full_version < '3.8' + # via + # readme-renderer + # sphinx +pygments==2.18.0 ; python_full_version >= '3.8' # via # readme-renderer # sphinx pyproject-hooks==1.1.0 # via build -pytest==8.3.2; python_version >= "3.8" +pytest==7.4.4 ; python_full_version < '3.8' + # via + # cryptography (pyproject.toml) + # pytest-benchmark + # pytest-cov + # pytest-randomly + # pytest-xdist +pytest==8.3.3 ; python_full_version >= '3.8' # via # cryptography (pyproject.toml) # pytest-benchmark @@ -95,64 +164,119 @@ pytest==8.3.2; python_version >= "3.8" # pytest-xdist pytest-benchmark==4.0.0 # via cryptography (pyproject.toml) -pytest-cov==5.0.0; python_version >= "3.8" +pytest-cov==4.1.0 ; python_full_version < '3.8' + # via cryptography (pyproject.toml) +pytest-cov==5.0.0 ; python_full_version >= '3.8' + # via cryptography (pyproject.toml) +pytest-randomly==3.12.0 ; python_full_version < '3.8' + # via cryptography (pyproject.toml) +pytest-randomly==3.15.0 ; python_full_version >= '3.8' + # via cryptography (pyproject.toml) +pytest-xdist==3.5.0 ; python_full_version < '3.8' # via cryptography (pyproject.toml) -pytest-randomly==3.15.0 +pytest-xdist==3.6.1 ; python_full_version >= '3.8' # via cryptography (pyproject.toml) -pytest-xdist==3.6.1; python_version >= "3.8" +pytz==2024.1 ; python_full_version < '3.9' + # via babel +readme-renderer==37.3 ; python_full_version < '3.8' # via cryptography (pyproject.toml) -readme-renderer==44.0 +readme-renderer==43.0 ; python_full_version >= '3.8' and python_full_version < '3.10' # via cryptography (pyproject.toml) -requests==2.32.3 +readme-renderer==44.0 ; python_full_version >= '3.10' + # via cryptography (pyproject.toml) +requests==2.31.0 ; python_full_version < '3.8' + # via sphinx +requests==2.32.3 ; python_full_version >= '3.8' # via sphinx ruff==0.6.4 # via cryptography (pyproject.toml) +six==1.16.0 ; python_full_version < '3.8' + # via bleach snowballstemmer==2.2.0 # via sphinx -sphinx==8.0.2 +sphinx==5.3.0 ; python_full_version < '3.8' + # via + # cryptography (pyproject.toml) + # sphinxcontrib-spelling +sphinx==7.1.2 ; python_full_version >= '3.8' and python_full_version < '3.10' # via # cryptography (pyproject.toml) # sphinx-rtd-theme - # sphinxcontrib-applehelp - # sphinxcontrib-devhelp - # sphinxcontrib-htmlhelp # sphinxcontrib-jquery - # sphinxcontrib-qthelp - # sphinxcontrib-serializinghtml # sphinxcontrib-spelling -sphinx-rtd-theme==3.0.0rc1 +sphinx==8.0.2 ; python_full_version >= '3.10' + # via + # cryptography (pyproject.toml) + # sphinx-rtd-theme + # sphinxcontrib-jquery + # sphinxcontrib-spelling +sphinx-rtd-theme==3.0.0rc1 ; python_full_version >= '3.8' # via cryptography (pyproject.toml) -sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-applehelp==1.0.2 ; python_full_version < '3.8' + # via sphinx +sphinxcontrib-applehelp==1.0.4 ; python_full_version >= '3.8' and python_full_version < '3.10' # via sphinx -sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-applehelp==2.0.0 ; python_full_version >= '3.10' # via sphinx -sphinxcontrib-htmlhelp==2.1.0 +sphinxcontrib-devhelp==1.0.2 ; python_full_version < '3.10' # via sphinx -sphinxcontrib-jquery==4.1 +sphinxcontrib-devhelp==2.0.0 ; python_full_version >= '3.10' + # via sphinx +sphinxcontrib-htmlhelp==2.0.0 ; python_full_version < '3.8' + # via sphinx +sphinxcontrib-htmlhelp==2.0.1 ; python_full_version >= '3.8' and python_full_version < '3.10' + # via sphinx +sphinxcontrib-htmlhelp==2.1.0 ; python_full_version >= '3.10' + # via sphinx +sphinxcontrib-jquery==4.1 ; python_full_version >= '3.8' # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-qthelp==1.0.3 ; python_full_version < '3.10' + # via sphinx +sphinxcontrib-qthelp==2.0.0 ; python_full_version >= '3.10' # via sphinx -sphinxcontrib-serializinghtml==2.0.0 +sphinxcontrib-serializinghtml==1.1.5 ; python_full_version < '3.10' + # via sphinx +sphinxcontrib-serializinghtml==2.0.0 ; python_full_version >= '3.10' # via sphinx sphinxcontrib-spelling==8.0.0 # via cryptography (pyproject.toml) -tomli==2.0.1 +tomli==2.0.1 ; python_full_version <= '3.11' # via # build - # check-manifest + # check-sdist # coverage # mypy - # pyproject-hooks + # nox # pytest -typing-extensions==4.12.2; python_version >= "3.8" + # sphinx +typed-ast==1.5.5 ; python_full_version < '3.8' + # via mypy +typing-extensions==4.7.1 ; python_full_version < '3.8' + # via + # importlib-metadata + # mypy + # nox + # platformdirs +typing-extensions==4.12.2 ; python_full_version >= '3.8' # via mypy -urllib3==2.2.2 +urllib3==2.0.7 ; python_full_version < '3.8' # via requests -virtualenv==20.26.3 +urllib3==2.2.2 ; python_full_version >= '3.8' + # via requests +virtualenv==20.26.4 # via nox +webencodings==0.5.1 ; python_full_version < '3.8' + # via bleach +zipp==3.15.0 ; python_full_version < '3.8' + # via importlib-metadata +zipp==3.20.1 ; python_full_version >= '3.8' and python_full_version < '3.10.2' + # via + # importlib-metadata + # importlib-resources -# The following packages are considered to be unsafe in a requirements file: +# The following packages were excluded from the output: # cffi # pycparser +# cryptography-vectors diff --git a/pyproject.toml b/pyproject.toml index 44348415061a..4f9fab38d563 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ test = [ "certifi", ] test-randomorder = ["pytest-randomly"] -docs = ["sphinx >=5.3.0", "sphinx-rtd-theme >=3.0.0rc1"] +docs = ["sphinx >=5.3.0", "sphinx-rtd-theme >=3.0.0rc1; python_version >= '3.8'"] docstest = ["pyenchant >=1.6.11", "readme-renderer", "sphinxcontrib-spelling >=4.0.1"] sdist = ["build"] # `click` included because its needed to type check `release.py` @@ -184,3 +184,8 @@ git-only = [ ".gitattributes", ".gitignore", ] + +[tool.uv] +# These cover all Python versions, but by expressing multiple environments we +# force uv's resolver to pick the latest versions of packages for each version. +environments = ["python_version >= '3.10'", "python_version >= '3.8' and python_version < '3.10'", "python_version < '3.8'"] diff --git a/src/cryptography/hazmat/bindings/_rust/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/__init__.pyi index c0ea0a5405ca..30b67d85597e 100644 --- a/src/cryptography/hazmat/bindings/_rust/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/__init__.pyi @@ -6,7 +6,6 @@ import typing from cryptography.hazmat.primitives import padding -def check_pkcs7_padding(data: bytes) -> bool: ... def check_ansix923_padding(data: bytes) -> bool: ... class PKCS7PaddingContext(padding.PaddingContext): @@ -14,6 +13,11 @@ class PKCS7PaddingContext(padding.PaddingContext): def update(self, data: bytes) -> bytes: ... def finalize(self) -> bytes: ... +class PKCS7UnpaddingContext(padding.PaddingContext): + def __init__(self, block_size: int) -> None: ... + def update(self, data: bytes) -> bytes: ... + def finalize(self) -> bytes: ... + class ObjectIdentifier: def __init__(self, val: str) -> None: ... @property diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py index d1ca775f33d0..b2a3f1cfffaa 100644 --- a/src/cryptography/hazmat/primitives/padding.py +++ b/src/cryptography/hazmat/primitives/padding.py @@ -11,8 +11,8 @@ from cryptography.exceptions import AlreadyFinalized from cryptography.hazmat.bindings._rust import ( PKCS7PaddingContext, + PKCS7UnpaddingContext, check_ansix923_padding, - check_pkcs7_padding, ) @@ -115,32 +115,11 @@ def padder(self) -> PaddingContext: return PKCS7PaddingContext(self.block_size) def unpadder(self) -> PaddingContext: - return _PKCS7UnpaddingContext(self.block_size) - - -class _PKCS7UnpaddingContext(PaddingContext): - _buffer: bytes | None - - def __init__(self, block_size: int): - self.block_size = block_size - # TODO: more copies than necessary, we should use zero-buffer (#193) - self._buffer = b"" - - def update(self, data: bytes) -> bytes: - self._buffer, result = _byte_unpadding_update( - self._buffer, data, self.block_size - ) - return result - - def finalize(self) -> bytes: - result = _byte_unpadding_check( - self._buffer, self.block_size, check_pkcs7_padding - ) - self._buffer = None - return result + return PKCS7UnpaddingContext(self.block_size) PaddingContext.register(PKCS7PaddingContext) +PaddingContext.register(PKCS7UnpaddingContext) class ANSIX923: diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 7539222c90e7..250a146c02aa 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -42,9 +42,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "cc" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ "shlex", ] diff --git a/src/rust/cryptography-cffi/Cargo.toml b/src/rust/cryptography-cffi/Cargo.toml index 2ef2c2fb1e12..50c6567df22c 100644 --- a/src/rust/cryptography-cffi/Cargo.toml +++ b/src/rust/cryptography-cffi/Cargo.toml @@ -11,4 +11,4 @@ pyo3 = { version = "0.22.2", features = ["abi3"] } openssl-sys = "0.9.103" [build-dependencies] -cc = "1.1.16" +cc = "1.1.18" diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index cd7b99f1570a..e15fffa6d32e 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -102,7 +102,7 @@ mod _rust { #[pymodule_export] use crate::oid::ObjectIdentifier; #[pymodule_export] - use crate::padding::{check_ansix923_padding, check_pkcs7_padding, PKCS7PaddingContext}; + use crate::padding::{check_ansix923_padding, PKCS7PaddingContext, PKCS7UnpaddingContext}; #[pymodule_export] use crate::pkcs12::pkcs12; #[pymodule_export] diff --git a/src/rust/src/padding.rs b/src/rust/src/padding.rs index 3a55039d3385..0031f148ea15 100644 --- a/src/rust/src/padding.rs +++ b/src/rust/src/padding.rs @@ -20,7 +20,6 @@ fn constant_time_lt(a: u8, b: u8) -> u8 { duplicate_msb_to_all(a ^ ((a ^ b) | (a.wrapping_sub(b) ^ b))) } -#[pyo3::pyfunction] pub(crate) fn check_pkcs7_padding(data: &[u8]) -> bool { let mut mismatch = 0; let pad_size = *data.last().unwrap(); @@ -111,6 +110,65 @@ impl PKCS7PaddingContext { } } +#[pyo3::pyclass] +pub(crate) struct PKCS7UnpaddingContext { + block_size: usize, + buffer: Option>, +} + +#[pyo3::pymethods] +impl PKCS7UnpaddingContext { + #[new] + pub(crate) fn new(block_size: usize) -> PKCS7UnpaddingContext { + PKCS7UnpaddingContext { + block_size: block_size / 8, + buffer: Some(Vec::new()), + } + } + + pub(crate) fn update<'a>( + &mut self, + py: pyo3::Python<'a>, + buf: CffiBuf<'a>, + ) -> CryptographyResult> { + match self.buffer.as_mut() { + Some(v) => { + v.extend_from_slice(buf.as_bytes()); + let finished_blocks = (v.len() / self.block_size).saturating_sub(1); + let result_size = finished_blocks * self.block_size; + let result = v.drain(..result_size); + Ok(pyo3::types::PyBytes::new_bound(py, result.as_slice())) + } + None => Err(exceptions::already_finalized_error()), + } + } + + pub(crate) fn finalize<'p>( + &mut self, + py: pyo3::Python<'p>, + ) -> CryptographyResult> { + match self.buffer.take() { + Some(v) => { + if v.len() != self.block_size { + return Err( + pyo3::exceptions::PyValueError::new_err("Invalid padding bytes.").into(), + ); + } + if !check_pkcs7_padding(&v) { + return Err( + pyo3::exceptions::PyValueError::new_err("Invalid padding bytes.").into(), + ); + } + + let pad_size = *v.last().unwrap(); + let result = &v[..v.len() - pad_size as usize]; + Ok(pyo3::types::PyBytes::new_bound(py, result)) + } + None => Err(exceptions::already_finalized_error()), + } + } +} + #[cfg(test)] mod tests { use super::constant_time_lt; diff --git a/tests/hazmat/primitives/test_padding.py b/tests/hazmat/primitives/test_padding.py index 0ab1125f5bfb..df1ee4ec1131 100644 --- a/tests/hazmat/primitives/test_padding.py +++ b/tests/hazmat/primitives/test_padding.py @@ -80,6 +80,8 @@ def test_pad(self, size, unpadded, padded): b"111111111111111122222222222222", b"111111111111111122222222222222\x02\x02", ), + (128, b"1" * 16, b"1" * 16 + b"\x10" * 16), + (128, b"1" * 17, b"1" * 17 + b"\x0f" * 15), ], ) def test_unpad(self, size, unpadded, padded):