From 22d33a12524bf6116c14fba01cba4a894c70cd4e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 2 Jan 2023 12:06:43 +0700 Subject: [PATCH 001/827] reopen for 40 (#7955) * reopen for 40 * oops --- .github/downstream.d/certbot.sh | 1 + CHANGELOG.rst | 8 ++++++++ src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/downstream.d/certbot.sh b/.github/downstream.d/certbot.sh index 2479d0c25b86..e2f2203bbf0a 100755 --- a/.github/downstream.d/certbot.sh +++ b/.github/downstream.d/certbot.sh @@ -7,6 +7,7 @@ case "${1}" in git rev-parse HEAD tools/pip_install_editable.py ./acme[test] tools/pip_install_editable.py ./certbot[test] + pip install -U pyopenssl ;; run) cd certbot diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bd70b9bc7b34..32eb2065e4e7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog ========= +.. _v40-0-0: + +40.0.0 - `main`_ +~~~~~~~~~~~~~~~~ + +.. note:: This version is not yet released and is under active development. + + .. _v39-0-0: 39.0.0 - 2023-01-01 diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 83439a962dd3..379a73a95383 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -9,7 +9,7 @@ "__copyright__", ] -__version__ = "39.0.0" +__version__ = "40.0.0.dev1" __author__ = "The Python Cryptographic Authority and individual contributors" __copyright__ = "Copyright 2013-2022 {}".format(__author__) diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index 9b607dd65f03..46c562addb25 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "39.0.0" +__version__ = "40.0.0.dev1" From 52018d73f61fca4bf84f09680f160dcb68a4e648 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 2 Jan 2023 12:27:13 +0700 Subject: [PATCH 002/827] more release.py fixes and improvements (#7956) * more release.py fixes and improvements * Update release.py Co-authored-by: Alex Gaynor Co-authored-by: Alex Gaynor --- release.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/release.py b/release.py index 003605384583..01101bcd872a 100644 --- a/release.py +++ b/release.py @@ -87,18 +87,29 @@ def fetch_github_actions_artifacts( ) -> typing.List[str]: session = requests.Session() - response = session.get( - ( - f"https://api.github.com/repos/pyca/cryptography/actions" - f"/workflows/wheel-builder.yml/runs?event=push&branch={version}" - ), - headers={ - "Content-Type": "application/json", - "Authorization": "token {}".format(token), - }, - ) - response.raise_for_status() - run_url: str = response.json()["workflow_runs"][0]["url"] + workflow_runs = [] + + # There is a race condition where no workflow run has triggered after + # pushing the tag, so loop until we get the run. + while True: + response = session.get( + ( + f"https://api.github.com/repos/pyca/cryptography/actions" + f"/workflows/wheel-builder.yml/runs?event=push&" + f"branch={version}" + ), + headers={ + "Content-Type": "application/json", + "Authorization": "token {}".format(token), + }, + ) + response.raise_for_status() + workflow_runs = response.json()["workflow_runs"] + if len(workflow_runs) > 0: + break + time.sleep(3) + + run_url: str = workflow_runs[0]["url"] wait_for_build_complete_github_actions(session, token, run_url) return download_artifacts_github_actions(session, token, run_url) @@ -212,7 +223,7 @@ def release(version: str) -> None: ``version`` should be a string like '0.4' or '1.0'. """ print( - f"Create a new GH PAT at: " + f"Create a new GH PAT with only actions permissions at: " f"https://github.com/settings/tokens/new?" f"description={version}&scopes=repo" ) @@ -224,9 +235,11 @@ def release(version: str) -> None: circle_token = getpass.getpass("CircleCI token: ") # Tag and push the tag (this will trigger the wheel builder in Actions) - run("git", "tag", "-s", version, "-m", "{0} release".format(version)) + run("git", "tag", "-s", version, "-m", f"{version} release") run("git", "push", "--tags") + os.makedirs(os.path.join(os.path.dirname(__file__), "dist"), exist_ok=True) + # Wait for Actions to complete and download the wheels github_actions_artifact_paths = fetch_github_actions_artifacts( github_token, version From 4e1d5cbe0fc97882844ca6df6d330f2abbcc2e88 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 2 Jan 2023 12:46:33 +0700 Subject: [PATCH 003/827] Only depend on sphinx_rtd_theme (#7957) This avoids version compatibility issues since sphinx_rtd_theme has sphinx as a dep (with version constraints) --- setup.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 7a78922c0e2d..1830f9b41e78 100644 --- a/setup.cfg +++ b/setup.cfg @@ -66,8 +66,8 @@ test = pytz hypothesis>=1.11.4,!=3.79.2 docs = - sphinx >= 1.6.5,!=1.8.0,!=3.1.0,!=3.1.1,!=5.2.0,!=5.2.0.post0 - sphinx_rtd_theme + sphinx >= 5.3.0 + sphinx-rtd-theme>=1.1.1 docstest = pyenchant >= 1.6.11 twine >= 1.12.0 From 57578319d4fab29873847ac10c4131d63bf92a02 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 2 Jan 2023 18:25:52 -0500 Subject: [PATCH 004/827] Last step in deprecating 3.6 (#7961) refs #7843 --- CHANGELOG.rst | 2 ++ src/cryptography/__init__.py | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 32eb2065e4e7..a50daf03d431 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,8 @@ Changelog .. note:: This version is not yet released and is under active development. +* Support for Python 3.6 is deprecated and will be removed in the next + release. .. _v39-0-0: diff --git a/src/cryptography/__init__.py b/src/cryptography/__init__.py index 07c894ea33f8..7f8a25c6ed9c 100644 --- a/src/cryptography/__init__.py +++ b/src/cryptography/__init__.py @@ -18,8 +18,7 @@ warnings.warn( "Python 3.6 is no longer supported by the Python core team. " "Therefore, support for it is deprecated in cryptography. The next " - "release of cryptography (40.0) will be the last to support Python " - "3.6.", + "release of cryptography will remove support for Python 3.6.", CryptographyDeprecationWarning, stacklevel=2, ) From 07d76445e64653263cdf52a2524738fe131763ac Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 2 Jan 2023 20:47:06 -0500 Subject: [PATCH 005/827] Pin python dev dependencies in CI with a pip constraints file (#7962) --- .github/dependabot.yml | 6 + .github/workflows/benchmark.yml | 4 +- .github/workflows/ci.yml | 15 +- .github/workflows/macarm64.yml | 2 +- .github/workflows/wheel-builder.yml | 4 +- MANIFEST.in | 2 +- ci-constraints-requirements.txt | 223 +++++++++++++++++++++++++++ dev-requirements.txt | 5 - docs/development/getting-started.rst | 44 ++---- setup.cfg | 9 ++ tox.ini | 10 +- 11 files changed, 272 insertions(+), 52 deletions(-) create mode 100644 ci-constraints-requirements.txt delete mode 100644 dev-requirements.txt diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d4a20bc61049..67861ffae223 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,7 @@ updates: directory: "/" schedule: interval: "daily" + - package-ecosystem: cargo directory: "/src/rust/" schedule: @@ -11,3 +12,8 @@ updates: allow: # Also update indirect dependencies - dependency-type: all + + - package-ecosystem: pip + directory: "/" + schedule: + interval: daily diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 2d14948f95b4..e9369f9bc9b6 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -35,11 +35,13 @@ jobs: - name: Create virtualenv (main) run: | python -m venv .venv-main + # TODO: add -c ./cryptography-main/ci-constraints-requirements.txt + # after https://github.com/pyca/cryptography/pull/7962 is merged .venv-main/bin/pip install -v "./cryptography-main[test]" ./cryptography-main/vectors/ - name: Create virtualenv (PR) run: | python -m venv .venv-pr - .venv-pr/bin/pip install -v "./cryptography-pr[test]" ./cryptography-main/vectors/ + .venv-pr/bin/pip install -v -c ./cryptography-pr/ci-constraints-requirements.txt "./cryptography-pr[test]" ./cryptography-pr/vectors/ - name: Run benchmarks (main) run: .venv-main/bin/pytest --benchmark-enable --benchmark-only ./cryptography-pr/tests/bench/ --benchmark-json=bench-main.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0dcce6503b7f..853b22063fc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,7 +75,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install tox requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] - name: Compute config hash and set config vars run: | DEFAULT_CONFIG_FLAGS="shared no-ssl2 no-ssl3" @@ -175,6 +175,7 @@ jobs: echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV if: matrix.IMAGE.FIPS + - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt tox - run: '/venv/bin/tox -vvv -- --wycheproof-root="wycheproof"' env: TOXENV: ${{ matrix.IMAGE.TOXENV }} @@ -234,7 +235,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install tox coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] - name: Tests run: | tox -vvv -r -- --color=yes --wycheproof-root=wycheproof @@ -290,7 +291,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install tox coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] - name: Tests run: | tox -vvv -r -- --color=yes --wycheproof-root=wycheproof @@ -363,7 +364,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} - - run: python -m pip install tox requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] - uses: actions/checkout@v3.2.0 timeout-minutes: 3 @@ -428,7 +429,7 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - run: python -m pip install tox requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL run: | python .github/workflows/download_openssl.py windows openssl-${{ matrix.WINDOWS.WINDOWS }} @@ -530,7 +531,7 @@ jobs: uses: actions/setup-python@v4.4.0 with: python-version: 3.11 - - run: python -m pip install -U tox + - run: python -m pip install -c ci-constraints-requirements.txt tox - run: tox -r -- --color=yes env: TOXENV: docs-linkcheck @@ -554,7 +555,7 @@ jobs: uses: actions/setup-python@v4.4.0 with: python-version: '3.10' - - run: pip install coverage[toml] + - run: pip install -c ci-constraints-requirements.txt coverage[toml] if: ${{ always() }} - name: Download coverage data if: ${{ always() }} diff --git a/.github/workflows/macarm64.yml b/.github/workflows/macarm64.yml index 71c1419a279f..5d8c5da6d413 100644 --- a/.github/workflows/macarm64.yml +++ b/.github/workflows/macarm64.yml @@ -46,7 +46,7 @@ jobs: - name: Setup venv and install deps run: | $BIN_PATH -m venv venv - venv/bin/python -m pip install tox requests + venv/bin/python -m pip install -c ci-constraints-requirements.txt tox requests env: BIN_PATH: ${{ matrix.PYTHON.BIN_PATH }} - name: Download OpenSSL diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 9bf72146de86..77d3ca57e978 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -172,7 +172,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') - - run: ${{ matrix.PYTHON.BIN_PATH }} -m pip install -U requests + - run: ${{ matrix.PYTHON.BIN_PATH }} -m pip install -c ci-constraints-requirements.txt -U requests - name: Download OpenSSL run: | ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 @@ -255,7 +255,7 @@ jobs: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} - - run: pip install requests + - run: pip install -c ci-constraints-requirements.txt requests - name: Download OpenSSL run: | python .github/workflows/download_openssl.py windows openssl-${{ matrix.WINDOWS.WINDOWS }} diff --git a/MANIFEST.in b/MANIFEST.in index 8471d75785ab..52db6dc8169c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -19,6 +19,6 @@ recursive-exclude vectors * recursive-exclude .github * -exclude release.py .readthedocs.yml dev-requirements.txt tox.ini mypy.ini +exclude release.py .readthedocs.yml ci-constraints-requirements.txt tox.ini mypy.ini recursive-exclude .circleci * diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt new file mode 100644 index 000000000000..94cdd247f223 --- /dev/null +++ b/ci-constraints-requirements.txt @@ -0,0 +1,223 @@ +# 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=tox --resolver=backtracking --strip-extras setup.cfg +# and then manually massaged to remove non-dev dependencies and add version +# specifiers to packages whose versions vary by Python version + +alabaster==0.7.12 + # via sphinx +attrs==22.2.0 + # via + # hypothesis + # pytest +babel==2.11.0 + # via sphinx +black==22.12.0 + # via cryptography (setup.cfg) +bleach==5.0.1 + # via readme-renderer +build==0.9.0 + # via check-manifest +cachetools==5.2.0 + # via tox +certifi==2022.12.7 + # via requests +chardet==5.1.0 + # via tox +charset-normalizer==2.1.1; python_version >= "3.7" + # via requests +check-manifest==0.49 + # via cryptography (setup.cfg) +click==8.1.3 + # via black +colorama==0.4.6; python_version >= "3.7" + # via tox +commonmark==0.9.1 + # via rich +coverage==7.0.1; python_version >= "3.7" + # via pytest-cov +distlib==0.3.6 + # via virtualenv +docutils==0.17.1 + # via + # readme-renderer + # sphinx + # sphinx-rtd-theme +exceptiongroup==1.1.0 + # via + # hypothesis + # pytest +execnet==1.9.0 + # via pytest-xdist +filelock==3.9.0; python_version >= "3.7" + # via + # tox + # virtualenv +hypothesis==6.61.0; python_version >= "3.7" + # via cryptography (setup.cfg) +idna==3.4 + # via requests +imagesize==1.4.1 + # via sphinx +importlib-metadata==6.0.0; python_version >= "3.7" + # via + # keyring + # twine +iniconfig==1.1.1 + # via pytest +iso8601==1.1.0 + # via cryptography (setup.cfg) +jaraco-classes==3.2.3 + # via keyring +jinja2==3.1.2 + # via sphinx +keyring==23.13.1 + # via twine +markupsafe==2.1.1 + # via jinja2 +more-itertools==9.0.0 + # via jaraco-classes +mypy==0.991 + # via cryptography (setup.cfg) +mypy-extensions==0.4.3 + # via + # black + # mypy +packaging==22.0; python_version >= "3.7" + # via + # build + # pyproject-api + # pytest + # sphinx + # tox +pathspec==0.10.3 + # via black +pep517==0.13.0 + # via build +pkginfo==1.9.2 + # via twine +platformdirs==2.6.2; python_version >= "3.7" + # via + # black + # tox + # virtualenv +pluggy==1.0.0; python_version >= "3.7" + # via + # pytest + # tox +pretend==1.0.9 + # via cryptography (setup.cfg) +py-cpuinfo==9.0.0 + # via pytest-benchmark +pyenchant==3.2.2 + # via + # cryptography (setup.cfg) + # sphinxcontrib-spelling +pygments==2.14.0 + # via + # readme-renderer + # rich + # sphinx +pyproject-api==1.2.1 + # via tox +pytest==7.2.0; python_version >= "3.7" + # via + # cryptography (setup.cfg) + # pytest-benchmark + # pytest-cov + # pytest-randomly + # pytest-shard + # pytest-subtests + # pytest-xdist +pytest-benchmark==4.0.0; python_version >= "3.7" + # via cryptography (setup.cfg) +pytest-cov==4.0.0 + # via cryptography (setup.cfg) +pytest-randomly==3.12.0 + # via cryptography (setup.cfg) +pytest-shard==0.1.2 + # via cryptography (setup.cfg) +pytest-subtests==0.9.0; python_version >= "3.7" + # via cryptography (setup.cfg) +pytest-xdist==3.1.0; python_version >= "3.7" + # via cryptography (setup.cfg) +pytz==2022.7 + # via + # babel + # cryptography (setup.cfg) +readme-renderer==37.3 + # via twine +requests==2.28.1; python_version >= "3.7" + # via + # requests-toolbelt + # sphinx + # twine +requests-toolbelt==0.10.1 + # via twine +rfc3986==2.0.0 + # via twine +rich==13.0.0 + # via twine +ruff==0.0.206 + # via cryptography (setup.cfg) +six==1.16.0 + # via bleach +snowballstemmer==2.2.0 + # via sphinx +sortedcontainers==2.4.0 + # via hypothesis +sphinx==5.3.0 + # via + # cryptography (setup.cfg) + # sphinx-rtd-theme + # sphinxcontrib-spelling +sphinx-rtd-theme==1.1.1 + # via cryptography (setup.cfg) +sphinxcontrib-applehelp==1.0.2 + # via sphinx +sphinxcontrib-devhelp==1.0.2 + # via sphinx +sphinxcontrib-htmlhelp==2.0.0 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.3 + # via sphinx +sphinxcontrib-serializinghtml==1.1.5 + # via sphinx +sphinxcontrib-spelling==7.7.0 + # via cryptography (setup.cfg) +tomli==2.0.1 + # via + # black + # build + # check-manifest + # coverage + # mypy + # pep517 + # pyproject-api + # pytest + # tox +tox==4.1.2; python_version >= "3.7" + # via cryptography (setup.cfg) +twine==4.0.2 + # via cryptography (setup.cfg) +types-pytz==2022.7.0.0 + # via cryptography (setup.cfg) +types-requests==2.28.11.7 + # via cryptography (setup.cfg) +types-urllib3==1.26.25.4 + # via types-requests +typing-extensions==4.4.0; python_version >= "3.7" + # via mypy +urllib3==1.26.13 + # via + # requests + # twine +virtualenv==20.17.1 + # via tox +webencodings==0.5.1 + # via bleach +zipp==3.11.0; python_version >= "3.7" + # via importlib-metadata diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 41d533168eda..000000000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -click -tox >= 2.4.1 -twine >= 1.8.0 --e .[test,docs,docstest,pep8test] --e vectors diff --git a/docs/development/getting-started.rst b/docs/development/getting-started.rst index b52a4fd0cd45..00638aa576d1 100644 --- a/docs/development/getting-started.rst +++ b/docs/development/getting-started.rst @@ -3,37 +3,26 @@ Getting started Development dependencies ------------------------ + Working on ``cryptography`` requires the installation of a small number of development dependencies in addition to the dependencies for -:doc:`/installation`. These are listed in ``dev-requirements.txt`` and they can -be installed in a `virtualenv`_ using `pip`_. Before you install them, follow -the **build** instructions in :doc:`/installation` (be sure to stop before -actually installing ``cryptography``). Once you've done that, install the -development dependencies, and then install ``cryptography`` in ``editable`` -mode. For example: +:doc:`/installation`. These are handled by the use of ``tox``, which can be +installed with ``pip``. .. code-block:: console $ # Create a virtualenv and activate it $ # Set up your cryptography build environment - $ pip install --requirement dev-requirements.txt - $ pip install --editable . - -Make sure that ``pip install --requirement ...`` has installed the Python -package ``vectors/`` and packages on ``tests/`` . If it didn't, you may -install them manually by using ``pip`` on each directory. - -You will also need to install ``enchant`` using your system's package manager -to check spelling in the documentation. - -You are now ready to run the tests and build the documentation. + $ pip install tox + $ # Specify your Python version here. + $ tox -e py310 OpenSSL on macOS ~~~~~~~~~~~~~~~~ You must have installed `OpenSSL`_ via `Homebrew`_ or `MacPorts`_ and must set -``CFLAGS`` and ``LDFLAGS`` environment variables before installing the -``dev-requirements.txt`` otherwise pip will fail with include errors. +``CFLAGS`` and ``LDFLAGS`` environment variables before running ``tox`` +otherwise pip will fail with include errors. For example, with `Homebrew`_: @@ -41,7 +30,7 @@ For example, with `Homebrew`_: $ env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" \ CFLAGS="-I$(brew --prefix openssl@1.1)/include" \ - pip install --requirement ./dev-requirements.txt + tox -e py310 Alternatively for a static build you can specify ``CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1`` and ensure ``LDFLAGS`` points to the @@ -54,20 +43,16 @@ Running tests ------------- ``cryptography`` unit tests are found in the ``tests/`` directory and are -designed to be run using `pytest`_. `pytest`_ will discover the tests -automatically, so all you have to do is: +designed to be run using `pytest`_. ``tox`` automatically invokes ``pytest``: .. code-block:: console - $ pytest + $ tox -e py310 ... 62746 passed in 220.43 seconds -This runs the tests with the default Python interpreter. - -You can also verify that the tests pass on other supported Python interpreters. -For this we use `tox`_, which will automatically create a `virtualenv`_ for -each supported Python version and run the tests. For example: +You can also verify that the tests pass on other supported Python interpreters +with ``tox``. For example: .. code-block:: console @@ -75,6 +60,9 @@ each supported Python version and run the tests. For example: ... ERROR: pypy: InterpreterNotFound: pypy py38: commands succeeded + py39: commands succeeded + py310: commands succeeded + py311: commands succeeded docs: commands succeeded pep8: commands succeeded diff --git a/setup.cfg b/setup.cfg index 1830f9b41e78..8a22fec8b068 100644 --- a/setup.cfg +++ b/setup.cfg @@ -55,8 +55,11 @@ exclude = _cffi_src.* [options.extras_require] +tox = + tox test = pytest>=6.2.0 + pytest-shard>=0.1.2 pytest-benchmark pytest-cov pytest-subtests @@ -65,6 +68,8 @@ test = iso8601 pytz hypothesis>=1.11.4,!=3.79.2 +test-randomorder: + pytest-randomly docs = sphinx >= 5.3.0 sphinx-rtd-theme>=1.1.1 @@ -77,6 +82,10 @@ sdist = pep8test = black ruff + mypy + types-pytz + types-requests + check-manifest # This extra is for OpenSSH private keys that use bcrypt KDF # Versions: v3.1.3 - ignore_few_rounds, v3.1.5 - abi3 ssh = diff --git a/tox.ini b/tox.ini index fc30b72f101c..b369da8e9f79 100644 --- a/tox.ini +++ b/tox.ini @@ -6,10 +6,9 @@ isolated_build = True extras = test ssh: ssh + randomorder: test-randomorder deps = -e ./vectors - pytest-shard>=0.1.2 - randomorder: pytest-randomly passenv = ARCHFLAGS LDFLAGS @@ -26,6 +25,8 @@ passenv = CRYPTOGRAPHY_OPENSSL_NO_LEGACY OPENSSL_ENABLE_SHA1_SIGNATURES CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS +setenv = + PIP_CONSTRAINT=ci-constraints-requirements.txt commands = pip list !nocoverage: pytest -n auto --cov=cryptography --cov=tests --durations=10 {posargs} tests/ @@ -59,11 +60,6 @@ extras = pep8test test ssh -deps = - mypy - types-pytz - types-requests - check-manifest commands = ruff . black --check . From 0e510ce89803aa8164f58223d8b56332e31380e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 02:12:25 +0000 Subject: [PATCH 006/827] Bump coverage from 7.0.1 to 7.0.2 (#7965) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.1 to 7.0.2. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.1...7.0.2) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 94cdd247f223..2fed394c3073 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -35,7 +35,7 @@ colorama==0.4.6; python_version >= "3.7" # via tox commonmark==0.9.1 # via rich -coverage==7.0.1; python_version >= "3.7" +coverage==7.0.2; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From ecbf40c6025160788e7dbb758f86cc7735df2776 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 02:32:29 +0000 Subject: [PATCH 007/827] Bump tox from 4.1.2 to 4.1.3 (#7964) Bumps [tox](https://github.com/tox-dev/tox) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.1.2...4.1.3) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2fed394c3073..2aa679009107 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1 # pyproject-api # pytest # tox -tox==4.1.2; python_version >= "3.7" +tox==4.1.3; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From dd0d44398d8e16cef47fb6dd079461e3a751a487 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 02:56:00 +0000 Subject: [PATCH 008/827] Bump ruff from 0.0.206 to 0.0.207 (#7968) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.206 to 0.0.207. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.206...v0.0.207) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2aa679009107..d78fa9350de3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.206 +ruff==0.0.207 # via cryptography (setup.cfg) six==1.16.0 # via bleach From f676e9199eec4973730965744313d0fc6acd98a1 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 2 Jan 2023 22:39:08 -0500 Subject: [PATCH 009/827] use constraints file in benchmark.yml (#7969) --- .github/workflows/benchmark.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e9369f9bc9b6..2058e549e13d 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -35,9 +35,7 @@ jobs: - name: Create virtualenv (main) run: | python -m venv .venv-main - # TODO: add -c ./cryptography-main/ci-constraints-requirements.txt - # after https://github.com/pyca/cryptography/pull/7962 is merged - .venv-main/bin/pip install -v "./cryptography-main[test]" ./cryptography-main/vectors/ + .venv-main/bin/pip install -v -c ./cryptography-main/ci-constraints-requirements.txt "./cryptography-main[test]" ./cryptography-main/vectors/ - name: Create virtualenv (PR) run: | python -m venv .venv-pr From 91f4b7c999d1998ea7fec9889b63a4577f5297b3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 2 Jan 2023 22:40:32 -0500 Subject: [PATCH 010/827] also install coverage in distros jobs (#7970) --- .github/workflows/ci.yml | 2 +- ci-constraints-requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 853b22063fc6..aa1a22373fee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,7 +175,7 @@ jobs: echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt tox + - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt tox coverage - run: '/venv/bin/tox -vvv -- --wycheproof-root="wycheproof"' env: TOXENV: ${{ matrix.IMAGE.TOXENV }} diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d78fa9350de3..04d26650c1f0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -188,7 +188,7 @@ sphinxcontrib-serializinghtml==1.1.5 # via sphinx sphinxcontrib-spelling==7.7.0 # via cryptography (setup.cfg) -tomli==2.0.1 +tomli==2.0.1; python_version >= "3.7" # via # black # build From c5a385af07af99f8f6537d3e21c8d09e7f981351 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 3 Jan 2023 00:18:24 -0500 Subject: [PATCH 011/827] update circleci config for new docker images (#7971) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ceb2a7ee28e5..8cecba9b973d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,7 +32,7 @@ jobs: image: <> - docker-run: image: <> - command: /venv/bin/tox -e <> + command: /venv/bin/pip install -c ci-constraints-requirements.txt tox && /venv/bin/tox -e <> linux-arm64-wheel: machine: image: ubuntu-2004:current From 28f020a0bd18802a4b84b46b0e8d5d3c1a8dc4a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 12:21:57 +0000 Subject: [PATCH 012/827] Bump ruff from 0.0.207 to 0.0.208 (#7972) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.207 to 0.0.208. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.207...v0.0.208) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 04d26650c1f0..13e7f57ea07c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.207 +ruff==0.0.208 # via cryptography (setup.cfg) six==1.16.0 # via bleach From b19fc716a46032a87ff7a0705413c23193bec439 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 12:34:40 +0000 Subject: [PATCH 013/827] Bump ruff from 0.0.208 to 0.0.209 (#7975) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.208 to 0.0.209. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.208...v0.0.209) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 13e7f57ea07c..84596a1df296 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.208 +ruff==0.0.209 # via cryptography (setup.cfg) six==1.16.0 # via bleach From c2d27a969b25a817a635727e5d6c3aa70314a1b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 12:35:11 +0000 Subject: [PATCH 014/827] Bump pyproject-api from 1.2.1 to 1.3.0 (#7976) Bumps [pyproject-api](https://github.com/tox-dev/pyproject-api) from 1.2.1 to 1.3.0. - [Release notes](https://github.com/tox-dev/pyproject-api/releases) - [Changelog](https://github.com/tox-dev/pyproject-api/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/pyproject-api/compare/1.2.1...1.3.0) --- updated-dependencies: - dependency-name: pyproject-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 84596a1df296..405c1c173ded 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -119,7 +119,7 @@ pygments==2.14.0 # readme-renderer # rich # sphinx -pyproject-api==1.2.1 +pyproject-api==1.3.0 # via tox pytest==7.2.0; python_version >= "3.7" # via From 63c481949a81ba8c58e1b8b44289a1340e7de4fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 12:49:26 +0000 Subject: [PATCH 015/827] Bump coverage from 7.0.2 to 7.0.3 (#7977) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.2 to 7.0.3. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.2...7.0.3) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 405c1c173ded..149d67a23678 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -35,7 +35,7 @@ colorama==0.4.6; python_version >= "3.7" # via tox commonmark==0.9.1 # via rich -coverage==7.0.2; python_version >= "3.7" +coverage==7.0.3; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From cdc829794e570de820d0ee189f2b009004d7b9ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 12:51:04 +0000 Subject: [PATCH 016/827] Bump pkginfo from 1.9.2 to 1.9.3 (#7978) Bumps [pkginfo](https://code.launchpad.net/~tseaver/pkginfo/trunk) from 1.9.2 to 1.9.3. --- updated-dependencies: - dependency-name: pkginfo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 149d67a23678..b574544037d7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -95,7 +95,7 @@ pathspec==0.10.3 # via black pep517==0.13.0 # via build -pkginfo==1.9.2 +pkginfo==1.9.3 # via twine platformdirs==2.6.2; python_version >= "3.7" # via From 90a60be57e6ea54a3050e6fa087902a2bc8a7849 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 4 Jan 2023 08:04:56 -0500 Subject: [PATCH 017/827] Increase PR limits for dependabot (#7979) There's limited value in dragging them out. --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 67861ffae223..c6cd0aa8c132 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,7 @@ updates: directory: "/" schedule: interval: "daily" + open-pull-requests-limit: 1024 - package-ecosystem: cargo directory: "/src/rust/" @@ -12,8 +13,10 @@ updates: allow: # Also update indirect dependencies - dependency-type: all + open-pull-requests-limit: 1024 - package-ecosystem: pip directory: "/" schedule: interval: daily + open-pull-requests-limit: 1024 From 26f315908311d4e56ef5673a1c1f00e6ddd42626 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:13:33 +0000 Subject: [PATCH 018/827] Bump tox from 4.1.3 to 4.2.1 (#7974) Bumps [tox](https://github.com/tox-dev/tox) from 4.1.3 to 4.2.1. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.1.3...4.2.1) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b574544037d7..63c1f8141fa0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-api # pytest # tox -tox==4.1.3; python_version >= "3.7" +tox==4.2.1; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From fe1d90232bb24babf94440c6957ce15c5fabc861 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 00:33:00 +0000 Subject: [PATCH 019/827] Bump BoringSSL and/or OpenSSL in CI (#7981) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa1a22373fee..ed8ee759002b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Dec 23, 2022. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "31bad2514d21f6207f3925ba56754611c462a873"}} - # Latest commit on the OpenSSL master branch, as of Dec 29, 2022. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "43a9e682d80d0abe4ffd0c76d18c43cf059a2bcc"}} + # Latest commit on the OpenSSL master branch, as of Jan 05, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "55e2dd8c3162d7313d9408cb20fca8a4fe6e6f5a"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 33105233752e42858d8f6ea52c0ca77f74d9f45b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 5 Jan 2023 20:25:25 +0800 Subject: [PATCH 020/827] small refactor in ssh for key type (#7983) this prevents duplicating this logic more times for ssh certs --- .../hazmat/primitives/serialization/ssh.py | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 7125badb403d..b4951671722c 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -84,6 +84,27 @@ def _bcrypt_kdf( } +def _get_ssh_key_type( + key: typing.Union["_SSH_PRIVATE_KEY_TYPES", "_SSH_PUBLIC_KEY_TYPES"] +) -> bytes: + if isinstance(key, ec.EllipticCurvePrivateKey): + key_type = _ecdsa_key_type(key.public_key()) + elif isinstance(key, ec.EllipticCurvePublicKey): + key_type = _ecdsa_key_type(key) + elif isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): + key_type = _SSH_RSA + elif isinstance(key, (dsa.DSAPrivateKey, dsa.DSAPublicKey)): + key_type = _SSH_DSA + elif isinstance( + key, (ed25519.Ed25519PrivateKey, ed25519.Ed25519PublicKey) + ): + key_type = _SSH_ED25519 + else: + raise ValueError("Unsupported key type") + + return key_type + + def _ecdsa_key_type(public_key: ec.EllipticCurvePublicKey) -> bytes: """Return SSH key_type and curve_name for private key.""" curve = public_key.curve @@ -613,16 +634,7 @@ def _serialize_ssh_private_key( """Serialize private key with OpenSSH custom encoding.""" utils._check_bytes("password", password) - if isinstance(private_key, ec.EllipticCurvePrivateKey): - key_type = _ecdsa_key_type(private_key.public_key()) - elif isinstance(private_key, rsa.RSAPrivateKey): - key_type = _SSH_RSA - elif isinstance(private_key, dsa.DSAPrivateKey): - key_type = _SSH_DSA - elif isinstance(private_key, ed25519.Ed25519PrivateKey): - key_type = _SSH_ED25519 - else: - raise ValueError("Unsupported key type") + key_type = _get_ssh_key_type(private_key) kformat = _lookup_kformat(key_type) # setup parameters @@ -738,16 +750,7 @@ def load_ssh_public_key( def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: """One-line public key format for OpenSSH""" - if isinstance(public_key, ec.EllipticCurvePublicKey): - key_type = _ecdsa_key_type(public_key) - elif isinstance(public_key, rsa.RSAPublicKey): - key_type = _SSH_RSA - elif isinstance(public_key, dsa.DSAPublicKey): - key_type = _SSH_DSA - elif isinstance(public_key, ed25519.Ed25519PublicKey): - key_type = _SSH_ED25519 - else: - raise ValueError("Unsupported key type") + key_type = _get_ssh_key_type(public_key) kformat = _lookup_kformat(key_type) f_pub = _FragList() From a67e6b3b0cc17e41b61284f0ca33066eb529b3d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 12:28:53 +0000 Subject: [PATCH 021/827] Bump ruff from 0.0.209 to 0.0.211 (#7987) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.209 to 0.0.211. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.209...v0.0.211) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 63c1f8141fa0..86ee77050c8e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.209 +ruff==0.0.211 # via cryptography (setup.cfg) six==1.16.0 # via bleach From e308f696d691b6d1e54209a486a5b32886ad7c36 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 5 Jan 2023 20:30:39 +0800 Subject: [PATCH 022/827] move ssh tests to a new file (#7982) --- tests/hazmat/primitives/test_serialization.py | 579 ----------------- tests/hazmat/primitives/test_ssh.py | 604 ++++++++++++++++++ 2 files changed, 604 insertions(+), 579 deletions(-) create mode 100644 tests/hazmat/primitives/test_ssh.py diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 6b026eb8e863..8fb9939d2b44 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -23,7 +23,6 @@ from cryptography.hazmat.primitives.serialization import ( BestAvailableEncryption, Encoding, - KeySerializationEncryption, NoEncryption, PrivateFormat, PublicFormat, @@ -33,13 +32,10 @@ load_pem_parameters, load_pem_private_key, load_pem_public_key, - load_ssh_private_key, load_ssh_public_key, - ssh, ) from cryptography.hazmat.primitives.serialization.pkcs12 import PBES -from ...doubles import DummyKeySerializationEncryption from ...utils import load_vectors_from_file, raises_unsupported_algorithm from .fixtures_rsa import RSA_KEY_2048 from .test_ec import _skip_curve_unsupported @@ -1857,581 +1853,6 @@ def test_dh_private_key(self, backend): private_key.private_bytes(enc, fmt, NoEncryption()) -class TestOpenSSHSerialization: - @pytest.mark.parametrize( - ("key_file", "cert_file"), - [ - ("rsa-psw.key.pub", None), - ("rsa-nopsw.key.pub", "rsa-nopsw.key-cert.pub"), - ("dsa-psw.key.pub", None), - ("dsa-nopsw.key.pub", "dsa-nopsw.key-cert.pub"), - ("ecdsa-psw.key.pub", None), - ("ecdsa-nopsw.key.pub", "ecdsa-nopsw.key-cert.pub"), - ("ed25519-psw.key.pub", None), - ("ed25519-nopsw.key.pub", "ed25519-nopsw.key-cert.pub"), - ], - ) - def test_load_ssh_public_key(self, key_file, cert_file, backend): - if "ed25519" in key_file and not backend.ed25519_supported(): - pytest.skip("Requires OpenSSL with Ed25519 support") - - # normal public key - pub_data = load_vectors_from_file( - os.path.join("asymmetric", "OpenSSH", key_file), - lambda f: f.read(), - mode="rb", - ) - public_key = load_ssh_public_key(pub_data, backend) - nocomment_data = b" ".join(pub_data.split()[:2]) - assert ( - public_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) - - self.run_partial_pubkey(pub_data, backend) - - # parse public key with ssh certificate - if cert_file: - cert_data = load_vectors_from_file( - os.path.join("asymmetric", "OpenSSH", cert_file), - lambda f: f.read(), - mode="rb", - ) - cert_key = load_ssh_public_key(cert_data, backend) - assert ( - cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) - - # try with more spaces - cert_data = b" \t ".join(cert_data.split()) - cert_key = load_ssh_public_key(cert_data, backend) - assert ( - cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) - - self.run_partial_pubkey(cert_data, backend) - - def run_partial_pubkey(self, pubdata, backend): - parts = pubdata.split() - raw = base64.b64decode(parts[1]) - for i in range(1, len(raw)): - frag = base64.b64encode(raw[:i]) - new_pub = b" ".join([parts[0], frag]) - with pytest.raises(ValueError): - load_ssh_public_key(new_pub, backend) - - @pytest.mark.parametrize( - ("key_file",), - [ - ("rsa-nopsw.key",), - ("rsa-psw.key",), - ("dsa-nopsw.key",), - ("dsa-psw.key",), - ("ecdsa-nopsw.key",), - ("ecdsa-psw.key",), - ("ed25519-nopsw.key",), - ("ed25519-psw.key",), - ], - ) - def test_load_ssh_private_key(self, key_file, backend): - if "ed25519" in key_file and not backend.ed25519_supported(): - pytest.skip("Requires OpenSSL with Ed25519 support") - if "-psw" in key_file and not ssh._bcrypt_supported: - pytest.skip("Requires bcrypt module") - - # read public and private key from ssh-keygen - priv_data = load_vectors_from_file( - os.path.join("asymmetric", "OpenSSH", key_file), - lambda f: f.read(), - mode="rb", - ) - pub_data = load_vectors_from_file( - os.path.join("asymmetric", "OpenSSH", key_file + ".pub"), - lambda f: f.read(), - mode="rb", - ) - nocomment_data = b" ".join(pub_data.split()[:2]) - - # load and compare - password = None - if "-psw" in key_file: - password = b"password" - private_key = load_ssh_private_key(priv_data, password, backend) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # bytearray - private_key = load_ssh_private_key( - bytearray(priv_data), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # memoryview(bytes) - private_key = load_ssh_private_key( - memoryview(priv_data), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # memoryview(bytearray) - private_key = load_ssh_private_key( - memoryview(bytearray(priv_data)), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # serialize with own code and reload - encryption: KeySerializationEncryption = NoEncryption() - if password: - encryption = BestAvailableEncryption(password) - priv_data2 = private_key.private_bytes( - Encoding.PEM, - PrivateFormat.OpenSSH, - encryption, - ) - private_key2 = load_ssh_private_key(priv_data2, password, backend) - assert ( - private_key2.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # make sure multi-line base64 is used - maxline = max(map(len, priv_data2.split(b"\n"))) - assert maxline < 80 - - @pytest.mark.supported( - only_if=lambda backend: ssh._bcrypt_supported, - skip_message="Requires that bcrypt exists", - ) - def test_bcrypt_encryption(self, backend): - private_key = ec.generate_private_key(ec.SECP256R1(), backend) - pub1 = private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - - for psw in ( - b"1", - b"1234", - b"1234" * 4, - b"x" * 72, - ): - # BestAvailableEncryption does not handle bytes-like? - best = BestAvailableEncryption(psw) - encdata = private_key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, best - ) - decoded_key = load_ssh_private_key(encdata, psw, backend) - pub2 = decoded_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - assert pub1 == pub2 - - # bytearray - decoded_key2 = load_ssh_private_key( - bytearray(encdata), psw, backend - ) - pub2 = decoded_key2.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - assert pub1 == pub2 - - # memoryview(bytes) - decoded_key2 = load_ssh_private_key( - memoryview(encdata), psw, backend - ) - pub2 = decoded_key2.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - assert pub1 == pub2 - - # memoryview(bytearray) - decoded_key2 = load_ssh_private_key( - memoryview(bytearray(encdata)), psw, backend - ) - pub2 = decoded_key2.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - assert pub1 == pub2 - - with pytest.raises(ValueError): - decoded_key = load_ssh_private_key(encdata, None, backend) - with pytest.raises(ValueError): - decoded_key = load_ssh_private_key(encdata, b"wrong", backend) - - @pytest.mark.supported( - only_if=lambda backend: not ssh._bcrypt_supported, - skip_message="Requires that bcrypt is missing", - ) - def test_missing_bcrypt(self, backend): - priv_data = load_vectors_from_file( - os.path.join("asymmetric", "OpenSSH", "ecdsa-psw.key"), - lambda f: f.read(), - mode="rb", - ) - with raises_unsupported_algorithm(None): - load_ssh_private_key(priv_data, b"password", backend) - - private_key = ec.generate_private_key(ec.SECP256R1(), backend) - with raises_unsupported_algorithm(None): - private_key.private_bytes( - Encoding.PEM, - PrivateFormat.OpenSSH, - BestAvailableEncryption(b"x"), - ) - - def test_fraglist_corners(self): - f = ssh._FragList() - with pytest.raises(ValueError): - f.put_mpint(-1) - f.put_mpint(0) - f.put_mpint(0x80) - assert f.tobytes() == b"\0\0\0\0" + b"\0\0\0\x02" + b"\0\x80" - - def make_file( - self, - magic=b"openssh-key-v1\0", - ciphername=b"none", - kdfname=b"none", - kdfoptions=b"", - nkeys=1, - pub_type=b"ecdsa-sha2-nistp256", - pub_fields=( - b"nistp256", - b"\x04" * 65, - ), - priv_type=None, - priv_fields=(b"nistp256", b"\x04" * 65, b"\x7F" * 32), - comment=b"comment", - checkval1=b"1234", - checkval2=b"1234", - pad=None, - header=b"-----BEGIN OPENSSH PRIVATE KEY-----\n", - footer=b"-----END OPENSSH PRIVATE KEY-----\n", - cut=8192, - ): - """Create private key file""" - if not priv_type: - priv_type = pub_type - - pub = ssh._FragList() - for elem in (pub_type,) + pub_fields: - pub.put_sshstr(elem) - - secret = ssh._FragList([checkval1, checkval2]) - for i in range(nkeys): - for elem in (priv_type,) + priv_fields + (comment,): - secret.put_sshstr(elem) - - if pad is None: - pad_len = 8 - (secret.size() % 8) - pad = bytearray(range(1, 1 + pad_len)) - secret.put_raw(pad) - - main = ssh._FragList([magic]) - main.put_sshstr(ciphername) - main.put_sshstr(kdfname) - main.put_sshstr(kdfoptions) - main.put_u32(nkeys) - for i in range(nkeys): - main.put_sshstr(pub) - main.put_sshstr(secret) - - res = main.tobytes() - return ssh._ssh_pem_encode(res[:cut], header, footer) - - def test_ssh_make_file(self, backend): - # check if works by default - data = self.make_file() - key = load_ssh_private_key(data, None, backend) - assert isinstance(key, ec.EllipticCurvePrivateKey) - - def test_load_ssh_private_key_errors(self, backend): - # bad kdf - data = self.make_file(kdfname=b"unknown", ciphername=b"aes256-ctr") - with raises_unsupported_algorithm(None): - load_ssh_private_key(data, None, backend) - - # bad cipher - data = self.make_file(ciphername=b"unknown", kdfname=b"bcrypt") - with raises_unsupported_algorithm(None): - load_ssh_private_key(data, None, backend) - - # bad magic - data = self.make_file(magic=b"unknown") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # too few keys - data = self.make_file(nkeys=0) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # too many keys - data = self.make_file(nkeys=2) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - def test_ssh_errors_bad_values(self, backend): - # bad curve - data = self.make_file(pub_type=b"ecdsa-sha2-nistp444") - with raises_unsupported_algorithm(None): - load_ssh_private_key(data, None, backend) - - # curve mismatch - data = self.make_file(priv_type=b"ecdsa-sha2-nistp384") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # invalid bigint - data = self.make_file( - priv_fields=(b"nistp256", b"\x04" * 65, b"\x80" * 32) - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - def test_ssh_errors_pubpriv_mismatch(self, backend): - # ecdsa public-private mismatch - data = self.make_file( - pub_fields=( - b"nistp256", - b"\x04" + b"\x05" * 64, - ) - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # rsa public-private mismatch - data = self.make_file( - pub_type=b"ssh-rsa", - pub_fields=(b"x" * 32,) * 2, - priv_fields=(b"z" * 32,) * 6, - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # dsa public-private mismatch - data = self.make_file( - pub_type=b"ssh-dss", - pub_fields=(b"x" * 32,) * 4, - priv_fields=(b"z" * 32,) * 5, - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # ed25519 public-private mismatch - sk = b"x" * 32 - pk1 = b"y" * 32 - pk2 = b"z" * 32 - data = self.make_file( - pub_type=b"ssh-ed25519", - pub_fields=(pk1,), - priv_fields=( - pk1, - sk + pk2, - ), - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - data = self.make_file( - pub_type=b"ssh-ed25519", - pub_fields=(pk1,), - priv_fields=( - pk2, - sk + pk1, - ), - ) - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - def test_ssh_errors_bad_wrapper(self, backend): - # wrong header - data = self.make_file(header=b"-----BEGIN RSA PRIVATE KEY-----\n") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # wring footer - data = self.make_file(footer=b"-----END RSA PRIVATE KEY-----\n") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - def test_ssh_no_padding(self, backend): - # no padding must work, if data is on block boundary - data = self.make_file(pad=b"", comment=b"") - key = load_ssh_private_key(data, None, backend) - assert isinstance(key, ec.EllipticCurvePrivateKey) - - # no padding with right last byte - data = self.make_file(pad=b"", comment=b"\x08" * 8) - key = load_ssh_private_key(data, None, backend) - assert isinstance(key, ec.EllipticCurvePrivateKey) - - # avoid unexpected padding removal - data = self.make_file(pad=b"", comment=b"1234\x01\x02\x03\x04") - key = load_ssh_private_key(data, None, backend) - assert isinstance(key, ec.EllipticCurvePrivateKey) - - # bad padding with right size - data = self.make_file(pad=b"\x08" * 8, comment=b"") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - def test_ssh_errors_bad_secrets(self, backend): - # checkval mismatch - data = self.make_file(checkval2=b"4321") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - # bad padding, correct=1 - data = self.make_file(pad=b"\x01\x02") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - data = self.make_file(pad=b"") - with pytest.raises(ValueError): - load_ssh_private_key(data, None, backend) - - @pytest.mark.supported( - only_if=lambda backend: backend.elliptic_curve_supported( - ec.SECP192R1() - ), - skip_message="Requires backend support for ec.SECP192R1", - ) - def test_serialize_ssh_private_key_errors_bad_curve(self, backend): - private_key = ec.generate_private_key(ec.SECP192R1(), backend) - with pytest.raises(ValueError): - private_key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() - ) - - def test_serialize_ssh_private_key_errors(self, backend): - # bad encoding - private_key = ec.generate_private_key(ec.SECP256R1(), backend) - with pytest.raises(ValueError): - private_key.private_bytes( - Encoding.DER, PrivateFormat.OpenSSH, NoEncryption() - ) - - # bad object type - with pytest.raises(ValueError): - ssh._serialize_ssh_private_key( - object(), # type:ignore[arg-type] - b"", - NoEncryption(), - ) - - private_key = ec.generate_private_key(ec.SECP256R1(), backend) - - # unknown encryption class - with pytest.raises(ValueError): - private_key.private_bytes( - Encoding.PEM, - PrivateFormat.OpenSSH, - DummyKeySerializationEncryption(), - ) - - @pytest.mark.supported( - only_if=lambda backend: ssh._bcrypt_supported, - skip_message="Requires that bcrypt exists", - ) - @pytest.mark.parametrize( - "password", - ( - b"1234", - b"p@ssw0rd", - b"x" * 100, - ), - ) - @pytest.mark.parametrize( - "kdf_rounds", - [ - 1, - 10, - 30, - ], - ) - def test_serialize_ssh_private_key_with_password( - self, password, kdf_rounds, backend - ): - original_key = ec.generate_private_key(ec.SECP256R1(), backend) - encoded_key_data = original_key.private_bytes( - Encoding.PEM, - PrivateFormat.OpenSSH, - ( - PrivateFormat.OpenSSH.encryption_builder() - .kdf_rounds(kdf_rounds) - .build(password) - ), - ) - - decoded_key = load_ssh_private_key( - data=encoded_key_data, - password=password, - backend=backend, - ) - - original_public_key = original_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - - decoded_public_key = decoded_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - - assert original_public_key == decoded_public_key - - @pytest.mark.supported( - only_if=lambda backend: backend.dsa_supported(), - skip_message="Does not support DSA.", - ) - @pytest.mark.parametrize( - ("key_path", "supported"), - [ - (["Traditional_OpenSSL_Serialization", "dsa.1024.pem"], True), - (["Traditional_OpenSSL_Serialization", "dsa.2048.pem"], False), - (["Traditional_OpenSSL_Serialization", "dsa.3072.pem"], False), - ], - ) - def test_dsa_private_key_sizes(self, key_path, supported, backend): - key = load_vectors_from_file( - os.path.join("asymmetric", *key_path), - lambda pemfile: load_pem_private_key( - pemfile.read(), None, backend - ), - mode="rb", - ) - assert isinstance(key, dsa.DSAPrivateKey) - if supported: - res = key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() - ) - assert isinstance(res, bytes) - else: - with pytest.raises(ValueError): - key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() - ) - - class TestEncryptionBuilder: def test_unsupported_format(self): f = PrivateFormat.PKCS8 diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py new file mode 100644 index 000000000000..0446a6490b13 --- /dev/null +++ b/tests/hazmat/primitives/test_ssh.py @@ -0,0 +1,604 @@ +# 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. + + +import base64 +import os + +import pytest + +from cryptography.hazmat.primitives.asymmetric import ( + dsa, + ec, +) +from cryptography.hazmat.primitives.serialization import ( + BestAvailableEncryption, + Encoding, + KeySerializationEncryption, + NoEncryption, + PrivateFormat, + PublicFormat, + load_pem_private_key, + load_ssh_private_key, + load_ssh_public_key, + ssh, +) + +from ...doubles import DummyKeySerializationEncryption +from ...utils import load_vectors_from_file, raises_unsupported_algorithm + + +class TestOpenSSHSerialization: + @pytest.mark.parametrize( + ("key_file", "cert_file"), + [ + ("rsa-psw.key.pub", None), + ("rsa-nopsw.key.pub", "rsa-nopsw.key-cert.pub"), + ("dsa-psw.key.pub", None), + ("dsa-nopsw.key.pub", "dsa-nopsw.key-cert.pub"), + ("ecdsa-psw.key.pub", None), + ("ecdsa-nopsw.key.pub", "ecdsa-nopsw.key-cert.pub"), + ("ed25519-psw.key.pub", None), + ("ed25519-nopsw.key.pub", "ed25519-nopsw.key-cert.pub"), + ], + ) + def test_load_ssh_public_key(self, key_file, cert_file, backend): + if "ed25519" in key_file and not backend.ed25519_supported(): + pytest.skip("Requires OpenSSL with Ed25519 support") + + # normal public key + pub_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", key_file), + lambda f: f.read(), + mode="rb", + ) + public_key = load_ssh_public_key(pub_data, backend) + nocomment_data = b" ".join(pub_data.split()[:2]) + assert ( + public_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) + == nocomment_data + ) + + self.run_partial_pubkey(pub_data, backend) + + # parse public key with ssh certificate + if cert_file: + cert_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", cert_file), + lambda f: f.read(), + mode="rb", + ) + cert_key = load_ssh_public_key(cert_data, backend) + assert ( + cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) + == nocomment_data + ) + + # try with more spaces + cert_data = b" \t ".join(cert_data.split()) + cert_key = load_ssh_public_key(cert_data, backend) + assert ( + cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) + == nocomment_data + ) + + self.run_partial_pubkey(cert_data, backend) + + def run_partial_pubkey(self, pubdata, backend): + parts = pubdata.split() + raw = base64.b64decode(parts[1]) + for i in range(1, len(raw)): + frag = base64.b64encode(raw[:i]) + new_pub = b" ".join([parts[0], frag]) + with pytest.raises(ValueError): + load_ssh_public_key(new_pub, backend) + + @pytest.mark.parametrize( + ("key_file",), + [ + ("rsa-nopsw.key",), + ("rsa-psw.key",), + ("dsa-nopsw.key",), + ("dsa-psw.key",), + ("ecdsa-nopsw.key",), + ("ecdsa-psw.key",), + ("ed25519-nopsw.key",), + ("ed25519-psw.key",), + ], + ) + def test_load_ssh_private_key(self, key_file, backend): + if "ed25519" in key_file and not backend.ed25519_supported(): + pytest.skip("Requires OpenSSL with Ed25519 support") + if "-psw" in key_file and not ssh._bcrypt_supported: + pytest.skip("Requires bcrypt module") + + # read public and private key from ssh-keygen + priv_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", key_file), + lambda f: f.read(), + mode="rb", + ) + pub_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", key_file + ".pub"), + lambda f: f.read(), + mode="rb", + ) + nocomment_data = b" ".join(pub_data.split()[:2]) + + # load and compare + password = None + if "-psw" in key_file: + password = b"password" + private_key = load_ssh_private_key(priv_data, password, backend) + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + + # bytearray + private_key = load_ssh_private_key( + bytearray(priv_data), password, backend + ) + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + + # memoryview(bytes) + private_key = load_ssh_private_key( + memoryview(priv_data), password, backend + ) + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + + # memoryview(bytearray) + private_key = load_ssh_private_key( + memoryview(bytearray(priv_data)), password, backend + ) + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + + # serialize with own code and reload + encryption: KeySerializationEncryption = NoEncryption() + if password: + encryption = BestAvailableEncryption(password) + priv_data2 = private_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + encryption, + ) + private_key2 = load_ssh_private_key(priv_data2, password, backend) + assert ( + private_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + + # make sure multi-line base64 is used + maxline = max(map(len, priv_data2.split(b"\n"))) + assert maxline < 80 + + @pytest.mark.supported( + only_if=lambda backend: ssh._bcrypt_supported, + skip_message="Requires that bcrypt exists", + ) + def test_bcrypt_encryption(self, backend): + private_key = ec.generate_private_key(ec.SECP256R1(), backend) + pub1 = private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + + for psw in ( + b"1", + b"1234", + b"1234" * 4, + b"x" * 72, + ): + # BestAvailableEncryption does not handle bytes-like? + best = BestAvailableEncryption(psw) + encdata = private_key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, best + ) + decoded_key = load_ssh_private_key(encdata, psw, backend) + pub2 = decoded_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + assert pub1 == pub2 + + # bytearray + decoded_key2 = load_ssh_private_key( + bytearray(encdata), psw, backend + ) + pub2 = decoded_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + assert pub1 == pub2 + + # memoryview(bytes) + decoded_key2 = load_ssh_private_key( + memoryview(encdata), psw, backend + ) + pub2 = decoded_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + assert pub1 == pub2 + + # memoryview(bytearray) + decoded_key2 = load_ssh_private_key( + memoryview(bytearray(encdata)), psw, backend + ) + pub2 = decoded_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + assert pub1 == pub2 + + with pytest.raises(ValueError): + decoded_key = load_ssh_private_key(encdata, None, backend) + with pytest.raises(ValueError): + decoded_key = load_ssh_private_key(encdata, b"wrong", backend) + + @pytest.mark.supported( + only_if=lambda backend: not ssh._bcrypt_supported, + skip_message="Requires that bcrypt is missing", + ) + def test_missing_bcrypt(self, backend): + priv_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "ecdsa-psw.key"), + lambda f: f.read(), + mode="rb", + ) + with raises_unsupported_algorithm(None): + load_ssh_private_key(priv_data, b"password", backend) + + private_key = ec.generate_private_key(ec.SECP256R1(), backend) + with raises_unsupported_algorithm(None): + private_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + BestAvailableEncryption(b"x"), + ) + + def test_fraglist_corners(self): + f = ssh._FragList() + with pytest.raises(ValueError): + f.put_mpint(-1) + f.put_mpint(0) + f.put_mpint(0x80) + assert f.tobytes() == b"\0\0\0\0" + b"\0\0\0\x02" + b"\0\x80" + + def make_file( + self, + magic=b"openssh-key-v1\0", + ciphername=b"none", + kdfname=b"none", + kdfoptions=b"", + nkeys=1, + pub_type=b"ecdsa-sha2-nistp256", + pub_fields=( + b"nistp256", + b"\x04" * 65, + ), + priv_type=None, + priv_fields=(b"nistp256", b"\x04" * 65, b"\x7F" * 32), + comment=b"comment", + checkval1=b"1234", + checkval2=b"1234", + pad=None, + header=b"-----BEGIN OPENSSH PRIVATE KEY-----\n", + footer=b"-----END OPENSSH PRIVATE KEY-----\n", + cut=8192, + ): + """Create private key file""" + if not priv_type: + priv_type = pub_type + + pub = ssh._FragList() + for elem in (pub_type,) + pub_fields: + pub.put_sshstr(elem) + + secret = ssh._FragList([checkval1, checkval2]) + for i in range(nkeys): + for elem in (priv_type,) + priv_fields + (comment,): + secret.put_sshstr(elem) + + if pad is None: + pad_len = 8 - (secret.size() % 8) + pad = bytearray(range(1, 1 + pad_len)) + secret.put_raw(pad) + + main = ssh._FragList([magic]) + main.put_sshstr(ciphername) + main.put_sshstr(kdfname) + main.put_sshstr(kdfoptions) + main.put_u32(nkeys) + for i in range(nkeys): + main.put_sshstr(pub) + main.put_sshstr(secret) + + res = main.tobytes() + return ssh._ssh_pem_encode(res[:cut], header, footer) + + def test_ssh_make_file(self, backend): + # check if works by default + data = self.make_file() + key = load_ssh_private_key(data, None, backend) + assert isinstance(key, ec.EllipticCurvePrivateKey) + + def test_load_ssh_private_key_errors(self, backend): + # bad kdf + data = self.make_file(kdfname=b"unknown", ciphername=b"aes256-ctr") + with raises_unsupported_algorithm(None): + load_ssh_private_key(data, None, backend) + + # bad cipher + data = self.make_file(ciphername=b"unknown", kdfname=b"bcrypt") + with raises_unsupported_algorithm(None): + load_ssh_private_key(data, None, backend) + + # bad magic + data = self.make_file(magic=b"unknown") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # too few keys + data = self.make_file(nkeys=0) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # too many keys + data = self.make_file(nkeys=2) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + def test_ssh_errors_bad_values(self, backend): + # bad curve + data = self.make_file(pub_type=b"ecdsa-sha2-nistp444") + with raises_unsupported_algorithm(None): + load_ssh_private_key(data, None, backend) + + # curve mismatch + data = self.make_file(priv_type=b"ecdsa-sha2-nistp384") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # invalid bigint + data = self.make_file( + priv_fields=(b"nistp256", b"\x04" * 65, b"\x80" * 32) + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + def test_ssh_errors_pubpriv_mismatch(self, backend): + # ecdsa public-private mismatch + data = self.make_file( + pub_fields=( + b"nistp256", + b"\x04" + b"\x05" * 64, + ) + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # rsa public-private mismatch + data = self.make_file( + pub_type=b"ssh-rsa", + pub_fields=(b"x" * 32,) * 2, + priv_fields=(b"z" * 32,) * 6, + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # dsa public-private mismatch + data = self.make_file( + pub_type=b"ssh-dss", + pub_fields=(b"x" * 32,) * 4, + priv_fields=(b"z" * 32,) * 5, + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # ed25519 public-private mismatch + sk = b"x" * 32 + pk1 = b"y" * 32 + pk2 = b"z" * 32 + data = self.make_file( + pub_type=b"ssh-ed25519", + pub_fields=(pk1,), + priv_fields=( + pk1, + sk + pk2, + ), + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + data = self.make_file( + pub_type=b"ssh-ed25519", + pub_fields=(pk1,), + priv_fields=( + pk2, + sk + pk1, + ), + ) + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + def test_ssh_errors_bad_wrapper(self, backend): + # wrong header + data = self.make_file(header=b"-----BEGIN RSA PRIVATE KEY-----\n") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # wring footer + data = self.make_file(footer=b"-----END RSA PRIVATE KEY-----\n") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + def test_ssh_no_padding(self, backend): + # no padding must work, if data is on block boundary + data = self.make_file(pad=b"", comment=b"") + key = load_ssh_private_key(data, None, backend) + assert isinstance(key, ec.EllipticCurvePrivateKey) + + # no padding with right last byte + data = self.make_file(pad=b"", comment=b"\x08" * 8) + key = load_ssh_private_key(data, None, backend) + assert isinstance(key, ec.EllipticCurvePrivateKey) + + # avoid unexpected padding removal + data = self.make_file(pad=b"", comment=b"1234\x01\x02\x03\x04") + key = load_ssh_private_key(data, None, backend) + assert isinstance(key, ec.EllipticCurvePrivateKey) + + # bad padding with right size + data = self.make_file(pad=b"\x08" * 8, comment=b"") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + def test_ssh_errors_bad_secrets(self, backend): + # checkval mismatch + data = self.make_file(checkval2=b"4321") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + # bad padding, correct=1 + data = self.make_file(pad=b"\x01\x02") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + data = self.make_file(pad=b"") + with pytest.raises(ValueError): + load_ssh_private_key(data, None, backend) + + @pytest.mark.supported( + only_if=lambda backend: backend.elliptic_curve_supported( + ec.SECP192R1() + ), + skip_message="Requires backend support for ec.SECP192R1", + ) + def test_serialize_ssh_private_key_errors_bad_curve(self, backend): + private_key = ec.generate_private_key(ec.SECP192R1(), backend) + with pytest.raises(ValueError): + private_key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() + ) + + def test_serialize_ssh_private_key_errors(self, backend): + # bad encoding + private_key = ec.generate_private_key(ec.SECP256R1(), backend) + with pytest.raises(ValueError): + private_key.private_bytes( + Encoding.DER, PrivateFormat.OpenSSH, NoEncryption() + ) + + # bad object type + with pytest.raises(ValueError): + ssh._serialize_ssh_private_key( + object(), # type:ignore[arg-type] + b"", + NoEncryption(), + ) + + private_key = ec.generate_private_key(ec.SECP256R1(), backend) + + # unknown encryption class + with pytest.raises(ValueError): + private_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + DummyKeySerializationEncryption(), + ) + + @pytest.mark.supported( + only_if=lambda backend: ssh._bcrypt_supported, + skip_message="Requires that bcrypt exists", + ) + @pytest.mark.parametrize( + "password", + ( + b"1234", + b"p@ssw0rd", + b"x" * 100, + ), + ) + @pytest.mark.parametrize( + "kdf_rounds", + [ + 1, + 10, + 30, + ], + ) + def test_serialize_ssh_private_key_with_password( + self, password, kdf_rounds, backend + ): + original_key = ec.generate_private_key(ec.SECP256R1(), backend) + encoded_key_data = original_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + ( + PrivateFormat.OpenSSH.encryption_builder() + .kdf_rounds(kdf_rounds) + .build(password) + ), + ) + + decoded_key = load_ssh_private_key( + data=encoded_key_data, + password=password, + backend=backend, + ) + + original_public_key = original_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + + decoded_public_key = decoded_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + + assert original_public_key == decoded_public_key + + @pytest.mark.supported( + only_if=lambda backend: backend.dsa_supported(), + skip_message="Does not support DSA.", + ) + @pytest.mark.parametrize( + ("key_path", "supported"), + [ + (["Traditional_OpenSSL_Serialization", "dsa.1024.pem"], True), + (["Traditional_OpenSSL_Serialization", "dsa.2048.pem"], False), + (["Traditional_OpenSSL_Serialization", "dsa.3072.pem"], False), + ], + ) + def test_dsa_private_key_sizes(self, key_path, supported, backend): + key = load_vectors_from_file( + os.path.join("asymmetric", *key_path), + lambda pemfile: load_pem_private_key( + pemfile.read(), None, backend + ), + mode="rb", + ) + assert isinstance(key, dsa.DSAPrivateKey) + if supported: + res = key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() + ) + assert isinstance(res, bytes) + else: + with pytest.raises(ValueError): + key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() + ) From 6bab5f52fc6123f8eb00154371fc78bf320a5c95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 12:33:23 +0000 Subject: [PATCH 023/827] Bump tox from 4.2.1 to 4.2.3 (#7988) Bumps [tox](https://github.com/tox-dev/tox) from 4.2.1 to 4.2.3. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.2.1...4.2.3) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 86ee77050c8e..93f5dc09b71c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-api # pytest # tox -tox==4.2.1; python_version >= "3.7" +tox==4.2.3; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 8554696b7a2fe0f04d4db9e39e03db8b399d04fc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 5 Jan 2023 20:34:44 +0800 Subject: [PATCH 024/827] add arm64 pypy38 and pyp39 on manylinux_2_28 (#7986) --- .circleci/build-wheel.sh | 2 +- .circleci/config.yml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.circleci/build-wheel.sh b/.circleci/build-wheel.sh index d69e8c9213fe..26bb00df4933 100755 --- a/.circleci/build-wheel.sh +++ b/.circleci/build-wheel.sh @@ -25,7 +25,7 @@ fi LDFLAGS="-L/opt/pyca/cryptography/openssl/lib" \ CFLAGS="-I/opt/pyca/cryptography/openssl/include -Wl,--exclude-libs,ALL" \ - ../../.venv/bin/python setup.py bdist_wheel "$PY_LIMITED_API" + ../../.venv/bin/python setup.py bdist_wheel $PY_LIMITED_API auditwheel repair --plat "${PLATFORM}" -w wheelhouse/ dist/cryptography*.whl diff --git a/.circleci/config.yml b/.circleci/config.yml index 8cecba9b973d..566c14c91a06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,6 +102,22 @@ workflows: filters: tags: only: /.*/ + - linux-arm64-wheel: + name: manylinux_2_28_aarch64-wheel + image: ghcr.io/pyca/cryptography-manylinux_2_28:aarch64 + python: pp38-pypy38_pp73 + platform: manylinux_2_28_aarch64 + filters: + tags: + only: /.*/ + - linux-arm64-wheel: + name: manylinux_2_28_aarch64-wheel + image: ghcr.io/pyca/cryptography-manylinux_2_28:aarch64 + python: pp39-pypy39_pp73 + platform: manylinux_2_28_aarch64 + filters: + tags: + only: /.*/ - linux-arm64-wheel: name: musllinux_1_1_aarch64-wheel image: ghcr.io/pyca/cryptography-musllinux_1_1:aarch64 From 2aaa272c1287b5750fdd0bbf9843d1e64daa4fed Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 5 Jan 2023 20:41:22 +0800 Subject: [PATCH 025/827] add ssh certificate test vectors (#7984) --- docs/development/test-vectors.rst | 21 +++++++++++++++++++ .../asymmetric/OpenSSH/certs/dsa-p256.pub | 1 + .../asymmetric/OpenSSH/certs/p256-dsa.pub | 1 + .../p256-p256-broken-signature-key-type.pub | 1 + .../certs/p256-p256-duplicate-crit-opts.pub | 1 + .../certs/p256-p256-duplicate-extension.pub | 1 + .../certs/p256-p256-empty-principals.pub | 1 + .../certs/p256-p256-non-lexical-crit-opts.pub | 1 + .../p256-p256-non-lexical-extensions.pub | 1 + 9 files changed, 29 insertions(+) create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/dsa-p256.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-dsa.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-broken-signature-key-type.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-crit-opts.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-extension.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-empty-principals.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-crit-opts.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-extensions.pub diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 256ee9d9a4c7..32e1f01c04f4 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -823,6 +823,27 @@ using command-line tools from OpenSSH_7.6p1 package. Password-protected RSA-2048 private key and corresponding public key. Password is "password". +Custom OpenSSH Certificate Test Vectors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``p256-p256-duplicate-extension.pub`` - A certificate with a duplicate + extension. +* ``p256-p256-non-lexical-extensions.pub`` - A certificate with extensions + in non-lexical order. +* ``p256-p256-duplicate-crit-opts.pub`` - A certificate with a duplicate + critical option. +* ``p256-p256-non-lexical-crit-opts.pub`` - A certificate with critical + options in non-lexical order. +* ``dsa-p256.pub`` - A certificate with a DSA public key signed by a P256 + CA. +* ``p256-dsa.pub`` - A certificate with a P256 public key signed by a DSA + CA. +* ``p256-p256-broken-signature-key-type.pub`` - A certificate with a P256 + public key signed by a P256 CA, but the signature key type is set to + ``rsa-sha2-512``. +* ``p256-p256-empty-principals.pub`` - A certificate with a P256 public + key signed by a P256 CA with an empty valid principals list. + Hashes ~~~~~~ diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/dsa-p256.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/dsa-p256.pub new file mode 100644 index 000000000000..3e9cd30ef1fc --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/dsa-p256.pub @@ -0,0 +1 @@ +ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgIE0DERxEocGf8SILUWuT5wakv34qIiz0+1/fQVf0PYQAAACBAPloKFUpz5YJF4doiftzBT3wlM37PvuklYVczyOr8HCn4srUK4Zwe13Ce/Ee+Ibpy3nECDI9AICjYycWOVVbpDAy4nFDpsWal/nxL1wFIocSVD3eiDK0sCJI0JoKN8CtARnX4EmMwa8VJW9VyHZyRQ2LMKHsIY3WYoJswmMk+uRtAAAAFQCbeL/Q/whJsTM5Mz42+p2NA0MAJwAAAIEAjhE+6yBllAn2AFUoMN9kC5dSxWrcVG8flczdhGDfryTTO7ouUlZEQXjtgc8XDaz3ABttq8WDmihsJ10F9QY/jh4D6ml8tFL4F59CiiImZHSnUv5GBVzkp/P26a9q/PJr9VwQEhIwDQ4lEOHPApBTQFMjDhEO+/5seqWDerzcuJkAAACAJn80y6FFao0jV4WVK8O5x2DFAmX2ic3DcjZiehRtB7ar9FQJfkLRFgq4AqR683n2DyO2Mta4mNVuLEcmHO+uC08BRbwx3CuftAXUDsMK+4bcZFQGNtBfIQHugA58sIvjBENlEfbZwNNLiyzKtG7W+61WZEnNb5FBNHH8lSCMJ04AAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAACAAAAAYY3JpdGljYWxAY3J5cHRvZ3JhcGh5LmlvAAAAAAAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQSVuxZ77Yb35R81SnzVzIhFlOJ8KDTC7O3KL/OFzutJJ71Uah4j9ixchyr+uY3SpUnE0NqHqKTZYOMe/9MJzCdWAAAAZAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASQAAACEA99MMfmfSFIYvB1EF3s7mWXqUsch4sdf+I28jr1SUKD8AAAAgY04RTcT1vqMzs5bVoO0vF/RfQyr06Z1IDzCX1l3h70k= \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-dsa.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-dsa.pub new file mode 100644 index 000000000000..fafb77de94c0 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-dsa.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgqlL0IDRu6PBXcHrEqr66w+nW4TWpgWcqB9/SiSVsHk0AAAAIbmlzdHAyNTYAAABBBKxrpV0taLLnqbE08WQoMGmopbPBTC1Vj3GLi4/+n9BINlKBskAjhVfQdfLzse4REtYbNH2iOseHS/r1l+jj2REAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAACAAAAAYY3JpdGljYWxAY3J5cHRvZ3JhcGh5LmlvAAAAAAAAAAAAAAAAAAABsgAAAAdzc2gtZHNzAAAAgQC2BuglMCTWhV809q9omijAGP+z54k1BwCdFngTXr4k4Nm5DAsbUUaaQuELVK+oeB/iClhq17ghSM6gbGRZRZYlyBNfp05w77aKzw7w+0Z3JY8FDjwvsE6hWK7oWTUIF+79Nwe6QdHuryVsXKOG6YmKC+CPzSnpZ8jEGtCnI/HGqQAAABUA0UVWDteeovroX1jW5a0kbBbqnxUAAACAYkibo7SpYozbSObn2YlwLPa0phfpYcLmtwtZFaraYcJWsUSA8F4UATXNCxVPqwsl7PJfmGcJ+T+wvL16VxoCXsGqOgSNox3eVkGlwxF964AQ8BON77gi+ho6zw9ALoHUEDAKLwupRKXLoqLoRe+0T3//zokR3PX1JMbdraIgBcUAAACBAK41XlUiNgUc2fgcRhcPgFP7Ru1NxQ/a+muyfbcWaHPrOW5Jb90MfhmIqktc6tbqUceGtH2qqch1lxdaCw4e1sjeDsd0wnrIQcg4occQqZ2PYu3K3tcclyBXtVbzpxXq18QPUtl9idIDZ17L64iZgO1+EKlMsl0dZBtH37SWxIoWAAAANwAAAAdzc2gtZHNzAAAAKIvmGjVssyGoO4sCGCyz2wDCXUtMMbDxAp8nKRk6H0XdXoixPGY0oAo= \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-broken-signature-key-type.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-broken-signature-key-type.pub new file mode 100644 index 000000000000..83d90f8909c7 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-broken-signature-key-type.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg5F1PDG/y2CzJp73derFFtoa/OJjJQZ1jaQKqf2nKciQAAAAIbmlzdHAyNTYAAABBBL4QG3yEahvircH4Px+aVHip40dqWot+JJB3TuyFGN5rCDP4eZmM5gmTIDJw+Y3uJk/8oP44nSXmUhceEI01LlMAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAACIAAAAaaW52YWxpZHNpZ0BjcnlwdG9ncmFwaHkuaW8AAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBINdZJ7jyyOqECwnOcDNw8OHgHwTU8uexxAU8Qs/QYv3bmjR7ExP9QVGKzWJ2LxyCzIwt+wjjt/7Y/DGWJ5ja5kAAABeAAAADHJzYS1zaGEyLTI1NgAAAEoAAAAhAIYe8pC0okwX8m6lbsdSNZFhNl5GXGKMvy0Czi33NktHAAAAIQDLKohBedhNdftYor3+G2mSFAJFGM/fDJgs8L3cOEsYfQ== \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-crit-opts.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-crit-opts.pub new file mode 100644 index 000000000000..01b6233a1511 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-crit-opts.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLhqcBHfeQKtL85NO1EYeTF6EWUPuCswcuhsj4jN8+9gAAAAIbmlzdHAyNTYAAABBBMnYLqlS1l6aEf5MAzEnTd2rfYYAdaesNxUsSW+2/QyIE0KiR1OOqnth+V+8JDTWBf78EcqxLOaz7Icw8d4dOzAAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAAEIAAAAZZHVwbGljYXRlQGNyeXB0b2dyYXBoeS5pbwAAAAAAAAAZZHVwbGljYXRlQGNyeXB0b2dyYXBoeS5pbwAAAAAAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEEbA70TLh7ri83WgjRWsQc0dP146vVEFhHqSdKHw8TMScFt4pcJnBcCPmr2TvxUdNcDHfum11bQWuAxvOOZ/RfxAAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAOP5SYGetAQ849rV+ezStHi2WRkRLA6QnBrWXFWjtTNzAAAAIESwusuQ5ucNFnxR/B+mF8Fcwk22mx09i5vATfJSTNxW \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-extension.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-extension.pub new file mode 100644 index 000000000000..900d700094f4 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-duplicate-extension.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgN6rRGEpLjA1BohPwr8SEa33Vn4+H+94Jifl6hg6n5IIAAAAIbmlzdHAyNTYAAABBBFQDtz1+0wnP2wLnHZhES+XJVxImzusYhXd3G2cWCZL4HKZHRMIWj1x6oU9JdoEOMHppb6DK/OIFsXHwJeRBOOwAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAAAAAAAA+AAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQlhngteNXbqpH+iOYQyIWciB0SCfHkjXir3gZXszfzWka1sP0LIHAtszMTofPG0+SosIKtZWfiJvh0BoxtbthJAAAAZQAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASgAAACEAyAyVc+9ORWbQ/LdtR82+rKUxfMkD1wWDarYHk4mAWWIAAAAhALnEsJAtB4AVsNIC8COVeEEjmsPSQt4seHF6V5u7IWw9 \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-empty-principals.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-empty-principals.pub new file mode 100644 index 000000000000..9f2e27130fca --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-empty-principals.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgBXWXwDzsP++5IxnXmRrXXXP5wyJzMXW1nnQh7DPYZx8AAAAIbmlzdHAyNTYAAABBBCuO1AQsw/HmbXrjAHBJ7YA1ydYJeNbZ6LSArnxvrTX9kXDWF4bfOTSpUsC6OBKfzOiryc2Jr7QzXsFaOX0KPXUAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQRKq69tU5OhiF+0NOuZQU7X9BPL9aiW9Srxh5nizieNn1TLRkdpUXJisOk0t9Q5OgeFmo2JOcY3Cc2zXpBKWmp0AAAAZQAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASgAAACEAyfMU07vNgYpI+vi8O3XmBkKnuYFcofPoaq0H1FCWj0oAAAAhAIhv9JCLdJM2fKc++EFu51glQUggTzgBQR+zR8HEbpFN \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-crit-opts.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-crit-opts.pub new file mode 100644 index 000000000000..c16acae61953 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-crit-opts.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAghD4Bg5C3PR6Yjo0Onv9jTmMJL/ysWxOWM3lvbjkwSbgAAAAIbmlzdHAyNTYAAABBBMXF33sjujlcCsz5pnR7SXXO34s49Ofqw6wIoqNe2zJy2MxaBTQzMi+WXLTpv1+c5fKW1+jhlZEM+8aWuQehE8UAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAAEgAAAAab21lZ2EtcGVybUBjcnlwdG9ncmFwaHkuaW8AAAAAAAAAHmFscGhhLW9yZGVyaW5nQGNyeXB0b2dyYXBoeS5pbwAAAAAAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEET7TXKVMaHak8L5dyeoHUtWPY7ozrqZm82pkGh4nDDhV/ftU4eHq/D4FAVX0ETt1mvhZMWdcB8cKBkM75y96zUAAAAGMAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEgAAAAgVN9wU6zFsYQbPdI4MeRXpPuWRBx+jJM8PWVWvP7QYysAAAAgWXE00j8SKuyJO4X/Jz9QIyLfkEmcXqoHkLVnPRoRZ10= \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-extensions.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-extensions.pub new file mode 100644 index 000000000000..72238e05e969 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-non-lexical-extensions.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgTbZxg0yj7wdJdgLZWEmyQ27GJzA6hm0qmproBqnoGc0AAAAIbmlzdHAyNTYAAABBBKGL/tGE87lFxV86H/xeWCOc5EOwjojk5Mju0yM/z37Jgg1UJT0RYbZQdPEuFHlXrUsxNCgf7skyPFWoc784IoQAAAAAAAAAAAAAAAEAAAAEdGVzdAAAABAAAAADZXZlAAAABWFsaWNlAAAAAGS0cnQAAAAAY8XhBAAAAAAAAAAxAAAACnBlcm1pdC1wdHkAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOfVQv1ctoUn0QWVDCUViWOscuAi/ccYii4reJ9oUFMI0yJAM8HfLH8SQpGOQLzdP+Gr0YaLyDu/EFiZt9cMXwIAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIQCOQPb59BMqmZVlGvo/JYclnpWqIGiPB0c3Y1QZux/lXQAAACB0R5iKCzLmHo5A9wfsOv7oYLfDYGWSaA4WbBKJK3ETRw== \ No newline at end of file From 289301e6feb9a44d8c46fd153e3c6badc648e266 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 13:14:22 +0000 Subject: [PATCH 026/827] Bump pyproject-api from 1.3.0 to 1.4.0 (#7989) Bumps [pyproject-api](https://github.com/tox-dev/pyproject-api) from 1.3.0 to 1.4.0. - [Release notes](https://github.com/tox-dev/pyproject-api/releases) - [Changelog](https://github.com/tox-dev/pyproject-api/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/pyproject-api/compare/1.3.0...1.4.0) --- updated-dependencies: - dependency-name: pyproject-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 93f5dc09b71c..2d4afe130f0b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -119,7 +119,7 @@ pygments==2.14.0 # readme-renderer # rich # sphinx -pyproject-api==1.3.0 +pyproject-api==1.4.0 # via tox pytest==7.2.0; python_version >= "3.7" # via From 3a23d4674dc7181f1d3e4d10a6397fb9f0870b45 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 5 Jan 2023 21:26:16 +0800 Subject: [PATCH 027/827] another ssh cert vector (#7991) --- docs/development/test-vectors.rst | 2 ++ .../asymmetric/OpenSSH/certs/p256-p256-invalid-cert-type.pub | 1 + 2 files changed, 3 insertions(+) create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-invalid-cert-type.pub diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 32e1f01c04f4..c2be8b8c9f71 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -843,6 +843,8 @@ Custom OpenSSH Certificate Test Vectors ``rsa-sha2-512``. * ``p256-p256-empty-principals.pub`` - A certificate with a P256 public key signed by a P256 CA with an empty valid principals list. +* ``p256-p256-invalid-cert-type.pub`` - A certificate with a P256 public + key signed by a P256 CA with an invalid certificate type. Hashes ~~~~~~ diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-invalid-cert-type.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-invalid-cert-type.pub new file mode 100644 index 000000000000..5a06827bf56b --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p256-invalid-cert-type.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgSgPwfPbsfbii+9RAUJYav6zJ0oU54htu+vOuTdctY88AAAAIbmlzdHAyNTYAAABBBCARilffhR67GJ6CjUyP78jhu8eGCJ6bb68l86BnJIudjlYAQ/sgiFsQjmrMmDVqNrKGFudmJ3l+Nr78qump4pcAAAAAAAAAAAAAADIAAAAAAAAAAAAAAABktHJ0AAAAAGPFmrQAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK8dtlOuaMxRf6l2vYPkXBalJrwPuvA95aXVn7Y4TEwfKwlztl9x2kYVPq0z1zCcrST5xbObEkqpvwI7ibEYVNkAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIGxkTfbvXgevWi7ggjKUhaXQwT8cAKFoBaR1MX2602CGAAAAIQDmhJ+Jb4ZEb1vJU/9ekCUkAJg4MJ2nxLO4Rh02Gd1kDg== \ No newline at end of file From a9d8f4e21d4d947f2f25fce292b7486388008fc5 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 00:21:14 +0000 Subject: [PATCH 028/827] Bump BoringSSL and/or OpenSSL in CI (#7992) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed8ee759002b..ffcc87c6ada1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Dec 23, 2022. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "31bad2514d21f6207f3925ba56754611c462a873"}} - # Latest commit on the OpenSSL master branch, as of Jan 05, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "55e2dd8c3162d7313d9408cb20fca8a4fe6e6f5a"}} + # Latest commit on the OpenSSL master branch, as of Jan 06, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "a2a09af086e97da35225ec952f2ae75c833b19e7"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From c4deff553753827943c02cc5aa908cfd5aecbbce Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 6 Jan 2023 12:25:56 +0800 Subject: [PATCH 029/827] more test vectors for ssh certs (#7993) --- docs/development/test-vectors.rst | 10 ++++++++++ .../asymmetric/OpenSSH/certs/p256-p384.pub | 1 + .../asymmetric/OpenSSH/certs/p256-p521.pub | 1 + .../asymmetric/OpenSSH/certs/p256-rsa-sha1.pub | 1 + .../asymmetric/OpenSSH/certs/p256-rsa-sha256.pub | 1 + .../asymmetric/OpenSSH/certs/p256-rsa-sha512.pub | 1 + 6 files changed, 15 insertions(+) create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p384.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p521.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha1.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha256.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha512.pub diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index c2be8b8c9f71..7290f5ae0843 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -845,6 +845,16 @@ Custom OpenSSH Certificate Test Vectors key signed by a P256 CA with an empty valid principals list. * ``p256-p256-invalid-cert-type.pub`` - A certificate with a P256 public key signed by a P256 CA with an invalid certificate type. +* ``p256-p384.pub`` - A certificate with a P256 public key signed by a P384 + CA. +* ``p256-p521.pub`` - A certificate with a P256 public key signed by a P521 + CA. +* ``p256-rsa-sha1.pub`` - A certificate with a P256 public key signed by a + RSA CA using SHA1. +* ``p256-rsa-sha256.pub`` - A certificate with a P256 public key signed by + a RSA CA using SHA256. +* ``p256-rsa-sha512.pub`` - A certificate with a P256 public key signed by + a RSA CA using SHA512. Hashes ~~~~~~ diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p384.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p384.pub new file mode 100644 index 000000000000..3016df3fd5ab --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p384.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAghNd9jFDm9sueG2QuKV7fTRhKPKB0pprZqRP44dYXSZwAAAAIbmlzdHAyNTYAAABBBIdWgz67U4Fg01DzNm9UmX9EdFEqrfSyWj0ay2JLiCj8I+GHUoSTxOSrj0XkWvVdVpTAkmOX/cQrfJwRwDO71MUAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAAAiAAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQSSpNYuZi/yHiolKGD8FG5oJH8aohYgCxp+u2U3sH7UKnaTOwQUU7hYdbl/YH2Ab+vCZ3ZHx/5naCgo4nTzotyegQITU3aeOS+Ivh8P4zsNc0PrnihFknh1DVLW9w09+8gAAACEAAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAABpAAAAMQCtcUgAwYP8j657ThbfsTUZz1aiZZL0s1OfSkQKYJ49PJIEWDwZbgTohIG3D0j8PbkAAAAwT0ELlMrSu2sMcqRzbhcOK3KZgkZqdRW+5BHrc7TvYQQiYtOepqPjAC0LhRObcrep \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p521.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p521.pub new file mode 100644 index 000000000000..cff72de7a8d2 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-p521.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAga9pP3iYGmmVlFMM97Lb2Nuj7LCi4fVeLN++/xsyHLOoAAAAIbmlzdHAyNTYAAABBBD42p7j3tjDcn1YoNjKgDgec+9Czi+6KNZM9EV51kpSq1ZZz1D5H+iqWByjmT5EtWCPq+2EgdprznvJgRMVejswAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAAArAAAABNlY2RzYS1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQAP2p5Dgl+/P+tRZAsAoV3enPh2oCHheAWHjMLb1tlLPd9uZWH6vG/lb1SElA0KqMsRMNIjGfx2m1DGHuV6LirL/MBMWYTBhvrbMi+ltTd8cMiKaZKwAGcxJGbPtuRR/26qM8w8Aw04l5k4Ipy1l7dDjmO4QkI1rB2kAXHw0u/Wf0UBIsAAACnAAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAACMAAAAQgHbsKp+DSYdwqFDwk3/sF7vAy1rliZG8LYJqwAS6KvyncYgRVGGy2dP3KcBVnGn1DVwBXG4JNzHMZZolUgrK2nxiwAAAEIBhW3gjZ/7vA/Dy8azlubecyPfeLyegulmxvvJ6whmT/xQtkdSAx+JnLERN3cGRLToKA4TTmF0DG/dnfFOQygkMJE= \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha1.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha1.pub new file mode 100644 index 000000000000..27442beafc3c --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgUvBup0dKwDazWqFmuY+CX0+O9SvgYe6XXwZdGSsCFoAAAAAIbmlzdHAyNTYAAABBBCRtIgvrukZwrNM62pkYACgJjoL0ViIzOZTvyuoaPRxbKTpVUQVeLt+H6kZDnrsloOzfH0P12DN3L4W6+rSyZnAAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAwEAAQAAAQEA5KypvcBCHtATD1GEgz8s2diLeb7efvSzeYHWmxA/gbuhEtT8grhqi9fi7ZU8Y4+5jL5Wk8fRMhiscle8EM7JeQb20Pxd3c67OfuIXK654q1wyQs60xd9LXEwdJguUsC3KsayZgM42vEg0Z0ZTv3P/i9ZnIdRp+3avIrMmIUrizm7oTIyu/u1QAO8fOLtULtkOLU47vs1h9vM9q3LJMn+s/DcrrHX8Wfto+9Cvbb+B99LUycP2rDNzebs8tMYYAVKwAxEYLbbXeTIhj649/QDyUtGbA5GvYZEB6XVDwD5EYtKDJtZv2lCq3eECklAlzP9j+VGBd6WThNaHZEPklZ/ewAAAQ8AAAAHc3NoLXJzYQAAAQBzQwOIXymvAyvyNhgTSPIi2FFKQdTcjz/2hgoLtroreN/5NMz2DkACChQo6qe5YMJHHsv5JVA4+gdVEMRxp1pL8RASPuSHHN9PSizDrNKZ2MT+woEE1nSFeKj9YzhSTMxvLti67W+FPnw7S39Bf7xrLkWbds+/rwoBeeYXAvwA/4DH0aplF1BUpC5dCFxhaPyVY6MgDC9J5nRxgbuATE40Hn1XwEl5EjKCMSyjnWU6Aqe3b5jJ5HAQFTe3Jmb4fBkivKxvwmbEHDfOLWk0ZMMGZMbHMUT7dSiy5Hjh1J5S8xMnbgPXuFer3q0+4FmdJwvqty+XHSTkwFP53Msw//Gz \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha256.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha256.pub new file mode 100644 index 000000000000..a2d9630f74c6 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha256.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgEZ5t7LyaprT8g277kTvOMv/kgHECdpguBplHoRgAYpoAAAAIbmlzdHAyNTYAAABBBLQNIj2s2PZDa7LFPocsNN6ORF1ZsPmXqII23UPlpvFcUa8vDIccoO2shfUrFAMoudRiiyEHaLnpJCjIAvlM+0wAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAwEAAQAAAQEAnT7TBoEM1/ezloAEJ77uOOyRcx9K/PB/NPVVjTR6QgYirEGBkHOfxYBw7d2LlbdaZwiSOirwxj+rbox9+68w5XK/83P4YrxblxycCL6m/9R7y9k0B2TtAnq41Hf59CFZ3dI5WI3tCM2nUr/sUNRIjWelxA3EdTZ5eGhKia2B+dWVn+4YePcJXbasmPUdIA+7a+jdJ5znPiCUOA7bg3JjAOky9rKE/LiXJbpKl20D3RvXbIWosPGo+c93I3buGOFKGYNyWkYI4fljEZlVS5mZYGwG7xpdUq4ATK85lRB/RYU85gJMUdHA+2kqhXKBmMY1PPBoac2RF0zkDrQMbw1SmwAAARQAAAAMcnNhLXNoYTItMjU2AAABAIvIhSDBZwIL81IFD5dCOkT9UWy6PqHZo6xOIWXq/v2y0xZ7WLG4i5alCwxr9R8trBnrEjIrcA9XZVKawC11kaXxTxloLf5HnnEs6e49YewymgmwPMalLUqqJsAIDgdFN42g3UbeLF06a8PsHtcAui08/+xffgKNGV83+QpH+J5F8ykwWKmpc48NjulcTgUbvFmL1qOkt+Jq7ac/Hyrvu/KFx9YibCWSVLOSwL9wwQLBwq3Ham9ggnjBVj2rOfPwMBFGKaXvjb5LUlYMt2LjiPQJVVdAAKjvo/UjTWb5N21hQdtd3QEHViD+dYMkmLCCyo1U2Wfy5yfk05Hy3XqFLe8= \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha512.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha512.pub new file mode 100644 index 000000000000..914a84801bce --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-rsa-sha512.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgIOnlOEWH3RJ+U/Yr/pGEU2ig0h5qeLO9XgwIzocUxgUAAAAIbmlzdHAyNTYAAABBBAR7IuTauq/eQ9DgGVuv9qJ1jmI89k/9VIpKD/edK/mI9Rhz7RprmXC2Heopinwt9vyzvrNts7EwXasmIQcGbq4AAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAZLRydAAAAABjxeEEAAAAAAAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAwEAAQAAAQEAtsv6VhNt0q6UiBtzVOamVUpjEpLljN/r1yE9YkZdbEX9dmJHFMjr5uJxBT+PQ4w3lzdW0rnDUgX2HU8UkmzwOXCwj8USzs9Mxt9yL78hIVeZL2yRx4jYaWJsw58LzT48GyQGoW+/+FmCI+GBCMoiQ4ehTRhqREpwe0PM3iChc/9XBagjeXDmZir7rHvP3X3R04qCf+ybVv56mWIqWJAizfMMLASe6tnWvz5vvIVwJoCG6oZQeCMVXe4eBbq/gOLrUrnFtHtdpVAS15mE2tvpmG39wYc/fSmgJJC4owg62s1rCSYm+U8SWt9mkyK8BpVZvOcbf/6TXP81AnKqhL0nVwAAARQAAAAMcnNhLXNoYTItNTEyAAABAJpzmavIr0HwFiEX5wCDO+hvR7pKor2kWxSo1dYW+Hgk3DN/pyEc8GQ+jFFY1eiK1mOJ6MPIR/SfJbtIUM0OmfuLIYVGTl6bl+a/faTuvmzXgOWZ9DYtY1NYTWqLkIGgfXFwc3E4Hjamc+t9TD3aN35dYRfJFuMPZr4RmJCKEKlXBnrjFQfJQFCgzFmoFVp3jr+K5odM7oQ/JXmM3xZILeUHTNcC7xXljmweCbqfmRQtlkUheASkyPiV/tR7iz/e+hk17au+X2yymmL27SgK4CHSTcb4hGePUW1DQF7fk2AocEYr/UrXep3TXShBDQtYcJ0A7JaQaI+cEav6wN1EQZQ= \ No newline at end of file From da2d172c113295318c1c7cb784c3fbaf36bc03db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:25:13 +0000 Subject: [PATCH 030/827] Bump actions/checkout from 3.2.0 to 3.3.0 (#7996) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 4 +-- .../workflows/boring-open-version-bump.yml | 2 +- .github/workflows/ci.yml | 30 +++++++++---------- .github/workflows/macarm64.yml | 4 +-- .github/workflows/wheel-builder.yml | 6 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 2058e549e13d..ecfa7e5cdfe4 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false path: "cryptography-pr" - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "pyca/cryptography" diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 4f84e07cbec3..c438ec2fc34a 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 - id: check-sha-boring run: | SHA=$(git ls-remote https://boringssl.googlesource.com/boringssl refs/heads/master | cut -f1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffcc87c6ada1..4cccca96c0b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -69,7 +69,7 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-5-${{ hashFiles('**/Cargo.lock') }} - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -144,7 +144,7 @@ jobs: name: "${{ matrix.IMAGE.TOXENV }} on ${{ matrix.IMAGE.IMAGE }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -161,7 +161,7 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -205,7 +205,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -229,7 +229,7 @@ jobs: - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f with: toolchain: ${{ matrix.RUST }} - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -256,7 +256,7 @@ jobs: name: "Rust Coverage" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -285,7 +285,7 @@ jobs: - run: cargo install cargo-binutils if: steps.cargo-cache.outputs.cache-hit != 'true' - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -342,7 +342,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on macOS" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -366,7 +366,7 @@ jobs: - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -406,7 +406,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -439,7 +439,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: repository: "google/wycheproof" @@ -474,7 +474,7 @@ jobs: name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false @@ -524,7 +524,7 @@ jobs: name: "linkcheck" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: persist-credentials: false - name: Setup python @@ -542,7 +542,7 @@ jobs: needs: [linux, linux-distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: persist-credentials: false diff --git a/.github/workflows/macarm64.yml b/.github/workflows/macarm64.yml index 5d8c5da6d413..e8138a6f573a 100644 --- a/.github/workflows/macarm64.yml +++ b/.github/workflows/macarm64.yml @@ -29,7 +29,7 @@ jobs: steps: - name: "Delete workspace" # self-hosted runners need this, sigh run: gfind ! -name '.' ! -name '..' -delete - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: persist-credentials: false - uses: actions/cache@v3.2.2 @@ -38,7 +38,7 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.PYTHON.TOXENV }}-cargo-macarm64-${{ hashFiles('**/Cargo.lock') }} - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: repository: "google/wycheproof" path: "wycheproof" diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 77d3ca57e978..f03d9ee2e7b0 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest name: sdists steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} @@ -151,7 +151,7 @@ jobs: name: "${{ matrix.PYTHON.VERSION }} ABI ${{ matrix.PYTHON.ABI_VERSION }} macOS ${{ matrix.PYTHON.ARCHFLAGS }}" steps: # Needed for download_openssl.py - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} @@ -236,7 +236,7 @@ jobs: name: "${{ matrix.PYTHON.VERSION }} ${{ matrix.WINDOWS.WINDOWS }} ${{ matrix.PYTHON.ABI_VERSION }}" steps: # Needed for download_openssl.py - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} From 9c2f2d302dfe63c7aeb2fb06232aaee36c87da45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:25:35 +0000 Subject: [PATCH 031/827] Bump actions/download-artifact from 3.0.1 to 3.0.2 (#7995) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3.0.1...v3.0.2) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/wheel-builder.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cccca96c0b8..d56a3607105f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -559,7 +559,7 @@ jobs: if: ${{ always() }} - name: Download coverage data if: ${{ always() }} - uses: actions/download-artifact@v3.0.1 + uses: actions/download-artifact@v3.0.2 with: name: coverage-data - name: Combine coverage and fail if it's <100%. diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index f03d9ee2e7b0..670cb506b0e0 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -70,7 +70,7 @@ jobs: MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64"} name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}" steps: - - uses: actions/download-artifact@v3.0.1 + - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist @@ -156,7 +156,7 @@ jobs: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} persist-credentials: false - - uses: actions/download-artifact@v3.0.1 + - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist @@ -241,7 +241,7 @@ jobs: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} persist-credentials: false - - uses: actions/download-artifact@v3.0.1 + - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist From ac81169a5dba0092204be24e84a67d080e874aa3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:35:12 +0000 Subject: [PATCH 032/827] Bump pkginfo from 1.9.3 to 1.9.4 (#7997) Bumps [pkginfo](https://code.launchpad.net/~tseaver/pkginfo/trunk) from 1.9.3 to 1.9.4. --- updated-dependencies: - dependency-name: pkginfo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2d4afe130f0b..46523478f78b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -95,7 +95,7 @@ pathspec==0.10.3 # via black pep517==0.13.0 # via build -pkginfo==1.9.3 +pkginfo==1.9.4 # via twine platformdirs==2.6.2; python_version >= "3.7" # via From a38f5b0026a086a2fa9f716f407280b5c995aa60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:39:56 +0000 Subject: [PATCH 033/827] Bump ruff from 0.0.211 to 0.0.212 (#7999) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.211 to 0.0.212. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.211...v0.0.212) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 46523478f78b..e5b664583683 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.211 +ruff==0.0.212 # via cryptography (setup.cfg) six==1.16.0 # via bleach From d53c588bee330fe25f3cfa031e1dd94b6b86f4b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:53:06 +0000 Subject: [PATCH 034/827] Bump tox from 4.2.3 to 4.2.4 (#7998) Bumps [tox](https://github.com/tox-dev/tox) from 4.2.3 to 4.2.4. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.2.3...4.2.4) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e5b664583683..12359228127a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-api # pytest # tox -tox==4.2.3; python_version >= "3.7" +tox==4.2.4; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 090caee984dddc7c443fcaac08b1acd5876ca39b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 6 Jan 2023 21:04:19 +0800 Subject: [PATCH 035/827] more SSH tests moved to test_ssh (#8001) --- tests/hazmat/primitives/test_serialization.py | 407 +----------------- tests/hazmat/primitives/test_ssh.py | 407 ++++++++++++++++++ 2 files changed, 408 insertions(+), 406 deletions(-) diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 8fb9939d2b44..6ea5498fd5f4 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -32,11 +32,10 @@ load_pem_parameters, load_pem_private_key, load_pem_public_key, - load_ssh_public_key, ) from cryptography.hazmat.primitives.serialization.pkcs12 import PBES -from ...utils import load_vectors_from_file, raises_unsupported_algorithm +from ...utils import load_vectors_from_file from .fixtures_rsa import RSA_KEY_2048 from .test_ec import _skip_curve_unsupported from .utils import _check_dsa_private_numbers, _check_rsa_private_numbers @@ -1006,410 +1005,6 @@ def test_load_bad_encryption_oid_key(self, key_file, password, backend): ) -class TestRSASSHSerialization: - def test_load_ssh_public_key_unsupported(self, backend): - ssh_key = b"ecdsa-sha2-junk AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY=" - - with raises_unsupported_algorithm(None): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_bad_format(self, backend): - ssh_key = b"ssh-rsa not-a-real-key" - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_rsa_too_short(self, backend): - ssh_key = b"ssh-rsa" - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_truncated_int(self, backend): - ssh_key = b"ssh-rsa AAAAB3NzaC1yc2EAAAA=" - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - ssh_key = b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAACKr+IHXo" - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_rsa_comment_with_spaces(self, backend): - ssh_key = ( - b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" - b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" - b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" - b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" - b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" - b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" - # Extra section appended - b"2MzHvnbv testkey@localhost extra" - ) - - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_rsa_extra_data_after_modulo(self, backend): - ssh_key = ( - b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" - b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" - b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" - b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" - b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" - b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" - b"2MzHvnbvAQ== testkey@localhost" - ) - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_rsa_different_string(self, backend): - ssh_key = ( - # "AAAAB3NzA" the final A is capitalized here to cause the string - # ssh-rsa inside the base64 encoded blob to be incorrect. It should - # be a lower case 'a'. - b"ssh-rsa AAAAB3NzAC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" - b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" - b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" - b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" - b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" - b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" - b"2MzHvnbvAQ== testkey@localhost" - ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_rsa(self, backend): - ssh_key = ( - b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" - b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" - b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" - b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" - b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" - b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" - b"2MzHvnbv testkey@localhost" - ) - - key = load_ssh_public_key(ssh_key, backend) - - assert key is not None - assert isinstance(key, rsa.RSAPublicKey) - - numbers = key.public_numbers() - - expected_e = 0x10001 - expected_n = int( - "00C3BBF5D13F59322BA0A0B77EA0B6CF570241628AE24B5BA454D" - "23DCA295652B3523B67752653DFFD69587FAD9578DD6406F23691" - "EA491C3F8B2D391D0312D9653C303B651067ADF887A5241843CEF" - "8019680A088E092FEC305FB04EA070340BB9BD0F1635B2AD84142" - "61B4E2D010ABD8FC6D2FB768912F78EE6B05A60857532B75B75EF" - "C007601A4EF58BA947B7E75E38F3443CDD87E7C138A1DAD9D9FB3" - "19FF69DA43A9F6F6B0CD243F042CD1A5AFAEB286BD46AEB2D922B" - "D01385D6892167074A0907F94A2BF08A54ABB2FFFFC89920861D0" - "46F8706AB88DDADBD9E8204D48B87789081E074024C8996783B31" - "7076A98ABF0A2D8550EAF2097D8CCC7BE76EF", - 16, - ) - - expected = rsa.RSAPublicNumbers(expected_e, expected_n) - - assert numbers == expected - - -class TestDSSSSHSerialization: - def test_load_ssh_public_key_dss_too_short(self, backend): - ssh_key = b"ssh-dss" - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_dss_comment_with_spaces(self, backend): - ssh_key = ( - b"ssh-dss AAAAB3NzaC1kc3MAAACBALmwUtfwdjAUjU2Dixd5DvT0NDcjjr69UD" - b"LqSD/Xt5Al7D3GXr1WOrWGpjO0NE9qzRCvMTU7zykRH6XjuNXB6Hvv48Zfm4vm" - b"nHQHFmmMg2bI75JbnOwdzWnnPZJrVU4rS23dFFPqs5ug+EbhVVrcwzxahjcSjJ" - b"7WEQSkVQWnSPbbAAAAFQDXmpD3DIkGvLSBf1GdUF4PHKtUrQAAAIB/bJFwss+2" - b"fngmfG/Li5OyL7A9iVoGdkUaFaxEUROTp7wkm2z49fXFAir+/U31v50Tu98YLf" - b"WvKlxdHcdgQYV9Ww5LIrhWwwD4UKOwC6w5S3KHVbi3pWUi7vxJFXOWfeu1mC/J" - b"TWqMKR91j+rmOtdppWIZRyIVIqLcMdGO3m+2VgAAAIANFDz5KQH5NvoljpoRQi" - b"RgyPjxWXiE7vjLElKj4v8KrpanAywBzdhIW1y/tzpGuwRwj5ihi8iNTHgSsoTa" - b"j5AG5HPomJf5vJElxpu/2O9pHA52wcNObIQ7j+JA5uWusxNIbl+pF6sSiP8abr" - b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost extra" - ) - - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_dss_extra_data_after_modulo(self, backend): - ssh_key = ( - b"ssh-dss AAAAB3NzaC1kc3MAAACBALmwUtfwdjAUjU2Dixd5DvT0NDcjjr69UD" - b"LqSD/Xt5Al7D3GXr1WOrWGpjO0NE9qzRCvMTU7zykRH6XjuNXB6Hvv48Zfm4vm" - b"nHQHFmmMg2bI75JbnOwdzWnnPZJrVU4rS23dFFPqs5ug+EbhVVrcwzxahjcSjJ" - b"7WEQSkVQWnSPbbAAAAFQDXmpD3DIkGvLSBf1GdUF4PHKtUrQAAAIB/bJFwss+2" - b"fngmfG/Li5OyL7A9iVoGdkUaFaxEUROTp7wkm2z49fXFAir+/U31v50Tu98YLf" - b"WvKlxdHcdgQYV9Ww5LIrhWwwD4UKOwC6w5S3KHVbi3pWUi7vxJFXOWfeu1mC/J" - b"TWqMKR91j+rmOtdppWIZRyIVIqLcMdGO3m+2VgAAAIANFDz5KQH5NvoljpoRQi" - b"RgyPjxWXiE7vjLElKj4v8KrpanAywBzdhIW1y/tzpGuwRwj5ihi8iNTHgSsoTa" - b"j5AG5HPomJf5vJElxpu/2O9pHA52wcNObIQ7j+JA5uWusxNIbl+pF6sSiP8abr" - b"z53N7tPF/IhHTjBHb1Ol7IFu9p9AAwMD== testkey@localhost" - ) - - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_dss_different_string(self, backend): - ssh_key = ( - # "AAAAB3NzA" the final A is capitalized here to cause the string - # ssh-dss inside the base64 encoded blob to be incorrect. It should - # be a lower case 'a'. - b"ssh-dss AAAAB3NzAC1kc3MAAACBALmwUtfwdjAUjU2Dixd5DvT0NDcjjr69UD" - b"LqSD/Xt5Al7D3GXr1WOrWGpjO0NE9qzRCvMTU7zykRH6XjuNXB6Hvv48Zfm4vm" - b"nHQHFmmMg2bI75JbnOwdzWnnPZJrVU4rS23dFFPqs5ug+EbhVVrcwzxahjcSjJ" - b"7WEQSkVQWnSPbbAAAAFQDXmpD3DIkGvLSBf1GdUF4PHKtUrQAAAIB/bJFwss+2" - b"fngmfG/Li5OyL7A9iVoGdkUaFaxEUROTp7wkm2z49fXFAir+/U31v50Tu98YLf" - b"WvKlxdHcdgQYV9Ww5LIrhWwwD4UKOwC6w5S3KHVbi3pWUi7vxJFXOWfeu1mC/J" - b"TWqMKR91j+rmOtdppWIZRyIVIqLcMdGO3m+2VgAAAIANFDz5KQH5NvoljpoRQi" - b"RgyPjxWXiE7vjLElKj4v8KrpanAywBzdhIW1y/tzpGuwRwj5ihi8iNTHgSsoTa" - b"j5AG5HPomJf5vJElxpu/2O9pHA52wcNObIQ7j+JA5uWusxNIbl+pF6sSiP8abr" - b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost" - ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_dss(self, backend): - ssh_key = ( - b"ssh-dss AAAAB3NzaC1kc3MAAACBALmwUtfwdjAUjU2Dixd5DvT0NDcjjr69UD" - b"LqSD/Xt5Al7D3GXr1WOrWGpjO0NE9qzRCvMTU7zykRH6XjuNXB6Hvv48Zfm4vm" - b"nHQHFmmMg2bI75JbnOwdzWnnPZJrVU4rS23dFFPqs5ug+EbhVVrcwzxahjcSjJ" - b"7WEQSkVQWnSPbbAAAAFQDXmpD3DIkGvLSBf1GdUF4PHKtUrQAAAIB/bJFwss+2" - b"fngmfG/Li5OyL7A9iVoGdkUaFaxEUROTp7wkm2z49fXFAir+/U31v50Tu98YLf" - b"WvKlxdHcdgQYV9Ww5LIrhWwwD4UKOwC6w5S3KHVbi3pWUi7vxJFXOWfeu1mC/J" - b"TWqMKR91j+rmOtdppWIZRyIVIqLcMdGO3m+2VgAAAIANFDz5KQH5NvoljpoRQi" - b"RgyPjxWXiE7vjLElKj4v8KrpanAywBzdhIW1y/tzpGuwRwj5ihi8iNTHgSsoTa" - b"j5AG5HPomJf5vJElxpu/2O9pHA52wcNObIQ7j+JA5uWusxNIbl+pF6sSiP8abr" - b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost" - ) - - key = load_ssh_public_key(ssh_key, backend) - - assert key is not None - assert isinstance(key, dsa.DSAPublicKey) - - numbers = key.public_numbers() - - expected_y = int( - "d143cf92901f936fa258e9a11422460c8f8f1597884eef8cb1252a3e2ff0aae" - "96a7032c01cdd8485b5cbfb73a46bb04708f98a18bc88d4c7812b284da8f900" - "6e473e89897f9bc9125c69bbfd8ef691c0e76c1c34e6c843b8fe240e6e5aeb3" - "13486e5fa917ab1288ff1a6ebcf9dcdeed3c5fc88474e30476f53a5ec816ef6" - "9f4", - 16, - ) - expected_p = int( - "b9b052d7f07630148d4d838b17790ef4f43437238ebebd5032ea483fd7b7902" - "5ec3dc65ebd563ab586a633b4344f6acd10af31353bcf29111fa5e3b8d5c1e8" - "7befe3c65f9b8be69c740716698c8366c8ef925b9cec1dcd69e73d926b554e2" - "b4b6ddd1453eab39ba0f846e1555adcc33c5a8637128c9ed61104a45505a748" - "f6db", - 16, - ) - expected_q = 1230879958723280233885494314531920096931919647917 - expected_g = int( - "7f6c9170b2cfb67e78267c6fcb8b93b22fb03d895a0676451a15ac44511393a" - "7bc249b6cf8f5f5c5022afefd4df5bf9d13bbdf182df5af2a5c5d1dc7604185" - "7d5b0e4b22b856c300f850a3b00bac394b728755b8b7a56522eefc491573967" - "debb5982fc94d6a8c291f758feae63ad769a5621947221522a2dc31d18ede6f" - "b656", - 16, - ) - expected = dsa.DSAPublicNumbers( - expected_y, - dsa.DSAParameterNumbers(expected_p, expected_q, expected_g), - ) - - assert numbers == expected - - -class TestECDSASSHSerialization: - def test_load_ssh_public_key_ecdsa_nist_p256(self, backend): - _skip_curve_unsupported(backend, ec.SECP256R1()) - - ssh_key = ( - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTYAAABBBGG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCFPls= root@cloud-server-01" - ) - key = load_ssh_public_key(ssh_key, backend) - assert isinstance(key, ec.EllipticCurvePublicKey) - - expected_x = int( - "44196257377740326295529888716212621920056478823906609851236662550" - "785814128027", - 10, - ) - expected_y = int( - "12257763433170736656417248739355923610241609728032203358057767672" - "925775019611", - 10, - ) - - assert key.public_numbers() == ec.EllipticCurvePublicNumbers( - expected_x, expected_y, ec.SECP256R1() - ) - - def test_load_ssh_public_key_byteslike(self, backend): - _skip_curve_unsupported(backend, ec.SECP256R1()) - - ssh_key = ( - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTYAAABBBGG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCFPls= root@cloud-server-01" - ) - assert load_ssh_public_key(bytearray(ssh_key), backend) - assert load_ssh_public_key(memoryview(ssh_key), backend) - assert load_ssh_public_key(memoryview(bytearray(ssh_key)), backend) - - def test_load_ssh_public_key_ecdsa_nist_p384(self, backend): - _skip_curve_unsupported(backend, ec.SECP384R1()) - ssh_key = ( - b"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAz" - b"ODQAAABhBMzucOm9wbwg4iMr5QL0ya0XNQGXpw4wM5f12E3tWhdcrzyGHyel71t1" - b"4bvF9JZ2/WIuSxUr33XDl8jYo+lMQ5N7Vanc7f7i3AR1YydatL3wQfZStQ1I3rBa" - b"qQtRSEU8Tg== root@cloud-server-01" - ) - key = load_ssh_public_key(ssh_key, backend) - assert isinstance(key, ec.EllipticCurvePublicKey) - - expected_x = int( - "31541830871345183397582554827482786756220448716666815789487537666" - "592636882822352575507883817901562613492450642523901", - 10, - ) - expected_y = int( - "15111413269431823234030344298767984698884955023183354737123929430" - "995703524272335782455051101616329050844273733614670", - 10, - ) - - assert key.public_numbers() == ec.EllipticCurvePublicNumbers( - expected_x, expected_y, ec.SECP384R1() - ) - - def test_load_ssh_public_key_ecdsa_nist_p521(self, backend): - _skip_curve_unsupported(backend, ec.SECP521R1()) - ssh_key = ( - b"ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1" - b"MjEAAACFBAGTrRhMSEgF6Ni+PXNz+5fjS4lw3ypUILVVQ0Av+0hQxOx+MyozELon" - b"I8NKbrbBjijEs1GuImsmkTmWsMXS1j2A7wB4Kseh7W9KA9IZJ1+TMrzWUEwvOOXi" - b"wT23pbaWWXG4NaM7vssWfZBnvz3S174TCXnJ+DSccvWBFnKP0KchzLKxbg== " - b"root@cloud-server-01" - ) - key = load_ssh_public_key(ssh_key, backend) - assert isinstance(key, ec.EllipticCurvePublicKey) - - expected_x = int( - "54124123120178189598842622575230904027376313369742467279346415219" - "77809037378785192537810367028427387173980786968395921877911964629" - "142163122798974160187785455", - 10, - ) - expected_y = int( - "16111775122845033200938694062381820957441843014849125660011303579" - "15284560361402515564433711416776946492019498546572162801954089916" - "006665939539407104638103918", - 10, - ) - - assert key.public_numbers() == ec.EllipticCurvePublicNumbers( - expected_x, expected_y, ec.SECP521R1() - ) - - def test_load_ssh_public_key_ecdsa_nist_p256_trailing_data(self, backend): - ssh_key = ( - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTYAAABBBGG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCFPltB= root@cloud-server-01" - ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_ecdsa_nist_p256_missing_data(self, backend): - ssh_key = ( - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTYAAABBBGG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCF= root@cloud-server-01" - ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_ecdsa_nist_p256_compressed(self, backend): - # If we ever implement compressed points, note that this is not a valid - # one, it just has the compressed marker in the right place. - ssh_key = ( - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTYAAABBAWG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCFPls= root@cloud-server-01" - ) - with pytest.raises(NotImplementedError): - load_ssh_public_key(ssh_key, backend) - - def test_load_ssh_public_key_ecdsa_nist_p256_bad_curve_name(self, backend): - ssh_key = ( - # The curve name in here is changed to be "nistp255". - b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" - b"NTUAAABBBGG2MfkHXp0UkxUyllDzWNBAImsvt5t7pFtTXegZK2WbGxml8zMrgWi5" - b"teIg1TO03/FD9hbpBFgBeix3NrCFPls= root@cloud-server-01" - ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) - - -@pytest.mark.supported( - only_if=lambda backend: backend.ed25519_supported(), - skip_message="Requires OpenSSL with Ed25519 support", -) -class TestEd25519SSHSerialization: - def test_load_ssh_public_key(self, backend): - ssh_key = ( - b"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG2fgpmpYO61qeAxGd0wgRaN/E4" - b"GR+xWvBmvxjxrB1vG user@chiron.local" - ) - key = load_ssh_public_key(ssh_key, backend) - assert isinstance(key, ed25519.Ed25519PublicKey) - assert key.public_bytes(Encoding.Raw, PublicFormat.Raw) == ( - b"m\x9f\x82\x99\xa9`\xee\xb5\xa9\xe01\x19\xdd0\x81\x16\x8d\xfc" - b"N\x06G\xecV\xbc\x19\xaf\xc6 Date: Sat, 7 Jan 2023 00:20:00 +0000 Subject: [PATCH 036/827] Bump BoringSSL and/or OpenSSL in CI (#8002) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d56a3607105f..d009ecac7324 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Dec 23, 2022. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "31bad2514d21f6207f3925ba56754611c462a873"}} - # Latest commit on the OpenSSL master branch, as of Jan 06, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "a2a09af086e97da35225ec952f2ae75c833b19e7"}} + # Latest commit on the BoringSSL master branch, as of Jan 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "412b20b0f699938a370a97cc11815b1eb1e0fcb2"}} + # Latest commit on the OpenSSL master branch, as of Jan 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "accd3bdd11bd4a69fdba42bbeead28945fe50e56"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From d043c722465ce2d0b2d506941192d04a3c2da32a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 7 Jan 2023 09:22:31 +0800 Subject: [PATCH 037/827] test on py311 on macos too (#8003) --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d009ecac7324..0fbc03d76b33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -338,7 +338,7 @@ jobs: matrix: PYTHON: - {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""} - - {VERSION: "3.10", TOXENV: "py310", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"} + - {VERSION: "3.11", TOXENV: "py311", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"} name: "${{ matrix.PYTHON.TOXENV }} on macOS" timeout-minutes: 15 steps: @@ -382,7 +382,7 @@ jobs: run: | CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ LDFLAGS="${HOME}/openssl-macos-universal2/lib/libcrypto.a ${HOME}/openssl-macos-universal2/lib/libssl.a" \ - CFLAGS="-I${HOME}/openssl-macos-universal2/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 -march=core2 $EXTRA_CFLAGS" \ + CFLAGS="-I${HOME}/openssl-macos-universal2/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ tox -vvv -r -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} From aca8de845e751dd45fe4e48f8492f357d34d1861 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 7 Jan 2023 09:27:25 +0800 Subject: [PATCH 038/827] support SSH certificate parsing (#7960) * support SSH certificate parsing DSA (deliberately) not supported * make a unified API * Update src/cryptography/hazmat/primitives/serialization/ssh.py Co-authored-by: Alex Gaynor Co-authored-by: Alex Gaynor --- CHANGELOG.rst | 4 + .../primitives/asymmetric/serialization.rst | 173 +++++++++++ docs/spelling_wordlist.txt | 1 + .../primitives/serialization/__init__.py | 2 + .../hazmat/primitives/serialization/ssh.py | 278 +++++++++++++++++- tests/hazmat/primitives/test_ssh.py | 229 +++++++++++++++ 6 files changed, 686 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a50daf03d431..6dd6d8bcbf53 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,10 @@ Changelog * Support for Python 3.6 is deprecated and will be removed in the next release. +* Added support for parsing SSH certificates in addition to public keys with + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` + continues to support only public keys. .. _v39-0-0: diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 4d1af99425ba..5eaf86736482 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -459,6 +459,179 @@ An example ECDSA key in OpenSSH format:: :raises cryptography.exceptions.UnsupportedAlgorithm: If the serialized key is of a type that is not supported. + +OpenSSH Certificate +~~~~~~~~~~~~~~~~~~~ + +The format used by OpenSSH for certificates, as specified in +`PROTOCOL.certkeys`_. + +.. function:: load_ssh_public_identity(data) + + .. versionadded:: 40.0 + + .. note:: + + This function does not support parsing certificates with DSA public + keys or signatures from DSA certificate authorities. DSA is a + deprecated algorithm and should not be used. + + Deserialize an OpenSSH encoded identity to an instance of + :class:`SSHCertificate` or the appropriate public key type. + Parsing a certificate does not verify anything. It is up to the caller to + perform any necessary verification. + + :param data: The OpenSSH encoded data. + :type data: bytes + + :returns: :class:`SSHCertificate` or one of + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + , or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`. + + :raises ValueError: If the OpenSSH data could not be properly decoded. + + :raises cryptography.exceptions.UnsupportedAlgorithm: If the data contains + a public key type that is not supported. + + +.. class:: SSHCertificate + + .. versionadded:: 40.0 + + .. attribute:: nonce + + :type: bytes + + The nonce field is a CA-provided random value of arbitrary length + (but typically 16 or 32 bytes) included to make attacks that depend on + inducing collisions in the signature hash infeasible. + + .. method:: public_key() + + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` + + The public key contained in the certificate. + + .. attribute:: serial + + :type: int + + Serial is an optional certificate serial number set by the CA to + provide an abbreviated way to refer to certificates from that CA. + If a CA does not wish to number its certificates, it must set this + field to zero. + + .. attribute:: type + + :type: :class:`SSHCertificateType` + + Type specifies whether this certificate is for identification of a user + or a host. + + .. attribute:: key_id + + :type: bytes + + This is a free-form text field that is filled in by the CA at the time + of signing; the intention is that the contents of this field are used to + identify the identity principal in log messages. + + .. attribute:: valid_principals + + :type: list[bytes] + + "valid principals" is a list containing zero or more principals as + byte strings. These principals list the names for which this + certificate is valid; hostnames for host certificates and + usernames for user certificates. As a special case, an + empty list means the certificate is valid for any principal of + the specified type. + + .. attribute:: valid_after + + :type: :class:`datetime.datetime` + + A naïve datetime representing the UTC time after which the certificate + is valid. **This time is inclusive.** + + .. attribute:: valid_before + + :type: :class:`datetime.datetime` + + A naïve datetime representing the UTC time before which the certificate + is valid. **This time is not inclusive.** + + .. attribute:: critical_options + + :type: dict[bytes, bytes] + + Critical options is a dict of zero or more options that are + critical for the certificate to be considered valid. If + any of these options are not supported by the implementation, the + certificate must be rejected. + + .. attribute:: extensions + + :type: dict[bytes, bytes] + + Extensions is a dict of zero or more options that are + non-critical for the certificate to be considered valid. If any of + these options are not supported by the implementation, the + implementation may safely ignore them. + + .. method:: signature_key() + + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` + + The public key used to sign the certificate. + + .. method:: verify_cert_signature() + + .. warning:: + + This method does not validate anything about whether the + signing key is trusted! Callers are responsible for validating + trust in the signer. + + Validates that the signature on the certificate was created by + the private key associated with the certificate's signature key + and that the certificate has not been changed since signing. + + :return: None + :raises: :class:`~cryptography.exceptions.InvalidSignature` if the + signature is invalid. + + .. method:: public_bytes() + + :return: The serialized certificate in OpenSSH format. + :rtype: bytes + + +.. class:: SSHCertificateType + + .. versionadded:: 40.0 + + An enumeration of the types of SSH certificates. + + .. attribute:: USER + + The cert is intended for identification of a user. Corresponds to the + value ``1``. + + .. attribute:: HOST + + The cert is intended for identification of a host. Corresponds to the + value ``2``. + PKCS12 ~~~~~~ diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 13e1fa1dd095..b4b8685deecc 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -60,6 +60,7 @@ Google hazmat Homebrew hostname +hostnames incrementing indistinguishability initialisms diff --git a/src/cryptography/hazmat/primitives/serialization/__init__.py b/src/cryptography/hazmat/primitives/serialization/__init__.py index af4112f3968f..d298e2800411 100644 --- a/src/cryptography/hazmat/primitives/serialization/__init__.py +++ b/src/cryptography/hazmat/primitives/serialization/__init__.py @@ -23,6 +23,7 @@ ) from cryptography.hazmat.primitives.serialization.ssh import ( load_ssh_private_key, + load_ssh_public_identity, load_ssh_public_key, ) @@ -34,6 +35,7 @@ "load_pem_private_key", "load_pem_public_key", "load_ssh_private_key", + "load_ssh_public_identity", "load_ssh_public_key", "Encoding", "PrivateFormat", diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index b4951671722c..ccb878650570 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -4,6 +4,8 @@ import binascii +import datetime +import enum import os import re import typing @@ -11,7 +13,15 @@ from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm -from cryptography.hazmat.primitives.asymmetric import dsa, ec, ed25519, rsa +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import ( + dsa, + ec, + ed25519, + padding, + rsa, +) +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.serialization import ( Encoding, @@ -47,6 +57,11 @@ def _bcrypt_kdf( _ECDSA_NISTP521 = b"ecdsa-sha2-nistp521" _CERT_SUFFIX = b"-cert-v01@openssh.com" +# These are not key types, only algorithms, so they cannot appear +# as a public key type +_SSH_RSA_SHA256 = b"rsa-sha2-256" +_SSH_RSA_SHA512 = b"rsa-sha2-512" + _SSH_PUBKEY_RC = re.compile(rb"\A(\S+)[ \t]+(\S+)") _SK_MAGIC = b"openssh-key-v1\0" _SK_START = b"-----BEGIN OPENSSH PRIVATE KEY-----" @@ -703,6 +718,267 @@ def _serialize_ssh_private_key( ed25519.Ed25519PublicKey, ] +_SSH_CERT_PUBLIC_KEY_TYPES = typing.Union[ + ec.EllipticCurvePublicKey, + rsa.RSAPublicKey, + ed25519.Ed25519PublicKey, +] + + +class SSHCertificateType(enum.Enum): + USER = 1 + HOST = 2 + + +class SSHCertificate: + def __init__( + self, + _nonce: memoryview, + _public_key: _SSH_PUBLIC_KEY_TYPES, + _serial: int, + _cctype: int, + _key_id: memoryview, + _valid_principals: typing.List[bytes], + _valid_after: int, + _valid_before: int, + _critical_options: typing.Dict[bytes, bytes], + _extensions: typing.Dict[bytes, bytes], + _sig_type: memoryview, + _sig_key: memoryview, + _inner_sig_type: memoryview, + _signature: memoryview, + _tbs_cert_body: memoryview, + _cert_key_type: bytes, + _cert_body: memoryview, + ): + self._nonce = _nonce + self._public_key = _public_key + self._serial = _serial + try: + self._type = SSHCertificateType(_cctype) + except ValueError: + raise ValueError("Invalid certificate type") + self._key_id = _key_id + self._valid_principals = _valid_principals + self._valid_after = datetime.datetime.utcfromtimestamp(_valid_after) + self._valid_before = datetime.datetime.utcfromtimestamp(_valid_before) + self._critical_options = _critical_options + self._extensions = _extensions + self._sig_type = _sig_type + self._sig_key = _sig_key + self._inner_sig_type = _inner_sig_type + self._signature = _signature + self._cert_key_type = _cert_key_type + self._cert_body = _cert_body + self._tbs_cert_body = _tbs_cert_body + + @property + def nonce(self) -> bytes: + return bytes(self._nonce) + + def public_key(self) -> _SSH_CERT_PUBLIC_KEY_TYPES: + # make mypy happy until we remove DSA support entirely and + # the underlying union won't have a disallowed type + assert not isinstance(self._public_key, dsa.DSAPublicKey) + return self._public_key + + @property + def serial(self) -> int: + return self._serial + + @property + def type(self) -> SSHCertificateType: + return self._type + + @property + def key_id(self) -> bytes: + return bytes(self._key_id) + + @property + def valid_principals(self) -> typing.List[bytes]: + return self._valid_principals + + @property + def valid_before(self) -> datetime.datetime: + return self._valid_before + + @property + def valid_after(self) -> datetime.datetime: + return self._valid_after + + @property + def critical_options(self) -> typing.Dict[bytes, bytes]: + return self._critical_options + + @property + def extensions(self) -> typing.Dict[bytes, bytes]: + return self._extensions + + def signature_key(self) -> _SSH_CERT_PUBLIC_KEY_TYPES: + sigformat = _lookup_kformat(self._sig_type) + signature_key, sigkey_rest = sigformat.load_public(self._sig_key) + _check_empty(sigkey_rest) + return signature_key + + def public_bytes(self) -> bytes: + return ( + bytes(self._cert_key_type) + + b" " + + binascii.b2a_base64(bytes(self._cert_body), newline=False) + ) + + def verify_cert_signature(self) -> None: + signature_key = self.signature_key() + if isinstance(signature_key, ed25519.Ed25519PublicKey): + signature_key.verify( + bytes(self._signature), bytes(self._tbs_cert_body) + ) + elif isinstance(signature_key, ec.EllipticCurvePublicKey): + # The signature is encoded as a pair of big-endian integers + r, data = _get_mpint(self._signature) + s, data = _get_mpint(data) + _check_empty(data) + computed_sig = asym_utils.encode_dss_signature(r, s) + hash_alg = _get_ec_hash_alg(signature_key.curve) + signature_key.verify( + computed_sig, bytes(self._tbs_cert_body), ec.ECDSA(hash_alg) + ) + else: + assert isinstance(signature_key, rsa.RSAPublicKey) + if self._inner_sig_type == _SSH_RSA: + hash_alg = hashes.SHA1() + elif self._inner_sig_type == _SSH_RSA_SHA256: + hash_alg = hashes.SHA256() + else: + assert self._inner_sig_type == _SSH_RSA_SHA512 + hash_alg = hashes.SHA512() + signature_key.verify( + bytes(self._signature), + bytes(self._tbs_cert_body), + padding.PKCS1v15(), + hash_alg, + ) + + +def _get_ec_hash_alg(curve: ec.EllipticCurve) -> hashes.HashAlgorithm: + if isinstance(curve, ec.SECP256R1): + return hashes.SHA256() + elif isinstance(curve, ec.SECP384R1): + return hashes.SHA384() + else: + assert isinstance(curve, ec.SECP521R1) + return hashes.SHA512() + + +def load_ssh_public_identity( + data: bytes, +) -> typing.Union[SSHCertificate, _SSH_PUBLIC_KEY_TYPES]: + utils._check_byteslike("data", data) + + m = _SSH_PUBKEY_RC.match(data) + if not m: + raise ValueError("Invalid line format") + key_type = orig_key_type = m.group(1) + key_body = m.group(2) + with_cert = False + if key_type.endswith(_CERT_SUFFIX): + with_cert = True + key_type = key_type[: -len(_CERT_SUFFIX)] + if key_type == _SSH_DSA: + raise UnsupportedAlgorithm( + "DSA keys aren't supported in SSH certificates" + ) + kformat = _lookup_kformat(key_type) + + try: + rest = memoryview(binascii.a2b_base64(key_body)) + except (TypeError, binascii.Error): + raise ValueError("Invalid format") + + if with_cert: + cert_body = rest + inner_key_type, rest = _get_sshstr(rest) + if inner_key_type != orig_key_type: + raise ValueError("Invalid key format") + if with_cert: + nonce, rest = _get_sshstr(rest) + public_key, rest = kformat.load_public(rest) + if with_cert: + serial, rest = _get_u64(rest) + cctype, rest = _get_u32(rest) + key_id, rest = _get_sshstr(rest) + principals, rest = _get_sshstr(rest) + valid_principals = [] + while principals: + principal, principals = _get_sshstr(principals) + valid_principals.append(bytes(principal)) + valid_after, rest = _get_u64(rest) + valid_before, rest = _get_u64(rest) + crit_options, rest = _get_sshstr(rest) + critical_options = _parse_exts_opts(crit_options) + exts, rest = _get_sshstr(rest) + extensions = _parse_exts_opts(exts) + # Get the reserved field, which is unused. + _, rest = _get_sshstr(rest) + sig_key_raw, rest = _get_sshstr(rest) + sig_type, sig_key = _get_sshstr(sig_key_raw) + if sig_type == _SSH_DSA: + raise UnsupportedAlgorithm( + "DSA signatures aren't supported in SSH certificates" + ) + # Get the entire cert body and subtract the signature + tbs_cert_body = cert_body[: -len(rest)] + signature_raw, rest = _get_sshstr(rest) + _check_empty(rest) + inner_sig_type, sig_rest = _get_sshstr(signature_raw) + # RSA certs can have multiple algorithm types + if ( + sig_type == _SSH_RSA + and inner_sig_type + not in [_SSH_RSA_SHA256, _SSH_RSA_SHA512, _SSH_RSA] + ) or (sig_type != _SSH_RSA and inner_sig_type != sig_type): + raise ValueError("Signature key type does not match") + signature, sig_rest = _get_sshstr(sig_rest) + _check_empty(sig_rest) + return SSHCertificate( + nonce, + public_key, + serial, + cctype, + key_id, + valid_principals, + valid_after, + valid_before, + critical_options, + extensions, + sig_type, + sig_key, + inner_sig_type, + signature, + tbs_cert_body, + orig_key_type, + cert_body, + ) + else: + _check_empty(rest) + return public_key + + +def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: + result: typing.Dict[bytes, bytes] = {} + last_name = None + while exts_opts: + name, exts_opts = _get_sshstr(exts_opts) + bname: bytes = bytes(name) + if bname in result: + raise ValueError("Duplicate name") + if last_name is not None and bname < last_name: + raise ValueError("Fields not lexically sorted") + value, exts_opts = _get_sshstr(exts_opts) + result[bname] = bytes(value) + last_name = bname + return result + def load_ssh_public_key( data: bytes, backend: typing.Any = None diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 3d5c2a502a54..0a05a96a661c 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -4,10 +4,12 @@ import base64 +import datetime import os import pytest +from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives.asymmetric import ( dsa, ec, @@ -23,6 +25,7 @@ PublicFormat, load_pem_private_key, load_ssh_private_key, + load_ssh_public_identity, load_ssh_public_key, ssh, ) @@ -1009,3 +1012,229 @@ def test_load_ssh_public_key_trailing_data(self, backend): ) with pytest.raises(ValueError): load_ssh_public_key(ssh_key, backend) + + +class TestSSHCertificate: + @pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", + ) + def test_loads_ssh_cert(self, backend): + # secp256r1 public key, ed25519 signing key + cert = load_ssh_public_identity( + b"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbm" + b"lzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgtdU+dl9vD4xPi8afxERYo" + b"s0c0d9/3m7XGY6fGeSkqn0AAAAIbmlzdHAyNTYAAABBBAsuVFNNj/mMyFm2xB99" + b"G4xiaUJE1lZNjcp+S2tXYW5KorcHpusSlSqOkUPZ2l0644dgiNPDKR/R+BtYENC" + b"8aq8AAAAAAAAAAAAAAAEAAAAUdGVzdEBjcnlwdG9ncmFwaHkuaW8AAAAaAAAACm" + b"NyeXB0b3VzZXIAAAAIdGVzdHVzZXIAAAAAY7KyZAAAAAB2frXAAAAAAAAAAIIAA" + b"AAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9y" + b"d2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGV" + b"ybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3" + b"NoLWVkMjU1MTkAAAAg3P0eyGf2crKGwSlnChbLzTVOFKwQELE1Ve+EZ6rXF18AA" + b"ABTAAAAC3NzaC1lZDI1NTE5AAAAQKoij8BsPj/XLb45+wHmRWKNqXeZYXyDIj8J" + b"IE6dIymjEqq0TP6ntu5t59hTmWlDO85GnMXAVGBjFbeikBMfAQc= reaperhulk" + b"@despoina.local" + ) + assert isinstance(cert, ssh.SSHCertificate) + cert.verify_cert_signature() + signature_key = cert.signature_key() + assert isinstance(signature_key, ed25519.Ed25519PublicKey) + assert cert.nonce == ( + b"\xb5\xd5>v_o\x0f\x8cO\x8b\xc6\x9f\xc4DX\xa2\xcd\x1c\xd1\xdf" + b"\x7f\xden\xd7\x19\x8e\x9f\x19\xe4\xa4\xaa}" + ) + public_key = cert.public_key() + assert isinstance(public_key, ec.EllipticCurvePublicKey) + assert isinstance(public_key.curve, ec.SECP256R1) + assert cert.serial == 0 + assert cert.type is ssh.SSHCertificateType.USER + assert cert.key_id == b"test@cryptography.io" + assert cert.valid_principals == [b"cryptouser", b"testuser"] + assert cert.valid_before == datetime.datetime(2032, 12, 30, 10, 32, 32) + assert cert.valid_after == datetime.datetime(2023, 1, 2, 10, 31) + assert cert.critical_options == {} + assert cert.extensions == { + b"permit-X11-forwarding": b"", + b"permit-agent-forwarding": b"", + b"permit-port-forwarding": b"", + b"permit-pty": b"", + b"permit-user-rc": b"", + } + + @pytest.mark.parametrize( + "filename", + [ + "p256-p384.pub", + "p256-p521.pub", + "p256-rsa-sha1.pub", + "p256-rsa-sha256.pub", + "p256-rsa-sha512.pub", + ], + ) + def test_verify_cert_signature(self, filename): + data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "certs", filename), + lambda f: f.read(), + mode="rb", + ) + cert = load_ssh_public_identity(data) + assert isinstance(cert, ssh.SSHCertificate) + cert.verify_cert_signature() + + @pytest.mark.parametrize( + "filename", + [ + "p256-p256-empty-principals.pub", + "p256-p384.pub", + "p256-p521.pub", + "p256-rsa-sha1.pub", + "p256-rsa-sha256.pub", + "p256-rsa-sha512.pub", + ], + ) + def test_invalid_signature(self, filename): + data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "certs", filename), + lambda f: f.read(), + mode="rb", + ) + data = bytearray(data) + # mutate the signature so it's invalid + data[-10] = 71 + cert = load_ssh_public_identity(data) + assert isinstance(cert, ssh.SSHCertificate) + with pytest.raises(InvalidSignature): + cert.verify_cert_signature() + + def test_not_bytes(self): + with pytest.raises(TypeError): + load_ssh_public_identity( + "these aren't bytes" # type:ignore[arg-type] + ) + + def test_load_ssh_public_key(self, backend): + # This test will be removed when we implement load_ssh_public_key + # in terms of load_ssh_public_identity. Needed for coverage now. + pub_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "rsa-nopsw.key.pub"), + lambda f: f.read(), + mode="rb", + ) + key = load_ssh_public_identity(pub_data) + assert isinstance(key, rsa.RSAPublicKey) + + @pytest.mark.parametrize("filename", ["dsa-p256.pub", "p256-dsa.pub"]) + def test_dsa_unsupported(self, filename): + data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "certs", filename), + lambda f: f.read(), + mode="rb", + ) + with raises_unsupported_algorithm(None): + load_ssh_public_identity(data) + + def test_mismatched_inner_signature_type_and_sig_type(self): + data = load_vectors_from_file( + os.path.join( + "asymmetric", + "OpenSSH", + "certs", + "p256-p256-broken-signature-key-type.pub", + ), + lambda f: f.read(), + mode="rb", + ) + with pytest.raises(ValueError): + load_ssh_public_identity(data) + + def test_invalid_cert_type(self): + data = load_vectors_from_file( + os.path.join( + "asymmetric", + "OpenSSH", + "certs", + "p256-p256-invalid-cert-type.pub", + ), + lambda f: f.read(), + mode="rb", + ) + with pytest.raises(ValueError): + load_ssh_public_identity(data) + + @pytest.mark.parametrize( + "filename", + [ + "p256-p256-duplicate-extension.pub", + "p256-p256-non-lexical-extensions.pub", + "p256-p256-duplicate-crit-opts.pub", + "p256-p256-non-lexical-crit-opts.pub", + ], + ) + def test_invalid_encodings(self, filename): + data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "certs", filename), + lambda f: f.read(), + mode="rb", + ) + with pytest.raises(ValueError): + load_ssh_public_identity(data) + + def test_invalid_line_format(self, backend): + with pytest.raises(ValueError): + load_ssh_public_identity(b"whaaaaaaaaaaat") + + def test_invalid_b64(self, backend): + with pytest.raises(ValueError): + load_ssh_public_identity(b"ssh-rsa-cert-v01@openssh.com invalid") + + def test_inner_outer_key_type_mismatch(self): + with pytest.raises(ValueError): + load_ssh_public_identity( + b"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAK0VjZHNhLXNoYTI" + b"tbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg/9dq+iibMSMdJ0v" + b"l6D0SrsazwccWptLQs4sEgJBVnQMAAAAIbmlzdHAyNTYAAABBBAsuVFNNj/m" + b"MyFm2xB99G4xiaUJE1lZNjcp+S2tXYW5KorcHpusSlSqOkUPZ2l0644dgiNP" + b"DKR/R+BtYENC8aq8AAAAAAAAAAAAAAAEAAAAUdGVzdEBjcnlwdG9ncmFwaHk" + b"uaW8AAAAaAAAACmNyeXB0b3VzZXIAAAAIdGVzdHVzZXIAAAAAY7ZXNAAAAAB" + b"2glqqAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABd" + b"wZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9" + b"yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXI" + b"tcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN" + b"0cDI1NgAAAEEEzwNcwptXrrgztCug8ZB82f5OsPWJiO4WP0kjdFz1vbBGQOU" + b"DcCaabh5EbgfMOf1mg58zw35QrqjTXDiBMjyPhwAAAGQAAAATZWNkc2Etc2h" + b"hMi1uaXN0cDI1NgAAAEkAAAAhAOaNCEtn0JkFfSygACVZMBUMd5/m7avwqxW" + b"+FxCje1GpAAAAIGf9opl4YoC5XcO92WMFEwUdE3jUQtBg3GRQlXBqFcoL" + ) + + def test_loads_a_cert_empty_principals(self, backend): + data = load_vectors_from_file( + os.path.join( + "asymmetric", + "OpenSSH", + "certs", + "p256-p256-empty-principals.pub", + ), + lambda f: f.read(), + mode="rb", + ) + cert = load_ssh_public_identity(data) + assert isinstance(cert, ssh.SSHCertificate) + assert cert.valid_principals == [] + assert cert.extensions == {} + assert cert.critical_options == {} + + def test_public_bytes(self, backend): + data = load_vectors_from_file( + os.path.join( + "asymmetric", + "OpenSSH", + "certs", + "p256-p256-empty-principals.pub", + ), + lambda f: f.read(), + mode="rb", + ) + cert = load_ssh_public_identity(data) + assert isinstance(cert, ssh.SSHCertificate) + assert data == cert.public_bytes() From d9c1182e5c6c81c056662fab8a0a755e2a5bc24d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 7 Jan 2023 16:39:50 -0500 Subject: [PATCH 039/827] Use the more modern OpenSSL incantation in tests (#8005) --- tests/hazmat/backends/test_openssl.py | 2 +- tests/hazmat/bindings/test_openssl.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 9a706a1bb11a..8a0b46c9b044 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -134,7 +134,7 @@ def test_consume_errors(self): assert len(errors) == 10 def test_ssl_ciphers_registered(self): - meth = backend._lib.SSLv23_method() + meth = backend._lib.TLS_method() ctx = backend._lib.SSL_CTX_new(meth) assert ctx != backend._ffi.NULL backend._lib.SSL_CTX_free(ctx) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 6204262728f7..5c651f0fa2cd 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -32,7 +32,7 @@ def test_ssl_ctx_options(self): # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) current_options = b.lib.SSL_CTX_get_options(ctx) @@ -47,7 +47,7 @@ def test_ssl_options(self): # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) @@ -64,7 +64,7 @@ def test_ssl_mode(self): # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) From 41fbe1f6f0e527e4fa941767bf9458e6cf4e0a9f Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 8 Jan 2023 00:20:24 +0000 Subject: [PATCH 040/827] Bump BoringSSL and/or OpenSSL in CI (#8006) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fbc03d76b33..c2fc1a377711 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "412b20b0f699938a370a97cc11815b1eb1e0fcb2"}} + # Latest commit on the BoringSSL master branch, as of Jan 08, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "01d195bd03bfff54dc99c0df0858197c71d35417"}} # Latest commit on the OpenSSL master branch, as of Jan 07, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "accd3bdd11bd4a69fdba42bbeead28945fe50e56"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From 1b4ad81ff3004b436e627b9e248905113b9cc4a1 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 8 Jan 2023 09:08:22 +0800 Subject: [PATCH 041/827] SSHCertificateBuilder (#8004) * SSHCertificateBuilder This adds support for generating SSH certificates * add deterministic signing tests and valid_for_all_principals * test another edge * one of these two fixes makes no sense --- CHANGELOG.rst | 2 + .../primitives/asymmetric/serialization.rst | 126 ++++- .../primitives/serialization/__init__.py | 6 + .../hazmat/primitives/serialization/ssh.py | 407 +++++++++++++++++ tests/hazmat/primitives/test_ssh.py | 431 +++++++++++++++++- 5 files changed, 965 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6dd6d8bcbf53..d3fe0fa29f67 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,8 @@ Changelog :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` continues to support only public keys. +* Added support for generating SSH certificates with + :class:`~cryptography.hazmat.primitives.serialization.SSHCertificateBuilder`. .. _v39-0-0: diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 5eaf86736482..2bc75ab08609 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -546,7 +546,7 @@ The format used by OpenSSH for certificates, as specified in :type: list[bytes] - "valid principals" is a list containing zero or more principals as + "valid principals" is a list containing one or more principals as byte strings. These principals list the names for which this certificate is valid; hostnames for host certificates and usernames for user certificates. As a special case, an @@ -632,6 +632,130 @@ The format used by OpenSSH for certificates, as specified in The cert is intended for identification of a host. Corresponds to the value ``2``. +SSH Certificate Builder +~~~~~~~~~~~~~~~~~~~~~~~ + +.. class:: SSHCertificateBuilder + + .. versionadded:: 40.0 + + .. note:: + + This builder does not support generating certificates with DSA public + keys or creating signatures with DSA certificate authorities. DSA is a + deprecated algorithm and should not be used. + + .. doctest:: + + >>> import datetime + >>> from cryptography.hazmat.primitives.asymmetric import ec + >>> from cryptography.hazmat.primitives.serialization import ( + ... SSHCertificateType, SSHCertificateBuilder + ... ) + >>> signing_key = ec.generate_private_key(ec.SECP256R1()) + >>> private_key = ec.generate_private_key(ec.SECP256R1()) + >>> public_key = private_key.public_key() + >>> valid_after = datetime.datetime(2023, 1, 1, 1) + >>> valid_before = datetime.datetime(2023, 7, 1, 1) + >>> key_id = b"a_key_id" + >>> valid_principals = [b"eve", b"alice"] + >>> builder = ( + ... SSHCertificateBuilder() + ... .public_key(public_key) + ... .type(SSHCertificateType.USER) + ... .valid_before(valid_before) + ... .valid_after(valid_after) + ... .key_id(b"a_key_id") + ... .valid_principals(valid_principals) + ... .add_extension(b"no-touch-required", b"") + ... ) + >>> builder.sign(private_key).public_bytes() + b'...' + + .. method:: public_key(public_key) + + :param public_key: The public key to be included in the certificate. + This value is required. + :type public_key: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` + + .. method:: serial(serial) + + :param int serial: The serial number to be included in the certificate. + This is not a required value and will be set to zero if not + provided. Value must be between 0 and 2:sup:`64` - 1, inclusive. + + .. method:: type(type) + + :param type: The type of the certificate. There are two options, + user or host. + :type type: :class:`SSHCertificateType` + + .. method:: key_id(key_id) + + :param key_id: The key ID to be included in the certificate. This is + not a required value. + :type key_id: bytes + + .. method:: valid_principals(valid_principals) + + :param valid_principals: A list of principals that the certificate is + valid for. This is a required value unless + :meth:`valid_for_all_principals` has been called. + :type valid_principals: list[bytes] + + .. method:: valid_for_all_principals() + + Marks the certificate as valid for all principals. This cannot be + set if principals have been added via :meth:`valid_principals`. + + .. method:: valid_after(valid_after) + + :param valid_after: The time (in UTC) that marks the activation + time for the certificate. Naïve datetime values are treated as + UTC, but timezone aware datetime values are also allowed. + This is a required value. + :type valid_after: :class:`datetime.datetime` + + .. method:: valid_before(valid_before) + + :param valid_before: The time (in UTC) that marks the expiration + time for the certificate. Naïve datetime values are treated as + UTC, but timezone aware datetime values are also allowed. + This is a required value. + :type valid_before: :class:`datetime.datetime` + + .. method:: add_critical_option(name, value) + + :param name: The name of the critical option to add. No duplicates + are allowed. + :type name: bytes + :param value: The value of the critical option to add. This is + commonly an empty byte string. + :type value: bytes + + .. method:: add_extension(name, value) + + :param name: The name of the extension to add. No duplicates are + allowed. + :type name: bytes + :param value: The value of the extension to add. + :type value: bytes + + .. method:: sign(private_key) + + :param private_key: The private key that will be used to sign the + certificate. + :type private_key: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` + + :return: The signed certificate. + :rtype: :class:`SSHCertificate` + PKCS12 ~~~~~~ diff --git a/src/cryptography/hazmat/primitives/serialization/__init__.py b/src/cryptography/hazmat/primitives/serialization/__init__.py index d298e2800411..84c18e504e88 100644 --- a/src/cryptography/hazmat/primitives/serialization/__init__.py +++ b/src/cryptography/hazmat/primitives/serialization/__init__.py @@ -22,6 +22,9 @@ load_pem_public_key, ) from cryptography.hazmat.primitives.serialization.ssh import ( + SSHCertificate, + SSHCertificateBuilder, + SSHCertificateType, load_ssh_private_key, load_ssh_public_identity, load_ssh_public_key, @@ -45,4 +48,7 @@ "BestAvailableEncryption", "NoEncryption", "_KeySerializationEncryption", + "SSHCertificateBuilder", + "SSHCertificate", + "SSHCertificateType", ] diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index ccb878650570..a008fac90fa9 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -225,6 +225,10 @@ def put_u32(self, val: int) -> None: """Big-endian uint32""" self.flist.append(val.to_bytes(length=4, byteorder="big")) + def put_u64(self, val: int) -> None: + """Big-endian uint64""" + self.flist.append(val.to_bytes(length=8, byteorder="big")) + def put_sshstr(self, val: typing.Union[bytes, "_FragList"]) -> None: """Bytes prefixed with u32 length""" if isinstance(val, (bytes, memoryview, bytearray)): @@ -1035,3 +1039,406 @@ def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: pub = binascii.b2a_base64(f_pub.tobytes()).strip() return b"".join([key_type, b" ", pub]) + + +def _datetime_to_utc_timestamp(time: datetime.datetime) -> int: + if time.tzinfo is not None: + offset = time.utcoffset() + offset = offset if offset else datetime.timedelta() + new_time = time.replace(tzinfo=datetime.timezone.utc) - offset + else: + new_time = time.replace(tzinfo=datetime.timezone.utc) + + return int(new_time.timestamp()) + + +_SSH_CERT_PRIVATE_KEY_TYPES = typing.Union[ + ec.EllipticCurvePrivateKey, + rsa.RSAPrivateKey, + ed25519.Ed25519PrivateKey, +] + + +class SSHCertificateBuilder: + def __init__( + self, + _public_key: typing.Optional[_SSH_CERT_PUBLIC_KEY_TYPES] = None, + _serial: typing.Optional[int] = None, + _type: typing.Optional[SSHCertificateType] = None, + _key_id: typing.Optional[bytes] = None, + _valid_principals: typing.List[bytes] = [], + _valid_for_all_principals: bool = False, + _valid_before: typing.Optional[datetime.datetime] = None, + _valid_after: typing.Optional[datetime.datetime] = None, + _critical_options: typing.List[typing.Tuple[bytes, bytes]] = [], + _extensions: typing.List[typing.Tuple[bytes, bytes]] = [], + ): + self._public_key = _public_key + self._serial = _serial + self._type = _type + self._key_id = _key_id + self._valid_principals = _valid_principals + self._valid_for_all_principals = _valid_for_all_principals + self._valid_before = _valid_before + self._valid_after = _valid_after + self._critical_options = _critical_options + self._extensions = _extensions + + def public_key( + self, public_key: _SSH_CERT_PUBLIC_KEY_TYPES + ) -> "SSHCertificateBuilder": + if not isinstance( + public_key, + ( + ec.EllipticCurvePublicKey, + rsa.RSAPublicKey, + ed25519.Ed25519PublicKey, + ), + ): + raise TypeError("Unsupported key type") + if self._public_key is not None: + raise ValueError("public_key already set") + + return SSHCertificateBuilder( + _public_key=public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def serial(self, serial: int) -> "SSHCertificateBuilder": + if not isinstance(serial, int): + raise TypeError("serial must be an integer") + if not 0 <= serial < 2**64: + raise ValueError("serial must be between 0 and 2**64") + if self._serial is not None: + raise ValueError("serial already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def type(self, type: SSHCertificateType) -> "SSHCertificateBuilder": + if not isinstance(type, SSHCertificateType): + raise TypeError("type must be an SSHCertificateType") + if self._type is not None: + raise ValueError("type already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def key_id(self, key_id: bytes) -> "SSHCertificateBuilder": + if not isinstance(key_id, bytes): + raise TypeError("key_id must be bytes") + if self._key_id is not None: + raise ValueError("key_id already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_principals( + self, valid_principals: typing.List[bytes] + ) -> "SSHCertificateBuilder": + if self._valid_for_all_principals: + raise ValueError( + "Principals can't be set because the cert is valid " + "for all principals" + ) + if ( + not all(isinstance(x, bytes) for x in valid_principals) + or not valid_principals + ): + raise TypeError( + "principals must be a list of bytes and can't be empty" + ) + if self._valid_principals: + raise ValueError("valid_principals already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_for_all_principals(self): + if self._valid_principals: + raise ValueError( + "valid_principals already set, can't set " + "valid_for_all_principals" + ) + if self._valid_for_all_principals: + raise ValueError("valid_for_all_principals already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=True, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_before( + self, valid_before: datetime.datetime + ) -> "SSHCertificateBuilder": + if not isinstance(valid_before, datetime.datetime): + raise TypeError("valid_before must be a datetime") + if _datetime_to_utc_timestamp(valid_before) < 0: + raise ValueError("valid_before must be after the Unix epoch") + if self._valid_before is not None: + raise ValueError("valid_before already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_after( + self, valid_after: datetime.datetime + ) -> "SSHCertificateBuilder": + if not isinstance(valid_after, datetime.datetime): + raise TypeError("valid_after must be a datetime") + if _datetime_to_utc_timestamp(valid_after) < 0: + raise ValueError("valid_after must be after the Unix epoch") + if self._valid_after is not None: + raise ValueError("valid_after already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def add_critical_option( + self, name: bytes, value: bytes + ) -> "SSHCertificateBuilder": + if not isinstance(name, bytes) or not isinstance(value, bytes): + raise TypeError("name and value must be bytes") + # This is O(n**2) + if name in [name for name, _ in self._critical_options]: + raise ValueError("Duplicate critical option name") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options + [(name, value)], + _extensions=self._extensions, + ) + + def add_extension( + self, name: bytes, value: bytes + ) -> "SSHCertificateBuilder": + if not isinstance(name, bytes) or not isinstance(value, bytes): + raise TypeError("name and value must be bytes") + # This is O(n**2) + if name in [name for name, _ in self._extensions]: + raise ValueError("Duplicate extension name") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions + [(name, value)], + ) + + def sign(self, private_key: _SSH_CERT_PRIVATE_KEY_TYPES) -> SSHCertificate: + if not isinstance( + private_key, + ( + ec.EllipticCurvePrivateKey, + rsa.RSAPrivateKey, + ed25519.Ed25519PrivateKey, + ), + ): + raise TypeError("Unsupported private key type") + + if self._public_key is None: + raise ValueError("public_key must be set") + + # Not required + serial = 0 if self._serial is None else self._serial + + if self._type is None: + raise ValueError("type must be set") + + # Not required + key_id = b"" if self._key_id is None else self._key_id + + # A zero length list is valid, but means the certificate + # is valid for any principal of the specified type. We require + # the user to explicitly set valid_for_all_principals to get + # that behavior. + if not self._valid_principals and not self._valid_for_all_principals: + raise ValueError( + "valid_principals must be set if valid_for_all_principals " + "is False" + ) + + if self._valid_before is None: + raise ValueError("valid_before must be set") + + if self._valid_after is None: + raise ValueError("valid_after must be set") + + valid_after = _datetime_to_utc_timestamp(self._valid_after) + valid_before = _datetime_to_utc_timestamp(self._valid_before) + if valid_after > valid_before: + raise ValueError("valid_after must be earlier than valid_before") + + # lexically sort our byte strings + self._critical_options.sort(key=lambda x: x[0]) + self._extensions.sort(key=lambda x: x[0]) + + key_type = _get_ssh_key_type(self._public_key) + cert_prefix = key_type + _CERT_SUFFIX + + # Marshal the bytes to be signed + nonce = os.urandom(32) + kformat = _lookup_kformat(key_type) + f = _FragList() + f.put_sshstr(cert_prefix) + f.put_sshstr(nonce) + kformat.encode_public(self._public_key, f) + f.put_u64(serial) + f.put_u32(self._type.value) + f.put_sshstr(key_id) + fprincipals = _FragList() + for p in self._valid_principals: + fprincipals.put_sshstr(p) + f.put_sshstr(fprincipals.tobytes()) + f.put_u64(valid_after) + f.put_u64(valid_before) + fcrit = _FragList() + for name, value in self._critical_options: + fcrit.put_sshstr(name) + fcrit.put_sshstr(value) + f.put_sshstr(fcrit.tobytes()) + fext = _FragList() + for name, value in self._extensions: + fext.put_sshstr(name) + fext.put_sshstr(value) + f.put_sshstr(fext.tobytes()) + f.put_sshstr(b"") # RESERVED FIELD + # encode CA public key + ca_type = _get_ssh_key_type(private_key) + caformat = _lookup_kformat(ca_type) + caf = _FragList() + caf.put_sshstr(ca_type) + caformat.encode_public(private_key.public_key(), caf) + f.put_sshstr(caf.tobytes()) + # Sigs according to the rules defined for the CA's public key + # (RFC4253 section 6.6 for ssh-rsa, RFC5656 for ECDSA, + # and RFC8032 for Ed25519). + if isinstance(private_key, ed25519.Ed25519PrivateKey): + signature = private_key.sign(f.tobytes()) + fsig = _FragList() + fsig.put_sshstr(ca_type) + fsig.put_sshstr(signature) + f.put_sshstr(fsig.tobytes()) + elif isinstance(private_key, ec.EllipticCurvePrivateKey): + hash_alg = _get_ec_hash_alg(private_key.curve) + signature = private_key.sign(f.tobytes(), ec.ECDSA(hash_alg)) + r, s = asym_utils.decode_dss_signature(signature) + fsig = _FragList() + fsig.put_sshstr(ca_type) + fsigblob = _FragList() + fsigblob.put_mpint(r) + fsigblob.put_mpint(s) + fsig.put_sshstr(fsigblob.tobytes()) + f.put_sshstr(fsig.tobytes()) + + else: + assert isinstance(private_key, rsa.RSAPrivateKey) + # Just like Golang, we're going to use SHA512 for RSA + # https://cs.opensource.google/go/x/crypto/+/refs/tags/ + # v0.4.0:ssh/certs.go;l=445 + # RFC 8332 defines SHA256 and 512 as options + fsig = _FragList() + fsig.put_sshstr(_SSH_RSA_SHA512) + signature = private_key.sign( + f.tobytes(), padding.PKCS1v15(), hashes.SHA512() + ) + fsig.put_sshstr(signature) + f.put_sshstr(fsig.tobytes()) + + cert_data = binascii.b2a_base64(f.tobytes()).strip() + # load_ssh_public_identity returns a union, but this is + # guaranteed to be an SSHCertificate, so we cast to make + # mypy happy. + return typing.cast( + SSHCertificate, + load_ssh_public_identity(b"".join([cert_prefix, b" ", cert_data])), + ) diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 0a05a96a661c..fb801f5d0c6e 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -8,6 +8,7 @@ import os import pytest +import pytz from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives.asymmetric import ( @@ -23,6 +24,9 @@ NoEncryption, PrivateFormat, PublicFormat, + SSHCertificate, + SSHCertificateBuilder, + SSHCertificateType, load_pem_private_key, load_ssh_private_key, load_ssh_public_identity, @@ -32,6 +36,7 @@ from ...doubles import DummyKeySerializationEncryption from ...utils import load_vectors_from_file, raises_unsupported_algorithm +from .fixtures_rsa import RSA_KEY_2048 from .test_ec import _skip_curve_unsupported @@ -1036,7 +1041,7 @@ def test_loads_ssh_cert(self, backend): b"IE6dIymjEqq0TP6ntu5t59hTmWlDO85GnMXAVGBjFbeikBMfAQc= reaperhulk" b"@despoina.local" ) - assert isinstance(cert, ssh.SSHCertificate) + assert isinstance(cert, SSHCertificate) cert.verify_cert_signature() signature_key = cert.signature_key() assert isinstance(signature_key, ed25519.Ed25519PublicKey) @@ -1048,7 +1053,7 @@ def test_loads_ssh_cert(self, backend): assert isinstance(public_key, ec.EllipticCurvePublicKey) assert isinstance(public_key.curve, ec.SECP256R1) assert cert.serial == 0 - assert cert.type is ssh.SSHCertificateType.USER + assert cert.type is SSHCertificateType.USER assert cert.key_id == b"test@cryptography.io" assert cert.valid_principals == [b"cryptouser", b"testuser"] assert cert.valid_before == datetime.datetime(2032, 12, 30, 10, 32, 32) @@ -1079,7 +1084,7 @@ def test_verify_cert_signature(self, filename): mode="rb", ) cert = load_ssh_public_identity(data) - assert isinstance(cert, ssh.SSHCertificate) + assert isinstance(cert, SSHCertificate) cert.verify_cert_signature() @pytest.mark.parametrize( @@ -1103,7 +1108,7 @@ def test_invalid_signature(self, filename): # mutate the signature so it's invalid data[-10] = 71 cert = load_ssh_public_identity(data) - assert isinstance(cert, ssh.SSHCertificate) + assert isinstance(cert, SSHCertificate) with pytest.raises(InvalidSignature): cert.verify_cert_signature() @@ -1219,7 +1224,7 @@ def test_loads_a_cert_empty_principals(self, backend): mode="rb", ) cert = load_ssh_public_identity(data) - assert isinstance(cert, ssh.SSHCertificate) + assert isinstance(cert, SSHCertificate) assert cert.valid_principals == [] assert cert.extensions == {} assert cert.critical_options == {} @@ -1236,5 +1241,419 @@ def test_public_bytes(self, backend): mode="rb", ) cert = load_ssh_public_identity(data) - assert isinstance(cert, ssh.SSHCertificate) + assert isinstance(cert, SSHCertificate) assert data == cert.public_bytes() + + +class TestSSHCertificateBuilder: + def test_signs_a_cert(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + public_key = ec.generate_private_key(ec.SECP256R1()).public_key() + valid_before = datetime.datetime(2023, 7, 16, 18, 43) + tz = pytz.timezone("US/Eastern") + valid_before = tz.localize(valid_before) + utc_time_before = datetime.datetime(2023, 7, 16, 22, 43) + valid_after = datetime.datetime(2023, 1, 16, 22, 43) + key_id = b"test" + valid_principals = [b"eve", b"alice"] + builder = ( + SSHCertificateBuilder() + .public_key(public_key) + .type(SSHCertificateType.USER) + .valid_before(valid_before) + .valid_after(valid_after) + .key_id(key_id) + .valid_principals(valid_principals) + .add_critical_option(b"ordered", b"") + .add_critical_option(b"maybe", b"test2") + .add_extension(b"test", b"a value") + .add_extension(b"allowed", b"") + ) + cert = builder.sign(private_key) + cert.verify_cert_signature() + cert_public_key = cert.public_key() + assert isinstance(cert_public_key, ec.EllipticCurvePublicKey) + assert cert_public_key.public_numbers() == public_key.public_numbers() + assert cert.serial == 0 + assert cert.type is SSHCertificateType.USER + assert cert.key_id == key_id + assert cert.valid_principals == valid_principals + assert cert.valid_before == utc_time_before + assert cert.valid_after == valid_after + assert cert.critical_options == {b"ordered": b"", b"maybe": b"test2"} + assert list(cert.critical_options) == [b"maybe", b"ordered"] + assert cert.extensions == {b"test": b"a value", b"allowed": b""} + assert list(cert.extensions) == [b"allowed", b"test"] + signature_key = cert.signature_key() + assert isinstance(signature_key, ec.EllipticCurvePublicKey) + assert ( + signature_key.public_numbers() + == private_key.public_key().public_numbers() + ) + + def test_public_key_errors(self): + public_key = ec.generate_private_key(ec.SECP256R1()).public_key() + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.public_key("not a key") # type: ignore[arg-type] + builder = builder.public_key(public_key) + with pytest.raises(ValueError): + builder.public_key(public_key) + + def test_serial_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.serial("not a serial") # type: ignore[arg-type] + with pytest.raises(ValueError): + builder.serial(-1) + with pytest.raises(ValueError): + builder.serial(2**64) + builder = builder.serial(1) + with pytest.raises(ValueError): + builder.serial(1) + + def test_type_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.type("not a type") # type: ignore[arg-type] + builder = builder.type(SSHCertificateType.USER) + with pytest.raises(ValueError): + builder.type(SSHCertificateType.USER) + + def test_key_id_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.key_id("not bytes") # type: ignore[arg-type] + builder = builder.key_id(b"test") + with pytest.raises(ValueError): + builder.key_id(b"test") + + def test_valid_principals_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.valid_principals("not a list") # type: ignore[arg-type] + with pytest.raises(TypeError): + builder.valid_principals( + [b"test", "not bytes"] # type: ignore[list-item] + ) + with pytest.raises(TypeError): + builder.valid_principals([]) + builder = builder.valid_principals([b"test"]) + with pytest.raises(ValueError): + builder.valid_principals([b"test"]) + with pytest.raises(ValueError): + builder.valid_for_all_principals() + + def test_valid_for_all_principals_errors(self): + builder = SSHCertificateBuilder() + builder = builder.valid_for_all_principals() + with pytest.raises(ValueError): + builder.valid_for_all_principals() + with pytest.raises(ValueError): + builder.valid_principals([b"test"]) + + def test_valid_before_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.valid_before("not a datetime") # type: ignore[arg-type] + with pytest.raises(ValueError): + builder.valid_before(datetime.datetime(1960, 1, 1)) + builder = builder.valid_before(datetime.datetime(2023, 1, 1)) + with pytest.raises(ValueError): + builder.valid_before(datetime.datetime(2023, 1, 1)) + + def test_valid_after_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.valid_after("not a datetime") # type: ignore[arg-type] + with pytest.raises(ValueError): + builder.valid_after(datetime.datetime(1960, 1, 1)) + builder = builder.valid_after(datetime.datetime(2023, 1, 1)) + with pytest.raises(ValueError): + builder.valid_after(datetime.datetime(2023, 1, 1)) + + def test_add_critical_option_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.add_critical_option( + "not bytes", b"test" # type: ignore[arg-type] + ) + with pytest.raises(TypeError): + builder.add_critical_option( + b"test", object() # type: ignore[arg-type] + ) + builder = builder.add_critical_option(b"test", b"test") + with pytest.raises(ValueError): + builder.add_critical_option(b"test", b"test") + + def test_add_extension_errors(self): + builder = SSHCertificateBuilder() + with pytest.raises(TypeError): + builder.add_extension( + "not bytes", b"test" # type: ignore[arg-type] + ) + with pytest.raises(TypeError): + builder.add_extension(b"test", object()) # type: ignore[arg-type] + builder = builder.add_extension(b"test", b"test") + with pytest.raises(ValueError): + builder.add_extension(b"test", b"test") + + def test_sign_unsupported_key(self): + builder = ( + SSHCertificateBuilder() + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(TypeError): + builder.sign("not a key") + + def test_sign_no_public_key(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_no_type(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_no_valid_principals(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_no_valid_after(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_no_valid_before(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_principals([b"bob"]) + .valid_after(datetime.datetime(2023, 1, 1)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_valid_after_after_valid_before(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_principals([b"eve"]) + .valid_after(datetime.datetime(2023, 1, 2)) + .valid_before(datetime.datetime(2023, 1, 1)) + .type(SSHCertificateType.USER) + ) + with pytest.raises(ValueError): + builder.sign(private_key) + + def test_sign_non_zero_serial(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .serial(123456789) + .valid_principals([b"alice"]) + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + assert cert.serial == 123456789 + + def test_crit_opts_exts_lexically_sorted(self): + private_key = ec.generate_private_key(ec.SECP256R1()) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + .add_critical_option(b"zebra@cryptography.io", b"") + .add_critical_option(b"apple@cryptography.io", b"") + .add_critical_option(b"banana@cryptography.io", b"") + .add_extension(b"zebra@cryptography.io", b"") + .add_extension(b"apple@cryptography.io", b"") + .add_extension(b"banana@cryptography.io", b"") + ) + cert = builder.sign(private_key) + # This returns a dict, but dicts are order preserving in + # all our supported versions of Python so we can use + # items to confirm the order. + assert list(cert.extensions.items()) == [ + (b"apple@cryptography.io", b""), + (b"banana@cryptography.io", b""), + (b"zebra@cryptography.io", b""), + ] + assert list(cert.critical_options.items()) == [ + (b"apple@cryptography.io", b""), + (b"banana@cryptography.io", b""), + (b"zebra@cryptography.io", b""), + ] + + @pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", + ) + def test_sign_ed25519(self, backend): + private_key = ed25519.Ed25519PrivateKey.generate() + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + assert isinstance(cert.signature_key(), ed25519.Ed25519PublicKey) + cert.verify_cert_signature() + + @pytest.mark.parametrize( + "curve", [ec.SECP256R1(), ec.SECP384R1(), ec.SECP521R1()] + ) + def test_sign_ec(self, curve): + private_key = ec.generate_private_key(curve) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + sig_key = cert.signature_key() + assert isinstance(sig_key, ec.EllipticCurvePublicKey) + assert isinstance(sig_key.curve, type(curve)) + cert.verify_cert_signature() + + def test_sign_rsa(self): + private_key = RSA_KEY_2048.private_key() + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + sig_key = cert.signature_key() + assert isinstance(sig_key, rsa.RSAPublicKey) + cert.verify_cert_signature() + + def test_sign_and_byte_compare_rsa(self, monkeypatch): + # Monkey patch urandom to return a known value so we + # get a deterministic signature with RSA. + monkeypatch.setattr(os, "urandom", lambda _: b"\x00" * 32) + private_key = RSA_KEY_2048.private_key() + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + sig_key = cert.signature_key() + assert isinstance(sig_key, rsa.RSAPublicKey) + cert.verify_cert_signature() + assert cert.public_bytes() == ( + b"ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3Blbn" + b"NzaC5jb20AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA" + b"QABAAABAQDBevx+d0dMqlqoMDYVij/797UhaFG6IjDl1qv8wcbP71npI+oTMLxZ" + b"O3OAKrYIpuSjMGUjoxFrpao5ZhRRdOE7bEnpt4Bi5EnXLvsQ/UnpH6CLltBR54L" + b"p9avFtab3mEgnrbjnPaAPIrLv3Nt26rRu2tmO1lZidD/cbA4zal0M26p9wp5TY1" + b"4kyHpbLEIVloBjzetoqXK6u8Hjz/APuagONypNDCySDR6M7jM85HDcLoFFrbBb8" + b"pruHSTxQejMeEmJxYf8b7rNl58/IWPB1ymbNlvHL/4oSOlnrtHkjcxRWzpQ7U3g" + b"T9BThGyhCiI7EMyEHMgP3r7kTzEUwT6IavWDAAAAAAAAAAAAAAABAAAAAAAAAAA" + b"AAAAAY7DNAAAAAABjsh6AAAAAAAAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAw" + b"EAAQAAAQEAwXr8fndHTKpaqDA2FYo/+/e1IWhRuiIw5dar/MHGz+9Z6SPqEzC8W" + b"TtzgCq2CKbkozBlI6MRa6WqOWYUUXThO2xJ6beAYuRJ1y77EP1J6R+gi5bQUeeC" + b"6fWrxbWm95hIJ6245z2gDyKy79zbduq0btrZjtZWYnQ/3GwOM2pdDNuqfcKeU2N" + b"eJMh6WyxCFZaAY83raKlyurvB48/wD7moDjcqTQwskg0ejO4zPORw3C6BRa2wW/" + b"Ka7h0k8UHozHhJicWH/G+6zZefPyFjwdcpmzZbxy/+KEjpZ67R5I3MUVs6UO1N4" + b"E/QU4RsoQoiOxDMhBzID96+5E8xFME+iGr1gwAAARQAAAAMcnNhLXNoYTItNTEy" + b"AAABAKCRnfhn6MZs3jRgIDICUpUyWrDCbpStEbdzhmoxF8w2m8klR7owRH/rxOf" + b"nWhKMGnXnoERS+az3Zh9ckiQPujkuEToORKpzu6CEWlzHSzyK1o2X548KkW76HJ" + b"gqzwMas94HY7UOJUgKSFUI0S3jAgqXAKSa1DxvJBu5/n57aUqPq+BmAtoI8uNBo" + b"x4F1pNEop38+oD7rUt8bZ8K0VcrubJZz806K8UNiK0mOahaEIkvZXBfzPGvSNRj" + b"0OjDl1dLUZaP8C1o5lVRomEm7pLcgE9i+ZDq5iz+mvQrSBStlpQ5hPGuUOrZ/oY" + b"ZLZ1G30R5tWj212MHoNZjxFxM8+f2OT4=" + ) + + @pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", + ) + def test_sign_and_byte_compare_ed25519(self, monkeypatch, backend): + # Monkey patch urandom to return a known value so we + # get a deterministic signature with Ed25519. + monkeypatch.setattr(os, "urandom", lambda _: b"\x00" * 32) + private_key = load_vectors_from_file( + os.path.join("asymmetric", "Ed25519", "ed25519-pkcs8.pem"), + lambda pemfile: load_pem_private_key( + pemfile.read(), None, backend + ), + mode="rb", + ) + assert isinstance(private_key, ed25519.Ed25519PrivateKey) + builder = ( + SSHCertificateBuilder() + .public_key(private_key.public_key()) + .valid_for_all_principals() + .valid_after(datetime.datetime(2023, 1, 1)) + .valid_before(datetime.datetime(2023, 1, 2)) + .type(SSHCertificateType.USER) + ) + cert = builder.sign(private_key) + sig_key = cert.signature_key() + assert isinstance(sig_key, ed25519.Ed25519PublicKey) + cert.verify_cert_signature() + assert cert.public_bytes() == ( + b"ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdj" + b"AxQG9wZW5zc2guY29tAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + b"AAAAAAAINdamAGCsQq31Uv+08lkBzoO4XLz2qYjJa8CGmj3B1EaAAAAAAAAAAAA" + b"AAABAAAAAAAAAAAAAAAAY7DNAAAAAABjsh6AAAAAAAAAAAAAAAAAAAAAMwAAAAt" + b"zc2gtZWQyNTUxOQAAACDXWpgBgrEKt9VL/tPJZAc6DuFy89qmIyWvAhpo9wdRGg" + b"AAAFMAAAALc3NoLWVkMjU1MTkAAABAAlF6Lxabxs+8fkOr7KjKYei9konIG13cQ" + b"gJ2tWf3yFcg3OuV5s/AkRmKdwHlQfTUrhRdOmDnGxeLEB0mvkVFCw==" + ) From 2d99b89046f87cd8b70e45a88eb9c76a872eea5f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 8 Jan 2023 11:19:27 +0800 Subject: [PATCH 042/827] UNIX is a trademark, Unix is a category (#8008) If I'm willing to be pedantic about Apple's Mac OS vs macOS vs OS X vs Mac OS X I'm willing to die on this hill too --- docs/fernet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fernet.rst b/docs/fernet.rst index 0533e10642dc..b55ecea3206a 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -129,7 +129,7 @@ has support for implementing key rotation via :class:`MultiFernet`. :param bytes or str token: The Fernet token. This is the result of calling :meth:`encrypt`. - :returns int: The UNIX timestamp of the token. + :returns int: The Unix timestamp of the token. :raises cryptography.fernet.InvalidToken: If the ``token``'s signature is invalid this exception is raised. From 79937e9242c6c18ffd537d9b8139d39f9d14965d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 8 Jan 2023 11:29:05 +0800 Subject: [PATCH 043/827] switch to using integers for valid_after/valid_before in SSH certs (#8007) * switch to using integers for valid_after/valid_before in SSH certs * i know this, it's a unix timestamp * one more review nit --- .../primitives/asymmetric/serialization.rst | 34 ++++--- .../hazmat/primitives/serialization/ssh.py | 54 +++++------ tests/hazmat/primitives/test_ssh.py | 92 ++++++++++--------- 3 files changed, 85 insertions(+), 95 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 2bc75ab08609..155ab24f93d2 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -555,17 +555,17 @@ The format used by OpenSSH for certificates, as specified in .. attribute:: valid_after - :type: :class:`datetime.datetime` + :type: int - A naïve datetime representing the UTC time after which the certificate - is valid. **This time is inclusive.** + An integer representing the Unix timestamp (in UTC) after which the + certificate is valid. **This time is inclusive.** .. attribute:: valid_before - :type: :class:`datetime.datetime` + :type: int - A naïve datetime representing the UTC time before which the certificate - is valid. **This time is not inclusive.** + An integer representing the Unix timestamp (in UTC) before which the + certificate is valid. **This time is not inclusive.** .. attribute:: critical_options @@ -655,8 +655,12 @@ SSH Certificate Builder >>> signing_key = ec.generate_private_key(ec.SECP256R1()) >>> private_key = ec.generate_private_key(ec.SECP256R1()) >>> public_key = private_key.public_key() - >>> valid_after = datetime.datetime(2023, 1, 1, 1) - >>> valid_before = datetime.datetime(2023, 7, 1, 1) + >>> valid_after = datetime.datetime( + ... 2023, 1, 1, 1, tzinfo=datetime.timezone.utc + ... ).timestamp() + >>> valid_before = datetime.datetime( + ... 2023, 7, 1, 1, tzinfo=datetime.timezone.utc + ... ).timestamp() >>> key_id = b"a_key_id" >>> valid_principals = [b"eve", b"alice"] >>> builder = ( @@ -713,19 +717,13 @@ SSH Certificate Builder .. method:: valid_after(valid_after) - :param valid_after: The time (in UTC) that marks the activation - time for the certificate. Naïve datetime values are treated as - UTC, but timezone aware datetime values are also allowed. - This is a required value. - :type valid_after: :class:`datetime.datetime` + :param int valid_after: The Unix timestamp (in UTC) that marks the + activation time for the certificate. This is a required value. .. method:: valid_before(valid_before) - :param valid_before: The time (in UTC) that marks the expiration - time for the certificate. Naïve datetime values are treated as - UTC, but timezone aware datetime values are also allowed. - This is a required value. - :type valid_before: :class:`datetime.datetime` + :param int valid_before: The Unix timestamp (in UTC) that marks the + expiration time for the certificate. This is a required value. .. method:: add_critical_option(name, value) diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index a008fac90fa9..33686dc8c1a6 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -4,7 +4,6 @@ import binascii -import datetime import enum import os import re @@ -764,8 +763,8 @@ def __init__( raise ValueError("Invalid certificate type") self._key_id = _key_id self._valid_principals = _valid_principals - self._valid_after = datetime.datetime.utcfromtimestamp(_valid_after) - self._valid_before = datetime.datetime.utcfromtimestamp(_valid_before) + self._valid_after = _valid_after + self._valid_before = _valid_before self._critical_options = _critical_options self._extensions = _extensions self._sig_type = _sig_type @@ -803,11 +802,11 @@ def valid_principals(self) -> typing.List[bytes]: return self._valid_principals @property - def valid_before(self) -> datetime.datetime: + def valid_before(self) -> int: return self._valid_before @property - def valid_after(self) -> datetime.datetime: + def valid_after(self) -> int: return self._valid_after @property @@ -1041,17 +1040,6 @@ def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: return b"".join([key_type, b" ", pub]) -def _datetime_to_utc_timestamp(time: datetime.datetime) -> int: - if time.tzinfo is not None: - offset = time.utcoffset() - offset = offset if offset else datetime.timedelta() - new_time = time.replace(tzinfo=datetime.timezone.utc) - offset - else: - new_time = time.replace(tzinfo=datetime.timezone.utc) - - return int(new_time.timestamp()) - - _SSH_CERT_PRIVATE_KEY_TYPES = typing.Union[ ec.EllipticCurvePrivateKey, rsa.RSAPrivateKey, @@ -1068,8 +1056,8 @@ def __init__( _key_id: typing.Optional[bytes] = None, _valid_principals: typing.List[bytes] = [], _valid_for_all_principals: bool = False, - _valid_before: typing.Optional[datetime.datetime] = None, - _valid_after: typing.Optional[datetime.datetime] = None, + _valid_before: typing.Optional[int] = None, + _valid_after: typing.Optional[int] = None, _critical_options: typing.List[typing.Tuple[bytes, bytes]] = [], _extensions: typing.List[typing.Tuple[bytes, bytes]] = [], ): @@ -1225,12 +1213,13 @@ def valid_for_all_principals(self): ) def valid_before( - self, valid_before: datetime.datetime + self, valid_before: typing.Union[int, float] ) -> "SSHCertificateBuilder": - if not isinstance(valid_before, datetime.datetime): - raise TypeError("valid_before must be a datetime") - if _datetime_to_utc_timestamp(valid_before) < 0: - raise ValueError("valid_before must be after the Unix epoch") + if not isinstance(valid_before, (int, float)): + raise TypeError("valid_before must be an int or float") + valid_before = int(valid_before) + if valid_before < 0 or valid_before >= 2**64: + raise ValueError("valid_before must [0, 2**64)") if self._valid_before is not None: raise ValueError("valid_before already set") @@ -1248,12 +1237,13 @@ def valid_before( ) def valid_after( - self, valid_after: datetime.datetime + self, valid_after: typing.Union[int, float] ) -> "SSHCertificateBuilder": - if not isinstance(valid_after, datetime.datetime): - raise TypeError("valid_after must be a datetime") - if _datetime_to_utc_timestamp(valid_after) < 0: - raise ValueError("valid_after must be after the Unix epoch") + if not isinstance(valid_after, (int, float)): + raise TypeError("valid_after must be an int or float") + valid_after = int(valid_after) + if valid_after < 0 or valid_after >= 2**64: + raise ValueError("valid_after must [0, 2**64)") if self._valid_after is not None: raise ValueError("valid_after already set") @@ -1353,9 +1343,7 @@ def sign(self, private_key: _SSH_CERT_PRIVATE_KEY_TYPES) -> SSHCertificate: if self._valid_after is None: raise ValueError("valid_after must be set") - valid_after = _datetime_to_utc_timestamp(self._valid_after) - valid_before = _datetime_to_utc_timestamp(self._valid_before) - if valid_after > valid_before: + if self._valid_after > self._valid_before: raise ValueError("valid_after must be earlier than valid_before") # lexically sort our byte strings @@ -1379,8 +1367,8 @@ def sign(self, private_key: _SSH_CERT_PRIVATE_KEY_TYPES) -> SSHCertificate: for p in self._valid_principals: fprincipals.put_sshstr(p) f.put_sshstr(fprincipals.tobytes()) - f.put_u64(valid_after) - f.put_u64(valid_before) + f.put_u64(self._valid_after) + f.put_u64(self._valid_before) fcrit = _FragList() for name, value in self._critical_options: fcrit.put_sshstr(name) diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index fb801f5d0c6e..0bf782e5dd05 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -8,7 +8,6 @@ import os import pytest -import pytz from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives.asymmetric import ( @@ -1056,8 +1055,8 @@ def test_loads_ssh_cert(self, backend): assert cert.type is SSHCertificateType.USER assert cert.key_id == b"test@cryptography.io" assert cert.valid_principals == [b"cryptouser", b"testuser"] - assert cert.valid_before == datetime.datetime(2032, 12, 30, 10, 32, 32) - assert cert.valid_after == datetime.datetime(2023, 1, 2, 10, 31) + assert cert.valid_before == 1988015552 + assert cert.valid_after == 1672655460 assert cert.critical_options == {} assert cert.extensions == { b"permit-X11-forwarding": b"", @@ -1249,11 +1248,12 @@ class TestSSHCertificateBuilder: def test_signs_a_cert(self): private_key = ec.generate_private_key(ec.SECP256R1()) public_key = ec.generate_private_key(ec.SECP256R1()).public_key() - valid_before = datetime.datetime(2023, 7, 16, 18, 43) - tz = pytz.timezone("US/Eastern") - valid_before = tz.localize(valid_before) - utc_time_before = datetime.datetime(2023, 7, 16, 22, 43) - valid_after = datetime.datetime(2023, 1, 16, 22, 43) + valid_after = datetime.datetime( + 2023, 1, 1, 1, tzinfo=datetime.timezone.utc + ).timestamp() + valid_before = datetime.datetime( + 2023, 6, 1, 1, tzinfo=datetime.timezone.utc + ).timestamp() key_id = b"test" valid_principals = [b"eve", b"alice"] builder = ( @@ -1278,8 +1278,8 @@ def test_signs_a_cert(self): assert cert.type is SSHCertificateType.USER assert cert.key_id == key_id assert cert.valid_principals == valid_principals - assert cert.valid_before == utc_time_before - assert cert.valid_after == valid_after + assert cert.valid_before == int(valid_before) + assert cert.valid_after == int(valid_after) assert cert.critical_options == {b"ordered": b"", b"maybe": b"test2"} assert list(cert.critical_options) == [b"maybe", b"ordered"] assert cert.extensions == {b"test": b"a value", b"allowed": b""} @@ -1355,22 +1355,26 @@ def test_valid_for_all_principals_errors(self): def test_valid_before_errors(self): builder = SSHCertificateBuilder() with pytest.raises(TypeError): - builder.valid_before("not a datetime") # type: ignore[arg-type] + builder.valid_before("not an int") # type: ignore[arg-type] with pytest.raises(ValueError): - builder.valid_before(datetime.datetime(1960, 1, 1)) - builder = builder.valid_before(datetime.datetime(2023, 1, 1)) + builder.valid_before(-1) with pytest.raises(ValueError): - builder.valid_before(datetime.datetime(2023, 1, 1)) + builder.valid_after(2**64) + builder = builder.valid_before(12345) + with pytest.raises(ValueError): + builder.valid_before(123456) def test_valid_after_errors(self): builder = SSHCertificateBuilder() with pytest.raises(TypeError): - builder.valid_after("not a datetime") # type: ignore[arg-type] + builder.valid_after("not an int") # type: ignore[arg-type] + with pytest.raises(ValueError): + builder.valid_after(-1) with pytest.raises(ValueError): - builder.valid_after(datetime.datetime(1960, 1, 1)) - builder = builder.valid_after(datetime.datetime(2023, 1, 1)) + builder.valid_after(2**64) + builder = builder.valid_after(1234) with pytest.raises(ValueError): - builder.valid_after(datetime.datetime(2023, 1, 1)) + builder.valid_after(12345) def test_add_critical_option_errors(self): builder = SSHCertificateBuilder() @@ -1402,8 +1406,8 @@ def test_sign_unsupported_key(self): builder = ( SSHCertificateBuilder() .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) with pytest.raises(TypeError): @@ -1414,8 +1418,8 @@ def test_sign_no_public_key(self): builder = ( SSHCertificateBuilder() .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) with pytest.raises(ValueError): @@ -1427,8 +1431,8 @@ def test_sign_no_type(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) ) with pytest.raises(ValueError): builder.sign(private_key) @@ -1438,8 +1442,8 @@ def test_sign_no_valid_principals(self): builder = ( SSHCertificateBuilder() .public_key(private_key.public_key()) - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) with pytest.raises(ValueError): @@ -1451,7 +1455,7 @@ def test_sign_no_valid_after(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) with pytest.raises(ValueError): @@ -1463,7 +1467,7 @@ def test_sign_no_valid_before(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_principals([b"bob"]) - .valid_after(datetime.datetime(2023, 1, 1)) + .valid_after(0) .type(SSHCertificateType.USER) ) with pytest.raises(ValueError): @@ -1475,8 +1479,8 @@ def test_sign_valid_after_after_valid_before(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_principals([b"eve"]) - .valid_after(datetime.datetime(2023, 1, 2)) - .valid_before(datetime.datetime(2023, 1, 1)) + .valid_after(20) + .valid_before(0) .type(SSHCertificateType.USER) ) with pytest.raises(ValueError): @@ -1489,8 +1493,8 @@ def test_sign_non_zero_serial(self): .public_key(private_key.public_key()) .serial(123456789) .valid_principals([b"alice"]) - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) @@ -1502,8 +1506,8 @@ def test_crit_opts_exts_lexically_sorted(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) .add_critical_option(b"zebra@cryptography.io", b"") .add_critical_option(b"apple@cryptography.io", b"") @@ -1537,8 +1541,8 @@ def test_sign_ed25519(self, backend): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) @@ -1554,8 +1558,8 @@ def test_sign_ec(self, curve): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) @@ -1570,8 +1574,8 @@ def test_sign_rsa(self): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(0) + .valid_before(2**64 - 1) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) @@ -1588,8 +1592,8 @@ def test_sign_and_byte_compare_rsa(self, monkeypatch): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(1672531200) + .valid_before(1672617600) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) @@ -1640,8 +1644,8 @@ def test_sign_and_byte_compare_ed25519(self, monkeypatch, backend): SSHCertificateBuilder() .public_key(private_key.public_key()) .valid_for_all_principals() - .valid_after(datetime.datetime(2023, 1, 1)) - .valid_before(datetime.datetime(2023, 1, 2)) + .valid_after(1672531200) + .valid_before(1672617600) .type(SSHCertificateType.USER) ) cert = builder.sign(private_key) From f7f33fb6763cebe93f240ec7367287215d4275d1 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 8 Jan 2023 21:59:16 +0800 Subject: [PATCH 044/827] deprecate support for DSA in load_ssh_public_key (#8009) * deprecate support for DSA in load_ssh_public_key * try to prevent bad things a bit more --- CHANGELOG.rst | 2 + .../hazmat/primitives/serialization/ssh.py | 69 +++++++------------ src/cryptography/utils.py | 1 + tests/hazmat/primitives/test_ssh.py | 25 +++++-- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d3fe0fa29f67..35bd9fa22745 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ Changelog * Support for Python 3.6 is deprecated and will be removed in the next release. +* Deprecated support for parsing DSA keys in + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key`. * Added support for parsing SSH certificates in addition to public keys with :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 33686dc8c1a6..9395493e8b9e 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -8,6 +8,7 @@ import os import re import typing +import warnings from base64 import encodebytes as _base64_encode from cryptography import utils @@ -782,8 +783,7 @@ def nonce(self) -> bytes: def public_key(self) -> _SSH_CERT_PUBLIC_KEY_TYPES: # make mypy happy until we remove DSA support entirely and # the underlying union won't have a disallowed type - assert not isinstance(self._public_key, dsa.DSAPublicKey) - return self._public_key + return typing.cast(_SSH_CERT_PUBLIC_KEY_TYPES, self._public_key) @property def serial(self) -> int: @@ -873,8 +873,9 @@ def _get_ec_hash_alg(curve: ec.EllipticCurve) -> hashes.HashAlgorithm: return hashes.SHA512() -def load_ssh_public_identity( +def _load_ssh_public_identity( data: bytes, + _legacy_dsa_allowed=False, ) -> typing.Union[SSHCertificate, _SSH_PUBLIC_KEY_TYPES]: utils._check_byteslike("data", data) @@ -887,7 +888,7 @@ def load_ssh_public_identity( if key_type.endswith(_CERT_SUFFIX): with_cert = True key_type = key_type[: -len(_CERT_SUFFIX)] - if key_type == _SSH_DSA: + if key_type == _SSH_DSA and not _legacy_dsa_allowed: raise UnsupportedAlgorithm( "DSA keys aren't supported in SSH certificates" ) @@ -925,7 +926,7 @@ def load_ssh_public_identity( _, rest = _get_sshstr(rest) sig_key_raw, rest = _get_sshstr(rest) sig_type, sig_key = _get_sshstr(sig_key_raw) - if sig_type == _SSH_DSA: + if sig_type == _SSH_DSA and not _legacy_dsa_allowed: raise UnsupportedAlgorithm( "DSA signatures aren't supported in SSH certificates" ) @@ -967,6 +968,12 @@ def load_ssh_public_identity( return public_key +def load_ssh_public_identity( + data: bytes, +) -> typing.Union[SSHCertificate, _SSH_PUBLIC_KEY_TYPES]: + return _load_ssh_public_identity(data) + + def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: result: typing.Dict[bytes, bytes] = {} last_name = None @@ -986,44 +993,20 @@ def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: def load_ssh_public_key( data: bytes, backend: typing.Any = None ) -> _SSH_PUBLIC_KEY_TYPES: - """Load public key from OpenSSH one-line format.""" - utils._check_byteslike("data", data) - - m = _SSH_PUBKEY_RC.match(data) - if not m: - raise ValueError("Invalid line format") - key_type = orig_key_type = m.group(1) - key_body = m.group(2) - with_cert = False - if _CERT_SUFFIX == key_type[-len(_CERT_SUFFIX) :]: - with_cert = True - key_type = key_type[: -len(_CERT_SUFFIX)] - kformat = _lookup_kformat(key_type) - - try: - rest = memoryview(binascii.a2b_base64(key_body)) - except (TypeError, binascii.Error): - raise ValueError("Invalid key format") - - inner_key_type, rest = _get_sshstr(rest) - if inner_key_type != orig_key_type: - raise ValueError("Invalid key format") - if with_cert: - nonce, rest = _get_sshstr(rest) - public_key, rest = kformat.load_public(rest) - if with_cert: - serial, rest = _get_u64(rest) - cctype, rest = _get_u32(rest) - key_id, rest = _get_sshstr(rest) - principals, rest = _get_sshstr(rest) - valid_after, rest = _get_u64(rest) - valid_before, rest = _get_u64(rest) - crit_options, rest = _get_sshstr(rest) - extensions, rest = _get_sshstr(rest) - reserved, rest = _get_sshstr(rest) - sig_key, rest = _get_sshstr(rest) - signature, rest = _get_sshstr(rest) - _check_empty(rest) + cert_or_key = _load_ssh_public_identity(data, _legacy_dsa_allowed=True) + public_key: _SSH_PUBLIC_KEY_TYPES + if isinstance(cert_or_key, SSHCertificate): + public_key = cert_or_key.public_key() + else: + public_key = cert_or_key + + if isinstance(public_key, dsa.DSAPublicKey): + warnings.warn( + "SSH DSA keys are deprecated and will be removed in a future " + "release.", + utils.DeprecatedIn40, + stacklevel=2, + ) return public_key diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 7f4a4799bf92..709e7ca88968 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -23,6 +23,7 @@ class CryptographyDeprecationWarning(UserWarning): DeprecatedIn36 = CryptographyDeprecationWarning DeprecatedIn37 = CryptographyDeprecationWarning DeprecatedIn39 = CryptographyDeprecationWarning +DeprecatedIn40 = CryptographyDeprecationWarning def _check_bytes(name: str, value: bytes) -> None: diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 0bf782e5dd05..50727ce1b6bb 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -9,6 +9,7 @@ import pytest +from cryptography import utils from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives.asymmetric import ( dsa, @@ -63,7 +64,11 @@ def test_load_ssh_public_key(self, key_file, cert_file, backend): lambda f: f.read(), mode="rb", ) - public_key = load_ssh_public_key(pub_data, backend) + if key_file.startswith("dsa"): + with pytest.warns(utils.DeprecatedIn40): + public_key = load_ssh_public_key(pub_data, backend) + else: + public_key = load_ssh_public_key(pub_data, backend) nocomment_data = b" ".join(pub_data.split()[:2]) assert ( public_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) @@ -79,7 +84,11 @@ def test_load_ssh_public_key(self, key_file, cert_file, backend): lambda f: f.read(), mode="rb", ) - cert_key = load_ssh_public_key(cert_data, backend) + if cert_file.startswith("dsa"): + with pytest.warns(utils.DeprecatedIn40): + cert_key = load_ssh_public_key(cert_data, backend) + else: + cert_key = load_ssh_public_key(cert_data, backend) assert ( cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) == nocomment_data @@ -87,7 +96,11 @@ def test_load_ssh_public_key(self, key_file, cert_file, backend): # try with more spaces cert_data = b" \t ".join(cert_data.split()) - cert_key = load_ssh_public_key(cert_data, backend) + if cert_file.startswith("dsa"): + with pytest.warns(utils.DeprecatedIn40): + cert_key = load_ssh_public_key(cert_data, backend) + else: + cert_key = load_ssh_public_key(cert_data, backend) assert ( cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) == nocomment_data @@ -747,7 +760,8 @@ def test_load_ssh_public_key_dss_comment_with_spaces(self, backend): b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost extra" ) - load_ssh_public_key(ssh_key, backend) + with pytest.warns(utils.DeprecatedIn40): + load_ssh_public_key(ssh_key, backend) def test_load_ssh_public_key_dss_extra_data_after_modulo(self, backend): ssh_key = ( @@ -799,7 +813,8 @@ def test_load_ssh_public_key_dss(self, backend): b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost" ) - key = load_ssh_public_key(ssh_key, backend) + with pytest.warns(utils.DeprecatedIn40): + key = load_ssh_public_key(ssh_key, backend) assert key is not None assert isinstance(key, dsa.DSAPublicKey) From 5c48b8917a2f327a197f2abbbe38f76fb38d7f01 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 8 Jan 2023 21:59:47 +0800 Subject: [PATCH 045/827] more rigorously document that our verify methods return none (#8010) they raise an exception! --- docs/hazmat/primitives/asymmetric/dsa.rst | 1 + docs/hazmat/primitives/asymmetric/ec.rst | 1 + docs/hazmat/primitives/asymmetric/ed25519.rst | 1 + docs/hazmat/primitives/asymmetric/ed448.rst | 1 + docs/hazmat/primitives/asymmetric/rsa.rst | 1 + 5 files changed, 5 insertions(+) diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst index 69f128ba1b20..8bfe815bba40 100644 --- a/docs/hazmat/primitives/asymmetric/dsa.rst +++ b/docs/hazmat/primitives/asymmetric/dsa.rst @@ -408,6 +408,7 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed` if the ``data`` you want to sign has already been hashed. + :returns: None :raises cryptography.exceptions.InvalidSignature: If the signature does not validate. diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index 95244c2eba13..dd95f223d27f 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -715,6 +715,7 @@ Key Interfaces :param signature_algorithm: An instance of :class:`EllipticCurveSignatureAlgorithm`. + :returns: None :raises cryptography.exceptions.InvalidSignature: If the signature does not validate. diff --git a/docs/hazmat/primitives/asymmetric/ed25519.rst b/docs/hazmat/primitives/asymmetric/ed25519.rst index 3229f0932ae7..17ebe2778945 100644 --- a/docs/hazmat/primitives/asymmetric/ed25519.rst +++ b/docs/hazmat/primitives/asymmetric/ed25519.rst @@ -169,6 +169,7 @@ Key interfaces :param bytes data: The data to verify. + :returns: None :raises cryptography.exceptions.InvalidSignature: Raised when the signature cannot be verified. diff --git a/docs/hazmat/primitives/asymmetric/ed448.rst b/docs/hazmat/primitives/asymmetric/ed448.rst index fb79dcb61ba3..d20fe73892cb 100644 --- a/docs/hazmat/primitives/asymmetric/ed448.rst +++ b/docs/hazmat/primitives/asymmetric/ed448.rst @@ -123,6 +123,7 @@ Key interfaces :param bytes data: The data to verify. + :returns: None :raises cryptography.exceptions.InvalidSignature: Raised when the signature cannot be verified. diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 0bf4c0291b11..7291e8c5b0ad 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -729,6 +729,7 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed` if the ``data`` you want to verify has already been hashed. + :returns: None :raises cryptography.exceptions.InvalidSignature: If the signature does not validate. From 17da400b651fd940879a14b6d9c2964037de8d7f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 9 Jan 2023 09:14:00 +0800 Subject: [PATCH 046/827] deprecate the rest of DSA support for SSH (#8013) * deprecate the rest of DSA support for SSH * review comments --- CHANGELOG.rst | 10 +- docs/hazmat/primitives/asymmetric/dsa.rst | 1 - .../primitives/asymmetric/serialization.rst | 10 ++ .../hazmat/primitives/serialization/ssh.py | 22 +++ tests/hazmat/primitives/test_dsa.py | 9 +- tests/hazmat/primitives/test_ssh.py | 170 ++++++++++-------- 6 files changed, 146 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 35bd9fa22745..1d252cd2d116 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,8 +10,14 @@ Changelog * Support for Python 3.6 is deprecated and will be removed in the next release. -* Deprecated support for parsing DSA keys in - :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key`. +* Deprecated support for DSA keys in + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` + and + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key`. +* Deprecated support for OpenSSH serialization in + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey` + and + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. * Added support for parsing SSH certificates in addition to public keys with :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst index 8bfe815bba40..e70312cc3baa 100644 --- a/docs/hazmat/primitives/asymmetric/dsa.rst +++ b/docs/hazmat/primitives/asymmetric/dsa.rst @@ -315,7 +315,6 @@ Key interfaces :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`), format ( :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.TraditionalOpenSSL`, - :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.OpenSSH` or :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8`) and encryption algorithm (such as diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 155ab24f93d2..14022f26d7ce 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -392,6 +392,11 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than .. versionadded:: 0.7 + .. note:: + + SSH DSA key support is deprecated and will be removed in a future + release. + Deserialize a public key from OpenSSH (:rfc:`4253` and `PROTOCOL.certkeys`_) encoded data to an instance of the public key type. @@ -435,6 +440,11 @@ An example ECDSA key in OpenSSH format:: .. versionadded:: 3.0 + .. note:: + + SSH DSA key support is deprecated and will be removed in a future + release. + Deserialize a private key from OpenSSH encoded data to an instance of the private key type. diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 9395493e8b9e..2970ede1b7e3 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -642,6 +642,14 @@ def load_ssh_private_key( if edata != _PADDING[: len(edata)]: raise ValueError("Corrupt data: invalid padding") + if isinstance(private_key, dsa.DSAPrivateKey): + warnings.warn( + "SSH DSA keys are deprecated and will be removed in a future " + "release.", + utils.DeprecatedIn40, + stacklevel=2, + ) + return private_key @@ -652,6 +660,13 @@ def _serialize_ssh_private_key( ) -> bytes: """Serialize private key with OpenSSH custom encoding.""" utils._check_bytes("password", password) + if isinstance(private_key, dsa.DSAPrivateKey): + warnings.warn( + "SSH DSA key support is deprecated and will be " + "removed in a future release", + utils.DeprecatedIn40, + stacklevel=4, + ) key_type = _get_ssh_key_type(private_key) kformat = _lookup_kformat(key_type) @@ -1012,6 +1027,13 @@ def load_ssh_public_key( def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: """One-line public key format for OpenSSH""" + if isinstance(public_key, dsa.DSAPublicKey): + warnings.warn( + "SSH DSA key support is deprecated and will be " + "removed in a future release", + utils.DeprecatedIn40, + stacklevel=4, + ) key_type = _get_ssh_key_type(public_key) kformat = _lookup_kformat(key_type) diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 4ad4e9317482..a1814c08209d 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -9,6 +9,7 @@ import pytest +from cryptography import utils from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import dsa @@ -920,9 +921,11 @@ def test_public_bytes_openssh(self, backend): ) key = serialization.load_pem_public_key(key_bytes, backend) - ssh_bytes = key.public_bytes( - serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH - ) + with pytest.warns(utils.DeprecatedIn40): + ssh_bytes = key.public_bytes( + serialization.Encoding.OpenSSH, + serialization.PublicFormat.OpenSSH, + ) assert ssh_bytes == ( b"ssh-dss AAAAB3NzaC1kc3MAAACBAKoJMMwUWCUiHK/6KKwolBlqJ4M95ewhJweR" b"aJQgd3Si57I4sNNvGySZosJYUIPrAUMpJEGNhn+qIS3RBx1NzrJ4J5StOTzAik1K" diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 50727ce1b6bb..8403b9f88059 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -64,16 +64,23 @@ def test_load_ssh_public_key(self, key_file, cert_file, backend): lambda f: f.read(), mode="rb", ) + nocomment_data = b" ".join(pub_data.split()[:2]) if key_file.startswith("dsa"): with pytest.warns(utils.DeprecatedIn40): public_key = load_ssh_public_key(pub_data, backend) + with pytest.warns(utils.DeprecatedIn40): + assert ( + public_key.public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) else: public_key = load_ssh_public_key(pub_data, backend) - nocomment_data = b" ".join(pub_data.split()[:2]) - assert ( - public_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) + assert ( + public_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) + == nocomment_data + ) self.run_partial_pubkey(pub_data, backend) @@ -87,24 +94,42 @@ def test_load_ssh_public_key(self, key_file, cert_file, backend): if cert_file.startswith("dsa"): with pytest.warns(utils.DeprecatedIn40): cert_key = load_ssh_public_key(cert_data, backend) + with pytest.warns(utils.DeprecatedIn40): + assert ( + cert_key.public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) else: cert_key = load_ssh_public_key(cert_data, backend) - assert ( - cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) + assert ( + cert_key.public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) # try with more spaces cert_data = b" \t ".join(cert_data.split()) if cert_file.startswith("dsa"): with pytest.warns(utils.DeprecatedIn40): cert_key = load_ssh_public_key(cert_data, backend) + with pytest.warns(utils.DeprecatedIn40): + assert ( + cert_key.public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) else: cert_key = load_ssh_public_key(cert_data, backend) - assert ( - cert_key.public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH) - == nocomment_data - ) + assert ( + cert_key.public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) self.run_partial_pubkey(cert_data, backend) @@ -153,63 +178,66 @@ def test_load_ssh_private_key(self, key_file, backend): password = None if "-psw" in key_file: password = b"password" - private_key = load_ssh_private_key(priv_data, password, backend) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # bytearray - private_key = load_ssh_private_key( - bytearray(priv_data), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # memoryview(bytes) - private_key = load_ssh_private_key( - memoryview(priv_data), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) - - # memoryview(bytearray) - private_key = load_ssh_private_key( - memoryview(bytearray(priv_data)), password, backend - ) - assert ( - private_key.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH - ) - == nocomment_data - ) + for data in [ + priv_data, + bytearray(priv_data), + memoryview(priv_data), + memoryview(bytearray(priv_data)), + ]: + if key_file.startswith("dsa"): + with pytest.warns(utils.DeprecatedIn40): + private_key = load_ssh_private_key(data, password, backend) + with pytest.warns(utils.DeprecatedIn40): + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + else: + private_key = load_ssh_private_key(data, password, backend) + assert ( + private_key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) # serialize with own code and reload encryption: KeySerializationEncryption = NoEncryption() if password: encryption = BestAvailableEncryption(password) - priv_data2 = private_key.private_bytes( - Encoding.PEM, - PrivateFormat.OpenSSH, - encryption, - ) - private_key2 = load_ssh_private_key(priv_data2, password, backend) - assert ( - private_key2.public_key().public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH + if key_file.startswith("dsa"): + with pytest.warns(utils.DeprecatedIn40): + priv_data2 = private_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + encryption, + ) + with pytest.warns(utils.DeprecatedIn40): + private_key2 = load_ssh_private_key( + priv_data2, password, backend + ) + with pytest.warns(utils.DeprecatedIn40): + assert ( + private_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data + ) + else: + priv_data2 = private_key.private_bytes( + Encoding.PEM, + PrivateFormat.OpenSSH, + encryption, + ) + private_key2 = load_ssh_private_key(priv_data2, password, backend) + assert ( + private_key2.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH + ) + == nocomment_data ) - == nocomment_data - ) # make sure multi-line base64 is used maxline = max(map(len, priv_data2.split(b"\n"))) @@ -616,15 +644,17 @@ def test_dsa_private_key_sizes(self, key_path, supported, backend): ) assert isinstance(key, dsa.DSAPrivateKey) if supported: - res = key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() - ) + with pytest.warns(utils.DeprecatedIn40): + res = key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() + ) assert isinstance(res, bytes) else: with pytest.raises(ValueError): - key.private_bytes( - Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() - ) + with pytest.warns(utils.DeprecatedIn40): + key.private_bytes( + Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption() + ) class TestRSASSHSerialization: From d13482e4902b86835b2d19a3f33e93484ba0a991 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 9 Jan 2023 14:05:01 -0500 Subject: [PATCH 047/827] update sid's python (#8029) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2fc1a377711..975e026e990d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -133,7 +133,7 @@ jobs: - {IMAGE: "buster", TOXENV: "py37"} - {IMAGE: "bullseye", TOXENV: "py39"} - {IMAGE: "bookworm", TOXENV: "py310"} - - {IMAGE: "sid", TOXENV: "py310"} + - {IMAGE: "sid", TOXENV: "py311"} - {IMAGE: "ubuntu-bionic", TOXENV: "py36"} - {IMAGE: "ubuntu-focal", TOXENV: "py38"} - {IMAGE: "ubuntu-jammy", TOXENV: "py310"} From e0bf9d9c234fd3c8eba2b14c111436eaad0a064e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:27:59 +0800 Subject: [PATCH 048/827] Bump sphinxcontrib-applehelp from 1.0.2 to 1.0.3 (#8022) Bumps [sphinxcontrib-applehelp](https://github.com/sphinx-doc/sphinxcontrib-applehelp) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/sphinx-doc/sphinxcontrib-applehelp/releases) - [Changelog](https://github.com/sphinx-doc/sphinxcontrib-applehelp/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinxcontrib-applehelp/compare/1.0.2...1.0.3) --- updated-dependencies: - dependency-name: sphinxcontrib-applehelp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 12359228127a..3e153c40edc3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -174,7 +174,7 @@ sphinx==5.3.0 # sphinxcontrib-spelling sphinx-rtd-theme==1.1.1 # via cryptography (setup.cfg) -sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-applehelp==1.0.3 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx From 92403b79455b01a717594d2c69a97f6c19745620 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:28:22 +0800 Subject: [PATCH 049/827] Bump coverage from 7.0.3 to 7.0.4 (#8028) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.3 to 7.0.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.3...7.0.4) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3e153c40edc3..4391050cdf85 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -35,7 +35,7 @@ colorama==0.4.6; python_version >= "3.7" # via tox commonmark==0.9.1 # via rich -coverage==7.0.3; python_version >= "3.7" +coverage==7.0.4; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 3ade0fef5e0299213ad1b1e3ab77905cfc80b5f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:28:35 +0800 Subject: [PATCH 050/827] Bump actions/upload-artifact from 3.1.1 to 3.1.2 (#8014) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3.1.1...v3.1.2) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 975e026e990d..dd05788ddf4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -601,14 +601,14 @@ jobs: run: python -m coverage html if: ${{ failure() && steps.combinecoverage.outcome == 'failure' }} - name: Upload HTML report. - uses: actions/upload-artifact@v3.1.1 + uses: actions/upload-artifact@v3.1.2 with: name: _html-report path: htmlcov if-no-files-found: ignore if: ${{ failure() && steps.combinecoverage.outcome == 'failure' }} - name: Upload rust HTML report. - uses: actions/upload-artifact@v3.1.1 + uses: actions/upload-artifact@v3.1.2 with: name: _html-rust-report path: rust-coverage diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 670cb506b0e0..37e92995f910 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -37,11 +37,11 @@ jobs: run: .venv/bin/python setup.py sdist - name: Make sdist and wheel (vectors) run: cd vectors/ && ../.venv/bin/python setup.py sdist bdist_wheel - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v3.1.2 with: name: "cryptography-sdist" path: dist/cryptography* - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v3.1.2 with: name: "vectors-sdist-wheel" path: vectors/dist/cryptography* @@ -104,7 +104,7 @@ jobs: .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'))" - run: mkdir cryptography-wheelhouse - run: mv wheelhouse/cryptography*.whl cryptography-wheelhouse/ - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v3.1.2 with: name: "cryptography-${{ github.event.inputs.version }}-${{ matrix.MANYLINUX.NAME }}-${{ matrix.PYTHON.VERSION }}" path: cryptography-wheelhouse/ @@ -209,7 +209,7 @@ jobs: - run: mv wheelhouse/cryptography*.whl cryptography-wheelhouse/ - run: | echo "CRYPTOGRAPHY_WHEEL_NAME=$(basename $(ls cryptography-wheelhouse/cryptography*.whl))" >> $GITHUB_ENV - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v3.1.2 with: name: "${{ env.CRYPTOGRAPHY_WHEEL_NAME }}" path: cryptography-wheelhouse/ @@ -277,7 +277,7 @@ jobs: - run: mkdir cryptography-wheelhouse - run: move wheelhouse\cryptography*.whl cryptography-wheelhouse\ - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v3.1.2 with: name: "cryptography-${{ github.event.inputs.version }}-${{ matrix.WINDOWS.WINDOWS }}-${{ matrix.PYTHON.VERSION }}-${{ matrix.PYTHON.ABI_VERSION}}" path: cryptography-wheelhouse\ From 276f6f28fe4d561901d4b731fb8ac4154e53e39d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:28:49 +0800 Subject: [PATCH 051/827] Bump actions/cache from 3.2.2 to 3.2.3 (#8015) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.2 to 3.2.3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.2...v3.2.3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 16 ++++++++-------- .github/workflows/macarm64.yml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd05788ddf4a..88b70e3d579e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: actions/setup-python@v4.4.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | @@ -89,7 +89,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load cache - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 id: ossl-cache timeout-minutes: 5 with: @@ -148,7 +148,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | @@ -209,7 +209,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | @@ -260,7 +260,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 id: cargo-cache timeout-minutes: 5 with: @@ -346,7 +346,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | @@ -416,7 +416,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | @@ -478,7 +478,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 timeout-minutes: 5 with: path: | diff --git a/.github/workflows/macarm64.yml b/.github/workflows/macarm64.yml index e8138a6f573a..2acd099c3ea4 100644 --- a/.github/workflows/macarm64.yml +++ b/.github/workflows/macarm64.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v3.3.0 with: persist-credentials: false - - uses: actions/cache@v3.2.2 + - uses: actions/cache@v3.2.3 with: path: | src/rust/target/ From c5d53e5c22c575c4badbd247a0b48edbf5f9f07f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:29:15 +0800 Subject: [PATCH 052/827] Bump cxx from 1.0.85 to 1.0.86 in /src/rust (#8016) Bumps [cxx](https://github.com/dtolnay/cxx) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.85...1.0.86) --- updated-dependencies: - dependency-name: cxx dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 02b8e8c73488..fe8f1587663e 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" dependencies = [ "cc", "cxxbridge-flags", @@ -149,15 +149,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" +checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" [[package]] name = "cxxbridge-macro" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" dependencies = [ "proc-macro2", "quote", From e2a90c35ccf682cbc334d713cd3b46cdf76d2dcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:29:35 +0800 Subject: [PATCH 053/827] Bump hypothesis from 6.61.0 to 6.62.0 (#8027) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.61.0 to 6.62.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.61.0...hypothesis-python-6.62.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4391050cdf85..7c1f670cb248 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -54,7 +54,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.61.0; python_version >= "3.7" +hypothesis==6.62.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 1738ae0e45b57c43498a536ca1fb28a253b24dc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:29:50 +0800 Subject: [PATCH 054/827] Bump cachetools from 5.2.0 to 5.2.1 (#8023) Bumps [cachetools](https://github.com/tkem/cachetools) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/tkem/cachetools/releases) - [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tkem/cachetools/commits) --- updated-dependencies: - dependency-name: cachetools dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7c1f670cb248..435a9a248aac 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -19,7 +19,7 @@ bleach==5.0.1 # via readme-renderer build==0.9.0 # via check-manifest -cachetools==5.2.0 +cachetools==5.2.1 # via tox certifi==2022.12.7 # via requests From cbcb10a4d011ee6b5e3a592d3f133f7bab3eb511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:30:07 +0800 Subject: [PATCH 055/827] Bump ruff from 0.0.212 to 0.0.215 (#8020) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.212 to 0.0.215. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.212...v0.0.215) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 435a9a248aac..1c21f0acb86d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.0 # via twine -ruff==0.0.212 +ruff==0.0.215 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 4a273177e9941662f93edea93151c44c671ed39e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:30:35 +0800 Subject: [PATCH 056/827] Bump pkginfo from 1.9.4 to 1.9.6 (#8018) Bumps [pkginfo](https://code.launchpad.net/~tseaver/pkginfo/trunk) from 1.9.4 to 1.9.6. --- updated-dependencies: - dependency-name: pkginfo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1c21f0acb86d..3e58ec16126c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -95,7 +95,7 @@ pathspec==0.10.3 # via black pep517==0.13.0 # via build -pkginfo==1.9.4 +pkginfo==1.9.6 # via twine platformdirs==2.6.2; python_version >= "3.7" # via From 632e97b24817bd36482d1a4e714bf8795c7e48fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:31:18 +0800 Subject: [PATCH 057/827] Bump cxx-build from 1.0.85 to 1.0.86 in /src/rust (#8017) Bumps [cxx-build](https://github.com/dtolnay/cxx) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.85...1.0.86) --- updated-dependencies: - dependency-name: cxx-build dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index fe8f1587663e..d5ee7daec00b 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" dependencies = [ "cc", "codespan-reporting", From 730a7eac87d3671d59438cd9bf348e9486468236 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 03:32:36 +0800 Subject: [PATCH 058/827] Bump packaging from 22.0 to 23.0 (#8026) Bumps [packaging](https://github.com/pypa/packaging) from 22.0 to 23.0. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/22.0...23.0) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3e58ec16126c..aa9480cee1a7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -84,7 +84,7 @@ mypy-extensions==0.4.3 # via # black # mypy -packaging==22.0; python_version >= "3.7" +packaging==23.0; python_version >= "3.7" # via # build # pyproject-api From 25ee70bf7aad66f928dfb5370f2866ed9fff0266 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 20:33:35 +0000 Subject: [PATCH 059/827] Bump tox from 4.2.4 to 4.2.6 (#8025) Bumps [tox](https://github.com/tox-dev/tox) from 4.2.4 to 4.2.6. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.2.4...4.2.6) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index aa9480cee1a7..b91897dd7a4e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-api # pytest # tox -tox==4.2.4; python_version >= "3.7" +tox==4.2.6; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 6b8fd76516a6b16575174b6e921e52233edd09d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 20:33:48 +0000 Subject: [PATCH 060/827] Bump rich from 13.0.0 to 13.0.1 (#8019) Bumps [rich](https://github.com/Textualize/rich) from 13.0.0 to 13.0.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.0.0...v13.0.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b91897dd7a4e..abb05f13076a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -157,7 +157,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.0.0 +rich==13.0.1 # via twine ruff==0.0.215 # via cryptography (setup.cfg) From 93f8b094fd21b8011ebf6b83455a8ebd130881e2 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 10 Jan 2023 06:42:42 +0800 Subject: [PATCH 061/827] remove the last vestiges of sha1 out of pkcs7 (#8032) we already didn't support signing (released in 39.0) --- src/cryptography/hazmat/primitives/serialization/pkcs7.py | 3 +-- src/rust/src/pkcs7.rs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 7e593e719377..7b8ab300fecb 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -88,7 +88,6 @@ def add_signer( if not isinstance( hash_algorithm, ( - hashes.SHA1, hashes.SHA224, hashes.SHA256, hashes.SHA384, @@ -96,7 +95,7 @@ def add_signer( ), ): raise TypeError( - "hash_algorithm must be one of hashes.SHA1, SHA224, " + "hash_algorithm must be one of hashes.SHA224, " "SHA256, SHA384, or SHA512" ) if not isinstance(certificate, x509.Certificate): diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index db5db88ec658..d760776564e3 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -32,7 +32,6 @@ static EMPTY_STRING_TLV: Lazy> = static OIDS_TO_MIC_NAME: Lazy> = Lazy::new(|| { let mut h = HashMap::new(); - h.insert(&x509::oid::SHA1_OID, "sha1"); h.insert(&x509::oid::SHA224_OID, "sha-224"); h.insert(&x509::oid::SHA256_OID, "sha-256"); h.insert(&x509::oid::SHA384_OID, "sha-384"); From c888314f7dc76472efc7c8836ed75f4d64ad4350 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 10 Jan 2023 06:42:53 +0800 Subject: [PATCH 062/827] update ini_config (replaces #8024) (#8033) --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index abb05f13076a..e874a18f70bc 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -64,7 +64,7 @@ importlib-metadata==6.0.0; python_version >= "3.7" # via # keyring # twine -iniconfig==1.1.1 +iniconfig==2.0.0; python_version >= "3.7" # via pytest iso8601==1.1.0 # via cryptography (setup.cfg) From d1deb7cee88b6eadece6d078d3dec07cc8598c30 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 00:24:06 +0000 Subject: [PATCH 063/827] Bump BoringSSL and/or OpenSSL in CI (#8034) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88b70e3d579e..15f72a15bf71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 08, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "01d195bd03bfff54dc99c0df0858197c71d35417"}} - # Latest commit on the OpenSSL master branch, as of Jan 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "accd3bdd11bd4a69fdba42bbeead28945fe50e56"}} + # Latest commit on the BoringSSL master branch, as of Jan 10, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f8a10eeef9549601a91c4525f55bf8a59d338eff"}} + # Latest commit on the OpenSSL master branch, as of Jan 10, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4b65d79d7132d6e46bfb385a76082f6502ef617b"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From a5c096919c8e0852767dc0db991eb1f5c7f9b09d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:35:56 +0000 Subject: [PATCH 064/827] Bump ruff from 0.0.215 to 0.0.217 (#8036) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.215 to 0.0.217. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.215...v0.0.217) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e874a18f70bc..90449e969adb 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.1 # via twine -ruff==0.0.215 +ruff==0.0.217 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 1dcb208a3e5c7c1adf3a6506d7f438919efd8f04 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 00:20:35 +0000 Subject: [PATCH 065/827] Bump BoringSSL and/or OpenSSL in CI (#8037) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15f72a15bf71..1deb0f9ee083 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Jan 10, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f8a10eeef9549601a91c4525f55bf8a59d338eff"}} - # Latest commit on the OpenSSL master branch, as of Jan 10, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4b65d79d7132d6e46bfb385a76082f6502ef617b"}} + # Latest commit on the OpenSSL master branch, as of Jan 11, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "8d927e55b751ba1af6c08cd4e37d565a43c56157"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 587eb98e7eb3c3486beef76b0ba45c2ec96c9c15 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 11 Jan 2023 11:00:35 +0800 Subject: [PATCH 066/827] mismatched inner/outer signature algorithm x509 cert (#8038) --- docs/development/test-vectors.rst | 3 +++ .../mismatch_inner_outer_sig_algorithm.der | Bin 0 -> 1473 bytes 2 files changed, 3 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/mismatch_inner_outer_sig_algorithm.der diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 7290f5ae0843..1b39e7209216 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -478,6 +478,9 @@ Custom X.509 Vectors with ``asymmetric/PKCS8/rsa_pss_2048.pem`` as its key. * ``long-form-name-attribute.pem`` - A certificate with ``subject`` and ``issuer`` names containing attributes whose value's tag is encoded in long-form. +* ``mismatch_inner_outer_sig_algorithm.der`` - A leaf certificate derived from + ``x509/cryptography.io.pem`` but modifying the ``tbs_cert.signature_algorithm`` + OID to not match the outer signature algorithm OID. Custom X.509 Request Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vectors/cryptography_vectors/x509/custom/mismatch_inner_outer_sig_algorithm.der b/vectors/cryptography_vectors/x509/custom/mismatch_inner_outer_sig_algorithm.der new file mode 100644 index 0000000000000000000000000000000000000000..ff4e7fb557e59043edc751aedd92dc1fe5438a0f GIT binary patch literal 1473 zcmXqLV%=-d#Ike&GZP~d6O+Ay0WTY8LYoI;Dl-c+Co6-2yCJs$CmVAp3!5-gXt1G} zfe47hCCuxdnjcbBT3n*wnU}0*s9+!m5@!|`4@xY^ObHJ5Q3&>MG%__)aCTJCRd6>p zkQ3)MG%++VG&M9burxM`0&*=34Gql<3=K^UjH3)1ryB|z2!agZ7UpsfF|jZ=F|sr> zH8eEPhX`r}r=}{DmzV1mfov!)&e2QG&($wVEzU13N=_}-PcA4{&`8zrp2bys`MebaSu>n3&0 z>gq(U)5^*(OjQho-t->R4Nl9;HsyKlp|nQ+a)jh$o9irh_kBCO{G`}Ko9~CJBQCEm zPr0qP+QzT)+vi)?$^s@y7EcpaobqRJrv0RMe8OFQTH)DDtW!;{n0a!p)T!(6{XM}q zG>h}B*}0;P=LF{We2}wwu+ouBW#h{KF(t5+~osv17?ezP^ z+SBno;$i1%?&#X@XG|Ia5@=Ca$vo*tQ{SG?!1|KTOmrf4p-9n%b5lO|Et@;<{FjM$giX7^5#;vb{{7~ycrV!MUpwO!@^j)mTH*t6>M?cUiz%V$OP&3kavvB(U z@SEVKzQxJ=L}&czpX!>S)arL~ZTEu%;hw9GSXL=be(>;7)A7Z7b5zm|-gffOaGO~CZcmg#*`38(_!Wktc1y=g{>1BGwmAT0&pd@af23Nq;CWWdX37iLj zs*{UK4ER7c^D{F3XJKJxVqIV$3*xJ?fU+#q24+S$iwT^qWCd9?4Ah#iCHp3R^n9QV zGEbgG#X!kGVS(HN89a{3G2j6y76v(n$$-JY6~t3uu`{qSuwvr^l`m~STp8KT40H^% zU`}FU6q5t_t{CWljBK8hnx2@0oC~=@xsZ{O!C0|*Tff}H>l+>Y_vxzV+z!9owIc1e zL%h*_R$cp^n38&veX~ydQGeWh+UAwl@3#x|nN}R`U79RccjfG}hn^nm_XE%C?UB1{_-VNVr{STsIf<^H=g2Ev=t$(?5?}5cAn|F{ z^Dqsi$fIved?v4G$=DmDx|3tgZYF0nSKhydTfgq*Tl%iyF!y5drVSF2syt^;>aISe z^?LuM;~8uJy=Y5bduG$uoto!=7^^)uYW3g!^c>IWpUYje-YQ**=Hyi literal 0 HcmV?d00001 From c97b0e06e13a0eefcf0ab159389e3ccca072c052 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 12:38:02 +0000 Subject: [PATCH 067/827] Bump ruff from 0.0.217 to 0.0.218 (#8041) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.217 to 0.0.218. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.217...v0.0.218) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 90449e969adb..19e0136831ed 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.1 # via twine -ruff==0.0.217 +ruff==0.0.218 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 29425ef88bb1c7fdc581927d1ec576b9c12958c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 12:48:15 +0000 Subject: [PATCH 068/827] Bump coverage from 7.0.4 to 7.0.5 (#8042) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.4 to 7.0.5. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.4...7.0.5) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 19e0136831ed..2be8ef73cbf5 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -35,7 +35,7 @@ colorama==0.4.6; python_version >= "3.7" # via tox commonmark==0.9.1 # via rich -coverage==7.0.4; python_version >= "3.7" +coverage==7.0.5; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 1f82fc62490d5ab427f2d1bca974b6da223fc888 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:49:47 +0000 Subject: [PATCH 069/827] Bump pem from 1.1.0 to 1.1.1 in /src/rust (#8043) Bumps [pem](https://github.com/jcreekmore/pem-rs) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/jcreekmore/pem-rs/releases) - [Changelog](https://github.com/jcreekmore/pem-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/jcreekmore/pem-rs/compare/v1.1.0...v1.1.1) --- updated-dependencies: - dependency-name: pem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index d5ee7daec00b..393238101293 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -357,9 +357,9 @@ dependencies = [ [[package]] name = "pem" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" dependencies = [ "base64", ] From c400cd6cb2e5c71dbd0f18e9fad38b62a2b18f31 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 00:21:49 +0000 Subject: [PATCH 070/827] Bump BoringSSL and/or OpenSSL in CI (#8044) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1deb0f9ee083..fdc3717de69b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 10, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f8a10eeef9549601a91c4525f55bf8a59d338eff"}} - # Latest commit on the OpenSSL master branch, as of Jan 11, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "8d927e55b751ba1af6c08cd4e37d565a43c56157"}} + # Latest commit on the BoringSSL master branch, as of Jan 12, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "396625d50212143bc03517c9fdd21b1c965b3f45"}} + # Latest commit on the OpenSSL master branch, as of Jan 12, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c455f87aebf245814ba58d6a398b45ca4e80d1d7"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 796ebf67027063afb207a4e1eb7d2b92cd056178 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 11 Jan 2023 23:07:33 -0500 Subject: [PATCH 071/827] fixes #8035 -- added a test for loading a cert with another PEM block containing headers (#8045) --- docs/development/test-vectors.rst | 2 + tests/x509/test_x509.py | 7 ++ .../x509/cryptography.io.with_headers.pem | 64 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/cryptography.io.with_headers.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 1b39e7209216..93ab03232859 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -220,6 +220,8 @@ X.509 legacy PEM header format. * ``cryptography.io.chain.pem`` - The same as ``cryptography.io.pem``, but ``rapidssl_sha256_ca_g3.pem`` is concatenated to the end. +* ``cryptography.io.with_headers.pem`` - The same as ``cryptography.io.pem``, + but with an unrelated (encrypted) private key concatenated to the end. * ``cryptography.io.chain_with_garbage.pem`` - The same as ``cryptography.io.chain.pem``, but with other sections and text around it. * ``cryptography.io.with_garbage.pem`` - The same as ``cryptography.io.pem``, diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 59587294e5dd..cc11e3aa2166 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -764,6 +764,13 @@ def test_load_with_other_sections(self, backend): ) assert isinstance(cert, x509.Certificate) + cert = _load_cert( + os.path.join("x509", "cryptography.io.with_headers.pem"), + x509.load_pem_x509_certificate, + backend, + ) + assert isinstance(cert, x509.Certificate) + def test_load_multiple_sections(self, backend): # We match OpenSSL's behavior of loading the first cert # if there are multiple. Arguably this would ideally be an diff --git a/vectors/cryptography_vectors/x509/cryptography.io.with_headers.pem b/vectors/cryptography_vectors/x509/cryptography.io.with_headers.pem new file mode 100644 index 000000000000..46f2ecae6695 --- /dev/null +++ b/vectors/cryptography_vectors/x509/cryptography.io.with_headers.pem @@ -0,0 +1,64 @@ +-----BEGIN CERTIFICATE----- +MIIFvTCCBKWgAwIBAgICPyAwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlkU1NMIFNIQTI1 +NiBDQSAtIEczMB4XDTE0MTAxNTEyMDkzMloXDTE4MTExNjAxMTUwM1owgZcxEzAR +BgNVBAsTCkdUNDg3NDI5NjUxMTAvBgNVBAsTKFNlZSB3d3cucmFwaWRzc2wuY29t +L3Jlc291cmNlcy9jcHMgKGMpMTQxLzAtBgNVBAsTJkRvbWFpbiBDb250cm9sIFZh +bGlkYXRlZCAtIFJhcGlkU1NMKFIpMRwwGgYDVQQDExN3d3cuY3J5cHRvZ3JhcGh5 +LmlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAom/FebKJIot7Sp3s +itG1sicpe3thCssjI+g1JDAS7I3GLVNmbms1DOdIIqwf01gZkzzXBN2+9sOnyRaR +PPfCe1jTr3dk2y6rPE559vPa1nZQkhlzlhMhlPyjaT+S7g4Tio4qV2sCBZU01DZJ +CaksfohN+5BNVWoJzTbOcrHOEJ+M8B484KlBCiSxqf9cyNQKru4W3bHaCVNVJ8eu +6i6KyhzLa0L7yK3LXwwXVs583C0/vwFhccGWsFODqD/9xHUzsBIshE8HKjdjDi7Y +3BFQzVUQFjBB50NSZfAA/jcdt1blxJouc7z9T8Oklh+V5DDBowgAsrT4b6Z2Fq6/ +r7D1GqivLK/ypUQmxq2WXWAUBb/Q6xHgxASxI4Br+CByIUQJsm8L2jzc7k+mF4hW +ltAIUkbo8fGiVnat0505YJgxWEDKOLc4Gda6d/7GVd5AvKrz242bUqeaWo6e4MTx +diku2Ma3rhdcr044Qvfh9hGyjqNjvhWY/I+VRWgihU7JrYvgwFdJqsQ5eiKT4OHi +gsejvWwkZzDtiQ+aQTrzM1FsY2swJBJsLSX4ofohlVRlIJCn/ME+XErj553431Lu +YQ5SzMd3nXzN78Vj6qzTfMUUY72UoT1/AcFiUMobgIqrrmwuNxfrkbVE2b6Bga74 +FsJX63prvrJ41kuHK/16RQBM7fcCAwEAAaOCAWAwggFcMB8GA1UdIwQYMBaAFMOc +8/zTRgg0u85Gf6B8W/PiCMtZMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT +aHR0cDovL2d2LnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL2d2LnN5bWNi +LmNvbS9ndi5jcnQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB +BggrBgEFBQcDAjAvBgNVHREEKDAmghN3d3cuY3J5cHRvZ3JhcGh5Lmlvgg9jcnlw +dG9ncmFwaHkuaW8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2d2LnN5bWNiLmNv +bS9ndi5jcmwwDAYDVR0TAQH/BAIwADBFBgNVHSAEPjA8MDoGCmCGSAGG+EUBBzYw +LDAqBggrBgEFBQcCARYeaHR0cHM6Ly93d3cucmFwaWRzc2wuY29tL2xlZ2FsMA0G +CSqGSIb3DQEBCwUAA4IBAQAzIYO2jx7h17FBT74tJ2zbV9OKqGb7QF8y3wUtP4xc +dH80vprI/Cfji8s86kr77aAvAqjDjaVjHn7UzebhSUivvRPmfzRgyWBacomnXTSt +Xlt2dp2nDQuwGyK2vB7dMfKnQAkxwq1sYUXznB8i0IhhCAoXp01QGPKq51YoIlnF +7DRMk6iEaL1SJbkIrLsCQyZFDf0xtfW9DqXugMMLoxeCsBhZJQzNyS2ryirrv9LH +aK3+6IZjrcyy9bkpz/gzJucyhU+75c4My/mnRCrtItRbCQuiI5pd5poDowm+HH9i +GVI9+0lAFwxOUnOnwsoI40iOoxjLMGB+CgFLKCGUcWxP +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,975C518B7D2CCD1164A3354D1F89C5A6 + +xXOPSE88uXYkutY15A7kLycP5Tvryb0D2DQgRKiFXeZlVhqIW6n9FUn9/GK81xBx +EEmqzlc//6JDDWyBfYDzLb63BPuUBOIaiUjmHRteS0oQQWCY68cAoSl+Wc3801cB +UB7Yi0xNb6TN6jOx8HlWAHGq2Xm8Gs/k8y0RAEHBsaPGHISj6xNBaDS3PsHEIbBz +Adt6sbe01bQNZpfTiibV4IvZcf/O83TItGAotM83aZzN/N3Yq3OCboIJRUNLZ+aA +5n2StkLqtUqNITjRylc0rGYwWnvYdQtYt9+bKjefHwaQRJta4OTY8qkd8IabOamH +3DNyF4WnXnYWND1erzP3cYWt1rvBLFd2to9QGH54dWX1bsyrGb0iryesFk9iUB3A +JrgmrVcH3rajHN9BsqJ+uffkehe5ZRKTr9qJ7t2Pk3q3DEMmLm8vtkTSKA/q+vN1 +4eOJ8Nbiekp+zXYaJ6Wqt38VzWV3c19qePpBWaMsRWv4mTM+W0ZQtsAxXatNbGPs +Dq/Idc9xwwE/Ou4TDVTS0DlvqvGGB1MsX4uhzdyUF/6/b9/qHEEYjHePz4jX5Hcy +Jg4bpYIU9pszOVKRKjmCKyp6jPnuHISnhZJeG0jJOfKZQeaNoWEqDdy9ctIg1v6K +OnRVnPATCYtDrXpXe3YxT3n8g0+d9ZkyL5614Rj05P+Q7OukEnn/nQnMfUXk1gZ3 +7jSEJL47iOvxGWz4SvtSfHSCNYUFhm/fNSJMJ5TRApEPmZ71NrVTtgGAwWRPU3iM +JJRPZOXmrzt9rdlkTsH7V3Bn/lcdbIHPJ87Pv5dLFEota7we0WRRlAQJXp0NzG17 +Vn2IndftSeLUy7vGmNRAJEDSJe7OozN46n5RX04Q0ax5Z03p2m/mue2swk+Gqtf5 +2hYxgRZypuVIsgHyBOL9w0OV3Jvg246m0iCFRXJH7juaZ5c2MJ4mhTvAd4NdsS2v +46w6Kf5KDHCtgKnDTGtyx9Gzfhhi+wFlYREkMXN1QNpzW/USv0nPBjlVirGGzZBq +z6iJNIe5XEX+mP2EDu47PXoF5uwyhfIPHvM4qM/U8aRUgMwmtq8mR9LYsDrSkzXY +vxNxiXgl5eGG8rkOxQhSka9JIfkJVgA1tdk3ThTOXtm4B3vzRmbWbuYrwYtZ2Ls4 +XafQrVnoiMGX8/+Enn05M0bcTdZWm5vU2BZ/MhrwjAiMUMFV0FeHjk9j0fXDz9LM +GJyK6/4+P7owv3jbeCrQ3v4rvOwQony3LAOprlGSgSAcmq7g+HdoD8Jh+f4Z2Q26 +QLWAT9ikFVYSn2/B+m87Zr2eObZn1rExK40HlQrlyUMaklJ/IRxkWuap/h8N39W9 +8t7NIMdIy6QzCVkNhVx66QKyE7BJw8y4DZOCQ7YNqjPuc81lTt72eBDH3D12VVO9 +ZSOuQs4QV/zltAsWgJFQg7XtHVISELNELjMRm6N/543BkpSOUzInkctBTFBuwHGj ++5F+pR3qlNodEMFKCpm5aC9miDI854h66lv417mGkvZ7mz+Ktk8P7MoWecneVTkO +9WRU42KnNFSxK8C+cmFNxN1/97pWEQnXEV/32S/O5myly+kJPev2MsXtIFpqN1mE +-----END RSA PRIVATE KEY----- + From db7dd61de3c6f7c8d66d5615cbfbcf5c085c4448 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 12 Jan 2023 12:32:52 +0800 Subject: [PATCH 072/827] Add Certificate.verify_signed_by (#8011) * Add Certificate.verify_signed_by Verify that the signature on a certificate was created by the private key belonging to another certificate's public key. This code does not validate anything else! It is not a path builder, general x509 validator, etc. * switch to issued_by validate issuer subject matches certificate issuer and refactor * two fixes * signed_by isn't the right target now * coverage * skip test on some *ssls * extensive refactoring * lol * does any of this work * final commit i swear --- CHANGELOG.rst | 2 + docs/x509/reference.rst | 29 ++++ src/cryptography/x509/base.py | 8 + src/rust/src/x509/certificate.rs | 26 +++- src/rust/src/x509/sign.rs | 253 +++++++++++++++++++++++++++++++ tests/x509/test_x509.py | 235 +++++++++++++++++++++++++++- 6 files changed, 550 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1d252cd2d116..fbb9bb40498a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,8 @@ Changelog continues to support only public keys. * Added support for generating SSH certificates with :class:`~cryptography.hazmat.primitives.serialization.SSHCertificateBuilder`. +* Added :meth:`~cryptography.x509.Certificate.verify_directly_issued_by` to + :class:`~cryptography.x509.Certificate`. .. _v39-0-0: diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 839bce21d0bf..86a0e4e8ea22 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -486,6 +486,35 @@ X.509 Certificate Object An :class:`~cryptography.exceptions.InvalidSignature` exception will be raised if the signature fails to verify. + .. method:: verify_directly_issued_by(issuer) + + .. versionadded:: 40.0 + + :param issuer: The issuer certificate to check against. + :type issuer: :class:`~cryptography.x509.Certificate` + + .. warning:: + This method verifies that the certificate issuer name matches the + issuer subject name and that the certificate is signed by the + issuer's private key. **No other validation is performed.** + Callers are responsible for performing any additional + validations required for their use case (e.g. checking the validity + period, whether the signer is allowed to issue certificates, + that the issuing certificate has a strong public key, etc). + + Validates that the certificate is signed by the provided issuer and + that the issuer's subject name matches the issuer name of the + certificate. + + :return: None + :raise ValueError: If the issuer name on the certificate does + not match the subject name of the issuer or the signature + algorithm is unsupported. + :raise TypeError: If the issuer does not have a supported public + key type. + :raise cryptography.exceptions.InvalidSignature: If the + signature fails to verify. + .. attribute:: tbs_precertificate_bytes diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 6eae41cbe895..9b436fdf8887 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -265,6 +265,14 @@ def public_bytes(self, encoding: serialization.Encoding) -> bytes: Serializes the certificate to PEM or DER format. """ + @abc.abstractmethod + def verify_directly_issued_by(self, issuer: "Certificate") -> None: + """ + This method verifies that certificate issuer name matches the + issuer subject name and that the certificate is signed by the + issuer's private key. No other validation is performed. + """ + # Runtime isinstance checks need this since the rust class is not a subclass. Certificate.register(rust_x509.Certificate) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 92e522f45ffe..65c37d334d69 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -7,7 +7,7 @@ use crate::asn1::{ PyAsn1Error, PyAsn1Result, }; use crate::x509; -use crate::x509::{crl, extensions, oid, sct, Asn1ReadableOrWritable}; +use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; use chrono::Datelike; use pyo3::ToPyObject; use std::collections::hash_map::DefaultHasher; @@ -319,6 +319,30 @@ impl Certificate { }, ) } + + fn verify_directly_issued_by<'p>( + &self, + py: pyo3::Python<'p>, + issuer: pyo3::PyRef<'_, Certificate>, + ) -> PyAsn1Result<()> { + if self.raw.borrow_value().tbs_cert.signature_alg != self.raw.borrow_value().signature_alg { + return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + "Inner and outer signature algorithms do not match. This is an invalid certificate." + ))); + }; + if self.raw.borrow_value().tbs_cert.issuer != issuer.raw.borrow_value().tbs_cert.subject { + return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + "Issuer certificate subject does not match certificate issuer.", + ))); + }; + sign::verify_signature_with_oid( + py, + issuer.public_key(py)?, + &self.raw.borrow_value().signature_alg.oid, + self.raw.borrow_value().signature.as_bytes(), + &asn1::write_single(&self.raw.borrow_value().tbs_cert)?, + ) + } } fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, PyAsn1Error> { diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 37860c3a5c7c..bc5f07994b4c 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -2,6 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::asn1::{PyAsn1Error, PyAsn1Result}; use crate::x509; use crate::x509::oid; @@ -14,6 +15,7 @@ static NULL_DER: Lazy> = Lazy::new(|| { pub(crate) static NULL_TLV: Lazy> = Lazy::new(|| asn1::parse_single(&NULL_DER).unwrap()); +#[derive(Debug, PartialEq)] enum KeyType { Rsa, Dsa, @@ -22,6 +24,7 @@ enum KeyType { Ed448, } +#[derive(Debug, PartialEq)] enum HashType { None, Sha224, @@ -256,3 +259,253 @@ pub(crate) fn sign_data<'p>( }; signature.extract() } + +fn py_hash_name_from_hash_type(hash_type: HashType) -> Option<&'static str> { + match hash_type { + HashType::None => None, + HashType::Sha224 => Some("SHA224"), + HashType::Sha256 => Some("SHA256"), + HashType::Sha384 => Some("SHA384"), + HashType::Sha512 => Some("SHA512"), + HashType::Sha3_224 => Some("SHA3_224"), + HashType::Sha3_256 => Some("SHA3_256"), + HashType::Sha3_384 => Some("SHA3_384"), + HashType::Sha3_512 => Some("SHA3_512"), + } +} + +pub(crate) fn verify_signature_with_oid<'p>( + py: pyo3::Python<'p>, + issuer_public_key: &'p pyo3::PyAny, + signature_oid: &asn1::ObjectIdentifier, + signature: &[u8], + data: &[u8], +) -> PyAsn1Result<()> { + let key_type = identify_public_key_type(py, issuer_public_key)?; + let (sig_key_type, sig_hash_type) = identify_key_hash_type_for_oid(signature_oid)?; + if key_type != sig_key_type { + return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + "Signature algorithm does not match issuer key type", + ))); + } + let sig_hash_name = py_hash_name_from_hash_type(sig_hash_type); + let hashes = py.import("cryptography.hazmat.primitives.hashes")?; + let signature_hash = match sig_hash_name { + Some(data) => hashes.getattr(data)?.call0()?, + None => py.None().into_ref(py), + }; + + match key_type { + KeyType::Ed25519 | KeyType::Ed448 => { + issuer_public_key.call_method1("verify", (signature, data))? + } + KeyType::Ec => { + let ec_mod = py.import("cryptography.hazmat.primitives.asymmetric.ec")?; + let ecdsa = ec_mod + .getattr(crate::intern!(py, "ECDSA"))? + .call1((signature_hash,))?; + issuer_public_key.call_method1("verify", (signature, data, ecdsa))? + } + KeyType::Rsa => { + let padding_mod = py.import("cryptography.hazmat.primitives.asymmetric.padding")?; + let pkcs1v15 = padding_mod + .getattr(crate::intern!(py, "PKCS1v15"))? + .call0()?; + issuer_public_key.call_method1("verify", (signature, data, pkcs1v15, signature_hash))? + } + KeyType::Dsa => { + issuer_public_key.call_method1("verify", (signature, data, signature_hash))? + } + }; + Ok(()) +} + +fn identify_public_key_type( + py: pyo3::Python<'_>, + public_key: &pyo3::PyAny, +) -> pyo3::PyResult { + let rsa_key_type: &pyo3::types::PyType = py + .import("cryptography.hazmat.primitives.asymmetric.rsa")? + .getattr(crate::intern!(py, "RSAPublicKey"))? + .extract()?; + let dsa_key_type: &pyo3::types::PyType = py + .import("cryptography.hazmat.primitives.asymmetric.dsa")? + .getattr(crate::intern!(py, "DSAPublicKey"))? + .extract()?; + let ec_key_type: &pyo3::types::PyType = py + .import("cryptography.hazmat.primitives.asymmetric.ec")? + .getattr(crate::intern!(py, "EllipticCurvePublicKey"))? + .extract()?; + let ed25519_key_type: &pyo3::types::PyType = py + .import("cryptography.hazmat.primitives.asymmetric.ed25519")? + .getattr(crate::intern!(py, "Ed25519PublicKey"))? + .extract()?; + let ed448_key_type: &pyo3::types::PyType = py + .import("cryptography.hazmat.primitives.asymmetric.ed448")? + .getattr(crate::intern!(py, "Ed448PublicKey"))? + .extract()?; + + if rsa_key_type.is_instance(public_key)? { + Ok(KeyType::Rsa) + } else if dsa_key_type.is_instance(public_key)? { + Ok(KeyType::Dsa) + } else if ec_key_type.is_instance(public_key)? { + Ok(KeyType::Ec) + } else if ed25519_key_type.is_instance(public_key)? { + Ok(KeyType::Ed25519) + } else if ed448_key_type.is_instance(public_key)? { + Ok(KeyType::Ed448) + } else { + Err(pyo3::exceptions::PyTypeError::new_err( + "Key must be an rsa, dsa, ec, ed25519, or ed448 public key.", + )) + } +} + +fn identify_key_hash_type_for_oid( + oid: &asn1::ObjectIdentifier, +) -> pyo3::PyResult<(KeyType, HashType)> { + match *oid { + oid::RSA_WITH_SHA224_OID => Ok((KeyType::Rsa, HashType::Sha224)), + oid::RSA_WITH_SHA256_OID => Ok((KeyType::Rsa, HashType::Sha256)), + oid::RSA_WITH_SHA384_OID => Ok((KeyType::Rsa, HashType::Sha384)), + oid::RSA_WITH_SHA512_OID => Ok((KeyType::Rsa, HashType::Sha512)), + oid::RSA_WITH_SHA3_224_OID => Ok((KeyType::Rsa, HashType::Sha3_224)), + oid::RSA_WITH_SHA3_256_OID => Ok((KeyType::Rsa, HashType::Sha3_256)), + oid::RSA_WITH_SHA3_384_OID => Ok((KeyType::Rsa, HashType::Sha3_384)), + oid::RSA_WITH_SHA3_512_OID => Ok((KeyType::Rsa, HashType::Sha3_512)), + oid::ECDSA_WITH_SHA224_OID => Ok((KeyType::Ec, HashType::Sha224)), + oid::ECDSA_WITH_SHA256_OID => Ok((KeyType::Ec, HashType::Sha256)), + oid::ECDSA_WITH_SHA384_OID => Ok((KeyType::Ec, HashType::Sha384)), + oid::ECDSA_WITH_SHA512_OID => Ok((KeyType::Ec, HashType::Sha512)), + oid::ECDSA_WITH_SHA3_224_OID => Ok((KeyType::Ec, HashType::Sha3_224)), + oid::ECDSA_WITH_SHA3_256_OID => Ok((KeyType::Ec, HashType::Sha3_256)), + oid::ECDSA_WITH_SHA3_384_OID => Ok((KeyType::Ec, HashType::Sha3_384)), + oid::ECDSA_WITH_SHA3_512_OID => Ok((KeyType::Ec, HashType::Sha3_512)), + oid::ED25519_OID => Ok((KeyType::Ed25519, HashType::None)), + oid::ED448_OID => Ok((KeyType::Ed448, HashType::None)), + oid::DSA_WITH_SHA224_OID => Ok((KeyType::Dsa, HashType::Sha224)), + oid::DSA_WITH_SHA256_OID => Ok((KeyType::Dsa, HashType::Sha256)), + oid::DSA_WITH_SHA384_OID => Ok((KeyType::Dsa, HashType::Sha384)), + oid::DSA_WITH_SHA512_OID => Ok((KeyType::Dsa, HashType::Sha512)), + _ => Err(pyo3::exceptions::PyValueError::new_err( + "Unsupported signature algorithm", + )), + } +} + +#[cfg(test)] +mod tests { + use super::{identify_key_hash_type_for_oid, py_hash_name_from_hash_type, HashType, KeyType}; + use crate::x509::oid; + + #[test] + fn test_identify_key_hash_type_for_oid() { + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA224_OID).unwrap(), + (KeyType::Rsa, HashType::Sha224) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA256_OID).unwrap(), + (KeyType::Rsa, HashType::Sha256) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA384_OID).unwrap(), + (KeyType::Rsa, HashType::Sha384) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA512_OID).unwrap(), + (KeyType::Rsa, HashType::Sha512) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_224_OID).unwrap(), + (KeyType::Rsa, HashType::Sha3_224) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_256_OID).unwrap(), + (KeyType::Rsa, HashType::Sha3_256) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_384_OID).unwrap(), + (KeyType::Rsa, HashType::Sha3_384) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_512_OID).unwrap(), + (KeyType::Rsa, HashType::Sha3_512) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA224_OID).unwrap(), + (KeyType::Ec, HashType::Sha224) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA256_OID).unwrap(), + (KeyType::Ec, HashType::Sha256) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA384_OID).unwrap(), + (KeyType::Ec, HashType::Sha384) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA512_OID).unwrap(), + (KeyType::Ec, HashType::Sha512) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_224_OID).unwrap(), + (KeyType::Ec, HashType::Sha3_224) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_256_OID).unwrap(), + (KeyType::Ec, HashType::Sha3_256) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_384_OID).unwrap(), + (KeyType::Ec, HashType::Sha3_384) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_512_OID).unwrap(), + (KeyType::Ec, HashType::Sha3_512) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ED25519_OID).unwrap(), + (KeyType::Ed25519, HashType::None) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::ED448_OID).unwrap(), + (KeyType::Ed448, HashType::None) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA224_OID).unwrap(), + (KeyType::Dsa, HashType::Sha224) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA256_OID).unwrap(), + (KeyType::Dsa, HashType::Sha256) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA384_OID).unwrap(), + (KeyType::Dsa, HashType::Sha384) + ); + assert_eq!( + identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA512_OID).unwrap(), + (KeyType::Dsa, HashType::Sha512) + ); + assert!(identify_key_hash_type_for_oid(&oid::TLS_FEATURE_OID).is_err()); + } + + #[test] + fn test_py_hash_name_from_hash_type() { + for (hash, name) in [ + (HashType::Sha224, "SHA224"), + (HashType::Sha256, "SHA256"), + (HashType::Sha384, "SHA384"), + (HashType::Sha512, "SHA512"), + (HashType::Sha3_224, "SHA3_224"), + (HashType::Sha3_256, "SHA3_256"), + (HashType::Sha3_384, "SHA3_384"), + (HashType::Sha3_512, "SHA3_512"), + ] { + let hash_str = py_hash_name_from_hash_type(hash).unwrap(); + assert_eq!(hash_str, name); + } + } +} diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index cc11e3aa2166..b0584c3bf916 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -15,6 +15,7 @@ import pytz from cryptography import utils, x509 +from cryptography.exceptions import InvalidSignature from cryptography.hazmat.bindings._rust import asn1 from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ( @@ -25,6 +26,7 @@ ed25519, padding, rsa, + types, x448, x25519, ) @@ -41,9 +43,13 @@ SubjectInformationAccessOID, ) -from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048 +from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048, DSA_KEY_3072 from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1 -from ..hazmat.primitives.fixtures_rsa import RSA_KEY_512, RSA_KEY_2048 +from ..hazmat.primitives.fixtures_rsa import ( + RSA_KEY_512, + RSA_KEY_2048, + RSA_KEY_2048_ALT, +) from ..hazmat.primitives.test_ec import _skip_curve_unsupported from ..utils import ( load_nist_vectors, @@ -77,6 +83,57 @@ def _load_cert(filename, loader: typing.Callable[..., T], backend=None) -> T: return cert +def _generate_ca_and_leaf( + issuer_private_key: types.CERTIFICATE_PRIVATE_KEY_TYPES, + subject_private_key: types.CERTIFICATE_PRIVATE_KEY_TYPES, +): + if isinstance( + issuer_private_key, + (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey), + ): + hash_alg = None + else: + hash_alg = hashes.SHA256() + + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(issuer_private_key.public_key()) + .serial_number(1) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2030, 1, 1)) + ) + ca = builder.sign(issuer_private_key, hash_alg) + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "leaf")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(subject_private_key.public_key()) + .serial_number(100) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2025, 1, 1)) + ) + cert = builder.sign(issuer_private_key, hash_alg) + return ca, cert + + +def _break_cert_sig(cert: x509.Certificate) -> x509.Certificate: + cert_bad_sig = bytearray(cert.public_bytes(serialization.Encoding.PEM)) + # Break the sig by mutating 5 bytes. This has a 2**-40 chance of + # not breaking the sig. Spin that roulette wheel. + cert_bad_sig[-40:-35] = 90, 90, 90, 90, 90 + return x509.load_pem_x509_certificate(bytes(cert_bad_sig)) + + class TestCertificateRevocationList: def test_load_pem_crl(self, backend): crl = _load_cert( @@ -1473,6 +1530,108 @@ def test_parse_tls_feature_extension(self, backend): [x509.TLSFeatureType.status_request] ) + def test_verify_directly_issued_by_rsa(self): + issuer_private_key = RSA_KEY_2048.private_key() + subject_private_key = RSA_KEY_2048_ALT.private_key() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_rsa_bad_sig(self): + issuer_private_key = RSA_KEY_2048.private_key() + subject_private_key = RSA_KEY_2048_ALT.private_key() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert_bad_sig = _break_cert_sig(cert) + with pytest.raises(InvalidSignature): + cert_bad_sig.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_rsa_mismatched_inner_out_oid(self): + cert = _load_cert( + os.path.join( + "x509", "custom", "mismatch_inner_outer_sig_algorithm.der" + ), + x509.load_der_x509_certificate, + ) + with pytest.raises(ValueError) as exc: + cert.verify_directly_issued_by(cert) + + assert str(exc.value) == ( + "Inner and outer signature algorithms do not match. This is an " + "invalid certificate." + ) + + def test_verify_directly_issued_by_subject_issuer_mismatch(self): + cert = _load_cert( + os.path.join("x509", "cryptography.io.pem"), + x509.load_pem_x509_certificate, + ) + with pytest.raises(ValueError) as exc: + cert.verify_directly_issued_by(cert) + + assert str(exc.value) == ( + "Issuer certificate subject does not match certificate issuer." + ) + + def test_verify_directly_issued_by_algorithm_mismatch(self): + issuer_private_key = RSA_KEY_2048.private_key() + subject_private_key = RSA_KEY_2048_ALT.private_key() + _, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + # We need a CA with the same issuer DN but diff signature algorithm + secondary_issuer_key = ec.generate_private_key(ec.SECP256R1()) + ca2, _ = _generate_ca_and_leaf( + secondary_issuer_key, subject_private_key + ) + with pytest.raises(ValueError): + cert.verify_directly_issued_by(ca2) + + @pytest.mark.supported( + only_if=lambda backend: ( + backend.ed25519_supported() and backend.x25519_supported() + ), + skip_message="Requires OpenSSL with Ed25519 and X25519 support", + ) + def test_verify_directly_issued_by_unsupported_key_type(self, backend): + private_key = ed25519.Ed25519PrivateKey.generate() + x25519_public = x25519.X25519PrivateKey.generate().public_key() + # Generate an ed25519 CA + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(private_key.public_key()) + .serial_number(1) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2030, 1, 1)) + ) + cert = builder.sign(private_key, None) + # Make a cert with the right issuer name but the wrong public key + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(x25519_public) + .serial_number(1) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2030, 1, 1)) + ) + leaf = builder.sign(private_key, None) + + with pytest.raises(TypeError): + cert.verify_directly_issued_by(leaf) + class TestRSACertificateRequest: @pytest.mark.parametrize( @@ -4562,6 +4721,24 @@ def test_tbs_certificate_bytes(self, backend): cert.signature_hash_algorithm, ) + def test_verify_directly_issued_by_dsa(self): + issuer_private_key = DSA_KEY_3072.private_key() + subject_private_key = DSA_KEY_2048.private_key() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_dsa_bad_sig(self): + issuer_private_key = DSA_KEY_3072.private_key() + subject_private_key = DSA_KEY_2048.private_key() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert_bad_sig = _break_cert_sig(cert) + with pytest.raises(InvalidSignature): + cert_bad_sig.verify_directly_issued_by(ca) + @pytest.mark.supported( only_if=lambda backend: backend.dsa_supported(), @@ -4788,6 +4965,24 @@ def test_load_ecdsa_no_named_curve(self, backend): with pytest.raises(ValueError, match="explicit parameters"): cert.public_key() + def test_verify_directly_issued_by_ec(self): + issuer_private_key = ec.generate_private_key(ec.SECP256R1()) + subject_private_key = ec.generate_private_key(ec.SECP256R1()) + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_ec_bad_sig(self): + issuer_private_key = ec.generate_private_key(ec.SECP256R1()) + subject_private_key = ec.generate_private_key(ec.SECP256R1()) + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert_bad_sig = _break_cert_sig(cert) + with pytest.raises(InvalidSignature): + cert_bad_sig.verify_directly_issued_by(ca) + class TestECDSACertificateRequest: @pytest.mark.parametrize( @@ -5411,6 +5606,24 @@ def test_deepcopy(self, backend): ) assert copy.deepcopy(cert) is cert + def test_verify_directly_issued_by_ed25519(self, backend): + issuer_private_key = ed25519.Ed25519PrivateKey.generate() + subject_private_key = ed25519.Ed25519PrivateKey.generate() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_ed25519_bad_sig(self, backend): + issuer_private_key = ed25519.Ed25519PrivateKey.generate() + subject_private_key = ed25519.Ed25519PrivateKey.generate() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert_bad_sig = _break_cert_sig(cert) + with pytest.raises(InvalidSignature): + cert_bad_sig.verify_directly_issued_by(ca) + @pytest.mark.supported( only_if=lambda backend: backend.ed448_supported(), @@ -5432,6 +5645,24 @@ def test_load_pem_cert(self, backend): assert cert.signature_hash_algorithm is None assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED448 + def test_verify_directly_issued_by_ed448(self, backend): + issuer_private_key = ed448.Ed448PrivateKey.generate() + subject_private_key = ed448.Ed448PrivateKey.generate() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert.verify_directly_issued_by(ca) + + def test_verify_directly_issued_by_ed448_bad_sig(self, backend): + issuer_private_key = ed448.Ed448PrivateKey.generate() + subject_private_key = ed448.Ed448PrivateKey.generate() + ca, cert = _generate_ca_and_leaf( + issuer_private_key, subject_private_key + ) + cert_bad_sig = _break_cert_sig(cert) + with pytest.raises(InvalidSignature): + cert_bad_sig.verify_directly_issued_by(ca) + @pytest.mark.supported( only_if=lambda backend: backend.dh_supported(), From c2824f5797f858f4e95cbd729f057d6f1fdc272b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 12 Jan 2023 12:57:04 +0800 Subject: [PATCH 073/827] fix a math mistake in a comment (#8046) the shame of it all --- tests/x509/test_x509.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index b0584c3bf916..d641335210e7 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -128,7 +128,8 @@ def _generate_ca_and_leaf( def _break_cert_sig(cert: x509.Certificate) -> x509.Certificate: cert_bad_sig = bytearray(cert.public_bytes(serialization.Encoding.PEM)) - # Break the sig by mutating 5 bytes. This has a 2**-40 chance of + # Break the sig by mutating 5 bytes. That's the base64 representation + # though so there's somewhere closer to 2**-32 probability of # not breaking the sig. Spin that roulette wheel. cert_bad_sig[-40:-35] = 90, 90, 90, 90, 90 return x509.load_pem_x509_certificate(bytes(cert_bad_sig)) From 4c954e00eb5141d82549c6b8cb02408bc964b169 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:34:01 +0000 Subject: [PATCH 074/827] Bump actions/setup-python from 4.4.0 to 4.5.0 (#8047) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4.4.0...v4.5.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 16 ++++++++-------- .github/workflows/wheel-builder.yml | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index ecfa7e5cdfe4..ea25e2b70d16 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -28,7 +28,7 @@ jobs: - name: Setup python id: setup-python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: "3.11" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fdc3717de69b..0e74619f4df3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: persist-credentials: false - name: Setup python id: setup-python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - uses: actions/cache@v3.2.3 @@ -223,7 +223,7 @@ jobs: key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f @@ -275,7 +275,7 @@ jobs: key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ matrix.RUST }}-coverage - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f @@ -360,7 +360,7 @@ jobs: key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} @@ -412,7 +412,7 @@ jobs: persist-credentials: false - name: Setup python id: setup-python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} @@ -492,7 +492,7 @@ jobs: key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON }} - run: ./.github/downstream.d/${{ matrix.DOWNSTREAM }}.sh install @@ -528,7 +528,7 @@ jobs: with: persist-credentials: false - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: 3.11 - run: python -m pip install -c ci-constraints-requirements.txt tox @@ -552,7 +552,7 @@ jobs: jobs: ${{ toJSON(needs) }} - name: Setup python if: ${{ always() }} - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: '3.10' - run: pip install -c ci-constraints-requirements.txt coverage[toml] diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 37e92995f910..0bcc174b6e60 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -168,7 +168,7 @@ jobs: PYTHON_DOWNLOAD_URL: ${{ matrix.PYTHON.DOWNLOAD_URL }} if: contains(matrix.PYTHON.VERSION, 'pypy') == false - name: Setup pypy - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') @@ -246,7 +246,7 @@ jobs: name: cryptography-sdist - name: Setup python - uses: actions/setup-python@v4.4.0 + uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} From 291a484874225ee80c485334fea4f1ce83cdd9a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:34:15 +0000 Subject: [PATCH 075/827] Bump urllib3 from 1.26.13 to 1.26.14 (#8049) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.13 to 1.26.14. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/1.26.14/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.13...1.26.14) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2be8ef73cbf5..1e05e4ed2942 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -211,7 +211,7 @@ types-urllib3==1.26.25.4 # via types-requests typing-extensions==4.4.0; python_version >= "3.7" # via mypy -urllib3==1.26.13 +urllib3==1.26.14 # via # requests # twine From dd29a3ddbe45a734ecd43c3a3b235a7e58bf3c65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:44:57 +0000 Subject: [PATCH 076/827] Bump build from 0.9.0 to 0.10.0 (#8050) Bumps [build](https://github.com/pypa/build) from 0.9.0 to 0.10.0. - [Release notes](https://github.com/pypa/build/releases) - [Changelog](https://github.com/pypa/build/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/build/compare/0.9.0...0.10.0) --- updated-dependencies: - dependency-name: build dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1e05e4ed2942..365bab297d03 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -17,7 +17,7 @@ black==22.12.0 # via cryptography (setup.cfg) bleach==5.0.1 # via readme-renderer -build==0.9.0 +build==0.10.0 # via check-manifest cachetools==5.2.1 # via tox From 306d99a107abee61812f82cb2ebea75ded2b8409 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:57:20 +0000 Subject: [PATCH 077/827] Bump ruff from 0.0.218 to 0.0.219 (#8048) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.218 to 0.0.219. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.218...v0.0.219) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 365bab297d03..77c6721fa8a9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.1 # via twine -ruff==0.0.218 +ruff==0.0.219 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 2e61ae75741a80b496584e7d94ed5f962480abe2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 13:05:54 +0000 Subject: [PATCH 078/827] Bump tox from 4.2.6 to 4.2.8 (#8051) Bumps [tox](https://github.com/tox-dev/tox) from 4.2.6 to 4.2.8. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.2.6...4.2.8) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 77c6721fa8a9..d9027a3f2b8e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-api # pytest # tox -tox==4.2.6; python_version >= "3.7" +tox==4.2.8; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 296863e96fcf473dbd1f70e89d05dd032ca78252 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 00:59:46 +0000 Subject: [PATCH 079/827] Bump BoringSSL and/or OpenSSL in CI (#8053) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e74619f4df3..cfd4ef134e35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 12, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "396625d50212143bc03517c9fdd21b1c965b3f45"}} - # Latest commit on the OpenSSL master branch, as of Jan 12, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c455f87aebf245814ba58d6a398b45ca4e80d1d7"}} + # Latest commit on the BoringSSL master branch, as of Jan 13, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a230a8205e8f87893182a39756948526beb1d579"}} + # Latest commit on the OpenSSL master branch, as of Jan 13, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9fa553247874728cee8ca0ece9aaed476eb0f303"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From b194dc14128a47441ecb3f698df6c19e4bc360c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 12:33:55 +0000 Subject: [PATCH 080/827] Bump alabaster from 0.7.12 to 0.7.13 (#8055) Bumps [alabaster](https://github.com/bitprophet/alabaster) from 0.7.12 to 0.7.13. - [Release notes](https://github.com/bitprophet/alabaster/releases) - [Changelog](https://github.com/bitprophet/alabaster/blob/main/docs/changelog.rst) - [Commits](https://github.com/bitprophet/alabaster/compare/0.7.12...0.7.13) --- updated-dependencies: - dependency-name: alabaster dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d9027a3f2b8e..e172f9f24d29 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -5,7 +5,7 @@ # and then manually massaged to remove non-dev dependencies and add version # specifiers to packages whose versions vary by Python version -alabaster==0.7.12 +alabaster==0.7.13 # via sphinx attrs==22.2.0 # via From 8bd94756cfb2e1fdd1a5b77e5cd4c2087eeba443 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 12:38:45 +0000 Subject: [PATCH 081/827] Bump ruff from 0.0.219 to 0.0.220 (#8056) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.219 to 0.0.220. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.219...v0.0.220) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e172f9f24d29..30ae93a94000 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.1 # via twine -ruff==0.0.219 +ruff==0.0.220 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 510a1f1cdecdf53bf42ca5d2b4855b597e13e769 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 12:43:41 +0000 Subject: [PATCH 082/827] Bump requests from 2.28.1 to 2.28.2 (#8057) Bumps [requests](https://github.com/psf/requests) from 2.28.1 to 2.28.2. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.28.1...v2.28.2) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 30ae93a94000..a60f29f9c3f6 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -148,7 +148,7 @@ pytz==2022.7 # cryptography (setup.cfg) readme-renderer==37.3 # via twine -requests==2.28.1; python_version >= "3.7" +requests==2.28.2; python_version >= "3.7" # via # requests-toolbelt # sphinx From 0fd8d8406089758ab61646b3ab71ce18463c6909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 13:03:11 +0000 Subject: [PATCH 083/827] Bump charset-normalizer from 2.1.1 to 3.0.1 (#7963) Bumps [charset-normalizer](https://github.com/Ousret/charset_normalizer) from 2.1.1 to 3.0.1. - [Release notes](https://github.com/Ousret/charset_normalizer/releases) - [Changelog](https://github.com/Ousret/charset_normalizer/blob/master/CHANGELOG.md) - [Upgrade guide](https://github.com/Ousret/charset_normalizer/blob/master/UPGRADE.md) - [Commits](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.1) --- updated-dependencies: - dependency-name: charset-normalizer dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a60f29f9c3f6..9894b077830d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -25,7 +25,7 @@ certifi==2022.12.7 # via requests chardet==5.1.0 # via tox -charset-normalizer==2.1.1; python_version >= "3.7" +charset-normalizer==3.0.1; python_version >= "3.7" # via requests check-manifest==0.49 # via cryptography (setup.cfg) From 171bce1d3b026f1f01e0663385ff0f4cebff1790 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Jan 2023 15:31:00 -0500 Subject: [PATCH 084/827] serial_number is not a function (#8061) --- docs/x509/reference.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 86a0e4e8ea22..abbc803bf583 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -3003,7 +3003,7 @@ instances. The following common OIDs are available as constants. Corresponds to the dotted string ``"2.5.4.5"``. This is distinct from the serial number of the certificate itself (which can be obtained with - :func:`~cryptography.x509.Certificate.serial_number`). + :attr:`~cryptography.x509.Certificate.serial_number`). .. attribute:: SURNAME From cef402f92150ba8905f5ebca237518057058b042 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Jan 2023 15:31:49 -0500 Subject: [PATCH 085/827] fixes #8052 -- correct NameAttribute.value documentation (#8060) --- docs/x509/reference.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index abbc803bf583..03bd86b9e221 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -1417,9 +1417,11 @@ X.509 CSR (Certificate Signing Request) Builder Object .. attribute:: value - :type: str + :type: ``str`` or ``bytes`` - The value of the attribute. + The value of the attribute. This will generally be a ``str``, the only + times it can be a ``bytes`` is when :attr:`oid` is + ``X500_UNIQUE_IDENTIFIER``. .. attribute:: rfc4514_attribute_name From 1125a9e359e3f0c303dc51655edc7ed92ce52fe5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Jan 2023 15:34:31 -0500 Subject: [PATCH 086/827] Re-compile ci-constraints-requirements.txt (#8059) dependabot doesn't automatically pin new transitive deps --- ci-constraints-requirements.txt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9894b077830d..07f6bc4fb3c6 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -1,9 +1,9 @@ # 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=tox --resolver=backtracking --strip-extras setup.cfg -# and then manually massaged to remove non-dev dependencies and add version -# specifiers to packages whose versions vary by Python version +# pip-compile --extra=docs --extra=docstest --extra=pep8test --extra=test --extra=test-randomorder --extra=tox --resolver=backtracking --strip-extras --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools setup.cfg +# and then manually massaged to add version specifiers to packages whose +# versions vary by Python version alabaster==0.7.13 # via sphinx @@ -93,8 +93,6 @@ packaging==23.0; python_version >= "3.7" # tox pathspec==0.10.3 # via black -pep517==0.13.0 - # via build pkginfo==1.9.6 # via twine platformdirs==2.6.2; python_version >= "3.7" @@ -121,6 +119,8 @@ pygments==2.14.0 # sphinx pyproject-api==1.4.0 # via tox +pyproject-hooks==1.0.0 + # via build pytest==7.2.0; python_version >= "3.7" # via # cryptography (setup.cfg) @@ -195,8 +195,8 @@ tomli==2.0.1; python_version >= "3.7" # check-manifest # coverage # mypy - # pep517 # pyproject-api + # pyproject-hooks # pytest # tox tox==4.2.8; python_version >= "3.7" @@ -221,3 +221,8 @@ webencodings==0.5.1 # via bleach zipp==3.11.0; python_version >= "3.7" # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# cffi +# pycparser +# setuptools From 20ed0eb848e497f7cabf18d755b40f61c0bef871 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 14 Jan 2023 00:19:28 +0000 Subject: [PATCH 087/827] Bump BoringSSL and/or OpenSSL in CI (#8063) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfd4ef134e35..3e534b710cd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 13, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a230a8205e8f87893182a39756948526beb1d579"}} - # Latest commit on the OpenSSL master branch, as of Jan 13, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9fa553247874728cee8ca0ece9aaed476eb0f303"}} + # Latest commit on the BoringSSL master branch, as of Jan 14, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3251ca1f63ff8c9ea760c0046309e93596f6c12b"}} + # Latest commit on the OpenSSL master branch, as of Jan 14, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "b639475a9433c827675b8154ea9e0ce361403c76"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From a5f3fe175ac04b172a0491bf854bfbc67b080549 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 14 Jan 2023 11:57:14 +0800 Subject: [PATCH 088/827] we now have ephemeral GHA M1 runners (#8064) --- .github/workflows/macarm64.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/macarm64.yml b/.github/workflows/macarm64.yml index 2acd099c3ea4..2de198ac6628 100644 --- a/.github/workflows/macarm64.yml +++ b/.github/workflows/macarm64.yml @@ -1,5 +1,6 @@ name: macOS arm64 CI on: + pull_request: {} push: branches: - main @@ -18,17 +19,15 @@ concurrency: jobs: macos-arm64: if: github.repository_owner == 'pyca' - runs-on: [self-hosted, macos, ARM64] + runs-on: [self-hosted, macos, ARM64, tart] name: "macOS arm64" strategy: fail-fast: false matrix: PYTHON: - - {TOXENV: "py310", BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.10/bin/python3'} + - {TOXENV: "py311", BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3'} timeout-minutes: 10 steps: - - name: "Delete workspace" # self-hosted runners need this, sigh - run: gfind ! -name '.' ! -name '..' -delete - uses: actions/checkout@v3.3.0 with: persist-credentials: false From cc4ee2b77a8a60f8536055ef7829618ad284293d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 14 Jan 2023 21:20:21 +0800 Subject: [PATCH 089/827] merge our macOS arm64 CI into our primary ci.yml (#8066) --- .github/workflows/ci.yml | 14 ++++++-- .github/workflows/macarm64.yml | 64 ---------------------------------- 2 files changed, 11 insertions(+), 67 deletions(-) delete mode 100644 .github/workflows/macarm64.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e534b710cd6..f33d95ec50f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -332,14 +332,21 @@ jobs: - uses: ./.github/actions/upload-coverage macos: - runs-on: macos-12 + runs-on: ${{ matrix.RUNNER.OS }} strategy: fail-fast: false matrix: + RUNNER: + - {OS: 'macos-12', ARCH: 'x86_64'} + - {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} PYTHON: - {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""} - {VERSION: "3.11", TOXENV: "py311", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"} - name: "${{ matrix.PYTHON.TOXENV }} on macOS" + exclude: + # We only test latest Python on arm64. The py36 won't work since there's no universal2 binary + - PYTHON: {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""} + RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} + name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 steps: - uses: actions/checkout@v3.3.0 @@ -357,12 +364,13 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} + architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] diff --git a/.github/workflows/macarm64.yml b/.github/workflows/macarm64.yml deleted file mode 100644 index 2de198ac6628..000000000000 --- a/.github/workflows/macarm64.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: macOS arm64 CI -on: - pull_request: {} - push: - branches: - - main - - '*.*.x' - tags: - - '*.*' - - '*.*.*' - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -jobs: - macos-arm64: - if: github.repository_owner == 'pyca' - runs-on: [self-hosted, macos, ARM64, tart] - name: "macOS arm64" - strategy: - fail-fast: false - matrix: - PYTHON: - - {TOXENV: "py311", BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3'} - timeout-minutes: 10 - steps: - - uses: actions/checkout@v3.3.0 - with: - persist-credentials: false - - uses: actions/cache@v3.2.3 - with: - path: | - src/rust/target/ - key: ${{ runner.os }}-${{ matrix.PYTHON.TOXENV }}-cargo-macarm64-${{ hashFiles('**/Cargo.lock') }} - - - uses: actions/checkout@v3.3.0 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" - - name: Setup venv and install deps - run: | - $BIN_PATH -m venv venv - venv/bin/python -m pip install -c ci-constraints-requirements.txt tox requests - env: - BIN_PATH: ${{ matrix.PYTHON.BIN_PATH }} - - name: Download OpenSSL - run: | - venv/bin/python .github/workflows/download_openssl.py macos openssl-macos-universal2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Tests - run: | - CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ - LDFLAGS="${HOME}/openssl-macos-universal2/lib/libcrypto.a ${HOME}/openssl-macos-universal2/lib/libssl.a" \ - CFLAGS="-I${HOME}/openssl-macos-universal2/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function $EXTRA_CFLAGS" \ - venv/bin/tox -r -- --color=yes --wycheproof-root=wycheproof - env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} - CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} From 276b7271654d310bbbd9b8b20e56e3292d5d6ca5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 14 Jan 2023 16:07:31 -0500 Subject: [PATCH 090/827] Update installation.rst (#8067) --- docs/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.rst b/docs/installation.rst index a52a9df6d49f..959128961048 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -20,7 +20,7 @@ operating systems. * x86-64 CentOS 9 Stream * x86-64 Fedora (latest) * x86-64 macOS 12 Monterey -* ARM64 macOS 12 Monterey +* ARM64 macOS 13 Ventura * x86-64 Ubuntu 18.04, 20.04, 22.04, rolling * ARM64 Ubuntu 20.04 * x86-64 Debian Buster (10.x), Bullseye (11.x), Bookworm (12.x) From 965af65ae7bcc23ff1b3d123b95c0b7b29d2795b Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 00:20:10 +0000 Subject: [PATCH 091/827] Bump BoringSSL and/or OpenSSL in CI (#8068) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f33d95ec50f9..2abad2490808 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Jan 14, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3251ca1f63ff8c9ea760c0046309e93596f6c12b"}} - # Latest commit on the OpenSSL master branch, as of Jan 14, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "b639475a9433c827675b8154ea9e0ce361403c76"}} + # Latest commit on the OpenSSL master branch, as of Jan 15, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "30667f5c306dbc11ac0e6fddc7d26fd984d546ab"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 8b466d24bdf42359df4c4ed9b0d3bb2c98d02b16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:51:00 +0000 Subject: [PATCH 092/827] Bump ruff from 0.0.220 to 0.0.222 (#8069) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.220 to 0.0.222. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.220...v0.0.222) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 07f6bc4fb3c6..729035b7df62 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.0.1 # via twine -ruff==0.0.220 +ruff==0.0.222 # via cryptography (setup.cfg) six==1.16.0 # via bleach From b91bb457c0ce3d147dcfb8a969cbf9847d98549e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:51:21 +0000 Subject: [PATCH 093/827] Bump pytest from 7.2.0 to 7.2.1 (#8072) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.0 to 7.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.0...7.2.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 729035b7df62..75ffd2bd373a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -121,7 +121,7 @@ pyproject-api==1.4.0 # via tox pyproject-hooks==1.0.0 # via build -pytest==7.2.0; python_version >= "3.7" +pytest==7.2.1; python_version >= "3.7" # via # cryptography (setup.cfg) # pytest-benchmark From 235ef384eb4966dcd15eb04ce8b5367f13144d53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:51:35 +0000 Subject: [PATCH 094/827] Bump termcolor from 1.1.3 to 1.2.0 in /src/rust (#8070) Bumps [termcolor](https://github.com/BurntSushi/termcolor) from 1.1.3 to 1.2.0. - [Release notes](https://github.com/BurntSushi/termcolor/releases) - [Commits](https://github.com/BurntSushi/termcolor/compare/1.1.3...1.2.0) --- updated-dependencies: - dependency-name: termcolor dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 393238101293..ca41c5d4b242 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -500,9 +500,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] From d3b074de10fdea832985039eabc07c266ee4858f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:55:33 +0000 Subject: [PATCH 095/827] Bump pytz from 2022.7 to 2022.7.1 (#8073) Bumps [pytz](https://github.com/stub42/pytz) from 2022.7 to 2022.7.1. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2022.7...release_2022.7.1) --- updated-dependencies: - dependency-name: pytz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 75ffd2bd373a..99cef40445ae 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -142,7 +142,7 @@ pytest-subtests==0.9.0; python_version >= "3.7" # via cryptography (setup.cfg) pytest-xdist==3.1.0; python_version >= "3.7" # via cryptography (setup.cfg) -pytz==2022.7 +pytz==2022.7.1 # via # babel # cryptography (setup.cfg) From 4aee32f34ef321503c223cbd3278adc57bc2fbd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 16:15:45 +0000 Subject: [PATCH 096/827] Bump hypothesis from 6.62.0 to 6.62.1 (#8075) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.62.0 to 6.62.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.62.0...hypothesis-python-6.62.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 99cef40445ae..53a9f4606a5e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -54,7 +54,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.62.0; python_version >= "3.7" +hypothesis==6.62.1; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 33b566022770a0534ca543a49615c613ea63ab87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 16:26:15 +0000 Subject: [PATCH 097/827] Bump types-pytz from 2022.7.0.0 to 2022.7.1.0 (#8071) Bumps [types-pytz](https://github.com/python/typeshed) from 2022.7.0.0 to 2022.7.1.0. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pytz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 53a9f4606a5e..52f9527610c0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -203,7 +203,7 @@ tox==4.2.8; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -types-pytz==2022.7.0.0 +types-pytz==2022.7.1.0 # via cryptography (setup.cfg) types-requests==2.28.11.7 # via cryptography (setup.cfg) From a5661f792ead2199951be55c8cb4e3c213608cac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 11:31:53 -0500 Subject: [PATCH 098/827] Bump rich from 13.0.1 to 13.1.0 (#8074) Bumps [rich](https://github.com/Textualize/rich) from 13.0.1 to 13.1.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.0.1...v13.1.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 52f9527610c0..d07399027159 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -157,7 +157,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.0.1 +rich==13.1.0 # via twine ruff==0.0.222 # via cryptography (setup.cfg) From 6e574f9bc38c3ef957107a970148325a5101710d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 15 Jan 2023 16:07:02 -0500 Subject: [PATCH 099/827] try making download_openssl.py a bit more resilient (#8076) --- .github/workflows/download_openssl.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/download_openssl.py b/.github/workflows/download_openssl.py index 3be39084b0d4..ad310d0d6d30 100644 --- a/.github/workflows/download_openssl.py +++ b/.github/workflows/download_openssl.py @@ -66,6 +66,15 @@ def main(platform, target): ) response = get_response(session, runs_url, token).json() + # We see this happen occasionally. Maybe this will help debug it + retry + # for resilience. + if not response["workflow_runs"]: + print( + f"`workflow_runs` is empty for some reason, retrying. response: " + f"{response}" + ) + response = get_response(session, runs_url, token).json() + artifacts_url = response["workflow_runs"][0]["artifacts_url"] response = get_response(session, artifacts_url, token).json() for artifact in response["artifacts"]: From 76ebc4df1ea7cff63988aeccbc1916d110af0e74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 20:35:59 +0800 Subject: [PATCH 100/827] Bump ruff from 0.0.222 to 0.0.223 (#8078) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.222 to 0.0.223. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.222...v0.0.223) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d07399027159..45e82a32e105 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.1.0 # via twine -ruff==0.0.222 +ruff==0.0.223 # via cryptography (setup.cfg) six==1.16.0 # via bleach From ba7b627f11d8cc49ceee2aad9198a917aabfddfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 12:38:48 +0000 Subject: [PATCH 101/827] Bump tox from 4.2.8 to 4.3.1 (#8079) Bumps [tox](https://github.com/tox-dev/tox) from 4.2.8 to 4.3.1. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.2.8...4.3.1) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 45e82a32e105..4387dc362ace 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.2.8; python_version >= "3.7" +tox==4.3.1; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 8d9faad806e437ab48cb1a9e9a1a6bccf8a4d977 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 16 Jan 2023 15:53:52 -0500 Subject: [PATCH 102/827] rename variable to make sense (#8080) --- src/cryptography/hazmat/backends/openssl/backend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 48f4265b023c..e492e9bdd78d 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1461,17 +1461,17 @@ def _tmp_bn_ctx(self): finally: self._lib.BN_CTX_end(bn_ctx) - def _ec_key_determine_group_get_func(self, ctx): + def _ec_key_determine_group_get_func(self, ec_key): """ Given an EC_KEY determine the group and what function is required to get point coordinates. """ - self.openssl_assert(ctx != self._ffi.NULL) + self.openssl_assert(ec_key != self._ffi.NULL) nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field") self.openssl_assert(nid_two_field != self._lib.NID_undef) - group = self._lib.EC_KEY_get0_group(ctx) + group = self._lib.EC_KEY_get0_group(ec_key) self.openssl_assert(group != self._ffi.NULL) method = self._lib.EC_GROUP_method_of(group) From d404f58673ea529827a319a68ec78b6f6740d59a Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:21:32 +0000 Subject: [PATCH 103/827] Bump BoringSSL and/or OpenSSL in CI (#8081) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2abad2490808..dc283091bf6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Jan 14, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3251ca1f63ff8c9ea760c0046309e93596f6c12b"}} - # Latest commit on the OpenSSL master branch, as of Jan 15, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "30667f5c306dbc11ac0e6fddc7d26fd984d546ab"}} + # Latest commit on the OpenSSL master branch, as of Jan 17, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "fe2a7341b50450dc6acd6f8a17d4420511a5aefe"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 7be12dc458c638f48572931ff1c8e0c00467dce1 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 16 Jan 2023 21:04:08 -0500 Subject: [PATCH 104/827] build boringssl's rust bindings in CI (#8082) * build boringssl's rust bindings in CI * bust-a-cache! --- .github/workflows/build_openssl.sh | 3 ++- .github/workflows/ci.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_openssl.sh b/.github/workflows/build_openssl.sh index 947b828222b2..a12794fa4877 100755 --- a/.github/workflows/build_openssl.sh +++ b/.github/workflows/build_openssl.sh @@ -68,7 +68,8 @@ elif [[ "${TYPE}" == "boringssl" ]]; then git checkout "${VERSION}" mkdir build pushd build - cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON + # Find the default rust target based on what rustc is built for + cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" make -j"$(nproc)" mkdir -p "${OSSL_PATH}/lib/" mkdir -p "${OSSL_PATH}/include/" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc283091bf6f..38ea5b0a59a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: path: ${{ github.workspace }}/osslcache # When altering the openssl build process you may need to increment the value on the end of this cache key # so that you can prevent it from fetching the cache and skipping the build step. - key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-4 + key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-5 if: matrix.PYTHON.OPENSSL - name: Build custom OpenSSL/LibreSSL run: .github/workflows/build_openssl.sh From 9833891563931cf73ef580b2f7340573002e4e97 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 17 Jan 2023 13:12:04 +0800 Subject: [PATCH 105/827] use our new self-hosted linux arm64 ephemeral runners (#8083) * use our new self-hosted linux arm64 ephemeral runners * review comments, install alpine aarch64 workaround * Update .github/workflows/ci.yml Co-authored-by: Alex Gaynor * remove ARCH Co-authored-by: Alex Gaynor --- .github/workflows/ci.yml | 47 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38ea5b0a59a6..6f12b8270bbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,30 +120,41 @@ jobs: - uses: ./.github/actions/upload-coverage linux-distros: - runs-on: ubuntu-latest + runs-on: ${{ matrix.IMAGE.RUNNER }} container: ghcr.io/pyca/cryptography-runner-${{ matrix.IMAGE.IMAGE }} strategy: fail-fast: false matrix: IMAGE: - - {IMAGE: "rhel8", TOXENV: "py36"} - - {IMAGE: "rhel8-fips", TOXENV: "py36", FIPS: true} - - {IMAGE: "rhel8", TOXENV: "py38"} - - {IMAGE: "rhel8-fips", TOXENV: "py38", FIPS: true} - - {IMAGE: "buster", TOXENV: "py37"} - - {IMAGE: "bullseye", TOXENV: "py39"} - - {IMAGE: "bookworm", TOXENV: "py310"} - - {IMAGE: "sid", TOXENV: "py311"} - - {IMAGE: "ubuntu-bionic", TOXENV: "py36"} - - {IMAGE: "ubuntu-focal", TOXENV: "py38"} - - {IMAGE: "ubuntu-jammy", TOXENV: "py310"} - - {IMAGE: "ubuntu-rolling", TOXENV: "py310"} - - {IMAGE: "fedora", TOXENV: "py311"} - - {IMAGE: "alpine", TOXENV: "py310"} - - {IMAGE: "centos-stream9", TOXENV: "py39"} - name: "${{ matrix.IMAGE.TOXENV }} on ${{ matrix.IMAGE.IMAGE }}" + - {IMAGE: "rhel8", TOXENV: "py36", RUNNER: "ubuntu-latest"} + - {IMAGE: "rhel8-fips", TOXENV: "py36", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "rhel8", TOXENV: "py38", RUNNER: "ubuntu-latest"} + - {IMAGE: "rhel8-fips", TOXENV: "py38", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "buster", TOXENV: "py37", RUNNER: "ubuntu-latest"} + - {IMAGE: "bullseye", TOXENV: "py39", RUNNER: "ubuntu-latest"} + - {IMAGE: "bookworm", TOXENV: "py310", RUNNER: "ubuntu-latest"} + - {IMAGE: "sid", TOXENV: "py311", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-bionic", TOXENV: "py36", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-focal", TOXENV: "py38", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-jammy", TOXENV: "py310", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-rolling", TOXENV: "py310", RUNNER: "ubuntu-latest"} + - {IMAGE: "fedora", TOXENV: "py311", RUNNER: "ubuntu-latest"} + - {IMAGE: "alpine", TOXENV: "py310", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9", TOXENV: "py39", RUNNER: "ubuntu-latest"} + + - {IMAGE: "ubuntu-focal:aarch64", TOXENV: "py38", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 steps: + - name: Ridiculous alpine workaround for actions support on arm64 + run: | + # This modifies /etc/os-release so the JS actions + # from GH can't detect that it's on alpine:aarch64. It will + # then use a glibc nodejs, which works fine when gcompat + # is installed in the container (which it is) + sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release + if: matrix.IMAGE.IMAGE == 'alpine:aarch64' + - uses: actions/checkout@v3.3.0 timeout-minutes: 3 with: @@ -159,7 +170,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - uses: actions/checkout@v3.3.0 timeout-minutes: 3 From 89ddadcc13d3131e0981d9f3fa07b76a2cabccb9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Jan 2023 00:31:01 -0500 Subject: [PATCH 106/827] remove CI jobs that are now in GHA (#8084) --- .circleci/config.yml | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 566c14c91a06..acc3d09475d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,22 +17,6 @@ commands: - run: docker run -e PLATFORM -e PYTHON -v $(pwd):/test <> /bin/bash -c 'cd /test;<>' jobs: - linux-arm64: - machine: - image: ubuntu-2004:current - resource_class: arm.medium - parameters: - image: - type: string - toxenv: - type: string - steps: - - checkout - - docker-pull: - image: <> - - docker-run: - image: <> - command: /venv/bin/pip install -c ci-constraints-requirements.txt tox && /venv/bin/tox -e <> linux-arm64-wheel: machine: image: ubuntu-2004:current @@ -60,24 +44,6 @@ jobs: workflows: ci: jobs: - - linux-arm64: - # Changing this name should only be done in conjunction with updating - # the required checks on GH - name: linux-arm64-ci - image: ghcr.io/pyca/cryptography-runner-ubuntu-focal:aarch64 - toxenv: py38 - # This makes sure it runs on all tags in addition to PRs/branches. - # By default CircleCI ignores tags. - filters: - tags: - only: /.*/ - - linux-arm64: - name: linux-arm64-alpine-ci - image: ghcr.io/pyca/cryptography-runner-alpine:aarch64 - toxenv: py310 - filters: - tags: - only: /.*/ - linux-arm64-wheel: name: manylinux2014_aarch64-wheel image: ghcr.io/pyca/cryptography-manylinux2014_aarch64:latest From 46b0c6d484778d05227a3f2b96d7f69385f3850d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:24:22 +0000 Subject: [PATCH 107/827] Bump proc-macro2 from 1.0.49 to 1.0.50 in /src/rust (#8086) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.49 to 1.0.50. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.49...1.0.50) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index ca41c5d4b242..24ba48b8f30a 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -396,9 +396,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] From e2b91816070330a234d98610188b29bfda5e1a12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:33:47 +0000 Subject: [PATCH 108/827] Bump ruff from 0.0.223 to 0.0.224 (#8087) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.223 to 0.0.224. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.223...v0.0.224) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4387dc362ace..8a3b12a496e4 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.1.0 # via twine -ruff==0.0.223 +ruff==0.0.224 # via cryptography (setup.cfg) six==1.16.0 # via bleach From b40e3f64abca46529d271ff67113d6e6a989e1c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:39:57 +0000 Subject: [PATCH 109/827] Bump tox from 4.3.1 to 4.3.3 (#8088) Bumps [tox](https://github.com/tox-dev/tox) from 4.3.1 to 4.3.3. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.3.1...4.3.3) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8a3b12a496e4..12bf84b059f0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.3.1; python_version >= "3.7" +tox==4.3.3; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From ed7bf4a2efeafb69b688de80f6e1eb8c9f17d8ac Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 18 Jan 2023 06:14:41 +0800 Subject: [PATCH 110/827] build arm64 linux wheels in GHA and drop manylinux_2_24 wheels (#8085) * build arm64 linux wheels in GHA and drop manylinux_2_24 wheels the image is unsupported as of two weeks ago and no one requires them (we have manylinux2014 aka manylinux_2_17 still) * remove unneeded excludes --- .github/workflows/wheel-builder.yml | 40 ++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 0bcc174b6e60..dc658e7bac85 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -48,7 +48,7 @@ jobs: manylinux: needs: [sdist] - runs-on: ubuntu-latest + runs-on: ${{ matrix.MANYLINUX.RUNNER }} container: ghcr.io/pyca/${{ matrix.MANYLINUX.CONTAINER }} strategy: fail-fast: false @@ -58,18 +58,44 @@ jobs: - { VERSION: "pp38-pypy38_pp73" } - { VERSION: "pp39-pypy39_pp73" } MANYLINUX: - - { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64" } - - { NAME: "manylinux_2_24_x86_64", CONTAINER: "cryptography-manylinux_2_24:x86_64"} - - { NAME: "manylinux_2_28_x86_64", CONTAINER: "cryptography-manylinux_2_28:x86_64"} - - { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64"} + - { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest" } + - { NAME: "manylinux_2_28_x86_64", CONTAINER: "cryptography-manylinux_2_28:x86_64", RUNNER: "ubuntu-latest"} + - { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} + + - { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64] } + - { NAME: "manylinux_2_28_aarch64", CONTAINER: "cryptography-manylinux_2_28:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} exclude: # There are no readily available musllinux PyPy distributions - PYTHON: { VERSION: "pp38-pypy38_pp73" } - MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64"} + MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} + - PYTHON: { VERSION: "pp39-pypy39_pp73" } + MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} + - PYTHON: { VERSION: "pp38-pypy38_pp73" } + MANYLINUX: { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - PYTHON: { VERSION: "pp39-pypy39_pp73" } + MANYLINUX: { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + # We also don't build pypy wheels for anything except the latest manylinux + - PYTHON: { VERSION: "pp38-pypy38_pp73" } + MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} - PYTHON: { VERSION: "pp39-pypy39_pp73" } - MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64"} + MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} + - PYTHON: { VERSION: "pp38-pypy38_pp73" } + MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - PYTHON: { VERSION: "pp39-pypy39_pp73" } + MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - PYTHON: { VERSION: "pp38-pypy38_pp73" } name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}" steps: + - name: Ridiculous alpine workaround for actions support on arm64 + run: | + # This modifies /etc/os-release so the JS actions + # from GH can't detect that it's on alpine:aarch64. It will + # then use a glibc nodejs, which works fine when gcompat + # is installed in the container (which it is) + sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release + if: matrix.MANYLINUX.NAME == 'musllinux_1_1_aarch64' + - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist From 9b59981740bcc399f1c08ec48de057b368d4eb23 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Jan 2023 19:55:22 -0500 Subject: [PATCH 111/827] this function doesn't return anything (#8091) --- src/_cffi_src/openssl/x509v3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 863973fc0d08..838bda2903ec 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -51,7 +51,7 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, const char *, const char *); -void *X509V3_set_ctx_nodb(X509V3_CTX *); +void X509V3_set_ctx_nodb(X509V3_CTX *); int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *); GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int); From 09e9951e5212174439d104462bc95bb5dbaaafd6 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 01:11:55 +0000 Subject: [PATCH 112/827] Bump BoringSSL and/or OpenSSL in CI (#8090) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f12b8270bbb..b1d20437ee5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 14, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3251ca1f63ff8c9ea760c0046309e93596f6c12b"}} - # Latest commit on the OpenSSL master branch, as of Jan 17, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "fe2a7341b50450dc6acd6f8a17d4420511a5aefe"}} + # Latest commit on the BoringSSL master branch, as of Jan 18, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "db38fc55939095dd8082e0a89b0c9d187ac164f6"}} + # Latest commit on the OpenSSL master branch, as of Jan 18, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "235ef96049dbe337a3c3c5d419dacbb5a81df1b3"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 72305421f3f65069c8a4398a02523ad219e015db Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Jan 2023 20:47:40 -0500 Subject: [PATCH 113/827] Remove CircleCI (#8092) --- .circleci/build-wheel.sh | 35 ------------ .circleci/config.yml | 94 -------------------------------- MANIFEST.in | 2 - release.py | 114 +-------------------------------------- 4 files changed, 1 insertion(+), 244 deletions(-) delete mode 100755 .circleci/build-wheel.sh delete mode 100644 .circleci/config.yml diff --git a/.circleci/build-wheel.sh b/.circleci/build-wheel.sh deleted file mode 100755 index 26bb00df4933..000000000000 --- a/.circleci/build-wheel.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -ex - -cd /test - -echo "Building for ${PLATFORM}" - -PYBIN="/opt/python/${PYTHON}/bin" - -mkdir -p /test/wheelhouse.final - -"${PYBIN}"/python -m venv .venv - -.venv/bin/pip install -U pip wheel cffi setuptools-rust - -.venv/bin/python setup.py sdist -cd dist -tar zxf cryptography*.tar.gz -rm -rf cryptograph*.tar.gz -cd cryptography* - -REGEX="cp3([0-9])*" -if [[ "${PYBIN}" =~ $REGEX ]]; then - PY_LIMITED_API="--py-limited-api=cp3${BASH_REMATCH[1]}" -fi - -LDFLAGS="-L/opt/pyca/cryptography/openssl/lib" \ - CFLAGS="-I/opt/pyca/cryptography/openssl/include -Wl,--exclude-libs,ALL" \ - ../../.venv/bin/python setup.py bdist_wheel $PY_LIMITED_API - -auditwheel repair --plat "${PLATFORM}" -w wheelhouse/ dist/cryptography*.whl - -../../.venv/bin/pip install cryptography --no-index -f wheelhouse/ -../../.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'))" - -mv wheelhouse/* /test/wheelhouse.final diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index acc3d09475d6..000000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,94 +0,0 @@ -version: 2.1 - -commands: - docker-pull: - parameters: - image: - type: string - steps: - - run: docker pull <> || docker pull <> - docker-run: - parameters: - image: - type: string - command: - type: string - steps: - - run: docker run -e PLATFORM -e PYTHON -v $(pwd):/test <> /bin/bash -c 'cd /test;<>' - -jobs: - linux-arm64-wheel: - machine: - image: ubuntu-2004:current - resource_class: arm.medium - parameters: - image: - type: string - platform: - type: string - python: - type: string - environment: - PLATFORM: <> - PYTHON: <> - steps: - - checkout - - docker-pull: - image: <> - - docker-run: - image: <> - command: /test/.circleci/build-wheel.sh - - store_artifacts: - path: wheelhouse.final - -workflows: - ci: - jobs: - - linux-arm64-wheel: - name: manylinux2014_aarch64-wheel - image: ghcr.io/pyca/cryptography-manylinux2014_aarch64:latest - python: cp36-cp36m - platform: manylinux2014_aarch64 - filters: - tags: - only: /.*/ - - linux-arm64-wheel: - name: manylinux_2_24_aarch64-wheel - image: ghcr.io/pyca/cryptography-manylinux_2_24:aarch64 - python: cp36-cp36m - platform: manylinux_2_24_aarch64 - filters: - tags: - only: /.*/ - - linux-arm64-wheel: - name: manylinux_2_28_aarch64-wheel - image: ghcr.io/pyca/cryptography-manylinux_2_28:aarch64 - python: cp36-cp36m - platform: manylinux_2_28_aarch64 - filters: - tags: - only: /.*/ - - linux-arm64-wheel: - name: manylinux_2_28_aarch64-wheel - image: ghcr.io/pyca/cryptography-manylinux_2_28:aarch64 - python: pp38-pypy38_pp73 - platform: manylinux_2_28_aarch64 - filters: - tags: - only: /.*/ - - linux-arm64-wheel: - name: manylinux_2_28_aarch64-wheel - image: ghcr.io/pyca/cryptography-manylinux_2_28:aarch64 - python: pp39-pypy39_pp73 - platform: manylinux_2_28_aarch64 - filters: - tags: - only: /.*/ - - linux-arm64-wheel: - name: musllinux_1_1_aarch64-wheel - image: ghcr.io/pyca/cryptography-musllinux_1_1:aarch64 - python: cp36-cp36m - platform: musllinux_1_1_aarch64 - filters: - tags: - only: /.*/ diff --git a/MANIFEST.in b/MANIFEST.in index 52db6dc8169c..62699330e9b2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -20,5 +20,3 @@ recursive-exclude vectors * recursive-exclude .github * exclude release.py .readthedocs.yml ci-constraints-requirements.txt tox.ini mypy.ini - -recursive-exclude .circleci * diff --git a/release.py b/release.py index 01101bcd872a..c108f1ead267 100644 --- a/release.py +++ b/release.py @@ -8,7 +8,6 @@ import subprocess import time import typing -import urllib import zipfile import click @@ -114,108 +113,6 @@ def fetch_github_actions_artifacts( return download_artifacts_github_actions(session, token, run_url) -def wait_for_build_complete_circleci( - session: requests.Session, token: str, pipeline_id: str -) -> None: - while True: - response = session.get( - f"https://circleci.com/api/v2/pipeline/{pipeline_id}/workflow", - headers={ - "Circle-Token": token, - }, - ) - response.raise_for_status() - status = response.json()["items"][0]["status"] - if status == "success": - break - elif status not in ("running", "on_hold", "not_run"): - raise ValueError(f"CircleCI build failed with status {status}") - time.sleep(3) - - -def download_artifacts_circleci( - session: requests.Session, urls: typing.List[str] -) -> typing.List[str]: - paths = [] - for url in urls: - name = os.path.basename(urllib.parse.urlparse(url).path) - response = session.get(url) - out_path = os.path.join( - os.path.dirname(__file__), - "dist", - os.path.basename(name), - ) - with open(out_path, "wb") as f: - f.write(response.content) - paths.append(out_path) - return paths - - -def fetch_circleci_artifacts(token: str, version: str) -> typing.List[str]: - session = requests.Session() - - response = session.get( - "https://circleci.com/api/v2/pipeline?org-slug=gh/pyca", - headers={"Circle-Token": token}, - ) - response.raise_for_status() - pipeline_id = None - for item in response.json()["items"]: - if item["project_slug"] == "gh/pyca/cryptography": - if item["vcs"].get("tag", None) == version: - pipeline_id = item["id"] - break - - if pipeline_id is None: - raise ValueError(f"Could not find a pipeline for version {version}") - - wait_for_build_complete_circleci(session, token, pipeline_id) - urls = fetch_circleci_artifact_urls(session, token, pipeline_id) - return download_artifacts_circleci(session, urls) - - -def fetch_circleci_artifact_urls( - session: requests.Session, token: str, pipeline_id: str -) -> typing.List[str]: - response = session.get( - f"https://circleci.com/api/v2/pipeline/{pipeline_id}/workflow", - headers={"Circle-Token": token}, - ) - response.raise_for_status() - workflow_id = response.json()["items"][0]["id"] - job_response = session.get( - f"https://circleci.com/api/v2/workflow/{workflow_id}/job", - headers={"Circle-Token": token}, - ) - job_response.raise_for_status() - artifact_urls = [] - for job in job_response.json()["items"]: - urls = fetch_circleci_artifact_url_from_job( - session, token, job["job_number"] - ) - artifact_urls.extend(urls) - - return artifact_urls - - -def fetch_circleci_artifact_url_from_job( - session: requests.Session, token: str, job: str -) -> typing.List[str]: - response = session.get( - f"https://circleci.com/api/v2/project/gh/pyca/cryptography/" - f"{job}/artifacts", - headers={"Circle-Token": token}, - ) - response.raise_for_status() - urls = [] - for item in response.json()["items"]: - url = item.get("url", None) - if url is not None: - urls.append(url) - - return urls - - @click.command() @click.argument("version") def release(version: str) -> None: @@ -227,12 +124,7 @@ def release(version: str) -> None: f"https://github.com/settings/tokens/new?" f"description={version}&scopes=repo" ) - print( - "Get a CircleCI token at: " - "https://app.circleci.com/settings/user/tokens" - ) github_token = getpass.getpass("Github person access token: ") - circle_token = getpass.getpass("CircleCI token: ") # Tag and push the tag (this will trigger the wheel builder in Actions) run("git", "tag", "-s", version, "-m", f"{version} release") @@ -244,13 +136,9 @@ def release(version: str) -> None: github_actions_artifact_paths = fetch_github_actions_artifacts( github_token, version ) - # Download wheels from CircleCI - circle_artifact_paths = fetch_circleci_artifacts(circle_token, version) - - artifact_paths = github_actions_artifact_paths + circle_artifact_paths # Upload wheels and sdist - run("twine", "upload", *artifact_paths) + run("twine", "upload", *github_actions_artifact_paths) if __name__ == "__main__": From 1daf843fc8d25495e2bdea690e8931bf80c1081e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:37:08 +0000 Subject: [PATCH 114/827] Bump pyproject-api from 1.4.0 to 1.5.0 (#8095) Bumps [pyproject-api](https://github.com/tox-dev/pyproject-api) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/tox-dev/pyproject-api/releases) - [Changelog](https://github.com/tox-dev/pyproject-api/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/pyproject-api/compare/1.4.0...1.5.0) --- updated-dependencies: - dependency-name: pyproject-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 12bf84b059f0..8bf0edd6afa9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -117,7 +117,7 @@ pygments==2.14.0 # readme-renderer # rich # sphinx -pyproject-api==1.4.0 +pyproject-api==1.5.0 # via tox pyproject-hooks==1.0.0 # via build From f508ad902130d7adb168aa08b5072846359b2a80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:37:21 +0000 Subject: [PATCH 115/827] Bump tox from 4.3.3 to 4.3.4 (#8096) Bumps [tox](https://github.com/tox-dev/tox) from 4.3.3 to 4.3.4. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.3.3...4.3.4) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8bf0edd6afa9..d0336d2bdd4a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.3.3; python_version >= "3.7" +tox==4.3.4; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 79567f36d575668855198c4826008a8d55221176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:46:36 +0000 Subject: [PATCH 116/827] Bump types-requests from 2.28.11.7 to 2.28.11.8 (#8097) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.7 to 2.28.11.8. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d0336d2bdd4a..d620b4cef1dd 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -205,7 +205,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.0 # via cryptography (setup.cfg) -types-requests==2.28.11.7 +types-requests==2.28.11.8 # via cryptography (setup.cfg) types-urllib3==1.26.25.4 # via types-requests From fb72e64e6a36c62ce7df2624463bf7a601cef844 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:46:47 +0000 Subject: [PATCH 117/827] Bump ruff from 0.0.224 to 0.0.225 (#8099) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.224 to 0.0.225. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.224...v0.0.225) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d620b4cef1dd..5ad31a84703f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.1.0 # via twine -ruff==0.0.224 +ruff==0.0.225 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 31051c9459cdd3bec1ff5db56bc0af80430973a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:46:59 +0000 Subject: [PATCH 118/827] Bump markupsafe from 2.1.1 to 2.1.2 (#8098) Bumps [markupsafe](https://github.com/pallets/markupsafe) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/pallets/markupsafe/releases) - [Changelog](https://github.com/pallets/markupsafe/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/markupsafe/compare/2.1.1...2.1.2) --- updated-dependencies: - dependency-name: markupsafe dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5ad31a84703f..bda38c117268 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -74,7 +74,7 @@ jinja2==3.1.2 # via sphinx keyring==23.13.1 # via twine -markupsafe==2.1.1 +markupsafe==2.1.2 # via jinja2 more-itertools==9.0.0 # via jaraco-classes From a83f407377ccf9faa0b994630a4e4e2c211bb8d9 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 19 Jan 2023 00:19:41 +0000 Subject: [PATCH 119/827] Bump BoringSSL and/or OpenSSL in CI (#8100) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1d20437ee5a..b077a3f15498 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 18, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "db38fc55939095dd8082e0a89b0c9d187ac164f6"}} + # Latest commit on the BoringSSL master branch, as of Jan 19, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "45b8d7bbd771cbf7e116db2ba1f1cc7af959497e"}} # Latest commit on the OpenSSL master branch, as of Jan 18, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "235ef96049dbe337a3c3c5d419dacbb5a81df1b3"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From 361835d91cb41e8aeef1a6d3e82f5d00c023ad82 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 19 Jan 2023 12:43:41 +0800 Subject: [PATCH 120/827] test on jammy arm64 (and not focal) (#8101) * test on jammy arm64 (and not focal) * actually py310 --- .github/workflows/ci.yml | 2 +- docs/installation.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b077a3f15498..28faffc7f34c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -142,7 +142,7 @@ jobs: - {IMAGE: "alpine", TOXENV: "py310", RUNNER: "ubuntu-latest"} - {IMAGE: "centos-stream9", TOXENV: "py39", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-focal:aarch64", TOXENV: "py38", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "ubuntu-jammy:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 steps: diff --git a/docs/installation.rst b/docs/installation.rst index 959128961048..c3d867d666f8 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -22,7 +22,7 @@ operating systems. * x86-64 macOS 12 Monterey * ARM64 macOS 13 Ventura * x86-64 Ubuntu 18.04, 20.04, 22.04, rolling -* ARM64 Ubuntu 20.04 +* ARM64 Ubuntu 22.04 * x86-64 Debian Buster (10.x), Bullseye (11.x), Bookworm (12.x) and Sid (unstable) * x86-64 Alpine (latest) From 2a86f6fcaf14d74271658b4d9cb804738f8d4c5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:38:24 +0000 Subject: [PATCH 121/827] Bump tox from 4.3.4 to 4.3.5 (#8103) Bumps [tox](https://github.com/tox-dev/tox) from 4.3.4 to 4.3.5. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.3.4...4.3.5) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index bda38c117268..d0fe084454c9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -199,7 +199,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.3.4; python_version >= "3.7" +tox==4.3.5; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From cb12054ec3c7308af8f050950427f7f41bdcfb8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:44:59 +0000 Subject: [PATCH 122/827] Bump ruff from 0.0.225 to 0.0.226 (#8102) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.225 to 0.0.226. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.225...v0.0.226) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d0fe084454c9..50854aeec3eb 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.1.0 # via twine -ruff==0.0.225 +ruff==0.0.226 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 5d3db676cf6f94228910acfc721f57b73bf79908 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 19 Jan 2023 16:36:01 -0500 Subject: [PATCH 123/827] Use the ruff 'pyupgrade' checks (#8104) --- .github/workflows/download_openssl.py | 10 ++-- docs/conf.py | 2 - .../custom-vectors/arc4/generate_arc4.py | 10 ++-- .../custom-vectors/cast5/generate_cast5.py | 14 +++--- .../custom-vectors/hkdf/generate_hkdf.py | 2 +- .../custom-vectors/idea/generate_idea.py | 16 +++---- .../custom-vectors/idea/verify_idea.py | 4 +- .../rsa-oaep-sha2/generate_rsa_oaep_sha2.py | 4 +- .../secp256k1/generate_secp256k1.py | 14 +++--- .../custom-vectors/seed/generate_seed.py | 16 +++---- .../custom-vectors/seed/verify_seed.py | 4 +- pyproject.toml | 4 +- release.py | 12 ++--- src/cryptography/__about__.py | 2 +- src/cryptography/exceptions.py | 4 +- .../hazmat/backends/openssl/backend.py | 6 +-- .../hazmat/backends/openssl/ciphers.py | 4 +- .../hazmat/backends/openssl/ec.py | 2 +- .../hazmat/backends/openssl/rsa.py | 4 +- .../hazmat/bindings/openssl/binding.py | 12 +++-- .../hazmat/primitives/_serialization.py | 2 +- .../hazmat/primitives/asymmetric/dh.py | 2 +- .../hazmat/primitives/ciphers/aead.py | 2 +- .../hazmat/primitives/ciphers/modes.py | 4 +- .../hazmat/primitives/kdf/concatkdf.py | 8 +--- .../hazmat/primitives/kdf/hkdf.py | 2 +- .../hazmat/primitives/kdf/x963kdf.py | 4 +- src/cryptography/utils.py | 6 +-- src/cryptography/x509/base.py | 10 ++-- src/cryptography/x509/extensions.py | 48 +++++++++---------- src/cryptography/x509/general_name.py | 12 ++--- src/cryptography/x509/name.py | 4 +- tests/bench/test_x509.py | 1 - tests/conftest.py | 4 +- tests/hazmat/backends/test_openssl_memleak.py | 2 +- tests/hazmat/primitives/test_aead.py | 2 +- tests/hazmat/primitives/test_aes.py | 4 +- tests/hazmat/primitives/test_pkcs12.py | 40 ++++++++-------- tests/hazmat/primitives/test_rsa.py | 16 ++----- tests/utils.py | 20 ++++---- tests/wycheproof/test_ecdsa.py | 2 +- tests/wycheproof/test_hmac.py | 2 +- tests/x509/test_name.py | 1 - tests/x509/test_x509.py | 1 - 44 files changed, 160 insertions(+), 185 deletions(-) diff --git a/.github/workflows/download_openssl.py b/.github/workflows/download_openssl.py index ad310d0d6d30..4341337e67f2 100644 --- a/.github/workflows/download_openssl.py +++ b/.github/workflows/download_openssl.py @@ -23,7 +23,7 @@ def get_response(session, url, token): requests.exceptions.ChunkedEncodingError, requests.exceptions.ConnectTimeout, ) as e: - print("Exception ({}) fetching {}, retrying".format(e, url)) + print(f"Exception ({e}) fetching {url}, retrying") time.sleep(2) continue if response.status_code != 200: @@ -37,9 +37,7 @@ def get_response(session, url, token): return response response = session.get(url, headers={"Authorization": "token " + token}) if response.status_code != 200: - raise ValueError( - "Got HTTP {} fetching {}: ".format(response.status_code, url) - ) + raise ValueError(f"Got HTTP {response.status_code} fetching {url}: ") return response @@ -59,7 +57,7 @@ def main(platform, target): session.mount("https://", adapter) token = os.environ["GITHUB_TOKEN"] - print("Looking for: {}".format(target)) + print(f"Looking for: {target}") runs_url = ( "https://api.github.com/repos/pyca/infra/actions/workflows/" "{}/runs?branch=main&status=success".format(workflow) @@ -87,7 +85,7 @@ def main(platform, target): os.path.join(path, artifact["name"]) ) return - raise ValueError("Didn't find {} in {}".format(target, response)) + raise ValueError(f"Didn't find {target} in {response}") if __name__ == "__main__": diff --git a/docs/conf.py b/docs/conf.py index dda20ca93c00..0c69fc85b15d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # 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. diff --git a/docs/development/custom-vectors/arc4/generate_arc4.py b/docs/development/custom-vectors/arc4/generate_arc4.py index 504d19643425..2ca919b40858 100644 --- a/docs/development/custom-vectors/arc4/generate_arc4.py +++ b/docs/development/custom-vectors/arc4/generate_arc4.py @@ -76,13 +76,11 @@ def _build_vectors(): while current_offset < offset: encryptor.update(plaintext) current_offset += len(plaintext) - output.append("\nCOUNT = {}".format(count)) + output.append(f"\nCOUNT = {count}") count += 1 - output.append("KEY = {}".format(key)) - output.append("OFFSET = {}".format(offset)) - output.append( - "PLAINTEXT = {}".format(binascii.hexlify(plaintext)) - ) + output.append(f"KEY = {key}") + output.append(f"OFFSET = {offset}") + output.append(f"PLAINTEXT = {binascii.hexlify(plaintext)}") output.append( "CIPHERTEXT = {}".format( binascii.hexlify(encryptor.update(plaintext)) diff --git a/docs/development/custom-vectors/cast5/generate_cast5.py b/docs/development/custom-vectors/cast5/generate_cast5.py index b57d71ddbc51..27fb4634e295 100644 --- a/docs/development/custom-vectors/cast5/generate_cast5.py +++ b/docs/development/custom-vectors/cast5/generate_cast5.py @@ -25,7 +25,7 @@ def build_vectors(mode, filename): iv = None plaintext = None - with open(filename, "r") as vector_file: + with open(filename) as vector_file: for line in vector_file: line = line.strip() if line.startswith("KEY"): @@ -35,20 +35,18 @@ def build_vectors(mode, filename): encrypt(mode, key, iv, plaintext) ) ) - output.append("\nCOUNT = {}".format(count)) + output.append(f"\nCOUNT = {count}") count += 1 name, key = line.split(" = ") - output.append("KEY = {}".format(key)) + output.append(f"KEY = {key}") elif line.startswith("IV"): name, iv = line.split(" = ") iv = iv[0:16] - output.append("IV = {}".format(iv)) + output.append(f"IV = {iv}") elif line.startswith("PLAINTEXT"): name, plaintext = line.split(" = ") - output.append("PLAINTEXT = {}".format(plaintext)) - output.append( - "CIPHERTEXT = {}".format(encrypt(mode, key, iv, plaintext)) - ) + output.append(f"PLAINTEXT = {plaintext}") + output.append(f"CIPHERTEXT = {encrypt(mode, key, iv, plaintext)}") return "\n".join(output) diff --git a/docs/development/custom-vectors/hkdf/generate_hkdf.py b/docs/development/custom-vectors/hkdf/generate_hkdf.py index 410d26f27f11..97ad2fae70d5 100644 --- a/docs/development/custom-vectors/hkdf/generate_hkdf.py +++ b/docs/development/custom-vectors/hkdf/generate_hkdf.py @@ -24,7 +24,7 @@ def _build_vectors(): "IKM = " + binascii.hexlify(IKM).decode("ascii"), "salt = ", "info = ", - "L = {}".format(L), + f"L = {L}", "OKM = " + binascii.hexlify(OKM).decode("ascii"), ] return "\n".join(output) diff --git a/docs/development/custom-vectors/idea/generate_idea.py b/docs/development/custom-vectors/idea/generate_idea.py index 4d0defaa2712..c0e93ee52a48 100644 --- a/docs/development/custom-vectors/idea/generate_idea.py +++ b/docs/development/custom-vectors/idea/generate_idea.py @@ -15,7 +15,7 @@ def encrypt(mode, key, iv, plaintext): def build_vectors(mode, filename): - with open(filename, "r") as f: + with open(filename) as f: vector_file = f.read().splitlines() count = 0 @@ -28,23 +28,21 @@ def build_vectors(mode, filename): if line.startswith("KEY"): if count != 0: output.append( - "CIPHERTEXT = {0}".format( - encrypt(mode, key, iv, plaintext) - ) + f"CIPHERTEXT = {encrypt(mode, key, iv, plaintext)}" ) - output.append("\nCOUNT = {0}".format(count)) + output.append(f"\nCOUNT = {count}") count += 1 name, key = line.split(" = ") - output.append("KEY = {0}".format(key)) + output.append(f"KEY = {key}") elif line.startswith("IV"): name, iv = line.split(" = ") iv = iv[0:16] - output.append("IV = {0}".format(iv)) + output.append(f"IV = {iv}") elif line.startswith("PLAINTEXT"): name, plaintext = line.split(" = ") - output.append("PLAINTEXT = {0}".format(plaintext)) + output.append(f"PLAINTEXT = {plaintext}") - output.append("CIPHERTEXT = {0}".format(encrypt(mode, key, iv, plaintext))) + output.append(f"CIPHERTEXT = {encrypt(mode, key, iv, plaintext)}") return "\n".join(output) diff --git a/docs/development/custom-vectors/idea/verify_idea.py b/docs/development/custom-vectors/idea/verify_idea.py index d356de0ba7f3..52e5f73f4e5f 100644 --- a/docs/development/custom-vectors/idea/verify_idea.py +++ b/docs/development/custom-vectors/idea/verify_idea.py @@ -9,7 +9,7 @@ def encrypt(mode, key, iv, plaintext): encryptor = botan.Cipher( - "IDEA/{0}/NoPadding".format(mode), "encrypt", binascii.unhexlify(key) + f"IDEA/{mode}/NoPadding", "encrypt", binascii.unhexlify(key) ) cipher_text = encryptor.cipher( @@ -19,7 +19,7 @@ def encrypt(mode, key, iv, plaintext): def verify_vectors(mode, filename): - with open(filename, "r") as f: + with open(filename) as f: vector_file = f.read().splitlines() vectors = load_nist_vectors(vector_file) diff --git a/docs/development/custom-vectors/rsa-oaep-sha2/generate_rsa_oaep_sha2.py b/docs/development/custom-vectors/rsa-oaep-sha2/generate_rsa_oaep_sha2.py index 6940f0400d47..f9e79122686e 100644 --- a/docs/development/custom-vectors/rsa-oaep-sha2/generate_rsa_oaep_sha2.py +++ b/docs/development/custom-vectors/rsa-oaep-sha2/generate_rsa_oaep_sha2.py @@ -82,7 +82,7 @@ def build_vectors(mgf1alg, hashalg, filename): ), ) output.append( - "# OAEP Example {0} alg={1} mgf1={2}".format( + "# OAEP Example {} alg={} mgf1={}".format( count, hashalg.name, mgf1alg.name ) ) @@ -118,5 +118,5 @@ def write_file(data, filename): write_file( build_vectors(hashtuple[0], hashtuple[1], oaep_path), - "oaep-{0}-{1}.txt".format(hashtuple[0].name, hashtuple[1].name), + f"oaep-{hashtuple[0].name}-{hashtuple[1].name}.txt", ) diff --git a/docs/development/custom-vectors/secp256k1/generate_secp256k1.py b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py index ab616de7f963..545b25af756c 100644 --- a/docs/development/custom-vectors/secp256k1/generate_secp256k1.py +++ b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py @@ -40,7 +40,7 @@ def build_vectors(fips_vectors): continue yield "" - yield "[K-256,{0}]".format(digest_algorithm) + yield f"[K-256,{digest_algorithm}]" yield "" for message in messages: @@ -56,12 +56,12 @@ def build_vectors(fips_vectors): r, s = sigdecode_der(signature, None) - yield "Msg = {0}".format(hexlify(message)) - yield "d = {0:x}".format(secret_key.privkey.secret_multiplier) - yield "Qx = {0:x}".format(public_key.pubkey.point.x()) - yield "Qy = {0:x}".format(public_key.pubkey.point.y()) - yield "R = {0:x}".format(r) - yield "S = {0:x}".format(s) + yield f"Msg = {hexlify(message)}" + yield f"d = {secret_key.privkey.secret_multiplier:x}" + yield f"Qx = {public_key.pubkey.point.x():x}" + yield f"Qy = {public_key.pubkey.point.y():x}" + yield f"R = {r:x}" + yield f"S = {s:x}" yield "" diff --git a/docs/development/custom-vectors/seed/generate_seed.py b/docs/development/custom-vectors/seed/generate_seed.py index 3e0125b9d9ed..c2ebf4b2b2b9 100644 --- a/docs/development/custom-vectors/seed/generate_seed.py +++ b/docs/development/custom-vectors/seed/generate_seed.py @@ -15,7 +15,7 @@ def encrypt(mode, key, iv, plaintext): def build_vectors(mode, filename): - with open(filename, "r") as f: + with open(filename) as f: vector_file = f.read().splitlines() count = 0 @@ -28,22 +28,20 @@ def build_vectors(mode, filename): if line.startswith("KEY"): if count != 0: output.append( - "CIPHERTEXT = {0}".format( - encrypt(mode, key, iv, plaintext) - ) + f"CIPHERTEXT = {encrypt(mode, key, iv, plaintext)}" ) - output.append("\nCOUNT = {0}".format(count)) + output.append(f"\nCOUNT = {count}") count += 1 name, key = line.split(" = ") - output.append("KEY = {0}".format(key)) + output.append(f"KEY = {key}") elif line.startswith("IV"): name, iv = line.split(" = ") - output.append("IV = {0}".format(iv)) + output.append(f"IV = {iv}") elif line.startswith("PLAINTEXT"): name, plaintext = line.split(" = ") - output.append("PLAINTEXT = {0}".format(plaintext)) + output.append(f"PLAINTEXT = {plaintext}") - output.append("CIPHERTEXT = {0}".format(encrypt(mode, key, iv, plaintext))) + output.append(f"CIPHERTEXT = {encrypt(mode, key, iv, plaintext)}") return "\n".join(output) diff --git a/docs/development/custom-vectors/seed/verify_seed.py b/docs/development/custom-vectors/seed/verify_seed.py index 252088d083e1..c28ed1e2fbef 100644 --- a/docs/development/custom-vectors/seed/verify_seed.py +++ b/docs/development/custom-vectors/seed/verify_seed.py @@ -7,7 +7,7 @@ def encrypt(mode, key, iv, plaintext): encryptor = botan.Cipher( - "SEED/{0}/NoPadding".format(mode), "encrypt", binascii.unhexlify(key) + f"SEED/{mode}/NoPadding", "encrypt", binascii.unhexlify(key) ) cipher_text = encryptor.cipher( @@ -17,7 +17,7 @@ def encrypt(mode, key, iv, plaintext): def verify_vectors(mode, filename): - with open(filename, "r") as f: + with open(filename) as f: vector_file = f.read().splitlines() vectors = load_nist_vectors(vector_file) diff --git a/pyproject.toml b/pyproject.toml index c98a37054b1f..2cb1643deac5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,8 +71,8 @@ exclude = [ '_build', '.hypothesis', ] -ignore = ['N818'] -select = ['E', 'F', 'I', 'N', 'W'] +ignore = ['N818', 'UP003', 'UP006', 'UP007'] +select = ['E', 'F', 'I', 'N', 'W', 'UP'] line-length = 79 [tool.ruff.isort] diff --git a/release.py b/release.py index c108f1ead267..fad64358cbdf 100644 --- a/release.py +++ b/release.py @@ -15,7 +15,7 @@ def run(*args: str) -> None: - print("[running] {0}".format(list(args))) + print(f"[running] {list(args)}") subprocess.check_call(list(args)) @@ -27,7 +27,7 @@ def wait_for_build_complete_github_actions( run_url, headers={ "Content-Type": "application/json", - "Authorization": "token {}".format(token), + "Authorization": f"token {token}", }, ) response.raise_for_status() @@ -43,7 +43,7 @@ def download_artifacts_github_actions( run_url, headers={ "Content-Type": "application/json", - "Authorization": "token {}".format(token), + "Authorization": f"token {token}", }, ) response.raise_for_status() @@ -52,7 +52,7 @@ def download_artifacts_github_actions( response.json()["artifacts_url"], headers={ "Content-Type": "application/json", - "Authorization": "token {}".format(token), + "Authorization": f"token {token}", }, ) response.raise_for_status() @@ -62,7 +62,7 @@ def download_artifacts_github_actions( artifact["archive_download_url"], headers={ "Content-Type": "application/json", - "Authorization": "token {}".format(token), + "Authorization": f"token {token}", }, ) with zipfile.ZipFile(io.BytesIO(response.content)) as z: @@ -99,7 +99,7 @@ def fetch_github_actions_artifacts( ), headers={ "Content-Type": "application/json", - "Authorization": "token {}".format(token), + "Authorization": f"token {token}", }, ) response.raise_for_status() diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 379a73a95383..48d5c220045c 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -12,4 +12,4 @@ __version__ = "40.0.0.dev1" __author__ = "The Python Cryptographic Authority and individual contributors" -__copyright__ = "Copyright 2013-2022 {}".format(__author__) +__copyright__ = f"Copyright 2013-2022 {__author__}" diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py index a315703c38d4..b0e2b4dac791 100644 --- a/src/cryptography/exceptions.py +++ b/src/cryptography/exceptions.py @@ -32,7 +32,7 @@ class UnsupportedAlgorithm(Exception): def __init__( self, message: str, reason: typing.Optional[_Reasons] = None ) -> None: - super(UnsupportedAlgorithm, self).__init__(message) + super().__init__(message) self._reason = reason @@ -60,7 +60,7 @@ class InternalError(Exception): def __init__( self, msg: str, err_code: typing.List["_OpenSSLErrorWithText"] ) -> None: - super(InternalError, self).__init__(msg) + super().__init__(msg) self.err_code = err_code diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index e492e9bdd78d..26188aa0f45e 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1307,7 +1307,7 @@ def generate_elliptic_curve_private_key( return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) else: raise UnsupportedAlgorithm( - "Backend object does not support {}.".format(curve.name), + f"Backend object does not support {curve.name}.", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, ) @@ -1445,7 +1445,7 @@ def _elliptic_curve_to_nid(self, curve: ec.EllipticCurve) -> int: curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) if curve_nid == self._lib.NID_undef: raise UnsupportedAlgorithm( - "{} is not a supported elliptic curve".format(curve.name), + f"{curve.name} is not a supported elliptic curve", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, ) return curve_nid @@ -2507,7 +2507,7 @@ def __call__(self, backend: Backend, cipher: CipherAlgorithm, mode: Mode): def _get_xts_cipher(backend: Backend, cipher: AES, mode): - cipher_name = "aes-{}-xts".format(cipher.key_size // 2) + cipher_name = f"aes-{cipher.key_size // 2}-xts" return backend._lib.EVP_get_cipherbyname(cipher_name.encode("ascii")) diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index fd2b6612f046..286583f93255 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -50,9 +50,9 @@ def __init__( evp_cipher = adapter(self._backend, cipher, mode) if evp_cipher == self._backend._ffi.NULL: - msg = "cipher {0.name} ".format(cipher) + msg = f"cipher {cipher.name} " if mode is not None: - msg += "in {0.name} mode ".format(mode) + msg += f"in {mode.name} mode " msg += ( "is not supported by this backend (Your version of OpenSSL " "may be too old. Current version: {}.)" diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 9bc6dd384dca..a2a42c2edba8 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -88,7 +88,7 @@ def _sn_to_elliptic_curve(backend: "Backend", sn: str) -> ec.EllipticCurve: return ec._CURVE_TYPES[sn]() except KeyError: raise UnsupportedAlgorithm( - "{} is not a supported elliptic curve".format(sn), + f"{sn} is not a supported elliptic curve", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, ) diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index e18bab3ff88e..c04cae029e64 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -88,7 +88,7 @@ def _enc_dec_rsa( else: raise UnsupportedAlgorithm( - "{} is not supported by this backend.".format(padding.name), + f"{padding.name} is not supported by this backend.", _Reasons.UNSUPPORTED_PADDING, ) @@ -199,7 +199,7 @@ def _rsa_sig_determine_padding( padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING else: raise UnsupportedAlgorithm( - "{} is not supported by this backend.".format(padding.name), + f"{padding.name} is not supported by this backend.", _Reasons.UNSUPPORTED_PADDING, ) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index a1602164d015..ba9e5f7becbc 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -14,10 +14,12 @@ from cryptography.hazmat.bindings._openssl import ffi, lib from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES -_OpenSSLErrorWithText = typing.NamedTuple( - "_OpenSSLErrorWithText", - [("code", int), ("lib", int), ("reason", int), ("reason_text", bytes)], -) + +class _OpenSSLErrorWithText(typing.NamedTuple): + code: int + lib: int + reason: int + reason_text: bytes class _OpenSSLError: @@ -94,7 +96,7 @@ def _openssl_assert( "OpenSSL try disabling it before reporting a bug. Otherwise " "please file an issue at https://github.com/pyca/cryptography/" "issues with information on how to reproduce " - "this. ({0!r})".format(errors_with_text), + "this. ({!r})".format(errors_with_text), errors_with_text, ) diff --git a/src/cryptography/hazmat/primitives/_serialization.py b/src/cryptography/hazmat/primitives/_serialization.py index fddb4c85eded..aa41f30d2586 100644 --- a/src/cryptography/hazmat/primitives/_serialization.py +++ b/src/cryptography/hazmat/primitives/_serialization.py @@ -71,7 +71,7 @@ class NoEncryption(KeySerializationEncryption): pass -class KeySerializationEncryptionBuilder(object): +class KeySerializationEncryptionBuilder: def __init__( self, format: PrivateFormat, diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index 33de0e551165..debf01e134fa 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -31,7 +31,7 @@ def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: if p.bit_length() < _MIN_MODULUS_SIZE: raise ValueError( - "p (modulus) must be at least {}-bit".format(_MIN_MODULUS_SIZE) + f"p (modulus) must be at least {_MIN_MODULUS_SIZE}-bit" ) self._p = p diff --git a/src/cryptography/hazmat/primitives/ciphers/aead.py b/src/cryptography/hazmat/primitives/ciphers/aead.py index 567301acc705..597bfbf147bd 100644 --- a/src/cryptography/hazmat/primitives/ciphers/aead.py +++ b/src/cryptography/hazmat/primitives/ciphers/aead.py @@ -302,7 +302,7 @@ def _check_params( raise ValueError("Nonce must be between 12 and 15 bytes") -class AESSIV(object): +class AESSIV: _MAX_SIZE = 2**31 - 1 def __init__(self, key: bytes): diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index b7468b1bda75..1fba397feb7a 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -94,9 +94,7 @@ def _check_nonce_length( _Reasons.UNSUPPORTED_CIPHER, ) if len(nonce) * 8 != algorithm.block_size: - raise ValueError( - "Invalid nonce size ({}) for {}.".format(len(nonce), name) - ) + raise ValueError(f"Invalid nonce size ({len(nonce)}) for {name}.") def _check_iv_and_key_length( diff --git a/src/cryptography/hazmat/primitives/kdf/concatkdf.py b/src/cryptography/hazmat/primitives/kdf/concatkdf.py index 94312fec303e..7bbce4ffcdbc 100644 --- a/src/cryptography/hazmat/primitives/kdf/concatkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/concatkdf.py @@ -22,9 +22,7 @@ def _common_args_checks( ) -> None: max_length = algorithm.digest_size * (2**32 - 1) if length > max_length: - raise ValueError( - "Cannot derive keys larger than {} bits.".format(max_length) - ) + raise ValueError(f"Cannot derive keys larger than {max_length} bits.") if otherinfo is not None: utils._check_bytes("otherinfo", otherinfo) @@ -98,9 +96,7 @@ def __init__( self._otherinfo: bytes = otherinfo if otherinfo is not None else b"" if algorithm.block_size is None: - raise TypeError( - "{} is unsupported for ConcatKDF".format(algorithm.name) - ) + raise TypeError(f"{algorithm.name} is unsupported for ConcatKDF") if salt is None: salt = b"\x00" * algorithm.block_size diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py index 2152ae2203ce..7d59a7ef77b9 100644 --- a/src/cryptography/hazmat/primitives/kdf/hkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py @@ -59,7 +59,7 @@ def __init__( if length > max_length: raise ValueError( - "Cannot derive keys larger than {} octets.".format(max_length) + f"Cannot derive keys larger than {max_length} octets." ) self._length = length diff --git a/src/cryptography/hazmat/primitives/kdf/x963kdf.py b/src/cryptography/hazmat/primitives/kdf/x963kdf.py index 651e691aa5c4..4ab64d08b1c5 100644 --- a/src/cryptography/hazmat/primitives/kdf/x963kdf.py +++ b/src/cryptography/hazmat/primitives/kdf/x963kdf.py @@ -25,9 +25,7 @@ def __init__( ): max_len = algorithm.digest_size * (2**32 - 1) if length > max_len: - raise ValueError( - "Cannot derive keys larger than {} bits.".format(max_len) - ) + raise ValueError(f"Cannot derive keys larger than {max_len} bits.") if sharedinfo is not None: utils._check_bytes("sharedinfo", sharedinfo) diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 709e7ca88968..8a97535203a3 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -28,14 +28,14 @@ class CryptographyDeprecationWarning(UserWarning): def _check_bytes(name: str, value: bytes) -> None: if not isinstance(value, bytes): - raise TypeError("{} must be bytes".format(name)) + raise TypeError(f"{name} must be bytes") def _check_byteslike(name: str, value: bytes) -> None: try: memoryview(value) except TypeError: - raise TypeError("{} must be bytes-like".format(name)) + raise TypeError(f"{name} must be bytes-like") def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: @@ -109,7 +109,7 @@ def deprecated( def cached_property(func: typing.Callable) -> property: - cached_name = "_cached_{}".format(func) + cached_name = f"_cached_{func}" sentinel = object() def inner(instance: object): diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 9b436fdf8887..29275b68fb39 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -39,7 +39,7 @@ class AttributeNotFound(Exception): def __init__(self, msg: str, oid: ObjectIdentifier) -> None: - super(AttributeNotFound, self).__init__(msg) + super().__init__(msg) self.oid = oid @@ -99,7 +99,7 @@ def value(self) -> bytes: return self._value def __repr__(self) -> str: - return "".format(self.oid, self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, Attribute): @@ -125,14 +125,14 @@ def __init__( __len__, __iter__, __getitem__ = _make_sequence_methods("_attributes") def __repr__(self) -> str: - return "".format(self._attributes) + return f"" def get_attribute_for_oid(self, oid: ObjectIdentifier) -> Attribute: for attr in self: if attr.oid == oid: return attr - raise AttributeNotFound("No {} attribute was found".format(oid), oid) + raise AttributeNotFound(f"No {oid} attribute was found", oid) class Version(utils.Enum): @@ -142,7 +142,7 @@ class Version(utils.Enum): class InvalidVersion(Exception): def __init__(self, msg: str, parsed_version: int) -> None: - super(InvalidVersion, self).__init__(msg) + super().__init__(msg) self.parsed_version = parsed_version diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 2012515f2bd3..c0053901e6df 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -85,13 +85,13 @@ def getitem_method(self, idx): class DuplicateExtension(Exception): def __init__(self, msg: str, oid: ObjectIdentifier) -> None: - super(DuplicateExtension, self).__init__(msg) + super().__init__(msg) self.oid = oid class ExtensionNotFound(Exception): def __init__(self, msg: str, oid: ObjectIdentifier) -> None: - super(ExtensionNotFound, self).__init__(msg) + super().__init__(msg) self.oid = oid @@ -103,7 +103,7 @@ def public_bytes(self) -> bytes: Serializes the extension type to DER. """ raise NotImplementedError( - "public_bytes is not implemented for extension type {0!r}".format( + "public_bytes is not implemented for extension type {!r}".format( self ) ) @@ -122,7 +122,7 @@ def get_extension_for_oid( if ext.oid == oid: return ext - raise ExtensionNotFound("No {} extension was found".format(oid), oid) + raise ExtensionNotFound(f"No {oid} extension was found", oid) def get_extension_for_class( self, extclass: typing.Type[ExtensionTypeVar] @@ -139,13 +139,13 @@ def get_extension_for_class( return ext raise ExtensionNotFound( - "No {} extension was found".format(extclass), extclass.oid + f"No {extclass} extension was found", extclass.oid ) __len__, __iter__, __getitem__ = _make_sequence_methods("_extensions") def __repr__(self) -> str: - return "".format(self._extensions) + return f"" class CRLNumber(ExtensionType): @@ -167,7 +167,7 @@ def __hash__(self) -> int: return hash(self.crl_number) def __repr__(self) -> str: - return "".format(self.crl_number) + return f"" @property def crl_number(self) -> int: @@ -306,7 +306,7 @@ def key_identifier(self) -> bytes: return self._digest def __repr__(self) -> str: - return "".format(self.digest) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, SubjectKeyIdentifier): @@ -339,7 +339,7 @@ def __init__( __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") def __repr__(self) -> str: - return "".format(self._descriptions) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, AuthorityInformationAccess): @@ -372,7 +372,7 @@ def __init__( __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") def __repr__(self) -> str: - return "".format(self._descriptions) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, SubjectInformationAccess): @@ -496,7 +496,7 @@ def __hash__(self) -> int: return hash(self.crl_number) def __repr__(self) -> str: - return "".format(self) + return f"" def public_bytes(self) -> bytes: return rust_x509.encode_extension_value(self) @@ -524,7 +524,7 @@ def __init__( ) def __repr__(self) -> str: - return "".format(self._distribution_points) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, CRLDistributionPoints): @@ -561,7 +561,7 @@ def __init__( ) def __repr__(self) -> str: - return "".format(self._distribution_points) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, FreshestCRL): @@ -816,7 +816,7 @@ def __init__(self, policies: typing.Iterable["PolicyInformation"]) -> None: __len__, __iter__, __getitem__ = _make_sequence_methods("_policies") def __repr__(self) -> str: - return "".format(self._policies) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, CertificatePolicies): @@ -990,7 +990,7 @@ def __init__(self, usages: typing.Iterable[ObjectIdentifier]) -> None: __len__, __iter__, __getitem__ = _make_sequence_methods("_usages") def __repr__(self) -> str: - return "".format(self._usages) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, ExtendedKeyUsage): @@ -1062,7 +1062,7 @@ def __init__(self, features: typing.Iterable["TLSFeatureType"]) -> None: __len__, __iter__, __getitem__ = _make_sequence_methods("_features") def __repr__(self) -> str: - return "".format(self) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, TLSFeature): @@ -1104,7 +1104,7 @@ def __init__(self, skip_certs: int) -> None: self._skip_certs = skip_certs def __repr__(self) -> str: - return "".format(self) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, InhibitAnyPolicy): @@ -1487,7 +1487,7 @@ def get_values_for_type( return list(objs) def __repr__(self) -> str: - return "".format(self._general_names) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, GeneralNames): @@ -1565,7 +1565,7 @@ def get_values_for_type( return self._general_names.get_values_for_type(type) def __repr__(self) -> str: - return "".format(self._general_names) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, SubjectAlternativeName): @@ -1646,7 +1646,7 @@ def get_values_for_type( return self._general_names.get_values_for_type(type) def __repr__(self) -> str: - return "".format(self._general_names) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, IssuerAlternativeName): @@ -1727,7 +1727,7 @@ def get_values_for_type( return self._general_names.get_values_for_type(type) def __repr__(self) -> str: - return "".format(self._general_names) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, CertificateIssuer): @@ -1752,7 +1752,7 @@ def __init__(self, reason: ReasonFlags) -> None: self._reason = reason def __repr__(self) -> str: - return "".format(self._reason) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, CRLReason): @@ -1872,7 +1872,7 @@ def __init__( ) def __repr__(self) -> str: - return "".format(list(self)) + return f"" def __hash__(self) -> int: return hash(tuple(self._signed_certificate_timestamps)) @@ -1909,7 +1909,7 @@ def __hash__(self) -> int: return hash(self.nonce) def __repr__(self) -> str: - return "".format(self) + return f"" @property def nonce(self) -> bytes: diff --git a/src/cryptography/x509/general_name.py b/src/cryptography/x509/general_name.py index b8b91ed94048..81de0ec77402 100644 --- a/src/cryptography/x509/general_name.py +++ b/src/cryptography/x509/general_name.py @@ -65,7 +65,7 @@ def _init_without_validation(cls, value: str) -> "RFC822Name": return instance def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, RFC822Name): @@ -104,7 +104,7 @@ def _init_without_validation(cls, value: str) -> "DNSName": return instance def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, DNSName): @@ -145,7 +145,7 @@ def _init_without_validation( return instance def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, UniformResourceIdentifier): @@ -169,7 +169,7 @@ def value(self) -> Name: return self._value def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, DirectoryName): @@ -193,7 +193,7 @@ def value(self) -> ObjectIdentifier: return self._value def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, RegisteredID): @@ -239,7 +239,7 @@ def _packed(self) -> bytes: ) def __repr__(self) -> str: - return "".format(self.value) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, IPAddress): diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index acd7c0f1e478..fd0782026392 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -259,7 +259,7 @@ def __len__(self) -> int: return len(self._attributes) def __repr__(self) -> str: - return "".format(self.rfc4514_string()) + return f"" class Name: @@ -354,7 +354,7 @@ def __len__(self) -> int: def __repr__(self) -> str: rdns = ",".join(attr.rfc4514_string() for attr in self._attributes) - return "".format(rdns) + return f"" class _RFC4514NameParser: diff --git a/tests/bench/test_x509.py b/tests/bench/test_x509.py index d689a00a01a9..8a36d3b5fa48 100644 --- a/tests/bench/test_x509.py +++ b/tests/bench/test_x509.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # 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. diff --git a/tests/conftest.py b/tests/conftest.py index a85b41ff9a0f..f077184d0d55 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,8 +18,8 @@ def pytest_configure(config): def pytest_report_header(config): return "\n".join( [ - "OpenSSL: {}".format(openssl_backend.openssl_version_text()), - "FIPS Enabled: {}".format(openssl_backend._fips_enabled), + f"OpenSSL: {openssl_backend.openssl_version_text()}", + f"FIPS Enabled: {openssl_backend._fips_enabled}", ] ) diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index ad5c4eb70a0e..b124582b6a50 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -165,7 +165,7 @@ def assert_no_memory_leaks(s, argv=[]): argv = [ sys.executable, "-c", - "{}\n\n{}".format(s, MEMORY_LEAK_SCRIPT), + f"{s}\n\n{MEMORY_LEAK_SCRIPT}", ] + argv # Shell out to a fresh Python process because OpenSSL does not allow you to # install new memory hooks after the first malloc/free occurs. diff --git a/tests/hazmat/primitives/test_aead.py b/tests/hazmat/primitives/test_aead.py index 98ebae866f03..87200048471a 100644 --- a/tests/hazmat/primitives/test_aead.py +++ b/tests/hazmat/primitives/test_aead.py @@ -616,7 +616,7 @@ def test_buffer_protocol(self, backend): not _aead_supported(AESSIV), reason="Does not support AESSIV", ) -class TestAESSIV(object): +class TestAESSIV: def test_data_too_large(self): key = AESSIV.generate_key(256) aessiv = AESSIV(key) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 5798aefc6f56..5322f8f4afea 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -274,7 +274,7 @@ def test_buffer_protocol_alternate_modes(mode, backend): data = bytearray(b"sixteen_byte_msg") key = algorithms.AES(bytearray(os.urandom(32))) if not backend.cipher_supported(key, mode): - pytest.skip("AES in {} mode not supported".format(mode.name)) + pytest.skip(f"AES in {mode.name} mode not supported") cipher = base.Cipher(key, mode, backend) enc = cipher.encryptor() ct = enc.update(data) + enc.finalize() @@ -298,7 +298,7 @@ def test_buffer_protocol_alternate_modes(mode, backend): def test_alternate_aes_classes(mode, alg_cls, backend): alg = alg_cls(b"0" * (alg_cls.key_size // 8)) if not backend.cipher_supported(alg, mode): - pytest.skip("AES in {} mode not supported".format(mode.name)) + pytest.skip(f"AES in {mode.name} mode not supported") data = bytearray(b"sixteen_byte_msg") cipher = base.Cipher(alg, mode, backend) enc = cipher.encryptor() diff --git a/tests/hazmat/primitives/test_pkcs12.py b/tests/hazmat/primitives/test_pkcs12.py index 9b6e6740870b..f44fdd115af3 100644 --- a/tests/hazmat/primitives/test_pkcs12.py +++ b/tests/hazmat/primitives/test_pkcs12.py @@ -186,9 +186,9 @@ def test_buffer_protocol(self, backend): (None, b"name2", None, "name-2-no-pwd.p12", None), (None, None, b"name3", "name-3-no-pwd.p12", None), ( - "☺".encode("utf-8"), - "ä".encode("utf-8"), - "ç".encode("utf-8"), + "☺".encode(), + "ä".encode(), + "ç".encode(), "name-unicode-no-pwd.p12", None, ), @@ -199,9 +199,9 @@ def test_buffer_protocol(self, backend): (None, b"name2", None, "name-2-pwd.p12", b"password"), (None, None, b"name3", "name-3-pwd.p12", b"password"), ( - "☺".encode("utf-8"), - "ä".encode("utf-8"), - "ç".encode("utf-8"), + "☺".encode(), + "ä".encode(), + "ç".encode(), "name-unicode-pwd.p12", b"password", ), @@ -240,8 +240,8 @@ def test_load_object( (b"name2", None, "no-cert-name-2-no-pwd.p12", None), (None, b"name3", "no-cert-name-3-no-pwd.p12", None), ( - "☹".encode("utf-8"), - "ï".encode("utf-8"), + "☹".encode(), + "ï".encode(), "no-cert-name-unicode-no-pwd.p12", None, ), @@ -250,8 +250,8 @@ def test_load_object( (b"name2", None, "no-cert-name-2-pwd.p12", b"password"), (None, b"name3", "no-cert-name-3-pwd.p12", b"password"), ( - "☹".encode("utf-8"), - "ï".encode("utf-8"), + "☹".encode(), + "ï".encode(), "no-cert-name-unicode-pwd.p12", b"password", ), @@ -794,12 +794,14 @@ def test_certificate_hash(self, backend): def test_certificate_repr(self, backend): cert = _load_cert(backend, os.path.join("x509", "cryptography.io.pem")) - assert repr( - PKCS12Certificate(cert, None) - ) == "".format(repr(cert)) - assert repr( - PKCS12Certificate(cert, b"a") - ) == "".format(repr(cert)) + assert ( + repr(PKCS12Certificate(cert, None)) + == f"" + ) + assert ( + repr(PKCS12Certificate(cert, b"a")) + == f"" + ) def test_key_and_certificates_constructor(self, backend): with pytest.raises(TypeError): @@ -944,9 +946,9 @@ def test_key_and_certificates_repr(self, backend): [PKCS12Certificate(cert2, b"name2")], ) ) - == ", additional_certs=[])>".format( + == ", additional_certs=[])>".format( key, cert, cert2, diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 31ae8b047c85..a3fb50302082 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -69,9 +69,7 @@ def _check_fips_key_length(backend, private_key): backend._fips_enabled and private_key.key_size < backend._fips_rsa_min_key_size ): - pytest.skip( - "Key size not FIPS compliant: {}".format(private_key.key_size) - ) + pytest.skip(f"Key size not FIPS compliant: {private_key.key_size}") def _check_rsa_private_numbers_if_serializable(key): @@ -115,7 +113,7 @@ def _build_oaep_sha2_vectors(): load_vectors_from_file( os.path.join( base_path, - "oaep-{}-{}.txt".format(mgf1alg.name, oaepalg.name), + f"oaep-{mgf1alg.name}-{oaepalg.name}.txt", ), load_pkcs1_vectors, ) @@ -134,9 +132,7 @@ def _skip_pss_hash_algorithm_unsupported(backend, hash_alg): mgf=padding.MGF1(hash_alg), salt_length=padding.PSS.MAX_LENGTH ) ): - pytest.skip( - "Does not support {} in MGF1 using PSS.".format(hash_alg.name) - ) + pytest.skip(f"Does not support {hash_alg.name} in MGF1 using PSS.") def test_skip_pss_hash_algorithm_unsupported(backend): @@ -179,11 +175,9 @@ class TestRSA: def test_generate_rsa_keys(self, backend, public_exponent, key_size): if backend._fips_enabled: if key_size < backend._fips_rsa_min_key_size: - pytest.skip("Key size not FIPS compliant: {}".format(key_size)) + pytest.skip(f"Key size not FIPS compliant: {key_size}") if public_exponent < backend._fips_rsa_min_public_exponent: - pytest.skip( - "Exponent not FIPS compliant: {}".format(public_exponent) - ) + pytest.skip(f"Exponent not FIPS compliant: {public_exponent}") skey = rsa.generate_private_key(public_exponent, key_size, backend) assert skey.key_size == key_size diff --git a/tests/utils.py b/tests/utils.py index 405cfbc783d1..dd3238fa97f1 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -66,7 +66,7 @@ def load_nist_vectors(vector_data): continue # Build our data using a simple Key = Value format - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) # Some tests (PBKDF2) contain \0, which should be interpreted as a # null character rather than literal. @@ -107,7 +107,7 @@ def load_cryptrec_vectors(vector_data): {"key": key, "plaintext": pt, "ciphertext": ct} ) else: - raise ValueError("Invalid line in file '{}'".format(line)) + raise ValueError(f"Invalid line in file '{line}'") return cryptrec_list @@ -300,7 +300,7 @@ def load_rsa_nist_vectors(vector_data): continue # Build our data using a simple Key = Value format - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) if name == "n": n = int(value, 16) @@ -396,7 +396,7 @@ def load_fips_dsa_sig_vectors(vector_data): if line.startswith("[mod"): continue - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) if name == "P": vectors.append( @@ -771,7 +771,7 @@ def load_nist_kbkdf_vectors(vector_data): if line.startswith("[") and line.endswith("]"): tag_data = line[1:-1] - name, value = [c.strip() for c in tag_data.split("=")] + name, value = (c.strip() for c in tag_data.split("=")) if value.endswith("_BITS"): value = int(value.split("_")[0]) tag.update({name.lower(): value}) @@ -783,10 +783,10 @@ def load_nist_kbkdf_vectors(vector_data): test_data.update(tag) vectors.append(test_data) elif line.startswith(("L", "DataBeforeCtrLen", "DataAfterCtrLen")): - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) test_data[name.lower()] = int(value) else: - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) test_data[name.lower()] = value.encode("ascii") return vectors @@ -828,7 +828,7 @@ def load_nist_ccm_vectors(vector_data): # Some of the CCM vectors have global values for this. They are always # at the top before the first section header (see: VADT, VNT, VPT) if line.startswith(("Alen", "Plen", "Nlen", "Tlen")): - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) global_data[name.lower()] = int(value) continue @@ -839,11 +839,11 @@ def load_nist_ccm_vectors(vector_data): section = line[1:-1] items = [c.strip() for c in section.split(",")] for item in items: - name, value = [c.strip() for c in item.split("=")] + name, value = (c.strip() for c in item.split("=")) section_data[name.lower()] = int(value) continue - name, value = [c.strip() for c in line.split("=")] + name, value = (c.strip() for c in line.split("=")) if name.lower() in ("key", "nonce") and new_section: section_data[name.lower()] = value.encode("ascii") diff --git a/tests/wycheproof/test_ecdsa.py b/tests/wycheproof/test_ecdsa.py index ffdfcc461342..e2c752dce6e1 100644 --- a/tests/wycheproof/test_ecdsa.py +++ b/tests/wycheproof/test_ecdsa.py @@ -72,7 +72,7 @@ def test_ecdsa_signature(backend, wycheproof): digest = _DIGESTS[wycheproof.testgroup["sha"]] if not backend.hash_supported(digest): - pytest.skip("Hash {} not supported".format(digest)) + pytest.skip(f"Hash {digest} not supported") if wycheproof.valid or ( wycheproof.acceptable and not wycheproof.has_flag("MissingZero") diff --git a/tests/wycheproof/test_hmac.py b/tests/wycheproof/test_hmac.py index 49fe772cb67a..4a42dc1eda5f 100644 --- a/tests/wycheproof/test_hmac.py +++ b/tests/wycheproof/test_hmac.py @@ -41,7 +41,7 @@ def test_hmac(backend, wycheproof): if wycheproof.testgroup["tagSize"] // 8 != hash_algo.digest_size: pytest.skip("Truncated HMAC not supported") if not backend.hmac_supported(hash_algo): - pytest.skip("Hash {} not supported".format(hash_algo.name)) + pytest.skip(f"Hash {hash_algo.name} not supported") h = hmac.HMAC( key=binascii.unhexlify(wycheproof.testcase["key"]), diff --git a/tests/x509/test_name.py b/tests/x509/test_name.py index de47a7a1af86..4c9ccc3b791c 100644 --- a/tests/x509/test_name.py +++ b/tests/x509/test_name.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # 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. diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index d641335210e7..c76c043b7b22 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # 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. From 52a6a19f19f3ee0d2697a9c69b8017580ed66e18 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 19 Jan 2023 19:53:51 -0500 Subject: [PATCH 124/827] Bump BoringSSL and/or OpenSSL in CI (#8105) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28faffc7f34c..1eb8eb8033ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 19, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "45b8d7bbd771cbf7e116db2ba1f1cc7af959497e"}} - # Latest commit on the OpenSSL master branch, as of Jan 18, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "235ef96049dbe337a3c3c5d419dacbb5a81df1b3"}} + # Latest commit on the BoringSSL master branch, as of Jan 20, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "029d0e77fb64625469cc02c8df26767c72081dfd"}} + # Latest commit on the OpenSSL master branch, as of Jan 20, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "69d6ecb7c320bafe0d30a88949eb22e19704221a"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From c0998242e1fb57510379cf51a45b371771450754 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Jan 2023 12:28:09 +0000 Subject: [PATCH 125/827] Bump dtolnay/rust-toolchain (#8106) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from e645b0cf01249a964ec099494d38d2da0f0b349f to 22cb70465de2ebc761c76f91046abd5a6986040f. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/e645b0cf01249a964ec099494d38d2da0f0b349f...22cb70465de2ebc761c76f91046abd5a6986040f) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1eb8eb8033ca..f5f285dfbe1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -237,7 +237,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f + - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f with: toolchain: ${{ matrix.RUST }} - uses: actions/checkout@v3.3.0 @@ -289,7 +289,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f + - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f with: toolchain: ${{ matrix.RUST }} components: llvm-tools-preview diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index dc658e7bac85..de45563a25b8 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -204,7 +204,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f + - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -276,7 +276,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f + - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From bc70840dd25b1d32a21063004acdd3e05dc068ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Jan 2023 12:35:54 +0000 Subject: [PATCH 126/827] Bump ruff from 0.0.226 to 0.0.227 (#8109) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.226 to 0.0.227. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.226...v0.0.227) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 50854aeec3eb..ea16625452f0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ rfc3986==2.0.0 # via twine rich==13.1.0 # via twine -ruff==0.0.226 +ruff==0.0.227 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 59cf91678e8d1017e8e6a08b45c6a3872e9417b0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Jan 2023 07:55:33 -0500 Subject: [PATCH 127/827] Add comment to CI on another potential future MSRV (#8111) --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5f285dfbe1b..8fb217519652 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,6 +213,7 @@ jobs: # Potential future MSRVs # 1.51 - const generics (for rust-asn1) # 1.56 - new versions of once_cell and bumpalo + # 1.60 - new version of cxx name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: From c219d332bbd279cf42450076814f4363177b86e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Jan 2023 13:00:17 +0000 Subject: [PATCH 128/827] Bump rich from 13.1.0 to 13.2.0 (#8110) Bumps [rich](https://github.com/Textualize/rich) from 13.1.0 to 13.2.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.1.0...v13.2.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ea16625452f0..841c77249c44 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -157,7 +157,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.1.0 +rich==13.2.0 # via twine ruff==0.0.227 # via cryptography (setup.cfg) From 321f5767dfcfa4b8ca9038c1fc40e3bfdf553028 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Jan 2023 15:33:51 -0500 Subject: [PATCH 129/827] Re-compile ci-constraints-requirements.txt (#8112) dependabot doesn't pin new transitive deps --- ci-constraints-requirements.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 841c77249c44..d693c8f9c387 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -33,8 +33,6 @@ click==8.1.3 # via black colorama==0.4.6; python_version >= "3.7" # via tox -commonmark==0.9.1 - # via rich coverage==7.0.5; python_version >= "3.7" # via pytest-cov distlib==0.3.6 @@ -74,8 +72,12 @@ jinja2==3.1.2 # via sphinx keyring==23.13.1 # via twine +markdown-it-py==2.1.0 + # via rich markupsafe==2.1.2 # via jinja2 +mdurl==0.1.2 + # via markdown-it-py more-itertools==9.0.0 # via jaraco-classes mypy==0.991 From 5a1d53b127e971c3f8477a194a96647129572f47 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Jan 2023 19:13:48 -0500 Subject: [PATCH 130/827] Re-enable sparse registry now that its stabilizing (#8113) --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fb217519652..1b22c36bfd9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true +env: + REGISTRIES_CRATES_IO_PROTOCOL: sparse + jobs: linux: runs-on: ubuntu-latest From 307e1b362d1612e9158f2e6fc9a0315aa5f9f4ec Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 21 Jan 2023 00:23:23 +0000 Subject: [PATCH 131/827] Bump BoringSSL and/or OpenSSL in CI (#8114) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b22c36bfd9f..64edfd4cef82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,10 +43,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 20, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "029d0e77fb64625469cc02c8df26767c72081dfd"}} - # Latest commit on the OpenSSL master branch, as of Jan 20, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "69d6ecb7c320bafe0d30a88949eb22e19704221a"}} + # Latest commit on the BoringSSL master branch, as of Jan 21, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ae1546b6f3bf1ad7eb24b491c914eb202b5547d3"}} + # Latest commit on the OpenSSL master branch, as of Jan 21, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c3bd630df0c3630c66155fb8c4baf54810d24695"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 0e8f558e521d94df4a05e0a90f1e6a1c2a10780a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 22 Jan 2023 00:01:29 +0800 Subject: [PATCH 132/827] see if python 3.10 works with our downstreams (#7958) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64edfd4cef82..a3316ccc89a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -493,7 +493,7 @@ jobs: - mitmproxy - scapy PYTHON: - - 3.9 + - '3.10' name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: From d0090ff069cebb3fb6a3194ec8012703ce0e558f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 18:31:41 +0000 Subject: [PATCH 133/827] Bump dtolnay/rust-toolchain (#8117) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from 22cb70465de2ebc761c76f91046abd5a6986040f to ce8f65846d7180d2ce63b1e74483d981800b9e22. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/22cb70465de2ebc761c76f91046abd5a6986040f...ce8f65846d7180d2ce63b1e74483d981800b9e22) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3316ccc89a5..527b92cae3ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -241,7 +241,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f + - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 with: toolchain: ${{ matrix.RUST }} - uses: actions/checkout@v3.3.0 @@ -293,7 +293,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f + - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 with: toolchain: ${{ matrix.RUST }} components: llvm-tools-preview diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index de45563a25b8..f375b332ff0b 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -204,7 +204,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f + - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -276,7 +276,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@22cb70465de2ebc761c76f91046abd5a6986040f + - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From a2028cd205b48a79b58ed9f37f0b3714d2392b82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 18:41:10 +0000 Subject: [PATCH 134/827] Bump hypothesis from 6.62.1 to 6.63.0 (#8118) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.62.1 to 6.63.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.62.1...hypothesis-python-6.63.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d693c8f9c387..d875fe02f216 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.62.1; python_version >= "3.7" +hypothesis==6.63.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 7d934694c08bdd214f7dacad0c0906801393506c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 22 Jan 2023 16:00:43 -0500 Subject: [PATCH 135/827] Style fixes for latest ruff (#8120) (Also objectively this is better) --- tests/hazmat/primitives/test_cast5.py | 8 ++++---- tests/hazmat/primitives/test_idea.py | 8 ++++---- tests/hazmat/primitives/test_seed.py | 8 ++++---- tests/hazmat/primitives/test_sm4.py | 10 +++++----- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py index a6f186a3c216..327a463b60e5 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -26,7 +26,7 @@ class TestCAST5ModeECB: os.path.join("ciphers", "CAST5"), ["cast5-ecb.txt"], lambda key, **kwargs: algorithms._CAST5Internal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda **kwargs: modes.ECB(), ) @@ -44,7 +44,7 @@ class TestCAST5ModeCBC: os.path.join("ciphers", "CAST5"), ["cast5-cbc.txt"], lambda key, **kwargs: algorithms._CAST5Internal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) @@ -62,7 +62,7 @@ class TestCAST5ModeOFB: os.path.join("ciphers", "CAST5"), ["cast5-ofb.txt"], lambda key, **kwargs: algorithms._CAST5Internal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) @@ -80,7 +80,7 @@ class TestCAST5ModeCFB: os.path.join("ciphers", "CAST5"), ["cast5-cfb.txt"], lambda key, **kwargs: algorithms._CAST5Internal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) diff --git a/tests/hazmat/primitives/test_idea.py b/tests/hazmat/primitives/test_idea.py index 9817d5444f9c..6631a93f91cc 100644 --- a/tests/hazmat/primitives/test_idea.py +++ b/tests/hazmat/primitives/test_idea.py @@ -26,7 +26,7 @@ class TestIDEAModeECB: os.path.join("ciphers", "IDEA"), ["idea-ecb.txt"], lambda key, **kwargs: algorithms._IDEAInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda **kwargs: modes.ECB(), ) @@ -44,7 +44,7 @@ class TestIDEAModeCBC: os.path.join("ciphers", "IDEA"), ["idea-cbc.txt"], lambda key, **kwargs: algorithms._IDEAInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) @@ -62,7 +62,7 @@ class TestIDEAModeOFB: os.path.join("ciphers", "IDEA"), ["idea-ofb.txt"], lambda key, **kwargs: algorithms._IDEAInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) @@ -80,7 +80,7 @@ class TestIDEAModeCFB: os.path.join("ciphers", "IDEA"), ["idea-cfb.txt"], lambda key, **kwargs: algorithms._IDEAInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) diff --git a/tests/hazmat/primitives/test_seed.py b/tests/hazmat/primitives/test_seed.py index 9f68bc3fb10d..f36ce1e4ecea 100644 --- a/tests/hazmat/primitives/test_seed.py +++ b/tests/hazmat/primitives/test_seed.py @@ -26,7 +26,7 @@ class TestSEEDModeECB: os.path.join("ciphers", "SEED"), ["rfc-4269.txt"], lambda key, **kwargs: algorithms._SEEDInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda **kwargs: modes.ECB(), ) @@ -44,7 +44,7 @@ class TestSEEDModeCBC: os.path.join("ciphers", "SEED"), ["rfc-4196.txt"], lambda key, **kwargs: algorithms._SEEDInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) @@ -62,7 +62,7 @@ class TestSEEDModeOFB: os.path.join("ciphers", "SEED"), ["seed-ofb.txt"], lambda key, **kwargs: algorithms._SEEDInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) @@ -80,7 +80,7 @@ class TestSEEDModeCFB: os.path.join("ciphers", "SEED"), ["seed-cfb.txt"], lambda key, **kwargs: algorithms._SEEDInternal( - binascii.unhexlify((key)) + binascii.unhexlify(key) ), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) diff --git a/tests/hazmat/primitives/test_sm4.py b/tests/hazmat/primitives/test_sm4.py index 13d9b5051c42..53893eecedff 100644 --- a/tests/hazmat/primitives/test_sm4.py +++ b/tests/hazmat/primitives/test_sm4.py @@ -24,7 +24,7 @@ class TestSM4ModeECB: load_nist_vectors, os.path.join("ciphers", "SM4"), ["draft-ribose-cfrg-sm4-10-ecb.txt"], - lambda key, **kwargs: algorithms.SM4(binascii.unhexlify((key))), + lambda key, **kwargs: algorithms.SM4(binascii.unhexlify(key)), lambda **kwargs: modes.ECB(), ) @@ -40,7 +40,7 @@ class TestSM4ModeCBC: load_nist_vectors, os.path.join("ciphers", "SM4"), ["draft-ribose-cfrg-sm4-10-cbc.txt"], - lambda key, **kwargs: algorithms.SM4(binascii.unhexlify((key))), + lambda key, **kwargs: algorithms.SM4(binascii.unhexlify(key)), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) @@ -56,7 +56,7 @@ class TestSM4ModeOFB: load_nist_vectors, os.path.join("ciphers", "SM4"), ["draft-ribose-cfrg-sm4-10-ofb.txt"], - lambda key, **kwargs: algorithms.SM4(binascii.unhexlify((key))), + lambda key, **kwargs: algorithms.SM4(binascii.unhexlify(key)), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) @@ -72,7 +72,7 @@ class TestSM4ModeCFB: load_nist_vectors, os.path.join("ciphers", "SM4"), ["draft-ribose-cfrg-sm4-10-cfb.txt"], - lambda key, **kwargs: algorithms.SM4(binascii.unhexlify((key))), + lambda key, **kwargs: algorithms.SM4(binascii.unhexlify(key)), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) @@ -88,6 +88,6 @@ class TestSM4ModeCTR: load_nist_vectors, os.path.join("ciphers", "SM4"), ["draft-ribose-cfrg-sm4-10-ctr.txt"], - lambda key, **kwargs: algorithms.SM4(binascii.unhexlify((key))), + lambda key, **kwargs: algorithms.SM4(binascii.unhexlify(key)), lambda iv, **kwargs: modes.CTR(binascii.unhexlify(iv)), ) From fcaca61e7e64ce9848a5eb356cabe272c9ef3051 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 21:18:58 +0000 Subject: [PATCH 136/827] Bump ruff from 0.0.227 to 0.0.230 (#8121) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.227 to 0.0.230. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.227...v0.0.230) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d875fe02f216..0a828c7cc8e0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.2.0 # via twine -ruff==0.0.227 +ruff==0.0.230 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 07a94effea37a3c6650881314d547d4e427f414d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:32:33 +0000 Subject: [PATCH 137/827] Bump sphinxcontrib-applehelp from 1.0.3 to 1.0.4 (#8123) Bumps [sphinxcontrib-applehelp](https://github.com/sphinx-doc/sphinxcontrib-applehelp) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/sphinx-doc/sphinxcontrib-applehelp/releases) - [Changelog](https://github.com/sphinx-doc/sphinxcontrib-applehelp/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinxcontrib-applehelp/compare/1.0.3...1.0.4) --- updated-dependencies: - dependency-name: sphinxcontrib-applehelp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 0a828c7cc8e0..d7950220499f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -176,7 +176,7 @@ sphinx==5.3.0 # sphinxcontrib-spelling sphinx-rtd-theme==1.1.1 # via cryptography (setup.cfg) -sphinxcontrib-applehelp==1.0.3 +sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx From 3f66bc732a219802f3031f6a47b338d1e1763698 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:40:04 +0000 Subject: [PATCH 138/827] Bump hypothesis from 6.63.0 to 6.64.0 (#8124) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.63.0 to 6.64.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.63.0...hypothesis-python-6.64.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d7950220499f..4aa1d0111d15 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.63.0; python_version >= "3.7" +hypothesis==6.64.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 6c24c6747a5df06b84ca6846c0ab216eb165c0e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:46:32 +0000 Subject: [PATCH 139/827] Bump cachetools from 5.2.1 to 5.3.0 (#8125) Bumps [cachetools](https://github.com/tkem/cachetools) from 5.2.1 to 5.3.0. - [Release notes](https://github.com/tkem/cachetools/releases) - [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tkem/cachetools/compare/v5.2.1...v5.3.0) --- updated-dependencies: - dependency-name: cachetools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4aa1d0111d15..d30962c41121 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -19,7 +19,7 @@ bleach==5.0.1 # via readme-renderer build==0.10.0 # via check-manifest -cachetools==5.2.1 +cachetools==5.3.0 # via tox certifi==2022.12.7 # via requests From 1d2c5374b3417c7a5c7e0c3b670fc882156e091f Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Jan 2023 14:59:48 -0500 Subject: [PATCH 140/827] Remove repeated hex conversion of tag in AES GCM tests (#8126) --- tests/hazmat/primitives/utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index aac7296e641d..6e2ce41dc5ec 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -103,10 +103,11 @@ def aead_test(backend, cipher_factory, mode_factory, params): # hex encoded. pytest.skip("Non-96-bit IVs unsupported in FIPS mode.") + tag = binascii.unhexlify(params["tag"]) mode = mode_factory( binascii.unhexlify(params["iv"]), - binascii.unhexlify(params["tag"]), - len(binascii.unhexlify(params["tag"])), + tag, + len(tag), ) assert isinstance(mode, GCM) if params.get("pt") is not None: @@ -134,14 +135,13 @@ def aead_test(backend, cipher_factory, mode_factory, params): encryptor.authenticate_additional_data(aad) actual_ciphertext = encryptor.update(plaintext) actual_ciphertext += encryptor.finalize() - tag_len = len(binascii.unhexlify(params["tag"])) - assert binascii.hexlify(encryptor.tag[:tag_len]) == params["tag"] + assert encryptor.tag[: len(tag)] == tag cipher = Cipher( cipher_factory(binascii.unhexlify(params["key"])), mode_factory( binascii.unhexlify(params["iv"]), - binascii.unhexlify(params["tag"]), - min_tag_length=tag_len, + tag, + min_tag_length=len(tag), ), backend, ) From c4978655a6b13a4eb49e0c6a8cf2a33bc9a0af68 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 08:24:52 +0800 Subject: [PATCH 141/827] Bump BoringSSL and/or OpenSSL in CI (#8128) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 527b92cae3ed..a8ea836b878b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,10 +43,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 21, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ae1546b6f3bf1ad7eb24b491c914eb202b5547d3"}} - # Latest commit on the OpenSSL master branch, as of Jan 21, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c3bd630df0c3630c66155fb8c4baf54810d24695"}} + # Latest commit on the BoringSSL master branch, as of Jan 24, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "0d5b6086143d19f86cc5d01b8944a1c13f99be24"}} + # Latest commit on the OpenSSL master branch, as of Jan 24, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "61222b95ff20f6a7bb20668e43b657561efdb922"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 818f1586fcc28035a4c4dca820e56f4e4895acf0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Jan 2023 19:00:18 -0700 Subject: [PATCH 142/827] try running downstream tests with 3.11 (#8115) --- .github/downstream.d/aws-encryption-sdk.sh | 2 +- .github/downstream.d/dynamodb-encryption-sdk.sh | 2 +- .github/workflows/ci.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/downstream.d/aws-encryption-sdk.sh b/.github/downstream.d/aws-encryption-sdk.sh index 276d47eee559..4992282cbaad 100755 --- a/.github/downstream.d/aws-encryption-sdk.sh +++ b/.github/downstream.d/aws-encryption-sdk.sh @@ -6,7 +6,7 @@ case "${1}" in cd aws-encryption-sdk-python git rev-parse HEAD pip install -e . - pip install -r test/upstream-requirements-py37.txt + pip install -r test/upstream-requirements-py311.txt ;; run) cd aws-encryption-sdk-python diff --git a/.github/downstream.d/dynamodb-encryption-sdk.sh b/.github/downstream.d/dynamodb-encryption-sdk.sh index 60bbecf36afd..e41288d44083 100755 --- a/.github/downstream.d/dynamodb-encryption-sdk.sh +++ b/.github/downstream.d/dynamodb-encryption-sdk.sh @@ -6,7 +6,7 @@ case "${1}" in cd aws-dynamodb-encryption-python git rev-parse HEAD pip install -e . - pip install -r test/upstream-requirements-py37.txt + pip install -r test/upstream-requirements-py311.txt ;; run) cd aws-dynamodb-encryption-python diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8ea836b878b..188af76acbf6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -493,7 +493,7 @@ jobs: - mitmproxy - scapy PYTHON: - - '3.10' + - '3.11' name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: From f4eda4641950c2017c30d779ac687b09b30208d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 12:28:46 +0000 Subject: [PATCH 143/827] Bump ruff from 0.0.230 to 0.0.231 (#8129) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.230 to 0.0.231. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.230...v0.0.231) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d30962c41121..5728093de817 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.2.0 # via twine -ruff==0.0.230 +ruff==0.0.231 # via cryptography (setup.cfg) six==1.16.0 # via bleach From fc45ba3f324abc8f8e634f3bae809aadd525a1a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 12:39:21 +0000 Subject: [PATCH 144/827] Bump hypothesis from 6.64.0 to 6.65.0 (#8131) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.64.0 to 6.65.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.64.0...hypothesis-python-6.65.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5728093de817..67c08d883934 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.64.0; python_version >= "3.7" +hypothesis==6.65.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 15173766a75ff2d3b64df4cf6d5d5603752fa2bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 12:50:16 +0000 Subject: [PATCH 145/827] Bump bleach from 5.0.1 to 6.0.0 (#8130) Bumps [bleach](https://github.com/mozilla/bleach) from 5.0.1 to 6.0.0. - [Release notes](https://github.com/mozilla/bleach/releases) - [Changelog](https://github.com/mozilla/bleach/blob/main/CHANGES) - [Commits](https://github.com/mozilla/bleach/compare/v5.0.1...v6.0.0) --- updated-dependencies: - dependency-name: bleach dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 67c08d883934..cccedc4bb45b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -15,7 +15,7 @@ babel==2.11.0 # via sphinx black==22.12.0 # via cryptography (setup.cfg) -bleach==5.0.1 +bleach==6.0.0 # via readme-renderer build==0.10.0 # via check-manifest From 3157dc0bd3aebdb6c9dc766a020ec96761c9a763 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 25 Jan 2023 00:22:52 +0000 Subject: [PATCH 146/827] Bump BoringSSL and/or OpenSSL in CI (#8132) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 188af76acbf6..baaac6512d0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,8 +45,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Jan 24, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "0d5b6086143d19f86cc5d01b8944a1c13f99be24"}} - # Latest commit on the OpenSSL master branch, as of Jan 24, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "61222b95ff20f6a7bb20668e43b657561efdb922"}} + # Latest commit on the OpenSSL master branch, as of Jan 25, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e95d6e1eec2f080713aa91c12e411cea4cffee65"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From be3d85ef25e8647862ccb74cd7ce2eb58aa23766 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jan 2023 05:36:01 -0800 Subject: [PATCH 147/827] Bump pathspec from 0.10.3 to 0.11.0 (#8133) Bumps [pathspec](https://github.com/cpburnz/python-pathspec) from 0.10.3 to 0.11.0. - [Release notes](https://github.com/cpburnz/python-pathspec/releases) - [Changelog](https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst) - [Commits](https://github.com/cpburnz/python-pathspec/compare/v0.10.3...v0.11.0) --- updated-dependencies: - dependency-name: pathspec dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index cccedc4bb45b..1bdc0b897e3d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -93,7 +93,7 @@ packaging==23.0; python_version >= "3.7" # pytest # sphinx # tox -pathspec==0.10.3 +pathspec==0.11.0 # via black pkginfo==1.9.6 # via twine From f7c50670bfd6cb14f0010d2bef1b2a6d7f3aea18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jan 2023 05:38:11 -0800 Subject: [PATCH 148/827] Bump coverage from 7.0.5 to 7.1.0 (#8134) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.5 to 7.1.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.5...7.1.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1bdc0b897e3d..7cb6411caccb 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -33,7 +33,7 @@ click==8.1.3 # via black colorama==0.4.6; python_version >= "3.7" # via tox -coverage==7.0.5; python_version >= "3.7" +coverage==7.1.0; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 0dea1bc83b0e9be87508e6aa2849901d697dec55 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 00:22:37 +0000 Subject: [PATCH 149/827] Bump BoringSSL and/or OpenSSL in CI (#8136) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index baaac6512d0c..b78364fe12b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,10 +43,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 24, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "0d5b6086143d19f86cc5d01b8944a1c13f99be24"}} - # Latest commit on the OpenSSL master branch, as of Jan 25, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e95d6e1eec2f080713aa91c12e411cea4cffee65"}} + # Latest commit on the BoringSSL master branch, as of Jan 26, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "97873cd1a59b97ced00907e274afaff75edf4a57"}} + # Latest commit on the OpenSSL master branch, as of Jan 26, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "114d99b46bfb212ffc510865df317ca2c1542623"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 1f01225c82e9e496193de95ba4de65a714cb4570 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 06:35:03 -0600 Subject: [PATCH 150/827] Bump ruff from 0.0.231 to 0.0.235 (#8138) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.231 to 0.0.235. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.231...v0.0.235) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7cb6411caccb..a2dbc2dc6709 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.2.0 # via twine -ruff==0.0.231 +ruff==0.0.235 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 1b35f6d0fde034ade593221729fb621ac8038ce6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 06:44:46 -0600 Subject: [PATCH 151/827] Bump tox from 4.3.5 to 4.4.2 (#8137) Bumps [tox](https://github.com/tox-dev/tox) from 4.3.5 to 4.4.2. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.3.5...4.4.2) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a2dbc2dc6709..48666e62d950 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -201,7 +201,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.3.5; python_version >= "3.7" +tox==4.4.2; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From ee5737f8a7d0089076d86b6bbc8d50ba50cd4dad Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 17:35:52 -0800 Subject: [PATCH 152/827] Bump BoringSSL and/or OpenSSL in CI (#8139) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b78364fe12b6..8a1436a49d16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,10 +43,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 26, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "97873cd1a59b97ced00907e274afaff75edf4a57"}} - # Latest commit on the OpenSSL master branch, as of Jan 26, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "114d99b46bfb212ffc510865df317ca2c1542623"}} + # Latest commit on the BoringSSL master branch, as of Jan 27, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "cbccae538c6f03cdf7b9fa263fd1c37724d7a769"}} + # Latest commit on the OpenSSL master branch, as of Jan 27, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6e3b1c81736b1829584e3f40c2d00040fe1aa881"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 43a84720995b2e698eb4ae40329dfc2c5d811f5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Jan 2023 12:17:23 +0000 Subject: [PATCH 153/827] Bump tibdex/github-app-token from 1.7.0 to 1.8.0 (#8141) Bumps [tibdex/github-app-token](https://github.com/tibdex/github-app-token) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/tibdex/github-app-token/releases) - [Commits](https://github.com/tibdex/github-app-token/compare/021a2405c7f990db57f5eae5397423dcc554159c...b62528385c34dbc9f38e5f4225ac829252d1ea92) --- updated-dependencies: - dependency-name: tibdex/github-app-token dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/boring-open-version-bump.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index c438ec2fc34a..87ac8501ca92 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -51,7 +51,7 @@ jobs: sed -E -i "s/TYPE: \"openssl\", VERSION: \"[0-9a-f]{40}\"/TYPE: \"openssl\", VERSION: \"${{ steps.check-sha-openssl.outputs.COMMIT_SHA }}\"/" .github/workflows/ci.yml git status if: steps.check-sha-openssl.outputs.COMMIT_SHA - - uses: tibdex/github-app-token@021a2405c7f990db57f5eae5397423dcc554159c + - uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 id: generate-token with: app_id: ${{ secrets.BORINGBOT_APP_ID }} From 8e641771c6a817508835b80ce97213007758959a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Jan 2023 12:36:02 +0000 Subject: [PATCH 154/827] Bump hypothesis from 6.65.0 to 6.65.2 (#8144) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.65.0 to 6.65.2. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.65.0...hypothesis-python-6.65.2) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 48666e62d950..829ca57dfabf 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.65.0; python_version >= "3.7" +hypothesis==6.65.2; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 7732bd30419679cb033bfac7b5cb6e810b508b31 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 27 Jan 2023 04:47:41 -0800 Subject: [PATCH 155/827] fix env var for cargo sparse registry (#8140) * fix env var for cargo sparse registry see https://github.com/rust-lang/cargo/pull/11632 * Update ci.yml --- .github/workflows/ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a1436a49d16..23c472bbc2c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true -env: - REGISTRIES_CRATES_IO_PROTOCOL: sparse - jobs: linux: runs-on: ubuntu-latest @@ -270,6 +267,8 @@ jobs: - nightly name: "Rust Coverage" timeout-minutes: 15 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.3.0 timeout-minutes: 3 From b41a2d05a4f7a4b17a08c55370f69d1f804efd2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Jan 2023 12:55:29 +0000 Subject: [PATCH 156/827] Bump ruff from 0.0.235 to 0.0.236 (#8145) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.235 to 0.0.236. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.235...v0.0.236) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 829ca57dfabf..4ea3a04ac3bb 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.2.0 # via twine -ruff==0.0.235 +ruff==0.0.236 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 8a3650249c3a26294f27a158315dc608629a2ecc Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 27 Jan 2023 08:16:43 -0800 Subject: [PATCH 157/827] fix for a future warning (#8146) --- src/rust/src/x509/certificate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 65c37d334d69..d47c9b2c3e25 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -320,9 +320,9 @@ impl Certificate { ) } - fn verify_directly_issued_by<'p>( + fn verify_directly_issued_by( &self, - py: pyo3::Python<'p>, + py: pyo3::Python<'_>, issuer: pyo3::PyRef<'_, Certificate>, ) -> PyAsn1Result<()> { if self.raw.borrow_value().tbs_cert.signature_alg != self.raw.borrow_value().signature_alg { From 0d0c48d4007c9230096599e13c755b793feaf796 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 00:36:04 +0000 Subject: [PATCH 158/827] Bump BoringSSL and/or OpenSSL in CI (#8149) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23c472bbc2c7..fb65fec01048 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 27, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "cbccae538c6f03cdf7b9fa263fd1c37724d7a769"}} - # Latest commit on the OpenSSL master branch, as of Jan 27, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6e3b1c81736b1829584e3f40c2d00040fe1aa881"}} + # Latest commit on the BoringSSL master branch, as of Jan 28, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "80a243e07ef77156af66efa7d22ac35aba44c1b3"}} + # Latest commit on the OpenSSL master branch, as of Jan 28, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6a9453572533e4a22e6f60fe8f6b7ef0823d9c1f"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 16b22bfc8fb490aa49488edce052a9dcb002d602 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 04:43:52 +0000 Subject: [PATCH 159/827] Bump zipp from 3.11.0 to 3.12.0 (#8150) Bumps [zipp](https://github.com/jaraco/zipp) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.11.0...v3.12.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4ea3a04ac3bb..d4a859362d1a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -221,7 +221,7 @@ virtualenv==20.17.1 # via tox webencodings==0.5.1 # via bleach -zipp==3.11.0; python_version >= "3.7" +zipp==3.12.0; python_version >= "3.7" # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From bd8ee424a461ac89e5eb65c405fbbfc409b83b2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 04:53:22 +0000 Subject: [PATCH 160/827] Bump rich from 13.2.0 to 13.3.0 (#8151) Bumps [rich](https://github.com/Textualize/rich) from 13.2.0 to 13.3.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.2.0...v13.3.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d4a859362d1a..e7eb850fa86e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.2.0 +rich==13.3.0 # via twine ruff==0.0.236 # via cryptography (setup.cfg) From c5139557fab46f0bb1b7e8ff3e10ac03eb39280b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 28 Jan 2023 17:20:19 -0500 Subject: [PATCH 161/827] try to simplify boring installation in CI (#8152) * try to simplify boring installation in CI * Update ci.yml --- .github/workflows/build_openssl.sh | 12 ++++-------- .github/workflows/ci.yml | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_openssl.sh b/.github/workflows/build_openssl.sh index a12794fa4877..6dd6e04fc331 100755 --- a/.github/workflows/build_openssl.sh +++ b/.github/workflows/build_openssl.sh @@ -69,15 +69,11 @@ elif [[ "${TYPE}" == "boringssl" ]]; then mkdir build pushd build # Find the default rust target based on what rustc is built for - cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" + cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" -DCMAKE_INSTALL_PREFIX="${OSSL_PATH}" make -j"$(nproc)" - mkdir -p "${OSSL_PATH}/lib/" - mkdir -p "${OSSL_PATH}/include/" - mkdir -p "${OSSL_PATH}/bin/" - cp -r ../include/openssl "${OSSL_PATH}/include/" - cp ssl/libssl.a "${OSSL_PATH}/lib/" - cp crypto/libcrypto.a "${OSSL_PATH}/lib/" - cp tool/bssl "${OSSL_PATH}/bin/openssl" + make install + # BoringSSL doesn't have a bin/openssl and we use that to detect success + touch "${OSSL_PATH}/bin/openssl" popd popd fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb65fec01048..8b55ddf0e5a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: path: ${{ github.workspace }}/osslcache # When altering the openssl build process you may need to increment the value on the end of this cache key # so that you can prevent it from fetching the cache and skipping the build step. - key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-5 + key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-6 if: matrix.PYTHON.OPENSSL - name: Build custom OpenSSL/LibreSSL run: .github/workflows/build_openssl.sh From 66560b92d1a6175269450cbdef01c007dc28db20 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 28 Jan 2023 23:17:54 -0600 Subject: [PATCH 162/827] separate tox into install and test steps (#8154) this allows us to measure how long installing our dependencies (and cryptography itself) takes vs our actual test time also attempt to modernize some flags --- .github/workflows/ci.yml | 50 ++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b55ddf0e5a7..34f9a9269554 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,9 +109,15 @@ jobs: echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration -I${OSSL_PATH}/include" >> $GITHUB_ENV echo "LDFLAGS=${LDFLAGS} -L${OSSL_PATH}/lib -L${OSSL_PATH}/lib64 -Wl,-rpath=${OSSL_PATH}/lib -Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV if: matrix.PYTHON.OPENSSL + - name: Build toxenv + run: | + tox -vvv --notest + env: + TOXENV: ${{ matrix.PYTHON.TOXENV }} + CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests run: | - tox -vvv -r -- --color=yes --wycheproof-root=wycheproof ${{ matrix.PYTHON.TOXARGS }} + tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof ${{ matrix.PYTHON.TOXARGS }} env: TOXENV: ${{ matrix.PYTHON.TOXENV }} CRYPTOGRAPHY_OPENSSL_NO_LEGACY: ${{ matrix.PYTHON.OPENSSL.NO_LEGACY }} @@ -187,13 +193,18 @@ jobs: echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt tox coverage - - run: '/venv/bin/tox -vvv -- --wycheproof-root="wycheproof"' + - run: '/venv/bin/tox -vvv --notest' env: TOXENV: ${{ matrix.IMAGE.TOXENV }} RUSTUP_HOME: /root/.rustup CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 + - run: '/venv/bin/tox --skip-pkg-install -- --color=yes --wycheproof-root="wycheproof"' + env: + TOXENV: ${{ matrix.IMAGE.TOXENV }} + # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream + OPENSSL_ENABLE_SHA1_SIGNATURES: 1 - uses: ./.github/actions/upload-coverage linux-rust: @@ -248,12 +259,15 @@ jobs: path: "wycheproof" ref: "master" - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] - - name: Tests - run: | - tox -vvv -r -- --color=yes --wycheproof-root=wycheproof + - name: Create toxenv + run: tox -vvv --notest env: TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + - name: Tests + run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof + env: + TOXENV: ${{ matrix.PYTHON.TOXENV }} - uses: ./.github/actions/upload-coverage linux-rust-coverage: @@ -306,9 +320,15 @@ jobs: path: "wycheproof" ref: "master" - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] + - name: Create toxenv + run: tox -vvv --notest + env: + TOXENV: ${{ matrix.PYTHON.TOXENV }} + CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + RUSTFLAGS: "-Cinstrument-coverage" + LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - name: Tests - run: | - tox -vvv -r -- --color=yes --wycheproof-root=wycheproof + run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} @@ -400,16 +420,20 @@ jobs: python .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Tests + - name: Build toxenv run: | CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ LDFLAGS="${HOME}/openssl-macos-universal2/lib/libcrypto.a ${HOME}/openssl-macos-universal2/lib/libssl.a" \ CFLAGS="-I${HOME}/openssl-macos-universal2/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ - tox -vvv -r -- --color=yes --wycheproof-root=wycheproof + tox -vvv --notest env: TOXENV: ${{ matrix.PYTHON.TOXENV }} EXTRA_CFLAGS: ${{ matrix.PYTHON.EXTRA_CFLAGS }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + - name: Tests + run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof + env: + TOXENV: ${{ matrix.PYTHON.TOXENV }} - uses: ./.github/actions/upload-coverage @@ -468,7 +492,13 @@ jobs: path: "wycheproof" ref: "master" - - run: tox -vvv -r -- --color=yes --wycheproof-root=wycheproof --num-shards=3 --shard-id=${{ matrix.JOB_NUMBER }} + - name: Build toxenv + run: tox -vvv --notest + env: + TOXENV: ${{ matrix.PYTHON.TOXENV }} + CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + - name: Tests + run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof --num-shards=3 --shard-id=${{ matrix.JOB_NUMBER }} env: TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} From 6509564481b9882228709f8a4f65d8318e0baa98 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 28 Jan 2023 23:39:18 -0600 Subject: [PATCH 163/827] make tox verbose on install again for tox4+ (#8155) --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index b369da8e9f79..b56796768a28 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,8 @@ minversion = 2.4 isolated_build = True [testenv] +# This is the default install_command but with -v added +install_command = python -I -m pip install -v {opts} {packages} extras = test ssh: ssh From 7cfa392eda71169ef090f33766880cb23275140b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 15:32:20 +0000 Subject: [PATCH 164/827] Bump cc from 1.0.78 to 1.0.79 in /src/rust (#8157) Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.78...1.0.79) --- updated-dependencies: - dependency-name: cc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 24ba48b8f30a..75f981a4fe92 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -70,9 +70,9 @@ checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" From 8941da6ac37217372288818377d8d1599b92aae5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 15:38:23 +0000 Subject: [PATCH 165/827] Bump rich from 13.3.0 to 13.3.1 (#8158) Bumps [rich](https://github.com/Textualize/rich) from 13.3.0 to 13.3.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.0...v13.3.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e7eb850fa86e..cd6d7a29ab0a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.3.0 +rich==13.3.1 # via twine ruff==0.0.236 # via cryptography (setup.cfg) From 4e0f61a2ca9a9010e76935767d23947afcf653a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 15:58:20 +0000 Subject: [PATCH 166/827] Bump ruff from 0.0.236 to 0.0.237 (#8159) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.236 to 0.0.237. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.236...v0.0.237) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index cd6d7a29ab0a..3c48c066050c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.236 +ruff==0.0.237 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 6f1f2820475d7c11149b8b54aab3728730e197d6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 29 Jan 2023 15:29:17 -0500 Subject: [PATCH 167/827] Use Rust for CSR::is_signature_valid (#8161) --- .../hazmat/backends/openssl/backend.py | 23 ------------------- src/rust/src/x509/csr.rs | 19 +++++++-------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 26188aa0f45e..737415a35f6f 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1102,14 +1102,6 @@ def _ossl2cert(self, x509: typing.Any) -> x509.Certificate: self.openssl_assert(res == 1) return rust_x509.load_der_x509_certificate(self._read_mem_bio(bio)) - def _csr2ossl(self, csr: x509.CertificateSigningRequest) -> typing.Any: - data = csr.public_bytes(serialization.Encoding.DER) - mem_bio = self._bytes_to_bio(data) - x509_req = self._lib.d2i_X509_REQ_bio(mem_bio.bio, self._ffi.NULL) - self.openssl_assert(x509_req != self._ffi.NULL) - x509_req = self._ffi.gc(x509_req, self._lib.X509_REQ_free) - return x509_req - def _crl2ossl(self, crl: x509.CertificateRevocationList) -> typing.Any: data = crl.public_bytes(serialization.Encoding.DER) mem_bio = self._bytes_to_bio(data) @@ -1144,21 +1136,6 @@ def _crl_is_signature_valid( return True - def _csr_is_signature_valid( - self, csr: x509.CertificateSigningRequest - ) -> bool: - x509_req = self._csr2ossl(csr) - pkey = self._lib.X509_REQ_get_pubkey(x509_req) - self.openssl_assert(pkey != self._ffi.NULL) - pkey = self._ffi.gc(pkey, self._lib.EVP_PKEY_free) - res = self._lib.X509_REQ_verify(x509_req, pkey) - - if res != 1: - self._consume_errors() - return False - - return True - def _check_keys_correspond(self, key1, key2): if self._lib.EVP_PKEY_cmp(key1._evp_pkey, key2._evp_pkey) != 1: raise ValueError("Keys do not correspond") diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 7bc3dc98a222..cb9056c80b23 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -4,7 +4,7 @@ use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid, PyAsn1Error, PyAsn1Result}; use crate::x509; -use crate::x509::{certificate, oid}; +use crate::x509::{certificate, oid, sign}; use asn1::SimpleAsn1Readable; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -266,14 +266,15 @@ impl CertificateSigningRequest { } #[getter] - fn is_signature_valid<'p>( - slf: pyo3::PyRef<'_, Self>, - py: pyo3::Python<'p>, - ) -> pyo3::PyResult<&'p pyo3::PyAny> { - let backend = py - .import("cryptography.hazmat.backends.openssl.backend")? - .getattr(crate::intern!(py, "backend"))?; - backend.call_method1("_csr_is_signature_valid", (slf,)) + fn is_signature_valid(slf: pyo3::PyRef<'_, Self>, py: pyo3::Python<'_>) -> PyAsn1Result { + Ok(sign::verify_signature_with_oid( + py, + slf.public_key(py)?, + &slf.raw.borrow_value().signature_alg.oid, + slf.raw.borrow_value().signature.as_bytes(), + &asn1::write_single(&slf.raw.borrow_value().csr_info)?, + ) + .is_ok()) } } From 957524e02eb38a32fe03de384806393d06ba81c5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 29 Jan 2023 16:00:59 -0600 Subject: [PATCH 168/827] add CRL vector with an inner/outer signature OID mismatch (#8163) --- docs/development/test-vectors.rst | 3 +++ .../x509/custom/crl_inner_outer_mismatch.der | Bin 0 -> 385 bytes 2 files changed, 3 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/crl_inner_outer_mismatch.der diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 93ab03232859..b8a703f90786 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -605,6 +605,9 @@ Custom X.509 Certificate Revocation List Vectors signature on this CRL is invalid. * ``crl_bad_version.pem`` - Contains a CRL with an invalid version. * ``crl_almost_10k.pem`` - Contains a CRL with 9,999 entries. +* ``crl_inner_outer_mismatch.der`` - A CRL created from + ``valid_signature_crl.pem`` but with a mismatched inner and + outer signature algorithm. The signature on this CRL is invalid. X.509 OCSP Test Vectors ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vectors/cryptography_vectors/x509/custom/crl_inner_outer_mismatch.der b/vectors/cryptography_vectors/x509/custom/crl_inner_outer_mismatch.der new file mode 100644 index 0000000000000000000000000000000000000000..ceec88fc2b2b34ab7e8d2572e6346d7788808559 GIT binary patch literal 385 zcmXqLVyrbtXJTYD;AP{~YV&CO&dbQi%F1A%YN%|W$i^JX!ptL;nOByWlbI4tqfnAsTq4eEXl`I(U}j)wVqs(&1?E~Bm_oS=_zZXqxPXSpim)&a7S2NS09jVK2NS)$L=uo++ ztKE_9`$dpZ?f-5a_I;8EPcWKI<&5|eF|YRa^@g}&!4>t5@!y!;Ht$>h-YWQ@zSX^| z*6q&WkIrSRyjxsaTe0fn(Su9ebUj5*+FMA=ebRgG$arI};^tS!7DxE|SVzwP_3NIv zz*!HENY=Ci|9h=1G6RpNJK6qUR@cZd-SA}dwj)*|O66M5&n@{_nzcz#^}A?+%Atik zmNt*_uQ|@J={{}T(En^lwA#HNOO2Q~ytbT4eCUyyVDxF5yvBwz(-L%TMQ^Ou>MOP8 WUTr)5uD}_WV)6RW_>Zw)cL4zOe3NAW literal 0 HcmV?d00001 From 6458c38a6b96b808a0e1d0a5b0feda50bb7da4d9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 29 Jan 2023 17:16:35 -0500 Subject: [PATCH 169/827] Use Rust for CRL::is_signature_valid (#8162) --- .../hazmat/backends/openssl/backend.py | 35 ------------------- src/rust/src/x509/crl.rs | 26 ++++++++++---- src/rust/src/x509/sign.rs | 4 +-- tests/x509/test_x509.py | 7 ++++ 4 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 737415a35f6f..b75bb9e71cb8 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -78,7 +78,6 @@ PKCS1v15, ) from cryptography.hazmat.primitives.asymmetric.types import ( - CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, PRIVATE_KEY_TYPES, PUBLIC_KEY_TYPES, ) @@ -1102,40 +1101,6 @@ def _ossl2cert(self, x509: typing.Any) -> x509.Certificate: self.openssl_assert(res == 1) return rust_x509.load_der_x509_certificate(self._read_mem_bio(bio)) - def _crl2ossl(self, crl: x509.CertificateRevocationList) -> typing.Any: - data = crl.public_bytes(serialization.Encoding.DER) - mem_bio = self._bytes_to_bio(data) - x509_crl = self._lib.d2i_X509_CRL_bio(mem_bio.bio, self._ffi.NULL) - self.openssl_assert(x509_crl != self._ffi.NULL) - x509_crl = self._ffi.gc(x509_crl, self._lib.X509_CRL_free) - return x509_crl - - def _crl_is_signature_valid( - self, - crl: x509.CertificateRevocationList, - public_key: CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, - ) -> bool: - if not isinstance( - public_key, - ( - _DSAPublicKey, - _RSAPublicKey, - _EllipticCurvePublicKey, - ), - ): - raise TypeError( - "Expecting one of DSAPublicKey, RSAPublicKey," - " or EllipticCurvePublicKey." - ) - x509_crl = self._crl2ossl(crl) - res = self._lib.X509_CRL_verify(x509_crl, public_key._evp_pkey) - - if res != 1: - self._consume_errors() - return False - - return True - def _check_keys_correspond(self, key1, key2): if self._lib.EVP_PKEY_cmp(key1._evp_pkey, key2._evp_pkey) != 1: raise ValueError("Keys do not correspond") diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 44e3bfd70fc9..5f4ff09e7a26 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -7,7 +7,7 @@ use crate::asn1::{ PyAsn1Error, PyAsn1Result, }; use crate::x509; -use crate::x509::{certificate, extensions, oid}; +use crate::x509::{certificate, extensions, oid, sign}; use pyo3::ToPyObject; use std::convert::TryInto; use std::sync::Arc; @@ -373,11 +373,25 @@ impl CertificateRevocationList { slf: pyo3::PyRef<'_, Self>, py: pyo3::Python<'p>, public_key: &'p pyo3::PyAny, - ) -> pyo3::PyResult<&'p pyo3::PyAny> { - let backend = py - .import("cryptography.hazmat.backends.openssl.backend")? - .getattr(crate::intern!(py, "backend"))?; - backend.call_method1("_crl_is_signature_valid", (slf, public_key)) + ) -> PyAsn1Result { + if slf.raw.borrow_value().tbs_cert_list.signature + != slf.raw.borrow_value().signature_algorithm + { + return Ok(false); + }; + + // Error on invalid public key -- below we treat any error as just + // being an invalid signature. + sign::identify_public_key_type(py, public_key)?; + + Ok(sign::verify_signature_with_oid( + py, + public_key, + &slf.raw.borrow_value().signature_algorithm.oid, + slf.raw.borrow_value().signature_value.as_bytes(), + &asn1::write_single(&slf.raw.borrow_value().tbs_cert_list)?, + ) + .is_ok()) } } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index bc5f07994b4c..e1d35265fe5d 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -16,7 +16,7 @@ pub(crate) static NULL_TLV: Lazy> = Lazy::new(|| asn1::parse_single(&NULL_DER).unwrap()); #[derive(Debug, PartialEq)] -enum KeyType { +pub(crate) enum KeyType { Rsa, Dsa, Ec, @@ -320,7 +320,7 @@ pub(crate) fn verify_signature_with_oid<'p>( Ok(()) } -fn identify_public_key_type( +pub(crate) fn identify_public_key_type( py: pyo3::Python<'_>, public_key: &pyo3::PyAny, ) -> pyo3::PyResult { diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index c76c043b7b22..ac73ad11c247 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -542,6 +542,13 @@ def test_verify_bad(self, backend): assert isinstance(public_key, rsa.RSAPublicKey) assert not crl.is_signature_valid(public_key) + crl = _load_cert( + os.path.join("x509", "custom", "crl_inner_outer_mismatch.der"), + x509.load_der_x509_crl, + backend, + ) + assert not crl.is_signature_valid(public_key) + def test_verify_good(self, backend): crl = _load_cert( os.path.join("x509", "custom", "valid_signature_crl.pem"), From c3fc4d23127b3ee3f0e9b19c5008d8cbe99ff6f8 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 00:23:51 +0000 Subject: [PATCH 170/827] Bump BoringSSL and/or OpenSSL in CI (#8164) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34f9a9269554..a84a62c1e933 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Jan 28, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "80a243e07ef77156af66efa7d22ac35aba44c1b3"}} - # Latest commit on the OpenSSL master branch, as of Jan 28, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6a9453572533e4a22e6f60fe8f6b7ef0823d9c1f"}} + # Latest commit on the OpenSSL master branch, as of Jan 30, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d79bb5316e1318bd776d6b2d6723a36778e07f9d"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 10b933bb0560260f86fabe7101e18c175999ff99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 07:34:35 -0500 Subject: [PATCH 171/827] Bump actions/cache from 3.2.3 to 3.2.4 (#8165) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.3 to 3.2.4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.3...v3.2.4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a84a62c1e933..092126300219 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | @@ -89,7 +89,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load cache - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 id: ossl-cache timeout-minutes: 5 with: @@ -165,7 +165,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | @@ -232,7 +232,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | @@ -288,7 +288,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 id: cargo-cache timeout-minutes: 5 with: @@ -387,7 +387,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | @@ -462,7 +462,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | @@ -530,7 +530,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.3 + - uses: actions/cache@v3.2.4 timeout-minutes: 5 with: path: | From 742c685e842ed57ce4fbd7d3c65146741a17cf58 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 30 Jan 2023 09:47:37 -0500 Subject: [PATCH 172/827] Several cleanups to the backend: (#8166) 1. use public API for loading DER cert 2. use length-API for PKCS12 friendly name, not NUL-terminated 3. don't upref and GC and X509* that doesn't need to live longer --- .../hazmat/backends/openssl/backend.py | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index b75bb9e71cb8..db2dace37582 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -57,7 +57,6 @@ _X25519PrivateKey, _X25519PublicKey, ) -from cryptography.hazmat.bindings._rust import x509 as rust_x509 from cryptography.hazmat.bindings.openssl import binding from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding @@ -1095,11 +1094,11 @@ def _cert2ossl(self, cert: x509.Certificate) -> typing.Any: x509 = self._ffi.gc(x509, self._lib.X509_free) return x509 - def _ossl2cert(self, x509: typing.Any) -> x509.Certificate: + def _ossl2cert(self, x509_ptr: typing.Any) -> x509.Certificate: bio = self._create_mem_bio_gc() - res = self._lib.i2d_X509_bio(bio, x509) + res = self._lib.i2d_X509_bio(bio, x509_ptr) self.openssl_assert(res == 1) - return rust_x509.load_der_x509_certificate(self._read_mem_bio(bio)) + return x509.load_der_x509_certificate(self._read_mem_bio(bio)) def _check_keys_correspond(self, key1, key2): if self._lib.EVP_PKEY_cmp(key1._evp_pkey, key2._evp_pkey) != 1: @@ -2299,13 +2298,15 @@ def serialize_key_and_certificates_to_pkcs12( if isinstance(ca, PKCS12Certificate): ca_alias = ca.friendly_name ossl_ca = self._cert2ossl(ca.certificate) - with self._zeroed_null_terminated_buf( - ca_alias - ) as ca_name_buf: + if ca_alias is None: res = self._lib.X509_alias_set1( - ossl_ca, ca_name_buf, -1 + ossl_ca, self._ffi.NULL, -1 ) - self.openssl_assert(res == 1) + else: + res = self._lib.X509_alias_set1( + ossl_ca, ca_alias, len(ca_alias) + ) + self.openssl_assert(res == 1) else: ossl_ca = self._cert2ossl(ca) ossl_cas.append(ossl_ca) @@ -2414,9 +2415,6 @@ def _load_pkcs7_certificates(self, p7): for i in range(num): x509 = self._lib.sk_X509_value(sk_x509, i) self.openssl_assert(x509 != self._ffi.NULL) - res = self._lib.X509_up_ref(x509) - self.openssl_assert(res == 1) - x509 = self._ffi.gc(x509, self._lib.X509_free) cert = self._ossl2cert(x509) certs.append(cert) From ada91f1cf03d59fa980f69d221b21d9ac5770375 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 19:21:32 -0500 Subject: [PATCH 173/827] Bump BoringSSL and/or OpenSSL in CI (#8169) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 092126300219..cd76428d954d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 28, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "80a243e07ef77156af66efa7d22ac35aba44c1b3"}} - # Latest commit on the OpenSSL master branch, as of Jan 30, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d79bb5316e1318bd776d6b2d6723a36778e07f9d"}} + # Latest commit on the BoringSSL master branch, as of Jan 31, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a7fbc543c9b2305befee733d689fdf8b821ab880"}} + # Latest commit on the OpenSSL master branch, as of Jan 31, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ecd445464a73bb3f125327a604dd13ad16303ebc"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 2083e27090533250e717c46fcb092eed96f4385a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 30 Jan 2023 21:55:32 -0500 Subject: [PATCH 174/827] pass CARGO_REGISTRIES_CRATES_IO_PROTOCOL through tox (#8173) --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index b56796768a28..da167c2ee52e 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,7 @@ passenv = LD_LIBRARY_PATH RUSTFLAGS CARGO_TARGET_DIR + CARGO_REGISTRIES_CRATES_IO_PROTOCOL LLVM_PROFILE_FILE OPENSSL_FORCE_FIPS_MODE RUSTUP_TOOLCHAIN From ab5ffdc13aa2063e13b8cd55b41de4f46742f324 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 30 Jan 2023 21:57:19 -0500 Subject: [PATCH 175/827] update our security reporting instructions (#8171) --- docs/security.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/security.rst b/docs/security.rst index 6cd9dbe33937..e1fba3a1ecec 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -52,14 +52,12 @@ Reporting a security issue We ask that you do not report security issues to our normal GitHub issue tracker. -If you believe you've identified a security issue with ``cryptography``, please -report it to ``alex.gaynor@gmail.com`` and/or ``paul.l.kehrer@gmail.com``. You -should verify that your MTA uses TLS to ensure the confidentiality of your -message. +If you believe you've identified a security issue with ``cryptography``, +please report it via our `security advisory page`_. -Once you've submitted an issue via email, you should receive an acknowledgment -within 48 hours, and depending on the action to be taken, you may receive -further follow-up emails. +Once you've submitted an issue, you should receive an acknowledgment within 48 +hours, and depending on the action to be taken, you may receive further +follow-up. Supported Versions ------------------ @@ -89,4 +87,5 @@ The steps for issuing a security release are described in our :doc:`/doing-a-release` documentation. +.. _`security advisory page`: https://github.com/pyca/cryptography/security/advisories/new .. _`main`: https://github.com/pyca/cryptography From 29364b5dc4057b61462969b4e8ed21b229d87329 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 30 Jan 2023 22:05:12 -0500 Subject: [PATCH 176/827] incorporate rust version into cache key (#8174) --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd76428d954d..a99690845a1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -288,6 +288,11 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 + id: rust-toolchain + with: + toolchain: ${{ matrix.RUST }} + components: llvm-tools-preview - uses: actions/cache@v3.2.4 id: cargo-cache timeout-minutes: 5 @@ -300,16 +305,12 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ matrix.RUST }}-coverage + key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage - name: Setup python uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 - with: - toolchain: ${{ matrix.RUST }} - components: llvm-tools-preview - run: cargo install cargo-binutils if: steps.cargo-cache.outputs.cache-hit != 'true' From 385a74b00f85561503ea7557bcf378c26e68bdb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 12:31:28 +0000 Subject: [PATCH 177/827] Bump ruff from 0.0.237 to 0.0.238 (#8177) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.237 to 0.0.238. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.237...v0.0.238) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3c48c066050c..8944832b0ef5 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.237 +ruff==0.0.238 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 5e83c6ba378cf46a4e7a8c478e6169acb09012cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 12:39:41 +0000 Subject: [PATCH 178/827] Bump tox from 4.4.2 to 4.4.3 (#8176) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.2 to 4.4.3. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.2...4.4.3) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8944832b0ef5..c823cca30007 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -201,7 +201,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.2; python_version >= "3.7" +tox==4.4.3; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 7a8ad9ee4fc0aaf0af9ab3c5f57f2efd4a5d38e5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 31 Jan 2023 18:10:42 -0500 Subject: [PATCH 179/827] Don't cache index when we use the cargo sparse protocol (#8172) --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a99690845a1b..aa45123503d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -300,7 +300,6 @@ jobs: path: | ~/.cache/pip/ ~/.cargo/bin/ - ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ From b14723c21e28d6693be2e3a67fa512a672e9c87a Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 00:23:20 +0000 Subject: [PATCH 180/827] Bump BoringSSL and/or OpenSSL in CI (#8178) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa45123503d5..d9e52e549036 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Jan 31, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a7fbc543c9b2305befee733d689fdf8b821ab880"}} - # Latest commit on the OpenSSL master branch, as of Jan 31, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ecd445464a73bb3f125327a604dd13ad16303ebc"}} + # Latest commit on the BoringSSL master branch, as of Feb 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a5ab818854d1adf6ee866f768b47f6162f4ca0a9"}} + # Latest commit on the OpenSSL master branch, as of Feb 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e788c772b12eea5ced4ce46619e13acf0e0eb6ba"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 536aec22404c9fb02f351e5314ba8097e4b965d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 23:16:42 -0500 Subject: [PATCH 181/827] Bump dtolnay/rust-toolchain (#8179) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from ce8f65846d7180d2ce63b1e74483d981800b9e22 to c758e63728211bd4acda6501cfa2a16c5c751fc4. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/ce8f65846d7180d2ce63b1e74483d981800b9e22...c758e63728211bd4acda6501cfa2a16c5c751fc4) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9e52e549036..3a6042bcd7ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -249,7 +249,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 + - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 with: toolchain: ${{ matrix.RUST }} - uses: actions/checkout@v3.3.0 @@ -288,7 +288,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 + - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 id: rust-toolchain with: toolchain: ${{ matrix.RUST }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index f375b332ff0b..7b8cdabbf1a4 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -204,7 +204,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 + - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -276,7 +276,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@ce8f65846d7180d2ce63b1e74483d981800b9e22 + - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From 1a765e882d8b09fe6883adb28387b760e1917da5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 04:16:53 +0000 Subject: [PATCH 182/827] Bump ruff from 0.0.238 to 0.0.239 (#8182) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.238 to 0.0.239. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.238...v0.0.239) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c823cca30007..b1b091c7a1f9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.238 +ruff==0.0.239 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 055302704d0d98deab0e1e9163e0a76ccd912af7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 04:20:00 +0000 Subject: [PATCH 183/827] Bump sphinxcontrib-htmlhelp from 2.0.0 to 2.0.1 (#8183) Bumps [sphinxcontrib-htmlhelp](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/releases) - [Changelog](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/commits) --- updated-dependencies: - dependency-name: sphinxcontrib-htmlhelp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b1b091c7a1f9..cb95412b94ac 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -180,7 +180,7 @@ sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.1 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx From 8260d5a2b5011272ec93832638b3bfd1049bc199 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 1 Feb 2023 00:24:17 -0500 Subject: [PATCH 184/827] fix CI with tox 4.4.4 (#8184) --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index da167c2ee52e..4b6d1d9d84fd 100644 --- a/tox.ini +++ b/tox.ini @@ -20,6 +20,7 @@ passenv = LIB LD_LIBRARY_PATH RUSTFLAGS + RUSTUP_HOME CARGO_TARGET_DIR CARGO_REGISTRIES_CRATES_IO_PROTOCOL LLVM_PROFILE_FILE From d83f5847970bbd61f245bf1af7927c9b6f656c64 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 1 Feb 2023 00:24:52 -0500 Subject: [PATCH 185/827] Update style for new black (#8185) --- src/cryptography/hazmat/primitives/ciphers/base.py | 1 - src/cryptography/hazmat/primitives/hashes.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index d7c4f096d09d..d80ef3f15d34 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -81,7 +81,6 @@ def __init__( mode: Mode, backend: typing.Any = None, ) -> None: - if not isinstance(algorithm, CipherAlgorithm): raise TypeError("Expected interface of CipherAlgorithm.") diff --git a/src/cryptography/hazmat/primitives/hashes.py b/src/cryptography/hazmat/primitives/hashes.py index 330c08dfa95f..6bbab4c0b92a 100644 --- a/src/cryptography/hazmat/primitives/hashes.py +++ b/src/cryptography/hazmat/primitives/hashes.py @@ -226,7 +226,6 @@ class BLAKE2b(HashAlgorithm): block_size = 128 def __init__(self, digest_size: int): - if digest_size != 64: raise ValueError("Digest size must be 64") @@ -244,7 +243,6 @@ class BLAKE2s(HashAlgorithm): _min_digest_size = 1 def __init__(self, digest_size: int): - if digest_size != 32: raise ValueError("Digest size must be 32") From 6ee5bb6cba067e7dd62384c36e8fc4afe31273d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 05:50:43 +0000 Subject: [PATCH 186/827] Bump black from 22.12.0 to 23.1.0 (#8181) Bumps [black](https://github.com/psf/black) from 22.12.0 to 23.1.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/22.12.0...23.1.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index cb95412b94ac..a4d7b132205c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -13,7 +13,7 @@ attrs==22.2.0 # pytest babel==2.11.0 # via sphinx -black==22.12.0 +black==23.1.0 # via cryptography (setup.cfg) bleach==6.0.0 # via readme-renderer From 5446844dc77874ea6c7bfacf5e0c9aa852f2df58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 05:55:02 +0000 Subject: [PATCH 187/827] Bump tox from 4.4.3 to 4.4.4 (#8180) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.3 to 4.4.4. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.3...4.4.4) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a4d7b132205c..7e99906d3f86 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -201,7 +201,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.3; python_version >= "3.7" +tox==4.4.4; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 31ac1eb7eb7efd1e19553d12d18ad248e52e39e6 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 00:27:08 +0000 Subject: [PATCH 188/827] Bump BoringSSL and/or OpenSSL in CI (#8188) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a6042bcd7ed..b43203a2419a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "a5ab818854d1adf6ee866f768b47f6162f4ca0a9"}} - # Latest commit on the OpenSSL master branch, as of Feb 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e788c772b12eea5ced4ce46619e13acf0e0eb6ba"}} + # Latest commit on the BoringSSL master branch, as of Feb 02, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "31f1466a613774369053a94eabbae38fb9cbb7f9"}} + # Latest commit on the OpenSSL master branch, as of Feb 02, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c007203b94b6921ebc8103cb7ae51af554c86afe"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 1fdaf7d063a3613ab7c84f85aa31aadb19fee025 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 08:18:35 -0500 Subject: [PATCH 189/827] Bump hypothesis from 6.65.2 to 6.66.0 (#8194) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.65.2 to 6.66.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.65.2...hypothesis-python-6.66.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7e99906d3f86..78bb043bab58 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.65.2; python_version >= "3.7" +hypothesis==6.66.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From b5ef5c8a42779941ca2fc285396b28cf9c638e25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 13:28:25 +0000 Subject: [PATCH 190/827] Bump js-sys from 0.3.60 to 0.3.61 in /src/rust (#8191) Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.60 to 0.3.61. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) --- updated-dependencies: - dependency-name: js-sys dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 75f981a4fe92..ce33de00f844 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -533,9 +533,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -558,9 +558,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -581,9 +581,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "winapi" From b46735834477895323b81c4cbe31dbb6e3c8095a Mon Sep 17 00:00:00 2001 From: Mat <68234729+mat-gas@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:56:49 +0100 Subject: [PATCH 191/827] add support for bytes-like objects in data and associated_data in aead algorithms (#8187) * add support for bytes-like objects in data and associated_data in aead algorithms * flake * flake again * rework AESSIV _check_params * flake and 80char columns * associated_data cannot be None in _check_params, set to [] in calling function * Update src/cryptography/hazmat/primitives/ciphers/aead.py Co-authored-by: Alex Gaynor * flake fix --------- Co-authored-by: mat gas Co-authored-by: Alex Gaynor --- docs/hazmat/primitives/aead.rst | 55 ++++++++++++------- .../hazmat/backends/openssl/aead.py | 12 ++-- .../hazmat/primitives/ciphers/aead.py | 29 +++++----- tests/hazmat/primitives/test_aead.py | 16 +++++- 4 files changed, 74 insertions(+), 38 deletions(-) diff --git a/docs/hazmat/primitives/aead.rst b/docs/hazmat/primitives/aead.rst index b886010ed1f0..82a64bcd5b52 100644 --- a/docs/hazmat/primitives/aead.rst +++ b/docs/hazmat/primitives/aead.rst @@ -56,10 +56,12 @@ also support providing integrity for associated data which is not encrypted. :param nonce: A 12 byte value. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to encrypt. - :param bytes associated_data: Additional data that should be + :param data: The data to encrypt. + :type data: :term:`bytes-like` + :param associated_data: Additional data that should be authenticated with the key, but does not need to be encrypted. Can be ``None``. + :type associated_data: :term:`bytes-like` :returns bytes: The ciphertext bytes with the 16 byte tag appended. :raises OverflowError: If ``data`` or ``associated_data`` is larger than 2\ :sup:`31` - 1 bytes. @@ -73,9 +75,11 @@ also support providing integrity for associated data which is not encrypted. :param nonce: A 12 byte value. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to decrypt (with tag appended). - :param bytes associated_data: Additional data to authenticate. Can be + :param data: The data to decrypt (with tag appended). + :type data: :term:`bytes-like` + :param associated_data: Additional data to authenticate. Can be ``None`` if none was passed during encryption. + :type associated_data: :term:`bytes-like` :returns bytes: The original plaintext. :raises cryptography.exceptions.InvalidTag: If the authentication tag doesn't validate this exception will be raised. This will occur @@ -130,9 +134,11 @@ also support providing integrity for associated data which is not encrypted. performance but it can be up to 2\ :sup:`64` - 1 :term:`bits`. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to encrypt. - :param bytes associated_data: Additional data that should be + :param data: The data to encrypt. + :type data: :term:`bytes-like` + :param associated_data: Additional data that should be authenticated with the key, but is not encrypted. Can be ``None``. + :type associated_data: :term:`bytes-like` :returns bytes: The ciphertext bytes with the 16 byte tag appended. :raises OverflowError: If ``data`` or ``associated_data`` is larger than 2\ :sup:`31` - 1 bytes. @@ -147,9 +153,11 @@ also support providing integrity for associated data which is not encrypted. performance but it can be up to 2\ :sup:`64` - 1 :term:`bits`. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to decrypt (with tag appended). - :param bytes associated_data: Additional data to authenticate. Can be + :param data: The data to decrypt (with tag appended). + :type data: :term:`bytes-like` + :param associated_data: Additional data to authenticate. Can be ``None`` if none was passed during encryption. + :type associated_data: :term:`bytes-like` :returns bytes: The original plaintext. :raises cryptography.exceptions.InvalidTag: If the authentication tag doesn't validate this exception will be raised. This will occur @@ -204,9 +212,11 @@ also support providing integrity for associated data which is not encrypted. :param nonce: A 12-15 byte value. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to encrypt. - :param bytes associated_data: Additional data that should be + :param data: The data to encrypt. + :type data: :term:`bytes-like` + :param associated_data: Additional data that should be authenticated with the key, but is not encrypted. Can be ``None``. + :type associated_data: :term:`bytes-like` :returns bytes: The ciphertext bytes with the 16 byte tag appended. :raises OverflowError: If ``data`` or ``associated_data`` is larger than 2\ :sup:`31` - 1 bytes. @@ -219,9 +229,11 @@ also support providing integrity for associated data which is not encrypted. :param nonce: A 12 byte value. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to decrypt (with tag appended). - :param bytes associated_data: Additional data to authenticate. Can be + :param data: The data to decrypt (with tag appended). + :type data: :term:`bytes-like` + :param associated_data: Additional data to authenticate. Can be ``None`` if none was passed during encryption. + :type associated_data: :term:`bytes-like` :returns bytes: The original plaintext. :raises cryptography.exceptions.InvalidTag: If the authentication tag doesn't validate this exception will be raised. This will occur @@ -288,8 +300,9 @@ also support providing integrity for associated data which is not encrypted. authenticating the ``associated_data``. The output of this can be passed directly to the ``decrypt`` method. - :param bytes data: The data to encrypt. - :param list associated_data: An optional ``list`` of ``bytes``. This + :param data: The data to encrypt. + :type data: :term:`bytes-like` + :param list associated_data: An optional ``list`` of ``bytes-like objects``. This is additional data that should be authenticated with the key, but is not encrypted. Can be ``None``. In SIV mode the final element of this list is treated as a ``nonce``. @@ -304,7 +317,7 @@ also support providing integrity for associated data which is not encrypted. ``associated_data`` in decrypt or the integrity check will fail. :param bytes data: The data to decrypt (with tag **prepended**). - :param list associated_data: An optional ``list`` of ``bytes``. This + :param list associated_data: An optional ``list`` of ``bytes-like objects``. This is additional data that should be authenticated with the key, but is not encrypted. Can be ``None`` if none was used during encryption. @@ -377,9 +390,11 @@ also support providing integrity for associated data which is not encrypted. ``len(data) < 2 ** (8 * (15 - len(nonce)))`` **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to encrypt. - :param bytes associated_data: Additional data that should be + :param data: The data to encrypt. + :type data: :term:`bytes-like` + :param associated_data: Additional data that should be authenticated with the key, but is not encrypted. Can be ``None``. + :type associated_data: :term:`bytes-like` :returns bytes: The ciphertext bytes with the tag appended. :raises OverflowError: If ``data`` or ``associated_data`` is larger than 2\ :sup:`31` - 1 bytes. @@ -394,9 +409,11 @@ also support providing integrity for associated data which is not encrypted. is the same value used when you originally called encrypt. **NEVER REUSE A NONCE** with a key. :type nonce: :term:`bytes-like` - :param bytes data: The data to decrypt (with tag appended). - :param bytes associated_data: Additional data to authenticate. Can be + :param data: The data to decrypt (with tag appended). + :type data: :term:`bytes-like` + :param associated_data: Additional data to authenticate. Can be ``None`` if none was passed during encryption. + :type associated_data: :term:`bytes-like` :returns bytes: The original plaintext. :raises cryptography.exceptions.InvalidTag: If the authentication tag doesn't validate this exception will be raised. This will occur diff --git a/src/cryptography/hazmat/backends/openssl/aead.py b/src/cryptography/hazmat/backends/openssl/aead.py index 5b0fd2217d18..1b5ecefaa88e 100644 --- a/src/cryptography/hazmat/backends/openssl/aead.py +++ b/src/cryptography/hazmat/backends/openssl/aead.py @@ -138,8 +138,9 @@ def _aead_setup( def _set_tag(backend, ctx, tag: bytes) -> None: + tag_ptr = backend._ffi.from_buffer(tag) res = backend._lib.EVP_CIPHER_CTX_ctrl( - ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag + ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag_ptr ) backend.openssl_assert(res != 0) @@ -167,8 +168,9 @@ def _set_length(backend: "Backend", ctx, data_len: int) -> None: def _process_aad(backend: "Backend", ctx, associated_data: bytes) -> None: outlen = backend._ffi.new("int *") + a_data_ptr = backend._ffi.from_buffer(associated_data) res = backend._lib.EVP_CipherUpdate( - ctx, backend._ffi.NULL, outlen, associated_data, len(associated_data) + ctx, backend._ffi.NULL, outlen, a_data_ptr, len(associated_data) ) backend.openssl_assert(res != 0) @@ -176,7 +178,8 @@ def _process_aad(backend: "Backend", ctx, associated_data: bytes) -> None: def _process_data(backend: "Backend", ctx, data: bytes) -> bytes: outlen = backend._ffi.new("int *") buf = backend._ffi.new("unsigned char[]", len(data)) - res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, data, len(data)) + data_ptr = backend._ffi.from_buffer(data) + res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, data_ptr, len(data)) if res == 0: # AES SIV can error here if the data is invalid on decrypt backend._consume_errors() @@ -286,7 +289,8 @@ def _decrypt( if isinstance(cipher, AESCCM): outlen = backend._ffi.new("int *") buf = backend._ffi.new("unsigned char[]", len(data)) - res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, data, len(data)) + d_ptr = backend._ffi.from_buffer(data) + res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, d_ptr, len(data)) if res != 1: backend._consume_errors() raise InvalidTag diff --git a/src/cryptography/hazmat/primitives/ciphers/aead.py b/src/cryptography/hazmat/primitives/ciphers/aead.py index 597bfbf147bd..f2e206bbfa5d 100644 --- a/src/cryptography/hazmat/primitives/ciphers/aead.py +++ b/src/cryptography/hazmat/primitives/ciphers/aead.py @@ -79,8 +79,8 @@ def _check_params( associated_data: bytes, ) -> None: utils._check_byteslike("nonce", nonce) - utils._check_bytes("data", data) - utils._check_bytes("associated_data", associated_data) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) if len(nonce) != 12: raise ValueError("Nonce must be 12 bytes") @@ -164,8 +164,8 @@ def _check_params( self, nonce: bytes, data: bytes, associated_data: bytes ) -> None: utils._check_byteslike("nonce", nonce) - utils._check_bytes("data", data) - utils._check_bytes("associated_data", associated_data) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) if not 7 <= len(nonce) <= 13: raise ValueError("Nonce must be between 7 and 13 bytes") @@ -227,8 +227,8 @@ def _check_params( associated_data: bytes, ) -> None: utils._check_byteslike("nonce", nonce) - utils._check_bytes("data", data) - utils._check_bytes("associated_data", associated_data) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) if len(nonce) < 8 or len(nonce) > 128: raise ValueError("Nonce must be between 8 and 128 bytes") @@ -296,8 +296,8 @@ def _check_params( associated_data: bytes, ) -> None: utils._check_byteslike("nonce", nonce) - utils._check_bytes("data", data) - utils._check_bytes("associated_data", associated_data) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) if len(nonce) < 12 or len(nonce) > 15: raise ValueError("Nonce must be between 12 and 15 bytes") @@ -365,10 +365,13 @@ def _check_params( data: bytes, associated_data: typing.List[bytes], ) -> None: - utils._check_bytes("data", data) + utils._check_byteslike("data", data) if len(data) == 0: raise ValueError("data must not be zero length") - if not isinstance(associated_data, list) or not all( - isinstance(x, bytes) for x in associated_data - ): - raise TypeError("associated_data must be a list of bytes or None") + + if not isinstance(associated_data, list): + raise TypeError( + "associated_data must be a list of bytes-like objects or None" + ) + for x in associated_data: + utils._check_byteslike("associated_data elements", x) diff --git a/tests/hazmat/primitives/test_aead.py b/tests/hazmat/primitives/test_aead.py index 87200048471a..c6811a496b24 100644 --- a/tests/hazmat/primitives/test_aead.py +++ b/tests/hazmat/primitives/test_aead.py @@ -464,10 +464,22 @@ def test_buffer_protocol(self, backend): computed_pt = aesgcm.decrypt(nonce, ct, ad) assert computed_pt == pt aesgcm2 = AESGCM(bytearray(key)) - ct2 = aesgcm2.encrypt(bytearray(nonce), pt, ad) + ct2 = aesgcm2.encrypt(bytearray(nonce), bytearray(pt), bytearray(ad)) assert ct2 == ct - computed_pt2 = aesgcm2.decrypt(bytearray(nonce), ct2, ad) + b_nonce = bytearray(nonce) + b_ct2 = bytearray(ct2) + b_ad = bytearray(ad) + computed_pt2 = aesgcm2.decrypt(b_nonce, b_ct2, b_ad) assert computed_pt2 == pt + aesgcm3 = AESGCM(memoryview(key)) + m_nonce = memoryview(nonce) + m_pt = memoryview(pt) + m_ad = memoryview(ad) + ct3 = aesgcm3.encrypt(m_nonce, m_pt, m_ad) + assert ct3 == ct + m_ct3 = memoryview(ct3) + computed_pt3 = aesgcm3.decrypt(m_nonce, m_ct3, m_ad) + assert computed_pt3 == pt @pytest.mark.skipif( From 8e8c477dd18b744a2635a4514e0adfad0ac50699 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Feb 2023 10:56:07 -0500 Subject: [PATCH 192/827] pre-announce MSRV increase (#8195) * pre-announce MSRV increase * Update CHANGELOG.rst --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fbb9bb40498a..dd17b2b530a8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,11 @@ Changelog * Support for Python 3.6 is deprecated and will be removed in the next release. +* Deprecated the current minimum supported Rust version (MSRV) of 1.48.0. + In the next release we will raise MSRV to 1.56.0. Users with the latest + ``pip`` will typically get a wheel and not need Rust installed, but check + :doc:`/installation` for documentation on installing a newer ``rustc`` if + required. * Deprecated support for DSA keys in :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` and From 47dfa5ad69541807593e1205a72b59d069984e78 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Feb 2023 20:46:34 -0500 Subject: [PATCH 193/827] bookworm python to the moon (#8199) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b43203a2419a..c449093e4432 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - {IMAGE: "rhel8-fips", TOXENV: "py38", RUNNER: "ubuntu-latest", FIPS: true} - {IMAGE: "buster", TOXENV: "py37", RUNNER: "ubuntu-latest"} - {IMAGE: "bullseye", TOXENV: "py39", RUNNER: "ubuntu-latest"} - - {IMAGE: "bookworm", TOXENV: "py310", RUNNER: "ubuntu-latest"} + - {IMAGE: "bookworm", TOXENV: "py311", RUNNER: "ubuntu-latest"} - {IMAGE: "sid", TOXENV: "py311", RUNNER: "ubuntu-latest"} - {IMAGE: "ubuntu-bionic", TOXENV: "py36", RUNNER: "ubuntu-latest"} - {IMAGE: "ubuntu-focal", TOXENV: "py38", RUNNER: "ubuntu-latest"} From af8dfba9358ddca0d5da5cae1292eeeb8993bef4 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 21:00:10 -0500 Subject: [PATCH 194/827] Bump BoringSSL and/or OpenSSL in CI (#8197) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c449093e4432..99c1f5b8c34f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 02, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "31f1466a613774369053a94eabbae38fb9cbb7f9"}} - # Latest commit on the OpenSSL master branch, as of Feb 02, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c007203b94b6921ebc8103cb7ae51af554c86afe"}} + # Latest commit on the BoringSSL master branch, as of Feb 03, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "5bdf5e4ac251e7e9eca5693104d802d94a28f28b"}} + # Latest commit on the OpenSSL master branch, as of Feb 03, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "323c47532ea7fc79d5e28a0fa58ea0cc4d5196b8"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From e7fc8abe98f46960f209bcf6fad830ff9ba7db83 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Feb 2023 01:14:35 -0500 Subject: [PATCH 195/827] don't run dsa wycheproof without dsa (#8201) --- tests/wycheproof/test_dsa.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/wycheproof/test_dsa.py b/tests/wycheproof/test_dsa.py index b7da82dc3c09..fd76a938bfd3 100644 --- a/tests/wycheproof/test_dsa.py +++ b/tests/wycheproof/test_dsa.py @@ -20,6 +20,10 @@ } +@pytest.mark.supported( + only_if=lambda backend: backend.dsa_supported(), + skip_message="Requires OpenSSL with DSA support", +) @wycheproof_tests( "dsa_test.json", "dsa_2048_224_sha224_test.json", From f683d9605c58f98c6c31ef435c8df71edb6ecab7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 08:24:34 -0500 Subject: [PATCH 196/827] Bump ruff from 0.0.239 to 0.0.240 (#8203) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.239 to 0.0.240. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.239...v0.0.240) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 78bb043bab58..c951c1a7b1cd 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.239 +ruff==0.0.240 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 64a5498901373762be4181a79445680485744271 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Feb 2023 10:21:32 -0500 Subject: [PATCH 197/827] document that inheritance is not the way (#8204) resolves #8186 --- docs/api-stability.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/api-stability.rst b/docs/api-stability.rst index 3822702d3937..eafbd1d9506e 100644 --- a/docs/api-stability.rst +++ b/docs/api-stability.rst @@ -24,6 +24,9 @@ What doesn't this policy cover? contents of ``obj.__dict__`` may change. * Objects are not guaranteed to be pickleable, and pickled objects from one version of ``cryptography`` may not be loadable in future versions. +* Unless otherwise documented, types in ``cryptography`` are not intended to + be sub-classed, and we do not guarantee that behavior with respect to + sub-classes will be stable. * Development versions of ``cryptography``. Before a feature is in a release, it is not covered by this policy and may change. From 540c607baedbbee5744971ae2d69fb3dbe3ad4ac Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 4 Feb 2023 00:19:33 +0000 Subject: [PATCH 198/827] Bump BoringSSL and/or OpenSSL in CI (#8205) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99c1f5b8c34f..f5008e464483 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 03, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "5bdf5e4ac251e7e9eca5693104d802d94a28f28b"}} + # Latest commit on the BoringSSL master branch, as of Feb 04, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "eb0b7e4df6eb5a082c2b977784f4270b55c58361"}} # Latest commit on the OpenSSL master branch, as of Feb 03, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "323c47532ea7fc79d5e28a0fa58ea0cc4d5196b8"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From d74bc0dc3b7e2c576fdf87b6ee40a3db81b2051b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 4 Feb 2023 17:14:52 -0500 Subject: [PATCH 199/827] Specify rust-version for clippy (#8206) --- src/rust/Cargo.toml | 2 ++ src/rust/src/lib.rs | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index d557fc049375..053902b01f9e 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" authors = ["The cryptography developers "] edition = "2018" publish = false +# This specifies the MSRV +rust-version = "1.48.0" [dependencies] once_cell = "1" diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 614680268816..afc96ed8ab28 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -6,10 +6,8 @@ // Temporarily allow `clippy::borrow_deref_ref` until we can upgrade to the // latest pyo3: https://github.com/PyO3/pyo3/pull/2503 // -// `clippy::uninlined_format_args` is required until our MSRV is >=1.58.0 -// // `unknown_lints` is required until GHA upgrades their rustc. -#![allow(unknown_lints, clippy::borrow_deref_ref, clippy::uninlined_format_args)] +#![allow(unknown_lints, clippy::borrow_deref_ref)] mod asn1; mod intern; From 1bbc5e31c98d3fde2d70490ee23bb68ed1de34fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 03:16:52 +0000 Subject: [PATCH 200/827] Bump hypothesis from 6.66.0 to 6.67.0 (#8207) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.66.0 to 6.67.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.66.0...hypothesis-python-6.67.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c951c1a7b1cd..2d7d47f4a585 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.66.0; python_version >= "3.7" +hypothesis==6.67.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From d08925f87f3427fe4bf089501e3f3c18cf9a9491 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 03:28:59 +0000 Subject: [PATCH 201/827] Bump proc-macro2 from 1.0.50 to 1.0.51 in /src/rust (#8208) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.50 to 1.0.51. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.50...1.0.51) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index ce33de00f844..bc91e7bc7b2d 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -396,9 +396,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] From 58eff32f658d650a2bde94b4a3ea1287e228d21c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 03:29:29 +0000 Subject: [PATCH 202/827] Bump ruff from 0.0.240 to 0.0.241 (#8209) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.240 to 0.0.241. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.240...v0.0.241) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2d7d47f4a585..69f670fc282e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.240 +ruff==0.0.241 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 525ccb88b9101f0598cfe2f4750b87fe159cf668 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 03:33:02 +0000 Subject: [PATCH 203/827] Bump mypy-extensions from 0.4.3 to 1.0.0 (#8210) Bumps [mypy-extensions](https://github.com/python/mypy_extensions) from 0.4.3 to 1.0.0. - [Release notes](https://github.com/python/mypy_extensions/releases) - [Commits](https://github.com/python/mypy_extensions/commits) --- updated-dependencies: - dependency-name: mypy-extensions dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 69f670fc282e..d45f4fd11118 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -82,7 +82,7 @@ more-itertools==9.0.0 # via jaraco-classes mypy==0.991 # via cryptography (setup.cfg) -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via # black # mypy From 82fa796c79cf2ab3d4b3947c2f27ab2977827c79 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Feb 2023 09:07:22 -0500 Subject: [PATCH 204/827] update comment for new planned MSRV (#8211) --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5008e464483..2d093eb9e428 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -220,10 +220,10 @@ jobs: # remove this section entirely. - 1.48.0 # 1.49.0 is the MSRV for parking_lot 0.12 - - 1.49.0 - # Potential future MSRVs # 1.51 - const generics (for rust-asn1) # 1.56 - new versions of once_cell and bumpalo + - 1.56.0 + # Potential future MSRVs # 1.60 - new version of cxx name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 From a2f033bdb4aa2edaf8c7bca291deffe626d2edf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Feb 2023 08:12:15 -0500 Subject: [PATCH 205/827] Bump zipp from 3.12.0 to 3.12.1 (#8215) Bumps [zipp](https://github.com/jaraco/zipp) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.12.0...v3.12.1) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d45f4fd11118..ee2306484226 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -221,7 +221,7 @@ virtualenv==20.17.1 # via tox webencodings==0.5.1 # via bleach -zipp==3.12.0; python_version >= "3.7" +zipp==3.12.1; python_version >= "3.7" # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From 8e3d3d5e90af4f544a553775fa2be80b0ca3b2ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Feb 2023 08:14:47 -0500 Subject: [PATCH 206/827] Bump hypothesis from 6.67.0 to 6.67.1 (#8214) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.67.0 to 6.67.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.67.0...hypothesis-python-6.67.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ee2306484226..a0e8f1d71ffe 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.67.0; python_version >= "3.7" +hypothesis==6.67.1; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 50df392f3b8df43798124f8ea06ab3f3357ca4ee Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 6 Feb 2023 10:42:54 -0600 Subject: [PATCH 207/827] add support for centos9-fips (#8216) * add support for centos9-fips Requires a variety of new FIPS constraints on our tests, including the addition of rsa_encryption_supported * review comments --- .github/workflows/ci.yml | 1 + .../hazmat/backends/openssl/backend.py | 9 +++ tests/hazmat/backends/test_openssl.py | 10 ++- tests/hazmat/primitives/test_rsa.py | 77 +++++++++---------- tests/hazmat/primitives/test_ssh.py | 10 ++- tests/wycheproof/test_rsa.py | 36 ++++++--- tests/x509/test_x509.py | 4 +- 7 files changed, 90 insertions(+), 57 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d093eb9e428..1f7b246a149f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -147,6 +147,7 @@ jobs: - {IMAGE: "fedora", TOXENV: "py311", RUNNER: "ubuntu-latest"} - {IMAGE: "alpine", TOXENV: "py310", RUNNER: "ubuntu-latest"} - {IMAGE: "centos-stream9", TOXENV: "py39", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9-fips", TOXENV: "py39", RUNNER: "ubuntu-latest", FIPS: true} - {IMAGE: "ubuntu-jammy:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index db2dace37582..6f6fb9021304 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -781,6 +781,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PUBLIC_KEY_TYPES: raise UnsupportedAlgorithm("Unsupported key type.") def _oaep_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + if self._fips_enabled and isinstance(algorithm, hashes.SHA1): + return False + return isinstance( algorithm, ( @@ -811,6 +814,12 @@ def rsa_padding_supported(self, padding: AsymmetricPadding) -> bool: else: return False + def rsa_encryption_supported(self, padding: AsymmetricPadding) -> bool: + if self._fips_enabled and isinstance(padding, PKCS1v15): + return False + else: + return self.rsa_padding_supported(padding) + def generate_dsa_parameters(self, key_size: int) -> dsa.DSAParameters: if key_size not in (1024, 2048, 3072, 4096): raise ValueError( diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 8a0b46c9b044..2638add8d0fe 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -380,8 +380,8 @@ def test_rsa_padding_supported_oaep(self): assert ( backend.rsa_padding_supported( padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA1()), - algorithm=hashes.SHA1(), + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), label=None, ), ) @@ -397,6 +397,12 @@ def test_rsa_padding_supported_oaep_sha2_combinations(self): hashes.SHA512(), ] for mgf1alg, oaepalg in itertools.product(hashalgs, hashalgs): + if backend._fips_enabled and ( + isinstance(mgf1alg, hashes.SHA1) + or isinstance(oaepalg, hashes.SHA1) + ): + continue + assert ( backend.rsa_padding_supported( padding.OAEP( diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index a3fb50302082..02d16a54a519 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -438,6 +438,12 @@ def test_oaep_wrong_label(self, enclabel, declabel, backend): ), ) + @pytest.mark.supported( + only_if=lambda backend: backend.rsa_encryption_supported( + padding.PKCS1v15() + ), + skip_message="Does not support PKCS1v1.5.", + ) def test_lazy_blinding(self, backend): private_key = RSA_KEY_2048.private_key(backend) public_key = private_key.public_key() @@ -1668,7 +1674,7 @@ def test_invalid_algorithm(self): class TestRSADecryption: @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.PKCS1v15() ), skip_message="Does not support PKCS1v1.5.", @@ -1705,7 +1711,7 @@ def test_unsupported_padding(self, backend): @pytest.mark.supported( only_if=lambda backend: ( - backend.rsa_padding_supported(padding.PKCS1v15()) + backend.rsa_encryption_supported(padding.PKCS1v15()) and not backend._lib.Cryptography_HAS_IMPLICIT_RSA_REJECTION ), skip_message="Does not support PKCS1v1.5.", @@ -1716,7 +1722,7 @@ def test_decrypt_invalid_decrypt(self, backend): private_key.decrypt(b"\x00" * 256, padding.PKCS1v15()) @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.PKCS1v15() ), skip_message="Does not support PKCS1v1.5.", @@ -1727,7 +1733,7 @@ def test_decrypt_ciphertext_too_large(self, backend): private_key.decrypt(b"\x00" * 257, padding.PKCS1v15()) @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.PKCS1v15() ), skip_message="Does not support PKCS1v1.5.", @@ -1742,7 +1748,7 @@ def test_decrypt_ciphertext_too_small(self, backend): private_key.decrypt(ct, padding.PKCS1v15()) @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), @@ -1751,7 +1757,7 @@ def test_decrypt_ciphertext_too_small(self, backend): ), skip_message="Does not support OAEP.", ) - def test_decrypt_oaep_vectors(self, subtests, backend): + def test_decrypt_oaep_sha1_vectors(self, subtests, backend): for private, public, example in _flatten_pkcs1_examples( load_vectors_from_file( os.path.join( @@ -1782,22 +1788,20 @@ def test_decrypt_oaep_vectors(self, subtests, backend): ) assert message == binascii.unhexlify(example["message"]) - @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( - padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA224()), - algorithm=hashes.SHA224(), - label=None, - ) - ), - skip_message=( - "Does not support OAEP using SHA224 MGF1 and SHA224 hash." - ), - ) def test_decrypt_oaep_sha2_vectors(self, backend, subtests): vectors = _build_oaep_sha2_vectors() for private, public, example, mgf1_alg, hash_alg in vectors: with subtests.test(): + pad = padding.OAEP( + mgf=padding.MGF1(algorithm=mgf1_alg), + algorithm=hash_alg, + label=None, + ) + if not backend.rsa_encryption_supported(pad): + pytest.skip( + f"Does not support OAEP using {mgf1_alg.name} MGF1 " + f"or {hash_alg.name} hash." + ) skey = rsa.RSAPrivateNumbers( p=private["p"], q=private["q"], @@ -1811,16 +1815,12 @@ def test_decrypt_oaep_sha2_vectors(self, backend, subtests): ).private_key(backend, unsafe_skip_rsa_key_validation=True) message = skey.decrypt( binascii.unhexlify(example["encryption"]), - padding.OAEP( - mgf=padding.MGF1(algorithm=mgf1_alg), - algorithm=hash_alg, - label=None, - ), + pad, ) assert message == binascii.unhexlify(example["message"]) @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), @@ -1857,7 +1857,7 @@ def test_invalid_oaep_decryption(self, backend): ) @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), @@ -1909,7 +1909,7 @@ def test_unsupported_oaep_mgf(self, backend): class TestRSAEncryption: @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), @@ -1953,18 +1953,6 @@ def test_rsa_encrypt_oaep(self, key_data, pad, backend): recovered_pt = private_key.decrypt(ct, pad) assert recovered_pt == pt - @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( - padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA256()), - algorithm=hashes.SHA512(), - label=None, - ) - ), - skip_message=( - "Does not support OAEP using SHA256 MGF1 and SHA512 hash." - ), - ) @pytest.mark.parametrize( ("mgf1hash", "oaephash"), itertools.product( @@ -1990,6 +1978,11 @@ def test_rsa_encrypt_oaep_sha2(self, mgf1hash, oaephash, backend): algorithm=oaephash, label=None, ) + if not backend.rsa_encryption_supported(pad): + pytest.skip( + f"Does not support OAEP using {mgf1hash.name} MGF1 " + f"or {oaephash.name} hash." + ) private_key = RSA_KEY_2048.private_key(backend) pt = b"encrypt me using sha2 hashes!" public_key = private_key.public_key() @@ -2000,7 +1993,7 @@ def test_rsa_encrypt_oaep_sha2(self, mgf1hash, oaephash, backend): assert recovered_pt == pt @pytest.mark.supported( - only_if=lambda backend: backend.rsa_padding_supported( + only_if=lambda backend: backend.rsa_encryption_supported( padding.PKCS1v15() ), skip_message="Does not support PKCS1v1.5.", @@ -2051,8 +2044,8 @@ def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend): ), ( padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA1()), - algorithm=hashes.SHA1(), + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), label=None, ), padding.PKCS1v15(), @@ -2061,6 +2054,8 @@ def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend): ) def test_rsa_encrypt_key_too_small(self, key_data, pad, backend): private_key = key_data.private_key(backend) + if not backend.rsa_encryption_supported(pad): + pytest.skip("PKCS1v15 padding not allowed in FIPS") _check_fips_key_length(backend, private_key) public_key = private_key.public_key() # Slightly smaller than the key size but not enough for padding. diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 8403b9f88059..672e08e08141 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -1121,14 +1121,17 @@ def test_loads_ssh_cert(self, backend): "p256-rsa-sha512.pub", ], ) - def test_verify_cert_signature(self, filename): + def test_verify_cert_signature(self, filename, backend): data = load_vectors_from_file( os.path.join("asymmetric", "OpenSSH", "certs", filename), lambda f: f.read(), mode="rb", ) cert = load_ssh_public_identity(data) + # we have no public API for getting the hash alg of the sig assert isinstance(cert, SSHCertificate) + if backend._fips_enabled and bytes(cert._inner_sig_type) == b"ssh-rsa": + pytest.skip("FIPS does not support RSA SHA1") cert.verify_cert_signature() @pytest.mark.parametrize( @@ -1142,7 +1145,7 @@ def test_verify_cert_signature(self, filename): "p256-rsa-sha512.pub", ], ) - def test_invalid_signature(self, filename): + def test_invalid_signature(self, filename, backend): data = load_vectors_from_file( os.path.join("asymmetric", "OpenSSH", "certs", filename), lambda f: f.read(), @@ -1153,6 +1156,9 @@ def test_invalid_signature(self, filename): data[-10] = 71 cert = load_ssh_public_identity(data) assert isinstance(cert, SSHCertificate) + # we have no public API for getting the hash alg of the sig + if backend._fips_enabled and bytes(cert._inner_sig_type) == b"ssh-rsa": + pytest.skip("FIPS does not support RSA SHA1") with pytest.raises(InvalidSignature): cert.verify_cert_signature() diff --git a/tests/wycheproof/test_rsa.py b/tests/wycheproof/test_rsa.py index 56ec21bc073b..8ce1f8cbd854 100644 --- a/tests/wycheproof/test_rsa.py +++ b/tests/wycheproof/test_rsa.py @@ -103,7 +103,9 @@ def test_rsa_pkcs1v15_signature_generation(backend, wycheproof): digest = _DIGESTS[wycheproof.testgroup["sha"]] assert digest is not None if backend._fips_enabled: - if key.key_size < 2048 or isinstance(digest, hashes.SHA1): + if key.key_size < backend._fips_rsa_min_key_size or isinstance( + digest, hashes.SHA1 + ): pytest.skip( "Invalid params for FIPS. key: {} bits, digest: {}".format( key.key_size, digest.name @@ -130,11 +132,13 @@ def test_rsa_pkcs1v15_signature_generation(backend, wycheproof): "rsa_pss_misc_test.json", ) def test_rsa_pss_signature(backend, wycheproof): + digest = _DIGESTS[wycheproof.testgroup["sha"]] + if backend._fips_enabled and isinstance(digest, hashes.SHA1): + pytest.skip("Invalid params for FIPS. SHA1 is disallowed") key = serialization.load_der_public_key( binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend ) assert isinstance(key, rsa.RSAPublicKey) - digest = _DIGESTS[wycheproof.testgroup["sha"]] mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]] if digest is None or mgf_digest is None: @@ -189,23 +193,29 @@ def test_rsa_pss_signature(backend, wycheproof): "rsa_oaep_misc_test.json", ) def test_rsa_oaep_encryption(backend, wycheproof): - key = serialization.load_pem_private_key( - wycheproof.testgroup["privateKeyPem"].encode("ascii"), - password=None, - backend=backend, - unsafe_skip_rsa_key_validation=True, - ) - assert isinstance(key, rsa.RSAPrivateKey) digest = _DIGESTS[wycheproof.testgroup["sha"]] mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]] assert digest is not None assert mgf_digest is not None - padding_algo = padding.OAEP( mgf=padding.MGF1(algorithm=mgf_digest), algorithm=digest, label=binascii.unhexlify(wycheproof.testcase["label"]), ) + if not backend.rsa_encryption_supported(padding_algo): + pytest.skip( + f"Does not support OAEP using {mgf_digest.name} MGF1 " + f"or {digest.name} hash." + ) + key = serialization.load_pem_private_key( + wycheproof.testgroup["privateKeyPem"].encode("ascii"), + password=None, + backend=backend, + unsafe_skip_rsa_key_validation=True, + ) + assert isinstance(key, rsa.RSAPrivateKey) + if backend._fips_enabled and key.key_size < backend._fips_rsa_min_key_size: + pytest.skip("Invalid params for FIPS. <2048 bit keys are disallowed") if wycheproof.valid or wycheproof.acceptable: pt = key.decrypt( @@ -219,6 +229,12 @@ def test_rsa_oaep_encryption(backend, wycheproof): ) +@pytest.mark.supported( + only_if=lambda backend: backend.rsa_encryption_supported( + padding.PKCS1v15() + ), + skip_message="Does not support PKCS1v1.5 for encryption.", +) @wycheproof_tests( "rsa_pkcs1_2048_test.json", "rsa_pkcs1_3072_test.json", diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index ac73ad11c247..821f1fe87e80 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -4728,7 +4728,7 @@ def test_tbs_certificate_bytes(self, backend): cert.signature_hash_algorithm, ) - def test_verify_directly_issued_by_dsa(self): + def test_verify_directly_issued_by_dsa(self, backend): issuer_private_key = DSA_KEY_3072.private_key() subject_private_key = DSA_KEY_2048.private_key() ca, cert = _generate_ca_and_leaf( @@ -4736,7 +4736,7 @@ def test_verify_directly_issued_by_dsa(self): ) cert.verify_directly_issued_by(ca) - def test_verify_directly_issued_by_dsa_bad_sig(self): + def test_verify_directly_issued_by_dsa_bad_sig(self, backend): issuer_private_key = DSA_KEY_3072.private_key() subject_private_key = DSA_KEY_2048.private_key() ca, cert = _generate_ca_and_leaf( From 957507ffe92c4ac87d21f44df4d5f4bf9b7aef98 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Feb 2023 20:56:24 -0500 Subject: [PATCH 208/827] workaround scapy bug in downstream tests (#8218) --- .github/downstream.d/scapy.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/downstream.d/scapy.sh b/.github/downstream.d/scapy.sh index ac1b8f820016..5ef3648ae2df 100755 --- a/.github/downstream.d/scapy.sh +++ b/.github/downstream.d/scapy.sh @@ -5,7 +5,8 @@ case "${1}" in git clone --depth=1 https://github.com/secdev/scapy cd scapy git rev-parse HEAD - pip install tox + # Pin virtualenv until https://github.com/secdev/scapy/pull/3862 is merged + pip install tox 'virtualenv<20.18' ;; run) cd scapy From 05986e499c01e9eca4e0168b769ccc493dc89682 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 03:39:21 +0000 Subject: [PATCH 209/827] Bump BoringSSL and/or OpenSSL in CI (#8217) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f7b246a149f..5eb7f6de3f0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 04, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "eb0b7e4df6eb5a082c2b977784f4270b55c58361"}} - # Latest commit on the OpenSSL master branch, as of Feb 03, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "323c47532ea7fc79d5e28a0fa58ea0cc4d5196b8"}} + # Latest commit on the BoringSSL master branch, as of Feb 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "60d61196e43cfcea45936de667f98f5d6a6fa684"}} + # Latest commit on the OpenSSL master branch, as of Feb 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cded5d05253df6eb29e025ab25d763805493479a"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 4cb4b42b9087e51ccaacb6ea5a4ed911b2daafae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 12:42:28 +0000 Subject: [PATCH 210/827] Bump types-requests from 2.28.11.8 to 2.28.11.11 (#8220) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.8 to 2.28.11.11. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a0e8f1d71ffe..9dca8bd1364d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -207,7 +207,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.0 # via cryptography (setup.cfg) -types-requests==2.28.11.8 +types-requests==2.28.11.11 # via cryptography (setup.cfg) types-urllib3==1.26.25.4 # via types-requests From 69614825f87640683ba7b0424a4f4986821e5a40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 12:49:57 +0000 Subject: [PATCH 211/827] Bump mypy from 0.991 to 1.0.0 (#8222) Bumps [mypy](https://github.com/python/mypy) from 0.991 to 1.0.0. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.991...v1.0.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9dca8bd1364d..80b4078bbfbf 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -80,7 +80,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.0.0 # via jaraco-classes -mypy==0.991 +mypy==1.0.0 # via cryptography (setup.cfg) mypy-extensions==1.0.0 # via From 118868ef71fa667b19c812012b5ed7f8aeb96321 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 13:16:42 +0000 Subject: [PATCH 212/827] Bump types-urllib3 from 1.26.25.4 to 1.26.25.5 (#8223) Bumps [types-urllib3](https://github.com/python/typeshed) from 1.26.25.4 to 1.26.25.5. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 80b4078bbfbf..13f0a8bfaaa1 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -209,7 +209,7 @@ types-pytz==2022.7.1.0 # via cryptography (setup.cfg) types-requests==2.28.11.11 # via cryptography (setup.cfg) -types-urllib3==1.26.25.4 +types-urllib3==1.26.25.5 # via types-requests typing-extensions==4.4.0; python_version >= "3.7" # via mypy From d9053ae63e3539d0d3e39f9ce29780c38fe28b31 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 08:39:54 -0500 Subject: [PATCH 213/827] update virtualenv only on py37+ (#8226) it has a new minimum python --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 13f0a8bfaaa1..8bf99d3c1356 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -217,7 +217,7 @@ urllib3==1.26.14 # via # requests # twine -virtualenv==20.17.1 +virtualenv==20.18.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach From 67a8facee0f9e29f3eea60381a657cd34a58ddb4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 08:40:55 -0500 Subject: [PATCH 214/827] ignore a new ruff warning type (#8225) * ignore a new ruff warning type * Update ci-constraints-requirements.txt --- ci-constraints-requirements.txt | 2 +- pyproject.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8bf99d3c1356..1d1bd8b00d57 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.241 +ruff==0.0.243 # via cryptography (setup.cfg) six==1.16.0 # via bleach diff --git a/pyproject.toml b/pyproject.toml index 2cb1643deac5..ed0046665a4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,8 @@ exclude = [ '_build', '.hypothesis', ] -ignore = ['N818', 'UP003', 'UP006', 'UP007'] +# UP007 and UP037 require a higher minimum Python version +ignore = ['N818', 'UP003', 'UP006', 'UP007', 'UP037'] select = ['E', 'F', 'I', 'N', 'W', 'UP'] line-length = 79 From 54c72f162b0e5e1f267816c2300353c7489fa34d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 08:41:12 -0500 Subject: [PATCH 215/827] ignore a new ruff warning type (#8225) * ignore a new ruff warning type * Update ci-constraints-requirements.txt From b2edd2e3e2a2b3e760a2b55eedae511aba7f1d9e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 09:05:25 -0500 Subject: [PATCH 216/827] always specify a minimum bound on tox (#8227) this prevents catastrophic backtracking and favors pip resolution errors over insanely old packages leading to runtime errors --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5eb7f6de3f0f..081a1c99723d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,7 +75,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] - name: Compute config hash and set config vars run: | DEFAULT_CONFIG_FLAGS="shared no-ssl2 no-ssl3" @@ -193,7 +193,7 @@ jobs: echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt tox coverage + - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage - run: '/venv/bin/tox -vvv --notest' env: TOXENV: ${{ matrix.IMAGE.TOXENV }} @@ -259,7 +259,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Create toxenv run: tox -vvv --notest env: @@ -320,7 +320,7 @@ jobs: repository: "google/wycheproof" path: "wycheproof" ref: "master" - - run: python -m pip install -c ci-constraints-requirements.txt tox coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Create toxenv run: tox -vvv --notest env: @@ -407,7 +407,7 @@ jobs: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 - - run: python -m pip install -c ci-constraints-requirements.txt tox requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] - uses: actions/checkout@v3.3.0 timeout-minutes: 3 From 9fbf84efc861668755ab645530ec7be9cf3c6696 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 11:34:18 -0500 Subject: [PATCH 217/827] Don't allow update_into to mutate immutable objects (#8230) --- src/cryptography/hazmat/backends/openssl/ciphers.py | 2 +- tests/hazmat/primitives/test_ciphers.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index 286583f93255..075d68fb9057 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -156,7 +156,7 @@ def update_into(self, data: bytes, buf: bytes) -> int: data_processed = 0 total_out = 0 outlen = self._backend._ffi.new("int *") - baseoutbuf = self._backend._ffi.from_buffer(buf) + baseoutbuf = self._backend._ffi.from_buffer(buf, require_writable=True) baseinbuf = self._backend._ffi.from_buffer(data) while data_processed != total_data_len: diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py index 02127dd9cab5..bf3b047dec25 100644 --- a/tests/hazmat/primitives/test_ciphers.py +++ b/tests/hazmat/primitives/test_ciphers.py @@ -318,6 +318,14 @@ def test_update_into_buffer_too_small(self, backend): with pytest.raises(ValueError): encryptor.update_into(b"testing", buf) + def test_update_into_immutable(self, backend): + key = b"\x00" * 16 + c = ciphers.Cipher(AES(key), modes.ECB(), backend) + encryptor = c.encryptor() + buf = b"\x00" * 32 + with pytest.raises((TypeError, BufferError)): + encryptor.update_into(b"testing", buf) + @pytest.mark.supported( only_if=lambda backend: backend.cipher_supported( AES(b"\x00" * 16), modes.GCM(b"\x00" * 12) From 75e3d1615e87e0b48c493568db4df79618365b17 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Feb 2023 12:30:59 -0600 Subject: [PATCH 218/827] port changelog to main (#8232) --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dd17b2b530a8..40850c1ca38f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -32,6 +32,15 @@ Changelog * Added :meth:`~cryptography.x509.Certificate.verify_directly_issued_by` to :class:`~cryptography.x509.Certificate`. +.. _v39-0-1: + +39.0.1 - 2023-02-07 +~~~~~~~~~~~~~~~~~~~ + +* **SECURITY ISSUE** - Fixed a bug where ``Cipher.update_into`` accepted Python + buffer protocol objects, but allowed immutable buffers. **CVE-2023-23931** +* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.0.8. + .. _v39-0-0: 39.0.0 - 2023-01-01 From 9dcdd88d56c3ac6d85c25ed1390eb152db3dfa97 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 00:19:34 +0000 Subject: [PATCH 219/827] Bump BoringSSL and/or OpenSSL in CI (#8233) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 081a1c99723d..f9dc3472992f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "60d61196e43cfcea45936de667f98f5d6a6fa684"}} - # Latest commit on the OpenSSL master branch, as of Feb 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cded5d05253df6eb29e025ab25d763805493479a"}} + # Latest commit on the BoringSSL master branch, as of Feb 08, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "908b1300ff4ed3cfc3c965d846560f2593a51491"}} + # Latest commit on the OpenSSL master branch, as of Feb 08, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4072a762664020524f536361a6de43e8de19a4f8"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 70af2734ec5f760b8f8be53ca58e9715b7122275 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Feb 2023 21:04:07 -0500 Subject: [PATCH 220/827] bump openssl for releases today (#8234) --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9dc3472992f..a777c57560a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,15 +25,15 @@ jobs: PYTHON: - {VERSION: "3.11", TOXENV: "flake"} - {VERSION: "3.11", TOXENV: "rust"} - - {VERSION: "3.11", TOXENV: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.0.7"}} + - {VERSION: "3.11", TOXENV: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} - {VERSION: "pypy-3.8", TOXENV: "pypy3-nocoverage"} - {VERSION: "pypy-3.9", TOXENV: "pypy3-nocoverage"} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1s"}} - - {VERSION: "3.11", TOXENV: "py311-ssh", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1s"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1s", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.7"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.7", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.0.7"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} + - {VERSION: "3.11", TOXENV: "py311-ssh", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} + - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.0.8"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0-beta1"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.3"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.1"}} From 3f0547f93d3b5bbcf3dcc64f24c93a606a767312 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 07:54:20 -0500 Subject: [PATCH 221/827] Bump pytest-xdist from 3.1.0 to 3.2.0 (#8241) Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/pytest-dev/pytest-xdist/releases) - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.1.0...v3.2.0) --- updated-dependencies: - dependency-name: pytest-xdist dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1d1bd8b00d57..f43375c2b53a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -142,7 +142,7 @@ pytest-shard==0.1.2 # via cryptography (setup.cfg) pytest-subtests==0.9.0; python_version >= "3.7" # via cryptography (setup.cfg) -pytest-xdist==3.1.0; python_version >= "3.7" +pytest-xdist==3.2.0; python_version >= "3.7" # via cryptography (setup.cfg) pytz==2022.7.1 # via From fffac8d75252c787adc3c7dc8d826ae2628b487e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 07:55:22 -0500 Subject: [PATCH 222/827] Bump virtualenv from 20.18.0 to 20.19.0 (#8240) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.18.0 to 20.19.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.18.0...20.19.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f43375c2b53a..529ee0805288 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -217,7 +217,7 @@ urllib3==1.26.14 # via # requests # twine -virtualenv==20.18.0; python_version >= "3.7" +virtualenv==20.19.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach From 21f45742c97c5efd34c9675e6b3df48c514b4e6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 07:55:50 -0500 Subject: [PATCH 223/827] Bump types-requests from 2.28.11.11 to 2.28.11.12 (#8239) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.11 to 2.28.11.12. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 529ee0805288..b2802074c812 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -207,7 +207,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.0 # via cryptography (setup.cfg) -types-requests==2.28.11.11 +types-requests==2.28.11.12 # via cryptography (setup.cfg) types-urllib3==1.26.25.5 # via types-requests From 65d2da484677ea35aca6e81f828ee901271e0d91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 07:57:41 -0500 Subject: [PATCH 224/827] Bump sphinx-rtd-theme from 1.1.1 to 1.2.0 (#8238) Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 1.1.1 to 1.2.0. - [Release notes](https://github.com/readthedocs/sphinx_rtd_theme/releases) - [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst) - [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/1.1.1...1.2.0) --- updated-dependencies: - dependency-name: sphinx-rtd-theme dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b2802074c812..616117116902 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -174,7 +174,7 @@ sphinx==5.3.0 # cryptography (setup.cfg) # sphinx-rtd-theme # sphinxcontrib-spelling -sphinx-rtd-theme==1.1.1 +sphinx-rtd-theme==1.2.0 # via cryptography (setup.cfg) sphinxcontrib-applehelp==1.0.4 # via sphinx From 27661088f8400c8a5f1826228c1ec0a363544ef0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:21:17 +0000 Subject: [PATCH 225/827] Bump tox from 4.4.4 to 4.4.5 (#8237) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.4 to 4.4.5. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.4...4.4.5) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 616117116902..3ea595047d94 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -201,7 +201,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.4; python_version >= "3.7" +tox==4.4.5; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 57705949ccf8ff90f1f9fe85d047097df343e84f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:45:09 +0000 Subject: [PATCH 226/827] Bump platformdirs from 2.6.2 to 3.0.0 (#8221) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 2.6.2 to 3.0.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/2.6.2...3.0.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3ea595047d94..4d1409f017a6 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -97,7 +97,7 @@ pathspec==0.11.0 # via black pkginfo==1.9.6 # via twine -platformdirs==2.6.2; python_version >= "3.7" +platformdirs==3.0.0; python_version >= "3.7" # via # black # tox From 49965cc078d628974320fe7d2c922978cf94df9d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Feb 2023 08:19:35 -0600 Subject: [PATCH 227/827] use the modern invocation for our sphinx rtd theme (#8243) * use the modern invocation for our sphinx rtd theme * works with sphinx6? --- ci-constraints-requirements.txt | 7 +++++-- docs/conf.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4d1409f017a6..ecdeb7630ffc 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -37,7 +37,7 @@ coverage==7.1.0; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv -docutils==0.17.1 +docutils==0.18.1 # via # readme-renderer # sphinx @@ -88,6 +88,7 @@ mypy-extensions==1.0.0 # mypy packaging==23.0; python_version >= "3.7" # via + # black # build # pyproject-api # pytest @@ -169,7 +170,7 @@ snowballstemmer==2.2.0 # via sphinx sortedcontainers==2.4.0 # via hypothesis -sphinx==5.3.0 +sphinx==6.1.3 # via # cryptography (setup.cfg) # sphinx-rtd-theme @@ -182,6 +183,8 @@ sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.1 # via sphinx +sphinxcontrib-jquery==2.0.0 + # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 diff --git a/docs/conf.py b/docs/conf.py index 0c69fc85b15d..e5b1146c0704 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -47,6 +47,7 @@ "sphinx.ext.intersphinx", "sphinx.ext.linkcode", "cryptography-docs", + "sphinx_rtd_theme", ] if spelling is not None: @@ -123,7 +124,6 @@ if sphinx_rtd_theme: html_theme = "sphinx_rtd_theme" - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] else: html_theme = "default" From 6537aa354b5dca0e6c01a2fc4dd11b02844d6556 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Feb 2023 08:50:58 -0600 Subject: [PATCH 228/827] use newer versions of everything for rtd builds (#8244) --- .readthedocs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index e615d30d52c1..95b3c4f46e7c 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,10 +9,10 @@ sphinx: build: # readdocs master now includes a rust toolchain - os: "ubuntu-20.04" + os: "ubuntu-22.04" tools: - python: "3.9" - rust: "1.55" + python: "3.11" + rust: "1.64" python: install: From 05105c8397b3eee03503a992375c01d61f0fe0a7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Feb 2023 11:19:46 -0600 Subject: [PATCH 229/827] fix some pytest warnings (#8245) this code will be gone soon, but it's easy enough to fix --- tests/hazmat/backends/test_openssl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 2638add8d0fe..6188689cdd75 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -181,7 +181,7 @@ def test_bn_to_int(self): ) @pytest.mark.skip_fips(reason="osrandom engine disabled for FIPS") class TestOpenSSLRandomEngine: - def setup(self): + def setup_method(self): # The default RAND engine is global and shared between # tests. We make sure that the default engine is osrandom # before we start each test and restore the global state to @@ -190,7 +190,7 @@ def setup(self): name = backend._lib.ENGINE_get_name(current_default) assert name == backend._lib.Cryptography_osrandom_engine_name - def teardown(self): + def teardown_method(self): # we need to reset state to being default. backend is a shared global # for all these tests. backend.activate_osrandom_engine() From 89a17e6414f3f6f97350c6d175af769a53a49c2d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Feb 2023 14:20:38 -0500 Subject: [PATCH 230/827] bump libressl versions (#8246) --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a777c57560a9..d04428021fef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,8 +35,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.0.8"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0-beta1"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.3"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.1"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} From 6405f0ee3c85dbffe2452bae4fc0fa4ca5c85a88 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 00:21:54 +0000 Subject: [PATCH 231/827] Bump BoringSSL and/or OpenSSL in CI (#8247) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d04428021fef..8eb1dd1228e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 08, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "908b1300ff4ed3cfc3c965d846560f2593a51491"}} - # Latest commit on the OpenSSL master branch, as of Feb 08, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4072a762664020524f536361a6de43e8de19a4f8"}} + # Latest commit on the BoringSSL master branch, as of Feb 09, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "04b3a96452b57f74f9768b1126f35b7398ddfff3"}} + # Latest commit on the OpenSSL master branch, as of Feb 09, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4596c20b86871b2bb0f9a7f6b855c0b7f0d4fbf3"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From ed1605a29e3e2b77fe651742b29a4c954b06c779 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 12:26:41 +0000 Subject: [PATCH 232/827] Bump ruff from 0.0.243 to 0.0.244 (#8248) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.243 to 0.0.244. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.243...v0.0.244) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ecdeb7630ffc..585b4af516c3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.243 +ruff==0.0.244 # via cryptography (setup.cfg) six==1.16.0 # via bleach From d7d698a1565f9ea60aaf22b8a59083384db407c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 12:53:48 +0000 Subject: [PATCH 233/827] Bump hypothesis from 6.67.1 to 6.68.0 (#8250) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.67.1 to 6.68.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.67.1...hypothesis-python-6.68.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 585b4af516c3..9295602f926b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.67.1; python_version >= "3.7" +hypothesis==6.68.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 850a064c71d538283053460748aeaac6ac84d4da Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 9 Feb 2023 10:23:57 -0600 Subject: [PATCH 234/827] fix extraneous exclude preventing pypy38 linux wheels from existing (#8252) --- .github/workflows/wheel-builder.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 7b8cdabbf1a4..bb8b3fbc21a4 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -84,7 +84,6 @@ jobs: MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} - PYTHON: { VERSION: "pp39-pypy39_pp73" } MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} - - PYTHON: { VERSION: "pp38-pypy38_pp73" } name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}" steps: - name: Ridiculous alpine workaround for actions support on arm64 From fb7df6225aeede9a9eccfe2235c9ca0a0cbb3746 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 00:23:26 +0000 Subject: [PATCH 235/827] Bump BoringSSL and/or OpenSSL in CI (#8254) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8eb1dd1228e3..b71f6b4009e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 09, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "04b3a96452b57f74f9768b1126f35b7398ddfff3"}} + # Latest commit on the BoringSSL master branch, as of Feb 10, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "9580424ca8579317d0ccf1d8db5e58539f239a20"}} # Latest commit on the OpenSSL master branch, as of Feb 09, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4596c20b86871b2bb0f9a7f6b855c0b7f0d4fbf3"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From d97c7071b9e364ecce187a51048c6e1ca5752d6b Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 10 Feb 2023 13:04:55 +0100 Subject: [PATCH 236/827] Remove redundant ruff excludes (#8256) Ruff ignores anything in gitignore by default, so these are all redundant. --- pyproject.toml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ed0046665a4f..e4f17dc5f0a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,13 +64,6 @@ exclude_lines = [ ] [tool.ruff] -exclude = [ - '.tox', - '*.egg', - '.git', - '_build', - '.hypothesis', -] # UP007 and UP037 require a higher minimum Python version ignore = ['N818', 'UP003', 'UP006', 'UP007', 'UP037'] select = ['E', 'F', 'I', 'N', 'W', 'UP'] From bbf65f6b87a851075c3227fe70f49aab7fb80a41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:13:28 +0000 Subject: [PATCH 237/827] Bump actions/cache from 3.2.4 to 3.2.5 (#8258) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.4 to 3.2.5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.4...v3.2.5) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b71f6b4009e2..8e6b5b6aa7b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | @@ -89,7 +89,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load cache - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 id: ossl-cache timeout-minutes: 5 with: @@ -166,7 +166,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | @@ -233,7 +233,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | @@ -294,7 +294,7 @@ jobs: with: toolchain: ${{ matrix.RUST }} components: llvm-tools-preview - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 id: cargo-cache timeout-minutes: 5 with: @@ -388,7 +388,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | @@ -463,7 +463,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | @@ -531,7 +531,7 @@ jobs: timeout-minutes: 3 with: persist-credentials: false - - uses: actions/cache@v3.2.4 + - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: path: | From 82a648912e6742e9e6f798062e42b4daf72ec359 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:24:14 +0000 Subject: [PATCH 238/827] Bump zipp from 3.12.1 to 3.13.0 (#8259) Bumps [zipp](https://github.com/jaraco/zipp) from 3.12.1 to 3.13.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.12.1...v3.13.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9295602f926b..b2508a8a2ff7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -224,7 +224,7 @@ virtualenv==20.19.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach -zipp==3.12.1; python_version >= "3.7" +zipp==3.13.0; python_version >= "3.7" # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From 09c32d70b77e37ad96784608a7c79b6aa1e19589 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:24:13 -0600 Subject: [PATCH 239/827] Bump BoringSSL and/or OpenSSL in CI (#8261) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e6b5b6aa7b4..03553ed85dbf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 10, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "9580424ca8579317d0ccf1d8db5e58539f239a20"}} + # Latest commit on the BoringSSL master branch, as of Feb 11, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ace33161544814ed6dc9e9d17cfde0422881b9d2"}} # Latest commit on the OpenSSL master branch, as of Feb 09, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4596c20b86871b2bb0f9a7f6b855c0b7f0d4fbf3"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From f8c98d21d303f992660486af13b70659d52e2701 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 10 Feb 2023 20:23:04 -0600 Subject: [PATCH 240/827] remove verify_interface (#8260) * remove verify_interface * ruff ruff --- src/cryptography/utils.py | 11 ----------- tests/test_interfaces.py | 20 -------------------- 2 files changed, 31 deletions(-) delete mode 100644 tests/test_interfaces.py diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 8a97535203a3..b8da26bdd8ae 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -3,7 +3,6 @@ # for complete details. -import abc import enum import sys import types @@ -48,16 +47,6 @@ class InterfaceNotImplemented(Exception): pass -# DeprecatedIn39 -- Our only known consumer is aws-encryption-sdk, but we've -# made this a no-op to avoid breaking old versions. -def verify_interface( - iface: abc.ABCMeta, klass: object, *, check_annotations: bool = False -): - # Exists exclusively for `aws-encryption-sdk` which relies on it existing, - # even though it was never a public API. - pass - - class _DeprecatedValue: def __init__(self, value: object, message: str, warning_class): self.value = value diff --git a/tests/test_interfaces.py b/tests/test_interfaces.py deleted file mode 100644 index 06c09f32739c..000000000000 --- a/tests/test_interfaces.py +++ /dev/null @@ -1,20 +0,0 @@ -# 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. - -import abc - -from cryptography.utils import verify_interface - - -class TestVerifyInterface: - def test_noop(self): - class SimpleInterface(metaclass=abc.ABCMeta): - @abc.abstractmethod - def method(self): - """A simple method""" - - class NonImplementer: - pass - - verify_interface(SimpleInterface, NonImplementer) From efbc6be009c52f0fa82081c912a9a8872b8937b5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Feb 2023 10:08:46 -0500 Subject: [PATCH 241/827] Simplify X25519 key loading (#8263) --- src/_cffi_src/openssl/cryptography.py | 2 + .../hazmat/backends/openssl/backend.py | 58 ++++--------------- .../hazmat/backends/openssl/x25519.py | 38 +++++------- 3 files changed, 25 insertions(+), 73 deletions(-) diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py index e12e36549528..84c0cf360727 100644 --- a/src/_cffi_src/openssl/cryptography.py +++ b/src/_cffi_src/openssl/cryptography.py @@ -86,6 +86,8 @@ static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE; static const int CRYPTOGRAPHY_HAS_WORKING_ED25519; +static const int CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370; + static const int CRYPTOGRAPHY_IS_LIBRESSL; static const int CRYPTOGRAPHY_IS_BORINGSSL; """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 6f6fb9021304..49e94b122fef 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1838,54 +1838,29 @@ def dh_x942_serialization_supported(self) -> bool: return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1 def x25519_load_public_bytes(self, data: bytes) -> x25519.X25519PublicKey: - # If/when LibreSSL adds support for EVP_PKEY_new_raw_public_key we - # can switch to it (Cryptography_HAS_RAW_KEY) if len(data) != 32: raise ValueError("An X25519 public key is 32 bytes long") - evp_pkey = self._create_evp_pkey_gc() - res = self._lib.EVP_PKEY_set_type(evp_pkey, self._lib.NID_X25519) - self.openssl_assert(res == 1) - res = self._lib.EVP_PKEY_set1_tls_encodedpoint( - evp_pkey, data, len(data) + data_ptr = self._ffi.from_buffer(data) + evp_pkey = self._lib.EVP_PKEY_new_raw_public_key( + self._lib.NID_X25519, self._ffi.NULL, data_ptr, len(data) ) - self.openssl_assert(res == 1) + self.openssl_assert(evp_pkey != self._ffi.NULL) + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) return _X25519PublicKey(self, evp_pkey) def x25519_load_private_bytes( self, data: bytes ) -> x25519.X25519PrivateKey: - # If/when LibreSSL adds support for EVP_PKEY_new_raw_private_key we - # can switch to it (Cryptography_HAS_RAW_KEY) drop the - # zeroed_bytearray garbage. - # OpenSSL only has facilities for loading PKCS8 formatted private - # keys using the algorithm identifiers specified in - # https://tools.ietf.org/html/draft-ietf-curdle-pkix-09. - # This is the standard PKCS8 prefix for a 32 byte X25519 key. - # The form is: - # 0:d=0 hl=2 l= 46 cons: SEQUENCE - # 2:d=1 hl=2 l= 1 prim: INTEGER :00 - # 5:d=1 hl=2 l= 5 cons: SEQUENCE - # 7:d=2 hl=2 l= 3 prim: OBJECT :1.3.101.110 - # 12:d=1 hl=2 l= 34 prim: OCTET STRING (the key) - # Of course there's a bit more complexity. In reality OCTET STRING - # contains an OCTET STRING of length 32! So the last two bytes here - # are \x04\x20, which is an OCTET STRING of length 32. if len(data) != 32: raise ValueError("An X25519 private key is 32 bytes long") - pkcs8_prefix = b'0.\x02\x01\x000\x05\x06\x03+en\x04"\x04 ' - with self._zeroed_bytearray(48) as ba: - ba[0:16] = pkcs8_prefix - ba[16:] = data - bio = self._bytes_to_bio(ba) - evp_pkey = self._lib.d2i_PrivateKey_bio(bio.bio, self._ffi.NULL) - + data_ptr = self._ffi.from_buffer(data) + evp_pkey = self._lib.EVP_PKEY_new_raw_private_key( + self._lib.NID_X25519, self._ffi.NULL, data_ptr, len(data) + ) self.openssl_assert(evp_pkey != self._ffi.NULL) evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - self.openssl_assert( - self._lib.EVP_PKEY_id(evp_pkey) == self._lib.EVP_PKEY_X25519 - ) return _X25519PrivateKey(self, evp_pkey) def _evp_pkey_keygen_gc(self, nid): @@ -1908,7 +1883,7 @@ def x25519_generate_key(self) -> x25519.X25519PrivateKey: def x25519_supported(self) -> bool: if self._fips_enabled: return False - return not self._lib.CRYPTOGRAPHY_IS_LIBRESSL + return not self._lib.CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 def x448_load_public_bytes(self, data: bytes) -> x448.X448PublicKey: if len(data) != 56: @@ -2074,19 +2049,6 @@ def aead_cipher_supported(self, cipher) -> bool: self._lib.EVP_get_cipherbyname(cipher_name) != self._ffi.NULL ) - @contextlib.contextmanager - def _zeroed_bytearray(self, length: int) -> typing.Iterator[bytearray]: - """ - This method creates a bytearray, which we copy data into (hopefully - also from a mutable buffer that can be dynamically erased!), and then - zero when we're done. - """ - ba = bytearray(length) - try: - yield ba - finally: - self._zero_data(ba, length) - def _zero_data(self, data, length: int) -> None: # We clear things this way because at the moment we're not # sure of a better way that can guarantee it overwrites the diff --git a/src/cryptography/hazmat/backends/openssl/x25519.py b/src/cryptography/hazmat/backends/openssl/x25519.py index e3b41eced1a5..b7f9406c7b2a 100644 --- a/src/cryptography/hazmat/backends/openssl/x25519.py +++ b/src/cryptography/hazmat/backends/openssl/x25519.py @@ -47,16 +47,14 @@ def public_bytes( ) def _raw_public_bytes(self) -> bytes: - ucharpp = self._backend._ffi.new("unsigned char **") - res = self._backend._lib.EVP_PKEY_get1_tls_encodedpoint( - self._evp_pkey, ucharpp + buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE) + buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE) + res = self._backend._lib.EVP_PKEY_get_raw_public_key( + self._evp_pkey, buf, buflen ) - self._backend.openssl_assert(res == 32) - self._backend.openssl_assert(ucharpp[0] != self._backend._ffi.NULL) - data = self._backend._ffi.gc( - ucharpp[0], self._backend._lib.OPENSSL_free - ) - return self._backend._ffi.buffer(data, res)[:] + self._backend.openssl_assert(res == 1) + self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE) + return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:] class _X25519PrivateKey(X25519PrivateKey): @@ -112,21 +110,11 @@ def private_bytes( ) def _raw_private_bytes(self) -> bytes: - # If/when LibreSSL adds support for EVP_PKEY_get_raw_private_key we - # can switch to it (Cryptography_HAS_RAW_KEY) - # The trick we use here is serializing to a PKCS8 key and just - # using the last 32 bytes, which is the key itself. - bio = self._backend._create_mem_bio_gc() - res = self._backend._lib.i2d_PKCS8PrivateKey_bio( - bio, - self._evp_pkey, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - 0, - self._backend._ffi.NULL, - self._backend._ffi.NULL, + buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE) + buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE) + res = self._backend._lib.EVP_PKEY_get_raw_private_key( + self._evp_pkey, buf, buflen ) self._backend.openssl_assert(res == 1) - pkcs8 = self._backend._read_mem_bio(bio) - self._backend.openssl_assert(len(pkcs8) == 48) - return pkcs8[-_X25519_KEY_SIZE:] + self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE) + return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:] From 9ef7b27b731cb6ffa10e7bff420453e96bf8163a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Feb 2023 10:26:43 -0500 Subject: [PATCH 242/827] Remove now-unused bindings (#8264) --- src/_cffi_src/openssl/evp.py | 13 ------------- .../hazmat/bindings/openssl/_conditional.py | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index 44e8a6e29ddc..357de292403e 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -34,7 +34,6 @@ static const int Cryptography_HAS_EVP_PKEY_set_alias_type; static const int Cryptography_HAS_SCRYPT; static const int Cryptography_HAS_EVP_PKEY_DHX; -static const int Cryptography_HAS_EVP_PKEY_get_set_tls_encodedpoint; static const long Cryptography_HAS_RAW_KEY; static const long Cryptography_HAS_EVP_DIGESTFINAL_XOF; static const long Cryptography_HAS_300_FIPS; @@ -134,9 +133,6 @@ const unsigned char *, size_t); int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t, const unsigned char *, size_t); -size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *, unsigned char **); -int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *, const unsigned char *, - size_t); int EVP_PKEY_bits(const EVP_PKEY *); @@ -199,15 +195,6 @@ static const long Cryptography_HAS_SCRYPT = 1; #endif -#if !CRYPTOGRAPHY_IS_LIBRESSL -static const long Cryptography_HAS_EVP_PKEY_get_set_tls_encodedpoint = 1; -#else -static const long Cryptography_HAS_EVP_PKEY_get_set_tls_encodedpoint = 0; -size_t (*EVP_PKEY_get1_tls_encodedpoint)(EVP_PKEY *, unsigned char **) = NULL; -int (*EVP_PKEY_set1_tls_encodedpoint)(EVP_PKEY *, const unsigned char *, - size_t) = NULL; -#endif - #if CRYPTOGRAPHY_IS_LIBRESSL static const long Cryptography_HAS_EVP_DIGESTFINAL_XOF = 0; int (*EVP_DigestFinalXOF)(EVP_MD_CTX *, unsigned char *, size_t) = NULL; diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 7903a9bb4543..af4ce33db443 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -101,13 +101,6 @@ def cryptography_has_evp_digestfinal_xof() -> typing.List[str]: ] -def cryptography_has_evp_pkey_get_set_tls_encodedpoint() -> typing.List[str]: - return [ - "EVP_PKEY_get1_tls_encodedpoint", - "EVP_PKEY_set1_tls_encodedpoint", - ] - - def cryptography_has_fips() -> typing.List[str]: return [ "FIPS_mode_set", @@ -321,9 +314,6 @@ def cryptography_has_get_extms_support() -> typing.List[str]: "Cryptography_HAS_ED448": cryptography_has_ed448, "Cryptography_HAS_ED25519": cryptography_has_ed25519, "Cryptography_HAS_POLY1305": cryptography_has_poly1305, - "Cryptography_HAS_EVP_PKEY_get_set_tls_encodedpoint": ( - cryptography_has_evp_pkey_get_set_tls_encodedpoint - ), "Cryptography_HAS_FIPS": cryptography_has_fips, "Cryptography_HAS_SIGALGS": cryptography_has_ssl_sigalgs, "Cryptography_HAS_PSK": cryptography_has_psk, From 33ed1c4dcaad2ccc97354e3f010f21c0149687f2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Feb 2023 16:58:43 -0500 Subject: [PATCH 243/827] Added type annotations for more things in backend (#8265) --- .../hazmat/backends/openssl/backend.py | 31 ++++++++++++------- .../hazmat/primitives/_cipheralgorithm.py | 2 +- .../hazmat/primitives/ciphers/algorithms.py | 20 ++++++------ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 49e94b122fef..73ac123fde28 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -177,13 +177,16 @@ class Backend: _fips_dh_min_key_size = 2048 _fips_dh_min_modulus = 1 << _fips_dh_min_key_size - def __init__(self): + def __init__(self) -> None: self._binding = binding.Binding() self._ffi = self._binding.ffi self._lib = self._binding.lib self._fips_enabled = self._is_fips_enabled() - self._cipher_registry = {} + self._cipher_registry: typing.Dict[ + typing.Tuple[typing.Type[CipherAlgorithm], typing.Type[Mode]], + typing.Callable, + ] = {} self._register_default_ciphers() if self._fips_enabled and self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE: warnings.warn( @@ -367,7 +370,7 @@ def cipher_supported(self, cipher: CipherAlgorithm, mode: Mode) -> bool: evp_cipher = adapter(self, cipher, mode) return self._ffi.NULL != evp_cipher - def register_cipher_adapter(self, cipher_cls, mode_cls, adapter): + def register_cipher_adapter(self, cipher_cls, mode_cls, adapter) -> None: if (cipher_cls, mode_cls) in self._cipher_registry: raise ValueError( "Duplicate registration for: {} {}.".format( @@ -618,7 +621,7 @@ def _rsa_cdata_to_evp_pkey(self, rsa_cdata): self.openssl_assert(res == 1) return evp_pkey - def _bytes_to_bio(self, data: bytes): + def _bytes_to_bio(self, data: bytes) -> _MemoryBIO: """ Return a _MemoryBIO namedtuple of (BIO, char*). @@ -863,7 +866,9 @@ def generate_dsa_private_key_and_parameters( parameters = self.generate_dsa_parameters(key_size) return self.generate_dsa_private_key(parameters) - def _dsa_cdata_set_values(self, dsa_cdata, p, q, g, pub_key, priv_key): + def _dsa_cdata_set_values( + self, dsa_cdata, p, q, g, pub_key, priv_key + ) -> None: res = self._lib.DSA_set0_pqg(dsa_cdata, p, q, g) self.openssl_assert(res == 1) res = self._lib.DSA_set0_key(dsa_cdata, pub_key, priv_key) @@ -1109,13 +1114,13 @@ def _ossl2cert(self, x509_ptr: typing.Any) -> x509.Certificate: self.openssl_assert(res == 1) return x509.load_der_x509_certificate(self._read_mem_bio(bio)) - def _check_keys_correspond(self, key1, key2): + def _check_keys_correspond(self, key1, key2) -> None: if self._lib.EVP_PKEY_cmp(key1._evp_pkey, key2._evp_pkey) != 1: raise ValueError("Keys do not correspond") def _load_key( self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation - ): + ) -> PRIVATE_KEY_TYPES: mem_bio = self._bytes_to_bio(data) userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") @@ -1439,7 +1444,9 @@ def _ec_key_determine_group_get_func(self, ec_key): return get_func, group - def _ec_key_set_public_key_affine_coordinates(self, ctx, x: int, y: int): + def _ec_key_set_public_key_affine_coordinates( + self, ctx, x: int, y: int + ) -> None: """ Sets the public key point in the EC_KEY context to the affine x and y values. @@ -1579,7 +1586,9 @@ def _private_key_bytes( # like Raw. raise ValueError("format is invalid with this key") - def _private_key_bytes_via_bio(self, write_bio, evp_pkey, password): + def _private_key_bytes_via_bio( + self, write_bio, evp_pkey, password + ) -> bytes: if not password: evp_cipher = self._ffi.NULL else: @@ -1596,7 +1605,7 @@ def _private_key_bytes_via_bio(self, write_bio, evp_pkey, password): self._ffi.NULL, ) - def _bio_func_output(self, write_bio, *args): + def _bio_func_output(self, write_bio, *args) -> bytes: bio = self._create_mem_bio_gc() res = write_bio(bio, *args) self.openssl_assert(res == 1) @@ -2370,7 +2379,7 @@ def load_der_pkcs7_certificates( p7 = self._ffi.gc(p7, self._lib.PKCS7_free) return self._load_pkcs7_certificates(p7) - def _load_pkcs7_certificates(self, p7): + def _load_pkcs7_certificates(self, p7) -> typing.List[x509.Certificate]: nid = self._lib.OBJ_obj2nid(p7.type) self.openssl_assert(nid != self._lib.NID_undef) if nid != self._lib.NID_pkcs7_signed: diff --git a/src/cryptography/hazmat/primitives/_cipheralgorithm.py b/src/cryptography/hazmat/primitives/_cipheralgorithm.py index 138a104e267c..b36dccfb3427 100644 --- a/src/cryptography/hazmat/primitives/_cipheralgorithm.py +++ b/src/cryptography/hazmat/primitives/_cipheralgorithm.py @@ -32,7 +32,7 @@ def key_size(self) -> int: """ -class BlockCipherAlgorithm(metaclass=abc.ABCMeta): +class BlockCipherAlgorithm(CipherAlgorithm): key: bytes @property diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py index 613854261c57..4357c17acab0 100644 --- a/src/cryptography/hazmat/primitives/ciphers/algorithms.py +++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -24,7 +24,7 @@ def _verify_key_size(algorithm: CipherAlgorithm, key: bytes) -> bytes: return key -class AES(CipherAlgorithm, BlockCipherAlgorithm): +class AES(BlockCipherAlgorithm): name = "AES" block_size = 128 # 512 added to support AES-256-XTS, which uses 512-bit keys @@ -38,7 +38,7 @@ def key_size(self) -> int: return len(self.key) * 8 -class AES128(CipherAlgorithm, BlockCipherAlgorithm): +class AES128(BlockCipherAlgorithm): name = "AES" block_size = 128 key_sizes = frozenset([128]) @@ -48,7 +48,7 @@ def __init__(self, key: bytes): self.key = _verify_key_size(self, key) -class AES256(CipherAlgorithm, BlockCipherAlgorithm): +class AES256(BlockCipherAlgorithm): name = "AES" block_size = 128 key_sizes = frozenset([256]) @@ -58,7 +58,7 @@ def __init__(self, key: bytes): self.key = _verify_key_size(self, key) -class Camellia(CipherAlgorithm, BlockCipherAlgorithm): +class Camellia(BlockCipherAlgorithm): name = "camellia" block_size = 128 key_sizes = frozenset([128, 192, 256]) @@ -71,7 +71,7 @@ def key_size(self) -> int: return len(self.key) * 8 -class TripleDES(CipherAlgorithm, BlockCipherAlgorithm): +class TripleDES(BlockCipherAlgorithm): name = "3DES" block_size = 64 key_sizes = frozenset([64, 128, 192]) @@ -88,7 +88,7 @@ def key_size(self) -> int: return len(self.key) * 8 -class Blowfish(CipherAlgorithm, BlockCipherAlgorithm): +class Blowfish(BlockCipherAlgorithm): name = "Blowfish" block_size = 64 key_sizes = frozenset(range(32, 449, 8)) @@ -111,7 +111,7 @@ def key_size(self) -> int: ) -class CAST5(CipherAlgorithm, BlockCipherAlgorithm): +class CAST5(BlockCipherAlgorithm): name = "CAST5" block_size = 64 key_sizes = frozenset(range(40, 129, 8)) @@ -146,7 +146,7 @@ def key_size(self) -> int: return len(self.key) * 8 -class IDEA(CipherAlgorithm, BlockCipherAlgorithm): +class IDEA(BlockCipherAlgorithm): name = "IDEA" block_size = 64 key_sizes = frozenset([128]) @@ -169,7 +169,7 @@ def key_size(self) -> int: ) -class SEED(CipherAlgorithm, BlockCipherAlgorithm): +class SEED(BlockCipherAlgorithm): name = "SEED" block_size = 128 key_sizes = frozenset([128]) @@ -214,7 +214,7 @@ def key_size(self) -> int: return len(self.key) * 8 -class SM4(CipherAlgorithm, BlockCipherAlgorithm): +class SM4(BlockCipherAlgorithm): name = "SM4" block_size = 128 key_sizes = frozenset([128]) From 7f01706ae5dce261daf95a9d55c901856dbfd490 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 11 Feb 2023 17:35:50 -0600 Subject: [PATCH 244/827] Set mtimes to improve cargo caching (#8266) * experiment with setting mtime * reset the caches --- .github/actions/mtime-fix/action.yml | 14 ++++++++++ .github/workflows/ci.yml | 41 +++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 .github/actions/mtime-fix/action.yml diff --git a/.github/actions/mtime-fix/action.yml b/.github/actions/mtime-fix/action.yml new file mode 100644 index 000000000000..ac6ae9157c5a --- /dev/null +++ b/.github/actions/mtime-fix/action.yml @@ -0,0 +1,14 @@ +name: Fix mtime +description: Fixes mtime so cargo will reuse caches more effectively + +runs: + using: "composite" + + steps: + - run: | + ls -Rla src/rust/src + echo "Setting mtimes for rust dirs" + for f in $(git ls-files src/rust); do touch -t $(git log --pretty=format:%cd --date=format:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done + echo "Done" + ls -Rla src/rust/src + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03553ed85dbf..12349a65e491 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python uses: actions/setup-python@v4.5.0 @@ -67,7 +70,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-5-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - uses: actions/checkout@v3.3.0 timeout-minutes: 3 @@ -166,6 +169,12 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: git config shenanigans + run: | + git config --global --add safe.directory $(pwd) # needed for the mtime fix since git doesn't think it owns the files due to being in containers + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: @@ -177,7 +186,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - uses: actions/checkout@v3.3.0 timeout-minutes: 3 @@ -233,6 +242,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: @@ -244,7 +256,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} + key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -289,6 +301,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 id: rust-toolchain with: @@ -305,7 +320,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage + key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage - name: Setup python uses: actions/setup-python@v4.5.0 @@ -388,6 +403,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: @@ -399,7 +417,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -457,6 +475,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python uses: actions/setup-python@v4.5.0 @@ -474,7 +495,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL @@ -531,6 +552,9 @@ jobs: timeout-minutes: 3 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - uses: actions/cache@v3.2.5 timeout-minutes: 5 with: @@ -542,7 +566,7 @@ jobs: ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -580,6 +604,9 @@ jobs: - uses: actions/checkout@v3.3.0 with: persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix - name: Setup python uses: actions/setup-python@v4.5.0 with: From c7cae2fac88701750b64d0231936c2f041634ab7 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:19:19 +0000 Subject: [PATCH 245/827] Bump BoringSSL and/or OpenSSL in CI (#8267) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12349a65e491..11e8857fc2a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 11, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ace33161544814ed6dc9e9d17cfde0422881b9d2"}} - # Latest commit on the OpenSSL master branch, as of Feb 09, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4596c20b86871b2bb0f9a7f6b855c0b7f0d4fbf3"}} + # Latest commit on the BoringSSL master branch, as of Feb 12, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "fc524c161e8640e017b0d838f76e75dc49181e34"}} + # Latest commit on the OpenSSL master branch, as of Feb 12, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1472127d9d6bc4866ab26b503e0d5937b40dca37"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From b27585fb14ecb2ca8feb374e925562a6ce1de887 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 12 Feb 2023 07:37:01 -0600 Subject: [PATCH 246/827] move wycheproof clone to a composite action (#8269) --- .github/actions/wycheproof/action.yml | 12 ++++++ .github/workflows/ci.yml | 54 +++++++++------------------ 2 files changed, 30 insertions(+), 36 deletions(-) create mode 100644 .github/actions/wycheproof/action.yml diff --git a/.github/actions/wycheproof/action.yml b/.github/actions/wycheproof/action.yml new file mode 100644 index 000000000000..9ba060abddc0 --- /dev/null +++ b/.github/actions/wycheproof/action.yml @@ -0,0 +1,12 @@ +name: Clone wycheproof +description: Clones the wycheproof repository + +runs: + using: "composite" + + steps: + - uses: actions/checkout@v3.3.0 + with: + repository: "google/wycheproof" + path: "wycheproof" + ref: "master" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11e8857fc2a1..989ab214d7d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,12 +72,9 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] - name: Compute config hash and set config vars run: | @@ -188,12 +185,9 @@ jobs: src/rust/target/ key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof # When run in a docker container the home directory doesn't have the same owner as the # apparent user so pip refuses to create a cache dir - name: create pip cache dir @@ -265,12 +259,9 @@ jobs: - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 with: toolchain: ${{ matrix.RUST }} - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Create toxenv run: tox -vvv --notest @@ -329,12 +320,9 @@ jobs: - run: cargo install cargo-binutils if: steps.cargo-cache.outputs.cache-hit != 'true' - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Create toxenv run: tox -vvv --notest @@ -427,12 +415,9 @@ jobs: - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof - name: Download OpenSSL run: | @@ -507,12 +492,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - - uses: actions/checkout@v3.3.0 - timeout-minutes: 3 - with: - repository: "google/wycheproof" - path: "wycheproof" - ref: "master" + - name: Clone wycheproof + timeout-minutes: 2 + uses: ./.github/actions/wycheproof - name: Build toxenv run: tox -vvv --notest From 3decfdb4a4d892b5d1584a5058d0099a59390489 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 12 Feb 2023 09:38:26 -0600 Subject: [PATCH 247/827] don't cache cargo/bin, we don't need it (#8268) * don't cache cargo/bin, we don't need it * empty commit for cache tests --- .github/workflows/ci.yml | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 989ab214d7d6..0ca2477dd78a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,14 +63,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/.cache/pip/ - ~/.cargo/bin/ + ~/.cache/pip/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Clone wycheproof timeout-minutes: 2 @@ -176,14 +175,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/.cache/pip/ - ~/.cargo/bin/ + ~/.cache/pip/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Clone wycheproof timeout-minutes: 2 @@ -243,14 +241,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/.cache/pip/ - ~/.cargo/bin/ + ~/.cache/pip/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} + key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -305,13 +302,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/.cache/pip/ + ~/.cache/pip/wheels ~/.cargo/bin/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage + key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage - name: Setup python uses: actions/setup-python@v4.5.0 @@ -398,14 +395,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/Library/Caches/pip/ - ~/.cargo/bin/ + ~/Library/Caches/pip/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -473,14 +469,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/AppData/Local/pip/Cache/ - ~/.cargo/bin/ + ~/AppData/Local/pip/Cache/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL @@ -541,14 +536,13 @@ jobs: timeout-minutes: 5 with: path: | - ~/.cache/pip/ - ~/.cargo/bin/ + ~/.cache/pip/wheels ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/registry/src/ ~/.cargo/git/db/ src/rust/target/ - key: ${{ runner.os }}-cargo-1-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 From 10809e3a9922c7a5e9cc79d988debb0c29cc0e60 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 12 Feb 2023 09:59:03 -0600 Subject: [PATCH 248/827] name things slightly nicer for CI and reduce win shards (#8270) * name things slightly nicer for CI distros makes it cut off less of the actual description of the job in the UI (although you can always see it all via tooltip) * reduce windows shards --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ca2477dd78a..d245606de14e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,7 +87,7 @@ jobs: env: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - - name: Load cache + - name: Load OpenSSL cache uses: actions/cache@v3.2.5 id: ossl-cache timeout-minutes: 5 @@ -124,7 +124,7 @@ jobs: - uses: ./.github/actions/upload-coverage - linux-distros: + distros: runs-on: ${{ matrix.IMAGE.RUNNER }} container: ghcr.io/pyca/cryptography-runner-${{ matrix.IMAGE.IMAGE }} strategy: @@ -448,7 +448,7 @@ jobs: PYTHON: - {VERSION: "3.6", TOXENV: "py36-nocoverage", CL_FLAGS: ""} - {VERSION: "3.11", TOXENV: "py311", CL_FLAGS: "/D USE_OSRANDOM_RNG_FOR_TESTING"} - JOB_NUMBER: [0, 1, 2] + JOB_NUMBER: [0, 1] name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 steps: @@ -497,7 +497,7 @@ jobs: TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof --num-shards=3 --shard-id=${{ matrix.JOB_NUMBER }} + run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof --num-shards=2 --shard-id=${{ matrix.JOB_NUMBER }} env: TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} @@ -595,7 +595,7 @@ jobs: all-green: # https://github.community/t/is-it-possible-to-require-all-github-actions-tasks-to-pass-without-enumerating-them/117957/4?u=graingert runs-on: ubuntu-latest - needs: [linux, linux-distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] + needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - uses: actions/checkout@v3.3.0 From 182857a08f1e32fa46f0f6a531fd10a70a31bd15 Mon Sep 17 00:00:00 2001 From: gbansaghi Date: Sun, 12 Feb 2023 18:29:32 +0100 Subject: [PATCH 249/827] Disallow wildcards in DNSName for name constraints (#8272) * Disallow wildcards in DNSName for name constraints As discussed in #8253, wildcards are unnecessary according to RFC 5280, and cause issues with at least Firefox. * update changelog --- CHANGELOG.rst | 4 ++++ src/cryptography/x509/extensions.py | 17 +++++++++++++++-- tests/x509/test_x509_ext.py | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 40850c1ca38f..b8b4954f6f60 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -31,6 +31,10 @@ Changelog :class:`~cryptography.hazmat.primitives.serialization.SSHCertificateBuilder`. * Added :meth:`~cryptography.x509.Certificate.verify_directly_issued_by` to :class:`~cryptography.x509.Certificate`. +* Added a check to :class:`~cryptography.x509.NameConstraints` to ensure that + :class:`~cryptography.x509.DNSName` constraints do not contain any ``*`` + wildcards. + .. _v39-0-1: diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index c0053901e6df..e0353662b632 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -1276,7 +1276,7 @@ def __init__( "or None" ) - self._validate_ip_name(permitted_subtrees) + self._validate_tree(permitted_subtrees) if excluded_subtrees is not None: excluded_subtrees = list(excluded_subtrees) @@ -1290,7 +1290,7 @@ def __init__( "or None" ) - self._validate_ip_name(excluded_subtrees) + self._validate_tree(excluded_subtrees) if permitted_subtrees is None and excluded_subtrees is None: raise ValueError( @@ -1310,6 +1310,10 @@ def __eq__(self, other: object) -> bool: and self.permitted_subtrees == other.permitted_subtrees ) + def _validate_tree(self, tree: typing.Iterable[GeneralName]) -> None: + self._validate_ip_name(tree) + self._validate_dns_name(tree) + def _validate_ip_name(self, tree: typing.Iterable[GeneralName]) -> None: if any( isinstance(name, IPAddress) @@ -1323,6 +1327,15 @@ def _validate_ip_name(self, tree: typing.Iterable[GeneralName]) -> None: " IPv6Network object" ) + def _validate_dns_name(self, tree: typing.Iterable[GeneralName]) -> None: + if any( + isinstance(name, DNSName) and "*" in name.value for name in tree + ): + raise ValueError( + "DNSName name constraints must not contain the '*' wildcard" + " character" + ) + def __repr__(self) -> str: return ( " Date: Sun, 12 Feb 2023 16:23:38 -0600 Subject: [PATCH 250/827] fix some binding declarations (#8273) * fix some binding declarations also adds a comment about why we deliberately incorrectly declare some of them, sigh * it's actually safe to do this since no high bit mode options exist --- src/_cffi_src/openssl/ssl.py | 39 +++++++++++++-------------- tests/hazmat/bindings/test_openssl.py | 17 ------------ 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index a9be153416d2..7384c9a06738 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -342,14 +342,10 @@ long SSL_SESSION_get_time(const SSL_SESSION *); long SSL_SESSION_get_timeout(const SSL_SESSION *); int SSL_SESSION_has_ticket(const SSL_SESSION *); -long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *); +unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *); -unsigned long SSL_set_mode(SSL *, unsigned long); -unsigned long SSL_clear_mode(SSL *, unsigned long); -unsigned long SSL_get_mode(SSL *); - -unsigned long SSL_set_options(SSL *, unsigned long); -unsigned long SSL_get_options(SSL *); +uint64_t SSL_set_options(SSL *, uint64_t); +uint64_t SSL_get_options(SSL *); int SSL_want_read(const SSL *); int SSL_want_write(const SSL *); @@ -367,19 +363,22 @@ long SSL_get_min_proto_version(SSL *); long SSL_get_max_proto_version(SSL *); -/* Defined as unsigned long because SSL_OP_ALL is greater than signed 32-bit - and Windows defines long as 32-bit. */ -unsigned long SSL_CTX_set_options(SSL_CTX *, unsigned long); -unsigned long SSL_CTX_clear_options(SSL_CTX *, unsigned long); -unsigned long SSL_CTX_get_options(SSL_CTX *); -unsigned long SSL_CTX_set_mode(SSL_CTX *, unsigned long); -unsigned long SSL_CTX_clear_mode(SSL_CTX *, unsigned long); -unsigned long SSL_CTX_get_mode(SSL_CTX *); -unsigned long SSL_CTX_set_session_cache_mode(SSL_CTX *, unsigned long); -unsigned long SSL_CTX_get_session_cache_mode(SSL_CTX *); -unsigned long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); -unsigned long SSL_CTX_set_tmp_ecdh(SSL_CTX *, EC_KEY *); -unsigned long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); +long SSL_CTX_set_tmp_ecdh(SSL_CTX *, EC_KEY *); +long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); +long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); +long SSL_CTX_get_session_cache_mode(SSL_CTX *); +long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); + +uint64_t SSL_CTX_set_options(SSL_CTX *, uint64_t); +uint64_t SSL_CTX_clear_options(SSL_CTX *, uint64_t); +uint64_t SSL_CTX_get_options(SSL_CTX *); + +long SSL_CTX_set_mode(SSL_CTX *, long); +long SSL_CTX_clear_mode(SSL_CTX *, long); +long SSL_CTX_get_mode(SSL_CTX *); +long SSL_set_mode(SSL *, long); +long SSL_clear_mode(SSL *, long); +long SSL_get_mode(SSL *); const SSL_METHOD *DTLS_method(void); const SSL_METHOD *DTLS_server_method(void); diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 5c651f0fa2cd..0721fc09a966 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -58,23 +58,6 @@ def test_ssl_options(self): assert resp == expected_options assert b.lib.SSL_get_options(ssl) == expected_options - def test_ssl_mode(self): - # Test that we're properly handling 32-bit unsigned on all platforms. - b = Binding() - # SSL_OP_ALL is 0 on BoringSSL - if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: - assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) - assert ctx != b.ffi.NULL - ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) - ssl = b.lib.SSL_new(ctx) - ssl = b.ffi.gc(ssl, b.lib.SSL_free) - current_options = b.lib.SSL_get_mode(ssl) - resp = b.lib.SSL_set_mode(ssl, b.lib.SSL_OP_ALL) - expected_options = current_options | b.lib.SSL_OP_ALL - assert resp == expected_options - assert b.lib.SSL_get_mode(ssl) == expected_options - def test_conditional_removal(self): b = Binding() From 10f77048eccb4f0685786c72f7aa74587ab2f35c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Feb 2023 23:17:19 +0000 Subject: [PATCH 251/827] Bump cxx-build from 1.0.86 to 1.0.90 in /src/rust (#8274) Bumps [cxx-build](https://github.com/dtolnay/cxx) from 1.0.86 to 1.0.90. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.86...1.0.90) --- updated-dependencies: - dependency-name: cxx-build dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index bc91e7bc7b2d..c5e89f960481 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" +checksum = "ebfa40bda659dd5c864e65f4c9a2b0aff19bea56b017b9b77c73d3766a453a38" dependencies = [ "cc", "codespan-reporting", From 351344a583f4f06a67165f13f584c0dbd6f2d97b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Feb 2023 23:17:39 +0000 Subject: [PATCH 252/827] Bump hypothesis from 6.68.0 to 6.68.1 (#8275) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.68.0 to 6.68.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.68.0...hypothesis-python-6.68.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b2508a8a2ff7..93b6619c7a3f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.68.0; python_version >= "3.7" +hypothesis==6.68.1; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 78f12711d71e14d4525c4e9a97b816fb1473f737 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Feb 2023 23:44:11 +0000 Subject: [PATCH 253/827] Bump cxx from 1.0.86 to 1.0.90 in /src/rust (#8276) Bumps [cxx](https://github.com/dtolnay/cxx) from 1.0.86 to 1.0.90. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.86...1.0.90) --- updated-dependencies: - dependency-name: cxx dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c5e89f960481..a45b1b236199 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" +checksum = "90d59d9acd2a682b4e40605a242f6670eaa58c5957471cbf85e8aa6a0b97a5e8" dependencies = [ "cc", "cxxbridge-flags", @@ -149,15 +149,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" +checksum = "457ce6757c5c70dc6ecdbda6925b958aae7f959bda7d8fb9bde889e34a09dc03" [[package]] name = "cxxbridge-macro" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" +checksum = "ebf883b7aacd7b2aeb2a7b338648ee19f57c140d4ee8e52c68979c6b2f7f2263" dependencies = [ "proc-macro2", "quote", From 7c77740cc7566675871b83c5b4f25ef4a4da6134 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 07:44:02 -0500 Subject: [PATCH 254/827] Bump dtolnay/rust-toolchain (#8278) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from c758e63728211bd4acda6501cfa2a16c5c751fc4 to 25dc93b901a87e864900a8aec6c12e9aa794c0c3. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/c758e63728211bd4acda6501cfa2a16c5c751fc4...25dc93b901a87e864900a8aec6c12e9aa794c0c3) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d245606de14e..2616b9e6039f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -253,7 +253,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 + - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 with: toolchain: ${{ matrix.RUST }} - name: Clone wycheproof @@ -292,7 +292,7 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 + - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 id: rust-toolchain with: toolchain: ${{ matrix.RUST }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index bb8b3fbc21a4..a23824b742da 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -203,7 +203,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 + - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -275,7 +275,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@c758e63728211bd4acda6501cfa2a16c5c751fc4 + - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From 4de381caa22033df0c28fd27d115657efb1bb3e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:47:48 +0000 Subject: [PATCH 255/827] Bump ruff from 0.0.244 to 0.0.246 (#8279) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.244 to 0.0.246. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.244...v0.0.246) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 93b6619c7a3f..b183b15ab5ea 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.244 +ruff==0.0.246 # via cryptography (setup.cfg) six==1.16.0 # via bleach From af68e9d2169617d1546fbf5d293a0c54453dd419 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 13 Feb 2023 08:36:11 -0500 Subject: [PATCH 256/827] fix a warning in C code via explicit cast (#8280) --- src/_cffi_src/openssl/callbacks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_cffi_src/openssl/callbacks.py b/src/_cffi_src/openssl/callbacks.py index 79d4f24bcee9..57a393686197 100644 --- a/src/_cffi_src/openssl/callbacks.py +++ b/src/_cffi_src/openssl/callbacks.py @@ -31,7 +31,7 @@ } CRYPTOGRAPHY_PASSWORD_DATA; int Cryptography_pem_password_cb(char *buf, int size, - int rwflag, void *userdata) { + int rwflag, void *userdata) { /* The password cb is only invoked if OpenSSL decides the private key is encrypted. So this path only occurs if it needs a password */ CRYPTOGRAPHY_PASSWORD_DATA *st = (CRYPTOGRAPHY_PASSWORD_DATA *)userdata; @@ -41,7 +41,7 @@ st->error = -1; return 0; } else if (st->length < size) { - memcpy(buf, st->password, st->length); + memcpy(buf, st->password, (size_t)st->length); return st->length; } else { st->error = -2; From a69f6da9cc409771489143758af1f7ce588a63c9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 13 Feb 2023 17:46:01 -0500 Subject: [PATCH 257/827] Revert "workaround scapy bug in downstream tests (#8218)" (#8282) This reverts commit 957507ffe92c4ac87d21f44df4d5f4bf9b7aef98. --- .github/downstream.d/scapy.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/downstream.d/scapy.sh b/.github/downstream.d/scapy.sh index 5ef3648ae2df..ac1b8f820016 100755 --- a/.github/downstream.d/scapy.sh +++ b/.github/downstream.d/scapy.sh @@ -5,8 +5,7 @@ case "${1}" in git clone --depth=1 https://github.com/secdev/scapy cd scapy git rev-parse HEAD - # Pin virtualenv until https://github.com/secdev/scapy/pull/3862 is merged - pip install tox 'virtualenv<20.18' + pip install tox ;; run) cd scapy From 1ffb38d3ab4ce1525aaeac3c5875af52e6499cf1 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 00:20:12 +0000 Subject: [PATCH 258/827] Bump BoringSSL and/or OpenSSL in CI (#8283) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2616b9e6039f..2b077ab40501 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 12, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "fc524c161e8640e017b0d838f76e75dc49181e34"}} - # Latest commit on the OpenSSL master branch, as of Feb 12, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1472127d9d6bc4866ab26b503e0d5937b40dca37"}} + # Latest commit on the BoringSSL master branch, as of Feb 14, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "dcabfe2d8940529a69e007660fa7bf6c15954ecc"}} + # Latest commit on the OpenSSL master branch, as of Feb 14, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6b58f498b3f5d8e4c9197c3c5228fb450e33aaaf"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 5aa20ce5ee80cc9f33b20f0f6d63bb81c220e3e4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 14 Feb 2023 08:27:45 -0500 Subject: [PATCH 259/827] fixes #8284 -- include tox.ini in the sdist (#8285) --- MANIFEST.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 62699330e9b2..995e3b0cedc2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,6 +5,7 @@ include LICENSE.APACHE include LICENSE.BSD include LICENSE.PSF include README.rst +include tox.ini include pyproject.toml recursive-include src py.typed *.pyi @@ -19,4 +20,4 @@ recursive-exclude vectors * recursive-exclude .github * -exclude release.py .readthedocs.yml ci-constraints-requirements.txt tox.ini mypy.ini +exclude release.py .readthedocs.yml ci-constraints-requirements.txt mypy.ini From 030381a9df38053c9f5028813eec15bdbeddb6be Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 14 Feb 2023 09:40:47 -0500 Subject: [PATCH 260/827] try to resolve two compilation warnings (#8286) --- src/_cffi_src/openssl/src/osrandom_engine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_cffi_src/openssl/src/osrandom_engine.h b/src/_cffi_src/openssl/src/osrandom_engine.h index 376b8ff21c21..89e45265186f 100644 --- a/src/_cffi_src/openssl/src/osrandom_engine.h +++ b/src/_cffi_src/openssl/src/osrandom_engine.h @@ -1,4 +1,4 @@ -#ifndef OPENSSL_NO_ENGINE +#if CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE /* OpenSSL has ENGINE support so include all of this. */ #ifdef _WIN32 #include From 2bf2f2c030ab520b2475fcb5a754177ff23a2f6a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 14 Feb 2023 09:44:51 -0600 Subject: [PATCH 261/827] make our rust/pip cache a composite action (#8287) * make our rust/pip cache a composite action * fixes --- .github/actions/cache/action.yml | 43 +++++++++++++++ .github/workflows/ci.yml | 92 ++++++++------------------------ 2 files changed, 66 insertions(+), 69 deletions(-) create mode 100644 .github/actions/cache/action.yml diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml new file mode 100644 index 000000000000..baf1faafa284 --- /dev/null +++ b/.github/actions/cache/action.yml @@ -0,0 +1,43 @@ +name: Cache rust and pip +description: Caches rust and pip data to speed builds +inputs: + additional-paths: + description: 'Additional paths to add to the cache' + required: false + default: '' + key: + description: 'cache key' + required: true +outputs: + cache-hit: + description: 'Was the cache hit?' + value: ${{ steps.cache.outputs.cache-hit }} + + +runs: + using: "composite" + + steps: + - name: Get pip cache dir + id: pip-cache + run: | + # Determine the path to our Python. It's in venv for our containers + # but just standard $PATH for setup-python pythons. + if [[ -f "/venv/bin/python" ]]; then + echo "dir=$(/venv/bin/python -m pip cache dir)" >> $GITHUB_OUTPUT + elif which python >/dev/null; then + echo "dir=$(python -m pip cache dir)" >> $GITHUB_OUTPUT + fi + shell: bash + - uses: actions/cache@v3.2.5 + id: cache + with: + path: | + ${{ steps.pip-cache.outputs.dir }} + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/registry/src/ + ~/.cargo/git/db/ + src/rust/target/ + ${{ inputs.additional-paths }} + key: ${{ inputs.key }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b077ab40501..54f7f94cdbb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,18 +59,11 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/.cache/pip/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -171,18 +164,11 @@ jobs: git config --global --add safe.directory $(pwd) # needed for the mtime fix since git doesn't think it owns the files due to being in containers - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/.cache/pip/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -237,18 +223,11 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/.cache/pip/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} - - name: Setup python uses: actions/setup-python@v4.5.0 with: @@ -297,19 +276,14 @@ jobs: with: toolchain: ${{ matrix.RUST }} components: llvm-tools-preview - - uses: actions/cache@v3.2.5 + - name: Cache rust and pip id: cargo-cache - timeout-minutes: 5 + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/.cache/pip/wheels - ~/.cargo/bin/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage - + additional-paths: | + ~/.cargo/bin/ - name: Setup python uses: actions/setup-python@v4.5.0 with: @@ -391,16 +365,10 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/Library/Caches/pip/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - name: Setup python @@ -465,18 +433,11 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/AppData/Local/pip/Cache/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL run: | @@ -532,18 +493,11 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: actions/cache@v3.2.5 - timeout-minutes: 5 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 with: - path: | - ~/.cache/pip/wheels - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ - src/rust/target/ key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} - - name: Setup python uses: actions/setup-python@v4.5.0 with: From 1c54e81754a8ed1a2875a167f8d0af2c431ff88a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 14 Feb 2023 11:05:00 -0600 Subject: [PATCH 262/827] simplify cache keys (#8288) * simplify cache keys * empty commit --- .github/actions/cache/action.yml | 2 +- .github/workflows/ci.yml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index baf1faafa284..530073ffde7c 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -40,4 +40,4 @@ runs: ~/.cargo/git/db/ src/rust/target/ ${{ inputs.additional-paths }} - key: ${{ inputs.key }} \ No newline at end of file + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-1 \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54f7f94cdbb1..1a4478f27f99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/Cargo.lock') }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -168,7 +168,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-${{ matrix.IMAGE.IMAGE }}-${{ runner.arch }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.IMAGE.IMAGE }}-${{ hashFiles('**/Cargo.lock') }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -227,7 +227,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} + key: ${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} - name: Setup python uses: actions/setup-python@v4.5.0 with: @@ -281,7 +281,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }}-rust-${{ steps.rust-toolchain.outputs.cachekey }}-coverage + key: ${{ hashFiles('**/Cargo.lock') }}-${{ steps.rust-toolchain.outputs.cachekey }}-coverage additional-paths: | ~/.cargo/bin/ - name: Setup python @@ -369,7 +369,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.PYTHON.VERSION }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.PYTHON.VERSION }}-${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -437,7 +437,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/Cargo.lock') }} - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL run: | @@ -497,7 +497,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ runner.os }}-cargo-3-${{ hashFiles('**/Cargo.lock') }} + key: ${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 with: From 8d964b24c6cc465645fbebd611d572fb0a8ba0e0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 14 Feb 2023 11:37:17 -0600 Subject: [PATCH 263/827] make twisted tests faster (#8290) --- .github/downstream.d/twisted.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/downstream.d/twisted.sh b/.github/downstream.d/twisted.sh index 522e763ec3b7..9fc195ba7552 100755 --- a/.github/downstream.d/twisted.sh +++ b/.github/downstream.d/twisted.sh @@ -9,7 +9,7 @@ case "${1}" in ;; run) cd twisted - python -m twisted.trial src/twisted + python -m twisted.trial -j4 src/twisted ;; *) exit 1 From bd6c41ca8ff58df0b18e9807bc8dd8a528ea028f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 14 Feb 2023 13:15:05 -0600 Subject: [PATCH 264/827] turn off coverage on py36 mac builder (#8291) --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a4478f27f99..65a5325241cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -349,11 +349,11 @@ jobs: - {OS: 'macos-12', ARCH: 'x86_64'} - {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} PYTHON: - - {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""} + - {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""} - {VERSION: "3.11", TOXENV: "py311", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"} exclude: # We only test latest Python on arm64. The py36 won't work since there's no universal2 binary - - PYTHON: {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""} + - PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""} RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 From c8c9a33772b49814c114145743acd5ae2465fb74 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 00:20:42 +0000 Subject: [PATCH 265/827] Bump BoringSSL and/or OpenSSL in CI (#8292) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65a5325241cc..152c46996d32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 14, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "dcabfe2d8940529a69e007660fa7bf6c15954ecc"}} - # Latest commit on the OpenSSL master branch, as of Feb 14, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6b58f498b3f5d8e4c9197c3c5228fb450e33aaaf"}} + # Latest commit on the BoringSSL master branch, as of Feb 15, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f30c031f0b42280edce0bfc66ef1f7486b015820"}} + # Latest commit on the OpenSSL master branch, as of Feb 15, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cd870db16348d0d09cb05b7393cf9281509c7795"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 5b714f5657c1ea7b9e608dbacf0e79d8c5e6ed38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:08:25 +0000 Subject: [PATCH 266/827] Bump dtolnay/rust-toolchain (#8293) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from 25dc93b901a87e864900a8aec6c12e9aa794c0c3 to 0a1713a447f74360b294fd86bc56dc23af3a9d3e. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/25dc93b901a87e864900a8aec6c12e9aa794c0c3...0a1713a447f74360b294fd86bc56dc23af3a9d3e) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 152c46996d32..87cfe591cd00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -232,7 +232,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 + - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e with: toolchain: ${{ matrix.RUST }} - name: Clone wycheproof @@ -271,7 +271,7 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 + - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e id: rust-toolchain with: toolchain: ${{ matrix.RUST }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index a23824b742da..67643cac6c83 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -203,7 +203,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 + - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -275,7 +275,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@25dc93b901a87e864900a8aec6c12e9aa794c0c3 + - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From 439e71bcc0a7c06c1ca048bb650a5bfbce68f81c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:26:07 +0000 Subject: [PATCH 267/827] Bump types-urllib3 from 1.26.25.5 to 1.26.25.6 (#8296) Bumps [types-urllib3](https://github.com/python/typeshed) from 1.26.25.5 to 1.26.25.6. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b183b15ab5ea..7f739b360788 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -212,7 +212,7 @@ types-pytz==2022.7.1.0 # via cryptography (setup.cfg) types-requests==2.28.11.12 # via cryptography (setup.cfg) -types-urllib3==1.26.25.5 +types-urllib3==1.26.25.6 # via types-requests typing-extensions==4.4.0; python_version >= "3.7" # via mypy From 59ef968532940faf1e2b20c44985b9a14e515b5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:41:28 +0000 Subject: [PATCH 268/827] Bump typing-extensions from 4.4.0 to 4.5.0 (#8295) Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.4.0...4.5.0) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7f739b360788..36199ab2468b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -214,7 +214,7 @@ types-requests==2.28.11.12 # via cryptography (setup.cfg) types-urllib3==1.26.25.6 # via types-requests -typing-extensions==4.4.0; python_version >= "3.7" +typing-extensions==4.5.0; python_version >= "3.7" # via mypy urllib3==1.26.14 # via From d90ed2b2bc6d02720191d6449be098451677b3fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:33:44 -0500 Subject: [PATCH 269/827] Bump types-requests from 2.28.11.12 to 2.28.11.13 (#8297) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.12 to 2.28.11.13. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 36199ab2468b..873fcf66c4a2 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -210,7 +210,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.0 # via cryptography (setup.cfg) -types-requests==2.28.11.12 +types-requests==2.28.11.13 # via cryptography (setup.cfg) types-urllib3==1.26.25.6 # via types-requests From 10ce2ab67e59365df87102ecee4d1525c2340605 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 00:20:00 +0000 Subject: [PATCH 270/827] Bump BoringSSL and/or OpenSSL in CI (#8300) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87cfe591cd00..98be5d90fd5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 15, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f30c031f0b42280edce0bfc66ef1f7486b015820"}} + # Latest commit on the BoringSSL master branch, as of Feb 16, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "987dff1a9fa953a8c7dffa369d78caae02b8d9ab"}} # Latest commit on the OpenSSL master branch, as of Feb 15, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cd870db16348d0d09cb05b7393cf9281509c7795"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From f59a7d42fb19639c90bc3cee7a552490ebf291a8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 15 Feb 2023 21:24:35 -0600 Subject: [PATCH 271/827] update to latest pytest-subtests and add the new flag (#8301) * update to latest pytest-subtests and add the new flag * crimez * lol --- ci-constraints-requirements.txt | 2 +- pyproject.toml | 2 +- setup.cfg | 1 + tests/conftest.py | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 873fcf66c4a2..5dd27449752d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -141,7 +141,7 @@ pytest-randomly==3.12.0 # via cryptography (setup.cfg) pytest-shard==0.1.2 # via cryptography (setup.cfg) -pytest-subtests==0.9.0; python_version >= "3.7" +pytest-subtests==0.10.0; python_version >= "3.7" # via cryptography (setup.cfg) pytest-xdist==3.2.0; python_version >= "3.7" # via cryptography (setup.cfg) diff --git a/pyproject.toml b/pyproject.toml index e4f17dc5f0a9..1f1a8ab49754 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ line-length = 79 target-version = ["py36"] [tool.pytest.ini_options] -addopts = "-r s --capture=no --strict-markers --benchmark-disable" +addopts = "-r s --capture=no --strict-markers --benchmark-disable --no-subtests-shortletter" markers = [ "skip_fips: this test is not executed in FIPS mode", "supported: parametrized test requiring only_if and skip_message", diff --git a/setup.cfg b/setup.cfg index 8a22fec8b068..b2ecf8961a1b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,6 +62,7 @@ test = pytest-shard>=0.1.2 pytest-benchmark pytest-cov + # pytest-subtests needs >=0.10.0 when we drop py36 support pytest-subtests pytest-xdist pretend diff --git a/tests/conftest.py b/tests/conftest.py index f077184d0d55..4b215802bc73 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import sys import pytest @@ -27,6 +28,11 @@ def pytest_report_header(config): def pytest_addoption(parser): parser.addoption("--wycheproof-root", default=None) parser.addoption("--enable-fips", default=False) + # REMOVE ME WHEN WE DROP PYTHON 3.6 SUPPORT + # This just adds a no-op flag so that we don't error on py36 where + # pytest-subtests is stuck on 0.8.0 + if sys.version_info[:2] == (3, 6): + parser.addoption("--no-subtests-shortletter", action="store_true") def pytest_runtest_setup(item): From 03702b11193b29574ca64bbe93c79bfe4209daf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:33:05 +0000 Subject: [PATCH 272/827] Bump dtolnay/rust-toolchain (#8306) Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from 0a1713a447f74360b294fd86bc56dc23af3a9d3e to 52e69531e6f69a396bc9d1226284493a5db969ff. - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/0a1713a447f74360b294fd86bc56dc23af3a9d3e...52e69531e6f69a396bc9d1226284493a5db969ff) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/wheel-builder.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98be5d90fd5d..95f3b8121deb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -232,7 +232,7 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e + - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff with: toolchain: ${{ matrix.RUST }} - name: Clone wycheproof @@ -271,7 +271,7 @@ jobs: fetch-depth: 0 - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e + - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff id: rust-toolchain with: toolchain: ${{ matrix.RUST }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 67643cac6c83..aefb19a22a51 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -203,7 +203,7 @@ jobs: ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e + - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff with: toolchain: stable # Add the arm64 target in addition to the native arch (x86_64) @@ -275,7 +275,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} - - uses: dtolnay/rust-toolchain@0a1713a447f74360b294fd86bc56dc23af3a9d3e + - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff with: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} From fbbbaa7371d6ac11fc99086f4642d5f82a5c7bd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:33:39 +0000 Subject: [PATCH 273/827] Bump cxx from 1.0.90 to 1.0.91 in /src/rust (#8309) Bumps [cxx](https://github.com/dtolnay/cxx) from 1.0.90 to 1.0.91. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.90...1.0.91) --- updated-dependencies: - dependency-name: cxx dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index a45b1b236199..afeed99ffc7f 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90d59d9acd2a682b4e40605a242f6670eaa58c5957471cbf85e8aa6a0b97a5e8" +checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" dependencies = [ "cc", "cxxbridge-flags", @@ -149,15 +149,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457ce6757c5c70dc6ecdbda6925b958aae7f959bda7d8fb9bde889e34a09dc03" +checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" [[package]] name = "cxxbridge-macro" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf883b7aacd7b2aeb2a7b338648ee19f57c140d4ee8e52c68979c6b2f7f2263" +checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" dependencies = [ "proc-macro2", "quote", From b17fc1d8e4e5ce6e219758683fee6a2a5e774458 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:43:32 +0000 Subject: [PATCH 274/827] Bump ouroboros from 0.15.5 to 0.15.6 in /src/rust (#8310) Bumps [ouroboros](https://github.com/joshua-maros/ouroboros) from 0.15.5 to 0.15.6. - [Release notes](https://github.com/joshua-maros/ouroboros/releases) - [Commits](https://github.com/joshua-maros/ouroboros/commits) --- updated-dependencies: - dependency-name: ouroboros dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index afeed99ffc7f..36b816b8f165 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -290,9 +290,9 @@ checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "ouroboros" -version = "0.15.5" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbb50b356159620db6ac971c6d5c9ab788c9cc38a6f49619fca2a27acb062ca" +checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" dependencies = [ "aliasable", "ouroboros_macro", @@ -300,9 +300,9 @@ dependencies = [ [[package]] name = "ouroboros_macro" -version = "0.15.5" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0d9d1a6191c4f391f87219d1ea42b23f09ee84d64763cd05ee6ea88d9f384d" +checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" dependencies = [ "Inflector", "proc-macro-error", From 2436fba413090d1bb455acf54b9932e5ae955cac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:43:54 +0000 Subject: [PATCH 275/827] Bump ruff from 0.0.246 to 0.0.247 (#8311) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.246 to 0.0.247. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.246...v0.0.247) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5dd27449752d..04b118f27abd 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.246 +ruff==0.0.247 # via cryptography (setup.cfg) six==1.16.0 # via bleach From a4fdc2b04fffa9afcd7fa076fe1386fb84da4460 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 16 Feb 2023 08:58:55 -0500 Subject: [PATCH 276/827] remove two bindings functions that were unused (#8304) just sort of sitting there --- src/_cffi_src/openssl/evp.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index 357de292403e..46301ecbb78e 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -171,13 +171,6 @@ const long EVP_PKEY_DHX = -1; #endif -EVP_MD_CTX *Cryptography_EVP_MD_CTX_new(void) { - return EVP_MD_CTX_new(); -} -void Cryptography_EVP_MD_CTX_free(EVP_MD_CTX *md) { - EVP_MD_CTX_free(md); -} - #if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_OPENSSL_300_OR_GREATER || \ CRYPTOGRAPHY_IS_BORINGSSL static const int Cryptography_HAS_EVP_PKEY_set_alias_type = 0; From ab92f8f3ec31612206d837a5c9c29d386c301f0c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 16 Feb 2023 08:59:24 -0500 Subject: [PATCH 277/827] remove unused typedefs (#8305) --- src/_cffi_src/openssl/objects.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/_cffi_src/openssl/objects.py b/src/_cffi_src/openssl/objects.py index 9911599ffa22..a5440c1b4328 100644 --- a/src/_cffi_src/openssl/objects.py +++ b/src/_cffi_src/openssl/objects.py @@ -8,14 +8,6 @@ """ TYPES = """ -typedef struct { - int type; - int alias; - const char *name; - const char *data; -} OBJ_NAME; - -static const long OBJ_NAME_TYPE_MD_METH; """ FUNCTIONS = """ From bb9fdac6437e1ffb183089151f328e767277266e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 08:00:36 -0600 Subject: [PATCH 278/827] Bump cxx-build from 1.0.90 to 1.0.91 in /src/rust (#8308) Bumps [cxx-build](https://github.com/dtolnay/cxx) from 1.0.90 to 1.0.91. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.90...1.0.91) --- updated-dependencies: - dependency-name: cxx-build dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 36b816b8f165..49d0efe837c2 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfa40bda659dd5c864e65f4c9a2b0aff19bea56b017b9b77c73d3766a453a38" +checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" dependencies = [ "cc", "codespan-reporting", From fdb02ca6c9a3f0bc7c38db31a0cb1f00318a9269 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 08:01:38 -0600 Subject: [PATCH 279/827] Bump ouroboros_macro from 0.15.5 to 0.15.6 in /src/rust (#8307) Bumps [ouroboros_macro](https://github.com/joshua-maros/ouroboros) from 0.15.5 to 0.15.6. - [Release notes](https://github.com/joshua-maros/ouroboros/releases) - [Commits](https://github.com/joshua-maros/ouroboros/commits) --- updated-dependencies: - dependency-name: ouroboros_macro dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From f9def1a5e9b669c0ad43b55ea7c46298842377c7 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 17 Feb 2023 00:23:26 +0000 Subject: [PATCH 280/827] Bump BoringSSL and/or OpenSSL in CI (#8312) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95f3b8121deb..077472ff6d8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 16, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "987dff1a9fa953a8c7dffa369d78caae02b8d9ab"}} + # Latest commit on the BoringSSL master branch, as of Feb 17, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "bab2f96e2637acb107fe9b099c58befbca918748"}} # Latest commit on the OpenSSL master branch, as of Feb 15, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cd870db16348d0d09cb05b7393cf9281509c7795"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From ed7c9d341dd46cfc4a98a9d12083ceaca4929589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Feb 2023 13:19:43 +0000 Subject: [PATCH 281/827] Bump hypothesis from 6.68.1 to 6.68.2 (#8313) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.68.1 to 6.68.2. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.68.1...hypothesis-python-6.68.2) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 04b118f27abd..4213acab5d24 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.68.1; python_version >= "3.7" +hypothesis==6.68.2; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 127a2860740c77f45362e68e0ed7d2d108a39033 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Feb 2023 08:31:05 -0500 Subject: [PATCH 282/827] Always use the Cargo.lock in the GHA cache key (#8314) --- .github/actions/cache/action.yml | 7 ++++--- .github/workflows/ci.yml | 14 ++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 530073ffde7c..e45b1a89ae43 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -6,8 +6,9 @@ inputs: required: false default: '' key: - description: 'cache key' - required: true + description: 'extra cache key components' + required: false + default: '' outputs: cache-hit: description: 'Was the cache hit?' @@ -40,4 +41,4 @@ runs: ~/.cargo/git/db/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-1 \ No newline at end of file + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-1-${{ hashFiles('**/Cargo.lock') }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 077472ff6d8e..069cb6c7e9ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -168,7 +168,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.IMAGE.IMAGE }}-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.IMAGE.IMAGE }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -227,7 +227,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ hashFiles('**/Cargo.lock') }}-${{ matrix.RUST }} + key: ${{ matrix.RUST }} - name: Setup python uses: actions/setup-python@v4.5.0 with: @@ -281,7 +281,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ hashFiles('**/Cargo.lock') }}-${{ steps.rust-toolchain.outputs.cachekey }}-coverage + key: ${{ steps.rust-toolchain.outputs.cachekey }}-coverage additional-paths: | ~/.cargo/bin/ - name: Setup python @@ -369,7 +369,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.PYTHON.VERSION }}-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.PYTHON.VERSION }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -437,7 +437,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - name: Download OpenSSL run: | @@ -496,8 +496,6 @@ jobs: - name: Cache rust and pip uses: ./.github/actions/cache timeout-minutes: 2 - with: - key: ${{ hashFiles('**/Cargo.lock') }} - name: Setup python uses: actions/setup-python@v4.5.0 with: From c0e78fb0aacc5f8b3986a8fb19d4549d2a0b7e45 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Feb 2023 11:56:06 -0500 Subject: [PATCH 283/827] fixes #8316 -- correct docstring (#8318) --- src/cryptography/hazmat/primitives/asymmetric/x25519.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index 690af78c2152..d1347b883f37 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -60,7 +60,7 @@ def from_private_bytes(cls, data: bytes) -> "X25519PrivateKey": @abc.abstractmethod def public_key(self) -> X25519PublicKey: """ - The serialized bytes of the public key. + Returns the public key assosciated with this private key """ @abc.abstractmethod From ec23d2edc94179b732e6e135b3592534ab6f42f1 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Feb 2023 12:19:46 -0500 Subject: [PATCH 284/827] fixes #8316 -- correct docstring (#8319) * fixes #8316 -- correct docstring * Update src/cryptography/hazmat/primitives/asymmetric/x448.py Co-authored-by: Paul Kehrer --------- Co-authored-by: Paul Kehrer --- src/cryptography/hazmat/primitives/asymmetric/x448.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index 7f71c2722a67..284d4c801f99 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -60,7 +60,7 @@ def from_private_bytes(cls, data: bytes) -> "X448PrivateKey": @abc.abstractmethod def public_key(self) -> X448PublicKey: """ - The serialized bytes of the public key. + Returns the public key associated with this private key """ @abc.abstractmethod From bd0352a3478672d6695dde3e26b685ba016eeae3 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 18 Feb 2023 00:19:57 +0000 Subject: [PATCH 285/827] Bump BoringSSL and/or OpenSSL in CI (#8320) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 069cb6c7e9ea..bc7ba0dc2993 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 17, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "bab2f96e2637acb107fe9b099c58befbca918748"}} + # Latest commit on the BoringSSL master branch, as of Feb 18, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e18ba272d4532659a20904c812207079c4ec2e80"}} # Latest commit on the OpenSSL master branch, as of Feb 15, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cd870db16348d0d09cb05b7393cf9281509c7795"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From d0017e318dbe738107df06ed8284f043b6583e96 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 09:13:49 -0500 Subject: [PATCH 286/827] Remove unused bindings (#8321) --- src/_cffi_src/openssl/evp.py | 10 ---------- src/_cffi_src/openssl/ssl.py | 10 ---------- src/_cffi_src/openssl/x509.py | 6 ------ .../hazmat/bindings/openssl/_conditional.py | 18 ------------------ 4 files changed, 44 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index 46301ecbb78e..c4d15f9f5a13 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -31,7 +31,6 @@ static const int EVP_CTRL_AEAD_GET_TAG; static const int EVP_CTRL_AEAD_SET_TAG; -static const int Cryptography_HAS_EVP_PKEY_set_alias_type; static const int Cryptography_HAS_SCRYPT; static const int Cryptography_HAS_EVP_PKEY_DHX; static const long Cryptography_HAS_RAW_KEY; @@ -121,7 +120,6 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *, EVP_PKEY *); int EVP_PKEY_derive(EVP_PKEY_CTX *, unsigned char *, size_t *); -int EVP_PKEY_set_alias_type(EVP_PKEY *, int); int EVP_PKEY_set_type(EVP_PKEY *, int); int EVP_PKEY_id(const EVP_PKEY *); @@ -171,14 +169,6 @@ const long EVP_PKEY_DHX = -1; #endif -#if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_OPENSSL_300_OR_GREATER || \ - CRYPTOGRAPHY_IS_BORINGSSL -static const int Cryptography_HAS_EVP_PKEY_set_alias_type = 0; -int (*EVP_PKEY_set_alias_type)(EVP_PKEY *, int) = NULL; -#else -static const int Cryptography_HAS_EVP_PKEY_set_alias_type = 1; -#endif - #if CRYPTOGRAPHY_IS_LIBRESSL || defined(OPENSSL_NO_SCRYPT) static const long Cryptography_HAS_SCRYPT = 0; int (*EVP_PBE_scrypt)(const char *, size_t, const unsigned char *, size_t, diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 7384c9a06738..2f7d99968224 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -12,7 +12,6 @@ TYPES = """ static const long Cryptography_HAS_SSL_ST; static const long Cryptography_HAS_TLS_ST; -static const long Cryptography_HAS_SSL3_METHOD; static const long Cryptography_HAS_TLSv1_1; static const long Cryptography_HAS_TLSv1_2; static const long Cryptography_HAS_TLSv1_3_FUNCTIONS; @@ -544,15 +543,6 @@ static const long Cryptography_HAS_KEYLOG = 1; static const long Cryptography_HAS_SECURE_RENEGOTIATION = 1; -#ifdef OPENSSL_NO_SSL3_METHOD -static const long Cryptography_HAS_SSL3_METHOD = 0; -SSL_METHOD* (*SSLv3_method)(void) = NULL; -SSL_METHOD* (*SSLv3_client_method)(void) = NULL; -SSL_METHOD* (*SSLv3_server_method)(void) = NULL; -#else -static const long Cryptography_HAS_SSL3_METHOD = 1; -#endif - static const long Cryptography_HAS_RELEASE_BUFFERS = 1; static const long Cryptography_HAS_OP_NO_COMPRESSION = 1; static const long Cryptography_HAS_TLSv1_1 = 1; diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 5b06ad772090..2cbc01c95878 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -201,18 +201,12 @@ int sk_X509_REVOKED_num(Cryptography_STACK_OF_X509_REVOKED *); X509_REVOKED *sk_X509_REVOKED_value(Cryptography_STACK_OF_X509_REVOKED *, int); -long X509_CRL_get_version(X509_CRL *); -const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *); -const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *); X509_NAME *X509_CRL_get_issuer(X509_CRL *); Cryptography_STACK_OF_X509_REVOKED *X509_CRL_get_REVOKED(X509_CRL *); int X509_CRL_set1_lastUpdate(X509_CRL *, const ASN1_TIME *); int X509_CRL_set1_nextUpdate(X509_CRL *, const ASN1_TIME *); -EC_KEY *d2i_EC_PUBKEY_bio(BIO *, EC_KEY **); -int i2d_EC_PUBKEY_bio(BIO *, EC_KEY *); -EC_KEY *d2i_ECPrivateKey_bio(BIO *, EC_KEY **); int i2d_ECPrivateKey_bio(BIO *, EC_KEY *); const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *); diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index af4ce33db443..9d802d3e4e8f 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -11,14 +11,6 @@ def cryptography_has_ec2m() -> typing.List[str]: ] -def cryptography_has_ssl3_method() -> typing.List[str]: - return [ - "SSLv3_method", - "SSLv3_client_method", - "SSLv3_server_method", - ] - - def cryptography_has_set_cert_cb() -> typing.List[str]: return [ "SSL_CTX_set_cert_cb", @@ -42,12 +34,6 @@ def cryptography_has_tls_st() -> typing.List[str]: ] -def cryptography_has_evp_pkey_set_alias_type() -> typing.List[str]: - return [ - "EVP_PKEY_set_alias_type", - ] - - def cryptography_has_scrypt() -> typing.List[str]: return [ "EVP_PBE_scrypt", @@ -298,13 +284,9 @@ def cryptography_has_get_extms_support() -> typing.List[str]: # lists so we can use coverage to measure which are used. CONDITIONAL_NAMES = { "Cryptography_HAS_EC2M": cryptography_has_ec2m, - "Cryptography_HAS_SSL3_METHOD": cryptography_has_ssl3_method, "Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb, "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st, "Cryptography_HAS_TLS_ST": cryptography_has_tls_st, - "Cryptography_HAS_EVP_PKEY_set_alias_type": ( - cryptography_has_evp_pkey_set_alias_type - ), "Cryptography_HAS_SCRYPT": cryptography_has_scrypt, "Cryptography_HAS_EVP_PKEY_DHX": cryptography_has_evp_pkey_dhx, "Cryptography_HAS_MEM_FUNCTIONS": cryptography_has_mem_functions, From 99b1789ffa3931e4eb897b0b06040b561a2991e8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:07:09 -0500 Subject: [PATCH 287/827] remove unused ssl bindings (#8323) --- src/_cffi_src/openssl/ssl.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 2f7d99968224..06aeb9135a3c 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -5,8 +5,6 @@ INCLUDES = """ #include - -typedef STACK_OF(SSL_CIPHER) Cryptography_STACK_OF_SSL_CIPHER; """ TYPES = """ @@ -154,7 +152,6 @@ static const long TLSEXT_STATUSTYPE_ocsp; typedef ... SSL_CIPHER; -typedef ... Cryptography_STACK_OF_SSL_CIPHER; typedef struct { const char *name; @@ -425,9 +422,6 @@ const unsigned char *, unsigned int, const unsigned char *, unsigned int); -int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *); -const SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int); - int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char *, unsigned); int SSL_set_alpn_protos(SSL *, const unsigned char *, unsigned); void SSL_CTX_set_alpn_select_cb(SSL_CTX *, From 7a021f7decef210ff50ec79c7989726ac2a9c1b4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:10:17 -0500 Subject: [PATCH 288/827] remove unused x509 bindings (#8324) --- src/_cffi_src/openssl/x509.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 2cbc01c95878..48433b2458b4 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -193,8 +193,6 @@ int sk_X509_EXTENSION_num(X509_EXTENSIONS *); X509_EXTENSION *sk_X509_EXTENSION_value(X509_EXTENSIONS *, int); int sk_X509_EXTENSION_push(X509_EXTENSIONS *, X509_EXTENSION *); -int sk_X509_EXTENSION_insert(X509_EXTENSIONS *, X509_EXTENSION *, int); -X509_EXTENSION *sk_X509_EXTENSION_delete(X509_EXTENSIONS *, int); void sk_X509_EXTENSION_free(X509_EXTENSIONS *); void sk_X509_EXTENSION_pop_free(X509_EXTENSIONS *, sk_X509_EXTENSION_freefunc); From 85ea18f1a7da082916051506d68d959e4e283038 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:12:12 -0500 Subject: [PATCH 289/827] remove unused x509name bindings (#8325) --- src/_cffi_src/openssl/x509name.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py index 6fdc2a3c1732..a9ff5ecd21f6 100644 --- a/src/_cffi_src/openssl/x509name.py +++ b/src/_cffi_src/openssl/x509name.py @@ -52,9 +52,6 @@ int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *); X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int); void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *); -Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_new_null(void); -int sk_X509_NAME_ENTRY_push(Cryptography_STACK_OF_X509_NAME_ENTRY *, - X509_NAME_ENTRY *); """ CUSTOMIZATIONS = """ From 83c2b34eee1194a951fc4363d08be80f51137959 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:13:26 -0500 Subject: [PATCH 290/827] remove verification error code bindings (#8326) --- src/_cffi_src/openssl/x509_vfy.py | 57 ------------------------------- 1 file changed, 57 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index daed17eeac99..037219088158 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -34,64 +34,7 @@ as longs, just in case they ever grow to large, such as what we saw with OP_ALL. */ -/* Verification error codes */ static const int X509_V_OK; -static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; -static const int X509_V_ERR_UNABLE_TO_GET_CRL; -static const int X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; -static const int X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; -static const int X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; -static const int X509_V_ERR_CERT_SIGNATURE_FAILURE; -static const int X509_V_ERR_CRL_SIGNATURE_FAILURE; -static const int X509_V_ERR_CERT_NOT_YET_VALID; -static const int X509_V_ERR_CERT_HAS_EXPIRED; -static const int X509_V_ERR_CRL_NOT_YET_VALID; -static const int X509_V_ERR_CRL_HAS_EXPIRED; -static const int X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; -static const int X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; -static const int X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; -static const int X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; -static const int X509_V_ERR_OUT_OF_MEM; -static const int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; -static const int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; -static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; -static const int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; -static const int X509_V_ERR_CERT_CHAIN_TOO_LONG; -static const int X509_V_ERR_CERT_REVOKED; -static const int X509_V_ERR_INVALID_CA; -static const int X509_V_ERR_PATH_LENGTH_EXCEEDED; -static const int X509_V_ERR_INVALID_PURPOSE; -static const int X509_V_ERR_CERT_UNTRUSTED; -static const int X509_V_ERR_CERT_REJECTED; -static const int X509_V_ERR_SUBJECT_ISSUER_MISMATCH; -static const int X509_V_ERR_AKID_SKID_MISMATCH; -static const int X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; -static const int X509_V_ERR_KEYUSAGE_NO_CERTSIGN; -static const int X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; -static const int X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; -static const int X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; -static const int X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; -static const int X509_V_ERR_INVALID_NON_CA; -static const int X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; -static const int X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; -static const int X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; -static const int X509_V_ERR_INVALID_EXTENSION; -static const int X509_V_ERR_INVALID_POLICY_EXTENSION; -static const int X509_V_ERR_NO_EXPLICIT_POLICY; -static const int X509_V_ERR_DIFFERENT_CRL_SCOPE; -static const int X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; -static const int X509_V_ERR_UNNESTED_RESOURCE; -static const int X509_V_ERR_PERMITTED_VIOLATION; -static const int X509_V_ERR_EXCLUDED_VIOLATION; -static const int X509_V_ERR_SUBTREE_MINMAX; -static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; -static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; -static const int X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -static const int X509_V_ERR_CRL_PATH_VALIDATION_ERROR; -static const int X509_V_ERR_HOSTNAME_MISMATCH; -static const int X509_V_ERR_EMAIL_MISMATCH; -static const int X509_V_ERR_IP_ADDRESS_MISMATCH; -static const int X509_V_ERR_APPLICATION_VERIFICATION; /* Verification parameters */ static const long X509_V_FLAG_USE_CHECK_TIME; From 25b9d96391a69045d2317c983ccc9e9ac5fc5577 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:16:44 -0500 Subject: [PATCH 291/827] remove unused bio bindings (#8322) --- src/_cffi_src/openssl/bio.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 6207cb2e20be..899856d355c2 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -15,13 +15,9 @@ FUNCTIONS = """ int BIO_free(BIO *); -void BIO_free_all(BIO *); BIO *BIO_new_file(const char *, const char *); -size_t BIO_ctrl_pending(BIO *); int BIO_read(BIO *, void *, int); -int BIO_gets(BIO *, char *, int); int BIO_write(BIO *, const void *, int); -int BIO_up_ref(BIO *); BIO *BIO_new(BIO_METHOD *); const BIO_METHOD *BIO_s_mem(void); @@ -33,8 +29,6 @@ int BIO_should_io_special(BIO *); int BIO_should_retry(BIO *); int BIO_reset(BIO *); -void BIO_set_retry_read(BIO *); -void BIO_clear_retry_flags(BIO *); BIO_ADDR *BIO_ADDR_new(void); void BIO_ADDR_free(BIO_ADDR *); From 940614123b192864c7c78addcda4932471fc84a5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:37:51 -0500 Subject: [PATCH 292/827] remove unused pkcs7 binding (#8327) --- src/_cffi_src/openssl/pem.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/pem.py b/src/_cffi_src/openssl/pem.py index 2ebcdf6b0eec..62253da7a544 100644 --- a/src/_cffi_src/openssl/pem.py +++ b/src/_cffi_src/openssl/pem.py @@ -27,7 +27,6 @@ int i2d_PKCS8PrivateKey_bio(BIO *, EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); -int i2d_PKCS7_bio(BIO *, PKCS7 *); PKCS7 *d2i_PKCS7_bio(BIO *, PKCS7 **); EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *, EVP_PKEY **, pem_password_cb *, From ad55360a9a6f1ce3578c67d046512c09e4ea28a3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 12:47:55 -0500 Subject: [PATCH 293/827] remove series of unused Cryptography_HAS bindings (#8328) --- src/_cffi_src/openssl/ssl.py | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 06aeb9135a3c..0361e6e21459 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -10,33 +10,19 @@ TYPES = """ static const long Cryptography_HAS_SSL_ST; static const long Cryptography_HAS_TLS_ST; -static const long Cryptography_HAS_TLSv1_1; -static const long Cryptography_HAS_TLSv1_2; static const long Cryptography_HAS_TLSv1_3_FUNCTIONS; -static const long Cryptography_HAS_SECURE_RENEGOTIATION; -static const long Cryptography_HAS_SSL_CTX_CLEAR_OPTIONS; static const long Cryptography_HAS_DTLS; static const long Cryptography_HAS_SIGALGS; static const long Cryptography_HAS_PSK; static const long Cryptography_HAS_PSK_TLSv1_3; static const long Cryptography_HAS_VERIFIED_CHAIN; static const long Cryptography_HAS_KEYLOG; -static const long Cryptography_HAS_TLSEXT_HOSTNAME; static const long Cryptography_HAS_SSL_COOKIE; -/* Internally invented symbol to tell us if SSL_MODE_RELEASE_BUFFERS is - * supported - */ -static const long Cryptography_HAS_RELEASE_BUFFERS; - /* Internally invented symbol to tell us if SSL_OP_NO_COMPRESSION is * supported */ -static const long Cryptography_HAS_OP_NO_COMPRESSION; static const long Cryptography_HAS_OP_NO_RENEGOTIATION; -static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING; -static const long Cryptography_HAS_SSL_SET_SSL_CTX; -static const long Cryptography_HAS_SSL_OP_NO_TICKET; static const long Cryptography_HAS_SSL_OP_IGNORE_UNEXPECTED_EOF; static const long Cryptography_HAS_ALPN; static const long Cryptography_HAS_NEXTPROTONEG; @@ -518,11 +504,6 @@ """ CUSTOMIZATIONS = """ -// This symbol is being preserved because removing it will break users with -// pyOpenSSL < 19.1 and pip < 20.x. We need to leave this in place until those -// users have upgraded. PersistentlyDeprecated2020 -static const long Cryptography_HAS_TLSEXT_HOSTNAME = 1; - #ifdef OPENSSL_NO_ENGINE int (*SSL_CTX_set_client_cert_engine)(SSL_CTX *, ENGINE *) = NULL; #endif @@ -535,15 +516,7 @@ #endif static const long Cryptography_HAS_KEYLOG = 1; -static const long Cryptography_HAS_SECURE_RENEGOTIATION = 1; - -static const long Cryptography_HAS_RELEASE_BUFFERS = 1; -static const long Cryptography_HAS_OP_NO_COMPRESSION = 1; -static const long Cryptography_HAS_TLSv1_1 = 1; -static const long Cryptography_HAS_TLSv1_2 = 1; -static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 1; -static const long Cryptography_HAS_SSL_OP_NO_TICKET = 1; -static const long Cryptography_HAS_SSL_SET_SSL_CTX = 1; + static const long Cryptography_HAS_NEXTPROTONEG = 0; static const long Cryptography_HAS_ALPN = 1; @@ -573,8 +546,6 @@ static const long Cryptography_HAS_GET_EXTMS_SUPPORT = 1; #endif -static const long Cryptography_HAS_SSL_CTX_CLEAR_OPTIONS = 1; - /* in OpenSSL 1.1.0 the SSL_ST values were renamed to TLS_ST and several were removed */ #if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_IS_BORINGSSL From 720f4722386b782a6c9e12d2ec8061f077c41266 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:00:03 -0500 Subject: [PATCH 294/827] remove unused CRL bindings (#8333) --- src/_cffi_src/openssl/x509.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 48433b2458b4..733baf9735c4 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -106,17 +106,13 @@ int X509_REVOKED_set_revocationDate(X509_REVOKED *, ASN1_TIME *); X509_CRL *X509_CRL_new(void); -X509_CRL *X509_CRL_dup(X509_CRL *); X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **); int X509_CRL_add0_revoked(X509_CRL *, X509_REVOKED *); -int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int); -int X509_CRL_cmp(const X509_CRL *, const X509_CRL *); int X509_CRL_print(BIO *, X509_CRL *); int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *); int X509_CRL_set_version(X509_CRL *, long); int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *); int X509_CRL_sort(X509_CRL *); -int X509_CRL_verify(X509_CRL *, EVP_PKEY *); int i2d_X509_CRL_bio(BIO *, X509_CRL *); void X509_CRL_free(X509_CRL *); From 9d9f704842b1bcb66d9b7ef748eb2a9d4b522a17 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:01:59 -0500 Subject: [PATCH 295/827] remove unused pkcs7 bindings (#8332) --- src/_cffi_src/openssl/pkcs7.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/_cffi_src/openssl/pkcs7.py b/src/_cffi_src/openssl/pkcs7.py index c802facf81ae..e0d52322f7e1 100644 --- a/src/_cffi_src/openssl/pkcs7.py +++ b/src/_cffi_src/openssl/pkcs7.py @@ -42,18 +42,7 @@ ...; } PKCS7; -static const int PKCS7_BINARY; -static const int PKCS7_DETACHED; -static const int PKCS7_NOATTR; -static const int PKCS7_NOCERTS; -static const int PKCS7_NOCHAIN; -static const int PKCS7_NOINTERN; -static const int PKCS7_NOSIGS; -static const int PKCS7_NOSMIMECAP; -static const int PKCS7_NOVERIFY; -static const int PKCS7_STREAM; static const int PKCS7_TEXT; -static const int PKCS7_PARTIAL; """ FUNCTIONS = """ From b1cb86ba0977ef28ef6e55702680e12e6456cb1e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:02:49 -0500 Subject: [PATCH 296/827] remove unused evp binding (#8331) --- src/_cffi_src/openssl/evp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index c4d15f9f5a13..19bdcf38bc28 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -120,7 +120,6 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *, EVP_PKEY *); int EVP_PKEY_derive(EVP_PKEY_CTX *, unsigned char *, size_t *); -int EVP_PKEY_set_type(EVP_PKEY *, int); int EVP_PKEY_id(const EVP_PKEY *); From d5d67685693b82a42b8c97e1230eacfa5dd4b77b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:04:13 -0500 Subject: [PATCH 297/827] remove unused netscape spki binding (#8330) --- src/_cffi_src/openssl/x509.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 733baf9735c4..93f0670bb7aa 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -119,7 +119,6 @@ int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *); int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *); char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *); -NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *, int); EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *); int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *, EVP_PKEY *); NETSCAPE_SPKI *NETSCAPE_SPKI_new(void); From 9d9a692aad7efe3907c0348c41249e23b11fb2a4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:07:31 -0500 Subject: [PATCH 298/827] remove unused ec bindings (#8329) --- src/_cffi_src/openssl/ec.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/_cffi_src/openssl/ec.py b/src/_cffi_src/openssl/ec.py index d9c3074cc06e..7314ee0715ec 100644 --- a/src/_cffi_src/openssl/ec.py +++ b/src/_cffi_src/openssl/ec.py @@ -34,7 +34,6 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int); const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); -const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); int EC_GROUP_get_curve_name(const EC_GROUP *); size_t EC_get_builtin_curves(EC_builtin_curve *, size_t); @@ -44,8 +43,6 @@ EC_KEY *EC_KEY_new_by_curve_name(int); const EC_GROUP *EC_KEY_get0_group(const EC_KEY *); -int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *, BN_CTX *); -int EC_KEY_set_group(EC_KEY *, const EC_GROUP *); const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *); int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *); const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *); @@ -56,11 +53,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *); void EC_POINT_free(EC_POINT *); -void EC_POINT_clear_free(EC_POINT *); -EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *); - -int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, BN_CTX *); int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); @@ -75,16 +67,7 @@ int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, const unsigned char *, size_t, BN_CTX *); -int EC_POINT_add(const EC_GROUP *, EC_POINT *, const EC_POINT *, - const EC_POINT *, BN_CTX *); - -int EC_POINT_dbl(const EC_GROUP *, EC_POINT *, const EC_POINT *, BN_CTX *); -int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); - -int EC_POINT_cmp( - const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *); int EC_POINT_mul(const EC_GROUP *, EC_POINT *, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); From db0c21b6074da9e64bf419f50e00d2b6c551eb62 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 15:34:55 -0600 Subject: [PATCH 299/827] remove some error bindings (#8334) --- src/_cffi_src/openssl/err.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index dc27abba364c..efeaae2175b1 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -15,13 +15,10 @@ static const int EVP_R_BAD_DECRYPT; static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM; static const int PKCS12_R_PKCS12_CIPHERFINAL_ERROR; -static const int PEM_R_UNSUPPORTED_ENCRYPTION; static const int EVP_R_XTS_DUPLICATED_KEYS; static const int ERR_LIB_EVP; -static const int ERR_LIB_PEM; static const int ERR_LIB_PROV; -static const int ERR_LIB_ASN1; static const int ERR_LIB_PKCS12; static const int SSL_TLSEXT_ERR_OK; From 895de04c7318edf0ecb5d55c4758598ff6d79724 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 15:38:28 -0600 Subject: [PATCH 300/827] remove unused constant (#8335) --- src/_cffi_src/openssl/ssl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 0361e6e21459..eb77ceca8b4b 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -115,7 +115,6 @@ static const long SSL_CB_HANDSHAKE_DONE; static const long SSL_MODE_RELEASE_BUFFERS; static const long SSL_MODE_ENABLE_PARTIAL_WRITE; -static const long SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const long SSL_MODE_AUTO_RETRY; static const long SSL3_RANDOM_SIZE; static const long TLS_ST_BEFORE; From 052cbb6729a44d978efbc2d6daca567f5dd8be87 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Feb 2023 16:42:36 -0500 Subject: [PATCH 301/827] remove unused x509 binding (#8336) --- src/_cffi_src/openssl/x509.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 93f0670bb7aa..03fd93abd9fa 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -47,7 +47,6 @@ X509 *X509_new(void); void X509_free(X509 *); X509 *X509_dup(X509 *); -int X509_cmp(const X509 *, const X509 *); int X509_up_ref(X509 *); int X509_print_ex(BIO *, X509 *, unsigned long, unsigned long); From 634b92d069c540862d489d777462d0807468b79c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 15:46:29 -0600 Subject: [PATCH 302/827] remove unused DTLS bindings (#8337) * remove unused DTLS bindings * remove conditional --- src/_cffi_src/openssl/ssl.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index eb77ceca8b4b..a3c10faa11bc 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -449,8 +449,6 @@ /* DTLS support */ long Cryptography_DTLSv1_get_timeout(SSL *, time_t *, long *); long DTLSv1_handle_timeout(SSL *); -long DTLS_set_link_mtu(SSL *, long); -long DTLS_get_link_min_mtu(SSL *); long SSL_set_mtu(SSL *, long); int DTLSv1_listen(SSL *, BIO_ADDR *); size_t DTLS_get_data_mtu(SSL *); @@ -564,11 +562,6 @@ static const long TLS_ST_OK = 0; #endif -#if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_IS_BORINGSSL -long (*DTLS_set_link_mtu)(SSL *, long) = NULL; -long (*DTLS_get_link_min_mtu)(SSL *) = NULL; -#endif - #if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_IS_BORINGSSL static const long Cryptography_HAS_DTLS_GET_DATA_MTU = 0; size_t (*DTLS_get_data_mtu)(SSL *) = NULL; From 94d33786cb7ccc28934f1a9f4dff75ce7cc95dbf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 15:50:32 -0600 Subject: [PATCH 303/827] remove SSL_sess bindings (#8338) --- src/_cffi_src/openssl/ssl.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index a3c10faa11bc..e210a9f61184 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -433,19 +433,6 @@ int SSL_export_keying_material(SSL *, unsigned char *, size_t, const char *, size_t, const unsigned char *, size_t, int); -long SSL_CTX_sess_number(SSL_CTX *); -long SSL_CTX_sess_connect(SSL_CTX *); -long SSL_CTX_sess_connect_good(SSL_CTX *); -long SSL_CTX_sess_connect_renegotiate(SSL_CTX *); -long SSL_CTX_sess_accept(SSL_CTX *); -long SSL_CTX_sess_accept_good(SSL_CTX *); -long SSL_CTX_sess_accept_renegotiate(SSL_CTX *); -long SSL_CTX_sess_hits(SSL_CTX *); -long SSL_CTX_sess_cb_hits(SSL_CTX *); -long SSL_CTX_sess_misses(SSL_CTX *); -long SSL_CTX_sess_timeouts(SSL_CTX *); -long SSL_CTX_sess_cache_full(SSL_CTX *); - /* DTLS support */ long Cryptography_DTLSv1_get_timeout(SSL *, time_t *, long *); long DTLSv1_handle_timeout(SSL *); From 4324f61005731d64df342358835eba76784f37b9 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 16:14:59 -0600 Subject: [PATCH 304/827] remove some reneg bindings (#8339) --- src/_cffi_src/openssl/ssl.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index e210a9f61184..e962202cbe47 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -19,9 +19,6 @@ static const long Cryptography_HAS_KEYLOG; static const long Cryptography_HAS_SSL_COOKIE; -/* Internally invented symbol to tell us if SSL_OP_NO_COMPRESSION is - * supported - */ static const long Cryptography_HAS_OP_NO_RENEGOTIATION; static const long Cryptography_HAS_SSL_OP_IGNORE_UNEXPECTED_EOF; static const long Cryptography_HAS_ALPN; @@ -77,8 +74,6 @@ static const long SSL_OP_NO_TICKET; static const long SSL_OP_ALL; static const long SSL_OP_SINGLE_ECDH_USE; -static const long SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -static const long SSL_OP_LEGACY_SERVER_CONNECT; static const long SSL_OP_IGNORE_UNEXPECTED_EOF; static const long SSL_VERIFY_PEER; static const long SSL_VERIFY_FAIL_IF_NO_PEER_CERT; @@ -332,7 +327,6 @@ int SSL_want_write(const SSL *); long SSL_total_renegotiations(SSL *); -long SSL_get_secure_renegotiation_support(SSL *); long SSL_CTX_set_min_proto_version(SSL_CTX *, int); long SSL_CTX_set_max_proto_version(SSL_CTX *, int); From 3c600f62d6fc6bba3317e396baa8ad6d75a4d149 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 00:43:12 +0000 Subject: [PATCH 305/827] Bump BoringSSL and/or OpenSSL in CI (#8342) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc7ba0dc2993..94472b770f7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Feb 18, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e18ba272d4532659a20904c812207079c4ec2e80"}} - # Latest commit on the OpenSSL master branch, as of Feb 15, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "cd870db16348d0d09cb05b7393cf9281509c7795"}} + # Latest commit on the OpenSSL master branch, as of Feb 20, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d54e91d3944304bca2bd4c74af52ccffc49c6126"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 47c0b0ce8dd1dd581169c3d534b300a28274694b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 20:44:56 -0600 Subject: [PATCH 306/827] remove SSL_CIPHER bindings (#8341) --- src/_cffi_src/openssl/ssl.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index e962202cbe47..8c2ffd53a23b 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -296,15 +296,6 @@ /* Information about actually used cipher */ const char *SSL_CIPHER_get_name(const SSL_CIPHER *); int SSL_CIPHER_get_bits(const SSL_CIPHER *, int *); -/* the modern signature of this is uint32_t, but older openssl declared it - as unsigned long. To make our compiler flags happy we'll declare it as a - 64-bit wide value, which should always be safe */ -uint64_t SSL_CIPHER_get_id(const SSL_CIPHER *); -int SSL_CIPHER_is_aead(const SSL_CIPHER *); -int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *); -int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *); -int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *); -int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *); size_t SSL_get_finished(const SSL *, void *, size_t); size_t SSL_get_peer_finished(const SSL *, void *, size_t); From 95f214a0d6cf71b2dbb6f7447b6eb1b15ea6123c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 19 Feb 2023 20:45:13 -0600 Subject: [PATCH 307/827] remove proto_version getters and most SSL_SESSION_* bindings (#8340) * remove proto_version getters and SSL_SESSION_* bindings * oops --- src/_cffi_src/openssl/ssl.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 8c2ffd53a23b..69baf60ff2d4 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -305,11 +305,6 @@ const char *SSL_CIPHER_get_version(const SSL_CIPHER *); SSL_SESSION *SSL_get_session(const SSL *); -const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *, unsigned int *); -long SSL_SESSION_get_time(const SSL_SESSION *); -long SSL_SESSION_get_timeout(const SSL_SESSION *); -int SSL_SESSION_has_ticket(const SSL_SESSION *); -unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *); uint64_t SSL_set_options(SSL *, uint64_t); uint64_t SSL_get_options(SSL *); @@ -321,13 +316,6 @@ long SSL_CTX_set_min_proto_version(SSL_CTX *, int); long SSL_CTX_set_max_proto_version(SSL_CTX *, int); -long SSL_set_min_proto_version(SSL *, int); -long SSL_set_max_proto_version(SSL *, int); - -long SSL_CTX_get_min_proto_version(SSL_CTX *); -long SSL_CTX_get_max_proto_version(SSL_CTX *); -long SSL_get_min_proto_version(SSL *); -long SSL_get_max_proto_version(SSL *); long SSL_CTX_set_tmp_ecdh(SSL_CTX *, EC_KEY *); long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); From 85e2b5056f219d0c54f02c93c8c40f7e6137516b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 12:40:46 +0000 Subject: [PATCH 308/827] Bump sphinxcontrib-spelling from 7.7.0 to 8.0.0 (#8350) Bumps [sphinxcontrib-spelling](https://github.com/sphinx-contrib/spelling) from 7.7.0 to 8.0.0. - [Release notes](https://github.com/sphinx-contrib/spelling/releases) - [Commits](https://github.com/sphinx-contrib/spelling/compare/7.7.0...8.0.0) --- updated-dependencies: - dependency-name: sphinxcontrib-spelling dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4213acab5d24..0e20cf30142b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -191,7 +191,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sphinxcontrib-spelling==7.7.0 +sphinxcontrib-spelling==8.0.0 # via cryptography (setup.cfg) tomli==2.0.1; python_version >= "3.7" # via From 220fdaf45b57c9b05379ce0b660249bb963816b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 12:46:28 +0000 Subject: [PATCH 309/827] Bump zipp from 3.13.0 to 3.14.0 (#8351) Bumps [zipp](https://github.com/jaraco/zipp) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.13.0...v3.14.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 0e20cf30142b..88f6e135d03b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -224,7 +224,7 @@ virtualenv==20.19.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach -zipp==3.13.0; python_version >= "3.7" +zipp==3.14.0; python_version >= "3.7" # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From e567363000bb0fb98c706aa97d644af3fa1ce86a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 12:49:57 +0000 Subject: [PATCH 310/827] Bump mypy from 1.0.0 to 1.0.1 (#8352) Bumps [mypy](https://github.com/python/mypy) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.0.0...v1.0.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 88f6e135d03b..b0d33b0c0a5f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -80,7 +80,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.0.0 # via jaraco-classes -mypy==1.0.0 +mypy==1.0.1 # via cryptography (setup.cfg) mypy-extensions==1.0.0 # via From 5e0381405211e2b05c0866cd03356e9de3fb0e76 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 08:50:06 -0500 Subject: [PATCH 311/827] Remove unused rsa binding (#8345) --- src/_cffi_src/openssl/rsa.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/rsa.py b/src/_cffi_src/openssl/rsa.py index 3492d4588e11..a7a3256b71bb 100644 --- a/src/_cffi_src/openssl/rsa.py +++ b/src/_cffi_src/openssl/rsa.py @@ -11,7 +11,6 @@ typedef ... RSA; typedef ... BN_GENCB; static const int RSA_PKCS1_PADDING; -static const int RSA_NO_PADDING; static const int RSA_PKCS1_OAEP_PADDING; static const int RSA_PKCS1_PSS_PADDING; static const int RSA_F4; From 04bd4f0b6b26bf60fc3ff29a06b66f1fc4383cb4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 08:50:43 -0500 Subject: [PATCH 312/827] remove unused object binding (#8344) --- src/_cffi_src/openssl/objects.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/objects.py b/src/_cffi_src/openssl/objects.py index a5440c1b4328..cfa7fac21268 100644 --- a/src/_cffi_src/openssl/objects.py +++ b/src/_cffi_src/openssl/objects.py @@ -16,7 +16,6 @@ int OBJ_obj2nid(const ASN1_OBJECT *); int OBJ_sn2nid(const char *); int OBJ_txt2nid(const char *); -ASN1_OBJECT *OBJ_txt2obj(const char *, int); """ CUSTOMIZATIONS = """ From 456697ed5ba47f677c743c64e4e07bb3ed4ee2e7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 08:51:09 -0500 Subject: [PATCH 313/827] remove unused ssl binding (#8346) --- src/_cffi_src/openssl/ssl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 69baf60ff2d4..8892212b15e1 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -111,7 +111,6 @@ static const long SSL_MODE_RELEASE_BUFFERS; static const long SSL_MODE_ENABLE_PARTIAL_WRITE; static const long SSL_MODE_AUTO_RETRY; -static const long SSL3_RANDOM_SIZE; static const long TLS_ST_BEFORE; static const long TLS_ST_OK; From 5e3913444b29fe1b9c9e3f744dddeaed39177964 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 08:51:57 -0500 Subject: [PATCH 314/827] remove unused x509 name binding (#8348) --- src/_cffi_src/openssl/x509name.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py index a9ff5ecd21f6..9eca79e38e7c 100644 --- a/src/_cffi_src/openssl/x509name.py +++ b/src/_cffi_src/openssl/x509name.py @@ -43,10 +43,6 @@ int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, const unsigned char *, int, int, int); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **, - const ASN1_OBJECT *, int, - const unsigned char *, int); - Cryptography_STACK_OF_X509_NAME *sk_X509_NAME_new_null(void); int sk_X509_NAME_num(Cryptography_STACK_OF_X509_NAME *); int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *); From 74f04555dbb2e4dca8ebac3ce2659e5e75557a24 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 10:43:50 -0500 Subject: [PATCH 315/827] remove unused ssl bindings (#8353) --- src/_cffi_src/openssl/ssl.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 8892212b15e1..419682b3eac3 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -337,10 +337,6 @@ const SSL_METHOD *DTLS_server_method(void); const SSL_METHOD *DTLS_client_method(void); -const SSL_METHOD *SSLv23_method(void); -const SSL_METHOD *SSLv23_server_method(void); -const SSL_METHOD *SSLv23_client_method(void); - const SSL_METHOD *TLS_method(void); const SSL_METHOD *TLS_server_method(void); const SSL_METHOD *TLS_client_method(void); From a07ad61e8ef9baa71d344cd9803c0bf19a1d5cc4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 12:13:15 -0500 Subject: [PATCH 316/827] remove unused x509 bindings (#8343) --- src/_cffi_src/openssl/x509.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 03fd93abd9fa..06445f12c4af 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -80,15 +80,12 @@ X509_REQ *X509_REQ_new(void); void X509_REQ_free(X509_REQ *); int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *); -int X509_REQ_set_subject_name(X509_REQ *, X509_NAME *); int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *); int X509_REQ_verify(X509_REQ *, EVP_PKEY *); EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *); int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long); int X509_REQ_add_extensions(X509_REQ *, X509_EXTENSIONS *); X509_EXTENSIONS *X509_REQ_get_extensions(X509_REQ *); -int X509_REQ_add1_attr_by_OBJ(X509_REQ *, const ASN1_OBJECT *, - int, const unsigned char *, int); int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int); ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *); @@ -98,7 +95,6 @@ int X509_REVOKED_set_serialNumber(X509_REVOKED *, ASN1_INTEGER *); -int X509_REVOKED_add_ext(X509_REVOKED *, X509_EXTENSION*, int); int X509_REVOKED_add1_ext_i2d(X509_REVOKED *, int, void *, int, unsigned long); X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *, int); @@ -155,11 +151,6 @@ X509_NAME *X509_get_subject_name(const X509 *); X509_NAME *X509_get_issuer_name(const X509 *); -X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **, - const ASN1_OBJECT *, int, - ASN1_OCTET_STRING *); - - int X509_EXTENSION_get_critical(const X509_EXTENSION *); int X509_REVOKED_get_ext_count(const X509_REVOKED *); From 721586ba5387ac0fd9bf6f65fd2a014110b21a5b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 12:14:47 -0500 Subject: [PATCH 317/827] remove unused x509 verify bindings (#8347) --- src/_cffi_src/openssl/x509_vfy.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 037219088158..156236a47b93 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -56,9 +56,6 @@ static const long X509_V_FLAG_NO_ALT_CHAINS; static const long X509_V_FLAG_NO_CHECK_TIME; -static const long X509_LU_X509; -static const long X509_LU_CRL; - static const long X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; static const long X509_CHECK_FLAG_NO_WILDCARDS; static const long X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; @@ -148,10 +145,8 @@ int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *, const char *); int sk_X509_OBJECT_num(Cryptography_STACK_OF_X509_OBJECT *); -X509_OBJECT *sk_X509_OBJECT_value(Cryptography_STACK_OF_X509_OBJECT *, int); X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *); Cryptography_STACK_OF_X509_OBJECT *X509_STORE_get0_objects(X509_STORE *); -X509 *X509_OBJECT_get0_X509(X509_OBJECT *); X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *); void X509_STORE_set_get_issuer(X509_STORE *, X509_STORE_CTX_get_issuer_fn); From d5540441b5c45c850884a81d8f1da0d6fb77bc53 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 13:28:25 -0500 Subject: [PATCH 318/827] remove unused ssl binding (#8354) --- src/_cffi_src/openssl/ssl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 419682b3eac3..fe3e0f4e8d4f 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -36,7 +36,6 @@ static const long SSL_ERROR_WANT_READ; static const long SSL_ERROR_WANT_WRITE; static const long SSL_ERROR_WANT_X509_LOOKUP; -static const long SSL_ERROR_WANT_CONNECT; static const long SSL_ERROR_SYSCALL; static const long SSL_ERROR_SSL; static const long SSL_SENT_SHUTDOWN; From 8bd05fffc79b7c13b21e4037b77213cb050f218c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 13:29:21 -0500 Subject: [PATCH 319/827] remove unused error binding (#8355) --- src/_cffi_src/openssl/err.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index efeaae2175b1..a38ad7326987 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -25,8 +25,6 @@ static const int SSL_TLSEXT_ERR_ALERT_FATAL; static const int SSL_TLSEXT_ERR_NOACK; -static const int X509_R_CERT_ALREADY_IN_HASH_TABLE; - static const int SSL_R_UNEXPECTED_EOF_WHILE_READING; static const int Cryptography_HAS_UNEXPECTED_EOF_WHILE_READING; From 20678fdd0e8d04d1ba2fe3b7257dcf64c4b85809 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 15:37:52 -0500 Subject: [PATCH 320/827] remove unused x509 verify bindings (#8356) * remove unused x509 verify bindings * Update x509_vfy.py * Update x509_vfy.py * Update x509_vfy.py --- src/_cffi_src/openssl/x509_vfy.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 156236a47b93..3e7a3bde8e81 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -118,31 +118,18 @@ /* X509_VERIFY_PARAM */ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *, unsigned long); -int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *, unsigned long); -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *); -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *, int); -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *, int); void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *, time_t); -int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *, ASN1_OBJECT *); -int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *, - Cryptography_STACK_OF_ASN1_OBJECT *); -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *, int); -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *); void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *); /* X509_STORE_CTX */ void X509_STORE_CTX_set0_crls(X509_STORE_CTX *, Cryptography_STACK_OF_X509_CRL *); -/* X509_VERIFY_PARAM */ int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *, const char *, size_t); void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *, unsigned int); -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *, const char *, - size_t); int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *, const unsigned char *, size_t); -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *, const char *); int sk_X509_OBJECT_num(Cryptography_STACK_OF_X509_OBJECT *); X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *); From 8ba0eced3d2c229d70d600c0bc4cd8786f43f623 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Feb 2023 17:48:04 -0500 Subject: [PATCH 321/827] remove unused x509 verify bindings (#8358) --- src/_cffi_src/openssl/x509_vfy.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 3e7a3bde8e81..b77b2ed3317e 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -100,20 +100,12 @@ void X509_STORE_CTX_free(X509_STORE_CTX *); int X509_STORE_CTX_init(X509_STORE_CTX *, X509_STORE *, X509 *, Cryptography_STACK_OF_X509 *); -void X509_STORE_CTX_set_cert(X509_STORE_CTX *, X509 *); -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *); -void X509_STORE_CTX_set0_param(X509_STORE_CTX *, X509_VERIFY_PARAM *); -int X509_STORE_CTX_set_default(X509_STORE_CTX *, const char *); -void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *, - int (*)(int, X509_STORE_CTX *)); Cryptography_STACK_OF_X509 *X509_STORE_CTX_get1_chain(X509_STORE_CTX *); int X509_STORE_CTX_get_error(X509_STORE_CTX *); void X509_STORE_CTX_set_error(X509_STORE_CTX *, int); int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *); X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *); -int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *, int, void *); void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *, int); -int X509_STORE_CTX_get1_issuer(X509 **, X509_STORE_CTX *, X509 *); /* X509_VERIFY_PARAM */ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); @@ -121,10 +113,6 @@ void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *, time_t); void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *); -/* X509_STORE_CTX */ -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *, - Cryptography_STACK_OF_X509_CRL *); - int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *, const char *, size_t); void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *, unsigned int); @@ -132,7 +120,6 @@ size_t); int sk_X509_OBJECT_num(Cryptography_STACK_OF_X509_OBJECT *); -X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *); Cryptography_STACK_OF_X509_OBJECT *X509_STORE_get0_objects(X509_STORE *); X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *); From 5d475502b31845c9b735495120313b511e86b4f7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 20 Feb 2023 17:28:44 -0600 Subject: [PATCH 322/827] remove more unused ssl bindings (#8359) `SSL_OP_NO_DTLS*` are identical to the `TLS` values and we've never used session_reused. --- src/_cffi_src/openssl/ssl.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index fe3e0f4e8d4f..84fdcd627ba7 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -46,8 +46,6 @@ static const long SSL_OP_NO_TLSv1_1; static const long SSL_OP_NO_TLSv1_2; static const long SSL_OP_NO_TLSv1_3; -static const long SSL_OP_NO_DTLSv1; -static const long SSL_OP_NO_DTLSv1_2; static const long SSL_OP_NO_RENEGOTIATION; static const long SSL_OP_NO_COMPRESSION; static const long SSL_OP_SINGLE_DH_USE; @@ -368,8 +366,6 @@ int SSL_set_tlsext_use_srtp(SSL *, const char *); SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *); -long SSL_session_reused(SSL *); - int SSL_select_next_proto(unsigned char **, unsigned char *, const unsigned char *, unsigned int, const unsigned char *, unsigned int); From 61cbf304eb4542dc4bc03f4fbdd19318f5cd3074 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 20 Feb 2023 17:49:16 -0600 Subject: [PATCH 323/827] endless binding removal (#8360) --- src/_cffi_src/openssl/ssl.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 84fdcd627ba7..a3b65a482c00 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -213,9 +213,6 @@ unsigned int )); -long SSL_CTX_get_read_ahead(SSL_CTX *); -long SSL_CTX_set_read_ahead(SSL_CTX *, long); - int SSL_CTX_use_psk_identity_hint(SSL_CTX *, const char *); void SSL_CTX_set_psk_server_callback(SSL_CTX *, unsigned int (*)( From 5a34d492bc93452d5aca89fc677ca54486fe5bda Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 20 Feb 2023 17:57:08 -0600 Subject: [PATCH 324/827] embrace my inner nitpicker (#8361) fixes all our versionadded/changed to match actual versions we released --- docs/hazmat/primitives/aead.rst | 4 +- docs/hazmat/primitives/asymmetric/rsa.rst | 4 +- .../primitives/asymmetric/serialization.rst | 16 ++++---- .../primitives/key-derivation-functions.rst | 4 +- docs/x509/certificate-transparency.rst | 10 ++--- docs/x509/reference.rst | 38 +++++++++---------- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/docs/hazmat/primitives/aead.rst b/docs/hazmat/primitives/aead.rst index 82a64bcd5b52..db9ef96d1ab7 100644 --- a/docs/hazmat/primitives/aead.rst +++ b/docs/hazmat/primitives/aead.rst @@ -166,7 +166,7 @@ also support providing integrity for associated data which is not encrypted. .. class:: AESOCB3(key) - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 The OCB3 construction is defined in :rfc:`7253`. It is an AEAD mode that offers strong integrity guarantees and good performance. @@ -242,7 +242,7 @@ also support providing integrity for associated data which is not encrypted. .. class:: AESSIV(key) - .. versionadded:: 37.0 + .. versionadded:: 37.0.0 The SIV (synthetic initialization vector) construction is defined in :rfc:`5297`. Depending on how it is used, SIV allows either diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 7291e8c5b0ad..7c268320ae21 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -304,7 +304,7 @@ Padding .. attribute:: DIGEST_LENGTH - .. versionadded:: 37.0 + .. versionadded:: 37.0.0 Pass this attribute to ``salt_length`` to set the salt length to the byte length of the digest passed when calling ``sign``. Note that this @@ -312,7 +312,7 @@ Padding .. attribute:: AUTO - .. versionadded:: 37.0 + .. versionadded:: 37.0.0 Pass this attribute to ``salt_length`` to automatically determine the salt length when verifying. Raises ``ValueError`` if used when signing. diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 14022f26d7ce..de6d59df0909 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -478,7 +478,7 @@ The format used by OpenSSH for certificates, as specified in .. function:: load_ssh_public_identity(data) - .. versionadded:: 40.0 + .. versionadded:: 40.0.0 .. note:: @@ -509,7 +509,7 @@ The format used by OpenSSH for certificates, as specified in .. class:: SSHCertificate - .. versionadded:: 40.0 + .. versionadded:: 40.0.0 .. attribute:: nonce @@ -628,7 +628,7 @@ The format used by OpenSSH for certificates, as specified in .. class:: SSHCertificateType - .. versionadded:: 40.0 + .. versionadded:: 40.0.0 An enumeration of the types of SSH certificates. @@ -647,7 +647,7 @@ SSH Certificate Builder .. class:: SSHCertificateBuilder - .. versionadded:: 40.0 + .. versionadded:: 40.0.0 .. note:: @@ -801,7 +801,7 @@ file suffix. .. function:: load_pkcs12(data, password) - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 Deserialize a PKCS12 blob, and return a :class:`~cryptography.hazmat.primitives.serialization.pkcs12.PKCS12KeyAndCertificates` @@ -911,7 +911,7 @@ file suffix. .. class:: PKCS12Certificate - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 Represents additional data provided for a certificate in a PKCS12 file. @@ -927,7 +927,7 @@ file suffix. .. class:: PKCS12KeyAndCertificates - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 A simplified representation of a PKCS12 file. @@ -1019,7 +1019,7 @@ contain certificates, CRLs, and much more. PKCS7 files commonly have a ``p7b``, .. function:: serialize_certificates(certs, encoding) - .. versionadded:: 37.0 + .. versionadded:: 37.0.0 Serialize a list of certificates to a PKCS7 structure. diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst index 6427645db78f..ff9a5ba0ffe7 100644 --- a/docs/hazmat/primitives/key-derivation-functions.rst +++ b/docs/hazmat/primitives/key-derivation-functions.rst @@ -723,7 +723,7 @@ KBKDF .. class:: KBKDFCMAC(algorithm, mode, length, rlen, llen, location,\ label, context, fixed) - .. versionadded:: 35.0 + .. versionadded:: 35.0.0 KBKDF (Key Based Key Derivation Function) is defined by the `NIST SP 800-108`_ document, to be used to derive additional @@ -879,7 +879,7 @@ KBKDF .. attribute:: MiddleFixed - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 The counter iteration variable will be concatenated in the middle of the fixed input data. diff --git a/docs/x509/certificate-transparency.rst b/docs/x509/certificate-transparency.rst index dffee0c3f619..33933384e19f 100644 --- a/docs/x509/certificate-transparency.rst +++ b/docs/x509/certificate-transparency.rst @@ -52,7 +52,7 @@ issued. .. attribute:: signature_hash_algorithm - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 :type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` @@ -61,7 +61,7 @@ issued. .. attribute:: signature_algorithm - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 :type: :class:`~cryptography.x509.certificate_transparency.SignatureAlgorithm` @@ -70,7 +70,7 @@ issued. .. attribute:: signature - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 :type: bytes @@ -78,7 +78,7 @@ issued. .. attribute:: extension_bytes - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 :type: bytes @@ -111,7 +111,7 @@ issued. .. class:: SignatureAlgorithm - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 An enumeration for SignedCertificateTimestamp signature algorithms. diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 03bd86b9e221..f536b531a231 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -172,7 +172,7 @@ Loading Certificates .. function:: load_pem_x509_certificates(data) :canonical: cryptography.x509.base.load_pem_x509_certificates - .. versionadded:: 39.0 + .. versionadded:: 39.0.0 Deserialize one or more certificates from PEM encoded data. @@ -488,7 +488,7 @@ X.509 Certificate Object .. method:: verify_directly_issued_by(issuer) - .. versionadded:: 40.0 + .. versionadded:: 40.0.0 :param issuer: The issuer certificate to check against. :type issuer: :class:`~cryptography.x509.Certificate` @@ -518,7 +518,7 @@ X.509 Certificate Object .. attribute:: tbs_precertificate_bytes - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 :type: bytes @@ -936,7 +936,7 @@ X.509 CSR (Certificate Signing Request) Object .. attribute:: attributes - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 :type: :class:`Attributes` @@ -1312,7 +1312,7 @@ X.509 CSR (Certificate Signing Request) Builder Object .. classmethod:: from_rfc4514_string(data, attr_name_overrides=None) - .. versionadded: 37.0 + .. versionadded: 37.0.0 :param str data: An :rfc:`4514` string. :param attr_name_overrides: Specify custom OID to name mappings, which @@ -1351,7 +1351,7 @@ X.509 CSR (Certificate Signing Request) Builder Object .. method:: rfc4514_string(attr_name_overrides=None) .. versionadded:: 2.5 - .. versionchanged:: 36.0 + .. versionchanged:: 36.0.0 Added ``attr_name_overrides`` parameter. @@ -1425,7 +1425,7 @@ X.509 CSR (Certificate Signing Request) Builder Object .. attribute:: rfc4514_attribute_name - .. versionadded:: 35.0 + .. versionadded:: 35.0.0 :type: str @@ -1435,7 +1435,7 @@ X.509 CSR (Certificate Signing Request) Builder Object .. method:: rfc4514_string(attr_name_overrides=None) .. versionadded:: 2.5 - .. versionchanged:: 36.0 + .. versionchanged:: 36.0.0 Added ``attr_name_overrides`` parameter. @@ -1468,7 +1468,7 @@ X.509 CSR (Certificate Signing Request) Builder Object .. method:: rfc4514_string(attr_name_overrides=None) .. versionadded:: 2.5 - .. versionchanged:: 36.0 + .. versionchanged:: 36.0.0 Added ``attr_name_overrides`` parameter. @@ -1712,7 +1712,7 @@ X.509 Extensions .. method:: public_bytes() - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 :return bytes: @@ -2916,7 +2916,7 @@ X.509 Request Attributes .. class:: Attributes :canonical: cryptography.x509.base.Attributes - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 An Attributes instance is an ordered list of attributes. The object is iterable to get every attribute. Each returned element is an @@ -2924,7 +2924,7 @@ X.509 Request Attributes .. method:: get_attribute_for_oid(oid) - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 :param oid: An :class:`ObjectIdentifier` instance. @@ -2937,7 +2937,7 @@ X.509 Request Attributes .. class:: Attribute :canonical: cryptography.x509.base.Attribute - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 An attribute associated with an X.509 request. @@ -3215,14 +3215,14 @@ instances. The following common OIDs are available as constants. .. attribute:: DSA_WITH_SHA384 - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.3"``. This is a SHA384 digest signed by a DSA key. .. attribute:: DSA_WITH_SHA512 - .. versionadded:: 36.0 + .. versionadded:: 36.0.0 Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.4"``. This is a SHA512 digest signed by a DSA key. @@ -3293,7 +3293,7 @@ instances. The following common OIDs are available as constants. .. attribute:: SMARTCARD_LOGON - .. versionadded:: 35.0 + .. versionadded:: 35.0.0 Corresponds to the dotted string ``"1.3.6.1.4.1.311.20.2.2"``. This is used to denote that a certificate may be used for ``PKINIT`` access @@ -3301,7 +3301,7 @@ instances. The following common OIDs are available as constants. .. attribute:: KERBEROS_PKINIT_KDC - .. versionadded:: 35.0 + .. versionadded:: 35.0.0 Corresponds to the dotted string ``"1.3.6.1.5.2.3.5"``. This is used to denote that a certificate may be used as a Kerberos @@ -3310,7 +3310,7 @@ instances. The following common OIDs are available as constants. .. attribute:: IPSEC_IKE - .. versionadded:: 37.0 + .. versionadded:: 37.0.0 Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.17"``. This is used to denote that a certificate may be assigned to an IPSEC SA, @@ -3319,7 +3319,7 @@ instances. The following common OIDs are available as constants. .. attribute:: CERTIFICATE_TRANSPARENCY - .. versionadded:: 38.0 + .. versionadded:: 38.0.0 Corresponds to the dotted string ``"1.3.6.1.4.1.11129.2.4.4"``. This is used to denote that a certificate may be used as a pre-certificate From fd60fc008dde1c7a62122a841495f96d97a69448 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 18:19:03 -0600 Subject: [PATCH 325/827] Bump BoringSSL and/or OpenSSL in CI (#8362) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94472b770f7e..0b6987f90567 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Feb 18, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e18ba272d4532659a20904c812207079c4ec2e80"}} - # Latest commit on the OpenSSL master branch, as of Feb 20, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d54e91d3944304bca2bd4c74af52ccffc49c6126"}} + # Latest commit on the OpenSSL master branch, as of Feb 21, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "7e5505107aacdf58a4d0c00da90af4b7407c8d65"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 751f89c1f167d9f08e5d97abe3a7c30f20e12128 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:16:22 +0000 Subject: [PATCH 326/827] Bump actions/cache from 3.2.5 to 3.2.6 (#8365) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.5 to 3.2.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.5...v3.2.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b6987f90567..0b31537add94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load OpenSSL cache - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 id: ossl-cache timeout-minutes: 5 with: From adde681bedc2fcd548888dbea3f9542d8050ef4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:20:22 +0000 Subject: [PATCH 327/827] Bump types-pytz from 2022.7.1.0 to 2022.7.1.1 (#8366) Bumps [types-pytz](https://github.com/python/typeshed) from 2022.7.1.0 to 2022.7.1.1. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pytz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b0d33b0c0a5f..8c9d3e855538 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -208,7 +208,7 @@ tox==4.4.5; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -types-pytz==2022.7.1.0 +types-pytz==2022.7.1.1 # via cryptography (setup.cfg) types-requests==2.28.11.13 # via cryptography (setup.cfg) From 3c98f9fef4c6153b7c39a63ea2073303d552dc10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:24:04 +0000 Subject: [PATCH 328/827] Bump ruff from 0.0.247 to 0.0.249 (#8367) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.247 to 0.0.249. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.247...v0.0.249) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8c9d3e855538..037f6d34fb48 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.247 +ruff==0.0.249 # via cryptography (setup.cfg) six==1.16.0 # via bleach From b4df1a4b40718479a7d07c57f42d084280df6641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:36:56 +0000 Subject: [PATCH 329/827] Bump types-urllib3 from 1.26.25.6 to 1.26.25.7 (#8368) Bumps [types-urllib3](https://github.com/python/typeshed) from 1.26.25.6 to 1.26.25.7. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 037f6d34fb48..0900366935f9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -212,7 +212,7 @@ types-pytz==2022.7.1.1 # via cryptography (setup.cfg) types-requests==2.28.11.13 # via cryptography (setup.cfg) -types-urllib3==1.26.25.6 +types-urllib3==1.26.25.7 # via types-requests typing-extensions==4.5.0; python_version >= "3.7" # via mypy From f44631cad85c0a1c3da5e53b47db70fa40b86c89 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 21 Feb 2023 08:53:33 -0500 Subject: [PATCH 330/827] document the bindings massacre (#8363) * document the bindings massacre * Update CHANGELOG.rst * Update CHANGELOG.rst Co-authored-by: Paul Kehrer --------- Co-authored-by: Paul Kehrer --- CHANGELOG.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b8b4954f6f60..a545cf5fac2a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -34,6 +34,10 @@ Changelog * Added a check to :class:`~cryptography.x509.NameConstraints` to ensure that :class:`~cryptography.x509.DNSName` constraints do not contain any ``*`` wildcards. +* Removed many unused CFFI OpenSSL bindings. This will not impact you unless + you are using ``cryptography`` to directly invoke OpenSSL's C API. Note that + these have never been considered a stable, supported, public API by + ``cryptography``, this note is included as a courtesy. .. _v39-0-1: From 1af039f5fe1ac2710dfe21f6e0b7bafeaa7116eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 08:41:02 -0600 Subject: [PATCH 331/827] Bump types-requests from 2.28.11.13 to 2.28.11.14 (#8369) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.13 to 2.28.11.14. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 0900366935f9..2566740fa903 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -210,7 +210,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.1 # via cryptography (setup.cfg) -types-requests==2.28.11.13 +types-requests==2.28.11.14 # via cryptography (setup.cfg) types-urllib3==1.26.25.7 # via types-requests From d4e7bf8e8906d7ef97e6247f9100d71a9f1898cb Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 00:19:49 +0000 Subject: [PATCH 332/827] Bump BoringSSL and/or OpenSSL in CI (#8372) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b31537add94..70823d78d01b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 18, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e18ba272d4532659a20904c812207079c4ec2e80"}} - # Latest commit on the OpenSSL master branch, as of Feb 21, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "7e5505107aacdf58a4d0c00da90af4b7407c8d65"}} + # Latest commit on the BoringSSL master branch, as of Feb 22, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "bade46179ea3d729a434b92c2577be18d8a1cc4b"}} + # Latest commit on the OpenSSL master branch, as of Feb 22, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "0aa7d7f42bc757a0993739b6cfdc8819a70d22ef"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 50fec7e5418a68088456d7041abf2b9ed91c8b9c Mon Sep 17 00:00:00 2001 From: Jake Date: Wed, 22 Feb 2023 23:03:26 +1100 Subject: [PATCH 333/827] Fix SSHCertificateBuilder sample code (#8373) Update SSHCertificateBuilder sample code to: * Correctly use the signing key when signing the certificate, rather than the user's own private key. * Generate the user's public key in one line, making it clearer to the reader that only the public key is an input to the certificate builder. --- docs/hazmat/primitives/asymmetric/serialization.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index de6d59df0909..6a9d7c1987a8 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -663,8 +663,7 @@ SSH Certificate Builder ... SSHCertificateType, SSHCertificateBuilder ... ) >>> signing_key = ec.generate_private_key(ec.SECP256R1()) - >>> private_key = ec.generate_private_key(ec.SECP256R1()) - >>> public_key = private_key.public_key() + >>> public_key = ec.generate_private_key(ec.SECP256R1()).public_key() >>> valid_after = datetime.datetime( ... 2023, 1, 1, 1, tzinfo=datetime.timezone.utc ... ).timestamp() @@ -683,7 +682,7 @@ SSH Certificate Builder ... .valid_principals(valid_principals) ... .add_extension(b"no-touch-required", b"") ... ) - >>> builder.sign(private_key).public_bytes() + >>> builder.sign(signing_key).public_bytes() b'...' .. method:: public_key(public_key) From db6905d69c4a1330570b00210e057bd3ecfbe7d3 Mon Sep 17 00:00:00 2001 From: David Buchanan Date: Wed, 22 Feb 2023 13:09:34 +0000 Subject: [PATCH 334/827] Add shortcut methods for exporting EC keys as raw bytes (#8357) * WIP: Add raw export alias method for x25519 keys * Ditto for x448, ed448, ed25519 * Document new private_bytes_raw public_bytes_raw methods * docs: Populate versionadded to be 40 * docs: Fix PublicFormat -> PrivateFormat where applicable * formatting * Update tests for test_pub_priv_bytes_raw in x25519, x448, ed448 (TODO: ed25519) * Add test_pub_priv_bytes_raw test for Ed25519 --- docs/hazmat/primitives/asymmetric/ed25519.rst | 27 +++++++++++++++++++ docs/hazmat/primitives/asymmetric/ed448.rst | 27 +++++++++++++++++++ docs/hazmat/primitives/asymmetric/x25519.rst | 27 +++++++++++++++++++ docs/hazmat/primitives/asymmetric/x448.rst | 27 +++++++++++++++++++ .../hazmat/primitives/asymmetric/ed25519.py | 20 ++++++++++++++ .../hazmat/primitives/asymmetric/ed448.py | 20 ++++++++++++++ .../hazmat/primitives/asymmetric/x25519.py | 20 ++++++++++++++ .../hazmat/primitives/asymmetric/x448.py | 20 ++++++++++++++ tests/hazmat/primitives/test_ed25519.py | 14 ++++++++++ tests/hazmat/primitives/test_ed448.py | 3 +++ tests/hazmat/primitives/test_x25519.py | 3 +++ tests/hazmat/primitives/test_x448.py | 3 +++ 12 files changed, 211 insertions(+) diff --git a/docs/hazmat/primitives/asymmetric/ed25519.rst b/docs/hazmat/primitives/asymmetric/ed25519.rst index 17ebe2778945..1ca06fc1b9f2 100644 --- a/docs/hazmat/primitives/asymmetric/ed25519.rst +++ b/docs/hazmat/primitives/asymmetric/ed25519.rst @@ -103,6 +103,20 @@ Key interfaces :return bytes: Serialized key. + .. method:: private_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`private_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding, + :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw` + format, and + :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. + + :return bytes: Raw key. + .. class:: Ed25519PublicKey .. versionadded:: 2.6 @@ -163,6 +177,19 @@ Key interfaces :returns bytes: The public key bytes. + .. method:: public_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`public_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding and + :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw` + format. + + :return bytes: Raw key. + .. method:: verify(signature, data) :param bytes signature: The signature to verify. diff --git a/docs/hazmat/primitives/asymmetric/ed448.rst b/docs/hazmat/primitives/asymmetric/ed448.rst index d20fe73892cb..efe245d568e9 100644 --- a/docs/hazmat/primitives/asymmetric/ed448.rst +++ b/docs/hazmat/primitives/asymmetric/ed448.rst @@ -81,6 +81,20 @@ Key interfaces :return bytes: Serialized key. + .. method:: private_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`private_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding, + :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw` + format, and + :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. + + :return bytes: Raw key. + .. class:: Ed448PublicKey .. versionadded:: 2.6 @@ -117,6 +131,19 @@ Key interfaces :returns bytes: The public key bytes. + .. method:: public_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`public_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding and + :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw` + format. + + :return bytes: Raw key. + .. method:: verify(signature, data) :param bytes signature: The signature to verify. diff --git a/docs/hazmat/primitives/asymmetric/x25519.rst b/docs/hazmat/primitives/asymmetric/x25519.rst index 014f3d01d5d3..859e0a54aece 100644 --- a/docs/hazmat/primitives/asymmetric/x25519.rst +++ b/docs/hazmat/primitives/asymmetric/x25519.rst @@ -129,6 +129,20 @@ Key interfaces :return bytes: Serialized key. + .. method:: private_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`private_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding, + :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw` + format, and + :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. + + :return bytes: Raw key. + .. class:: X25519PublicKey .. versionadded:: 2.0 @@ -176,6 +190,19 @@ Key interfaces :returns bytes: The public key bytes. + .. method:: public_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`public_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding and + :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw` + format. + + :return bytes: Raw key. + .. _`Diffie-Hellman key exchange`: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange .. _`Curve25519`: https://en.wikipedia.org/wiki/Curve25519 diff --git a/docs/hazmat/primitives/asymmetric/x448.rst b/docs/hazmat/primitives/asymmetric/x448.rst index f166355b83fa..439c3b4ec8ec 100644 --- a/docs/hazmat/primitives/asymmetric/x448.rst +++ b/docs/hazmat/primitives/asymmetric/x448.rst @@ -123,6 +123,20 @@ Key interfaces :return bytes: Serialized key. + .. method:: private_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`private_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding, + :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw` + format, and + :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. + + :return bytes: Raw key. + .. class:: X448PublicKey .. versionadded:: 2.5 @@ -171,6 +185,19 @@ Key interfaces :returns bytes: The public key bytes. + .. method:: public_bytes_raw() + + .. versionadded:: 40 + + Allows serialization of the key to raw bytes. This method is a + convenience shortcut for calling :meth:`public_bytes` with + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw` + encoding and + :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw` + format. + + :return bytes: Raw key. + .. _`Diffie-Hellman key exchange`: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange .. _`Curve448`: https://en.wikipedia.org/wiki/Curve448 diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index 220bf592c0bb..df34159ec7e0 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -35,6 +35,15 @@ def public_bytes( The serialized bytes of the public key. """ + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + return self.public_bytes( + _serialization.Encoding.Raw, _serialization.PublicFormat.Raw + ) + @abc.abstractmethod def verify(self, signature: bytes, data: bytes) -> None: """ @@ -84,6 +93,17 @@ def private_bytes( The serialized bytes of the private key. """ + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + return self.private_bytes( + _serialization.Encoding.Raw, + _serialization.PrivateFormat.Raw, + _serialization.NoEncryption(), + ) + @abc.abstractmethod def sign(self, data: bytes) -> bytes: """ diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed448.py b/src/cryptography/hazmat/primitives/asymmetric/ed448.py index 27bc27c69f31..8b0ac1fd87a3 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -32,6 +32,15 @@ def public_bytes( The serialized bytes of the public key. """ + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + return self.public_bytes( + _serialization.Encoding.Raw, _serialization.PublicFormat.Raw + ) + @abc.abstractmethod def verify(self, signature: bytes, data: bytes) -> None: """ @@ -85,3 +94,14 @@ def private_bytes( """ The serialized bytes of the private key. """ + + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + return self.private_bytes( + _serialization.Encoding.Raw, + _serialization.PrivateFormat.Raw, + _serialization.NoEncryption(), + ) diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index d1347b883f37..eb964f465316 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -32,6 +32,15 @@ def public_bytes( The serialized bytes of the public key. """ + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + return self.public_bytes( + _serialization.Encoding.Raw, _serialization.PublicFormat.Raw + ) + class X25519PrivateKey(metaclass=abc.ABCMeta): @classmethod @@ -74,6 +83,17 @@ def private_bytes( The serialized bytes of the private key. """ + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + return self.private_bytes( + _serialization.Encoding.Raw, + _serialization.PrivateFormat.Raw, + _serialization.NoEncryption(), + ) + @abc.abstractmethod def exchange(self, peer_public_key: X25519PublicKey) -> bytes: """ diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index 284d4c801f99..dcab0445a4f7 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -32,6 +32,15 @@ def public_bytes( The serialized bytes of the public key. """ + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + return self.public_bytes( + _serialization.Encoding.Raw, _serialization.PublicFormat.Raw + ) + class X448PrivateKey(metaclass=abc.ABCMeta): @classmethod @@ -74,6 +83,17 @@ def private_bytes( The serialized bytes of the private key. """ + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + return self.private_bytes( + _serialization.Encoding.Raw, + _serialization.PrivateFormat.Raw, + _serialization.NoEncryption(), + ) + @abc.abstractmethod def exchange(self, peer_public_key: X448PublicKey) -> bytes: """ diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index f3b6ed853a9c..5833c5c327b9 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -92,6 +92,20 @@ def test_sign_verify_input(self, backend, subtests): ) public_key.verify(signature, message) + def test_pub_priv_bytes_raw(self, backend, subtests): + vectors = load_vectors_from_file( + os.path.join("asymmetric", "Ed25519", "sign.input"), + load_ed25519_vectors, + ) + for vector in vectors: + with subtests.test(): + sk = binascii.unhexlify(vector["secret_key"]) + pk = binascii.unhexlify(vector["public_key"]) + private_key = Ed25519PrivateKey.from_private_bytes(sk) + assert private_key.private_bytes_raw() == sk + public_key = Ed25519PublicKey.from_public_bytes(pk) + assert public_key.public_bytes_raw() == pk + def test_invalid_signature(self, backend): key = Ed25519PrivateKey.generate() signature = key.sign(b"test data") diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index cf96880104e9..ac915c79953c 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -108,12 +108,14 @@ def test_pub_priv_bytes_raw(self, vector, backend): ) == sk ) + assert private_key.private_bytes_raw() == sk assert ( private_key.public_key().public_bytes( serialization.Encoding.Raw, serialization.PublicFormat.Raw ) == pk ) + assert private_key.public_key().public_bytes_raw() == pk public_key = Ed448PublicKey.from_public_bytes(pk) assert ( public_key.public_bytes( @@ -121,6 +123,7 @@ def test_pub_priv_bytes_raw(self, vector, backend): ) == pk ) + assert public_key.public_bytes_raw() == pk @pytest.mark.parametrize( ("encoding", "fmt", "encryption", "passwd", "load_func"), diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index b7fd1e148a70..a0a5083f35e1 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -138,12 +138,14 @@ def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend): ) == private_bytes ) + assert private_key.private_bytes_raw() == private_bytes assert ( private_key.public_key().public_bytes( serialization.Encoding.Raw, serialization.PublicFormat.Raw ) == public_bytes ) + assert private_key.public_key().public_bytes_raw() == public_bytes public_key = X25519PublicKey.from_public_bytes(public_bytes) assert ( public_key.public_bytes( @@ -151,6 +153,7 @@ def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend): ) == public_bytes ) + assert public_key.public_bytes_raw() == public_bytes def test_generate(self, backend): key = X25519PrivateKey.generate() diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 3f461ede44a9..3e6506732b5f 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -116,12 +116,14 @@ def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend): ) == private_bytes ) + assert private_key.private_bytes_raw() == private_bytes assert ( private_key.public_key().public_bytes( serialization.Encoding.Raw, serialization.PublicFormat.Raw ) == public_bytes ) + assert private_key.public_key().public_bytes_raw() == public_bytes public_key = X448PublicKey.from_public_bytes(public_bytes) assert ( public_key.public_bytes( @@ -129,6 +131,7 @@ def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend): ) == public_bytes ) + assert public_key.public_bytes_raw() == public_bytes @pytest.mark.parametrize( ("encoding", "fmt", "encryption", "passwd", "load_func"), From a8ae36c9dcdeb4b634df4867ef92bccfc694fb8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:28:59 +0000 Subject: [PATCH 335/827] Bump types-pytz from 2022.7.1.1 to 2022.7.1.2 (#8379) Bumps [types-pytz](https://github.com/python/typeshed) from 2022.7.1.1 to 2022.7.1.2. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pytz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2566740fa903..b272dd055d6a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -208,7 +208,7 @@ tox==4.4.5; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -types-pytz==2022.7.1.1 +types-pytz==2022.7.1.2 # via cryptography (setup.cfg) types-requests==2.28.11.14 # via cryptography (setup.cfg) From 8222b40d8868f99d33313904d9a33146c286cbea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:29:47 +0000 Subject: [PATCH 336/827] Bump tox from 4.4.5 to 4.4.6 (#8380) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.5 to 4.4.6. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.5...4.4.6) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b272dd055d6a..19fed6a38bd9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -204,7 +204,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.5; python_version >= "3.7" +tox==4.4.6; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From 0023c4dc1bbe97810b9ca7ab354a9d9bc9031ac2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:30:34 +0000 Subject: [PATCH 337/827] Bump ruff from 0.0.249 to 0.0.251 (#8378) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.249 to 0.0.251. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.249...v0.0.251) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 19fed6a38bd9..07def4277c79 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.249 +ruff==0.0.251 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 8aa6e2e804ac0c705711e58dddf5dbd06d56e94d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:41:04 +0000 Subject: [PATCH 338/827] Bump markdown-it-py from 2.1.0 to 2.2.0 (#8381) Bumps [markdown-it-py](https://github.com/executablebooks/markdown-it-py) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/executablebooks/markdown-it-py/releases) - [Changelog](https://github.com/executablebooks/markdown-it-py/blob/master/CHANGELOG.md) - [Commits](https://github.com/executablebooks/markdown-it-py/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: markdown-it-py dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 07def4277c79..c9f955484205 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -72,7 +72,7 @@ jinja2==3.1.2 # via sphinx keyring==23.13.1 # via twine -markdown-it-py==2.1.0 +markdown-it-py==2.2.0 # via rich markupsafe==2.1.2 # via jinja2 From 94debb12c65e9d577be8ebb525f2a0e3e988c90c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 22 Feb 2023 09:08:33 -0500 Subject: [PATCH 339/827] fixes #8374 -- removed docs for removed method (#8377) * fixes #8374 -- removed docs for removed method * Update CHANGELOG.rst --- CHANGELOG.rst | 4 ++-- docs/hazmat/primitives/asymmetric/ec.rst | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a545cf5fac2a..d4348fc61655 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -866,7 +866,7 @@ Changelog with no arguments has been deprecated. * Added support for encoding compressed and uncompressed points via :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey.public_bytes`. Deprecated the previous method - :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers.encode_point`. + ``cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers.encode_point``. .. _v2-4-2: @@ -1565,7 +1565,7 @@ Changelog * Added a ``__hash__`` method to :class:`~cryptography.x509.Name`. * Add support for encoding and decoding elliptic curve points to a byte string form using - :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers.encode_point` + ``cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers.encode_point`` and :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers.from_encoded_point`. * Added :meth:`~cryptography.x509.Extensions.get_extension_for_class`. diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index dd95f223d27f..8da29eea142a 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -187,22 +187,6 @@ Elliptic Curve Signature Algorithms :raises ValueError: Raised if the point is invalid for the curve. :returns: A new instance of :class:`EllipticCurvePublicKey`. - .. method:: encode_point() - - .. warning:: - - This method is deprecated as of version 2.5. Callers should migrate - to using - :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey.public_bytes`. - - .. versionadded:: 1.1 - - Encodes an elliptic curve point to a byte string as described in - `SEC 1 v2.0`_ section 2.3.3. This method only supports uncompressed - points. - - :return bytes: The encoded point. - .. classmethod:: from_encoded_point(curve, data) .. versionadded:: 1.1 From 7483c9bd99df4d2b0d97a32c9401ae8d18cf9aef Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 00:18:22 +0000 Subject: [PATCH 340/827] Bump BoringSSL and/or OpenSSL in CI (#8382) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70823d78d01b..498a0547c4b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 22, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "bade46179ea3d729a434b92c2577be18d8a1cc4b"}} - # Latest commit on the OpenSSL master branch, as of Feb 22, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "0aa7d7f42bc757a0993739b6cfdc8819a70d22ef"}} + # Latest commit on the BoringSSL master branch, as of Feb 23, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "85a1e2e01c440953834fd739162bca8d25d0311c"}} + # Latest commit on the OpenSSL master branch, as of Feb 23, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ab5a172f1b41b12133b95822d5bf004c322965cb"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From de8deb9e944c06eefd140d640757ca5326d8143f Mon Sep 17 00:00:00 2001 From: Jake Date: Thu, 23 Feb 2023 23:03:47 +1100 Subject: [PATCH 341/827] Enforce max number of SSH certificate principals (#8376) * Enforce max number of SSH certificate principals There is an undocumented limit for the maximum number of valid principals accepted by the openssh tooling, as seen at: * https://github.com/openssh/openssh-portable/blob/27267642699342412964aa785b98afd69d952c88/sshkey.h#L108 * https://github.com/openssh/openssh-portable/blob/25c8a2bbcc10c493d27faea57c42a6bf13fa51f2/sshkey.c#L1801 * https://github.com/openssh/openssh-portable/blob/6180b0fa4f7996687678702806257e661fd5931e/ssh-keygen.c#L1833 This change enforces that same restriction as currently a SSH certificate can be generated that is invalid against the default sshd server. Consideration might be given for any non openssh servers that accept openssh certificates, if they exist and want to allow a greater number of principals. Of note, the 256 limit is not found in the spec for SSH certificates as defined at https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys. It instead seems to be arbitrarily chosen by the project as some limit was needed. * Address formatting error. * Comment on valid_prinicpals size limit plus test added. --------- Co-authored-by: Jake --- .../hazmat/primitives/serialization/ssh.py | 10 ++++++++++ tests/hazmat/primitives/test_ssh.py | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 2970ede1b7e3..c461acb9d2df 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -1052,6 +1052,11 @@ def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: ] +# This is an undocumented limit enforced in the openssh codebase for sshd and +# ssh-keygen, but it is undefined in the ssh certificates spec. +_SSHKEY_CERT_MAX_PRINCIPALS = 256 + + class SSHCertificateBuilder: def __init__( self, @@ -1182,6 +1187,11 @@ def valid_principals( if self._valid_principals: raise ValueError("valid_principals already set") + if len(valid_principals) > _SSHKEY_CERT_MAX_PRINCIPALS: + raise ValueError( + "Reached or exceeded the maximum number of valid_principals" + ) + return SSHCertificateBuilder( _public_key=self._public_key, _serial=self._serial, diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index 672e08e08141..c9f995b1f0c6 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -1389,6 +1389,10 @@ def test_valid_principals_errors(self): ) with pytest.raises(TypeError): builder.valid_principals([]) + with pytest.raises(ValueError): + builder.valid_principals( + [b"test"] * (ssh._SSHKEY_CERT_MAX_PRINCIPALS + 1) + ) builder = builder.valid_principals([b"test"]) with pytest.raises(ValueError): builder.valid_principals([b"test"]) From dc1945040fbe326aa576f993bcc474836a04a735 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:13:48 +0000 Subject: [PATCH 342/827] Bump syn from 1.0.107 to 1.0.108 in /src/rust (#8383) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.107 to 1.0.108. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.107...1.0.108) --- updated-dependencies: - dependency-name: syn dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 49d0efe837c2..cec7ca4cf855 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -489,9 +489,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "d56e159d99e6c2b93995d171050271edb50ecc5288fbc7cc17de8fdce4e58c14" dependencies = [ "proc-macro2", "quote", From 32e1e808c7c9be77ec82a7c790fcff0a6d65fcea Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:21:58 +0000 Subject: [PATCH 343/827] Bump BoringSSL and/or OpenSSL in CI (#8384) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 498a0547c4b4..4d239f34c586 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 23, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "85a1e2e01c440953834fd739162bca8d25d0311c"}} - # Latest commit on the OpenSSL master branch, as of Feb 23, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ab5a172f1b41b12133b95822d5bf004c322965cb"}} + # Latest commit on the BoringSSL master branch, as of Feb 24, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "6ab4f0ae7f2db96d240eb61a5a8b4724e5a09b2f"}} + # Latest commit on the OpenSSL master branch, as of Feb 24, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ee58915cfd9d0ad67f52d43cc1a2ce549049d248"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 8787f354ad76c7da9a4e83c6583e2025117e6870 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 12:26:19 +0000 Subject: [PATCH 344/827] Bump syn from 1.0.108 to 1.0.109 in /src/rust (#8385) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.108 to 1.0.109. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.108...1.0.109) --- updated-dependencies: - dependency-name: syn dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index cec7ca4cf855..0fa61330ed75 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -489,9 +489,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" -version = "1.0.108" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56e159d99e6c2b93995d171050271edb50ecc5288fbc7cc17de8fdce4e58c14" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", From 8bfec9d12eedf7e59f0fb31d3d050747731d9f14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:43:02 +0000 Subject: [PATCH 345/827] Bump ruff from 0.0.251 to 0.0.252 (#8386) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.251 to 0.0.252. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.251...v0.0.252) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c9f955484205..4e6fc1d8f203 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.251 +ruff==0.0.252 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 199dc75189bb3ec49fefe871596458026a10f9cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:23:49 +0000 Subject: [PATCH 346/827] Bump coverage from 7.1.0 to 7.2.0 (#8387) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.1.0 to 7.2.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.1.0...7.2.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4e6fc1d8f203..156e59204cd9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -33,7 +33,7 @@ click==8.1.3 # via black colorama==0.4.6; python_version >= "3.7" # via tox -coverage==7.1.0; python_version >= "3.7" +coverage==7.2.0; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 008e69d755b4a7adbbad212211a5967ccceb930c Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 25 Feb 2023 01:57:12 +0000 Subject: [PATCH 347/827] Bump BoringSSL and/or OpenSSL in CI (#8388) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d239f34c586..0cf2f4b839d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 24, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "6ab4f0ae7f2db96d240eb61a5a8b4724e5a09b2f"}} - # Latest commit on the OpenSSL master branch, as of Feb 24, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "ee58915cfd9d0ad67f52d43cc1a2ce549049d248"}} + # Latest commit on the BoringSSL master branch, as of Feb 25, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "b3c2c756aeec1c4309447f5247f61d435274da4a"}} + # Latest commit on the OpenSSL master branch, as of Feb 25, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9a2f78e14a67eeaadefc77d05f0778fc9684d26c"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From bc61b605c75e3e6d271b1b597e778fc335ba2e98 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 25 Feb 2023 21:09:35 -0500 Subject: [PATCH 348/827] fixes #8298 -- correctly generate content-type header in PKCS#7 SMIME (#8389) --- .../hazmat/primitives/serialization/pkcs7.py | 23 +++- src/rust/src/pkcs7.rs | 123 ++++++++++++------ tests/hazmat/primitives/test_pkcs7.py | 25 +++- 3 files changed, 120 insertions(+), 51 deletions(-) diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 7b8ab300fecb..593c9b159db3 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -5,6 +5,7 @@ import email.base64mime import email.generator import email.message +import email.policy import io import typing @@ -176,7 +177,9 @@ def sign( return rust_pkcs7.sign_and_serialize(self, encoding, options) -def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: +def _smime_encode( + data: bytes, signature: bytes, micalg: str, text_mode: bool +) -> bytes: # This function works pretty hard to replicate what OpenSSL does # precisely. For good and for ill. @@ -191,9 +194,10 @@ def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: m.preamble = "This is an S/MIME signed message\n" - msg_part = email.message.MIMEPart() + msg_part = OpenSSLMimePart() msg_part.set_payload(data) - msg_part.add_header("Content-Type", "text/plain") + if text_mode: + msg_part.add_header("Content-Type", "text/plain") m.attach(msg_part) sig_part = email.message.MIMEPart() @@ -212,7 +216,18 @@ def _smime_encode(data: bytes, signature: bytes, micalg: str) -> bytes: fp = io.BytesIO() g = email.generator.BytesGenerator( - fp, maxheaderlen=0, mangle_from_=False, policy=m.policy + fp, + maxheaderlen=0, + mangle_from_=False, + policy=m.policy.clone(linesep="\r\n"), ) g.flatten(m) return fp.getvalue() + + +class OpenSSLMimePart(email.message.MIMEPart): + # A MIMEPart subclass that replicates OpenSSL's behavior of not including + # a newline if there are no headers. + def _write_headers(self, generator) -> None: + if list(self.raw_items()): + generator._write_headers(self) diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index d760776564e3..48eb099325b0 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -135,14 +135,13 @@ fn sign_and_serialize<'p>( .getattr(crate::intern!(py, "PKCS7Options"))?; let raw_data = builder.getattr(crate::intern!(py, "_data"))?.extract()?; - let data = if options.contains(pkcs7_options.getattr(crate::intern!(py, "Binary"))?)? { - Cow::Borrowed(raw_data) - } else { - smime_canonicalize( - raw_data, - options.contains(pkcs7_options.getattr(crate::intern!(py, "Text"))?)?, - ) - }; + let text_mode = options.contains(pkcs7_options.getattr(crate::intern!(py, "Text"))?)?; + let (data_with_header, data_without_header) = + if options.contains(pkcs7_options.getattr(crate::intern!(py, "Binary"))?)? { + (Cow::Borrowed(raw_data), Cow::Borrowed(raw_data)) + } else { + smime_canonicalize(raw_data, text_mode) + }; let content_type_bytes = asn1::write_single(&PKCS7_DATA_OID)?; let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_chrono( @@ -179,7 +178,7 @@ fn sign_and_serialize<'p>( { ( None, - x509::sign::sign_data(py, py_private_key, py_hash_alg, &data)?, + x509::sign::sign_data(py, py_private_key, py_hash_alg, &data_with_header)?, ) } else { let mut authenticated_attrs = vec![]; @@ -197,7 +196,8 @@ fn sign_and_serialize<'p>( ])), }); - let digest = asn1::write_single(&x509::ocsp::hash_data(py, py_hash_alg, &data)?)?; + let digest = + asn1::write_single(&x509::ocsp::hash_data(py, py_hash_alg, &data_with_header)?)?; // Gross hack: copy to PyBytes to extend the lifetime to 'p let digest_bytes = pyo3::types::PyBytes::new(py, &digest); authenticated_attrs.push(x509::csr::Attribute { @@ -263,7 +263,7 @@ fn sign_and_serialize<'p>( if options.contains(pkcs7_options.getattr(crate::intern!(py, "DetachedSignature"))?)? { None } else { - data_tlv_bytes = asn1::write_single(&data.deref())?; + data_tlv_bytes = asn1::write_single(&data_with_header.deref())?; Some(asn1::parse_single(&data_tlv_bytes).unwrap()) }; @@ -289,7 +289,7 @@ fn sign_and_serialize<'p>( content_type: PKCS7_SIGNED_DATA_OID, content: Some(asn1::parse_single(&signed_data_bytes).unwrap()), }; - let content_info_bytes = asn1::write_single(&content_info)?; + let ci_bytes = asn1::write_single(&content_info)?; let encoding_class = py .import("cryptography.hazmat.primitives.serialization")? @@ -301,43 +301,49 @@ fn sign_and_serialize<'p>( .map(|d| OIDS_TO_MIC_NAME[&d.oid]) .collect::>() .join(","); - Ok(py + let smime_encode = py .import("cryptography.hazmat.primitives.serialization.pkcs7")? - .getattr(crate::intern!(py, "_smime_encode"))? - .call1(( - pyo3::types::PyBytes::new(py, &data), - pyo3::types::PyBytes::new(py, &content_info_bytes), - mic_algs, - ))? + .getattr(crate::intern!(py, "_smime_encode"))?; + Ok(smime_encode + .call1((&*data_without_header, &*ci_bytes, mic_algs, text_mode))? .extract()?) } else { // Handles the DER, PEM, and error cases - encode_der_data(py, "PKCS7".to_string(), content_info_bytes, encoding) + encode_der_data(py, "PKCS7".to_string(), ci_bytes, encoding) } } -fn smime_canonicalize(data: &[u8], text_mode: bool) -> Cow<'_, [u8]> { - let mut new_data = vec![]; +fn smime_canonicalize(data: &[u8], text_mode: bool) -> (Cow<'_, [u8]>, Cow<'_, [u8]>) { + let mut new_data_with_header = vec![]; + let mut new_data_without_header = vec![]; if text_mode { - new_data.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + new_data_with_header.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); } let mut last_idx = 0; for (i, c) in data.iter().copied().enumerate() { if c == b'\n' && (i == 0 || data[i - 1] != b'\r') { - new_data.extend_from_slice(&data[last_idx..i]); - new_data.push(b'\r'); - new_data.push(b'\n'); + new_data_with_header.extend_from_slice(&data[last_idx..i]); + new_data_with_header.push(b'\r'); + new_data_with_header.push(b'\n'); + + new_data_without_header.extend_from_slice(&data[last_idx..i]); + new_data_without_header.push(b'\r'); + new_data_without_header.push(b'\n'); last_idx = i + 1; } } // If there's stuff in new_data, that means we need to copy the rest of // data over. - if !new_data.is_empty() { - new_data.extend_from_slice(&data[last_idx..]); - Cow::Owned(new_data) + if !new_data_with_header.is_empty() { + new_data_with_header.extend_from_slice(&data[last_idx..]); + new_data_without_header.extend_from_slice(&data[last_idx..]); + ( + Cow::Owned(new_data_with_header), + Cow::Owned(new_data_without_header), + ) } else { - Cow::Borrowed(data) + (Cow::Borrowed(data), Cow::Borrowed(data)) } } @@ -358,27 +364,60 @@ mod tests { #[test] fn test_smime_canonicalize() { - for (input, text_mode, expected, expected_is_borrowed) in [ + for ( + input, + text_mode, + expected_with_header, + expected_without_header, + expected_is_borrowed, + ) in [ // Values with text_mode=false - (b"" as &[u8], false, b"" as &[u8], true), - (b"\n", false, b"\r\n", false), - (b"abc", false, b"abc", true), - (b"abc\r\ndef\n", false, b"abc\r\ndef\r\n", false), - (b"abc\r\n", false, b"abc\r\n", true), - (b"abc\ndef\n", false, b"abc\r\ndef\r\n", false), + (b"" as &[u8], false, b"" as &[u8], b"" as &[u8], true), + (b"\n", false, b"\r\n", b"\r\n", false), + (b"abc", false, b"abc", b"abc", true), + ( + b"abc\r\ndef\n", + false, + b"abc\r\ndef\r\n", + b"abc\r\ndef\r\n", + false, + ), + (b"abc\r\n", false, b"abc\r\n", b"abc\r\n", true), + ( + b"abc\ndef\n", + false, + b"abc\r\ndef\r\n", + b"abc\r\ndef\r\n", + false, + ), // Values with text_mode=true - (b"", true, b"Content-Type: text/plain\r\n\r\n", false), - (b"abc", true, b"Content-Type: text/plain\r\n\r\nabc", false), + (b"", true, b"Content-Type: text/plain\r\n\r\n", b"", false), + ( + b"abc", + true, + b"Content-Type: text/plain\r\n\r\nabc", + b"abc", + false, + ), ( b"abc\n", true, b"Content-Type: text/plain\r\n\r\nabc\r\n", + b"abc\r\n", false, ), ] { - let result = smime_canonicalize(input, text_mode); - assert_eq!(result.deref(), expected); - assert_eq!(matches!(result, Cow::Borrowed(_)), expected_is_borrowed); + let (result_with_header, result_without_header) = smime_canonicalize(input, text_mode); + assert_eq!(result_with_header.deref(), expected_with_header); + assert_eq!(result_without_header.deref(), expected_without_header); + assert_eq!( + matches!(result_with_header, Cow::Borrowed(_)), + expected_is_borrowed + ); + assert_eq!( + matches!(result_without_header, Cow::Borrowed(_)), + expected_is_borrowed + ); } } } diff --git a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py index ebb8dc0a9baa..d879563e17d9 100644 --- a/tests/hazmat/primitives/test_pkcs7.py +++ b/tests/hazmat/primitives/test_pkcs7.py @@ -3,6 +3,7 @@ # for complete details. +import email.parser import os import typing @@ -289,6 +290,7 @@ def test_smime_sign_detached(self, backend): sig = builder.sign(serialization.Encoding.SMIME, options) sig_binary = builder.sign(serialization.Encoding.DER, options) + assert b"text/plain" not in sig # We don't have a generic ASN.1 parser available to us so we instead # will assert on specific byte sequences being present based on the # parameters chosen above. @@ -298,8 +300,17 @@ def test_smime_sign_detached(self, backend): # as a separate section before the PKCS7 data. So we should expect to # have data in sig but not in sig_binary assert data in sig + # Parse the message to get the signed data, which is the + # first payload in the message + message = email.parser.BytesParser().parsebytes(sig) + signed_data = message.get_payload()[0].get_payload().encode() _pkcs7_verify( - serialization.Encoding.SMIME, sig, data, [cert], options, backend + serialization.Encoding.SMIME, + sig, + signed_data, + [cert], + options, + backend, ) assert data not in sig_binary _pkcs7_verify( @@ -492,10 +503,14 @@ def test_sign_text(self, backend): # The text option adds text/plain headers to the S/MIME message # These headers are only relevant in SMIME mode, not binary, which is # just the PKCS7 structure itself. - assert b"text/plain" in sig_pem - # When passing the Text option the header is prepended so the actual - # signed data is this. - signed_data = b"Content-Type: text/plain\r\n\r\nhello world" + assert sig_pem.count(b"text/plain") == 1 + assert b"Content-Type: text/plain\r\n\r\nhello world\r\n" in sig_pem + # Parse the message to get the signed data, which is the + # first payload in the message + message = email.parser.BytesParser().parsebytes(sig_pem) + signed_data = message.get_payload()[0].as_bytes( + policy=message.policy.clone(linesep="\r\n") + ) _pkcs7_verify( serialization.Encoding.SMIME, sig_pem, From 384fdc4225b082b86de092a3c124d06f6d990723 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 26 Feb 2023 16:12:31 -0500 Subject: [PATCH 349/827] remove several unused SSL bindings (#8391) --- src/_cffi_src/openssl/ssl.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index a3b65a482c00..febe353636f3 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -325,7 +325,6 @@ long SSL_CTX_get_mode(SSL_CTX *); long SSL_set_mode(SSL *, long); long SSL_clear_mode(SSL *, long); -long SSL_get_mode(SSL *); const SSL_METHOD *DTLS_method(void); const SSL_METHOD *DTLS_server_method(void); @@ -363,10 +362,6 @@ int SSL_set_tlsext_use_srtp(SSL *, const char *); SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *); -int SSL_select_next_proto(unsigned char **, unsigned char *, - const unsigned char *, unsigned int, - const unsigned char *, unsigned int); - int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char *, unsigned); int SSL_set_alpn_protos(SSL *, const unsigned char *, unsigned); void SSL_CTX_set_alpn_select_cb(SSL_CTX *, @@ -379,8 +374,6 @@ void *); void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *); -long SSL_get_server_tmp_key(SSL *, EVP_PKEY **); - void SSL_CTX_set_cert_cb(SSL_CTX *, int (*)(SSL *, void *), void *); void SSL_set_cert_cb(SSL *, int (*)(SSL *, void *), void *); From 1937b4bb33ed376fd0f4c275322b8c5e50cae2cf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 27 Feb 2023 06:27:48 +0800 Subject: [PATCH 350/827] improve the custom build script slightly (#8392) this will make it more robust to some upcoming pip changes --- docs/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.rst b/docs/installation.rst index c3d867d666f8..385b904444c2 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -227,7 +227,7 @@ dependencies. ./config no-shared no-ssl2 no-ssl3 -fPIC --prefix=${CWD}/openssl make && make install cd .. - CFLAGS="-I${CWD}/openssl/include" LDFLAGS="-L${CWD}/openssl/lib" pip wheel --no-binary :all: cryptography + CFLAGS="-I${CWD}/openssl/include" LDFLAGS="-L${CWD}/openssl/lib" pip wheel --no-cache-dir --no-binary cryptography cryptography Building cryptography on macOS ------------------------------ From 64305f6d652e9b444711e79f13023ca853c1aceb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Feb 2023 23:16:56 +0000 Subject: [PATCH 351/827] Bump types-requests from 2.28.11.14 to 2.28.11.15 (#8393) Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.14 to 2.28.11.15. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 156e59204cd9..06450575459c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -210,7 +210,7 @@ twine==4.0.2 # via cryptography (setup.cfg) types-pytz==2022.7.1.2 # via cryptography (setup.cfg) -types-requests==2.28.11.14 +types-requests==2.28.11.15 # via cryptography (setup.cfg) types-urllib3==1.26.25.7 # via types-requests From 981cf35fae05f8e6481ea7720fc8e7a3c81e72ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Feb 2023 23:29:46 +0000 Subject: [PATCH 352/827] Bump coverage from 7.2.0 to 7.2.1 (#8395) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.0 to 7.2.1. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.0...7.2.1) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 06450575459c..79f0e6b27c4d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -33,7 +33,7 @@ click==8.1.3 # via black colorama==0.4.6; python_version >= "3.7" # via tox -coverage==7.2.0; python_version >= "3.7" +coverage==7.2.1; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 698940470246603327bcea13dbadb5b1b70be393 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Feb 2023 23:30:02 +0000 Subject: [PATCH 353/827] Bump zipp from 3.14.0 to 3.15.0 (#8396) Bumps [zipp](https://github.com/jaraco/zipp) from 3.14.0 to 3.15.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.14.0...v3.15.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 79f0e6b27c4d..a1c7efb83579 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -224,7 +224,7 @@ virtualenv==20.19.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach -zipp==3.14.0; python_version >= "3.7" +zipp==3.15.0; python_version >= "3.7" # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From 9ac28cb972ff8836d5b0eabec54e697479ed673f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Feb 2023 18:50:17 -0500 Subject: [PATCH 354/827] Bump types-urllib3 from 1.26.25.7 to 1.26.25.8 (#8394) Bumps [types-urllib3](https://github.com/python/typeshed) from 1.26.25.7 to 1.26.25.8. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a1c7efb83579..9d8c21978ed9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -212,7 +212,7 @@ types-pytz==2022.7.1.2 # via cryptography (setup.cfg) types-requests==2.28.11.15 # via cryptography (setup.cfg) -types-urllib3==1.26.25.7 +types-urllib3==1.26.25.8 # via types-requests typing-extensions==4.5.0; python_version >= "3.7" # via mypy From 280b42efb6ea5a6dcc9ea8f35168082403451673 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 27 Feb 2023 07:52:12 +0800 Subject: [PATCH 355/827] raise UnsupportedAlgorithm instead of ValueError in x509 builder sign (#8397) Also change the typing to be an explicit union --- CHANGELOG.rst | 2 ++ src/cryptography/x509/base.py | 19 ++++++++++++++++--- src/rust/src/x509/sign.rs | 21 ++++++++++++++------- tests/x509/test_ocsp.py | 3 ++- tests/x509/test_x509.py | 10 ++++++---- tests/x509/test_x509_crlbuilder.py | 13 +++++++++---- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d4348fc61655..0d89f62263a0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -38,6 +38,8 @@ Changelog you are using ``cryptography`` to directly invoke OpenSSL's C API. Note that these have never been considered a stable, supported, public API by ``cryptography``, this note is included as a courtesy. +* The X.509 builder classes now raise ``UnsupportedAlgorithm`` instead of + ``ValueError`` if an unsupported hash algorithm is passed. .. _v39-0-1: diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 29275b68fb39..de1323529d2e 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -36,6 +36,19 @@ _EARLIEST_UTC_TIME = datetime.datetime(1950, 1, 1) +# This must be kept in sync with sign.rs's list of allowable types in +# identify_hash_type +_AllowedHashTypes = typing.Union[ + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + hashes.SHA3_224, + hashes.SHA3_256, + hashes.SHA3_384, + hashes.SHA3_512, +] + class AttributeNotFound(Exception): def __init__(self, msg: str, oid: ObjectIdentifier) -> None: @@ -679,7 +692,7 @@ def add_attribute( def sign( self, private_key: CERTIFICATE_PRIVATE_KEY_TYPES, - algorithm: typing.Optional[hashes.HashAlgorithm], + algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> CertificateSigningRequest: """ @@ -900,7 +913,7 @@ def add_extension( def sign( self, private_key: CERTIFICATE_PRIVATE_KEY_TYPES, - algorithm: typing.Optional[hashes.HashAlgorithm], + algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> Certificate: """ @@ -1047,7 +1060,7 @@ def add_revoked_certificate( def sign( self, private_key: CERTIFICATE_PRIVATE_KEY_TYPES, - algorithm: typing.Optional[hashes.HashAlgorithm], + algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> CertificateRevocationList: if self._issuer_name is None: diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index e1d35265fe5d..3a1e0e9a3def 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -106,10 +106,15 @@ fn identify_hash_type( "sha3-256" => Ok(HashType::Sha3_256), "sha3-384" => Ok(HashType::Sha3_384), "sha3-512" => Ok(HashType::Sha3_512), - name => Err(pyo3::exceptions::PyValueError::new_err(format!( - "Hash algorithm {:?} not supported for signatures", - name - ))), + name => Err(pyo3::PyErr::from_instance( + py.import("cryptography.exceptions")?.call_method1( + "UnsupportedAlgorithm", + (format!( + "Hash algorithm {:?} not supported for signatures", + name + ),), + )?, + )), } } @@ -221,10 +226,12 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Dsa, HashType::Sha3_224) | (KeyType::Dsa, HashType::Sha3_256) | (KeyType::Dsa, HashType::Sha3_384) - | (KeyType::Dsa, HashType::Sha3_512) => Err(pyo3::exceptions::PyValueError::new_err( - "SHA3 hashes are not supported with DSA keys", + | (KeyType::Dsa, HashType::Sha3_512) => Err(pyo3::PyErr::from_instance( + py.import("cryptography.exceptions")?.call_method1( + "UnsupportedAlgorithm", + ("SHA3 hashes are not supported with DSA keys",), + )?, )), - (_, HashType::None) => Err(pyo3::exceptions::PyTypeError::new_err( "Algorithm must be a registered hash algorithm, not None.", )), diff --git a/tests/x509/test_ocsp.py b/tests/x509/test_ocsp.py index bd9204865867..0b0bc861acff 100644 --- a/tests/x509/test_ocsp.py +++ b/tests/x509/test_ocsp.py @@ -10,6 +10,7 @@ import pytest from cryptography import x509 +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec, ed448, ed25519, rsa from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15 @@ -917,7 +918,7 @@ def test_sign_unrecognized_hash_algorithm(self, backend): None, ) - with pytest.raises(ValueError): + with pytest.raises(UnsupportedAlgorithm): builder.sign(private_key, hashes.BLAKE2b(digest_size=64)) def test_sign_none_hash_not_eddsa(self): diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 821f1fe87e80..36da4585a122 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -14,7 +14,7 @@ import pytz from cryptography import utils, x509 -from cryptography.exceptions import InvalidSignature +from cryptography.exceptions import InvalidSignature, UnsupportedAlgorithm from cryptography.hazmat.bindings._rust import asn1 from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ( @@ -2853,7 +2853,7 @@ def test_sign_dsa_with_unsupported_hash(self, hash_algorithm, backend): .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1)) .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1)) ) - with pytest.raises(ValueError): + with pytest.raises(UnsupportedAlgorithm): builder.sign(private_key, hash_algorithm, backend) @pytest.mark.supported( @@ -2876,8 +2876,10 @@ def test_sign_ec_with_md5(self, backend): .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1)) .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1)) ) - with pytest.raises(ValueError): - builder.sign(private_key, hashes.MD5(), backend) + with pytest.raises(UnsupportedAlgorithm): + builder.sign( + private_key, hashes.MD5(), backend # type: ignore[arg-type] + ) @pytest.mark.supported( only_if=lambda backend: backend.dsa_supported(), diff --git a/tests/x509/test_x509_crlbuilder.py b/tests/x509/test_x509_crlbuilder.py index 9af98e40b262..ef0f18392b9d 100644 --- a/tests/x509/test_x509_crlbuilder.py +++ b/tests/x509/test_x509_crlbuilder.py @@ -9,6 +9,7 @@ import pytz from cryptography import x509 +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec, ed448, ed25519 from cryptography.x509.oid import ( @@ -732,8 +733,10 @@ def test_dsa_key_sign_md5(self, backend): .next_update(next_time) ) - with pytest.raises(ValueError): - builder.sign(private_key, hashes.MD5(), backend) + with pytest.raises(UnsupportedAlgorithm): + builder.sign( + private_key, hashes.MD5(), backend # type: ignore[arg-type] + ) def test_ec_key_sign_md5(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) @@ -755,8 +758,10 @@ def test_ec_key_sign_md5(self, backend): .next_update(next_time) ) - with pytest.raises(ValueError): - builder.sign(private_key, hashes.MD5(), backend) + with pytest.raises(UnsupportedAlgorithm): + builder.sign( + private_key, hashes.MD5(), backend # type: ignore[arg-type] + ) def test_sign_with_revoked_certificates(self, backend): private_key = RSA_KEY_2048.private_key(backend) From 06e6fa21724082fe6fa6401029fc5b2c0e599339 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 27 Feb 2023 09:04:49 +0800 Subject: [PATCH 356/827] handle timezones for our mtime fixer (#8398) * handle timezones for our mtime fixer avoids setting mtime into the future, which messes up the cache * add paranoia --- .github/actions/mtime-fix/action.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/actions/mtime-fix/action.yml b/.github/actions/mtime-fix/action.yml index ac6ae9157c5a..b7ab3b9b5c37 100644 --- a/.github/actions/mtime-fix/action.yml +++ b/.github/actions/mtime-fix/action.yml @@ -6,9 +6,21 @@ runs: steps: - run: | + GIT_WORKS=$(git rev-parse --is-inside-work-tree 2>/dev/null || true) + if [ "$GIT_WORKS" != "true" ]; then + echo "The git available is probably too old so checkout didn't create a real git clone, skipping mtime fix" + exit 0 + fi ls -Rla src/rust/src + echo "Verifying commits are monotonic because if they're not caching gets wrecked" + COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5) + SORTED_COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5 | sort -rn) + if [ "$COMMIT_ORDER" != "$SORTED_COMMIT_ORDER" ]; then + echo "Commits are not monotonic, git may have changed how date formatting works" + exit 1 + fi echo "Setting mtimes for rust dirs" - for f in $(git ls-files src/rust); do touch -t $(git log --pretty=format:%cd --date=format:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done + for f in $(git ls-files src/rust); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done echo "Done" ls -Rla src/rust/src shell: bash From 3ee1290221f69723ef64e8ea6cf2303656ce1256 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 00:23:28 +0000 Subject: [PATCH 357/827] Bump BoringSSL and/or OpenSSL in CI (#8402) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0cf2f4b839d1..269a87ea5775 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 25, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "b3c2c756aeec1c4309447f5247f61d435274da4a"}} - # Latest commit on the OpenSSL master branch, as of Feb 25, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9a2f78e14a67eeaadefc77d05f0778fc9684d26c"}} + # Latest commit on the BoringSSL master branch, as of Feb 28, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f88b7c83979d128fa83eb5f9102be56cc4bec33c"}} + # Latest commit on the OpenSSL master branch, as of Feb 28, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "359d6a26d64c32e7c2bebf5655c70c074f6c805b"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 4a2f994475f9afdfcefdcaa573dd704f445fbe8e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 27 Feb 2023 22:24:02 -0500 Subject: [PATCH 358/827] remove unused bignum bindings (#8401) --- src/_cffi_src/openssl/bignum.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/_cffi_src/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py index 052c7ed94cda..1e9f81128271 100644 --- a/src/_cffi_src/openssl/bignum.py +++ b/src/_cffi_src/openssl/bignum.py @@ -42,8 +42,6 @@ int BN_set_word(BIGNUM *, BN_ULONG); -const BIGNUM *BN_value_one(void); - char *BN_bn2hex(const BIGNUM *); int BN_hex2bn(BIGNUM **, const char *); @@ -52,20 +50,8 @@ int BN_num_bits(const BIGNUM *); -int BN_cmp(const BIGNUM *, const BIGNUM *); int BN_is_negative(const BIGNUM *); int BN_is_odd(const BIGNUM *); -int BN_add(BIGNUM *, const BIGNUM *, const BIGNUM *); -int BN_sub(BIGNUM *, const BIGNUM *, const BIGNUM *); -int BN_nnmod(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -int BN_mod_add(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, - BN_CTX *); -int BN_mod_sub(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, - BN_CTX *); -int BN_mod_mul(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, - BN_CTX *); -int BN_mod_exp(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, - BN_CTX *); int BN_mod_exp_mont(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *); int BN_mod_exp_mont_consttime(BIGNUM *, const BIGNUM *, const BIGNUM *, From d05a8ac6cd2905fc5375f8ae49172286cb1f2625 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 28 Feb 2023 00:07:54 -0500 Subject: [PATCH 359/827] Update to the new wycheproof (#8403) --- docs/development/test-vectors.rst | 2 +- .../hazmat/backends/openssl/utils.py | 5 ++++- tests/wycheproof/test_ecdh.py | 21 ++++++++++++++++++- tests/wycheproof/test_ecdsa.py | 5 +++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index b8a703f90786..72fdf7fabac1 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -22,7 +22,7 @@ for various cryptographic algorithms. These are not included in the repository continuous integration environments. We have ensured all test vectors are used as of commit -``2196000605e45d91097147c9c71f26b72af58003``. +``b063b4aedae951c69df014cd25fa6d69ae9e8cb9``. Asymmetric ciphers ~~~~~~~~~~~~~~~~~~ diff --git a/src/cryptography/hazmat/backends/openssl/utils.py b/src/cryptography/hazmat/backends/openssl/utils.py index 3a70a5818474..0a4c29595f02 100644 --- a/src/cryptography/hazmat/backends/openssl/utils.py +++ b/src/cryptography/hazmat/backends/openssl/utils.py @@ -18,7 +18,10 @@ def _evp_pkey_derive(backend: "Backend", evp_pkey, peer_public_key) -> bytes: res = backend._lib.EVP_PKEY_derive_init(ctx) backend.openssl_assert(res == 1) res = backend._lib.EVP_PKEY_derive_set_peer(ctx, peer_public_key._evp_pkey) - backend.openssl_assert(res == 1) + if res != 1: + errors_with_text = backend._consume_errors_with_text() + raise ValueError("Error computing shared key.", errors_with_text) + keylen = backend._ffi.new("size_t *") res = backend._lib.EVP_PKEY_derive(ctx, backend._ffi.NULL, keylen) backend.openssl_assert(res == 1) diff --git a/tests/wycheproof/test_ecdh.py b/tests/wycheproof/test_ecdh.py index 1de26cb263bd..9fecdef9ea4e 100644 --- a/tests/wycheproof/test_ecdh.py +++ b/tests/wycheproof/test_ecdh.py @@ -21,6 +21,12 @@ "secp521r1": ec.SECP521R1(), "secp224k1": None, "secp256k1": ec.SECP256K1(), + "sect283r1": ec.SECT283R1(), + "sect409r1": ec.SECT409R1(), + "sect571r1": ec.SECT571R1(), + "sect283k1": ec.SECT283K1(), + "sect409k1": ec.SECT409K1(), + "sect571k1": ec.SECT571K1(), "brainpoolP224r1": None, "brainpoolP256r1": ec.BrainpoolP256R1(), "brainpoolP320r1": None, @@ -31,6 +37,7 @@ "brainpoolP320t1": None, "brainpoolP384t1": None, "brainpoolP512t1": None, + "FRP256v1": None, } @@ -46,6 +53,12 @@ "ecdh_secp256r1_test.json", "ecdh_secp384r1_test.json", "ecdh_secp521r1_test.json", + "ecdh_sect283k1_test.json", + "ecdh_sect283r1_test.json", + "ecdh_sect409k1_test.json", + "ecdh_sect409r1_test.json", + "ecdh_sect571k1_test.json", + "ecdh_sect571r1_test.json", ) def test_ecdh(backend, wycheproof): curve = _CURVES[wycheproof.testgroup["curve"]] @@ -70,7 +83,13 @@ def test_ecdh(backend, wycheproof): except UnsupportedAlgorithm: return - if wycheproof.valid or wycheproof.acceptable: + if wycheproof.valid or ( + wycheproof.acceptable + and not ( + wycheproof.has_flag("LowOrderPublic") + and backend._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER + ) + ): computed_shared = private_key.exchange(ec.ECDH(), public_key) expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) assert computed_shared == expected_shared diff --git a/tests/wycheproof/test_ecdsa.py b/tests/wycheproof/test_ecdsa.py index e2c752dce6e1..c958c8397f19 100644 --- a/tests/wycheproof/test_ecdsa.py +++ b/tests/wycheproof/test_ecdsa.py @@ -53,6 +53,11 @@ "ecdsa_secp384r1_sha3_512_test.json", "ecdsa_secp521r1_sha512_test.json", "ecdsa_secp521r1_sha3_512_test.json", + "ecdsa_secp160k1_sha256_test.json", + "ecdsa_secp160r1_sha256_test.json", + "ecdsa_secp160r2_sha256_test.json", + "ecdsa_secp192k1_sha256_test.json", + "ecdsa_secp192r1_sha256_test.json", ) def test_ecdsa_signature(backend, wycheproof): try: From 00e3ab2cb223990b22446884b331c3c1025ee2de Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 28 Feb 2023 19:48:46 +0800 Subject: [PATCH 360/827] don't cache some things, output info about the cache size on hit (#8405) * don't cache some things, output info about the cache size on hit * empty commit to test cache --- .github/actions/cache/action.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index e45b1a89ae43..1f34e3317adb 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -37,8 +37,13 @@ runs: ${{ steps.pip-cache.outputs.dir }} ~/.cargo/registry/index/ ~/.cargo/registry/cache/ - ~/.cargo/registry/src/ - ~/.cargo/git/db/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-1-${{ hashFiles('**/Cargo.lock') }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-2-${{ hashFiles('**/Cargo.lock') }} + - name: Size of cache items + run: | + du -sh ~/.cargo/registry/index/ + du -sh ~/.cargo/registry/cache/ + du -sh src/rust/target/ + shell: bash + if: ${{ steps.cache.outputs.cache-hit }} \ No newline at end of file From b9caee556706f13fae41c73039bc670defa496c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 08:21:39 -0500 Subject: [PATCH 361/827] Bump babel from 2.11.0 to 2.12.0 (#8407) Bumps [babel](https://github.com/python-babel/babel) from 2.11.0 to 2.12.0. - [Release notes](https://github.com/python-babel/babel/releases) - [Changelog](https://github.com/python-babel/babel/blob/master/CHANGES.rst) - [Commits](https://github.com/python-babel/babel/compare/v2.11.0...v2.12.0) --- updated-dependencies: - dependency-name: babel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9d8c21978ed9..cb84ca9ee326 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -11,7 +11,7 @@ attrs==22.2.0 # via # hypothesis # pytest -babel==2.11.0 +babel==2.12.0 # via sphinx black==23.1.0 # via cryptography (setup.cfg) From 29d1eca149e6880a38ccaae15a8aa1246e316dc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:24:16 +0000 Subject: [PATCH 362/827] Bump ruff from 0.0.252 to 0.0.253 (#8408) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.252 to 0.0.253. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.252...v0.0.253) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index cb84ca9ee326..f2c221af2d02 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.252 +ruff==0.0.253 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 3dad3f5e41253b5065a53579587d57b79a20c88b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:29:04 +0000 Subject: [PATCH 363/827] Bump more-itertools from 9.0.0 to 9.1.0 (#8409) Bumps [more-itertools](https://github.com/more-itertools/more-itertools) from 9.0.0 to 9.1.0. - [Release notes](https://github.com/more-itertools/more-itertools/releases) - [Commits](https://github.com/more-itertools/more-itertools/compare/v9.0.0...v9.1.0) --- updated-dependencies: - dependency-name: more-itertools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f2c221af2d02..1dea36834bc4 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -78,7 +78,7 @@ markupsafe==2.1.2 # via jinja2 mdurl==0.1.2 # via markdown-it-py -more-itertools==9.0.0 +more-itertools==9.1.0 # via jaraco-classes mypy==1.0.1 # via cryptography (setup.cfg) From ca58d215e4c1ac17db4bc393211620790cf51a24 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 28 Feb 2023 15:17:37 -0500 Subject: [PATCH 364/827] Get dependabot updating reusable actions (#8406) Required until https://github.com/dependabot/dependabot-core/issues/6704 is fixed --- .github/dependabot.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c6cd0aa8c132..273a64e735bc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,22 @@ updates: interval: "daily" open-pull-requests-limit: 1024 + - package-ecosystem: "github-actions" + directory: "/.github/actions/cache/" + schedule: + interval: "daily" + open-pull-requests-limit: 1024 + - package-ecosystem: "github-actions" + directory: "/.github/actions/upload-coverage/" + schedule: + interval: "daily" + open-pull-requests-limit: 1024 + - package-ecosystem: "github-actions" + directory: "/.github/actions/wycheproof/" + schedule: + interval: "daily" + open-pull-requests-limit: 1024 + - package-ecosystem: cargo directory: "/src/rust/" schedule: From 24350e47a9153d9ab83d7393930281e7b02c3644 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:38:54 +0000 Subject: [PATCH 365/827] Bump actions/cache from 3.2.5 to 3.2.6 in /.github/actions/cache (#8410) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.5 to 3.2.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.5...v3.2.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/cache/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 1f34e3317adb..058e864ff60e 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -30,7 +30,7 @@ runs: echo "dir=$(python -m pip cache dir)" >> $GITHUB_OUTPUT fi shell: bash - - uses: actions/cache@v3.2.5 + - uses: actions/cache@v3.2.6 id: cache with: path: | From b2fa3cdced667613c90a7de9186f0355e739c9d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:46:14 +0000 Subject: [PATCH 366/827] Bump virtualenv from 20.19.0 to 20.20.0 (#8412) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.19.0 to 20.20.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.19.0...20.20.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1dea36834bc4..d2b5f8b03bed 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -220,7 +220,7 @@ urllib3==1.26.14 # via # requests # twine -virtualenv==20.19.0; python_version >= "3.7" +virtualenv==20.20.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach From eb0feea40131a5e6a6a2132487acf1eca77f51ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:50:10 +0000 Subject: [PATCH 367/827] Bump babel from 2.12.0 to 2.12.1 (#8413) Bumps [babel](https://github.com/python-babel/babel) from 2.12.0 to 2.12.1. - [Release notes](https://github.com/python-babel/babel/releases) - [Changelog](https://github.com/python-babel/babel/blob/master/CHANGES.rst) - [Commits](https://github.com/python-babel/babel/compare/v2.12.0...v2.12.1) --- updated-dependencies: - dependency-name: babel dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d2b5f8b03bed..08c562300147 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -11,7 +11,7 @@ attrs==22.2.0 # via # hypothesis # pytest -babel==2.12.0 +babel==2.12.1 # via sphinx black==23.1.0 # via cryptography (setup.cfg) From a434b7b19dd68202a4352501f4af418a58780403 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 21:02:55 +0000 Subject: [PATCH 368/827] Bump actions/upload-artifact in /.github/actions/upload-coverage (#8411) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3.1.0...v3.1.2) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/upload-coverage/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/upload-coverage/action.yml b/.github/actions/upload-coverage/action.yml index 98e88bee40ae..8fa9cca4e630 100644 --- a/.github/actions/upload-coverage/action.yml +++ b/.github/actions/upload-coverage/action.yml @@ -13,7 +13,7 @@ runs: fi id: coverage-uuid shell: bash - - uses: actions/upload-artifact@v3.1.0 + - uses: actions/upload-artifact@v3.1.2 with: name: coverage-data path: | From ad31d49cbd2055dedaae4dc2817ef5b8e01b5051 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 1 Mar 2023 01:01:17 +0000 Subject: [PATCH 369/827] Bump BoringSSL and/or OpenSSL in CI (#8415) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 269a87ea5775..eedd0ae15441 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Feb 28, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "f88b7c83979d128fa83eb5f9102be56cc4bec33c"}} - # Latest commit on the OpenSSL master branch, as of Feb 28, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "359d6a26d64c32e7c2bebf5655c70c074f6c805b"}} + # Latest commit on the BoringSSL master branch, as of Mar 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "028bae7ddc67b6061d80c17b0be4e2f60d94731b"}} + # Latest commit on the OpenSSL master branch, as of Mar 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3307338e26862070eaacad6ec7537a63a63b8a90"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 4f48485fdc250ba9428783b51b16006baf07e06d Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 00:38:11 +0000 Subject: [PATCH 370/827] Bump BoringSSL and/or OpenSSL in CI (#8418) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eedd0ae15441..fd10b25f4b5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "028bae7ddc67b6061d80c17b0be4e2f60d94731b"}} - # Latest commit on the OpenSSL master branch, as of Mar 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3307338e26862070eaacad6ec7537a63a63b8a90"}} + # Latest commit on the BoringSSL master branch, as of Mar 02, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "76cb7c5eb726e7637ed4c627ac27dacbd6250584"}} + # Latest commit on the OpenSSL master branch, as of Mar 02, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d0a3b9d1eb1fc510ec3447b44803bbf5520a0c47"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 43c4b6320638062d4000162f63e8f03d90a1bfe6 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 3 Mar 2023 05:17:31 +0800 Subject: [PATCH 371/827] port 39.0.2 changelog to main (#8422) --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0d89f62263a0..d20f3ab335e7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -41,6 +41,15 @@ Changelog * The X.509 builder classes now raise ``UnsupportedAlgorithm`` instead of ``ValueError`` if an unsupported hash algorithm is passed. +.. _v39-0-2: + + +39.0.2 - 2023-03-02 +~~~~~~~~~~~~~~~~~~~ + +* Fixed a bug where the content type header was not properly encoded for + PKCS7 signatures when using the ``Text`` option and ``SMIME`` encoding. + .. _v39-0-1: From c4ff4f92ef485ac9f01135dc15f064d4245bc967 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Mar 2023 18:02:58 -0500 Subject: [PATCH 372/827] ignore ntt in linkcheck (#8423) --- docs/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index e5b1146c0704..4764cd70540a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -195,6 +195,8 @@ linkcheck_timeout = 5 linkcheck_ignore = [ + # Insecure renegotiation settings + r"https://info.isl.ntt.co.jp/crypt/eng/camellia/", # Inconsistent small DH params they seem incapable of fixing r"https://www.secg.org/sec1-v2.pdf", # Cert is issued from an untrusted root From a20a12458d90fe05442fa77cfffa1828082e0fb8 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:15:50 -0500 Subject: [PATCH 373/827] Bump BoringSSL and/or OpenSSL in CI (#8424) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd10b25f4b5e..31f5f3e97f40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 02, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "76cb7c5eb726e7637ed4c627ac27dacbd6250584"}} - # Latest commit on the OpenSSL master branch, as of Mar 02, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d0a3b9d1eb1fc510ec3447b44803bbf5520a0c47"}} + # Latest commit on the BoringSSL master branch, as of Mar 03, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e06f172bf22c098719d0d9b970f839b39dcd41ce"}} + # Latest commit on the OpenSSL master branch, as of Mar 03, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "08a11ba20461ce14b0a6b9c9e374fbea91fbd8cf"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 5c6148b4d1f34ca35a141e4fc37ea9ac2093b3c8 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 4 Mar 2023 00:22:05 +0000 Subject: [PATCH 374/827] Bump BoringSSL and/or OpenSSL in CI (#8427) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31f5f3e97f40..cdfb20c8948e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 03, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "e06f172bf22c098719d0d9b970f839b39dcd41ce"}} + # Latest commit on the BoringSSL master branch, as of Mar 04, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "93e8d4463d59d671e9c5c6171226341f04b07907"}} # Latest commit on the OpenSSL master branch, as of Mar 03, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "08a11ba20461ce14b0a6b9c9e374fbea91fbd8cf"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From dbb99421f3951dac2101f49729653c4377d9f086 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Mar 2023 22:16:21 -0500 Subject: [PATCH 375/827] remove unused ssl bindings (#8428) --- src/_cffi_src/openssl/ssl.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index febe353636f3..fbcd8cc1a619 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -189,16 +189,12 @@ int SSL_CTX_set_cipher_list(SSL_CTX *, const char *); int SSL_CTX_load_verify_locations(SSL_CTX *, const char *, const char *); void SSL_CTX_set_default_passwd_cb(SSL_CTX *, pem_password_cb *); -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void *); int SSL_CTX_use_certificate(SSL_CTX *, X509 *); int SSL_CTX_use_certificate_file(SSL_CTX *, const char *, int); int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *); int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *); int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int); int SSL_CTX_check_private_key(const SSL_CTX *); -void SSL_CTX_set_cert_verify_callback(SSL_CTX *, - int (*)(X509_STORE_CTX *, void *), - void *); void SSL_CTX_set_cookie_generate_cb(SSL_CTX *, int (*)( @@ -256,14 +252,12 @@ int SSL_CTX_set_session_id_context(SSL_CTX *, const unsigned char *, unsigned int); -void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); int SSL_CTX_add_client_CA(SSL_CTX *, X509 *); void SSL_CTX_set_client_CA_list(SSL_CTX *, Cryptography_STACK_OF_X509_NAME *); void SSL_CTX_set_info_callback(SSL_CTX *, void (*)(const SSL *, int, int)); -void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); void SSL_CTX_set_msg_callback(SSL_CTX *, void (*)( @@ -317,12 +311,10 @@ long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); uint64_t SSL_CTX_set_options(SSL_CTX *, uint64_t); -uint64_t SSL_CTX_clear_options(SSL_CTX *, uint64_t); uint64_t SSL_CTX_get_options(SSL_CTX *); long SSL_CTX_set_mode(SSL_CTX *, long); long SSL_CTX_clear_mode(SSL_CTX *, long); -long SSL_CTX_get_mode(SSL_CTX *); long SSL_set_mode(SSL *, long); long SSL_clear_mode(SSL *, long); @@ -342,15 +334,12 @@ const char *SSL_get_version(const SSL *); int SSL_version(const SSL *); -void *SSL_CTX_get_ex_data(const SSL_CTX *, int); void *SSL_get_ex_data(const SSL *, int); void SSL_set_tlsext_host_name(SSL *, char *); void SSL_CTX_set_tlsext_servername_callback( SSL_CTX *, int (*)(SSL *, int *, void *)); -void SSL_CTX_set_tlsext_servername_arg( - SSL_CTX *, void *); long SSL_set_tlsext_status_ocsp_resp(SSL *, unsigned char *, int); long SSL_get_tlsext_status_ocsp_resp(SSL *, const unsigned char **); From b3f7751c1225eceb19370eceea5953a6e0aed34b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Mar 2023 22:18:19 -0500 Subject: [PATCH 376/827] we do not check for an openssl bin anymore (#8429) --- .github/workflows/build_openssl.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build_openssl.sh b/.github/workflows/build_openssl.sh index 6dd6e04fc331..566abae69aa9 100755 --- a/.github/workflows/build_openssl.sh +++ b/.github/workflows/build_openssl.sh @@ -72,8 +72,6 @@ elif [[ "${TYPE}" == "boringssl" ]]; then cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" -DCMAKE_INSTALL_PREFIX="${OSSL_PATH}" make -j"$(nproc)" make install - # BoringSSL doesn't have a bin/openssl and we use that to detect success - touch "${OSSL_PATH}/bin/openssl" popd popd fi From a368592e093223f0f68059db3eb45d4ae6753dd3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Mar 2023 22:40:15 -0500 Subject: [PATCH 377/827] remove one last unused ssl function (#8430) --- src/_cffi_src/openssl/ssl.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index fbcd8cc1a619..3e1b09209e3b 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -366,8 +366,6 @@ void SSL_CTX_set_cert_cb(SSL_CTX *, int (*)(SSL *, void *), void *); void SSL_set_cert_cb(SSL *, int (*)(SSL *, void *), void *); -int SSL_SESSION_set1_id_context(SSL_SESSION *, const unsigned char *, - unsigned int); size_t SSL_SESSION_get_master_key(const SSL_SESSION *, unsigned char *, size_t); size_t SSL_get_client_random(const SSL *, unsigned char *, size_t); From e2d09e269ecc9baf29767d24ff1196900e88bf90 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Mar 2023 22:47:18 -0500 Subject: [PATCH 378/827] remove final unused bindings from x509_vfy (#8431) --- src/_cffi_src/openssl/x509_vfy.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index b77b2ed3317e..69c31c966185 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -37,7 +37,6 @@ static const int X509_V_OK; /* Verification parameters */ -static const long X509_V_FLAG_USE_CHECK_TIME; static const long X509_V_FLAG_CRL_CHECK; static const long X509_V_FLAG_CRL_CHECK_ALL; static const long X509_V_FLAG_IGNORE_CRITICAL; @@ -45,16 +44,10 @@ static const long X509_V_FLAG_ALLOW_PROXY_CERTS; static const long X509_V_FLAG_POLICY_CHECK; static const long X509_V_FLAG_EXPLICIT_POLICY; -static const long X509_V_FLAG_INHIBIT_ANY; static const long X509_V_FLAG_INHIBIT_MAP; static const long X509_V_FLAG_NOTIFY_POLICY; -static const long X509_V_FLAG_EXTENDED_CRL_SUPPORT; -static const long X509_V_FLAG_USE_DELTAS; static const long X509_V_FLAG_CHECK_SS_SIGNATURE; -static const long X509_V_FLAG_TRUSTED_FIRST; static const long X509_V_FLAG_PARTIAL_CHAIN; -static const long X509_V_FLAG_NO_ALT_CHAINS; -static const long X509_V_FLAG_NO_CHECK_TIME; static const long X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; static const long X509_CHECK_FLAG_NO_WILDCARDS; From 10b861206cb60f6258c163f27dd47c68e8b2e101 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 4 Mar 2023 12:34:59 +0800 Subject: [PATCH 379/827] pointlessly optimize our ossl custom builds (#8432) --- .github/workflows/build_openssl.sh | 8 ++++++++ .github/workflows/ci.yml | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_openssl.sh b/.github/workflows/build_openssl.sh index 566abae69aa9..704e29b41931 100755 --- a/.github/workflows/build_openssl.sh +++ b/.github/workflows/build_openssl.sh @@ -41,6 +41,8 @@ if [[ "${TYPE}" == "openssl" ]]; then # avoid installing the docs (for performance) # https://github.com/openssl/openssl/issues/6685#issuecomment-403838728 make install_sw install_ssldirs + # delete binaries we don't need + rm -rf "${OSSL_PATH}/bin" # For OpenSSL 3.0.0 set up the FIPS config. This does not activate it by # default, but allows programmatic activation at runtime if [[ "${VERSION}" =~ ^3. && "${CONFIG_FLAGS}" =~ enable-fips ]]; then @@ -61,6 +63,10 @@ elif [[ "${TYPE}" == "libressl" ]]; then ./config -Wl -Wl,-Bsymbolic-functions -fPIC shared --prefix="${OSSL_PATH}" shlib_sed make -j"$(nproc)" install + # delete binaries, libtls, and docs we don't need. can't skip install/compile sadly + rm -rf "${OSSL_PATH}/bin" + rm -rf "${OSSL_PATH}/share" + rm -rf "${OSSL_PATH}/lib/libtls*" popd elif [[ "${TYPE}" == "boringssl" ]]; then git clone https://boringssl.googlesource.com/boringssl @@ -72,6 +78,8 @@ elif [[ "${TYPE}" == "boringssl" ]]; then cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" -DCMAKE_INSTALL_PREFIX="${OSSL_PATH}" make -j"$(nproc)" make install + # delete binaries we don't need + rm -rf "${OSSL_PATH}/bin" popd popd fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdfb20c8948e..e467952ba379 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,12 +83,12 @@ jobs: - name: Load OpenSSL cache uses: actions/cache@v3.2.6 id: ossl-cache - timeout-minutes: 5 + timeout-minutes: 2 with: path: ${{ github.workspace }}/osslcache # When altering the openssl build process you may need to increment the value on the end of this cache key # so that you can prevent it from fetching the cache and skipping the build step. - key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-6 + key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-8 if: matrix.PYTHON.OPENSSL - name: Build custom OpenSSL/LibreSSL run: .github/workflows/build_openssl.sh From d826ae73af17205e09dd775318a542b5600f5b89 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 4 Mar 2023 12:42:00 +0800 Subject: [PATCH 380/827] don't run benchmarks if we haven't touched the src or tests (#8434) --- .github/workflows/benchmark.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index ea25e2b70d16..75adcd394e21 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -1,6 +1,9 @@ name: Benchmark on: - pull_request: {} + pull_request: + paths: + - 'src/**' + - 'tests/**' permissions: contents: read From 08d539f1f7230d799a829e09ce52af4b788ffe11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Mar 2023 11:56:15 +0000 Subject: [PATCH 381/827] Bump platformdirs from 3.0.0 to 3.1.0 (#8435) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.0.0...3.1.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 08c562300147..4d0a2cc26a35 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -98,7 +98,7 @@ pathspec==0.11.0 # via black pkginfo==1.9.6 # via twine -platformdirs==3.0.0; python_version >= "3.7" +platformdirs==3.1.0; python_version >= "3.7" # via # black # tox From d4c991a7e435ee68c7257fbf17ac7dc9cc2621ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Mar 2023 11:56:33 +0000 Subject: [PATCH 382/827] Bump pytest from 7.2.1 to 7.2.2 (#8437) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4d0a2cc26a35..c1b262d0f6b7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -124,7 +124,7 @@ pyproject-api==1.5.0 # via tox pyproject-hooks==1.0.0 # via build -pytest==7.2.1; python_version >= "3.7" +pytest==7.2.2; python_version >= "3.7" # via # cryptography (setup.cfg) # pytest-benchmark From 39cf42eea66bc37817caea707e355c6071f40c7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:20:25 +0000 Subject: [PATCH 383/827] Bump scratch from 1.0.3 to 1.0.4 in /src/rust (#8438) Bumps [scratch](https://github.com/dtolnay/scratch) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/dtolnay/scratch/releases) - [Commits](https://github.com/dtolnay/scratch/compare/1.0.3...1.0.4) --- updated-dependencies: - dependency-name: scratch dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 0fa61330ed75..2f4da7395924 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -477,9 +477,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "5d5e082f6ea090deaf0e6dd04b68360fd5cddb152af6ce8927c9d25db299f98c" [[package]] name = "smallvec" From 56a46b98d2e0948a3f135518751c89ae9f91c33a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:20:50 +0000 Subject: [PATCH 384/827] Bump unicode-ident from 1.0.6 to 1.0.7 in /src/rust (#8439) Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.6 to 1.0.7. - [Release notes](https://github.com/dtolnay/unicode-ident/releases) - [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.6...1.0.7) --- updated-dependencies: - dependency-name: unicode-ident dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2f4da7395924..da8244444807 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7" [[package]] name = "unicode-width" From cf5b627a462d7385fc5d3ac9f2b7e24556de3062 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 4 Mar 2023 17:13:31 -0500 Subject: [PATCH 385/827] don't fail-fast in the linux-rust-coverage jobs (#8441) --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e467952ba379..8278d5005235 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -253,6 +253,7 @@ jobs: linux-rust-coverage: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: PYTHON: - {VERSION: "3.11", TOXENV: "py311"} From 03decbf52f3d15750607c2f010f675c884f59edf Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 4 Mar 2023 17:24:20 -0500 Subject: [PATCH 386/827] Add an ignore for the newest ruff (#8440) * Add an ignore for the newest ruff Clearly document why we have each of our ignores * Bump ruff from 0.0.253 to 0.0.254 Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.253 to 0.0.254. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.253...v0.0.254) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- pyproject.toml | 5 +++-- src/cryptography/hazmat/bindings/_rust/__init__.pyi | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c1b262d0f6b7..9072cd51a001 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -162,7 +162,7 @@ rfc3986==2.0.0 # via twine rich==13.3.1 # via twine -ruff==0.0.253 +ruff==0.0.254 # via cryptography (setup.cfg) six==1.16.0 # via bleach diff --git a/pyproject.toml b/pyproject.toml index 1f1a8ab49754..8460cfdd551f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,8 +64,9 @@ exclude_lines = [ ] [tool.ruff] -# UP007 and UP037 require a higher minimum Python version -ignore = ['N818', 'UP003', 'UP006', 'UP007', 'UP037'] +# UP006: Minimum Python 3.9 +# UP007, UP038: Minimum Python 3.10 +ignore = ['N818', 'UP006', 'UP007', 'UP038'] select = ['E', 'F', 'I', 'N', 'W', 'UP'] line-length = 79 diff --git a/src/cryptography/hazmat/bindings/_rust/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/__init__.pyi index d7642fcc4fe0..94a37a20aa96 100644 --- a/src/cryptography/hazmat/bindings/_rust/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/__init__.pyi @@ -22,7 +22,7 @@ class FixedPool(typing.Generic[T]): self, create: typing.Callable[[], T], ) -> None: ... - def acquire(self) -> "PoolAcquisition[T]": ... + def acquire(self) -> PoolAcquisition[T]: ... class PoolAcquisition(typing.Generic[T]): def __enter__(self) -> T: ... From f17f611e6de804e6518e55bf3b03cc198879a473 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 5 Mar 2023 07:45:29 +0800 Subject: [PATCH 387/827] faster linkcheck and rust jobs (#8442) linkcheck now uses caching and separates build from "test" rust now completely skips all package installation in tox --- .github/workflows/ci.yml | 19 +++++++++++++++++-- tox.ini | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8278d5005235..15cba94e7d98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -528,7 +528,7 @@ jobs: if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'linkcheck')) runs-on: ubuntu-latest name: "linkcheck" - timeout-minutes: 15 + timeout-minutes: 10 steps: - uses: actions/checkout@v3.3.0 with: @@ -537,11 +537,26 @@ jobs: - name: set mtimes for rust dirs uses: ./.github/actions/mtime-fix - name: Setup python + id: setup-python uses: actions/setup-python@v4.5.0 with: python-version: 3.11 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 + with: + # This creates the same key as the docs job (as long as they have the same + # python version) + key: 3.11-${{ steps.setup-python.outputs.python-version }} - run: python -m pip install -c ci-constraints-requirements.txt tox - - run: tox -r -- --color=yes + - name: Build toxenv + run: | + tox -vvv --notest + env: + TOXENV: docs-linkcheck + CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + - name: linkcheck + run: tox --skip-pkg-install -- --color=yes env: TOXENV: docs-linkcheck diff --git a/tox.ini b/tox.ini index 4b6d1d9d84fd..6e6e60c101fb 100644 --- a/tox.ini +++ b/tox.ini @@ -72,6 +72,9 @@ commands = [testenv:rust] basepython = python3 +skip_install = True +extras = +deps = changedir = src/rust/ allowlist_externals = cargo From 8a673a005a299ad0c70a8410d592ac619cc1ca9b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 5 Mar 2023 08:11:45 +0800 Subject: [PATCH 388/827] update all-green to py311 (#8443) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15cba94e7d98..d6b763457ad4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -578,7 +578,7 @@ jobs: if: ${{ always() }} uses: actions/setup-python@v4.5.0 with: - python-version: '3.10' + python-version: '3.11' - run: pip install -c ci-constraints-requirements.txt coverage[toml] if: ${{ always() }} - name: Download coverage data From df5893fe0ddbd8dd0ee1e05dffdf64b3bb4c44b3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 5 Mar 2023 08:41:50 +0800 Subject: [PATCH 389/827] deprecate support for OpenSSL <1.1.1d (#8444) * deprecate support for OpenSSL <1.1.1d * use an actually exported constant --- CHANGELOG.rst | 2 ++ .../hazmat/bindings/openssl/binding.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d20f3ab335e7..a55c4f85be09 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,8 @@ Changelog ``pip`` will typically get a wheel and not need Rust installed, but check :doc:`/installation` for documentation on installing a newer ``rustc`` if required. +* Deprecated support for OpenSSL less than 1.1.1d. The next release of + ``cryptography`` will drop support for older versions. * Deprecated support for DSA keys in :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` and diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index ba9e5f7becbc..af47a0853aa1 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -10,6 +10,7 @@ import warnings import cryptography +from cryptography import utils from cryptography.exceptions import InternalError from cryptography.hazmat.bindings._openssl import ffi, lib from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES @@ -244,3 +245,20 @@ def _verify_package_version(version: str) -> None: UserWarning, stacklevel=2, ) + + +def _verify_openssl_version(lib): + if ( + not lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER + and not lib.CRYPTOGRAPHY_IS_LIBRESSL + and not lib.CRYPTOGRAPHY_IS_BORINGSSL + ): + warnings.warn( + "Support for OpenSSL less than version 1.1.1d is deprecated and " + "the next release of cryptography will drop support. Please " + "upgrade your OpenSSL to version 1.1.1d or newer.", + utils.DeprecatedIn40, + ) + + +_verify_openssl_version(Binding.lib) From 550355b552afb61a5a24fedbec43b14a1f209521 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 5 Mar 2023 21:59:23 +0800 Subject: [PATCH 390/827] remove pytz test dependency (#8447) --- ci-constraints-requirements.txt | 3 --- setup.cfg | 2 -- tests/x509/test_x509.py | 11 ++++------- tests/x509/test_x509_crlbuilder.py | 11 ++++------- tests/x509/test_x509_revokedcertbuilder.py | 6 ++---- 5 files changed, 10 insertions(+), 23 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9072cd51a001..1d2da58b4591 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -148,7 +148,6 @@ pytest-xdist==3.2.0; python_version >= "3.7" pytz==2022.7.1 # via # babel - # cryptography (setup.cfg) readme-renderer==37.3 # via twine requests==2.28.2; python_version >= "3.7" @@ -208,8 +207,6 @@ tox==4.4.6; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -types-pytz==2022.7.1.2 - # via cryptography (setup.cfg) types-requests==2.28.11.15 # via cryptography (setup.cfg) types-urllib3==1.26.25.8 diff --git a/setup.cfg b/setup.cfg index b2ecf8961a1b..75204cfd7d6a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,7 +67,6 @@ test = pytest-xdist pretend iso8601 - pytz hypothesis>=1.11.4,!=3.79.2 test-randomorder: pytest-randomly @@ -84,7 +83,6 @@ pep8test = black ruff mypy - types-pytz types-requests check-manifest # This extra is for OpenSSH private keys that use bcrypt KDF diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 36da4585a122..4ff31205d632 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -11,7 +11,6 @@ import typing import pytest -import pytz from cryptography import utils, x509 from cryptography.exceptions import InvalidSignature, UnsupportedAlgorithm @@ -2616,9 +2615,8 @@ def test_serial_number_may_only_be_set_once(self): builder.serial_number(20) def test_aware_not_valid_after(self, backend): - time = datetime.datetime(2012, 1, 16, 22, 43) - tz = pytz.timezone("US/Pacific") - time = tz.localize(time) + tz = datetime.timezone(datetime.timedelta(hours=-8)) + time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_time = datetime.datetime(2012, 1, 17, 6, 43) private_key = RSA_KEY_2048.private_key(backend) cert_builder = x509.CertificateBuilder().not_valid_after(time) @@ -2688,9 +2686,8 @@ def test_not_valid_after_may_only_be_set_once(self): builder.not_valid_after(datetime.datetime.now()) def test_aware_not_valid_before(self, backend): - time = datetime.datetime(2012, 1, 16, 22, 43) - tz = pytz.timezone("US/Pacific") - time = tz.localize(time) + tz = datetime.timezone(datetime.timedelta(hours=-8)) + time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_time = datetime.datetime(2012, 1, 17, 6, 43) private_key = RSA_KEY_2048.private_key(backend) cert_builder = x509.CertificateBuilder().not_valid_before(time) diff --git a/tests/x509/test_x509_crlbuilder.py b/tests/x509/test_x509_crlbuilder.py index ef0f18392b9d..7ca4f4282913 100644 --- a/tests/x509/test_x509_crlbuilder.py +++ b/tests/x509/test_x509_crlbuilder.py @@ -6,7 +6,6 @@ import datetime import pytest -import pytz from cryptography import x509 from cryptography.exceptions import UnsupportedAlgorithm @@ -41,9 +40,8 @@ def test_set_issuer_name_twice(self): ) def test_aware_last_update(self, backend): - last_time = datetime.datetime(2012, 1, 16, 22, 43) - tz = pytz.timezone("US/Pacific") - last_time = tz.localize(last_time) + tz = datetime.timezone(datetime.timedelta(hours=-8)) + last_time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_last = datetime.datetime(2012, 1, 17, 6, 43) next_time = datetime.datetime(2022, 1, 17, 6, 43) private_key = RSA_KEY_2048.private_key(backend) @@ -83,9 +81,8 @@ def test_set_last_update_twice(self): builder.last_update(datetime.datetime(2002, 1, 1, 12, 1)) def test_aware_next_update(self, backend): - next_time = datetime.datetime(2022, 1, 16, 22, 43) - tz = pytz.timezone("US/Pacific") - next_time = tz.localize(next_time) + tz = datetime.timezone(datetime.timedelta(hours=-8)) + next_time = datetime.datetime(2022, 1, 16, 22, 43, tzinfo=tz) utc_next = datetime.datetime(2022, 1, 17, 6, 43) last_time = datetime.datetime(2012, 1, 17, 6, 43) private_key = RSA_KEY_2048.private_key(backend) diff --git a/tests/x509/test_x509_revokedcertbuilder.py b/tests/x509/test_x509_revokedcertbuilder.py index 83a71ff9b6ed..e0f53f856f02 100644 --- a/tests/x509/test_x509_revokedcertbuilder.py +++ b/tests/x509/test_x509_revokedcertbuilder.py @@ -6,7 +6,6 @@ import datetime import pytest -import pytz from cryptography import x509 @@ -58,9 +57,8 @@ def test_set_serial_number_twice(self): builder.serial_number(4) def test_aware_revocation_date(self, backend): - time = datetime.datetime(2012, 1, 16, 22, 43) - tz = pytz.timezone("US/Pacific") - time = tz.localize(time) + tz = datetime.timezone(datetime.timedelta(hours=-8)) + time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_time = datetime.datetime(2012, 1, 17, 6, 43) serial_number = 333 builder = ( From f8bbaeb62671db29dcd870a70c622ee4c99f4740 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Mar 2023 15:45:46 -0500 Subject: [PATCH 391/827] Shrink the cache for ~/.cargo/bin (#8451) * Shrink the cache for ~/.cargo/bin * Test the cache restoration --- .github/actions/cache/action.yml | 2 +- .github/workflows/ci.yml | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 058e864ff60e..29492a0dd846 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -39,7 +39,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-2-${{ hashFiles('**/Cargo.lock') }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock') }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6b763457ad4..6d1b87a4e7e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -284,7 +284,25 @@ jobs: with: key: ${{ steps.rust-toolchain.outputs.cachekey }}-coverage additional-paths: | - ~/.cargo/bin/ + ~/.cargo/bin/cargo-cov + ~/.cargo/bin/cargo-nm + ~/.cargo/bin/cargo-objcopy + ~/.cargo/bin/cargo-objdump + ~/.cargo/bin/cargo-profdata + ~/.cargo/bin/cargo-readobj + ~/.cargo/bin/cargo-size + ~/.cargo/bin/cargo-strip + ~/.cargo/bin/rust-ar + ~/.cargo/bin/rust-cov + ~/.cargo/bin/rust-ld + ~/.cargo/bin/rust-lld + ~/.cargo/bin/rust-nm + ~/.cargo/bin/rust-objcopy + ~/.cargo/bin/rust-objdump + ~/.cargo/bin/rust-profdata + ~/.cargo/bin/rust-readobj + ~/.cargo/bin/rust-size + ~/.cargo/bin/rust-strip - name: Setup python uses: actions/setup-python@v4.5.0 with: From f0a59fdfbbe5fe9a0bcae4eaa39fb4fb277aa120 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 00:17:56 +0000 Subject: [PATCH 392/827] Bump BoringSSL and/or OpenSSL in CI (#8452) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d1b87a4e7e0..b82e74d50174 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 04, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "93e8d4463d59d671e9c5c6171226341f04b07907"}} - # Latest commit on the OpenSSL master branch, as of Mar 03, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "08a11ba20461ce14b0a6b9c9e374fbea91fbd8cf"}} + # Latest commit on the BoringSSL master branch, as of Mar 06, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3a7dfdb984434a4b4beef947b2e49602c557c0de"}} + # Latest commit on the OpenSSL master branch, as of Mar 06, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "10836921e52ff9110c12b4b9f984e7c5ef1c89cc"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From c6e8014a55282496957034bb6a09ae9b000da8a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 00:48:34 +0000 Subject: [PATCH 393/827] Bump unicode-ident from 1.0.7 to 1.0.8 in /src/rust (#8453) Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.7 to 1.0.8. - [Release notes](https://github.com/dtolnay/unicode-ident/releases) - [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.7...1.0.8) --- updated-dependencies: - dependency-name: unicode-ident dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index da8244444807..8fe716b88f59 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-width" From 9d136eb135243e3e2e8eeb9366828782fdf12784 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Mar 2023 19:49:30 -0500 Subject: [PATCH 394/827] Bump rich from 13.3.1 to 13.3.2 (#8454) Bumps [rich](https://github.com/Textualize/rich) from 13.3.1 to 13.3.2. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.1...v13.3.2) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1d2da58b4591..e95ebddcb75c 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -159,7 +159,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.3.1 +rich==13.3.2 # via twine ruff==0.0.254 # via cryptography (setup.cfg) From b5c93aa00cc7fc578e6594139e2a89275f46d651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 00:55:12 +0000 Subject: [PATCH 395/827] Bump cxx-build from 1.0.91 to 1.0.92 in /src/rust (#8455) Bumps [cxx-build](https://github.com/dtolnay/cxx) from 1.0.91 to 1.0.92. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.91...1.0.92) --- updated-dependencies: - dependency-name: cxx-build dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 8fe716b88f59..94d053df583c 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" +checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613" dependencies = [ "cc", "codespan-reporting", From 7c6ca9be1bed73758c1b660ebbfdebaf32870694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 01:05:41 +0000 Subject: [PATCH 396/827] Bump cxx from 1.0.91 to 1.0.92 in /src/rust (#8456) Bumps [cxx](https://github.com/dtolnay/cxx) from 1.0.91 to 1.0.92. - [Release notes](https://github.com/dtolnay/cxx/releases) - [Commits](https://github.com/dtolnay/cxx/compare/1.0.91...1.0.92) --- updated-dependencies: - dependency-name: cxx dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 94d053df583c..29bf2bc997c8 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" +checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72" dependencies = [ "cc", "cxxbridge-flags", @@ -149,15 +149,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" +checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97" [[package]] name = "cxxbridge-macro" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" +checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" dependencies = [ "proc-macro2", "quote", From fbf28d8a1e3a4cff3702e5ce3b22568cfc2cd95e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 01:06:01 +0000 Subject: [PATCH 397/827] Bump scratch from 1.0.4 to 1.0.5 in /src/rust (#8457) Bumps [scratch](https://github.com/dtolnay/scratch) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/dtolnay/scratch/releases) - [Commits](https://github.com/dtolnay/scratch/compare/1.0.4...1.0.5) --- updated-dependencies: - dependency-name: scratch dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 29bf2bc997c8..03246928f292 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -477,9 +477,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5e082f6ea090deaf0e6dd04b68360fd5cddb152af6ce8927c9d25db299f98c" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "smallvec" From b522ec009292625e7079f80cdb47a9f734513d1c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 6 Mar 2023 10:19:52 +0800 Subject: [PATCH 398/827] double the speed of our rsa tests (#8458) * double the speed of our rsa tests this both creates a reusable fixture for our most commonly used private keys as well as disables key validation. as always, disabling key validation should not be done unless you never parse untrusted key input. unsurprisingly, our tests are trusted and understood input (and we also continue to have tests where we run check key to verify that it catches corrupt things) * fix typing * explain why we don't use the rsa_key_2048 fixture in the blinding test --- tests/hazmat/primitives/test_rsa.py | 364 +++++++++++++++++++--------- 1 file changed, 243 insertions(+), 121 deletions(-) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 02d16a54a519..36e65359bf51 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -59,6 +59,16 @@ ) +@pytest.fixture(scope="session") +def rsa_key_512() -> rsa.RSAPrivateKey: + return RSA_KEY_512.private_key(unsafe_skip_rsa_key_validation=True) + + +@pytest.fixture(scope="session") +def rsa_key_2048() -> rsa.RSAPrivateKey: + return RSA_KEY_2048.private_key(unsafe_skip_rsa_key_validation=True) + + class DummyMGF(padding.MGF): _salt_length = 0 _algorithm = hashes.SHA1() @@ -274,7 +284,7 @@ def test_load_pss_keys_strips_constraints(self, path, backend): key = load_vectors_from_file( filename=path, loader=lambda p: serialization.load_pem_private_key( - p.read(), password=None + p.read(), password=None, unsafe_skip_rsa_key_validation=True ), mode="rb", ) @@ -352,7 +362,10 @@ def test_load_pss_unsupported(self, backend): ) def test_oaep_label_decrypt(self, vector, backend): private_key = serialization.load_der_private_key( - binascii.unhexlify(vector["key"]), None, backend + binascii.unhexlify(vector["key"]), + None, + backend, + unsafe_skip_rsa_key_validation=True, ) assert isinstance(private_key, rsa.RSAPrivateKey) assert vector["oaepdigest"] == b"SHA512" @@ -383,8 +396,8 @@ def test_oaep_label_decrypt(self, vector, backend): ), skip_message="Does not support RSA OAEP labels", ) - def test_oaep_label_roundtrip(self, msg, label, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_oaep_label_roundtrip(self, rsa_key_2048, msg, label, backend): + private_key = rsa_key_2048 ct = private_key.public_key().encrypt( msg, padding.OAEP( @@ -417,8 +430,8 @@ def test_oaep_label_roundtrip(self, msg, label, backend): ), skip_message="Does not support RSA OAEP labels", ) - def test_oaep_wrong_label(self, enclabel, declabel, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_oaep_wrong_label(self, rsa_key_2048, enclabel, declabel, backend): + private_key = rsa_key_2048 msg = b"test" ct = private_key.public_key().encrypt( msg, @@ -445,7 +458,14 @@ def test_oaep_wrong_label(self, enclabel, declabel, backend): skip_message="Does not support PKCS1v1.5.", ) def test_lazy_blinding(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + # We don't want to reuse the rsa_key_2048 fixture here because lazy + # blinding mutates the object to add the blinding factor on + # the first call to decrypt/sign. Since we reuse rsa_key_2048 in + # many tests we can't properly test blinding, which will (likely) + # already be set on the fixture. + private_key = RSA_KEY_2048.private_key( + unsafe_skip_rsa_key_validation=True + ) public_key = private_key.public_key() msg = b"encrypt me!" ct = public_key.encrypt( @@ -546,7 +566,7 @@ def test_pss_signing(self, subtests, backend): public_numbers=rsa.RSAPublicNumbers( e=private["public_exponent"], n=private["modulus"] ), - ).private_key(backend) + ).private_key(backend, unsafe_skip_rsa_key_validation=True) public_key = rsa.RSAPublicNumbers( e=public["public_exponent"], n=public["modulus"] ).public_key(backend) @@ -576,9 +596,9 @@ def test_pss_signing(self, subtests, backend): "hash_alg", [hashes.SHA224(), hashes.SHA256(), hashes.SHA384(), hashes.SHA512()], ) - def test_pss_signing_sha2(self, hash_alg, backend): + def test_pss_signing_sha2(self, rsa_key_2048, hash_alg, backend): _skip_pss_hash_algorithm_unsupported(backend, hash_alg) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 public_key = private_key.public_key() pss = padding.PSS( mgf=padding.MGF1(hash_alg), salt_length=padding.PSS.MAX_LENGTH @@ -596,8 +616,8 @@ def test_pss_signing_sha2(self, hash_alg, backend): ), skip_message="Does not support PSS.", ) - def test_pss_digest_length(self, backend): - private_key = RSA_KEY_2048.private_key() + def test_pss_digest_length(self, rsa_key_2048, backend): + private_key = rsa_key_2048 signature = private_key.sign( b"some data", padding.PSS( @@ -640,7 +660,9 @@ def test_pss_digest_length(self, backend): ) @pytest.mark.skip_fips(reason="Unsupported key size in FIPS mode.") def test_pss_minimum_key_size_for_digest(self, backend): - private_key = RSA_KEY_522.private_key(backend) + private_key = RSA_KEY_522.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) private_key.sign( b"no failure", padding.PSS( @@ -664,8 +686,10 @@ def test_pss_minimum_key_size_for_digest(self, backend): skip_message="Does not support SHA512.", ) @pytest.mark.skip_fips(reason="Unsupported key size in FIPS mode.") - def test_pss_signing_digest_too_large_for_key_size(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_pss_signing_digest_too_large_for_key_size( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_512 with pytest.raises(ValueError): private_key.sign( b"msg", @@ -685,8 +709,10 @@ def test_pss_signing_digest_too_large_for_key_size(self, backend): ), skip_message="Does not support PSS.", ) - def test_pss_signing_salt_length_too_long(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_pss_signing_salt_length_too_long( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with pytest.raises(ValueError): private_key.sign( b"failure coming", @@ -696,13 +722,17 @@ def test_pss_signing_salt_length_too_long(self, backend): hashes.SHA256(), ) - def test_unsupported_padding(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_padding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): private_key.sign(b"msg", DummyAsymmetricPadding(), hashes.SHA1()) - def test_padding_incorrect_type(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_padding_incorrect_type( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with pytest.raises(TypeError): private_key.sign( b"msg", @@ -716,8 +746,10 @@ def test_padding_incorrect_type(self, backend): ), skip_message="Does not support PSS.", ) - def test_unsupported_pss_mgf(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_unsupported_pss_mgf( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_512 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): private_key.sign( b"msg", @@ -737,8 +769,10 @@ def test_unsupported_pss_mgf(self, backend): ), skip_message="Does not support PSS.", ) - def test_pss_sign_unsupported_auto(self, backend): - private_key = RSA_KEY_2048.private_key() + def test_pss_sign_unsupported_auto( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with pytest.raises(ValueError): private_key.sign( b"some data", @@ -757,7 +791,9 @@ def test_pss_sign_unsupported_auto(self, backend): ) @pytest.mark.skip_fips(reason="Unsupported key size in FIPS mode.") def test_pkcs1_digest_too_large_for_key_size(self, backend): - private_key = RSA_KEY_599.private_key(backend) + private_key = RSA_KEY_599.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) with pytest.raises(ValueError): private_key.sign( b"failure coming", padding.PKCS1v15(), hashes.SHA512() @@ -771,11 +807,13 @@ def test_pkcs1_digest_too_large_for_key_size(self, backend): ) @pytest.mark.skip_fips(reason="Unsupported key size in FIPS mode.") def test_pkcs1_minimum_key_size(self, backend): - private_key = RSA_KEY_745.private_key(backend) + private_key = RSA_KEY_745.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) private_key.sign(b"no failure", padding.PKCS1v15(), hashes.SHA512()) - def test_sign(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 message = b"one little message" pkcs = padding.PKCS1v15() algorithm = hashes.SHA256() @@ -789,8 +827,8 @@ def test_sign(self, backend): ), skip_message="Does not support PSS.", ) - def test_prehashed_sign(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_prehashed_sign(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 message = b"one little message" h = hashes.Hash(hashes.SHA256(), backend) h.update(message) @@ -810,8 +848,10 @@ def test_prehashed_sign(self, backend): ), skip_message="Does not support PSS.", ) - def test_prehashed_digest_length(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_prehashed_digest_length( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 message = b"one little message" h = hashes.Hash(hashes.SHA256(), backend) h.update(message) @@ -837,8 +877,8 @@ def test_prehashed_digest_length(self, backend): ), skip_message="Does not support PSS.", ) - def test_unsupported_hash(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_unsupported_hash(self, rsa_key_512: rsa.RSAPrivateKey, backend): + private_key = rsa_key_512 message = b"one little message" pss = padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=0) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): @@ -850,8 +890,10 @@ def test_unsupported_hash(self, backend): ), skip_message="Does not support PSS.", ) - def test_prehashed_digest_mismatch(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_prehashed_digest_mismatch( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_512 message = b"one little message" h = hashes.Hash(hashes.SHA512(), backend) h.update(message) @@ -861,8 +903,10 @@ def test_prehashed_digest_mismatch(self, backend): with pytest.raises(ValueError): private_key.sign(digest, pss, prehashed_alg) - def test_prehashed_unsupported_in_signature_recover(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_prehashed_unsupported_in_signature_recover( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() signature = private_key.sign( b"sign me", padding.PKCS1v15(), hashes.SHA256() @@ -936,8 +980,10 @@ def test_pkcs1v15_verification(self, backend, subtests): ), skip_message="Does not support PKCS1v1.5.", ) - def test_invalid_pkcs1v15_signature_wrong_data(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_invalid_pkcs1v15_signature_wrong_data( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() signature = private_key.sign( b"sign me", padding.PKCS1v15(), hashes.SHA256() @@ -950,8 +996,10 @@ def test_invalid_pkcs1v15_signature_wrong_data(self, backend): hashes.SHA256(), ) - def test_invalid_pkcs1v15_signature_recover_wrong_hash_alg(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_invalid_pkcs1v15_signature_recover_wrong_hash_alg( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() signature = private_key.sign( b"sign me", padding.PKCS1v15(), hashes.SHA256() @@ -1003,9 +1051,13 @@ def test_invalid_signature_sequence_removed(self, backend): ), skip_message="Does not support PKCS1v1.5.", ) - def test_invalid_pkcs1v15_signature_wrong_key(self, backend): - private_key = RSA_KEY_2048.private_key(backend) - private_key2 = RSA_KEY_2048_ALT.private_key(backend) + def test_invalid_pkcs1v15_signature_wrong_key( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 + private_key2 = RSA_KEY_2048_ALT.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) public_key = private_key2.public_key() msg = b"sign me" signature = private_key.sign(msg, padding.PKCS1v15(), hashes.SHA256()) @@ -1058,8 +1110,10 @@ def test_pss_verification(self, subtests, backend): ), skip_message="Does not support PSS.", ) - def test_pss_verify_auto_salt_length(self, backend): - private_key = RSA_KEY_2048.private_key() + def test_pss_verify_auto_salt_length( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 signature = private_key.sign( b"some data", padding.PSS( @@ -1191,7 +1245,9 @@ def test_invalid_pss_signature_data_too_large_for_modulus(self, backend): b"ac462c50a488dca486031a3dc8c4cdbbc53e9f71d64732e1533a5d1249b833ce" ) # 1024 bit key - public_key = RSA_KEY_1024.private_key(backend).public_key() + public_key = RSA_KEY_1024.private_key( + unsafe_skip_rsa_key_validation=True + ).public_key() with pytest.raises(InvalidSignature): public_key.verify( signature, @@ -1209,8 +1265,10 @@ def test_invalid_pss_signature_data_too_large_for_modulus(self, backend): ), skip_message="Does not support SHA1 signature.", ) - def test_invalid_pss_signature_recover(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_invalid_pss_signature_recover( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() pss_padding = padding.PSS( mgf=padding.MGF1(algorithm=hashes.SHA1()), @@ -1230,16 +1288,20 @@ def test_invalid_pss_signature_recover(self, backend): signature, pss_padding, hashes.SHA256() ) - def test_unsupported_padding(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_padding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): public_key.verify( b"sig", b"msg", DummyAsymmetricPadding(), hashes.SHA256() ) - def test_padding_incorrect_type(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_padding_incorrect_type( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() with pytest.raises(TypeError): public_key.verify( @@ -1255,8 +1317,10 @@ def test_padding_incorrect_type(self, backend): ), skip_message="Does not support PSS.", ) - def test_unsupported_pss_mgf(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_pss_mgf( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): public_key.verify( @@ -1282,8 +1346,10 @@ def test_unsupported_pss_mgf(self, backend): skip_message="Does not support SHA512.", ) @pytest.mark.skip_fips(reason="Unsupported key size in FIPS mode.") - def test_pss_verify_digest_too_large_for_key_size(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_pss_verify_digest_too_large_for_key_size( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_512 signature = binascii.unhexlify( b"8b9a3ae9fb3b64158f3476dd8d8a1f1425444e98940e0926378baa9944d219d8" b"534c050ef6b19b1bdc6eb4da422e89161106a6f5b5cc16135b11eb6439b646bd" @@ -1343,8 +1409,8 @@ def test_pss_verify_salt_length_too_long(self, backend): hashes.SHA1(), ) - def test_verify(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_verify(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 message = b"one little message" pkcs = padding.PKCS1v15() algorithm = hashes.SHA256() @@ -1352,8 +1418,8 @@ def test_verify(self, backend): public_key = private_key.public_key() public_key.verify(signature, message, pkcs, algorithm) - def test_prehashed_verify(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_prehashed_verify(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 message = b"one little message" h = hashes.Hash(hashes.SHA256(), backend) h.update(message) @@ -1364,8 +1430,10 @@ def test_prehashed_verify(self, backend): public_key = private_key.public_key() public_key.verify(signature, digest, pkcs, prehashed_alg) - def test_prehashed_digest_mismatch(self, backend): - public_key = RSA_KEY_2048.private_key(backend).public_key() + def test_prehashed_digest_mismatch( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + public_key = rsa_key_2048.public_key() message = b"one little message" h = hashes.Hash(hashes.SHA256(), backend) h.update(message) @@ -1704,8 +1772,10 @@ def test_decrypt_pkcs1v15_vectors(self, backend, subtests): message = skey.decrypt(ciphertext, padding.PKCS1v15()) assert message == binascii.unhexlify(example["message"]) - def test_unsupported_padding(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_padding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): private_key.decrypt(b"0" * 256, DummyAsymmetricPadding()) @@ -1716,8 +1786,10 @@ def test_unsupported_padding(self, backend): ), skip_message="Does not support PKCS1v1.5.", ) - def test_decrypt_invalid_decrypt(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_decrypt_invalid_decrypt( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with pytest.raises(ValueError): private_key.decrypt(b"\x00" * 256, padding.PKCS1v15()) @@ -1727,8 +1799,10 @@ def test_decrypt_invalid_decrypt(self, backend): ), skip_message="Does not support PKCS1v1.5.", ) - def test_decrypt_ciphertext_too_large(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_decrypt_ciphertext_too_large( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with pytest.raises(ValueError): private_key.decrypt(b"\x00" * 257, padding.PKCS1v15()) @@ -1738,8 +1812,10 @@ def test_decrypt_ciphertext_too_large(self, backend): ), skip_message="Does not support PKCS1v1.5.", ) - def test_decrypt_ciphertext_too_small(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_decrypt_ciphertext_too_small( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 ct = binascii.unhexlify( b"50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b80804f1" b"69d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d8ea0" @@ -1777,7 +1853,7 @@ def test_decrypt_oaep_sha1_vectors(self, subtests, backend): public_numbers=rsa.RSAPublicNumbers( e=private["public_exponent"], n=private["modulus"] ), - ).private_key(backend) + ).private_key(backend, unsafe_skip_rsa_key_validation=True) message = skey.decrypt( binascii.unhexlify(example["encryption"]), padding.OAEP( @@ -1829,11 +1905,13 @@ def test_decrypt_oaep_sha2_vectors(self, backend, subtests): ), skip_message="Does not support OAEP.", ) - def test_invalid_oaep_decryption(self, backend): + def test_invalid_oaep_decryption( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): # More recent versions of OpenSSL may raise different errors. # This test triggers a failure and confirms that we properly handle # it. - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 ciphertext = private_key.public_key().encrypt( b"secure data", @@ -1844,7 +1922,9 @@ def test_invalid_oaep_decryption(self, backend): ), ) - private_key_alt = RSA_KEY_2048_ALT.private_key(backend) + private_key_alt = RSA_KEY_2048_ALT.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) with pytest.raises(ValueError): private_key_alt.decrypt( @@ -1867,7 +1947,9 @@ def test_invalid_oaep_decryption(self, backend): skip_message="Does not support OAEP.", ) def test_invalid_oaep_decryption_data_to_large_for_modulus(self, backend): - key = RSA_KEY_2048_ALT.private_key(backend) + key = RSA_KEY_2048_ALT.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) ciphertext = ( b"\xb1ph\xc0\x0b\x1a|\xe6\xda\xea\xb5\xd7%\x94\x07\xf96\xfb\x96" @@ -1894,8 +1976,10 @@ def test_invalid_oaep_decryption_data_to_large_for_modulus(self, backend): ), ) - def test_unsupported_oaep_mgf(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_oaep_mgf( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): private_key.decrypt( b"0" * 256, @@ -1943,7 +2027,7 @@ class TestRSAEncryption: ), ) def test_rsa_encrypt_oaep(self, key_data, pad, backend): - private_key = key_data.private_key(backend) + private_key = key_data.private_key(unsafe_skip_rsa_key_validation=True) _check_fips_key_length(backend, private_key) pt = b"encrypt me!" public_key = private_key.public_key() @@ -1972,7 +2056,9 @@ def test_rsa_encrypt_oaep(self, key_data, pad, backend): ], ), ) - def test_rsa_encrypt_oaep_sha2(self, mgf1hash, oaephash, backend): + def test_rsa_encrypt_oaep_sha2( + self, rsa_key_2048: rsa.RSAPrivateKey, mgf1hash, oaephash, backend + ): pad = padding.OAEP( mgf=padding.MGF1(algorithm=mgf1hash), algorithm=oaephash, @@ -1983,7 +2069,7 @@ def test_rsa_encrypt_oaep_sha2(self, mgf1hash, oaephash, backend): f"Does not support OAEP using {mgf1hash.name} MGF1 " f"or {oaephash.name} hash." ) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 pt = b"encrypt me using sha2 hashes!" public_key = private_key.public_key() ct = public_key.encrypt(pt, pad) @@ -2017,7 +2103,7 @@ def test_rsa_encrypt_oaep_sha2(self, mgf1hash, oaephash, backend): ), ) def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend): - private_key = key_data.private_key(backend) + private_key = key_data.private_key(unsafe_skip_rsa_key_validation=True) _check_fips_key_length(backend, private_key) pt = b"encrypt me!" public_key = private_key.public_key() @@ -2053,7 +2139,7 @@ def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend): ), ) def test_rsa_encrypt_key_too_small(self, key_data, pad, backend): - private_key = key_data.private_key(backend) + private_key = key_data.private_key(unsafe_skip_rsa_key_validation=True) if not backend.rsa_encryption_supported(pad): pytest.skip("PKCS1v15 padding not allowed in FIPS") _check_fips_key_length(backend, private_key) @@ -2070,13 +2156,14 @@ def test_rsa_encrypt_key_too_small(self, key_data, pad, backend): only_if=lambda backend: backend._fips_enabled, skip_message="Requires FIPS", ) - def test_rsa_fips_small_key(self, backend): - key = RSA_KEY_512.private_key(backend) + def test_rsa_fips_small_key(self, rsa_key_512: rsa.RSAPrivateKey, backend): with pytest.raises(ValueError): - key.sign(b"somedata", padding.PKCS1v15(), hashes.SHA512()) + rsa_key_512.sign(b"somedata", padding.PKCS1v15(), hashes.SHA512()) - def test_unsupported_padding(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_padding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): @@ -2086,8 +2173,10 @@ def test_unsupported_padding(self, backend): b"somedata", padding=object() # type: ignore[arg-type] ) - def test_unsupported_oaep_mgf(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_unsupported_oaep_mgf( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): @@ -2128,7 +2217,9 @@ def test_rsa_private_numbers(self): assert private_numbers.public_numbers == public_numbers def test_rsa_private_numbers_create_key(self, backend): - private_key = RSA_KEY_1024.private_key(backend) + private_key = RSA_KEY_1024.private_key( + backend, unsafe_skip_rsa_key_validation=True + ) assert private_key def test_rsa_public_numbers_create_key(self, backend): @@ -2342,16 +2433,18 @@ class TestRSAPrivateKeySerialization: ], ), ) - def test_private_bytes_encrypted_pem(self, backend, fmt, password): + def test_private_bytes_encrypted_pem( + self, rsa_key_2048: rsa.RSAPrivateKey, backend, fmt, password + ): skip_fips_traditional_openssl(backend, fmt) - key = RSA_KEY_2048.private_key(backend) + key = rsa_key_2048 serialized = key.private_bytes( serialization.Encoding.PEM, fmt, serialization.BestAvailableEncryption(password), ) loaded_key = serialization.load_pem_private_key( - serialized, password, backend + serialized, password, backend, unsafe_skip_rsa_key_validation=True ) assert isinstance(loaded_key, rsa.RSAPrivateKey) loaded_priv_num = loaded_key.private_numbers() @@ -2367,8 +2460,10 @@ def test_private_bytes_encrypted_pem(self, backend, fmt, password): (serialization.Encoding.X962, serialization.PrivateFormat.PKCS8), ], ) - def test_private_bytes_rejects_invalid(self, encoding, fmt, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_rejects_invalid( + self, rsa_key_2048: rsa.RSAPrivateKey, encoding, fmt, backend + ): + key = rsa_key_2048 with pytest.raises(ValueError): key.private_bytes(encoding, fmt, serialization.NoEncryption()) @@ -2381,15 +2476,17 @@ def test_private_bytes_rejects_invalid(self, encoding, fmt, backend): [serialization.PrivateFormat.PKCS8, b"\x01" * 1000], ], ) - def test_private_bytes_encrypted_der(self, backend, fmt, password): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_encrypted_der( + self, rsa_key_2048: rsa.RSAPrivateKey, backend, fmt, password + ): + key = rsa_key_2048 serialized = key.private_bytes( serialization.Encoding.DER, fmt, serialization.BestAvailableEncryption(password), ) loaded_key = serialization.load_der_private_key( - serialized, password, backend + serialized, password, backend, unsafe_skip_rsa_key_validation=True ) assert isinstance(loaded_key, rsa.RSAPrivateKey) loaded_priv_num = loaded_key.private_numbers() @@ -2422,13 +2519,20 @@ def test_private_bytes_encrypted_der(self, backend, fmt, password): ], ) def test_private_bytes_unencrypted( - self, backend, encoding, fmt, loader_func + self, + rsa_key_2048: rsa.RSAPrivateKey, + backend, + encoding, + fmt, + loader_func, ): - key = RSA_KEY_2048.private_key(backend) + key = rsa_key_2048 serialized = key.private_bytes( encoding, fmt, serialization.NoEncryption() ) - loaded_key = loader_func(serialized, None, backend) + loaded_key = loader_func( + serialized, None, backend, unsafe_skip_rsa_key_validation=True + ) loaded_priv_num = loaded_key.private_numbers() priv_num = key.private_numbers() assert loaded_priv_num == priv_num @@ -2461,7 +2565,9 @@ def test_private_bytes_traditional_openssl_unencrypted( key_bytes = load_vectors_from_file( key_path, lambda pemfile: pemfile.read(), mode="rb" ) - key = loader_func(key_bytes, None, backend) + key = loader_func( + key_bytes, None, backend, unsafe_skip_rsa_key_validation=True + ) serialized = key.private_bytes( encoding, serialization.PrivateFormat.TraditionalOpenSSL, @@ -2469,8 +2575,10 @@ def test_private_bytes_traditional_openssl_unencrypted( ) assert serialized == key_bytes - def test_private_bytes_traditional_der_encrypted_invalid(self, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_traditional_der_encrypted_invalid( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048 with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.DER, @@ -2478,8 +2586,10 @@ def test_private_bytes_traditional_der_encrypted_invalid(self, backend): serialization.BestAvailableEncryption(b"password"), ) - def test_private_bytes_invalid_encoding(self, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_invalid_encoding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048 with pytest.raises(TypeError): key.private_bytes( "notencoding", # type: ignore[arg-type] @@ -2487,8 +2597,10 @@ def test_private_bytes_invalid_encoding(self, backend): serialization.NoEncryption(), ) - def test_private_bytes_invalid_format(self, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_invalid_format( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048 with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -2496,8 +2608,10 @@ def test_private_bytes_invalid_format(self, backend): serialization.NoEncryption(), ) - def test_private_bytes_invalid_encryption_algorithm(self, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_invalid_encryption_algorithm( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048 with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -2505,8 +2619,10 @@ def test_private_bytes_invalid_encryption_algorithm(self, backend): "notanencalg", # type: ignore[arg-type] ) - def test_private_bytes_unsupported_encryption_type(self, backend): - key = RSA_KEY_2048.private_key(backend) + def test_private_bytes_unsupported_encryption_type( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048 with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, @@ -2596,16 +2712,20 @@ def test_public_bytes_openssh(self, backend): serialization.PublicFormat.SubjectPublicKeyInfo, ) - def test_public_bytes_invalid_encoding(self, backend): - key = RSA_KEY_2048.private_key(backend).public_key() + def test_public_bytes_invalid_encoding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048.public_key() with pytest.raises(TypeError): key.public_bytes( "notencoding", # type: ignore[arg-type] serialization.PublicFormat.PKCS1, ) - def test_public_bytes_invalid_format(self, backend): - key = RSA_KEY_2048.private_key(backend).public_key() + def test_public_bytes_invalid_format( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + key = rsa_key_2048.public_key() with pytest.raises(TypeError): key.public_bytes( serialization.Encoding.PEM, @@ -2637,7 +2757,9 @@ def test_public_bytes_invalid_format(self, backend): ) ), ) - def test_public_bytes_rejects_invalid(self, encoding, fmt, backend): - key = RSA_KEY_2048.private_key(backend).public_key() + def test_public_bytes_rejects_invalid( + self, rsa_key_2048: rsa.RSAPrivateKey, encoding, fmt, backend + ): + key = rsa_key_2048.public_key() with pytest.raises(ValueError): key.public_bytes(encoding, fmt) From 89593113567918edcaf4bfe84f6c40db1d9851c8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Mar 2023 22:05:06 -0500 Subject: [PATCH 399/827] Remove use of deprecated EC functions (#8459) --- src/_cffi_src/openssl/ec.py | 22 ++---------- .../hazmat/backends/openssl/backend.py | 35 +++---------------- .../hazmat/backends/openssl/ec.py | 10 +++--- .../hazmat/bindings/openssl/_conditional.py | 7 ---- 4 files changed, 13 insertions(+), 61 deletions(-) diff --git a/src/_cffi_src/openssl/ec.py b/src/_cffi_src/openssl/ec.py index 7314ee0715ec..0c7e0545e67d 100644 --- a/src/_cffi_src/openssl/ec.py +++ b/src/_cffi_src/openssl/ec.py @@ -9,14 +9,11 @@ """ TYPES = """ -static const int Cryptography_HAS_EC2M; - static const int OPENSSL_EC_NAMED_CURVE; typedef ... EC_KEY; typedef ... EC_GROUP; typedef ... EC_POINT; -typedef ... EC_METHOD; typedef struct { int nid; const char *comment; @@ -33,7 +30,6 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int); -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); int EC_GROUP_get_curve_name(const EC_GROUP *); size_t EC_get_builtin_curves(EC_builtin_curve *, size_t); @@ -54,11 +50,8 @@ EC_POINT *EC_POINT_new(const EC_GROUP *); void EC_POINT_free(EC_POINT *); -int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); - -int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); +int EC_POINT_get_affine_coordinates(const EC_GROUP *, const EC_POINT *, + BIGNUM *, BIGNUM *, BN_CTX *); size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t, @@ -72,21 +65,10 @@ int EC_POINT_mul(const EC_GROUP *, EC_POINT *, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); -int EC_METHOD_get_field_type(const EC_METHOD *); - const char *EC_curve_nid2nist(int); int EC_GROUP_get_asn1_flag(const EC_GROUP *); """ CUSTOMIZATIONS = """ -#if defined(OPENSSL_NO_EC2M) -static const long Cryptography_HAS_EC2M = 0; - -int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; - -#else -static const long Cryptography_HAS_EC2M = 1; -#endif """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 73ac123fde28..62576b99d0ca 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1327,7 +1327,8 @@ def derive_elliptic_curve_private_key( ) -> ec.EllipticCurvePrivateKey: ec_cdata = self._ec_key_new_by_curve(curve) - get_func, group = self._ec_key_determine_group_get_func(ec_cdata) + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) point = self._lib.EC_POINT_new(group) self.openssl_assert(point != self._ffi.NULL) @@ -1345,7 +1346,9 @@ def derive_elliptic_curve_private_key( bn_x = self._lib.BN_CTX_get(bn_ctx) bn_y = self._lib.BN_CTX_get(bn_ctx) - res = get_func(group, point, bn_x, bn_y, bn_ctx) + res = self._lib.EC_POINT_get_affine_coordinates( + group, point, bn_x, bn_y, bn_ctx + ) if res != 1: self._consume_errors() raise ValueError("Unable to derive key from private_value") @@ -1416,34 +1419,6 @@ def _tmp_bn_ctx(self): finally: self._lib.BN_CTX_end(bn_ctx) - def _ec_key_determine_group_get_func(self, ec_key): - """ - Given an EC_KEY determine the group and what function is required to - get point coordinates. - """ - self.openssl_assert(ec_key != self._ffi.NULL) - - nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field") - self.openssl_assert(nid_two_field != self._lib.NID_undef) - - group = self._lib.EC_KEY_get0_group(ec_key) - self.openssl_assert(group != self._ffi.NULL) - - method = self._lib.EC_GROUP_method_of(group) - self.openssl_assert(method != self._ffi.NULL) - - nid = self._lib.EC_METHOD_get_field_type(method) - self.openssl_assert(nid != self._lib.NID_undef) - - if nid == nid_two_field and self._lib.Cryptography_HAS_EC2M: - get_func = self._lib.EC_POINT_get_affine_coordinates_GF2m - else: - get_func = self._lib.EC_POINT_get_affine_coordinates_GFp - - assert get_func - - return get_func, group - def _ec_key_set_public_key_affine_coordinates( self, ctx, x: int, y: int ) -> None: diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index a2a42c2edba8..969306bcb893 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -234,9 +234,9 @@ def key_size(self) -> int: return self.curve.key_size def public_numbers(self) -> ec.EllipticCurvePublicNumbers: - get_func, group = self._backend._ec_key_determine_group_get_func( - self._ec_key - ) + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + self._backend.openssl_assert(group != self._backend._ffi.NULL) + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) self._backend.openssl_assert(point != self._backend._ffi.NULL) @@ -244,7 +244,9 @@ def public_numbers(self) -> ec.EllipticCurvePublicNumbers: bn_x = self._backend._lib.BN_CTX_get(bn_ctx) bn_y = self._backend._lib.BN_CTX_get(bn_ctx) - res = get_func(group, point, bn_x, bn_y, bn_ctx) + res = self._backend._lib.EC_POINT_get_affine_coordinates( + group, point, bn_x, bn_y, bn_ctx + ) self._backend.openssl_assert(res == 1) x = self._backend._bn_to_int(bn_x) diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 9d802d3e4e8f..0f9977bc115b 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -5,12 +5,6 @@ import typing -def cryptography_has_ec2m() -> typing.List[str]: - return [ - "EC_POINT_get_affine_coordinates_GF2m", - ] - - def cryptography_has_set_cert_cb() -> typing.List[str]: return [ "SSL_CTX_set_cert_cb", @@ -283,7 +277,6 @@ def cryptography_has_get_extms_support() -> typing.List[str]: # when cffi supports #if in cdef. We use functions instead of just a dict of # lists so we can use coverage to measure which are used. CONDITIONAL_NAMES = { - "Cryptography_HAS_EC2M": cryptography_has_ec2m, "Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb, "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st, "Cryptography_HAS_TLS_ST": cryptography_has_tls_st, From ba46c3a39d9fbccade65c8f7436171cd6f7d9996 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 6 Mar 2023 11:51:20 +0800 Subject: [PATCH 400/827] use the rsa fixtures in x509 too (#8460) * use the rsa fixtures in x509 too * use strings in __all__ --- tests/x509/test_x509.py | 307 +++++++++++++++++++---------- tests/x509/test_x509_crlbuilder.py | 80 +++++--- tests/x509/test_x509_ext.py | 34 ++-- 3 files changed, 271 insertions(+), 150 deletions(-) diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 4ff31205d632..6018b394eae4 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -44,17 +44,20 @@ from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048, DSA_KEY_3072 from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1 from ..hazmat.primitives.fixtures_rsa import ( - RSA_KEY_512, - RSA_KEY_2048, RSA_KEY_2048_ALT, ) from ..hazmat.primitives.test_ec import _skip_curve_unsupported +from ..hazmat.primitives.test_rsa import rsa_key_512, rsa_key_2048 from ..utils import ( load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm, ) +# Make ruff happy since we're importing fixtures that pytest patches in as +# func args +__all__ = ["rsa_key_512", "rsa_key_2048"] + class DummyExtension(x509.ExtensionType): oid = x509.ObjectIdentifier("1.2.3.4") @@ -732,8 +735,10 @@ def test_indexing(self, backend): assert crl[2:4][0].serial_number == crl[2].serial_number assert crl[2:4][1].serial_number == crl[3].serial_number - def test_get_revoked_certificate_doesnt_reorder(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_get_revoked_certificate_doesnt_reorder( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -1536,17 +1541,25 @@ def test_parse_tls_feature_extension(self, backend): [x509.TLSFeatureType.status_request] ) - def test_verify_directly_issued_by_rsa(self): - issuer_private_key = RSA_KEY_2048.private_key() - subject_private_key = RSA_KEY_2048_ALT.private_key() + def test_verify_directly_issued_by_rsa( + self, rsa_key_2048: rsa.RSAPrivateKey + ): + issuer_private_key = rsa_key_2048 + subject_private_key = RSA_KEY_2048_ALT.private_key( + unsafe_skip_rsa_key_validation=True + ) ca, cert = _generate_ca_and_leaf( issuer_private_key, subject_private_key ) cert.verify_directly_issued_by(ca) - def test_verify_directly_issued_by_rsa_bad_sig(self): - issuer_private_key = RSA_KEY_2048.private_key() - subject_private_key = RSA_KEY_2048_ALT.private_key() + def test_verify_directly_issued_by_rsa_bad_sig( + self, rsa_key_2048: rsa.RSAPrivateKey + ): + issuer_private_key = rsa_key_2048 + subject_private_key = RSA_KEY_2048_ALT.private_key( + unsafe_skip_rsa_key_validation=True + ) ca, cert = _generate_ca_and_leaf( issuer_private_key, subject_private_key ) @@ -1581,9 +1594,13 @@ def test_verify_directly_issued_by_subject_issuer_mismatch(self): "Issuer certificate subject does not match certificate issuer." ) - def test_verify_directly_issued_by_algorithm_mismatch(self): - issuer_private_key = RSA_KEY_2048.private_key() - subject_private_key = RSA_KEY_2048_ALT.private_key() + def test_verify_directly_issued_by_algorithm_mismatch( + self, rsa_key_2048: rsa.RSAPrivateKey + ): + issuer_private_key = rsa_key_2048 + subject_private_key = RSA_KEY_2048_ALT.private_key( + unsafe_skip_rsa_key_validation=True + ) _, cert = _generate_ca_and_leaf( issuer_private_key, subject_private_key ) @@ -2045,12 +2062,14 @@ def test_hash(self, backend): (hashes.SHA3_512, x509.SignatureAlgorithmOID.RSA_WITH_SHA3_512), ], ) - def test_build_cert(self, hashalg, hashalg_oid, backend): + def test_build_cert( + self, rsa_key_2048: rsa.RSAPrivateKey, hashalg, hashalg_oid, backend + ): if not backend.signature_hash_supported(hashalg()): pytest.skip(f"{hashalg} signature not supported") - issuer_private_key = RSA_KEY_2048.private_key(backend) - subject_private_key = RSA_KEY_2048.private_key(backend) + issuer_private_key = rsa_key_2048 + subject_private_key = rsa_key_2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) @@ -2124,9 +2143,11 @@ def test_build_cert(self, hashalg, hashalg_oid, backend): x509.DNSName("cryptography.io"), ] - def test_build_cert_private_type_encoding(self, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_build_cert_private_type_encoding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_2048 + subject_private_key = rsa_key_2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) name = x509.Name( @@ -2173,9 +2194,11 @@ def test_build_cert_private_type_encoding(self, backend): == _ASN1Type.UTF8String ) - def test_build_cert_printable_string_country_name(self, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_build_cert_printable_string_country_name( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_2048 + subject_private_key = rsa_key_2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) @@ -2228,8 +2251,10 @@ def test_build_cert_printable_string_country_name(self, backend): class TestCertificateBuilder: - def test_checks_for_unsupported_extensions(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_checks_for_unsupported_extensions( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .subject_name( @@ -2248,8 +2273,10 @@ def test_checks_for_unsupported_extensions(self, backend): with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA256(), backend) - def test_encode_nonstandard_aia(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_encode_nonstandard_aia( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 aia = x509.AuthorityInformationAccess( [ @@ -2277,8 +2304,10 @@ def test_encode_nonstandard_aia(self, backend): builder.sign(private_key, hashes.SHA256(), backend) - def test_encode_nonstandard_sia(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_encode_nonstandard_sia( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 sia = x509.SubjectInformationAccess( [ @@ -2310,8 +2339,10 @@ def test_encode_nonstandard_sia(self, backend): ) assert ext.value == sia - def test_subject_dn_asn1_types(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_subject_dn_asn1_types( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 name = x509.Name( [ @@ -2367,8 +2398,14 @@ def test_subject_dn_asn1_types(self, backend): [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 12, 31)], ], ) - def test_extreme_times(self, not_valid_before, not_valid_after, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_extreme_times( + self, + rsa_key_2048: rsa.RSAPrivateKey, + not_valid_before, + not_valid_after, + backend, + ): + private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .subject_name( @@ -2393,8 +2430,8 @@ def test_extreme_times(self, not_valid_before, not_valid_after, backend): # GENERALIZED TIME assert parsed.not_after_tag == 0x18 - def test_no_subject_name(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_subject_name(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(777) @@ -2408,8 +2445,8 @@ def test_no_subject_name(self, backend): with pytest.raises(ValueError): builder.sign(subject_private_key, hashes.SHA256(), backend) - def test_no_issuer_name(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_issuer_name(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(777) @@ -2423,8 +2460,8 @@ def test_no_issuer_name(self, backend): with pytest.raises(ValueError): builder.sign(subject_private_key, hashes.SHA256(), backend) - def test_no_public_key(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_public_key(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(777) @@ -2440,8 +2477,10 @@ def test_no_public_key(self, backend): with pytest.raises(ValueError): builder.sign(subject_private_key, hashes.SHA256(), backend) - def test_no_not_valid_before(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_not_valid_before( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(777) @@ -2457,8 +2496,10 @@ def test_no_not_valid_before(self, backend): with pytest.raises(ValueError): builder.sign(subject_private_key, hashes.SHA256(), backend) - def test_no_not_valid_after(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_not_valid_after( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(777) @@ -2474,8 +2515,8 @@ def test_no_not_valid_after(self, backend): with pytest.raises(ValueError): builder.sign(subject_private_key, hashes.SHA256(), backend) - def test_no_serial_number(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_no_serial_number(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .issuer_name( @@ -2539,15 +2580,19 @@ def test_not_valid_after_before_not_valid_before(self): with pytest.raises(ValueError): builder.not_valid_after(datetime.datetime(2001, 1, 1, 12, 1)) - def test_public_key_must_be_public_key(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_public_key_must_be_public_key( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = x509.CertificateBuilder() with pytest.raises(TypeError): builder.public_key(private_key) # type: ignore[arg-type] - def test_public_key_may_only_be_set_once(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_public_key_may_only_be_set_once( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 public_key = private_key.public_key() builder = x509.CertificateBuilder().public_key(public_key) @@ -2568,8 +2613,10 @@ def test_serial_number_must_be_positive(self): with pytest.raises(ValueError): x509.CertificateBuilder().serial_number(0) - def test_minimal_serial_number(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_minimal_serial_number( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number(1) @@ -2586,8 +2633,10 @@ def test_minimal_serial_number(self, backend): cert = builder.sign(subject_private_key, hashes.SHA256(), backend) assert cert.serial_number == 1 - def test_biggest_serial_number(self, backend): - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_biggest_serial_number( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + subject_private_key = rsa_key_2048 builder = ( x509.CertificateBuilder() .serial_number((1 << 159) - 1) @@ -2614,11 +2663,13 @@ def test_serial_number_may_only_be_set_once(self): with pytest.raises(ValueError): builder.serial_number(20) - def test_aware_not_valid_after(self, backend): + def test_aware_not_valid_after( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): tz = datetime.timezone(datetime.timedelta(hours=-8)) time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_time = datetime.datetime(2012, 1, 17, 6, 43) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 cert_builder = x509.CertificateBuilder().not_valid_after(time) cert_builder = ( cert_builder.subject_name( @@ -2635,9 +2686,9 @@ def test_aware_not_valid_after(self, backend): cert = cert_builder.sign(private_key, hashes.SHA256(), backend) assert cert.not_valid_after == utc_time - def test_earliest_time(self, backend): + def test_earliest_time(self, rsa_key_2048: rsa.RSAPrivateKey, backend): time = datetime.datetime(1950, 1, 1) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 cert_builder = ( x509.CertificateBuilder() .subject_name( @@ -2685,11 +2736,13 @@ def test_not_valid_after_may_only_be_set_once(self): with pytest.raises(ValueError): builder.not_valid_after(datetime.datetime.now()) - def test_aware_not_valid_before(self, backend): + def test_aware_not_valid_before( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): tz = datetime.timezone(datetime.timedelta(hours=-8)) time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_time = datetime.datetime(2012, 1, 17, 6, 43) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 cert_builder = x509.CertificateBuilder().not_valid_before(time) cert_builder = ( cert_builder.subject_name( @@ -2752,8 +2805,10 @@ def test_add_invalid_extension_type(self): ) @pytest.mark.parametrize("algorithm", [object(), None]) - def test_sign_with_unsupported_hash(self, algorithm, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_with_unsupported_hash( + self, rsa_key_2048: rsa.RSAPrivateKey, algorithm, backend + ): + private_key = rsa_key_2048 builder = x509.CertificateBuilder() builder = ( builder.subject_name( @@ -3015,8 +3070,10 @@ def test_build_cert_with_ec_private_key( x509.DNSName("cryptography.io"), ] - def test_build_cert_with_bmpstring_universalstring_name(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_cert_with_bmpstring_universalstring_name( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 issuer = x509.Name( [ x509.NameAttribute( @@ -3113,8 +3170,10 @@ def test_build_cert_with_ed25519(self, backend): only_if=lambda backend: backend.ed25519_supported(), skip_message="Requires OpenSSL with Ed25519 support", ) - def test_build_cert_with_public_ed25519_rsa_sig(self, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) + def test_build_cert_with_public_ed25519_rsa_sig( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_2048 subject_private_key = ed25519.Ed25519PrivateKey.generate() not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) @@ -3211,8 +3270,10 @@ def test_build_cert_with_ed448(self, backend): only_if=lambda backend: backend.ed448_supported(), skip_message="Requires OpenSSL with Ed448 support", ) - def test_build_cert_with_public_ed448_rsa_sig(self, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) + def test_build_cert_with_public_ed448_rsa_sig( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_2048 subject_private_key = ed448.Ed448PrivateKey.generate() not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) @@ -3260,9 +3321,13 @@ def test_build_cert_with_public_ed448_rsa_sig(self, backend): ], ) def test_build_cert_with_public_x25519_x448_rsa_sig( - self, priv_key_cls, pub_key_cls, backend + self, + rsa_key_2048: rsa.RSAPrivateKey, + priv_key_cls, + pub_key_cls, + backend, ): - issuer_private_key = RSA_KEY_2048.private_key(backend) + issuer_private_key = rsa_key_2048 subject_private_key = priv_key_cls.generate() not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) @@ -3296,9 +3361,11 @@ def test_build_cert_with_public_x25519_x448_rsa_sig( assert isinstance(cert.signature_hash_algorithm, hashes.SHA256) assert isinstance(cert.public_key(), pub_key_cls) - def test_build_cert_with_rsa_key_too_small(self, backend): - issuer_private_key = RSA_KEY_512.private_key(backend) - subject_private_key = RSA_KEY_512.private_key(backend) + def test_build_cert_with_rsa_key_too_small( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_512 + subject_private_key = rsa_key_512 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) @@ -3765,9 +3832,11 @@ def test_build_cert_with_rsa_key_too_small(self, backend): x509.SubjectKeyIdentifier, ], ) - def test_extensions(self, add_ext, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_extensions( + self, rsa_key_2048: rsa.RSAPrivateKey, add_ext, backend + ): + issuer_private_key = rsa_key_2048 + subject_private_key = rsa_key_2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) @@ -3811,8 +3880,10 @@ def test_extensions(self, add_ext, backend): assert ext.critical is False assert ext.value == add_ext - def test_build_ca_request_with_path_length_none(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_ca_request_with_path_length_none( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 request = ( x509.CertificateSigningRequestBuilder() @@ -3847,8 +3918,10 @@ def test_build_ca_request_with_path_length_none(self, backend): ) ], ) - def test_unrecognized_extension(self, backend, unrecognized): - private_key = RSA_KEY_2048.private_key(backend) + def test_unrecognized_extension( + self, rsa_key_2048: rsa.RSAPrivateKey, backend, unrecognized + ): + private_key = rsa_key_2048 cert = ( x509.CertificateBuilder() @@ -3872,8 +3945,10 @@ def test_unrecognized_extension(self, backend, unrecognized): class TestCertificateSigningRequestBuilder: - def test_sign_invalid_hash_algorithm(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_invalid_hash_algorithm( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = x509.CertificateSigningRequestBuilder().subject_name( x509.Name([]) @@ -3909,15 +3984,17 @@ def test_request_with_unsupported_hash_ed448(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_no_subject_name(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_no_subject_name(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 builder = x509.CertificateSigningRequestBuilder() with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_build_ca_request_with_rsa(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_ca_request_with_rsa( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 request = ( x509.CertificateSigningRequestBuilder() @@ -3947,8 +4024,10 @@ def test_build_ca_request_with_rsa(self, backend): assert basic_constraints.value.ca is True assert basic_constraints.value.path_length == 2 - def test_build_ca_request_with_unicode(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_ca_request_with_unicode( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 request = ( x509.CertificateSigningRequestBuilder() @@ -3976,8 +4055,10 @@ def test_build_ca_request_with_unicode(self, backend): x509.NameAttribute(NameOID.ORGANIZATION_NAME, "PyCA\U0001f37a"), ] - def test_subject_dn_asn1_types(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_subject_dn_asn1_types( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 request = ( x509.CertificateSigningRequestBuilder() @@ -4034,8 +4115,10 @@ def test_subject_dn_asn1_types(self, backend): == asn1_type ) - def test_build_ca_request_with_multivalue_rdns(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_ca_request_with_multivalue_rdns( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 subject = x509.Name( [ x509.RelativeDistinguishedName( @@ -4063,8 +4146,10 @@ def test_build_ca_request_with_multivalue_rdns(self, backend): assert isinstance(loaded_request.subject, x509.Name) assert loaded_request.subject == subject - def test_build_nonca_request_with_rsa(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_build_nonca_request_with_rsa( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 request = ( x509.CertificateSigningRequestBuilder() @@ -4269,8 +4354,10 @@ def test_add_invalid_extension_type(self): False, ) - def test_add_unsupported_extension(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_add_unsupported_extension( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = x509.CertificateSigningRequestBuilder() builder = ( builder.subject_name( @@ -4285,8 +4372,10 @@ def test_add_unsupported_extension(self, backend): with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA256(), backend) - def test_add_two_extensions(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_add_two_extensions( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = x509.CertificateSigningRequestBuilder() request = ( builder.subject_name( @@ -4521,8 +4610,10 @@ def test_set_subject_twice(self): ), ], ) - def test_extensions(self, add_ext, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_extensions( + self, rsa_key_2048: rsa.RSAPrivateKey, add_ext, backend + ): + private_key = rsa_key_2048 csr = ( x509.CertificateSigningRequestBuilder() @@ -4541,8 +4632,10 @@ def test_extensions(self, add_ext, backend): assert not ext.critical assert ext.value == add_ext - def test_invalid_asn1_othername(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_invalid_asn1_othername( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = ( x509.CertificateSigningRequestBuilder() @@ -4565,8 +4658,10 @@ def test_invalid_asn1_othername(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_subject_alt_name_unsupported_general_name(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_subject_alt_name_unsupported_general_name( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 builder = ( x509.CertificateSigningRequestBuilder() @@ -4582,8 +4677,8 @@ def test_subject_alt_name_unsupported_general_name(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_rsa_key_too_small(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_rsa_key_too_small(self, rsa_key_512: rsa.RSAPrivateKey, backend): + private_key = rsa_key_512 builder = x509.CertificateSigningRequestBuilder() builder = builder.subject_name( x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) @@ -5687,9 +5782,9 @@ def load_key(self, backend): param = params.parameters(backend) return param.generate_private_key() - def test_crt_signing_check(self, backend): + def test_crt_signing_check(self, rsa_key_2048: rsa.RSAPrivateKey, backend): issuer_private_key = self.load_key(backend) - public_key = RSA_KEY_2048.private_key(backend).public_key() + public_key = rsa_key_2048.public_key() not_valid_before = datetime.datetime(2020, 1, 1, 1, 1) not_valid_after = datetime.datetime(2050, 12, 31, 8, 30) builder = ( diff --git a/tests/x509/test_x509_crlbuilder.py b/tests/x509/test_x509_crlbuilder.py index 7ca4f4282913..8633f8abba22 100644 --- a/tests/x509/test_x509_crlbuilder.py +++ b/tests/x509/test_x509_crlbuilder.py @@ -10,7 +10,7 @@ from cryptography import x509 from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import ec, ed448, ed25519 +from cryptography.hazmat.primitives.asymmetric import ec, ed448, ed25519, rsa from cryptography.x509.oid import ( AuthorityInformationAccessOID, NameOID, @@ -19,10 +19,14 @@ from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048 from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1 -from ..hazmat.primitives.fixtures_rsa import RSA_KEY_512, RSA_KEY_2048 from ..hazmat.primitives.test_ec import _skip_curve_unsupported +from ..hazmat.primitives.test_rsa import rsa_key_512, rsa_key_2048 from .test_x509 import DummyExtension +# Make ruff happy since we're importing fixtures that pytest patches in as +# func args +__all__ = ["rsa_key_512", "rsa_key_2048"] + class TestCertificateRevocationListBuilder: def test_issuer_name_invalid(self): @@ -39,12 +43,12 @@ def test_set_issuer_name_twice(self): x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) ) - def test_aware_last_update(self, backend): + def test_aware_last_update(self, rsa_key_2048: rsa.RSAPrivateKey, backend): tz = datetime.timezone(datetime.timedelta(hours=-8)) last_time = datetime.datetime(2012, 1, 16, 22, 43, tzinfo=tz) utc_last = datetime.datetime(2012, 1, 17, 6, 43) next_time = datetime.datetime(2022, 1, 17, 6, 43) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 builder = ( x509.CertificateRevocationListBuilder() .issuer_name( @@ -80,12 +84,12 @@ def test_set_last_update_twice(self): with pytest.raises(ValueError): builder.last_update(datetime.datetime(2002, 1, 1, 12, 1)) - def test_aware_next_update(self, backend): + def test_aware_next_update(self, rsa_key_2048: rsa.RSAPrivateKey, backend): tz = datetime.timezone(datetime.timedelta(hours=-8)) next_time = datetime.datetime(2022, 1, 16, 22, 43, tzinfo=tz) utc_next = datetime.datetime(2022, 1, 17, 6, 43) last_time = datetime.datetime(2012, 1, 17, 6, 43) - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 builder = ( x509.CertificateRevocationListBuilder() .issuer_name( @@ -155,8 +159,8 @@ def test_add_invalid_revoked_certificate(self): with pytest.raises(TypeError): builder.add_revoked_certificate(object()) # type:ignore[arg-type] - def test_no_issuer_name(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_no_issuer_name(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 builder = ( x509.CertificateRevocationListBuilder() .last_update(datetime.datetime(2002, 1, 1, 12, 1)) @@ -166,8 +170,8 @@ def test_no_issuer_name(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_no_last_update(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_no_last_update(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 builder = ( x509.CertificateRevocationListBuilder() .issuer_name( @@ -179,8 +183,8 @@ def test_no_last_update(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_no_next_update(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_no_next_update(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 builder = ( x509.CertificateRevocationListBuilder() .issuer_name( @@ -192,8 +196,8 @@ def test_no_next_update(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) - def test_sign_empty_list(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_empty_list(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -240,8 +244,10 @@ def test_sign_empty_list(self, backend): ), ], ) - def test_sign_extensions(self, backend, extension): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_extensions( + self, rsa_key_2048: rsa.RSAPrivateKey, backend, extension + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -267,8 +273,10 @@ def test_sign_extensions(self, backend, extension): assert ext.critical is False assert ext.value == extension - def test_sign_multiple_extensions_critical(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_multiple_extensions_critical( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) ian = x509.IssuerAlternativeName( @@ -304,8 +312,10 @@ def test_sign_multiple_extensions_critical(self, backend): assert ext2.critical is True assert ext2.value == ian - def test_freshestcrl_extension(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_freshestcrl_extension( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) freshest = x509.FreshestCRL( @@ -346,8 +356,10 @@ def test_freshestcrl_extension(self, backend): assert isinstance(uri, x509.UniformResourceIdentifier) assert uri.value == "http://d.om/delta" - def test_add_unsupported_extension(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_add_unsupported_extension( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -368,8 +380,10 @@ def test_add_unsupported_extension(self, backend): with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA256(), backend) - def test_add_unsupported_entry_extension(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_add_unsupported_entry_extension( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -396,8 +410,10 @@ def test_add_unsupported_entry_extension(self, backend): with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA256(), backend) - def test_sign_rsa_key_too_small(self, backend): - private_key = RSA_KEY_512.private_key(backend) + def test_sign_rsa_key_too_small( + self, rsa_key_512: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_512 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -418,8 +434,10 @@ def test_sign_rsa_key_too_small(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA512(), backend) - def test_sign_with_invalid_hash(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_with_invalid_hash( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -760,8 +778,10 @@ def test_ec_key_sign_md5(self, backend): private_key, hashes.MD5(), backend # type: ignore[arg-type] ) - def test_sign_with_revoked_certificates(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_sign_with_revoked_certificates( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + private_key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) invalidity_date = x509.InvalidityDate( diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py index 63d15efc4083..1368ffdf815a 100644 --- a/tests/x509/test_x509_ext.py +++ b/tests/x509/test_x509_ext.py @@ -36,11 +36,15 @@ SubjectInformationAccessOID, ) -from ..hazmat.primitives.fixtures_rsa import RSA_KEY_2048 from ..hazmat.primitives.test_ec import _skip_curve_unsupported +from ..hazmat.primitives.test_rsa import rsa_key_2048 from ..utils import load_vectors_from_file from .test_x509 import _load_cert +# Make ruff happy since we're importing fixtures that pytest patches in as +# func args +__all__ = ["rsa_key_2048"] + def _make_certbuilder(private_key): name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "example.org")]) @@ -800,9 +804,11 @@ def test_user_notice_no_explicit_text(self, backend): ] ) - def test_non_ascii_qualifier(self, backend): - issuer_private_key = RSA_KEY_2048.private_key(backend) - subject_private_key = RSA_KEY_2048.private_key(backend) + def test_non_ascii_qualifier( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + issuer_private_key = rsa_key_2048 + subject_private_key = rsa_key_2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) @@ -2715,13 +2721,13 @@ def test_other_name(self, backend): othernames = ext.value.get_values_for_type(x509.OtherName) assert othernames == [expected] - def test_certbuilder(self, backend): + def test_certbuilder(self, rsa_key_2048: rsa.RSAPrivateKey, backend): sans = [ "*.example.org", "*.xn--4ca7aey.example.com", "foobar.example.net", ] - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 builder = _make_certbuilder(private_key) builder = builder.add_extension( SubjectAlternativeName(list(map(DNSName, sans))), True @@ -3927,13 +3933,13 @@ def test_invalid_ipv4_netmask(self, backend): ExtensionOID.NAME_CONSTRAINTS ) - def test_certbuilder(self, backend): + def test_certbuilder(self, rsa_key_2048: rsa.RSAPrivateKey, backend): permitted = [ ".example.org", ".xn--4ca7aey.example.com", "foobar.example.net", ] - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 builder = _make_certbuilder(private_key) builder = builder.add_extension( NameConstraints( @@ -5685,8 +5691,8 @@ def test_hash(self): ), ], ) - def test_generate(self, idp, backend): - key = RSA_KEY_2048.private_key(backend) + def test_generate(self, rsa_key_2048: rsa.RSAPrivateKey, idp, backend): + key = rsa_key_2048 last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( @@ -5751,8 +5757,8 @@ def test_load(self, backend): ).value assert isinstance(poison, x509.PrecertPoison) - def test_generate(self, backend): - private_key = RSA_KEY_2048.private_key(backend) + def test_generate(self, rsa_key_2048: rsa.RSAPrivateKey, backend): + private_key = rsa_key_2048 cert = ( _make_certbuilder(private_key) .add_extension(x509.PrecertPoison(), critical=True) @@ -6087,7 +6093,7 @@ def test_simple(self, backend): ) assert sct.extension_bytes == b"" - def test_generate(self, backend): + def test_generate(self, rsa_key_2048: rsa.RSAPrivateKey, backend): cert = _load_cert( os.path.join("x509", "badssl-sct.pem"), x509.load_pem_x509_certificate, @@ -6099,7 +6105,7 @@ def test_generate(self, backend): assert len(scts) == 1 [sct] = scts - private_key = RSA_KEY_2048.private_key(backend) + private_key = rsa_key_2048 builder = _make_certbuilder(private_key).add_extension( x509.PrecertificateSignedCertificateTimestamps([sct]), critical=False, From 0b2d648a4da183a1611a729207f64090fa74628e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 6 Mar 2023 13:05:46 +0800 Subject: [PATCH 401/827] remove memleak tests for x509 paths that no longer use openssl (#8461) --- tests/hazmat/backends/test_openssl_memleak.py | 162 ------------------ 1 file changed, 162 deletions(-) diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index b124582b6a50..6ffe1a40635a 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -268,30 +268,6 @@ def func(): @pytest.mark.skip_fips(reason="FIPS self-test sets allow_customize = 0") @skip_if_memtesting_not_supported() class TestOpenSSLMemoryLeaks: - def test_x509_csr_extensions(self): - assert_no_memory_leaks( - textwrap.dedent( - """ - def func(): - from cryptography import x509 - from cryptography.hazmat.backends.openssl import backend - from cryptography.hazmat.primitives import hashes - from cryptography.hazmat.primitives.asymmetric import rsa - - private_key = rsa.generate_private_key( - key_size=2048, public_exponent=65537, backend=backend - ) - cert = x509.CertificateSigningRequestBuilder().subject_name( - x509.Name([]) - ).add_extension( - x509.OCSPNoCheck(), critical=False - ).sign(private_key, hashes.SHA256(), backend) - - cert.extensions - """ - ) - ) - def test_ec_private_numbers_private_key(self): assert_no_memory_leaks( textwrap.dedent( @@ -345,31 +321,6 @@ def func(): ) ) - def test_create_ocsp_request(self): - assert_no_memory_leaks( - textwrap.dedent( - """ - def func(): - from cryptography import x509 - from cryptography.hazmat.backends.openssl import backend - from cryptography.hazmat.primitives import hashes - from cryptography.x509 import ocsp - import cryptography_vectors - - path = "x509/PKITS_data/certs/ValidcRLIssuerTest28EE.crt" - with cryptography_vectors.open_vector_file(path, "rb") as f: - cert = x509.load_der_x509_certificate( - f.read(), backend - ) - builder = ocsp.OCSPRequestBuilder() - builder = builder.add_certificate( - cert, cert, hashes.SHA1() - ).add_extension(x509.OCSPNonce(b"0000"), False) - req = builder.build() - """ - ) - ) - @pytest.mark.parametrize( "path", ["pkcs12/cert-aes256cbc-no-key.p12", "pkcs12/cert-key-aes256cbc.p12"], @@ -393,119 +344,6 @@ def func(path): [path], ) - def test_create_crl_with_idp(self): - assert_no_memory_leaks( - textwrap.dedent( - """ - def func(): - import datetime - from cryptography import x509 - from cryptography.hazmat.backends.openssl import backend - from cryptography.hazmat.primitives import hashes - from cryptography.hazmat.primitives.asymmetric import ec - from cryptography.x509.oid import NameOID - - key = ec.generate_private_key(ec.SECP256R1(), backend) - last_update = datetime.datetime(2002, 1, 1, 12, 1) - next_update = datetime.datetime(2030, 1, 1, 12, 1) - idp = x509.IssuingDistributionPoint( - full_name=None, - relative_name=x509.RelativeDistinguishedName([ - x509.NameAttribute( - oid=x509.NameOID.ORGANIZATION_NAME, value=u"PyCA") - ]), - only_contains_user_certs=False, - only_contains_ca_certs=True, - only_some_reasons=None, - indirect_crl=False, - only_contains_attribute_certs=False, - ) - builder = x509.CertificateRevocationListBuilder().issuer_name( - x509.Name([ - x509.NameAttribute( - NameOID.COMMON_NAME, u"cryptography.io CA" - ) - ]) - ).last_update( - last_update - ).next_update( - next_update - ).add_extension( - idp, True - ) - - crl = builder.sign(key, hashes.SHA256(), backend) - crl.extensions.get_extension_for_class( - x509.IssuingDistributionPoint - ) - """ - ) - ) - - def test_create_certificate_with_extensions(self): - assert_no_memory_leaks( - textwrap.dedent( - """ - def func(): - import datetime - - from cryptography import x509 - from cryptography.hazmat.backends.openssl import backend - from cryptography.hazmat.primitives import hashes - from cryptography.hazmat.primitives.asymmetric import ec - from cryptography.x509.oid import ( - AuthorityInformationAccessOID, ExtendedKeyUsageOID, NameOID - ) - - private_key = ec.generate_private_key(ec.SECP256R1(), backend) - - not_valid_before = datetime.datetime.now() - not_valid_after = not_valid_before + datetime.timedelta(days=365) - - aia = x509.AuthorityInformationAccess([ - x509.AccessDescription( - AuthorityInformationAccessOID.OCSP, - x509.UniformResourceIdentifier(u"http://ocsp.domain.com") - ), - x509.AccessDescription( - AuthorityInformationAccessOID.CA_ISSUERS, - x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") - ) - ]) - sans = [u'*.example.org', u'foobar.example.net'] - san = x509.SubjectAlternativeName(list(map(x509.DNSName, sans))) - - ski = x509.SubjectKeyIdentifier.from_public_key( - private_key.public_key() - ) - eku = x509.ExtendedKeyUsage([ - ExtendedKeyUsageOID.CLIENT_AUTH, - ExtendedKeyUsageOID.SERVER_AUTH, - ExtendedKeyUsageOID.CODE_SIGNING, - ]) - - builder = x509.CertificateBuilder().serial_number( - 777 - ).issuer_name(x509.Name([ - x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'), - ])).subject_name(x509.Name([ - x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'), - ])).public_key( - private_key.public_key() - ).add_extension( - aia, critical=False - ).not_valid_before( - not_valid_before - ).not_valid_after( - not_valid_after - ) - - cert = builder.sign(private_key, hashes.SHA256(), backend) - cert.extensions - """ - ) - ) - def test_write_pkcs12_key_and_certificates(self): assert_no_memory_leaks( textwrap.dedent( From a28ad12125e2a269f5754c782e1a6e154eb29274 Mon Sep 17 00:00:00 2001 From: Marty Hill Date: Mon, 6 Mar 2023 07:26:20 -0600 Subject: [PATCH 402/827] Update serialization.rst (#8464) Proposed update to parameter in example call to pkcs12.serialize_key_and_certificates() on line 908. --- docs/hazmat/primitives/asymmetric/serialization.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 6a9d7c1987a8..ca33c156e429 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -905,7 +905,7 @@ file suffix. >>> cert = x509.load_pem_x509_certificate(ca_cert) >>> key = load_pem_private_key(ca_key, None) >>> p12 = pkcs12.serialize_key_and_certificates( - ... b"friendlyname", key, None, None, encryption + ... b"friendlyname", key, cert, None, encryption ... ) .. class:: PKCS12Certificate From 1b318af4726d75bb8d65a834c9f7325850f6320f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 13:39:51 +0000 Subject: [PATCH 403/827] Bump charset-normalizer from 3.0.1 to 3.1.0 (#8465) Bumps [charset-normalizer](https://github.com/Ousret/charset_normalizer) from 3.0.1 to 3.1.0. - [Release notes](https://github.com/Ousret/charset_normalizer/releases) - [Changelog](https://github.com/Ousret/charset_normalizer/blob/master/CHANGELOG.md) - [Commits](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) --- updated-dependencies: - dependency-name: charset-normalizer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e95ebddcb75c..d77e5e9b87e9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -25,7 +25,7 @@ certifi==2022.12.7 # via requests chardet==5.1.0 # via tox -charset-normalizer==3.0.1; python_version >= "3.7" +charset-normalizer==3.1.0; python_version >= "3.7" # via requests check-manifest==0.49 # via cryptography (setup.cfg) From fe91d4e68f8744132374358497fceccd39ecb401 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Mar 2023 17:04:08 -0500 Subject: [PATCH 404/827] Remove a zillion pointless backenda args in x509 tests (#8466) --- tests/x509/test_ocsp.py | 7 -- tests/x509/test_x509.py | 170 +++--------------------------------- tests/x509/test_x509_ext.py | 107 ----------------------- 3 files changed, 12 insertions(+), 272 deletions(-) diff --git a/tests/x509/test_ocsp.py b/tests/x509/test_ocsp.py index 0b0bc861acff..fd8bbfc1babe 100644 --- a/tests/x509/test_ocsp.py +++ b/tests/x509/test_ocsp.py @@ -28,17 +28,13 @@ def _load_data(filename, loader): def _cert_and_issuer(): - from cryptography.hazmat.backends.openssl.backend import backend - cert = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) issuer = _load_cert( os.path.join("x509", "rapidssl_sha256_ca_g3.pem"), x509.load_pem_x509_certificate, - backend, ) return cert, issuer @@ -1046,12 +1042,9 @@ def test_load_response(self): os.path.join("x509", "ocsp", "resp-sha256.der"), ocsp.load_der_ocsp_response, ) - from cryptography.hazmat.backends.openssl.backend import backend - issuer = _load_cert( os.path.join("x509", "letsencryptx3.pem"), x509.load_pem_x509_certificate, - backend, ) assert resp.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL assert ( diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 6018b394eae4..9d4208c65afc 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -75,13 +75,12 @@ def value(self): T = typing.TypeVar("T") -def _load_cert(filename, loader: typing.Callable[..., T], backend=None) -> T: - cert = load_vectors_from_file( +def _load_cert(filename, loader: typing.Callable[..., T]) -> T: + return load_vectors_from_file( filename=filename, - loader=lambda pemfile: loader(pemfile.read(), backend), + loader=lambda pemfile: loader(pemfile.read()), mode="rb", ) - return cert def _generate_ca_and_leaf( @@ -141,7 +140,6 @@ def test_load_pem_crl(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) assert isinstance(crl, x509.CertificateRevocationList) @@ -157,7 +155,6 @@ def test_load_der_crl(self, backend): crl = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) assert isinstance(crl, x509.CertificateRevocationList) @@ -169,7 +166,6 @@ def test_load_large_crl(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_almost_10k.pem"), x509.load_pem_x509_crl, - backend, ) assert len(crl) == 9999 @@ -179,7 +175,6 @@ def test_empty_crl_no_sequence(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_empty_no_sequence.der"), x509.load_der_x509_crl, - backend, ) assert len(crl) == 0 @@ -194,8 +189,7 @@ def test_invalid_pem(self, backend): pem_bytes = _load_cert( os.path.join("x509", "custom", "valid_signature_cert.pem"), - lambda data, backend: data, - backend, + lambda data: data, ) with pytest.raises(ValueError): x509.load_pem_x509_crl(pem_bytes, backend) @@ -209,7 +203,6 @@ def test_invalid_time(self, backend): _load_cert( os.path.join("x509", "custom", "crl_invalid_time.der"), x509.load_der_x509_crl, - backend, ) def test_unknown_signature_algorithm(self, backend): @@ -218,7 +211,6 @@ def test_unknown_signature_algorithm(self, backend): "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem" ), x509.load_pem_x509_crl, - backend, ) with raises_unsupported_algorithm(None): @@ -229,14 +221,12 @@ def test_invalid_version(self, backend): _load_cert( os.path.join("x509", "custom", "crl_bad_version.pem"), x509.load_pem_x509_crl, - backend, ) def test_issuer(self, backend): crl = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) assert isinstance(crl.issuer, x509.Name) @@ -255,19 +245,16 @@ def test_equality(self, backend): crl1 = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) crl2 = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) crl3 = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) assert crl1 == crl2 @@ -278,7 +265,6 @@ def test_comparison(self, backend): crl1 = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) with pytest.raises(TypeError): crl1 < crl1 # type: ignore[operator] @@ -287,7 +273,6 @@ def test_update_dates(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) assert isinstance(crl.next_update, datetime.datetime) @@ -300,7 +285,6 @@ def test_no_next_update(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_no_next_update.pem"), x509.load_pem_x509_crl, - backend, ) assert crl.next_update is None @@ -308,7 +292,6 @@ def test_unrecognized_extension(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_unrecognized_extension.der"), x509.load_der_x509_crl, - backend, ) unrecognized = x509.UnrecognizedExtension( x509.ObjectIdentifier("1.2.3.4.5"), @@ -321,7 +304,6 @@ def test_revoked_cert_retrieval(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) for r in crl: @@ -340,7 +322,6 @@ def test_get_revoked_certificate_by_serial_number(self, backend): "x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl" ), x509.load_der_x509_crl, - backend, ) serial_number = 725064303890588110203033396814564464046290047507 revoked = crl.get_revoked_certificate_by_serial_number(serial_number) @@ -357,7 +338,6 @@ def test_revoked_cert_retrieval_retain_only_revoked(self, backend): revoked = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, )[11] assert revoked.revocation_date == datetime.datetime(2015, 1, 1, 0, 0) assert revoked.serial_number == 11 @@ -366,7 +346,6 @@ def test_extensions(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_ian_aia_aki.pem"), x509.load_pem_x509_crl, - backend, ) crl_number = crl.extensions.get_extension_for_oid( @@ -404,7 +383,6 @@ def test_delta_crl_indicator(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_delta_crl_indicator.pem"), x509.load_pem_x509_crl, - backend, ) dci = crl.extensions.get_extension_for_oid( @@ -417,7 +395,6 @@ def test_signature(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) assert crl.signature == binascii.unhexlify( @@ -436,13 +413,11 @@ def test_tbs_certlist_bytes(self, backend): crl = _load_cert( os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), x509.load_der_x509_crl, - backend, ) ca_cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) public_key = ca_cert.public_key() @@ -459,7 +434,6 @@ def test_public_bytes_pem(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_empty.pem"), x509.load_pem_x509_crl, - backend, ) # Encode it to PEM and load it back. @@ -467,7 +441,6 @@ def test_public_bytes_pem(self, backend): crl.public_bytes( encoding=serialization.Encoding.PEM, ), - backend, ) assert len(crl) == 0 @@ -478,7 +451,6 @@ def test_public_bytes_der(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) # Encode it to DER and load it back. @@ -486,7 +458,6 @@ def test_public_bytes_der(self, backend): crl.public_bytes( encoding=serialization.Encoding.DER, ), - backend, ) assert len(crl) == 12 @@ -522,7 +493,6 @@ def test_public_bytes_invalid_encoding(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_empty.pem"), x509.load_pem_x509_crl, - backend, ) with pytest.raises(TypeError): @@ -532,12 +502,10 @@ def test_verify_bad(self, backend): crl = _load_cert( os.path.join("x509", "custom", "invalid_signature_crl.pem"), x509.load_pem_x509_crl, - backend, ) crt = _load_cert( os.path.join("x509", "custom", "invalid_signature_cert.pem"), x509.load_pem_x509_certificate, - backend, ) public_key = crt.public_key() @@ -547,7 +515,6 @@ def test_verify_bad(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_inner_outer_mismatch.der"), x509.load_der_x509_crl, - backend, ) assert not crl.is_signature_valid(public_key) @@ -555,12 +522,10 @@ def test_verify_good(self, backend): crl = _load_cert( os.path.join("x509", "custom", "valid_signature_crl.pem"), x509.load_pem_x509_crl, - backend, ) crt = _load_cert( os.path.join("x509", "custom", "valid_signature_cert.pem"), x509.load_pem_x509_certificate, - backend, ) public_key = crt.public_key() @@ -571,7 +536,6 @@ def test_verify_argument_must_be_a_public_key(self, backend): crl = _load_cert( os.path.join("x509", "custom", "valid_signature_crl.pem"), x509.load_pem_x509_crl, - backend, ) with pytest.raises(TypeError): @@ -588,7 +552,6 @@ def test_revoked_basics(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) for i, rev in enumerate(crl): @@ -604,7 +567,6 @@ def test_revoked_extensions(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) exp_issuer = [ @@ -667,7 +629,6 @@ def test_no_revoked_certs(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_empty.pem"), x509.load_pem_x509_crl, - backend, ) assert len(crl) == 0 @@ -675,7 +636,6 @@ def test_duplicate_entry_ext(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_dup_entry_ext.pem"), x509.load_pem_x509_crl, - backend, ) with pytest.raises(x509.DuplicateExtension): @@ -687,7 +647,6 @@ def test_unsupported_crit_entry_ext(self, backend): "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem" ), x509.load_pem_x509_crl, - backend, ) ext = crl[0].extensions.get_extension_for_oid( @@ -700,7 +659,6 @@ def test_unsupported_reason(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_unsupported_reason.pem"), x509.load_pem_x509_crl, - backend, ) with pytest.raises(ValueError): @@ -712,7 +670,6 @@ def test_invalid_cert_issuer_ext(self, backend): "x509", "custom", "crl_inval_cert_issuer_entry_ext.pem" ), x509.load_pem_x509_crl, - backend, ) with pytest.raises(ValueError): @@ -722,7 +679,6 @@ def test_indexing(self, backend): crl = _load_cert( os.path.join("x509", "custom", "crl_all_reasons.pem"), x509.load_pem_x509_crl, - backend, ) with pytest.raises(IndexError): @@ -786,13 +742,11 @@ def test_load_cert_pub_key(self, backend): cert = _load_cert( os.path.join("x509", "custom", "rsa_pss_cert.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) expected_pub_key = _load_cert( os.path.join("asymmetric", "PKCS8", "rsa_pss_2048_pub.der"), serialization.load_der_public_key, - backend, ) assert isinstance(expected_pub_key, rsa.RSAPublicKey) pub_key = cert.public_key() @@ -805,7 +759,6 @@ def test_load_pem_cert(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) assert cert.serial_number == 11559813051657483483 @@ -820,7 +773,6 @@ def test_load_legacy_pem_header(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.old_header.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) @@ -828,14 +780,12 @@ def test_load_with_other_sections(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.with_garbage.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) cert = _load_cert( os.path.join("x509", "cryptography.io.with_headers.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) @@ -846,12 +796,10 @@ def test_load_multiple_sections(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.chain.pem"), x509.load_pem_x509_certificate, - backend, ) cert2 = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert == cert2 @@ -862,7 +810,6 @@ def test_negative_serial_number(self, backend): cert = _load_cert( os.path.join("x509", "custom", "negative_serial.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.warns(utils.DeprecatedIn36): @@ -872,7 +819,6 @@ def test_country_jurisdiction_country_too_long(self, backend): cert = _load_cert( os.path.join("x509", "custom", "bad_country.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.warns(UserWarning): assert ( @@ -894,7 +840,6 @@ def test_alternate_rsa_with_sha1_oid(self, backend): cert = _load_cert( os.path.join("x509", "custom", "alternate-rsa-sha1-oid.der"), x509.load_der_x509_certificate, - backend, ) assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) assert ( @@ -906,7 +851,6 @@ def test_load_bmpstring_explicittext(self, backend): cert = _load_cert( os.path.join("x509", "accvraiz1.pem"), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions.get_extension_for_class(x509.CertificatePolicies) et = ext.value[0].policy_qualifiers[0].explicit_text @@ -920,7 +864,6 @@ def test_load_der_cert(self, backend): cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) assert isinstance(cert, x509.Certificate) assert cert.serial_number == 2 @@ -932,7 +875,6 @@ def test_signature(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.signature == binascii.unhexlify( b"8e0f72fcbebe4755abcaf76c8ce0bae17cde4db16291638e1b1ce04a93cdb4c" @@ -959,7 +901,6 @@ def test_tbs_certificate_bytes(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.tbs_certificate_bytes == binascii.unhexlify( b"308202d8a003020102020900a06cb4b955f7f4db300d06092a864886f70d010" @@ -1001,7 +942,6 @@ def test_tbs_precertificate_bytes_no_extensions_raises(self, backend): cert = _load_cert( os.path.join("x509", "v1_cert.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.raises( @@ -1014,7 +954,6 @@ def test_tbs_precertificate_bytes_missing_extension_raises(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) # This cert doesn't have an SCT list extension, so it will throw a @@ -1029,7 +968,6 @@ def test_tbs_precertificate_bytes_strips_scts(self, backend): cert = _load_cert( os.path.join("x509", "cryptography-scts.pem"), x509.load_pem_x509_certificate, - backend, ) expected_tbs_precertificate_bytes = load_vectors_from_file( @@ -1051,7 +989,6 @@ def test_issuer(self, backend): "Validpre2000UTCnotBeforeDateTest3EE.crt", ), x509.load_der_x509_certificate, - backend, ) issuer = cert.issuer assert isinstance(issuer, x509.Name) @@ -1070,7 +1007,6 @@ def test_all_issuer_name_types(self, backend): cert = _load_cert( os.path.join("x509", "custom", "all_supported_names.pem"), x509.load_pem_x509_certificate, - backend, ) issuer = cert.issuer @@ -1117,7 +1053,6 @@ def test_subject(self, backend): "Validpre2000UTCnotBeforeDateTest3EE.crt", ), x509.load_der_x509_certificate, - backend, ) subject = cert.subject assert isinstance(subject, x509.Name) @@ -1142,7 +1077,6 @@ def test_unicode_name(self, backend): cert = _load_cert( os.path.join("x509", "custom", "utf8_common_name.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [ x509.NameAttribute(NameOID.COMMON_NAME, "We heart UTF8!\u2122") @@ -1155,7 +1089,6 @@ def test_invalid_unicode_name(self, backend): cert = _load_cert( os.path.join("x509", "custom", "invalid_utf8_common_name.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.raises(ValueError, match="subject"): cert.subject @@ -1166,7 +1099,6 @@ def test_non_ascii_dns_name(self, backend): cert = _load_cert( os.path.join("x509", "utf8-dnsname.pem"), x509.load_pem_x509_certificate, - backend, ) san = cert.extensions.get_extension_for_class( x509.SubjectAlternativeName @@ -1188,7 +1120,6 @@ def test_all_subject_name_types(self, backend): cert = _load_cert( os.path.join("x509", "custom", "all_supported_names.pem"), x509.load_pem_x509_certificate, - backend, ) subject = cert.subject assert isinstance(subject, x509.Name) @@ -1233,7 +1164,6 @@ def test_load_good_ca_cert(self, backend): cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30) @@ -1254,7 +1184,6 @@ def test_utc_pre_2000_not_before_cert(self, backend): "Validpre2000UTCnotBeforeDateTest3EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1) @@ -1268,7 +1197,6 @@ def test_pre_2000_utc_not_after_cert(self, backend): "Invalidpre2000UTCEEnotAfterDateTest7EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1) @@ -1277,7 +1205,6 @@ def test_post_2000_utc_cert(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.not_valid_before == datetime.datetime( 2014, 11, 26, 21, 41, 20 @@ -1295,7 +1222,6 @@ def test_generalized_time_not_before_cert(self, backend): "ValidGeneralizedTimenotBeforeDateTest4EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1) assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30) @@ -1310,7 +1236,6 @@ def test_generalized_time_not_after_cert(self, backend): "ValidGeneralizedTimenotAfterDateTest8EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30) assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1) @@ -1321,7 +1246,6 @@ def test_invalid_version_cert(self, backend): _load_cert( os.path.join("x509", "custom", "invalid_version.pem"), x509.load_pem_x509_certificate, - backend, ) assert exc.value.parsed_version == 7 @@ -1330,12 +1254,10 @@ def test_eq(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) cert2 = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert == cert2 @@ -1343,7 +1265,6 @@ def test_ne(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) cert2 = _load_cert( os.path.join( @@ -1353,7 +1274,6 @@ def test_ne(self, backend): "ValidGeneralizedTimenotAfterDateTest8EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert cert != cert2 assert cert != object() @@ -1362,12 +1282,10 @@ def test_ordering_unsupported(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) cert2 = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.raises(TypeError, match="cannot be ordered"): cert > cert2 # type: ignore[operator] @@ -1376,12 +1294,10 @@ def test_hash(self, backend): cert1 = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) cert2 = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), x509.load_pem_x509_certificate, - backend, ) cert3 = _load_cert( os.path.join( @@ -1391,7 +1307,6 @@ def test_hash(self, backend): "ValidGeneralizedTimenotAfterDateTest8EE.crt", ), x509.load_der_x509_certificate, - backend, ) assert hash(cert1) == hash(cert2) @@ -1401,7 +1316,6 @@ def test_version_1_cert(self, backend): cert = _load_cert( os.path.join("x509", "v1_cert.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.version is x509.Version.v1 @@ -1425,7 +1339,6 @@ def test_unsupported_signature_hash_algorithm_cert(self, backend): cert = _load_cert( os.path.join("x509", "verisign_md2_root.pem"), x509.load_pem_x509_certificate, - backend, ) with raises_unsupported_algorithm(None): cert.signature_hash_algorithm @@ -1435,7 +1348,6 @@ def test_public_bytes_pem(self, backend): cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) # Encode it to PEM and load it back. @@ -1461,7 +1373,6 @@ def test_public_bytes_der(self, backend): cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) # Encode it to DER and load it back. @@ -1469,7 +1380,6 @@ def test_public_bytes_der(self, backend): cert.public_bytes( encoding=serialization.Encoding.DER, ), - backend, ) # We should recover what we had to start with. @@ -1486,7 +1396,6 @@ def test_public_bytes_invalid_encoding(self, backend): cert = _load_cert( os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), x509.load_der_x509_certificate, - backend, ) with pytest.raises(TypeError): @@ -1513,7 +1422,7 @@ def test_public_bytes_match( cert_bytes = load_vectors_from_file( cert_path, lambda pemfile: pemfile.read(), mode="rb" ) - cert = loader_func(cert_bytes, backend) + cert = loader_func(cert_bytes) serialized = cert.public_bytes(encoding) assert serialized == cert_bytes @@ -1521,7 +1430,6 @@ def test_certificate_repr(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) assert repr(cert) == ( " csr2 # type: ignore[operator] @@ -2033,17 +1915,14 @@ def test_hash(self, backend): request1 = _load_cert( os.path.join("x509", "requests", "rsa_sha1.pem"), x509.load_pem_x509_csr, - backend, ) request2 = _load_cert( os.path.join("x509", "requests", "rsa_sha1.pem"), x509.load_pem_x509_csr, - backend, ) request3 = _load_cert( os.path.join("x509", "requests", "san_rsa_sha1.pem"), x509.load_pem_x509_csr, - backend, ) assert hash(request1) == hash(request2) @@ -4703,7 +4582,6 @@ def test_load_dsa_cert(self, backend): cert = _load_cert( os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) public_key = cert.public_key() @@ -4753,7 +4631,6 @@ def test_signature(self, backend): cert = _load_cert( os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.signature == binascii.unhexlify( b"302c021425c4a84a936ab311ee017d3cbd9a3c650bb3ae4a02145d30c64b4326" @@ -4767,7 +4644,6 @@ def test_tbs_certificate_bytes(self, backend): cert = _load_cert( os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.tbs_certificate_bytes == binascii.unhexlify( b"3082051aa003020102020900a37352e0b2142f86300906072a8648ce3804033" @@ -4864,7 +4740,7 @@ class TestDSACertificateRequest: ], ) def test_load_dsa_request(self, path, loader_func, backend): - request = _load_cert(path, loader_func, backend) + request = _load_cert(path, loader_func) assert isinstance(request.signature_hash_algorithm, hashes.SHA1) public_key = request.public_key() assert isinstance(public_key, dsa.DSAPublicKey) @@ -4882,7 +4758,6 @@ def test_signature(self, backend): request = _load_cert( os.path.join("x509", "requests", "dsa_sha1.pem"), x509.load_pem_x509_csr, - backend, ) assert request.signature == binascii.unhexlify( b"302c021461d58dc028d0110818a7d817d74235727c4acfdf0214097b52e198e" @@ -4893,7 +4768,6 @@ def test_tbs_certrequest_bytes(self, backend): request = _load_cert( os.path.join("x509", "requests", "dsa_sha1.pem"), x509.load_pem_x509_csr, - backend, ) assert request.tbs_certrequest_bytes == binascii.unhexlify( b"3082021802010030573118301606035504030c0f63727970746f677261706879" @@ -4944,7 +4818,6 @@ def test_load_ecdsa_cert(self, backend): cert = _load_cert( os.path.join("x509", "ecdsa_root.pem"), x509.load_pem_x509_certificate, - backend, ) assert isinstance(cert.signature_hash_algorithm, hashes.SHA384) public_key = cert.public_key() @@ -4966,7 +4839,6 @@ def test_load_bitstring_dn(self, backend): cert = _load_cert( os.path.join("x509", "scottishpower-bitstring-dn.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.subject == x509.Name( [ @@ -4989,7 +4861,6 @@ def test_load_name_attribute_long_form_asn1_tag(self, backend): cert = _load_cert( os.path.join("x509", "custom", "long-form-name-attribute.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.raises(ValueError, match="Long-form"): cert.subject @@ -5000,7 +4871,6 @@ def test_signature(self, backend): cert = _load_cert( os.path.join("x509", "ecdsa_root.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.signature == binascii.unhexlify( b"3065023100adbcf26c3f124ad12d39c30a099773f488368c8827bbe6888d5085" @@ -5025,7 +4895,6 @@ def test_tbs_certificate_bytes(self, backend): cert = _load_cert( os.path.join("x509", "ecdsa_root.pem"), x509.load_pem_x509_certificate, - backend, ) assert cert.tbs_certificate_bytes == binascii.unhexlify( b"308201c5a0030201020210055556bcf25ea43535c3a40fd5ab4572300a06082" @@ -5058,7 +4927,6 @@ def test_load_ecdsa_no_named_curve(self, backend): cert = _load_cert( os.path.join("x509", "custom", "ec_no_named_curve.pem"), x509.load_pem_x509_certificate, - backend, ) # This test can trigger three different value errors depending # on OpenSSL/BoringSSL and versions. Match on the text to ensure @@ -5101,7 +4969,7 @@ class TestECDSACertificateRequest: ) def test_load_ecdsa_certificate_request(self, path, loader_func, backend): _skip_curve_unsupported(backend, ec.SECP384R1()) - request = _load_cert(path, loader_func, backend) + request = _load_cert(path, loader_func) assert isinstance(request.signature_hash_algorithm, hashes.SHA256) public_key = request.public_key() assert isinstance(public_key, ec.EllipticCurvePublicKey) @@ -5120,7 +4988,6 @@ def test_signature(self, backend): request = _load_cert( os.path.join("x509", "requests", "ec_sha256.pem"), x509.load_pem_x509_csr, - backend, ) assert request.signature == binascii.unhexlify( b"306502302c1a9f7de8c1787332d2307a886b476a59f172b9b0e250262f3238b1" @@ -5134,7 +5001,6 @@ def test_tbs_certrequest_bytes(self, backend): request = _load_cert( os.path.join("x509", "requests", "ec_sha256.pem"), x509.load_pem_x509_csr, - backend, ) assert request.tbs_certrequest_bytes == binascii.unhexlify( b"3081d602010030573118301606035504030c0f63727970746f6772617068792" @@ -5162,7 +5028,6 @@ def test_unsupported_subject_public_key_info(self, backend): "x509", "custom", "unsupported_subject_public_key_info.pem" ), x509.load_pem_x509_certificate, - backend, ) with pytest.raises(ValueError): @@ -5173,7 +5038,6 @@ def test_bad_time_in_validity(self, backend): _load_cert( os.path.join("x509", "badasn1time.pem"), x509.load_pem_x509_certificate, - backend, ) @@ -5688,7 +5552,6 @@ def test_load_pem_cert(self, backend): cert = _load_cert( os.path.join("x509", "ed25519", "root-ed25519.pem"), x509.load_pem_x509_certificate, - backend, ) # self-signed, so this will work public_key = cert.public_key() @@ -5703,7 +5566,6 @@ def test_deepcopy(self, backend): cert = _load_cert( os.path.join("x509", "ed25519", "root-ed25519.pem"), x509.load_pem_x509_certificate, - backend, ) assert copy.deepcopy(cert) is cert @@ -5735,7 +5597,6 @@ def test_load_pem_cert(self, backend): cert = _load_cert( os.path.join("x509", "ed448", "root-ed448.pem"), x509.load_pem_x509_certificate, - backend, ) # self-signed, so this will work public_key = cert.public_key() @@ -5988,7 +5849,6 @@ def test_get_attribute_for_oid_challenge(self, backend): request = _load_cert( os.path.join("x509", "requests", "challenge.pem"), x509.load_pem_x509_csr, - backend, ) with pytest.warns(utils.DeprecatedIn36): assert ( @@ -6009,7 +5869,6 @@ def test_get_attribute_for_oid_multiple(self, backend): request = _load_cert( os.path.join("x509", "requests", "challenge-unstructured.pem"), x509.load_pem_x509_csr, - backend, ) with pytest.warns(utils.DeprecatedIn36): assert ( @@ -6045,7 +5904,6 @@ def test_unsupported_asn1_type_in_attribute(self, backend): request = _load_cert( os.path.join("x509", "requests", "challenge-invalid.der"), x509.load_der_x509_csr, - backend, ) # Unsupported in the legacy path @@ -6066,7 +5924,6 @@ def test_long_form_asn1_tag_in_attribute(self, backend): request = _load_cert( os.path.join("x509", "requests", "long-form-attribute.pem"), x509.load_pem_x509_csr, - backend, ) with pytest.raises(ValueError, match="Long-form"): request.attributes @@ -6078,7 +5935,6 @@ def test_challenge_multivalued(self, backend): request = _load_cert( os.path.join("x509", "requests", "challenge-multi-valued.der"), x509.load_der_x509_csr, - backend, ) with pytest.raises(ValueError, match="Only single-valued"): with pytest.warns(utils.DeprecatedIn36): @@ -6093,7 +5949,6 @@ def test_no_challenge_password(self, backend): request = _load_cert( os.path.join("x509", "requests", "rsa_sha256.pem"), x509.load_pem_x509_csr, - backend, ) with pytest.raises(x509.AttributeNotFound) as exc: with pytest.warns(utils.DeprecatedIn36): @@ -6112,7 +5967,6 @@ def test_no_attributes(self, backend): request = _load_cert( os.path.join("x509", "requests", "rsa_sha256.pem"), x509.load_pem_x509_csr, - backend, ) assert len(request.attributes) == 0 diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py index 1368ffdf815a..a4f0f0f8b6a0 100644 --- a/tests/x509/test_x509_ext.py +++ b/tests/x509/test_x509_ext.py @@ -680,7 +680,6 @@ def test_long_oid(self, backend): cert = _load_cert( os.path.join("x509", "bigoid.pem"), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions.get_extension_for_class(x509.CertificatePolicies) @@ -711,7 +710,6 @@ def test_cps_uri_policy_qualifier(self, backend): cert = _load_cert( os.path.join("x509", "custom", "cp_cps_uri.pem"), x509.load_pem_x509_certificate, - backend, ) cp = cert.extensions.get_extension_for_oid( @@ -733,7 +731,6 @@ def test_user_notice_with_notice_reference(self, backend): "x509", "custom", "cp_user_notice_with_notice_reference.pem" ), x509.load_pem_x509_certificate, - backend, ) cp = cert.extensions.get_extension_for_oid( @@ -762,7 +759,6 @@ def test_user_notice_with_explicit_text(self, backend): "x509", "custom", "cp_user_notice_with_explicit_text.pem" ), x509.load_pem_x509_certificate, - backend, ) cp = cert.extensions.get_extension_for_oid( @@ -784,7 +780,6 @@ def test_user_notice_no_explicit_text(self, backend): "x509", "custom", "cp_user_notice_no_explicit_text.pem" ), x509.load_pem_x509_certificate, - backend, ) cp = cert.extensions.get_extension_for_oid( @@ -1487,7 +1482,6 @@ def test_no_extensions(self, backend): cert = _load_cert( os.path.join("x509", "verisign_md2_root.pem"), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions assert len(ext) == 0 @@ -1503,7 +1497,6 @@ def test_one_extension(self, backend): "x509", "custom", "basic_constraints_not_critical.pem" ), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions.get_extension_for_class(x509.BasicConstraints) assert ext is not None @@ -1513,7 +1506,6 @@ def test_duplicate_extension(self, backend): cert = _load_cert( os.path.join("x509", "custom", "two_basic_constraints.pem"), x509.load_pem_x509_certificate, - backend, ) with pytest.raises(x509.DuplicateExtension) as exc: cert.extensions @@ -1526,7 +1518,6 @@ def test_unsupported_critical_extension(self, backend): "x509", "custom", "unsupported_extension_critical.pem" ), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions.get_extension_for_oid( x509.ObjectIdentifier("1.2.3.4") @@ -1538,7 +1529,6 @@ def test_unsupported_extension(self, backend): cert = _load_cert( os.path.join("x509", "custom", "unsupported_extension_2.pem"), x509.load_pem_x509_certificate, - backend, ) extensions = cert.extensions assert len(extensions) == 2 @@ -1562,7 +1552,6 @@ def test_no_extensions_get_for_class(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) exts = cert.extensions with pytest.raises(x509.ExtensionNotFound) as exc: @@ -1578,7 +1567,6 @@ def test_indexing(self, backend): cert = _load_cert( os.path.join("x509", "cryptography.io.pem"), x509.load_pem_x509_certificate, - backend, ) exts = cert.extensions assert exts[-1] == exts[7] @@ -1590,7 +1578,6 @@ def test_one_extension_get_for_class(self, backend): "x509", "custom", "basic_constraints_not_critical.pem" ), x509.load_pem_x509_certificate, - backend, ) ext = cert.extensions.get_extension_for_class(x509.BasicConstraints) assert ext is not None @@ -1601,7 +1588,6 @@ def test_repr(self, backend): "x509", "custom", "basic_constraints_not_critical.pem" ), x509.load_pem_x509_certificate, - backend, ) assert repr(cert.extensions) == ( " Date: Tue, 7 Mar 2023 06:41:49 +0800 Subject: [PATCH 405/827] enable parallel testing for dynamo downstream (#8468) --- .github/downstream.d/dynamodb-encryption-sdk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/downstream.d/dynamodb-encryption-sdk.sh b/.github/downstream.d/dynamodb-encryption-sdk.sh index e41288d44083..b053e6eb4cc8 100755 --- a/.github/downstream.d/dynamodb-encryption-sdk.sh +++ b/.github/downstream.d/dynamodb-encryption-sdk.sh @@ -10,7 +10,7 @@ case "${1}" in ;; run) cd aws-dynamodb-encryption-python - pytest test/ -m "local and not slow and not veryslow and not nope" + pytest -n auto test/ -m "local and not slow and not veryslow and not nope" ;; *) exit 1 From 99a27f30f65d954f73fd1def5c8f93ebf5b9dfdd Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Mar 2023 07:56:26 +0800 Subject: [PATCH 406/827] refactor PBKDF2HMAC test vectors and skip one test (#8467) The test in question has 2**24 iterations and doesn't represent an interesting edge case in the algorithm, just a high iteration count. --- .../primitives/test_pbkdf2hmac_vectors.py | 27 ++++++++++++++----- tests/hazmat/primitives/utils.py | 25 ----------------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/tests/hazmat/primitives/test_pbkdf2hmac_vectors.py b/tests/hazmat/primitives/test_pbkdf2hmac_vectors.py index 60d2f864da84..db44114e3194 100644 --- a/tests/hazmat/primitives/test_pbkdf2hmac_vectors.py +++ b/tests/hazmat/primitives/test_pbkdf2hmac_vectors.py @@ -2,23 +2,36 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import binascii +import os import pytest from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC -from ...utils import load_nist_vectors -from .utils import generate_pbkdf2_test +from ...utils import load_nist_vectors, load_vectors_from_file @pytest.mark.supported( only_if=lambda backend: backend.pbkdf2_hmac_supported(hashes.SHA1()), skip_message="Does not support SHA1 for PBKDF2HMAC", ) -class TestPBKDF2HMACSHA1: - test_pbkdf2_sha1 = generate_pbkdf2_test( +def test_pbkdf2_hmacsha1_vectors(subtests, backend): + params = load_vectors_from_file( + os.path.join("KDF", "rfc-6070-PBKDF2-SHA1.txt"), load_nist_vectors, - "KDF", - ["rfc-6070-PBKDF2-SHA1.txt"], - hashes.SHA1(), ) + for param in params: + with subtests.test(): + iterations = int(param["iterations"]) + if iterations > 1_000_000: + pytest.skip("Skipping test due to iteration count") + kdf = PBKDF2HMAC( + hashes.SHA1(), + int(param["length"]), + param["salt"], + iterations, + ) + derived_key = kdf.derive(param["password"]) + assert binascii.hexlify(derived_key) == param["derived_key"] diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 6e2ce41dc5ec..282744e80eaa 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -31,7 +31,6 @@ CounterLocation, Mode, ) -from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from ...utils import load_vectors_from_file @@ -250,30 +249,6 @@ def hmac_test(backend, algorithm, params): assert h.finalize() == binascii.unhexlify(md.encode("ascii")) -def generate_pbkdf2_test(param_loader, path, file_names, algorithm): - def test_pbkdf2(self, backend, subtests): - for params in _load_all_params(path, file_names, param_loader): - with subtests.test(): - pbkdf2_test(backend, algorithm, params) - - return test_pbkdf2 - - -def pbkdf2_test(backend, algorithm, params): - # Password and salt can contain \0, which should be loaded as a null char. - # The NIST loader loads them as literal strings so we replace with the - # proper value. - kdf = PBKDF2HMAC( - algorithm, - int(params["length"]), - params["salt"], - int(params["iterations"]), - backend, - ) - derived_key = kdf.derive(params["password"]) - assert binascii.hexlify(derived_key) == params["derived_key"] - - def generate_aead_exception_test(cipher_factory, mode_factory): def test_aead_exception(self, backend): aead_exception_test(backend, cipher_factory, mode_factory) From f36f899a59ad0736842ec5edf93d115a63595295 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 7 Mar 2023 00:20:38 +0000 Subject: [PATCH 407/827] Bump BoringSSL and/or OpenSSL in CI (#8469) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b82e74d50174..dd2ad74f7edc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 06, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "3a7dfdb984434a4b4beef947b2e49602c557c0de"}} - # Latest commit on the OpenSSL master branch, as of Mar 06, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "10836921e52ff9110c12b4b9f984e7c5ef1c89cc"}} + # Latest commit on the BoringSSL master branch, as of Mar 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "082e953a134ad423a00b8859f9daf5708e729260"}} + # Latest commit on the OpenSSL master branch, as of Mar 07, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "bf762f9203d3b5541c21f2b376750e32ebf36651"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 79e38a379e8ab02fae6c1142db088889a0508a8c Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Tue, 7 Mar 2023 13:20:32 +0200 Subject: [PATCH 408/827] Make Union type aliases a documented public API (#8168) * Rename Union type aliases to CamelCase Many `typing.Union` type aliases were previously using `UPPER_SNAKE_CASE`, but Python's convention is `CamelCase` for these (e.g. https://docs.python.org/3/library/typing.html#type-aliases) * Add utils.deprecated for the old non-underscore type aliases * Added documentation for new type aliases & minor tweaks * Use 'versionadded:: 40.0.0' * Fix CertificatePublicKeyTypes vs CertificateIssuerPublicKeyTypes. Rename CertificatePrivateKeyTypes to CertificateIssuerPrivateKeyTypes * Fix imports (ruff) * Fix one more versionadded * Tweak docs & Reorder: CertificateIssuerPublicKeyTypes before CertificateIssuerPrivateKeyTypes * Fix test mypy errors using cast() * Fix black, oops * Revert "Fix black, oops" This reverts commit 85344e231d697bdc0940e105f7aed729445f9743. * Revert "Fix test mypy errors using cast()" This reverts commit b272d8ca95fbbbc62060663f9e8930a139a7a43e. * Revert type of SubjectKeyIdentifier.from_public_key arg * Changelog tweak --- CHANGELOG.rst | 25 +++ docs/hazmat/primitives/asymmetric/index.rst | 80 +++++++++ .../primitives/asymmetric/serialization.rst | 160 +++++++++++------- docs/hazmat/primitives/twofactor.rst | 11 +- docs/x509/reference.rst | 64 ++----- .../hazmat/backends/openssl/aead.py | 10 +- .../hazmat/backends/openssl/backend.py | 28 +-- .../hazmat/bindings/_rust/ocsp.pyi | 4 +- .../hazmat/bindings/_rust/x509.pyi | 8 +- .../hazmat/primitives/asymmetric/types.py | 51 +++++- .../primitives/serialization/__init__.py | 8 + .../hazmat/primitives/serialization/base.py | 12 +- .../hazmat/primitives/serialization/pkcs12.py | 17 +- .../hazmat/primitives/serialization/pkcs7.py | 12 +- .../hazmat/primitives/serialization/ssh.py | 38 ++--- .../hazmat/primitives/twofactor/hotp.py | 4 +- .../hazmat/primitives/twofactor/totp.py | 4 +- src/cryptography/x509/base.py | 22 +-- src/cryptography/x509/extensions.py | 30 ++-- src/cryptography/x509/general_name.py | 6 +- src/cryptography/x509/ocsp.py | 4 +- tests/x509/test_x509.py | 4 +- 22 files changed, 386 insertions(+), 216 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a55c4f85be09..b44a6cd57536 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -42,6 +42,31 @@ Changelog ``cryptography``, this note is included as a courtesy. * The X.509 builder classes now raise ``UnsupportedAlgorithm`` instead of ``ValueError`` if an unsupported hash algorithm is passed. +* Added public union type aliases for type hinting: + + * Asymmetric types: + :const:`~cryptography.hazmat.primitives.asymmetric.types.PublicKeyTypes`, + :const:`~cryptography.hazmat.primitives.asymmetric.types.PrivateKeyTypes`, + :const:`~cryptography.hazmat.primitives.asymmetric.types.CertificatePublicKeyTypes`, + :const:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPublicKeyTypes`, + :const:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPrivateKeyTypes`. + * SSH keys: + :const:`~cryptography.hazmat.primitives.serialization.SSHPublicKeyTypes`, + :const:`~cryptography.hazmat.primitives.serialization.SSHPrivateKeyTypes`, + :const:`~cryptography.hazmat.primitives.serialization.SSHCertPublicKeyTypes`, + :const:`~cryptography.hazmat.primitives.serialization.SSHCertPrivateKeyTypes`. + * PKCS12: + :const:`~cryptography.hazmat.primitives.serialization.pkcs12.PKCS12PrivateKeyTypes` + * PKCS7: + :const:`~cryptography.hazmat.primitives.serialization.pkcs7.PKCS7HashTypes`, + :const:`~cryptography.hazmat.primitives.serialization.pkcs7.PKCS7PrivateKeyTypes`. + * Two-factor: + :const:`~cryptography.hazmat.primitives.twofactor.hotp.HOTPHashTypes` + +* Deprecated previously undocumented but not private type aliases in the + ``cryptography.hazmat.primitives.asymmetric.types`` module in favor of new + ones above. + .. _v39-0-2: diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst index c27e1781e46e..136dd324b57e 100644 --- a/docs/hazmat/primitives/asymmetric/index.rst +++ b/docs/hazmat/primitives/asymmetric/index.rst @@ -36,3 +36,83 @@ private key is able to decrypt it. .. _`proof of identity`: https://en.wikipedia.org/wiki/Public-key_infrastructure + +Common types +~~~~~~~~~~~~ + +Asymmetric key types do not inherit from a common base class. The following +union type aliases can be used instead to reference a multitude of key types. + +.. currentmodule:: cryptography.hazmat.primitives.asymmetric.types + +.. data:: PublicKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of all public key types supported: + :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey`. + +.. data:: PrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of all private key types supported: + :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey`. + +.. data:: CertificatePublicKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of all public key types supported for X.509 + certificates: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey`. + +.. data:: CertificateIssuerPublicKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of all public key types that can sign other X.509 + certificates as an issuer. x448/x25519 can be a public key, but cannot be + used in signing, so they are not allowed in these contexts. + + Allowed: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`. + +.. data:: CertificateIssuerPrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of all private key types that can sign other X.509 + certificates as an issuer. x448/x25519 can be a public key, but cannot be + used in signing, so they are not allowed in these contexts. + + Allowed: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey`. diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index ca33c156e429..5fb248b554f9 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -388,6 +388,19 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than ``ssh-rsa``. ECDSA keys have a slightly different format, they begin with ``ecdsa-sha2-{curve}``. + +.. data:: SSHPublicKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of public key types accepted for SSH: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + , or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`. + + .. function:: load_ssh_public_key(data) .. versionadded:: 0.7 @@ -404,13 +417,8 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than :param data: The OpenSSH encoded key data. :type data: :term:`bytes-like` - :returns: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` - , or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, - depending on the contents of ``data``. + :returns: One of :data:`SSHPublicKeyTypes` depending on the contents of + ``data``. :raises ValueError: If the OpenSSH data could not be properly decoded or if the key is not in the proper format. @@ -436,6 +444,18 @@ An example ECDSA key in OpenSSH format:: BAUGBw== -----END OPENSSH PRIVATE KEY----- +.. data:: SSHPrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of private key types accepted for SSH: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`. + + .. function:: load_ssh_private_key(data, password) .. versionadded:: 3.0 @@ -454,13 +474,8 @@ An example ECDSA key in OpenSSH format:: :param bytes password: Password bytes to use to decrypt password-protected key. Or ``None`` if not needed. - :returns: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` - or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`, - depending on the contents of ``data``. + :returns: One of :data:`SSHPrivateKeyTypes` depending on the contents of + ``data``. :raises ValueError: If the OpenSSH data could not be properly decoded, if the key is not in the proper format or the incorrect password @@ -476,6 +491,28 @@ OpenSSH Certificate The format used by OpenSSH for certificates, as specified in `PROTOCOL.certkeys`_. +.. data:: SSHCertPublicKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of public key types supported for SSH + certificates: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` + +.. data:: SSHCertPrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of private key types supported for SSH + certificates: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` + .. function:: load_ssh_public_identity(data) .. versionadded:: 40.0.0 @@ -494,12 +531,7 @@ The format used by OpenSSH for certificates, as specified in :param data: The OpenSSH encoded data. :type data: bytes - :returns: :class:`SSHCertificate` or one of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` - , or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`. + :returns: :class:`SSHCertificate` or one of :data:`SSHCertPublicKeyTypes`. :raises ValueError: If the OpenSSH data could not be properly decoded. @@ -521,12 +553,8 @@ The format used by OpenSSH for certificates, as specified in .. method:: public_key() - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` - or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` - - The public key contained in the certificate. + The public key contained in the certificate, one of + :data:`SSHCertPublicKeyTypes`. .. attribute:: serial @@ -597,12 +625,8 @@ The format used by OpenSSH for certificates, as specified in .. method:: signature_key() - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` - or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` - - The public key used to sign the certificate. + The public key used to sign the certificate, one of + :data:`SSHCertPublicKeyTypes`. .. method:: verify_cert_signature() @@ -689,10 +713,7 @@ SSH Certificate Builder :param public_key: The public key to be included in the certificate. This value is required. - :type public_key: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` - or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` + :type public_key: :data:`SSHCertPublicKeyTypes` .. method:: serial(serial) @@ -755,10 +776,7 @@ SSH Certificate Builder :param private_key: The private key that will be used to sign the certificate. - :type private_key: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` - or - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` + :type private_key: :data:`SSHCertPrivateKeyTypes` :return: The signed certificate. :rtype: :class:`SSHCertificate` @@ -777,6 +795,23 @@ file suffix. ``cryptography`` only supports a single private key and associated certificates when parsing PKCS12 files at this time. + +.. data:: PKCS12PrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of private key types supported for PKCS12 + serialization: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` + , + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + , + :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` + , + :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` + or + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. + .. function:: load_key_and_certificates(data, password) .. versionadded:: 2.5 @@ -847,17 +882,7 @@ file suffix. :type name: bytes :param key: The private key to include in the structure. - :type key: An - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` - , - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` - , - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` - , - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` - , or - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey` - object. + :type key: :data:`PKCS12PrivateKeyTypes` :param cert: The certificate associated with the private key. :type cert: :class:`~cryptography.x509.Certificate` or ``None`` @@ -933,7 +958,8 @@ file suffix. .. attribute:: key An optional private key belonging to - :attr:`~cryptography.hazmat.primitives.serialization.pkcs12.PKCS12KeyAndCertificates.cert`. + :attr:`~cryptography.hazmat.primitives.serialization.pkcs12.PKCS12KeyAndCertificates.cert` + (see :data:`PKCS12PrivateKeyTypes`). .. attribute:: cert @@ -980,6 +1006,25 @@ contain certificates, CRLs, and much more. PKCS7 files commonly have a ``p7b``, ``cryptography`` only supports parsing certificates from PKCS7 files at this time. +.. data:: PKCS7HashTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of hash types supported for PKCS7 serialization: + :class:`~cryptography.hazmat.primitives.hashes.SHA1`, + :class:`~cryptography.hazmat.primitives.hashes.SHA224`, + :class:`~cryptography.hazmat.primitives.hashes.SHA256`, + :class:`~cryptography.hazmat.primitives.hashes.SHA384`, or + :class:`~cryptography.hazmat.primitives.hashes.SHA512`. + +.. data:: PKCS7PrivateKeyTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of private key types supported for PKCS7 serialization: + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` or + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + .. function:: load_pem_pkcs7_certificates(data) .. versionadded:: 3.1 @@ -1089,16 +1134,13 @@ contain certificates, CRLs, and much more. PKCS7 files commonly have a ``p7b``, :param private_key: The :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` or :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` - associated with the certificate provided. + associated with the certificate provided + (matches :data:`PKCS7PrivateKeyTypes`). :param hash_algorithm: The :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` that - will be used to generate the signature. This must be an instance of - :class:`~cryptography.hazmat.primitives.hashes.SHA1`, - :class:`~cryptography.hazmat.primitives.hashes.SHA224`, - :class:`~cryptography.hazmat.primitives.hashes.SHA256`, - :class:`~cryptography.hazmat.primitives.hashes.SHA384`, or - :class:`~cryptography.hazmat.primitives.hashes.SHA512`. + will be used to generate the signature. This must be one of the + types in :data:`PKCS7HashTypes`. .. method:: add_certificate(certificate) diff --git a/docs/hazmat/primitives/twofactor.rst b/docs/hazmat/primitives/twofactor.rst index 0d7d88f22dac..4cd437bedcf1 100644 --- a/docs/hazmat/primitives/twofactor.rst +++ b/docs/hazmat/primitives/twofactor.rst @@ -18,6 +18,15 @@ codes (HMAC). .. currentmodule:: cryptography.hazmat.primitives.twofactor.hotp +.. data:: HOTPHashTypes + + .. versionadded:: 40.0.0 + + Type alias: A union of supported hash algorithm types: + :class:`~cryptography.hazmat.primitives.hashes.SHA1`, + :class:`~cryptography.hazmat.primitives.hashes.SHA256` or + :class:`~cryptography.hazmat.primitives.hashes.SHA512`. + .. class:: HOTP(key, length, algorithm, *, enforce_key_length=True) .. versionadded:: 0.3 @@ -47,7 +56,7 @@ codes (HMAC). :param int length: Length of generated one time password as ``int``. :param cryptography.hazmat.primitives.hashes.HashAlgorithm algorithm: A :class:`~cryptography.hazmat.primitives.hashes` - instance. + instance (must match :data:`HOTPHashTypes`). :param enforce_key_length: A boolean flag defaulting to True that toggles whether a minimum key length of 128 :term:`bits` is enforced. This exists to work around the fact that as documented in `Issue #2915`_, diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index f536b531a231..81548812e6cb 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -331,13 +331,7 @@ X.509 Certificate Object The public key associated with the certificate. :returns: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey` + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificatePublicKeyTypes`. .. doctest:: @@ -779,13 +773,7 @@ X.509 Certificate Builder Sets the subject's public key. :param public_key: The subject's public key. This can be one of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey`. + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificatePublicKeyTypes`. .. method:: serial_number(serial_number) @@ -836,13 +824,9 @@ X.509 Certificate Builder Sign the certificate using the CA's private key. - :param private_key: The - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` - that will be used to sign the certificate. + :param private_key: The key that will be used to sign the certificate, + one of + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPrivateKeyTypes`. :param algorithm: The :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` that @@ -871,11 +855,7 @@ X.509 CSR (Certificate Signing Request) Object The public key associated with the request. :returns: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`. + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificatePublicKeyTypes`. .. doctest:: @@ -1067,13 +1047,9 @@ X.509 Certificate Revocation List Builder Sign this CRL using the CA's private key. - :param private_key: The - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` - that will be used to sign the certificate. + :param private_key: The private key that will be used to sign the + certificate, one of + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPrivateKeyTypes`. :param algorithm: The :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` that @@ -1246,15 +1222,11 @@ X.509 CSR (Certificate Signing Request) Builder Object .. method:: sign(private_key, algorithm) - :param private_key: The - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` + :param private_key: The private key that will be used to sign the request. When the request is signed by a certificate authority, the private key's associated - public key will be stored in the resulting certificate. + public key will be stored in the resulting certificate. One of + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPrivateKeyTypes`. :param algorithm: The :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` @@ -2038,11 +2010,7 @@ X.509 Extensions section 4.2.1.2. :param public_key: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`. + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPublicKeyTypes`. .. doctest:: @@ -2123,11 +2091,7 @@ X.509 Extensions recommendation in :rfc:`5280` section 4.2.1.2. :param public_key: One of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`, - :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey` or - :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`. + :data:`~cryptography.hazmat.primitives.asymmetric.types.CertificatePublicKeyTypes`. .. doctest:: diff --git a/src/cryptography/hazmat/backends/openssl/aead.py b/src/cryptography/hazmat/backends/openssl/aead.py index 1b5ecefaa88e..d43deb432a16 100644 --- a/src/cryptography/hazmat/backends/openssl/aead.py +++ b/src/cryptography/hazmat/backends/openssl/aead.py @@ -16,7 +16,7 @@ ChaCha20Poly1305, ) - _AEAD_TYPES = typing.Union[ + _AEADTypes = typing.Union[ AESCCM, AESGCM, AESOCB3, AESSIV, ChaCha20Poly1305 ] @@ -24,7 +24,7 @@ _DECRYPT = 0 -def _aead_cipher_name(cipher: "_AEAD_TYPES") -> bytes: +def _aead_cipher_name(cipher: "_AEADTypes") -> bytes: from cryptography.hazmat.primitives.ciphers.aead import ( AESCCM, AESGCM, @@ -64,7 +64,7 @@ def _evp_cipher(cipher_name: bytes, backend: "Backend"): def _aead_create_ctx( backend: "Backend", - cipher: "_AEAD_TYPES", + cipher: "_AEADTypes", key: bytes, ): ctx = backend._lib.EVP_CIPHER_CTX_new() @@ -189,7 +189,7 @@ def _process_data(backend: "Backend", ctx, data: bytes) -> bytes: def _encrypt( backend: "Backend", - cipher: "_AEAD_TYPES", + cipher: "_AEADTypes", nonce: bytes, data: bytes, associated_data: typing.List[bytes], @@ -247,7 +247,7 @@ def _encrypt( def _decrypt( backend: "Backend", - cipher: "_AEAD_TYPES", + cipher: "_AEADTypes", nonce: bytes, data: bytes, associated_data: typing.List[bytes], diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 62576b99d0ca..846af1e2e7a6 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -77,8 +77,8 @@ PKCS1v15, ) from cryptography.hazmat.primitives.asymmetric.types import ( - PRIVATE_KEY_TYPES, - PUBLIC_KEY_TYPES, + PrivateKeyTypes, + PublicKeyTypes, ) from cryptography.hazmat.primitives.ciphers import ( BlockCipherAlgorithm, @@ -112,11 +112,11 @@ from cryptography.hazmat.primitives.kdf import scrypt from cryptography.hazmat.primitives.serialization import ssh from cryptography.hazmat.primitives.serialization.pkcs12 import ( - _ALLOWED_PKCS12_TYPES, - _PKCS12_CAS_TYPES, PBES, PKCS12Certificate, PKCS12KeyAndCertificates, + PKCS12PrivateKeyTypes, + _PKCS12CATypes, ) _MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"]) @@ -658,7 +658,7 @@ def _read_mem_bio(self, bio) -> bytes: def _evp_pkey_to_private_key( self, evp_pkey, unsafe_skip_rsa_key_validation: bool - ) -> PRIVATE_KEY_TYPES: + ) -> PrivateKeyTypes: """ Return the appropriate type of PrivateKey given an evp_pkey cdata pointer. @@ -726,7 +726,7 @@ def _evp_pkey_to_private_key( else: raise UnsupportedAlgorithm("Unsupported key type.") - def _evp_pkey_to_public_key(self, evp_pkey) -> PUBLIC_KEY_TYPES: + def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: """ Return the appropriate type of PublicKey given an evp_pkey cdata pointer. @@ -957,7 +957,7 @@ def load_pem_private_key( data: bytes, password: typing.Optional[bytes], unsafe_skip_rsa_key_validation: bool, - ) -> PRIVATE_KEY_TYPES: + ) -> PrivateKeyTypes: return self._load_key( self._lib.PEM_read_bio_PrivateKey, data, @@ -965,7 +965,7 @@ def load_pem_private_key( unsafe_skip_rsa_key_validation, ) - def load_pem_public_key(self, data: bytes) -> PUBLIC_KEY_TYPES: + def load_pem_public_key(self, data: bytes) -> PublicKeyTypes: mem_bio = self._bytes_to_bio(data) # In OpenSSL 3.0.x the PEM_read_bio_PUBKEY function will invoke # the default password callback if you pass an encrypted private @@ -1024,7 +1024,7 @@ def load_der_private_key( data: bytes, password: typing.Optional[bytes], unsafe_skip_rsa_key_validation: bool, - ) -> PRIVATE_KEY_TYPES: + ) -> PrivateKeyTypes: # OpenSSL has a function called d2i_AutoPrivateKey that in theory # handles this automatically, however it doesn't handle encrypted # private keys. Instead we try to load the key two different ways. @@ -1059,7 +1059,7 @@ def _evp_pkey_from_der_traditional_key(self, bio_data, password): self._consume_errors() return None - def load_der_public_key(self, data: bytes) -> PUBLIC_KEY_TYPES: + def load_der_public_key(self, data: bytes) -> PublicKeyTypes: mem_bio = self._bytes_to_bio(data) evp_pkey = self._lib.d2i_PUBKEY_bio(mem_bio.bio, self._ffi.NULL) if evp_pkey != self._ffi.NULL: @@ -1120,7 +1120,7 @@ def _check_keys_correspond(self, key1, key2) -> None: def _load_key( self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation - ) -> PRIVATE_KEY_TYPES: + ) -> PrivateKeyTypes: mem_bio = self._bytes_to_bio(data) userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") @@ -2066,7 +2066,7 @@ def _zeroed_null_terminated_buf(self, data): def load_key_and_certificates_from_pkcs12( self, data: bytes, password: typing.Optional[bytes] ) -> typing.Tuple[ - typing.Optional[PRIVATE_KEY_TYPES], + typing.Optional[PrivateKeyTypes], typing.Optional[x509.Certificate], typing.List[x509.Certificate], ]: @@ -2155,9 +2155,9 @@ def load_pkcs12( def serialize_key_and_certificates_to_pkcs12( self, name: typing.Optional[bytes], - key: typing.Optional[_ALLOWED_PKCS12_TYPES], + key: typing.Optional[PKCS12PrivateKeyTypes], cert: typing.Optional[x509.Certificate], - cas: typing.Optional[typing.List[_PKCS12_CAS_TYPES]], + cas: typing.Optional[typing.List[_PKCS12CATypes]], encryption_algorithm: serialization.KeySerializationEncryption, ) -> bytes: password = None diff --git a/src/cryptography/hazmat/bindings/_rust/ocsp.pyi b/src/cryptography/hazmat/bindings/_rust/ocsp.pyi index 47a037adeeff..4671eb9ba34d 100644 --- a/src/cryptography/hazmat/bindings/_rust/ocsp.pyi +++ b/src/cryptography/hazmat/bindings/_rust/ocsp.pyi @@ -5,7 +5,7 @@ import typing from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes from cryptography.x509.ocsp import ( OCSPRequest, OCSPRequestBuilder, @@ -20,6 +20,6 @@ def create_ocsp_request(builder: OCSPRequestBuilder) -> OCSPRequest: ... def create_ocsp_response( status: OCSPResponseStatus, builder: typing.Optional[OCSPResponseBuilder], - private_key: typing.Optional[PRIVATE_KEY_TYPES], + private_key: typing.Optional[PrivateKeyTypes], hash_algorithm: typing.Optional[hashes.HashAlgorithm], ) -> OCSPResponse: ... diff --git a/src/cryptography/hazmat/bindings/_rust/x509.pyi b/src/cryptography/hazmat/bindings/_rust/x509.pyi index 1bbde80056ba..71c8d5c22c3e 100644 --- a/src/cryptography/hazmat/bindings/_rust/x509.pyi +++ b/src/cryptography/hazmat/bindings/_rust/x509.pyi @@ -6,7 +6,7 @@ import typing from cryptography import x509 from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes def load_pem_x509_certificate(data: bytes) -> x509.Certificate: ... def load_pem_x509_certificates( @@ -21,17 +21,17 @@ def encode_name_bytes(name: x509.Name) -> bytes: ... def encode_extension_value(extension: x509.ExtensionType) -> bytes: ... def create_x509_certificate( builder: x509.CertificateBuilder, - private_key: PRIVATE_KEY_TYPES, + private_key: PrivateKeyTypes, hash_algorithm: typing.Optional[hashes.HashAlgorithm], ) -> x509.Certificate: ... def create_x509_csr( builder: x509.CertificateSigningRequestBuilder, - private_key: PRIVATE_KEY_TYPES, + private_key: PrivateKeyTypes, hash_algorithm: typing.Optional[hashes.HashAlgorithm], ) -> x509.CertificateSigningRequest: ... def create_x509_crl( builder: x509.CertificateRevocationListBuilder, - private_key: PRIVATE_KEY_TYPES, + private_key: PrivateKeyTypes, hash_algorithm: typing.Optional[hashes.HashAlgorithm], ) -> x509.CertificateRevocationList: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/types.py b/src/cryptography/hazmat/primitives/asymmetric/types.py index 6b5ff08017e2..e911a9f602c2 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/types.py +++ b/src/cryptography/hazmat/primitives/asymmetric/types.py @@ -4,6 +4,7 @@ import typing +from cryptography import utils from cryptography.hazmat.primitives.asymmetric import ( dh, dsa, @@ -16,7 +17,7 @@ ) # Every asymmetric key type -PUBLIC_KEY_TYPES = typing.Union[ +PublicKeyTypes = typing.Union[ dh.DHPublicKey, dsa.DSAPublicKey, rsa.RSAPublicKey, @@ -26,8 +27,16 @@ x25519.X25519PublicKey, x448.X448PublicKey, ] +PUBLIC_KEY_TYPES = PublicKeyTypes +utils.deprecated( + PUBLIC_KEY_TYPES, + __name__, + "Use PublicKeyTypes instead", + utils.DeprecatedIn40, + name="PUBLIC_KEY_TYPES", +) # Every asymmetric key type -PRIVATE_KEY_TYPES = typing.Union[ +PrivateKeyTypes = typing.Union[ dh.DHPrivateKey, ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey, @@ -37,27 +46,51 @@ x25519.X25519PrivateKey, x448.X448PrivateKey, ] +PRIVATE_KEY_TYPES = PrivateKeyTypes +utils.deprecated( + PRIVATE_KEY_TYPES, + __name__, + "Use PrivateKeyTypes instead", + utils.DeprecatedIn40, + name="PRIVATE_KEY_TYPES", +) # Just the key types we allow to be used for x509 signing. This mirrors # the certificate public key types -CERTIFICATE_PRIVATE_KEY_TYPES = typing.Union[ +CertificateIssuerPrivateKeyTypes = typing.Union[ ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey, rsa.RSAPrivateKey, dsa.DSAPrivateKey, ec.EllipticCurvePrivateKey, ] +CERTIFICATE_PRIVATE_KEY_TYPES = CertificateIssuerPrivateKeyTypes +utils.deprecated( + CERTIFICATE_PRIVATE_KEY_TYPES, + __name__, + "Use CertificateIssuerPrivateKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_PRIVATE_KEY_TYPES", +) # Just the key types we allow to be used for x509 signing. This mirrors # the certificate private key types -CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES = typing.Union[ +CertificateIssuerPublicKeyTypes = typing.Union[ dsa.DSAPublicKey, rsa.RSAPublicKey, ec.EllipticCurvePublicKey, ed25519.Ed25519PublicKey, ed448.Ed448PublicKey, ] +CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES = CertificateIssuerPublicKeyTypes +utils.deprecated( + CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, + __name__, + "Use CertificateIssuerPublicKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES", +) # This type removes DHPublicKey. x448/x25519 can be a public key # but cannot be used in signing so they are allowed here. -CERTIFICATE_PUBLIC_KEY_TYPES = typing.Union[ +CertificatePublicKeyTypes = typing.Union[ dsa.DSAPublicKey, rsa.RSAPublicKey, ec.EllipticCurvePublicKey, @@ -66,3 +99,11 @@ x25519.X25519PublicKey, x448.X448PublicKey, ] +CERTIFICATE_PUBLIC_KEY_TYPES = CertificatePublicKeyTypes +utils.deprecated( + CERTIFICATE_PUBLIC_KEY_TYPES, + __name__, + "Use CertificatePublicKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_PUBLIC_KEY_TYPES", +) diff --git a/src/cryptography/hazmat/primitives/serialization/__init__.py b/src/cryptography/hazmat/primitives/serialization/__init__.py index 84c18e504e88..213c49958a74 100644 --- a/src/cryptography/hazmat/primitives/serialization/__init__.py +++ b/src/cryptography/hazmat/primitives/serialization/__init__.py @@ -25,6 +25,10 @@ SSHCertificate, SSHCertificateBuilder, SSHCertificateType, + SSHCertPrivateKeyTypes, + SSHCertPublicKeyTypes, + SSHPrivateKeyTypes, + SSHPublicKeyTypes, load_ssh_private_key, load_ssh_public_identity, load_ssh_public_key, @@ -51,4 +55,8 @@ "SSHCertificateBuilder", "SSHCertificate", "SSHCertificateType", + "SSHCertPublicKeyTypes", + "SSHCertPrivateKeyTypes", + "SSHPrivateKeyTypes", + "SSHPublicKeyTypes", ] diff --git a/src/cryptography/hazmat/primitives/serialization/base.py b/src/cryptography/hazmat/primitives/serialization/base.py index 8a841766404f..7956ce0feb3f 100644 --- a/src/cryptography/hazmat/primitives/serialization/base.py +++ b/src/cryptography/hazmat/primitives/serialization/base.py @@ -7,8 +7,8 @@ from cryptography.hazmat.primitives.asymmetric import dh from cryptography.hazmat.primitives.asymmetric.types import ( - PRIVATE_KEY_TYPES, - PUBLIC_KEY_TYPES, + PrivateKeyTypes, + PublicKeyTypes, ) @@ -18,7 +18,7 @@ def load_pem_private_key( backend: typing.Any = None, *, unsafe_skip_rsa_key_validation: bool = False, -) -> PRIVATE_KEY_TYPES: +) -> PrivateKeyTypes: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_pem_private_key( @@ -28,7 +28,7 @@ def load_pem_private_key( def load_pem_public_key( data: bytes, backend: typing.Any = None -) -> PUBLIC_KEY_TYPES: +) -> PublicKeyTypes: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_pem_public_key(data) @@ -48,7 +48,7 @@ def load_der_private_key( backend: typing.Any = None, *, unsafe_skip_rsa_key_validation: bool = False, -) -> PRIVATE_KEY_TYPES: +) -> PrivateKeyTypes: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_der_private_key( @@ -58,7 +58,7 @@ def load_der_private_key( def load_der_public_key( data: bytes, backend: typing.Any = None -) -> PUBLIC_KEY_TYPES: +) -> PublicKeyTypes: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_der_public_key(data) diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs12.py b/src/cryptography/hazmat/primitives/serialization/pkcs12.py index 05212257d72d..1d36146a97e4 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs12.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs12.py @@ -14,10 +14,11 @@ ed25519, rsa, ) -from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes __all__ = [ "PBES", + "PKCS12PrivateKeyTypes", "PKCS12Certificate", "PKCS12KeyAndCertificates", "load_key_and_certificates", @@ -25,7 +26,7 @@ "serialize_key_and_certificates", ] -_ALLOWED_PKCS12_TYPES = typing.Union[ +PKCS12PrivateKeyTypes = typing.Union[ rsa.RSAPrivateKey, dsa.DSAPrivateKey, ec.EllipticCurvePrivateKey, @@ -76,7 +77,7 @@ def __repr__(self) -> str: class PKCS12KeyAndCertificates: def __init__( self, - key: typing.Optional[PRIVATE_KEY_TYPES], + key: typing.Optional[PrivateKeyTypes], cert: typing.Optional[PKCS12Certificate], additional_certs: typing.List[PKCS12Certificate], ): @@ -109,7 +110,7 @@ def __init__( self._additional_certs = additional_certs @property - def key(self) -> typing.Optional[PRIVATE_KEY_TYPES]: + def key(self) -> typing.Optional[PrivateKeyTypes]: return self._key @property @@ -145,7 +146,7 @@ def load_key_and_certificates( password: typing.Optional[bytes], backend: typing.Any = None, ) -> typing.Tuple[ - typing.Optional[PRIVATE_KEY_TYPES], + typing.Optional[PrivateKeyTypes], typing.Optional[x509.Certificate], typing.List[x509.Certificate], ]: @@ -164,7 +165,7 @@ def load_pkcs12( return ossl.load_pkcs12(data, password) -_PKCS12_CAS_TYPES = typing.Union[ +_PKCS12CATypes = typing.Union[ x509.Certificate, PKCS12Certificate, ] @@ -172,9 +173,9 @@ def load_pkcs12( def serialize_key_and_certificates( name: typing.Optional[bytes], - key: typing.Optional[_ALLOWED_PKCS12_TYPES], + key: typing.Optional[PKCS12PrivateKeyTypes], cert: typing.Optional[x509.Certificate], - cas: typing.Optional[typing.Iterable[_PKCS12_CAS_TYPES]], + cas: typing.Optional[typing.Iterable[_PKCS12CATypes]], encryption_algorithm: serialization.KeySerializationEncryption, ) -> bytes: if key is not None and not isinstance( diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 593c9b159db3..59b3ab99d534 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -35,14 +35,14 @@ def serialize_certificates( return rust_pkcs7.serialize_certificates(certs, encoding) -_ALLOWED_PKCS7_HASH_TYPES = typing.Union[ +PKCS7HashTypes = typing.Union[ hashes.SHA224, hashes.SHA256, hashes.SHA384, hashes.SHA512, ] -_ALLOWED_PRIVATE_KEY_TYPES = typing.Union[ +PKCS7PrivateKeyTypes = typing.Union[ rsa.RSAPrivateKey, ec.EllipticCurvePrivateKey ] @@ -63,8 +63,8 @@ def __init__( signers: typing.List[ typing.Tuple[ x509.Certificate, - _ALLOWED_PRIVATE_KEY_TYPES, - _ALLOWED_PKCS7_HASH_TYPES, + PKCS7PrivateKeyTypes, + PKCS7HashTypes, ] ] = [], additional_certs: typing.List[x509.Certificate] = [], @@ -83,8 +83,8 @@ def set_data(self, data: bytes) -> "PKCS7SignatureBuilder": def add_signer( self, certificate: x509.Certificate, - private_key: _ALLOWED_PRIVATE_KEY_TYPES, - hash_algorithm: _ALLOWED_PKCS7_HASH_TYPES, + private_key: PKCS7PrivateKeyTypes, + hash_algorithm: PKCS7HashTypes, ) -> "PKCS7SignatureBuilder": if not isinstance( hash_algorithm, diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index c461acb9d2df..fa278d9ed47a 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -100,7 +100,7 @@ def _bcrypt_kdf( def _get_ssh_key_type( - key: typing.Union["_SSH_PRIVATE_KEY_TYPES", "_SSH_PUBLIC_KEY_TYPES"] + key: typing.Union["SSHPrivateKeyTypes", "SSHPublicKeyTypes"] ) -> bytes: if isinstance(key, ec.EllipticCurvePrivateKey): key_type = _ecdsa_key_type(key.public_key()) @@ -560,7 +560,7 @@ def _lookup_kformat(key_type: bytes): raise UnsupportedAlgorithm(f"Unsupported key type: {key_type!r}") -_SSH_PRIVATE_KEY_TYPES = typing.Union[ +SSHPrivateKeyTypes = typing.Union[ ec.EllipticCurvePrivateKey, rsa.RSAPrivateKey, dsa.DSAPrivateKey, @@ -572,7 +572,7 @@ def load_ssh_private_key( data: bytes, password: typing.Optional[bytes], backend: typing.Any = None, -) -> _SSH_PRIVATE_KEY_TYPES: +) -> SSHPrivateKeyTypes: """Load private key from OpenSSH custom encoding.""" utils._check_byteslike("data", data) if password is not None: @@ -654,7 +654,7 @@ def load_ssh_private_key( def _serialize_ssh_private_key( - private_key: _SSH_PRIVATE_KEY_TYPES, + private_key: SSHPrivateKeyTypes, password: bytes, encryption_algorithm: KeySerializationEncryption, ) -> bytes: @@ -730,14 +730,14 @@ def _serialize_ssh_private_key( return _ssh_pem_encode(buf[:mlen]) -_SSH_PUBLIC_KEY_TYPES = typing.Union[ +SSHPublicKeyTypes = typing.Union[ ec.EllipticCurvePublicKey, rsa.RSAPublicKey, dsa.DSAPublicKey, ed25519.Ed25519PublicKey, ] -_SSH_CERT_PUBLIC_KEY_TYPES = typing.Union[ +SSHCertPublicKeyTypes = typing.Union[ ec.EllipticCurvePublicKey, rsa.RSAPublicKey, ed25519.Ed25519PublicKey, @@ -753,7 +753,7 @@ class SSHCertificate: def __init__( self, _nonce: memoryview, - _public_key: _SSH_PUBLIC_KEY_TYPES, + _public_key: SSHPublicKeyTypes, _serial: int, _cctype: int, _key_id: memoryview, @@ -795,10 +795,10 @@ def __init__( def nonce(self) -> bytes: return bytes(self._nonce) - def public_key(self) -> _SSH_CERT_PUBLIC_KEY_TYPES: + def public_key(self) -> SSHCertPublicKeyTypes: # make mypy happy until we remove DSA support entirely and # the underlying union won't have a disallowed type - return typing.cast(_SSH_CERT_PUBLIC_KEY_TYPES, self._public_key) + return typing.cast(SSHCertPublicKeyTypes, self._public_key) @property def serial(self) -> int: @@ -832,7 +832,7 @@ def critical_options(self) -> typing.Dict[bytes, bytes]: def extensions(self) -> typing.Dict[bytes, bytes]: return self._extensions - def signature_key(self) -> _SSH_CERT_PUBLIC_KEY_TYPES: + def signature_key(self) -> SSHCertPublicKeyTypes: sigformat = _lookup_kformat(self._sig_type) signature_key, sigkey_rest = sigformat.load_public(self._sig_key) _check_empty(sigkey_rest) @@ -891,7 +891,7 @@ def _get_ec_hash_alg(curve: ec.EllipticCurve) -> hashes.HashAlgorithm: def _load_ssh_public_identity( data: bytes, _legacy_dsa_allowed=False, -) -> typing.Union[SSHCertificate, _SSH_PUBLIC_KEY_TYPES]: +) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: utils._check_byteslike("data", data) m = _SSH_PUBKEY_RC.match(data) @@ -985,7 +985,7 @@ def _load_ssh_public_identity( def load_ssh_public_identity( data: bytes, -) -> typing.Union[SSHCertificate, _SSH_PUBLIC_KEY_TYPES]: +) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: return _load_ssh_public_identity(data) @@ -1007,9 +1007,9 @@ def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: def load_ssh_public_key( data: bytes, backend: typing.Any = None -) -> _SSH_PUBLIC_KEY_TYPES: +) -> SSHPublicKeyTypes: cert_or_key = _load_ssh_public_identity(data, _legacy_dsa_allowed=True) - public_key: _SSH_PUBLIC_KEY_TYPES + public_key: SSHPublicKeyTypes if isinstance(cert_or_key, SSHCertificate): public_key = cert_or_key.public_key() else: @@ -1025,7 +1025,7 @@ def load_ssh_public_key( return public_key -def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: +def serialize_ssh_public_key(public_key: SSHPublicKeyTypes) -> bytes: """One-line public key format for OpenSSH""" if isinstance(public_key, dsa.DSAPublicKey): warnings.warn( @@ -1045,7 +1045,7 @@ def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: return b"".join([key_type, b" ", pub]) -_SSH_CERT_PRIVATE_KEY_TYPES = typing.Union[ +SSHCertPrivateKeyTypes = typing.Union[ ec.EllipticCurvePrivateKey, rsa.RSAPrivateKey, ed25519.Ed25519PrivateKey, @@ -1060,7 +1060,7 @@ def serialize_ssh_public_key(public_key: _SSH_PUBLIC_KEY_TYPES) -> bytes: class SSHCertificateBuilder: def __init__( self, - _public_key: typing.Optional[_SSH_CERT_PUBLIC_KEY_TYPES] = None, + _public_key: typing.Optional[SSHCertPublicKeyTypes] = None, _serial: typing.Optional[int] = None, _type: typing.Optional[SSHCertificateType] = None, _key_id: typing.Optional[bytes] = None, @@ -1083,7 +1083,7 @@ def __init__( self._extensions = _extensions def public_key( - self, public_key: _SSH_CERT_PUBLIC_KEY_TYPES + self, public_key: SSHCertPublicKeyTypes ) -> "SSHCertificateBuilder": if not isinstance( public_key, @@ -1319,7 +1319,7 @@ def add_extension( _extensions=self._extensions + [(name, value)], ) - def sign(self, private_key: _SSH_CERT_PRIVATE_KEY_TYPES) -> SSHCertificate: + def sign(self, private_key: SSHCertPrivateKeyTypes) -> SSHCertificate: if not isinstance( private_key, ( diff --git a/src/cryptography/hazmat/primitives/twofactor/hotp.py b/src/cryptography/hazmat/primitives/twofactor/hotp.py index cbb22704bf72..260822214db9 100644 --- a/src/cryptography/hazmat/primitives/twofactor/hotp.py +++ b/src/cryptography/hazmat/primitives/twofactor/hotp.py @@ -11,7 +11,7 @@ from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512 from cryptography.hazmat.primitives.twofactor import InvalidToken -_ALLOWED_HASH_TYPES = typing.Union[SHA1, SHA256, SHA512] +HOTPHashTypes = typing.Union[SHA1, SHA256, SHA512] def _generate_uri( @@ -45,7 +45,7 @@ def __init__( self, key: bytes, length: int, - algorithm: _ALLOWED_HASH_TYPES, + algorithm: HOTPHashTypes, backend: typing.Any = None, enforce_key_length: bool = True, ) -> None: diff --git a/src/cryptography/hazmat/primitives/twofactor/totp.py b/src/cryptography/hazmat/primitives/twofactor/totp.py index 314dbef718af..c66fa1de13c9 100644 --- a/src/cryptography/hazmat/primitives/twofactor/totp.py +++ b/src/cryptography/hazmat/primitives/twofactor/totp.py @@ -7,8 +7,8 @@ from cryptography.hazmat.primitives import constant_time from cryptography.hazmat.primitives.twofactor import InvalidToken from cryptography.hazmat.primitives.twofactor.hotp import ( - _ALLOWED_HASH_TYPES, HOTP, + HOTPHashTypes, _generate_uri, ) @@ -18,7 +18,7 @@ def __init__( self, key: bytes, length: int, - algorithm: _ALLOWED_HASH_TYPES, + algorithm: HOTPHashTypes, time_step: int, backend: typing.Any = None, enforce_key_length: bool = True, diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index de1323529d2e..35c846d34eda 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -21,9 +21,9 @@ x25519, ) from cryptography.hazmat.primitives.asymmetric.types import ( - CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, - CERTIFICATE_PRIVATE_KEY_TYPES, - CERTIFICATE_PUBLIC_KEY_TYPES, + CertificateIssuerPrivateKeyTypes, + CertificateIssuerPublicKeyTypes, + CertificatePublicKeyTypes, ) from cryptography.x509.extensions import ( Extension, @@ -181,7 +181,7 @@ def version(self) -> Version: """ @abc.abstractmethod - def public_key(self) -> CERTIFICATE_PUBLIC_KEY_TYPES: + def public_key(self) -> CertificatePublicKeyTypes: """ Returns the public key """ @@ -459,7 +459,7 @@ def __iter__(self) -> typing.Iterator[RevokedCertificate]: @abc.abstractmethod def is_signature_valid( - self, public_key: CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES + self, public_key: CertificateIssuerPublicKeyTypes ) -> bool: """ Verifies signature of revocation list against given public key. @@ -483,7 +483,7 @@ def __hash__(self) -> int: """ @abc.abstractmethod - def public_key(self) -> CERTIFICATE_PUBLIC_KEY_TYPES: + def public_key(self) -> CertificatePublicKeyTypes: """ Returns the public key """ @@ -691,7 +691,7 @@ def add_attribute( def sign( self, - private_key: CERTIFICATE_PRIVATE_KEY_TYPES, + private_key: CertificateIssuerPrivateKeyTypes, algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> CertificateSigningRequest: @@ -710,7 +710,7 @@ def __init__( self, issuer_name: typing.Optional[Name] = None, subject_name: typing.Optional[Name] = None, - public_key: typing.Optional[CERTIFICATE_PUBLIC_KEY_TYPES] = None, + public_key: typing.Optional[CertificatePublicKeyTypes] = None, serial_number: typing.Optional[int] = None, not_valid_before: typing.Optional[datetime.datetime] = None, not_valid_after: typing.Optional[datetime.datetime] = None, @@ -763,7 +763,7 @@ def subject_name(self, name: Name) -> "CertificateBuilder": def public_key( self, - key: CERTIFICATE_PUBLIC_KEY_TYPES, + key: CertificatePublicKeyTypes, ) -> "CertificateBuilder": """ Sets the requestor's public key (as found in the signing request). @@ -912,7 +912,7 @@ def add_extension( def sign( self, - private_key: CERTIFICATE_PRIVATE_KEY_TYPES, + private_key: CertificateIssuerPrivateKeyTypes, algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> Certificate: @@ -1059,7 +1059,7 @@ def add_revoked_certificate( def sign( self, - private_key: CERTIFICATE_PRIVATE_KEY_TYPES, + private_key: CertificateIssuerPrivateKeyTypes, algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, ) -> CertificateRevocationList: diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index e0353662b632..551887b4a60d 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -16,14 +16,13 @@ from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.hazmat.primitives.asymmetric.types import ( - CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, - CERTIFICATE_PUBLIC_KEY_TYPES, + CertificateIssuerPublicKeyTypes, + CertificatePublicKeyTypes, ) from cryptography.x509.certificate_transparency import ( SignedCertificateTimestamp, ) from cryptography.x509.general_name import ( - _IPADDRESS_TYPES, DirectoryName, DNSName, GeneralName, @@ -32,6 +31,7 @@ RegisteredID, RFC822Name, UniformResourceIdentifier, + _IPAddressTypes, ) from cryptography.x509.name import Name, RelativeDistinguishedName from cryptography.x509.oid import ( @@ -47,7 +47,7 @@ def _key_identifier_from_public_key( - public_key: CERTIFICATE_PUBLIC_KEY_TYPES, + public_key: CertificatePublicKeyTypes, ) -> bytes: if isinstance(public_key, RSAPublicKey): data = public_key.public_bytes( @@ -213,14 +213,14 @@ def __init__( self._authority_cert_issuer = authority_cert_issuer self._authority_cert_serial_number = authority_cert_serial_number - # This takes a subset of CERTIFICATE_PUBLIC_KEY_TYPES because an issuer + # This takes a subset of CertificatePublicKeyTypes because an issuer # cannot have an X25519/X448 key. This introduces some unfortunate # asymmetry that requires typing users to explicitly # narrow their type, but we should make this accurate and not just # convenient. @classmethod def from_issuer_public_key( - cls, public_key: CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES + cls, public_key: CertificateIssuerPublicKeyTypes ) -> "AuthorityKeyIdentifier": digest = _key_identifier_from_public_key(public_key) return cls( @@ -293,7 +293,7 @@ def __init__(self, digest: bytes) -> None: @classmethod def from_public_key( - cls, public_key: CERTIFICATE_PUBLIC_KEY_TYPES + cls, public_key: CertificatePublicKeyTypes ) -> "SubjectKeyIdentifier": return cls(_key_identifier_from_public_key(public_key)) @@ -1464,7 +1464,7 @@ def get_values_for_type( @typing.overload def get_values_for_type( self, type: typing.Type[IPAddress] - ) -> typing.List[_IPADDRESS_TYPES]: + ) -> typing.List[_IPAddressTypes]: ... @typing.overload @@ -1485,7 +1485,7 @@ def get_values_for_type( typing.Type[UniformResourceIdentifier], ], ) -> typing.Union[ - typing.List[_IPADDRESS_TYPES], + typing.List[_IPAddressTypes], typing.List[str], typing.List[OtherName], typing.List[Name], @@ -1548,7 +1548,7 @@ def get_values_for_type( @typing.overload def get_values_for_type( self, type: typing.Type[IPAddress] - ) -> typing.List[_IPADDRESS_TYPES]: + ) -> typing.List[_IPAddressTypes]: ... @typing.overload @@ -1569,7 +1569,7 @@ def get_values_for_type( typing.Type[UniformResourceIdentifier], ], ) -> typing.Union[ - typing.List[_IPADDRESS_TYPES], + typing.List[_IPAddressTypes], typing.List[str], typing.List[OtherName], typing.List[Name], @@ -1629,7 +1629,7 @@ def get_values_for_type( @typing.overload def get_values_for_type( self, type: typing.Type[IPAddress] - ) -> typing.List[_IPADDRESS_TYPES]: + ) -> typing.List[_IPAddressTypes]: ... @typing.overload @@ -1650,7 +1650,7 @@ def get_values_for_type( typing.Type[UniformResourceIdentifier], ], ) -> typing.Union[ - typing.List[_IPADDRESS_TYPES], + typing.List[_IPAddressTypes], typing.List[str], typing.List[OtherName], typing.List[Name], @@ -1710,7 +1710,7 @@ def get_values_for_type( @typing.overload def get_values_for_type( self, type: typing.Type[IPAddress] - ) -> typing.List[_IPADDRESS_TYPES]: + ) -> typing.List[_IPAddressTypes]: ... @typing.overload @@ -1731,7 +1731,7 @@ def get_values_for_type( typing.Type[UniformResourceIdentifier], ], ) -> typing.Union[ - typing.List[_IPADDRESS_TYPES], + typing.List[_IPAddressTypes], typing.List[str], typing.List[OtherName], typing.List[Name], diff --git a/src/cryptography/x509/general_name.py b/src/cryptography/x509/general_name.py index 81de0ec77402..ce8367b078d1 100644 --- a/src/cryptography/x509/general_name.py +++ b/src/cryptography/x509/general_name.py @@ -11,7 +11,7 @@ from cryptography.x509.name import Name from cryptography.x509.oid import ObjectIdentifier -_IPADDRESS_TYPES = typing.Union[ +_IPAddressTypes = typing.Union[ ipaddress.IPv4Address, ipaddress.IPv6Address, ipaddress.IPv4Network, @@ -206,7 +206,7 @@ def __hash__(self) -> int: class IPAddress(GeneralName): - def __init__(self, value: _IPADDRESS_TYPES) -> None: + def __init__(self, value: _IPAddressTypes) -> None: if not isinstance( value, ( @@ -225,7 +225,7 @@ def __init__(self, value: _IPADDRESS_TYPES) -> None: self._value = value @property - def value(self) -> _IPADDRESS_TYPES: + def value(self) -> _IPAddressTypes: return self._value def _packed(self) -> bytes: diff --git a/src/cryptography/x509/ocsp.py b/src/cryptography/x509/ocsp.py index 70aa3b3619f9..857e75afc191 100644 --- a/src/cryptography/x509/ocsp.py +++ b/src/cryptography/x509/ocsp.py @@ -11,7 +11,7 @@ from cryptography.hazmat.bindings._rust import ocsp from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric.types import ( - CERTIFICATE_PRIVATE_KEY_TYPES, + CertificateIssuerPrivateKeyTypes, ) from cryptography.x509.base import ( _EARLIEST_UTC_TIME, @@ -587,7 +587,7 @@ def add_extension( def sign( self, - private_key: CERTIFICATE_PRIVATE_KEY_TYPES, + private_key: CertificateIssuerPrivateKeyTypes, algorithm: typing.Optional[hashes.HashAlgorithm], ) -> OCSPResponse: if self._response is None: diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 9d4208c65afc..2164890b8155 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -84,8 +84,8 @@ def _load_cert(filename, loader: typing.Callable[..., T]) -> T: def _generate_ca_and_leaf( - issuer_private_key: types.CERTIFICATE_PRIVATE_KEY_TYPES, - subject_private_key: types.CERTIFICATE_PRIVATE_KEY_TYPES, + issuer_private_key: types.CertificateIssuerPrivateKeyTypes, + subject_private_key: types.CertificateIssuerPrivateKeyTypes, ): if isinstance( issuer_private_key, From 3f31494624638b7673df15a8b82bc7740b2c5ef2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Mar 2023 21:28:55 +0800 Subject: [PATCH 409/827] Bump mypy from 1.0.1 to 1.1.1 (#8471) Bumps [mypy](https://github.com/python/mypy) from 1.0.1 to 1.1.1. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.0.1...v1.1.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d77e5e9b87e9..b8ff06a4b397 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -80,7 +80,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.1.0 # via jaraco-classes -mypy==1.0.1 +mypy==1.1.1 # via cryptography (setup.cfg) mypy-extensions==1.0.0 # via From 5c1fa2429f193074a926c42e75f9ebe125bf0ae4 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 00:19:10 +0000 Subject: [PATCH 410/827] Bump BoringSSL and/or OpenSSL in CI (#8472) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd2ad74f7edc..bc614bf1799f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "082e953a134ad423a00b8859f9daf5708e729260"}} - # Latest commit on the OpenSSL master branch, as of Mar 07, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "bf762f9203d3b5541c21f2b376750e32ebf36651"}} + # Latest commit on the BoringSSL master branch, as of Mar 08, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ecb722aeeb7ec6fcd2d6c60d177b9e952eab51f8"}} + # Latest commit on the OpenSSL master branch, as of Mar 08, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "931369429564b5a9bb09711de8e885fef546a0ac"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 7f54011429b26b49d086a0875b968365f26b57c4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Mar 2023 13:27:14 +0800 Subject: [PATCH 411/827] add EC key load benchmark (#8473) --- tests/bench/test_ec_load.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/bench/test_ec_load.py diff --git a/tests/bench/test_ec_load.py b/tests/bench/test_ec_load.py new file mode 100644 index 000000000000..568dbd96f449 --- /dev/null +++ b/tests/bench/test_ec_load.py @@ -0,0 +1,13 @@ +# 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. + +from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1 + + +def test_load_ec_public_numbers(benchmark): + benchmark(EC_KEY_SECP256R1.public_numbers.public_key) + + +def test_load_ec_private_numbers(benchmark): + benchmark(EC_KEY_SECP256R1.private_key) From 36f418a6877c60459259acb796fc886bdac64421 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 9 Mar 2023 19:02:46 +0800 Subject: [PATCH 412/827] add pytest flag to show percentage at all times (#8474) progress-even-when-capture-no isn't in a released pytest yet, but when https://github.com/pytest-dev/pytest/pull/10755 is released this will work. Until then this flag will simply have no effect. Also add a COLUMNS variable and pass it through to tox so we can limit column width to 80 in CI --- .github/workflows/ci.yml | 6 ++++++ pyproject.toml | 1 + tox.ini | 1 + 3 files changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc614bf1799f..65d41d5a237b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,7 @@ jobs: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof ${{ matrix.PYTHON.TOXARGS }} env: TOXENV: ${{ matrix.PYTHON.TOXENV }} + COLUMNS: 80 CRYPTOGRAPHY_OPENSSL_NO_LEGACY: ${{ matrix.PYTHON.OPENSSL.NO_LEGACY }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} @@ -191,6 +192,7 @@ jobs: - run: '/venv/bin/tox --skip-pkg-install -- --color=yes --wycheproof-root="wycheproof"' env: TOXENV: ${{ matrix.IMAGE.TOXENV }} + COLUMNS: 80 # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 - uses: ./.github/actions/upload-coverage @@ -248,6 +250,7 @@ jobs: run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} + COLUMNS: 80 - uses: ./.github/actions/upload-coverage linux-rust-coverage: @@ -325,6 +328,7 @@ jobs: run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} + COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} RUSTFLAGS: "-Cinstrument-coverage" LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" @@ -421,6 +425,7 @@ jobs: run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} + COLUMNS: 80 - uses: ./.github/actions/upload-coverage @@ -480,6 +485,7 @@ jobs: run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof --num-shards=2 --shard-id=${{ matrix.JOB_NUMBER }} env: TOXENV: ${{ matrix.PYTHON.TOXENV }} + COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - uses: ./.github/actions/upload-coverage diff --git a/pyproject.toml b/pyproject.toml index 8460cfdd551f..d79a4d314d7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ target-version = ["py36"] [tool.pytest.ini_options] addopts = "-r s --capture=no --strict-markers --benchmark-disable --no-subtests-shortletter" +console_output_style = "progress-even-when-capture-no" markers = [ "skip_fips: this test is not executed in FIPS mode", "supported: parametrized test requiring only_if and skip_message", diff --git a/tox.ini b/tox.ini index 6e6e60c101fb..3a8737f28443 100644 --- a/tox.ini +++ b/tox.ini @@ -16,6 +16,7 @@ passenv = LDFLAGS CFLAGS CL + COLUMNS INCLUDE LIB LD_LIBRARY_PATH From 56bcc522b0ab69c82f3381da1507d4dca0b03ffc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 9 Mar 2023 19:06:01 +0800 Subject: [PATCH 413/827] replace use of EC_KEY_set_public_key_affine_coordinates (#8475) EC_KEY_set_public_key_affine_coordinates calls EC_KEY_check_key, which checks the point isn't at infinity, that it is on the curve (which has already been done by EC_POINT_set_affine_coordinates), and that the private scalar matches the public point. We don't want to do expensive checks twice, so instead we swap to calling EC_POINT_set_affine_coordinates directly and implement a private scalar matches public point check of our own. Also we no longer call deprecated functions. --- src/_cffi_src/openssl/ec.py | 5 ++- .../hazmat/backends/openssl/backend.py | 43 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/_cffi_src/openssl/ec.py b/src/_cffi_src/openssl/ec.py index 0c7e0545e67d..b037675f0d68 100644 --- a/src/_cffi_src/openssl/ec.py +++ b/src/_cffi_src/openssl/ec.py @@ -45,11 +45,14 @@ int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *); void EC_KEY_set_asn1_flag(EC_KEY *, int); int EC_KEY_generate_key(EC_KEY *); -int EC_KEY_set_public_key_affine_coordinates(EC_KEY *, BIGNUM *, BIGNUM *); EC_POINT *EC_POINT_new(const EC_GROUP *); void EC_POINT_free(EC_POINT *); +int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *, const EC_POINT *, + BN_CTX *); +int EC_POINT_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, BN_CTX *); int EC_POINT_get_affine_coordinates(const EC_GROUP *, const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 846af1e2e7a6..da9200460d50 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1284,6 +1284,35 @@ def load_elliptic_curve_private_numbers( self._ec_key_set_public_key_affine_coordinates( ec_cdata, public.x, public.y ) + # derive the expected public point and compare it to the one we just + # set based on the values we were given. If they don't match this + # isn't a valid key pair. + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + set_point = backend._lib.EC_KEY_get0_public_key(ec_cdata) + self.openssl_assert(set_point != self._ffi.NULL) + with self._tmp_bn_ctx() as bn_ctx: + computed_point = self._lib.EC_POINT_new(group) + self.openssl_assert(computed_point != self._ffi.NULL) + computed_point = self._ffi.gc( + computed_point, self._lib.EC_POINT_free + ) + res = self._lib.EC_POINT_mul( + group, + computed_point, + private_value, + self._ffi.NULL, + self._ffi.NULL, + bn_ctx, + ) + self.openssl_assert(res == 1) + if ( + self._lib.EC_POINT_cmp( + group, set_point, computed_point, bn_ctx + ) + != 0 + ): + raise ValueError("Invalid EC key.") evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) @@ -1420,7 +1449,7 @@ def _tmp_bn_ctx(self): self._lib.BN_CTX_end(bn_ctx) def _ec_key_set_public_key_affine_coordinates( - self, ctx, x: int, y: int + self, ec_cdata, x: int, y: int ) -> None: """ Sets the public key point in the EC_KEY context to the affine x and y @@ -1434,10 +1463,20 @@ def _ec_key_set_public_key_affine_coordinates( x = self._ffi.gc(self._int_to_bn(x), self._lib.BN_free) y = self._ffi.gc(self._int_to_bn(y), self._lib.BN_free) - res = self._lib.EC_KEY_set_public_key_affine_coordinates(ctx, x, y) + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + point = self._lib.EC_POINT_new(group) + self.openssl_assert(point != self._ffi.NULL) + point = self._ffi.gc(point, self._lib.EC_POINT_free) + with self._tmp_bn_ctx() as bn_ctx: + res = self._lib.EC_POINT_set_affine_coordinates( + group, point, x, y, bn_ctx + ) if res != 1: self._consume_errors() raise ValueError("Invalid EC key.") + res = self._lib.EC_KEY_set_public_key(ec_cdata, point) + self.openssl_assert(res == 1) def _private_key_bytes( self, From b45cef04832b96596a6229e32951f9ce4ec9b30b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 08:20:11 -0500 Subject: [PATCH 414/827] Bump actions/cache from 3.2.6 to 3.3.0 in /.github/actions/cache (#8478) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.6 to 3.3.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.6...v3.3.0) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/cache/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 29492a0dd846..a40397e7623a 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -30,7 +30,7 @@ runs: echo "dir=$(python -m pip cache dir)" >> $GITHUB_OUTPUT fi shell: bash - - uses: actions/cache@v3.2.6 + - uses: actions/cache@v3.3.0 id: cache with: path: | From a8e5fca2c2265266fe135aed6b0289c51caa4818 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Mar 2023 08:26:14 -0500 Subject: [PATCH 415/827] Small cleanups: (#8476) - Avoid typing.cast - Consolidate bn_ctx allocations --- .../hazmat/backends/openssl/backend.py | 40 ++++++++++--------- tests/x509/test_x509.py | 14 ++----- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index da9200460d50..a8964f365148 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1281,17 +1281,17 @@ def load_elliptic_curve_private_numbers( self._consume_errors() raise ValueError("Invalid EC key.") - self._ec_key_set_public_key_affine_coordinates( - ec_cdata, public.x, public.y - ) - # derive the expected public point and compare it to the one we just - # set based on the values we were given. If they don't match this - # isn't a valid key pair. - group = self._lib.EC_KEY_get0_group(ec_cdata) - self.openssl_assert(group != self._ffi.NULL) - set_point = backend._lib.EC_KEY_get0_public_key(ec_cdata) - self.openssl_assert(set_point != self._ffi.NULL) with self._tmp_bn_ctx() as bn_ctx: + self._ec_key_set_public_key_affine_coordinates( + ec_cdata, public.x, public.y, bn_ctx + ) + # derive the expected public point and compare it to the one we + # just set based on the values we were given. If they don't match + # this isn't a valid key pair. + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + set_point = backend._lib.EC_KEY_get0_public_key(ec_cdata) + self.openssl_assert(set_point != self._ffi.NULL) computed_point = self._lib.EC_POINT_new(group) self.openssl_assert(computed_point != self._ffi.NULL) computed_point = self._ffi.gc( @@ -1322,9 +1322,10 @@ def load_elliptic_curve_public_numbers( self, numbers: ec.EllipticCurvePublicNumbers ) -> ec.EllipticCurvePublicKey: ec_cdata = self._ec_key_new_by_curve(numbers.curve) - self._ec_key_set_public_key_affine_coordinates( - ec_cdata, numbers.x, numbers.y - ) + with self._tmp_bn_ctx() as bn_ctx: + self._ec_key_set_public_key_affine_coordinates( + ec_cdata, numbers.x, numbers.y, bn_ctx + ) evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) @@ -1449,7 +1450,11 @@ def _tmp_bn_ctx(self): self._lib.BN_CTX_end(bn_ctx) def _ec_key_set_public_key_affine_coordinates( - self, ec_cdata, x: int, y: int + self, + ec_cdata, + x: int, + y: int, + bn_ctx, ) -> None: """ Sets the public key point in the EC_KEY context to the affine x and y @@ -1468,10 +1473,9 @@ def _ec_key_set_public_key_affine_coordinates( point = self._lib.EC_POINT_new(group) self.openssl_assert(point != self._ffi.NULL) point = self._ffi.gc(point, self._lib.EC_POINT_free) - with self._tmp_bn_ctx() as bn_ctx: - res = self._lib.EC_POINT_set_affine_coordinates( - group, point, x, y, bn_ctx - ) + res = self._lib.EC_POINT_set_affine_coordinates( + group, point, x, y, bn_ctx + ) if res != 1: self._consume_errors() raise ValueError("Invalid EC key.") diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 2164890b8155..736c0113ec82 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -4125,11 +4125,8 @@ def test_build_ca_request_with_ed25519(self, backend): assert list(subject) == [ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Texas"), ] - basic_constraints = typing.cast( - x509.Extension[x509.BasicConstraints], - request.extensions.get_extension_for_oid( - ExtensionOID.BASIC_CONSTRAINTS - ), + basic_constraints = request.extensions.get_extension_for_class( + x509.BasicConstraints ) assert basic_constraints.value.ca is True assert basic_constraints.value.path_length == 2 @@ -4166,11 +4163,8 @@ def test_build_ca_request_with_ed448(self, backend): assert list(subject) == [ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Texas"), ] - basic_constraints = typing.cast( - x509.Extension[x509.BasicConstraints], - request.extensions.get_extension_for_oid( - ExtensionOID.BASIC_CONSTRAINTS - ), + basic_constraints = request.extensions.get_extension_for_class( + x509.BasicConstraints ) assert basic_constraints.value.ca is True assert basic_constraints.value.path_length == 2 From b6246e4658e4ffe72fa7ea33e6ebd8b4a4523964 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 13:26:36 +0000 Subject: [PATCH 416/827] Bump actions/cache from 3.2.6 to 3.3.0 (#8477) Bumps [actions/cache](https://github.com/actions/cache) from 3.2.6 to 3.3.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.6...v3.3.0) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65d41d5a237b..d39624f1b6c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load OpenSSL cache - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 id: ossl-cache timeout-minutes: 2 with: From 7ae97f8988b7bf151aea3ed9acf690a989f6f608 Mon Sep 17 00:00:00 2001 From: Alexandre Duc Date: Thu, 9 Mar 2023 18:24:55 +0100 Subject: [PATCH 417/827] On Windows, os.urandom doesn't use CryptGenRandom anymore (deprecated) (#8481) but BCryptGenRandom() --- docs/random-numbers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/random-numbers.rst b/docs/random-numbers.rst index 6161563a1fd3..e6562d7cbc94 100644 --- a/docs/random-numbers.rst +++ b/docs/random-numbers.rst @@ -18,7 +18,7 @@ you can obtain them with: >>> import os >>> iv = os.urandom(16) -This will use ``/dev/urandom`` on UNIX platforms, and ``CryptGenRandom`` on +This will use ``/dev/urandom`` on UNIX platforms, and ``BCryptGenRandom()`` on Windows. If you need your random number as an integer (for example, for From 31f0dcabdafbef6214d78f56f7a31f56caeeb568 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Mar 2023 16:17:42 -0500 Subject: [PATCH 418/827] Cache some keys that are reused in wycheproof tests (#8479) --- tests/utils.py | 15 +++++++--- tests/wycheproof/test_ecdsa.py | 7 +++-- tests/wycheproof/test_rsa.py | 53 ++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index dd3238fa97f1..e781f1afb3b0 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -899,20 +899,27 @@ def __repr__(self): ) @property - def valid(self): + def valid(self) -> bool: return self.testcase["result"] == "valid" @property - def acceptable(self): + def acceptable(self) -> bool: return self.testcase["result"] == "acceptable" @property - def invalid(self): + def invalid(self) -> bool: return self.testcase["result"] == "invalid" - def has_flag(self, flag): + def has_flag(self, flag: str) -> bool: return flag in self.testcase["flags"] + def cache_group_value(self, cache_key: str, func): + cache_val = self.testgroup.get(cache_key) + if cache_val is not None: + return cache_val + self.testgroup[cache_key] = cache_val = func(self.testgroup) + return cache_val + def load_wycheproof_tests(wycheproof, test_file): path = os.path.join(wycheproof, "testvectors", test_file) diff --git a/tests/wycheproof/test_ecdsa.py b/tests/wycheproof/test_ecdsa.py index c958c8397f19..75f9d4413d50 100644 --- a/tests/wycheproof/test_ecdsa.py +++ b/tests/wycheproof/test_ecdsa.py @@ -61,8 +61,11 @@ ) def test_ecdsa_signature(backend, wycheproof): try: - key = serialization.load_der_public_key( - binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend + key = wycheproof.cache_group_value( + "cache_key", + lambda group: serialization.load_der_public_key( + binascii.unhexlify(group["keyDer"]), backend + ), ) assert isinstance(key, ec.EllipticCurvePublicKey) except (UnsupportedAlgorithm, ValueError): diff --git a/tests/wycheproof/test_rsa.py b/tests/wycheproof/test_rsa.py index 8ce1f8cbd854..14f6b478e248 100644 --- a/tests/wycheproof/test_rsa.py +++ b/tests/wycheproof/test_rsa.py @@ -63,8 +63,11 @@ def should_verify(backend, wycheproof): "rsa_signature_4096_sha512_256_test.json", ) def test_rsa_pkcs1v15_signature(backend, wycheproof): - key = serialization.load_der_public_key( - binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend + key = wycheproof.cache_group_value( + "cached_key", + lambda group: serialization.load_der_public_key( + binascii.unhexlify(group["keyDer"]), backend + ), ) assert isinstance(key, rsa.RSAPublicKey) digest = _DIGESTS[wycheproof.testgroup["sha"]] @@ -93,13 +96,16 @@ def test_rsa_pkcs1v15_signature(backend, wycheproof): @wycheproof_tests("rsa_sig_gen_misc_test.json") def test_rsa_pkcs1v15_signature_generation(backend, wycheproof): - key = serialization.load_pem_private_key( - wycheproof.testgroup["privateKeyPem"].encode(), - password=None, - backend=backend, - unsafe_skip_rsa_key_validation=True, + key = wycheproof.cache_group_value( + "cached_key", + lambda group: serialization.load_pem_private_key( + group["privateKeyPem"].encode("ascii"), + password=None, + unsafe_skip_rsa_key_validation=True, + ), ) assert isinstance(key, rsa.RSAPrivateKey) + digest = _DIGESTS[wycheproof.testgroup["sha"]] assert digest is not None if backend._fips_enabled: @@ -135,8 +141,12 @@ def test_rsa_pss_signature(backend, wycheproof): digest = _DIGESTS[wycheproof.testgroup["sha"]] if backend._fips_enabled and isinstance(digest, hashes.SHA1): pytest.skip("Invalid params for FIPS. SHA1 is disallowed") - key = serialization.load_der_public_key( - binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend + + key = wycheproof.cache_group_value( + "cached_key", + lambda group: serialization.load_der_public_key( + binascii.unhexlify(group["keyDer"]), backend + ), ) assert isinstance(key, rsa.RSAPublicKey) mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]] @@ -207,11 +217,14 @@ def test_rsa_oaep_encryption(backend, wycheproof): f"Does not support OAEP using {mgf_digest.name} MGF1 " f"or {digest.name} hash." ) - key = serialization.load_pem_private_key( - wycheproof.testgroup["privateKeyPem"].encode("ascii"), - password=None, - backend=backend, - unsafe_skip_rsa_key_validation=True, + + key = wycheproof.cache_group_value( + "cached_key", + lambda group: serialization.load_pem_private_key( + group["privateKeyPem"].encode("ascii"), + password=None, + unsafe_skip_rsa_key_validation=True, + ), ) assert isinstance(key, rsa.RSAPrivateKey) if backend._fips_enabled and key.key_size < backend._fips_rsa_min_key_size: @@ -241,11 +254,13 @@ def test_rsa_oaep_encryption(backend, wycheproof): "rsa_pkcs1_4096_test.json", ) def test_rsa_pkcs1_encryption(backend, wycheproof): - key = serialization.load_pem_private_key( - wycheproof.testgroup["privateKeyPem"].encode("ascii"), - password=None, - backend=backend, - unsafe_skip_rsa_key_validation=True, + key = wycheproof.cache_group_value( + "cached_key", + lambda group: serialization.load_pem_private_key( + group["privateKeyPem"].encode("ascii"), + password=None, + unsafe_skip_rsa_key_validation=True, + ), ) assert isinstance(key, rsa.RSAPrivateKey) From f84327556ac3bd48645ca7491ffcb2cc3c09f379 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Mar 2023 16:19:39 -0500 Subject: [PATCH 419/827] remove out of date details in random numbers docs (#8482) --- docs/random-numbers.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/random-numbers.rst b/docs/random-numbers.rst index e6562d7cbc94..5d6fd3d89736 100644 --- a/docs/random-numbers.rst +++ b/docs/random-numbers.rst @@ -18,16 +18,13 @@ you can obtain them with: >>> import os >>> iv = os.urandom(16) -This will use ``/dev/urandom`` on UNIX platforms, and ``BCryptGenRandom()`` on -Windows. -If you need your random number as an integer (for example, for -:meth:`~cryptography.x509.CertificateBuilder.serial_number`), you can use +If you need your random number as an big integer, you can use ``int.from_bytes`` to convert the result of ``os.urandom``: .. code-block:: pycon - >>> serial = int.from_bytes(os.urandom(20), byteorder="big") + >>> serial = int.from_bytes(os.urandom(16), byteorder="big") In addition, the `Python standard library`_ includes the ``secrets`` module, which can be used for generating cryptographically secure random numbers, with From ab008041c468cb24a419900e76899937dd242c52 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Mar 2023 16:23:28 -0500 Subject: [PATCH 420/827] use cargo sparse registry in distro CI (#8480) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d39624f1b6c9..24af3be70cee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -145,6 +145,8 @@ jobs: - {IMAGE: "ubuntu-jammy:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - name: Ridiculous alpine workaround for actions support on arm64 run: | From d69a28ab060f9280c9bcfd54ec111caaff367c7e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Mar 2023 16:25:11 -0500 Subject: [PATCH 421/827] Use action-download-artifact to simplify CI (#8484) --- .github/workflows/ci.yml | 40 ++++++++---- .github/workflows/download_openssl.py | 92 --------------------------- .github/workflows/wheel-builder.yml | 46 ++++++-------- 3 files changed, 47 insertions(+), 131 deletions(-) delete mode 100644 .github/workflows/download_openssl.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24af3be70cee..55730337d496 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Compute config hash and set config vars run: | DEFAULT_CONFIG_FLAGS="shared no-ssl2 no-ssl3" @@ -402,22 +402,26 @@ jobs: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' requests coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - name: Download OpenSSL - run: | - python .github/workflows/download_openssl.py macos openssl-macos-universal2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + with: + repo: pyca/infra + workflow: build-macos-openssl.yml + branch: main + workflow_conclusion: success + name: openssl-macos-universal2 + path: "../openssl-macos-universal2/" + github_token: ${{ secrets.GITHUB_TOKEN }} - name: Build toxenv run: | CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ - LDFLAGS="${HOME}/openssl-macos-universal2/lib/libcrypto.a ${HOME}/openssl-macos-universal2/lib/libssl.a" \ - CFLAGS="-I${HOME}/openssl-macos-universal2/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ + LDFLAGS="$(readlink -f ../openssl-macos-universal2/lib/libcrypto.a) $(readlink -f ../openssl-macos-universal2/lib/libssl.a)" \ + CFLAGS="-I$(readlink -f ../openssl-macos-universal2/include) -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ tox -vvv --notest env: TOXENV: ${{ matrix.PYTHON.TOXENV }} @@ -464,16 +468,24 @@ jobs: timeout-minutes: 2 with: key: ${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" requests coverage[toml] - - name: Download OpenSSL + - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" coverage[toml] + + - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + with: + repo: pyca/infra + workflow: build-windows-openssl.yml + branch: main + workflow_conclusion: success + name: "openssl-${{ matrix.WINDOWS.WINDOWS }}" + path: "C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/" + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Configure run: | - python .github/workflows/download_openssl.py windows openssl-${{ matrix.WINDOWS.WINDOWS }} echo "INCLUDE=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/include;$INCLUDE" >> $GITHUB_ENV echo "LIB=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/lib;$LIB" >> $GITHUB_ENV echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash + - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof diff --git a/.github/workflows/download_openssl.py b/.github/workflows/download_openssl.py deleted file mode 100644 index 4341337e67f2..000000000000 --- a/.github/workflows/download_openssl.py +++ /dev/null @@ -1,92 +0,0 @@ -# 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. - -import io -import os -import sys -import time -import zipfile - -import requests -from urllib3.util.retry import Retry - - -def get_response(session, url, token): - # Retry on non-502s - for i in range(5): - try: - response = session.get( - url, headers={"Authorization": "token " + token} - ) - except ( - requests.exceptions.ChunkedEncodingError, - requests.exceptions.ConnectTimeout, - ) as e: - print(f"Exception ({e}) fetching {url}, retrying") - time.sleep(2) - continue - if response.status_code != 200: - print( - "HTTP error ({}) fetching {}, retrying".format( - response.status_code, url - ) - ) - time.sleep(2) - continue - return response - response = session.get(url, headers={"Authorization": "token " + token}) - if response.status_code != 200: - raise ValueError(f"Got HTTP {response.status_code} fetching {url}: ") - return response - - -def main(platform, target): - if platform == "windows": - workflow = "build-windows-openssl.yml" - path = "C:/" - elif platform == "macos": - workflow = "build-macos-openssl.yml" - path = os.environ["HOME"] - else: - raise ValueError("Invalid platform") - - session = requests.Session() - adapter = requests.adapters.HTTPAdapter(max_retries=Retry()) - session.mount("https://", adapter) - session.mount("https://", adapter) - - token = os.environ["GITHUB_TOKEN"] - print(f"Looking for: {target}") - runs_url = ( - "https://api.github.com/repos/pyca/infra/actions/workflows/" - "{}/runs?branch=main&status=success".format(workflow) - ) - - response = get_response(session, runs_url, token).json() - # We see this happen occasionally. Maybe this will help debug it + retry - # for resilience. - if not response["workflow_runs"]: - print( - f"`workflow_runs` is empty for some reason, retrying. response: " - f"{response}" - ) - response = get_response(session, runs_url, token).json() - - artifacts_url = response["workflow_runs"][0]["artifacts_url"] - response = get_response(session, artifacts_url, token).json() - for artifact in response["artifacts"]: - if artifact["name"] == target: - print("Found artifact") - response = get_response( - session, artifact["archive_download_url"], token - ) - zipfile.ZipFile(io.BytesIO(response.content)).extractall( - os.path.join(path, artifact["name"]) - ) - return - raise ValueError(f"Didn't find {target} in {response}") - - -if __name__ == "__main__": - main(sys.argv[1], sys.argv[2]) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index aefb19a22a51..ae6b10a269a6 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -175,12 +175,6 @@ jobs: ARCHFLAGS: '-arch x86_64' name: "${{ matrix.PYTHON.VERSION }} ABI ${{ matrix.PYTHON.ABI_VERSION }} macOS ${{ matrix.PYTHON.ARCHFLAGS }}" steps: - # Needed for download_openssl.py - - uses: actions/checkout@v3.3.0 - with: - # The tag to build or the tag received by the tag event - ref: ${{ github.event.inputs.version || github.ref }} - persist-credentials: false - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist @@ -197,12 +191,15 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') - - run: ${{ matrix.PYTHON.BIN_PATH }} -m pip install -c ci-constraints-requirements.txt -U requests - - name: Download OpenSSL - run: | - ${{ matrix.PYTHON.BIN_PATH }} .github/workflows/download_openssl.py macos openssl-macos-universal2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + with: + repo: pyca/infra + workflow: build-macos-openssl.yml + branch: main + workflow_conclusion: success + name: openssl-macos-universal2 + path: "../openssl-macos-universal2/" + github_token: ${{ secrets.GITHUB_TOKEN }} - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff with: toolchain: stable @@ -216,8 +213,8 @@ jobs: run: | cd cryptography* CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS="1" \ - LDFLAGS="${HOME}/openssl-macos-universal2/lib/libcrypto.a ${HOME}/openssl-macos-universal2/lib/libssl.a" \ - CFLAGS="-I${HOME}/openssl-macos-universal2/include" \ + LDFLAGS="../../openssl-macos-universal2/lib/libcrypto.a ../../openssl-macos-universal2/lib/libssl.a" \ + CFLAGS="-I../../openssl-macos-universal2/include" \ ../venv/bin/python setup.py bdist_wheel --py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} && mv dist/cryptography*.whl ../wheelhouse env: MACOSX_DEPLOYMENT_TARGET: ${{ matrix.PYTHON.DEPLOYMENT_TARGET }} @@ -260,12 +257,6 @@ jobs: PYTHON: {VERSION: "pypy-3.9"} name: "${{ matrix.PYTHON.VERSION }} ${{ matrix.WINDOWS.WINDOWS }} ${{ matrix.PYTHON.ABI_VERSION }}" steps: - # Needed for download_openssl.py - - uses: actions/checkout@v3.3.0 - with: - # The tag to build or the tag received by the tag event - ref: ${{ github.event.inputs.version || github.ref }} - persist-credentials: false - uses: actions/download-artifact@v3.0.2 with: name: cryptography-sdist @@ -280,14 +271,19 @@ jobs: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} - - run: pip install -c ci-constraints-requirements.txt requests - - name: Download OpenSSL + - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + with: + repo: pyca/infra + workflow: build-windows-openssl.yml + branch: main + workflow_conclusion: success + name: "openssl-${{ matrix.WINDOWS.WINDOWS }}" + path: "C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/" + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Configure OpenSSL run: | - python .github/workflows/download_openssl.py windows openssl-${{ matrix.WINDOWS.WINDOWS }} echo "INCLUDE=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/include;$INCLUDE" >> $GITHUB_ENV echo "LIB=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/lib;$LIB" >> $GITHUB_ENV - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - run: python -m pip install -U pip wheel From 0e9853f717d79491f386588cd5e602bda15222fa Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 08:54:55 +0800 Subject: [PATCH 422/827] Bump BoringSSL and/or OpenSSL in CI (#8485) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55730337d496..132b863dcb9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 08, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "ecb722aeeb7ec6fcd2d6c60d177b9e952eab51f8"}} + # Latest commit on the BoringSSL master branch, as of Mar 10, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "8aa51ddfcf1fbf2e5f976762657e21c7aee2f922"}} # Latest commit on the OpenSSL master branch, as of Mar 08, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "931369429564b5a9bb09711de8e885fef546a0ac"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From f046fd5844b7b575ee4f4a810b1510b07532d369 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 10 Mar 2023 10:07:34 +0800 Subject: [PATCH 423/827] speed up RSA key loading in tests a bit more (#8486) --- tests/hazmat/backends/test_openssl.py | 16 +++++---- tests/hazmat/primitives/test_pkcs7.py | 6 ++-- tests/hazmat/primitives/test_serialization.py | 36 +++++++++++++------ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 6188689cdd75..6f3f4a2bf508 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -28,12 +28,16 @@ DummyHashAlgorithm, DummyMode, ) +from ...hazmat.primitives.test_rsa import rsa_key_512, rsa_key_2048 from ...utils import ( load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm, ) -from ..primitives.fixtures_rsa import RSA_KEY_512, RSA_KEY_2048 + +# Make ruff happy since we're importing fixtures that pytest patches in as +# func args +__all__ = ["rsa_key_512", "rsa_key_2048"] def skip_if_libre_ssl(openssl_version): @@ -433,10 +437,9 @@ def test_rsa_padding_unsupported_mgf(self): is False ) - def test_unsupported_mgf1_hash_algorithm_md5_decrypt(self): - private_key = RSA_KEY_512.private_key(backend) + def test_unsupported_mgf1_hash_algorithm_md5_decrypt(self, rsa_key_512): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): - private_key.decrypt( + rsa_key_512.decrypt( b"0" * 64, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.MD5()), @@ -516,11 +519,10 @@ def test_sn_to_elliptic_curve_not_supported(self): class TestRSAPEMSerialization: - def test_password_length_limit(self): + def test_password_length_limit(self, rsa_key_2048): password = b"x" * 1024 - key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): - key.private_bytes( + rsa_key_2048.private_bytes( serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.BestAvailableEncryption(password), diff --git a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py index d879563e17d9..88de12ff5bb9 100644 --- a/tests/hazmat/primitives/test_pkcs7.py +++ b/tests/hazmat/primitives/test_pkcs7.py @@ -150,7 +150,7 @@ def _load_cert_key(): key = load_vectors_from_file( os.path.join("x509", "custom", "ca", "ca_key.pem"), lambda pemfile: serialization.load_pem_private_key( - pemfile.read(), None + pemfile.read(), None, unsafe_skip_rsa_key_validation=True ), mode="rb", ) @@ -599,7 +599,7 @@ def test_multiple_signers(self, backend): rsa_key = load_vectors_from_file( os.path.join("x509", "custom", "ca", "rsa_key.pem"), lambda pemfile: serialization.load_pem_private_key( - pemfile.read(), None + pemfile.read(), None, unsafe_skip_rsa_key_validation=True ), mode="rb", ) @@ -636,7 +636,7 @@ def test_multiple_signers_different_hash_algs(self, backend): rsa_key = load_vectors_from_file( os.path.join("x509", "custom", "ca", "rsa_key.pem"), lambda pemfile: serialization.load_pem_private_key( - pemfile.read(), None + pemfile.read(), None, unsafe_skip_rsa_key_validation=True ), mode="rb", ) diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 6ea5498fd5f4..59a141d3395a 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -36,10 +36,14 @@ from cryptography.hazmat.primitives.serialization.pkcs12 import PBES from ...utils import load_vectors_from_file -from .fixtures_rsa import RSA_KEY_2048 from .test_ec import _skip_curve_unsupported +from .test_rsa import rsa_key_2048 from .utils import _check_dsa_private_numbers, _check_rsa_private_numbers +# Make ruff happy since we're importing fixtures that pytest patches in as +# func args +__all__ = ["rsa_key_2048"] + def _skip_fips_format(key_path, password, backend): if backend._fips_enabled: @@ -77,7 +81,9 @@ def test_load_der_rsa_private_key(self, key_path, password, backend): lambda derfile: derfile.read(), mode="rb", ) - key = load_der_private_key(bytearray(data), password, backend) + key = load_der_private_key( + bytearray(data), password, unsafe_skip_rsa_key_validation=True + ) assert key assert isinstance(key, rsa.RSAPrivateKey) _check_rsa_private_numbers(key.private_numbers()) @@ -105,7 +111,9 @@ def test_load_pem_rsa_private_key(self, key_path, password, backend): lambda pemfile: pemfile.read(), mode="rb", ) - key = load_pem_private_key(bytearray(data), password, backend) + key = load_pem_private_key( + bytearray(data), password, unsafe_skip_rsa_key_validation=True + ) assert key assert isinstance(key, rsa.RSAPrivateKey) _check_rsa_private_numbers(key.private_numbers()) @@ -126,7 +134,7 @@ def test_load_der_rsa_private_key(self, key_path, password, backend): key = load_vectors_from_file( os.path.join("asymmetric", *key_path), lambda derfile: load_der_private_key( - derfile.read(), password, backend + derfile.read(), password, unsafe_skip_rsa_key_validation=True ), mode="rb", ) @@ -426,7 +434,9 @@ def test_load_pem_rsa_private_key(self, key_file, password, backend): key = load_vectors_from_file( os.path.join("asymmetric", *key_file), lambda pemfile: load_pem_private_key( - pemfile.read().encode(), password, backend + pemfile.read().encode(), + password, + unsafe_skip_rsa_key_validation=True, ), ) @@ -506,13 +516,15 @@ def test_load_pem_rsa_public_key(self, key_file, backend): numbers = key.public_numbers() assert numbers.e == 65537 - def test_load_priv_key_with_public_key_api_fails(self, backend): + def test_load_priv_key_with_public_key_api_fails( + self, rsa_key_2048, backend + ): # In OpenSSL 3.0.x the PEM_read_bio_PUBKEY function will invoke # the default password callback if you pass an encrypted private # key. This is very, very, very bad as the default callback can # trigger an interactive console prompt, which will hang the # Python process. This test makes sure we don't do that. - priv_key_serialized = RSA_KEY_2048.private_key().private_bytes( + priv_key_serialized = rsa_key_2048.private_bytes( Encoding.PEM, PrivateFormat.PKCS8, BestAvailableEncryption(b"password"), @@ -567,7 +579,9 @@ def test_rsa_traditional_encrypted_values(self, backend): "asymmetric", "Traditional_OpenSSL_Serialization", "key1.pem" ), lambda pemfile: load_pem_private_key( - pemfile.read().encode(), b"123456", backend + pemfile.read().encode(), + b"123456", + unsafe_skip_rsa_key_validation=True, ), ) assert isinstance(pkey, rsa.RSAPrivateKey) @@ -631,7 +645,7 @@ def test_invalid_encoding_with_traditional(self, backend): key = load_vectors_from_file( key_file, lambda pemfile: load_pem_private_key( - pemfile.read(), None, backend + pemfile.read(), None, unsafe_skip_rsa_key_validation=True ), mode="rb", ) @@ -866,7 +880,9 @@ def test_rsa_pkcs8_encrypted_values(self, backend): pkey = load_vectors_from_file( os.path.join("asymmetric", "PKCS8", "enc-rsa-pkcs8.pem"), lambda pemfile: load_pem_private_key( - pemfile.read().encode(), b"foobar", backend + pemfile.read().encode(), + b"foobar", + unsafe_skip_rsa_key_validation=True, ), ) assert isinstance(pkey, rsa.RSAPrivateKey) From d85db128fb782130b5cda938d643c6fcb49a1481 Mon Sep 17 00:00:00 2001 From: shane-kearns Date: Fri, 10 Mar 2023 12:16:13 +0000 Subject: [PATCH 424/827] Fix sample code for policy extension (#8489) --- docs/x509/reference.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 81548812e6cb..12ac440cb8ba 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -2681,7 +2681,7 @@ X.509 Extensions def contains_domain_validated(policies): return any( - policy.oid.dotted_string == "2.23.140.1.2.1" + policy.policy_identifier.dotted_string == "2.23.140.1.2.1" for policy in policies ) From ce05282e58f95e279cd81b94017484a4f9a1a0de Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 10 Mar 2023 20:31:10 +0800 Subject: [PATCH 425/827] cache ECDH values in wycheproof too (#8487) this alters and renames the caching function a bit since it caches *to the group* object but the actual values (in ECDH) come from the testcase itself --- tests/utils.py | 4 ++-- tests/wycheproof/test_ecdh.py | 17 ++++++++++++----- tests/wycheproof/test_ecdsa.py | 6 +++--- tests/wycheproof/test_rsa.py | 30 +++++++++++++++--------------- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index e781f1afb3b0..10f73c7ebd92 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -913,11 +913,11 @@ def invalid(self) -> bool: def has_flag(self, flag: str) -> bool: return flag in self.testcase["flags"] - def cache_group_value(self, cache_key: str, func): + def cache_value_to_group(self, cache_key: str, func): cache_val = self.testgroup.get(cache_key) if cache_val is not None: return cache_val - self.testgroup[cache_key] = cache_val = func(self.testgroup) + self.testgroup[cache_key] = cache_val = func() return cache_val diff --git a/tests/wycheproof/test_ecdh.py b/tests/wycheproof/test_ecdh.py index 9fecdef9ea4e..a797c224f3d8 100644 --- a/tests/wycheproof/test_ecdh.py +++ b/tests/wycheproof/test_ecdh.py @@ -67,12 +67,15 @@ def test_ecdh(backend, wycheproof): "Unsupported curve ({})".format(wycheproof.testgroup["curve"]) ) _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) - - private_key = ec.derive_private_key( - int(wycheproof.testcase["private"], 16), curve, backend + private_key = wycheproof.cache_value_to_group( + f"private_key_{wycheproof.testcase['private']}", + lambda: ec.derive_private_key( + int(wycheproof.testcase["private"], 16), curve + ), ) try: + # caching these values shows no performance improvement public_key = serialization.load_der_public_key( binascii.unhexlify(wycheproof.testcase["public"]), backend ) @@ -109,8 +112,11 @@ def test_ecdh_ecpoint(backend, wycheproof): assert isinstance(curve, ec.EllipticCurve) _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) - private_key = ec.derive_private_key( - int(wycheproof.testcase["private"], 16), curve, backend + private_key = wycheproof.cache_value_to_group( + f"private_key_{wycheproof.testcase['private']}", + lambda: ec.derive_private_key( + int(wycheproof.testcase["private"], 16), curve + ), ) if wycheproof.invalid: @@ -121,6 +127,7 @@ def test_ecdh_ecpoint(backend, wycheproof): return assert wycheproof.valid or wycheproof.acceptable + # caching these values shows no performance improvement public_key = ec.EllipticCurvePublicKey.from_encoded_point( curve, binascii.unhexlify(wycheproof.testcase["public"]) ) diff --git a/tests/wycheproof/test_ecdsa.py b/tests/wycheproof/test_ecdsa.py index 75f9d4413d50..0b0308393511 100644 --- a/tests/wycheproof/test_ecdsa.py +++ b/tests/wycheproof/test_ecdsa.py @@ -61,10 +61,10 @@ ) def test_ecdsa_signature(backend, wycheproof): try: - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cache_key", - lambda group: serialization.load_der_public_key( - binascii.unhexlify(group["keyDer"]), backend + lambda: serialization.load_der_public_key( + binascii.unhexlify(wycheproof.testgroup["keyDer"]) ), ) assert isinstance(key, ec.EllipticCurvePublicKey) diff --git a/tests/wycheproof/test_rsa.py b/tests/wycheproof/test_rsa.py index 14f6b478e248..48d20f316a1d 100644 --- a/tests/wycheproof/test_rsa.py +++ b/tests/wycheproof/test_rsa.py @@ -63,10 +63,10 @@ def should_verify(backend, wycheproof): "rsa_signature_4096_sha512_256_test.json", ) def test_rsa_pkcs1v15_signature(backend, wycheproof): - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cached_key", - lambda group: serialization.load_der_public_key( - binascii.unhexlify(group["keyDer"]), backend + lambda: serialization.load_der_public_key( + binascii.unhexlify(wycheproof.testgroup["keyDer"]), ), ) assert isinstance(key, rsa.RSAPublicKey) @@ -96,10 +96,10 @@ def test_rsa_pkcs1v15_signature(backend, wycheproof): @wycheproof_tests("rsa_sig_gen_misc_test.json") def test_rsa_pkcs1v15_signature_generation(backend, wycheproof): - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cached_key", - lambda group: serialization.load_pem_private_key( - group["privateKeyPem"].encode("ascii"), + lambda: serialization.load_pem_private_key( + wycheproof.testgroup["privateKeyPem"].encode("ascii"), password=None, unsafe_skip_rsa_key_validation=True, ), @@ -142,10 +142,10 @@ def test_rsa_pss_signature(backend, wycheproof): if backend._fips_enabled and isinstance(digest, hashes.SHA1): pytest.skip("Invalid params for FIPS. SHA1 is disallowed") - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cached_key", - lambda group: serialization.load_der_public_key( - binascii.unhexlify(group["keyDer"]), backend + lambda: serialization.load_der_public_key( + binascii.unhexlify(wycheproof.testgroup["keyDer"]), ), ) assert isinstance(key, rsa.RSAPublicKey) @@ -218,10 +218,10 @@ def test_rsa_oaep_encryption(backend, wycheproof): f"or {digest.name} hash." ) - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cached_key", - lambda group: serialization.load_pem_private_key( - group["privateKeyPem"].encode("ascii"), + lambda: serialization.load_pem_private_key( + wycheproof.testgroup["privateKeyPem"].encode("ascii"), password=None, unsafe_skip_rsa_key_validation=True, ), @@ -254,10 +254,10 @@ def test_rsa_oaep_encryption(backend, wycheproof): "rsa_pkcs1_4096_test.json", ) def test_rsa_pkcs1_encryption(backend, wycheproof): - key = wycheproof.cache_group_value( + key = wycheproof.cache_value_to_group( "cached_key", - lambda group: serialization.load_pem_private_key( - group["privateKeyPem"].encode("ascii"), + lambda: serialization.load_pem_private_key( + wycheproof.testgroup["privateKeyPem"].encode("ascii"), password=None, unsafe_skip_rsa_key_validation=True, ), From f7d8e9c66002513029a8986d214534280448b984 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:11:38 +0000 Subject: [PATCH 426/827] Bump libc from 0.2.139 to 0.2.140 in /src/rust (#8491) Bumps [libc](https://github.com/rust-lang/libc) from 0.2.139 to 0.2.140. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.139...0.2.140) --- updated-dependencies: - dependency-name: libc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 03246928f292..aeb4e02d65de 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -231,9 +231,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "link-cplusplus" From c01d382b4a7ee8c729ff6952b1c9ed8a28ad75f9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Mar 2023 15:16:43 -0500 Subject: [PATCH 427/827] use sparse crates.io in wheel-builder (#8492) --- .github/workflows/wheel-builder.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index ae6b10a269a6..ead955df9641 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -18,6 +18,8 @@ on: - pyproject.toml - src/cryptography/__about__.py +env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse jobs: sdist: From dd43b5588279042592813bd71b68afec11b9e196 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 23:19:27 +0000 Subject: [PATCH 428/827] Bump platformdirs from 3.1.0 to 3.1.1 (#8493) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.1.0...3.1.1) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b8ff06a4b397..d8903e154d36 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -98,7 +98,7 @@ pathspec==0.11.0 # via black pkginfo==1.9.6 # via twine -platformdirs==3.1.0; python_version >= "3.7" +platformdirs==3.1.1; python_version >= "3.7" # via # black # tox From 5e3061c05ed2e2dca55f1c395df4d6f7c1e101a6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Mar 2023 23:14:27 -0500 Subject: [PATCH 429/827] Stop validating keys in ECDH exchange (#8490) The theory here is that we're already doing sufficient validation key loading, and this is purely duplicative. Note that there's at least _some_ validationg that was previously occurring only ECDH, the LowOrderPublic check that can be seen in wycheproof. --- src/_cffi_src/openssl/evp.py | 9 +++++++++ src/cryptography/hazmat/backends/openssl/utils.py | 14 ++++++++++---- .../hazmat/bindings/openssl/_conditional.py | 7 +++++++ tests/wycheproof/test_ecdh.py | 8 +------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index 19bdcf38bc28..b8a38995c00b 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -38,6 +38,7 @@ static const long Cryptography_HAS_300_FIPS; static const long Cryptography_HAS_300_EVP_CIPHER; static const long Cryptography_HAS_EVP_PKEY_DH; +static const long Cryptography_HAS_EVP_PKEY_SET_PEER_EX; """ FUNCTIONS = """ @@ -119,6 +120,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *, EVP_PKEY **); int EVP_PKEY_derive_init(EVP_PKEY_CTX *); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *, EVP_PKEY *); +int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *, EVP_PKEY *, int); int EVP_PKEY_derive(EVP_PKEY_CTX *, unsigned char *, size_t *); int EVP_PKEY_id(const EVP_PKEY *); @@ -198,6 +200,13 @@ static const long Cryptography_HAS_EVP_DIGESTFINAL_XOF = 1; #endif +#if CRYPTOGRAPHY_OPENSSL_300_OR_GREATER +static const long Cryptography_HAS_EVP_PKEY_SET_PEER_EX = 1; +#else +static const long Cryptography_HAS_EVP_PKEY_SET_PEER_EX = 0; +int (*EVP_PKEY_derive_set_peer_ex)(EVP_PKEY_CTX *, EVP_PKEY *, int) = NULL; +#endif + /* This is tied to X25519 support so we reuse the Cryptography_HAS_X25519 conditional to remove it. OpenSSL 1.1.0 didn't have this define, but 1.1.1 will when it is released. We can remove this in the distant diff --git a/src/cryptography/hazmat/backends/openssl/utils.py b/src/cryptography/hazmat/backends/openssl/utils.py index 0a4c29595f02..019f412c7ee9 100644 --- a/src/cryptography/hazmat/backends/openssl/utils.py +++ b/src/cryptography/hazmat/backends/openssl/utils.py @@ -17,10 +17,16 @@ def _evp_pkey_derive(backend: "Backend", evp_pkey, peer_public_key) -> bytes: ctx = backend._ffi.gc(ctx, backend._lib.EVP_PKEY_CTX_free) res = backend._lib.EVP_PKEY_derive_init(ctx) backend.openssl_assert(res == 1) - res = backend._lib.EVP_PKEY_derive_set_peer(ctx, peer_public_key._evp_pkey) - if res != 1: - errors_with_text = backend._consume_errors_with_text() - raise ValueError("Error computing shared key.", errors_with_text) + + if backend._lib.Cryptography_HAS_EVP_PKEY_SET_PEER_EX: + res = backend._lib.EVP_PKEY_derive_set_peer_ex( + ctx, peer_public_key._evp_pkey, 0 + ) + else: + res = backend._lib.EVP_PKEY_derive_set_peer( + ctx, peer_public_key._evp_pkey + ) + backend.openssl_assert(res == 1) keylen = backend._ffi.new("size_t *") res = backend._lib.EVP_PKEY_derive(ctx, backend._ffi.NULL, keylen) diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 0f9977bc115b..c34fc3ae6960 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -271,6 +271,10 @@ def cryptography_has_get_extms_support() -> typing.List[str]: return ["SSL_get_extms_support"] +def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: + return ["EVP_PKEY_derive_set_peer_ex"] + + # This is a mapping of # {condition: function-returning-names-dependent-on-that-condition} so we can # loop over them and delete unsupported names at runtime. It will be removed @@ -322,4 +326,7 @@ def cryptography_has_get_extms_support() -> typing.List[str]: cryptography_has_ssl_op_ignore_unexpected_eof ), "Cryptography_HAS_GET_EXTMS_SUPPORT": cryptography_has_get_extms_support, + "Cryptography_HAS_EVP_PKEY_SET_PEER_EX": ( + cryptography_has_evp_pkey_set_peer_ex + ), } diff --git a/tests/wycheproof/test_ecdh.py b/tests/wycheproof/test_ecdh.py index a797c224f3d8..e2624a45a53c 100644 --- a/tests/wycheproof/test_ecdh.py +++ b/tests/wycheproof/test_ecdh.py @@ -86,13 +86,7 @@ def test_ecdh(backend, wycheproof): except UnsupportedAlgorithm: return - if wycheproof.valid or ( - wycheproof.acceptable - and not ( - wycheproof.has_flag("LowOrderPublic") - and backend._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER - ) - ): + if wycheproof.valid or wycheproof.acceptable: computed_shared = private_key.exchange(ec.ECDH(), public_key) expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) assert computed_shared == expected_shared From 22ae4d831f82e685b0acb98591de39d62e89cb83 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Mar 2023 23:26:32 -0500 Subject: [PATCH 430/827] Replace release.py with OIDC publishing (#8483) We are now in the PyPI OIDC publishing beta --- .github/workflows/pypi-publish.yml | 67 ++++++++++++++++ .github/workflows/wheel-builder.yml | 2 + release.py | 118 ---------------------------- 3 files changed, 69 insertions(+), 118 deletions(-) create mode 100644 .github/workflows/pypi-publish.yml diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml new file mode 100644 index 000000000000..91608f2b2728 --- /dev/null +++ b/.github/workflows/pypi-publish.yml @@ -0,0 +1,67 @@ +name: Publish to PyPI + +on: + workflow_dispatch: + inputs: + run_id: + description: The run of wheel-builder to use for finding artifacts. + required: true + environment: + description: Which PyPI environment to upload to + required: true + type: choice + options: ["pypi", "testpypi"] + # Disabled until this has been validated with `workflow_dispatch` + Test PyPI. + # workflow_run: + # workflows: ["wheel-builder.yml"] + # types: [completed] + +jobs: + publish: + runs-on: ubuntu-latest + # We're not actually verifying that the triggering push event was for a + # tag, because github doesn't expose enough information to do so. + # wheel-builder.yml currently only has push events for tags. + if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.event == 'push' && github.event.workflow_run.conclusion == 'success') + permissions: + id-token: "write" + steps: + - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + with: + path: dist/ + run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.event.id }} + - run: pip install -c ci-constraints-requirements.txt twine requests + + - run: | + echo "OIDC_AUDIENCE=pypi" >> GITHUB_ENV + echo "PYPI_DOMAIN=pypi.org" >> GITHUB_ENV + echo "TWINE_REPO=pypi" >> GITHUB_ENV + if: github.event_name == 'workflow_run' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi') + - run: | + echo "OIDC_AUDIENCE=testpypi" >> GITHUB_ENV + echo "PYPI_DOMAIN=test.pypi.org" >> GITHUB_ENV + echo "TWINE_REPO=testpypi" >> GITHUB_ENV + if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' + + - run: | + import os + + import requests + + response = requests.get( + os.environ["ACTIONS_ID_TOKEN_REQUEST_URL"], + params={"audience": os.environ["OIDC_AUDIENCE"]}, + headers={"Authorization": f"bearer {os.environ['ACTIONS_ID_TOKEN_REQUEST_TOKEN']}"} + ) + response.raise_for_status() + token = response.json()["value"] + + response = requests.post(f"https://{os.environ['PYPI_DOMAIN']}/_/oidc/github/mint-token", json={"token": token}) + response.raise_for_status() + pypi_token = response.json()["token"] + + with open(os.environ["GITHUB_ENV"], "a") as f: + f.write("TWINE_PASSWORD={pypi_token}\n") + shell: python + + - run: "twine upload --repository $TWINE_REPO dist/*" diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index ead955df9641..ec0c20bfe473 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -6,6 +6,8 @@ on: inputs: version: description: The version to build + # Do not add any non-tag push events without updating pypi-publish.yml. If + # you do, it'll upload wheels to PyPI. push: tags: - '*.*' diff --git a/release.py b/release.py index fad64358cbdf..339eb0610a8c 100644 --- a/release.py +++ b/release.py @@ -2,16 +2,9 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import getpass -import io -import os import subprocess -import time -import typing -import zipfile import click -import requests def run(*args: str) -> None: @@ -19,127 +12,16 @@ def run(*args: str) -> None: subprocess.check_call(list(args)) -def wait_for_build_complete_github_actions( - session: requests.Session, token: str, run_url: str -) -> None: - while True: - response = session.get( - run_url, - headers={ - "Content-Type": "application/json", - "Authorization": f"token {token}", - }, - ) - response.raise_for_status() - if response.json()["conclusion"] is not None: - break - time.sleep(3) - - -def download_artifacts_github_actions( - session: requests.Session, token: str, run_url: str -) -> typing.List[str]: - response = session.get( - run_url, - headers={ - "Content-Type": "application/json", - "Authorization": f"token {token}", - }, - ) - response.raise_for_status() - - response = session.get( - response.json()["artifacts_url"], - headers={ - "Content-Type": "application/json", - "Authorization": f"token {token}", - }, - ) - response.raise_for_status() - paths = [] - for artifact in response.json()["artifacts"]: - response = session.get( - artifact["archive_download_url"], - headers={ - "Content-Type": "application/json", - "Authorization": f"token {token}", - }, - ) - with zipfile.ZipFile(io.BytesIO(response.content)) as z: - for name in z.namelist(): - if not name.endswith(".whl") and not name.endswith(".tar.gz"): - continue - p = z.open(name) - out_path = os.path.join( - os.path.dirname(__file__), - "dist", - os.path.basename(name), - ) - with open(out_path, "wb") as f: - f.write(p.read()) - paths.append(out_path) - return paths - - -def fetch_github_actions_artifacts( - token: str, version: str -) -> typing.List[str]: - session = requests.Session() - - workflow_runs = [] - - # There is a race condition where no workflow run has triggered after - # pushing the tag, so loop until we get the run. - while True: - response = session.get( - ( - f"https://api.github.com/repos/pyca/cryptography/actions" - f"/workflows/wheel-builder.yml/runs?event=push&" - f"branch={version}" - ), - headers={ - "Content-Type": "application/json", - "Authorization": f"token {token}", - }, - ) - response.raise_for_status() - workflow_runs = response.json()["workflow_runs"] - if len(workflow_runs) > 0: - break - time.sleep(3) - - run_url: str = workflow_runs[0]["url"] - wait_for_build_complete_github_actions(session, token, run_url) - return download_artifacts_github_actions(session, token, run_url) - - @click.command() @click.argument("version") def release(version: str) -> None: """ ``version`` should be a string like '0.4' or '1.0'. """ - print( - f"Create a new GH PAT with only actions permissions at: " - f"https://github.com/settings/tokens/new?" - f"description={version}&scopes=repo" - ) - github_token = getpass.getpass("Github person access token: ") - # Tag and push the tag (this will trigger the wheel builder in Actions) run("git", "tag", "-s", version, "-m", f"{version} release") run("git", "push", "--tags") - os.makedirs(os.path.join(os.path.dirname(__file__), "dist"), exist_ok=True) - - # Wait for Actions to complete and download the wheels - github_actions_artifact_paths = fetch_github_actions_artifacts( - github_token, version - ) - - # Upload wheels and sdist - run("twine", "upload", *github_actions_artifact_paths) - if __name__ == "__main__": release() From d85d73a9147041355e6c484ac2e7967057bb6040 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Mar 2023 00:01:09 -0500 Subject: [PATCH 431/827] various fixes (still not enough) to the pypi uploader (#8495) * Don't pin installs in pypi-pulish We don't have the repo available to get the constraints file * fix obviously broken assignment * Update pypi-publish.yml --- .github/workflows/pypi-publish.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 91608f2b2728..785d8b11c4b2 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -30,17 +30,17 @@ jobs: with: path: dist/ run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.event.id }} - - run: pip install -c ci-constraints-requirements.txt twine requests + - run: pip install twine requests - run: | - echo "OIDC_AUDIENCE=pypi" >> GITHUB_ENV - echo "PYPI_DOMAIN=pypi.org" >> GITHUB_ENV - echo "TWINE_REPO=pypi" >> GITHUB_ENV + echo "OIDC_AUDIENCE=pypi" >> $GITHUB_ENV + echo "PYPI_DOMAIN=pypi.org" >> $GITHUB_ENV + echo "TWINE_REPO=pypi" >> $GITHUB_ENV if: github.event_name == 'workflow_run' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi') - run: | - echo "OIDC_AUDIENCE=testpypi" >> GITHUB_ENV - echo "PYPI_DOMAIN=test.pypi.org" >> GITHUB_ENV - echo "TWINE_REPO=testpypi" >> GITHUB_ENV + echo "OIDC_AUDIENCE=testpypi" >> $GITHUB_ENV + echo "PYPI_DOMAIN=test.pypi.org" >> $GITHUB_ENV + echo "TWINE_REPO=testpypi" >> $GITHUB_ENV if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' - run: | @@ -64,4 +64,4 @@ jobs: f.write("TWINE_PASSWORD={pypi_token}\n") shell: python - - run: "twine upload --repository $TWINE_REPO dist/*" + - run: "twine upload --repository $TWINE_REPO dist/**" From d6c24ff66b9c4382995d8d62965a1f9fbc8e4e6d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 11 Mar 2023 21:07:20 +0800 Subject: [PATCH 432/827] More fixes for PyPI OIDC publishing (still doesn't work) (#8496) * use find to only get files from the dist dir for pypi publish * add twine username reorder the upload choice so it defaults to testpypi * use xargs so it errors properly --- .github/workflows/pypi-publish.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 785d8b11c4b2..62cf42c73f4f 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -10,7 +10,7 @@ on: description: Which PyPI environment to upload to required: true type: choice - options: ["pypi", "testpypi"] + options: ["testpypi", "pypi"] # Disabled until this has been validated with `workflow_dispatch` + Test PyPI. # workflow_run: # workflows: ["wheel-builder.yml"] @@ -36,11 +36,13 @@ jobs: echo "OIDC_AUDIENCE=pypi" >> $GITHUB_ENV echo "PYPI_DOMAIN=pypi.org" >> $GITHUB_ENV echo "TWINE_REPO=pypi" >> $GITHUB_ENV + echo "TWINE_USERNAME=__token__" >> $GITHUB_ENV if: github.event_name == 'workflow_run' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi') - run: | echo "OIDC_AUDIENCE=testpypi" >> $GITHUB_ENV echo "PYPI_DOMAIN=test.pypi.org" >> $GITHUB_ENV echo "TWINE_REPO=testpypi" >> $GITHUB_ENV + echo "TWINE_USERNAME=__token__" >> $GITHUB_ENV if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' - run: | @@ -64,4 +66,4 @@ jobs: f.write("TWINE_PASSWORD={pypi_token}\n") shell: python - - run: "twine upload --repository $TWINE_REPO dist/**" + - run: find dist/ -type f -name 'cryptography*' | xargs twine upload --repository $TWINE_REPO From bf3f3457f9e0c1a3d938328261fe0e004101c9aa Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Mar 2023 17:36:40 -0500 Subject: [PATCH 433/827] fix obvious typo in upload (#8498) * fix obvious typo in upload * Update pypi-publish.yml * Update pypi-publish.yml * Update pypi-publish.yml --- .github/workflows/pypi-publish.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 62cf42c73f4f..8fb1e304f21b 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -35,13 +35,13 @@ jobs: - run: | echo "OIDC_AUDIENCE=pypi" >> $GITHUB_ENV echo "PYPI_DOMAIN=pypi.org" >> $GITHUB_ENV - echo "TWINE_REPO=pypi" >> $GITHUB_ENV + echo "TWINE_REPOSITORY=pypi" >> $GITHUB_ENV echo "TWINE_USERNAME=__token__" >> $GITHUB_ENV if: github.event_name == 'workflow_run' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi') - run: | echo "OIDC_AUDIENCE=testpypi" >> $GITHUB_ENV echo "PYPI_DOMAIN=test.pypi.org" >> $GITHUB_ENV - echo "TWINE_REPO=testpypi" >> $GITHUB_ENV + echo "TWINE_REPOSITORY=testpypi" >> $GITHUB_ENV echo "TWINE_USERNAME=__token__" >> $GITHUB_ENV if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' @@ -63,7 +63,8 @@ jobs: pypi_token = response.json()["token"] with open(os.environ["GITHUB_ENV"], "a") as f: - f.write("TWINE_PASSWORD={pypi_token}\n") + print(f"::add-mask::{pypi_token}") + f.write(f"TWINE_PASSWORD={pypi_token}\n") shell: python - - run: find dist/ -type f -name 'cryptography*' | xargs twine upload --repository $TWINE_REPO + - run: twine upload --skip-existing $(find dist/ -type f -name 'cryptography*') From 9b4a2f70b44f571e5ba859b28a6fa8bbbb4052b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 00:16:37 +0000 Subject: [PATCH 434/827] Bump urllib3 from 1.26.14 to 1.26.15 (#8499) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.14 to 1.26.15. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.14...1.26.15) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d8903e154d36..f54cbdcd8505 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -213,7 +213,7 @@ types-urllib3==1.26.25.8 # via types-requests typing-extensions==4.5.0; python_version >= "3.7" # via mypy -urllib3==1.26.14 +urllib3==1.26.15 # via # requests # twine From 35f2d9acfac7d21edcf9d30ec6a3e2d4efd4bc0d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 12 Mar 2023 10:28:27 -0400 Subject: [PATCH 435/827] enable pypi-publish on workflow_run (#8500) refs #8494 --- .github/workflows/pypi-publish.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 8fb1e304f21b..15d952a1b341 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -11,10 +11,9 @@ on: required: true type: choice options: ["testpypi", "pypi"] - # Disabled until this has been validated with `workflow_dispatch` + Test PyPI. - # workflow_run: - # workflows: ["wheel-builder.yml"] - # types: [completed] + workflow_run: + workflows: ["wheel-builder.yml"] + types: [completed] jobs: publish: From f6a4d4625bf0c7ba1ed2affaa0255e70d6677165 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 19:58:52 +0000 Subject: [PATCH 436/827] Bump pytest-xdist from 3.2.0 to 3.2.1 (#8502) Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.2.0 to 3.2.1. - [Release notes](https://github.com/pytest-dev/pytest-xdist/releases) - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.2.0...v3.2.1) --- updated-dependencies: - dependency-name: pytest-xdist dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f54cbdcd8505..90dfba6855de 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -143,7 +143,7 @@ pytest-shard==0.1.2 # via cryptography (setup.cfg) pytest-subtests==0.10.0; python_version >= "3.7" # via cryptography (setup.cfg) -pytest-xdist==3.2.0; python_version >= "3.7" +pytest-xdist==3.2.1; python_version >= "3.7" # via cryptography (setup.cfg) pytz==2022.7.1 # via From fc9fad5e5ccd115e49fe862125352803dd09ca1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 19:59:01 +0000 Subject: [PATCH 437/827] Bump pyproject-api from 1.5.0 to 1.5.1 (#8503) Bumps [pyproject-api](https://github.com/tox-dev/pyproject-api) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/tox-dev/pyproject-api/releases) - [Changelog](https://github.com/tox-dev/pyproject-api/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/pyproject-api/compare/1.5.0...1.5.1) --- updated-dependencies: - dependency-name: pyproject-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 90dfba6855de..9599ddd625d3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -120,7 +120,7 @@ pygments==2.14.0 # readme-renderer # rich # sphinx -pyproject-api==1.5.0 +pyproject-api==1.5.1 # via tox pyproject-hooks==1.0.0 # via build From 1fe4fd1ed23849bf5b0987cd5f14873a7b88ba7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 20:05:46 +0000 Subject: [PATCH 438/827] Bump virtualenv from 20.20.0 to 20.21.0 (#8504) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.20.0 to 20.21.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/20.21.0/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.20.0...20.21.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9599ddd625d3..5cc99d236e4a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -217,7 +217,7 @@ urllib3==1.26.15 # via # requests # twine -virtualenv==20.20.0; python_version >= "3.7" +virtualenv==20.21.0; python_version >= "3.7" # via tox webencodings==0.5.1 # via bleach From ed172896e85b6322bd027203051e01d466c7287c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 20:21:07 +0000 Subject: [PATCH 439/827] Bump tox from 4.4.6 to 4.4.7 (#8505) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.6 to 4.4.7. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.6...4.4.7) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5cc99d236e4a..1ec439723db0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -203,7 +203,7 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.6; python_version >= "3.7" +tox==4.4.7; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) From f3aee444d03c7e9171e9e0704919e9a18b4236ba Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 12 Mar 2023 21:21:29 -0400 Subject: [PATCH 440/827] fix pypi-publish.yml to trigger on workflow runs (#8506) looks like it really wants name, and not filename --- .github/workflows/pypi-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 15d952a1b341..8a90d24a93ba 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -12,7 +12,7 @@ on: type: choice options: ["testpypi", "pypi"] workflow_run: - workflows: ["wheel-builder.yml"] + workflows: ["Wheel Builder"] types: [completed] jobs: From 1078f1bb6fcbffca8bbf0cb6e192e46633c15bca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 03:04:00 +0000 Subject: [PATCH 441/827] Bump exceptiongroup from 1.1.0 to 1.1.1 (#8507) Bumps [exceptiongroup](https://github.com/agronholm/exceptiongroup) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/agronholm/exceptiongroup/releases) - [Changelog](https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst) - [Commits](https://github.com/agronholm/exceptiongroup/compare/1.1.0...1.1.1) --- updated-dependencies: - dependency-name: exceptiongroup dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1ec439723db0..611e17b8f513 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -42,7 +42,7 @@ docutils==0.18.1 # readme-renderer # sphinx # sphinx-rtd-theme -exceptiongroup==1.1.0 +exceptiongroup==1.1.1 # via # hypothesis # pytest From c97649e6d744baea9fbeae098e58c6d7e725e130 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 03:10:39 +0000 Subject: [PATCH 442/827] Bump proc-macro2 from 1.0.51 to 1.0.52 in /src/rust (#8508) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.51 to 1.0.52. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.51...1.0.52) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index aeb4e02d65de..c5fa8877b6db 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -396,9 +396,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ "unicode-ident", ] From d120334ad05eeb655146532e9ee3026aa95cd19c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 23:22:07 -0400 Subject: [PATCH 443/827] Bump chrono from 0.4.23 to 0.4.24 in /src/rust (#8509) Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.23 to 0.4.24. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.23...v0.4.24) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c5fa8877b6db..287783ae1ac8 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -82,9 +82,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "num-integer", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 053902b01f9e..79736d024406 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -12,7 +12,7 @@ once_cell = "1" pyo3 = { version = "0.15.2" } asn1 = { version = "0.13.0", default-features = false } pem = "1.1" -chrono = { version = "0.4.22", default-features = false, features = ["alloc", "clock"] } +chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" [features] From 6fae949c8fac559c30ca5933096cdb9846a23bd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 12:42:15 +0800 Subject: [PATCH 444/827] Bump quote from 1.0.23 to 1.0.25 in /src/rust (#8510) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.23 to 1.0.25. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.23...1.0.25) --- updated-dependencies: - dependency-name: quote dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 287783ae1ac8..4787d4aeeee3 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -453,9 +453,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5308e8208729c3e1504a6cfad0d5daacc4614c9a2e65d1ea312a34b5cb00fe84" dependencies = [ "proc-macro2", ] From 668b3054e17b9b26041da91092322b659a36cdff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:06:35 +0000 Subject: [PATCH 445/827] Bump actions/cache from 3.3.0 to 3.3.1 (#8511) Bumps [actions/cache](https://github.com/actions/cache) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 132b863dcb9e..e86268098717 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL - name: Load OpenSSL cache - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 id: ossl-cache timeout-minutes: 2 with: From de47a2224c2c72f80f8b86b2feb6ae7a2f3fc7d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:22:56 +0000 Subject: [PATCH 446/827] Bump actions/cache from 3.3.0 to 3.3.1 in /.github/actions/cache (#8512) Bumps [actions/cache](https://github.com/actions/cache) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/cache/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index a40397e7623a..67e6cd437030 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -30,7 +30,7 @@ runs: echo "dir=$(python -m pip cache dir)" >> $GITHUB_OUTPUT fi shell: bash - - uses: actions/cache@v3.3.0 + - uses: actions/cache@v3.3.1 id: cache with: path: | From af0c907dde1cf43e47c6734f2671ca420a7b444b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 12:27:37 +0000 Subject: [PATCH 447/827] Bump ruff from 0.0.254 to 0.0.255 (#8514) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.254 to 0.0.255. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.254...v0.0.255) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 611e17b8f513..b335d11141e1 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.2 # via twine -ruff==0.0.254 +ruff==0.0.255 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 2a67c783af2349d766d79ec10714d2ed2d536930 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 12:39:19 +0000 Subject: [PATCH 448/827] Bump quote from 1.0.25 to 1.0.26 in /src/rust (#8515) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.25 to 1.0.26. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.25...1.0.26) --- updated-dependencies: - dependency-name: quote dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 4787d4aeeee3..aaa43500de7b 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -453,9 +453,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5308e8208729c3e1504a6cfad0d5daacc4614c9a2e65d1ea312a34b5cb00fe84" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] From 61fee45724cbfe0616381c321ff25de12f3f6ebf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 15 Mar 2023 07:21:34 +0800 Subject: [PATCH 449/827] Test 3.1.0 final (#8517) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e86268098717..a0b546f4bcef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.0.8"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0-beta1"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} From a8c2eb219d3ab5c97750d056dc4e3bd198830e19 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 00:30:20 +0000 Subject: [PATCH 450/827] Bump BoringSSL and/or OpenSSL in CI (#8518) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0b546f4bcef..57bea02b33d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 10, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "8aa51ddfcf1fbf2e5f976762657e21c7aee2f922"}} - # Latest commit on the OpenSSL master branch, as of Mar 08, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "931369429564b5a9bb09711de8e885fef546a0ac"}} + # Latest commit on the BoringSSL master branch, as of Mar 15, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "50bc2ea0e8f60fec17dad62ef6e54a8aed284511"}} + # Latest commit on the OpenSSL master branch, as of Mar 15, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4a3b6266604ca447e0b3a14f1dbc8052e1498819"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 6c39999b40d8794945a8cd47106725334d6d3ae3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 15 Mar 2023 01:06:16 -0400 Subject: [PATCH 451/827] Ressurect the PoC of OpenSSL from Rust (#7164) --- .github/workflows/ci.yml | 16 +- .github/workflows/wheel-builder.yml | 13 +- CHANGELOG.rst | 8 + README.rst | 2 +- docs/installation.rst | 23 +-- setup.py | 3 - src/_cffi_src/build_openssl.py | 17 +- src/_cffi_src/utils.py | 13 ++ .../hazmat/bindings/{ => _rust}/_openssl.pyi | 0 .../hazmat/bindings/_rust/openssl.pyi | 5 + .../hazmat/bindings/openssl/binding.py | 23 ++- src/rust/Cargo.lock | 69 +++++++++ src/rust/Cargo.toml | 5 + src/rust/build.rs | 145 ++++++++++++++++++ src/rust/src/lib.rs | 33 ++++ tests/hazmat/backends/test_openssl_memleak.py | 54 ++++--- tox.ini | 2 +- 17 files changed, 370 insertions(+), 61 deletions(-) rename src/cryptography/hazmat/bindings/{ => _rust}/_openssl.pyi (100%) create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl.pyi create mode 100644 src/rust/build.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57bea02b33d4..492e543bbcc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,8 +98,9 @@ jobs: if: matrix.PYTHON.OPENSSL && steps.ossl-cache.outputs.cache-hit != 'true' - name: Set CFLAGS/LDFLAGS run: | - echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration -I${OSSL_PATH}/include" >> $GITHUB_ENV - echo "LDFLAGS=${LDFLAGS} -L${OSSL_PATH}/lib -L${OSSL_PATH}/lib64 -Wl,-rpath=${OSSL_PATH}/lib -Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV + echo "OPENSSL_DIR=${OSSL_PATH}" >> $GITHUB_ENV + echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration" >> $GITHUB_ENV + echo "RUSTFLAGS=-Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib -Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV if: matrix.PYTHON.OPENSSL - name: Build toxenv run: | @@ -318,7 +319,7 @@ jobs: - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] cffi - name: Create toxenv run: tox -vvv --notest env: @@ -419,9 +420,9 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Build toxenv run: | - CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ - LDFLAGS="$(readlink -f ../openssl-macos-universal2/lib/libcrypto.a) $(readlink -f ../openssl-macos-universal2/lib/libssl.a)" \ - CFLAGS="-I$(readlink -f ../openssl-macos-universal2/include) -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ + OPENSSL_DIR=$(readlink -f ../openssl-macos-universal2/) \ + OPENSSL_STATIC=1 \ + CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ tox -vvv --notest env: TOXENV: ${{ matrix.PYTHON.TOXENV }} @@ -481,8 +482,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Configure run: | - echo "INCLUDE=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/include;$INCLUDE" >> $GITHUB_ENV - echo "LIB=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/lib;$LIB" >> $GITHUB_ENV + echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV shell: bash diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index ec0c20bfe473..ea18da168cd9 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -113,8 +113,8 @@ jobs: PY_LIMITED_API="--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }}" fi cd cryptography* - LDFLAGS="-L/opt/pyca/cryptography/openssl/lib -L/opt/pyca/cryptography/openssl/lib64" \ - CFLAGS="-I/opt/pyca/cryptography/openssl/include -Wl,--exclude-libs,ALL" \ + OPENSSL_DIR="/opt/pyca/cryptography/openssl" \ + OPENSSL_STATIC=1 \ ../.venv/bin/python setup.py bdist_wheel $PY_LIMITED_API && mv dist/cryptography*.whl ../tmpwheelhouse env: RUSTUP_HOME: /root/.rustup @@ -216,9 +216,8 @@ jobs: - name: Build the wheel run: | cd cryptography* - CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS="1" \ - LDFLAGS="../../openssl-macos-universal2/lib/libcrypto.a ../../openssl-macos-universal2/lib/libssl.a" \ - CFLAGS="-I../../openssl-macos-universal2/include" \ + OPENSSL_DIR="$(readlink -f ../../openssl-macos-universal2/)" \ + OPENSSL_STATIC=1 \ ../venv/bin/python setup.py bdist_wheel --py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} && mv dist/cryptography*.whl ../wheelhouse env: MACOSX_DEPLOYMENT_TARGET: ${{ matrix.PYTHON.DEPLOYMENT_TARGET }} @@ -286,8 +285,8 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Configure OpenSSL run: | - echo "INCLUDE=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/include;$INCLUDE" >> $GITHUB_ENV - echo "LIB=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/lib;$LIB" >> $GITHUB_ENV + echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV + echo "OPENSSL_STATIC=1" >> $GITHUB_ENV shell: bash - run: python -m pip install -U pip wheel diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b44a6cd57536..deac7aedf93f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,13 @@ Changelog .. note:: This version is not yet released and is under active development. +* **BACKWARDS INCOMPATIBLE:** As announced in the 39.0.0 changelog, the way + ``cryptography`` links OpenSSL has changed. This only impacts users who + build ``cryptography`` from source (i.e., not from a ``wheel``), and + specify their own version of OpenSSL. For those users, the ``CFLAGS``, + ``LDFLAGS``, ``INCLUDE``, ``LIB``, and ``CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS`` + environment variables are no longer valid. Instead, users need to configure + their builds `as documented here`_. * Support for Python 3.6 is deprecated and will be removed in the next release. * Deprecated the current minimum supported Rust version (MSRV) of 1.48.0. @@ -25,6 +32,7 @@ Changelog :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey` and :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. +* The minimum supported version of PyPy3 is now 7.3.10. * Added support for parsing SSH certificates in addition to public keys with :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` diff --git a/README.rst b/README.rst index 1c0e57cbe5e4..e03cfcdff8a9 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ pyca/cryptography ``cryptography`` is a package which provides cryptographic recipes and primitives to Python developers. Our goal is for it to be your "cryptographic -standard library". It supports Python 3.6+ and PyPy3 7.2+. +standard library". It supports Python 3.6+ and PyPy3 7.3.10+. ``cryptography`` includes both high level recipes and low level interfaces to common cryptographic algorithms such as symmetric ciphers, message digests, and diff --git a/docs/installation.rst b/docs/installation.rst index 385b904444c2..210a372eb041 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -13,7 +13,7 @@ single most common cause of installation problems. Supported platforms ------------------- -Currently we test ``cryptography`` on Python 3.6+ and PyPy3 on these +Currently we test ``cryptography`` on Python 3.6+ and PyPy3 7.3.10+ on these operating systems. * x86-64 RHEL 8.x @@ -55,14 +55,13 @@ If you prefer to compile it yourself you'll need to have OpenSSL installed. You can compile OpenSSL yourself as well or use `a binary distribution`_. Be sure to download the proper version for your architecture and Python (VC2015 is required for 3.6 and above). Wherever you place your copy of OpenSSL -you'll need to set the ``LIB`` and ``INCLUDE`` environment variables to include -the proper locations. For example: +you'll need to set the ``OPENSSL_DIR`` environment variable to include the +proper location. For example: .. code-block:: console C:\> \path\to\vcvarsall.bat x86_amd64 - C:\> set LIB=C:\OpenSSL-win64\lib;%LIB% - C:\> set INCLUDE=C:\OpenSSL-win64\include;%INCLUDE% + C:\> set OPENSSL_DIR=C:\OpenSSL-win64 C:\> pip install cryptography You will also need to have :ref:`Rust installed and @@ -227,7 +226,7 @@ dependencies. ./config no-shared no-ssl2 no-ssl3 -fPIC --prefix=${CWD}/openssl make && make install cd .. - CFLAGS="-I${CWD}/openssl/include" LDFLAGS="-L${CWD}/openssl/lib" pip wheel --no-cache-dir --no-binary cryptography cryptography + OPENSSL_DIR="${CWD}/openssl" pip wheel --no-cache-dir --no-binary cryptography cryptography Building cryptography on macOS ------------------------------ @@ -259,7 +258,9 @@ development headers. You will also need to have :ref:`Rust installed and available`, which can be obtained from `Homebrew`_, -`MacPorts`_, or directly from the Rust website. +`MacPorts`_, or directly from the Rust website. If you are linking against a +``universal2`` archive of OpenSSL, the minimum supported Rust version is +1.66.0. Finally you need OpenSSL, which you can obtain from `Homebrew`_ or `MacPorts`_. Cryptography does **not** support the OpenSSL/LibreSSL libraries Apple ships @@ -272,14 +273,14 @@ To build cryptography and dynamically link it: .. code-block:: console $ brew install openssl@3 rust - $ env LDFLAGS="-L$(brew --prefix openssl@3)/lib" CFLAGS="-I$(brew --prefix openssl@3)/include" pip install cryptography + $ env OPENSSL_DIR="$(brew --prefix openssl@3)" pip install cryptography `MacPorts`_: .. code-block:: console $ sudo port install openssl rust - $ env LDFLAGS="-L/opt/local/lib" CFLAGS="-I/opt/local/include" pip install cryptography + $ env OPENSSL_DIR="-L/opt/local" pip install cryptography You can also build cryptography statically: @@ -288,14 +289,14 @@ You can also build cryptography statically: .. code-block:: console $ brew install openssl@3 rust - $ env CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 LDFLAGS="$(brew --prefix openssl@3)/lib/libssl.a $(brew --prefix openssl@3)/lib/libcrypto.a" CFLAGS="-I$(brew --prefix openssl@3)/include" pip install cryptography + $ env OPENSSL_STATIC=1 OPENSSL_DIR="$(brew --prefix openssl@3)" pip install cryptography `MacPorts`_: .. code-block:: console $ sudo port install openssl rust - $ env CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 LDFLAGS="/opt/local/lib/libssl.a /opt/local/lib/libcrypto.a" CFLAGS="-I/opt/local/include" pip install cryptography + $ env OPENSSL_STATIC=1 OPENSSL_DIR="/opt/local" pip install cryptography If you need to rebuild ``cryptography`` for any reason be sure to clear the local `wheel cache`_. diff --git a/setup.py b/setup.py index 4a7866c5ff45..2d084d1efbe7 100644 --- a/setup.py +++ b/setup.py @@ -46,9 +46,6 @@ try: # See setup.cfg for most of the config metadata. setup( - cffi_modules=[ - "src/_cffi_src/build_openssl.py:ffi", - ], rust_extensions=[ RustExtension( "cryptography.hazmat.bindings._rust", diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index a8e560960ebe..ab23e04b28c8 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -4,6 +4,7 @@ import os +import platform import sys from distutils import dist from distutils.ccompiler import get_default_compiler @@ -70,7 +71,7 @@ def _extra_compile_args(platform): ffi = build_ffi_for_binding( - module_name="cryptography.hazmat.bindings._openssl", + module_name="_openssl", module_prefix="_cffi_src.openssl.", modules=[ # This goes first so we can define some cryptography-wide symbols. @@ -110,3 +111,17 @@ def _extra_compile_args(platform): libraries=_get_openssl_libraries(sys.platform), extra_compile_args=_extra_compile_args(sys.platform), ) + +if __name__ == "__main__": + out_dir = os.getenv("OUT_DIR") + module_name, source, source_extension, kwds = ffi._assigned_source + c_file = os.path.join(out_dir, module_name + source_extension) + if platform.python_implementation() == "PyPy": + # Necessary because CFFI will ignore this if there's no declarations. + ffi.embedding_api( + """ + extern "Python" void Cryptography_unused(void); + """ + ) + ffi.embedding_init_code("") + ffi.emit_c_code(c_file) diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index 47d31b611c78..5d2c4224a12b 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -4,6 +4,7 @@ import os +import platform import sys from distutils.ccompiler import new_compiler from distutils.dist import Distribution @@ -70,6 +71,18 @@ def build_ffi( verify_source += '\n#define CRYPTOGRAPHY_PACKAGE_VERSION "{}"'.format( about["__version__"] ) + if platform.python_implementation() == "PyPy": + verify_source += r""" +int Cryptography_make_openssl_module(void) { + int result; + + Py_BEGIN_ALLOW_THREADS + result = cffi_start_python(); + Py_END_ALLOW_THREADS + + return result; +} +""" ffi.cdef(cdef_source) ffi.set_source( module_name, diff --git a/src/cryptography/hazmat/bindings/_openssl.pyi b/src/cryptography/hazmat/bindings/_rust/_openssl.pyi similarity index 100% rename from src/cryptography/hazmat/bindings/_openssl.pyi rename to src/cryptography/hazmat/bindings/_rust/_openssl.pyi diff --git a/src/cryptography/hazmat/bindings/_rust/openssl.pyi b/src/cryptography/hazmat/bindings/_rust/openssl.pyi new file mode 100644 index 000000000000..8cd7b30627e2 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl.pyi @@ -0,0 +1,5 @@ +# 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. + +def openssl_version() -> int: ... diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index af47a0853aa1..680164f41841 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -12,7 +12,7 @@ import cryptography from cryptography import utils from cryptography.exceptions import InternalError -from cryptography.hazmat.bindings._openssl import ffi, lib +from cryptography.hazmat.bindings._rust import _openssl, openssl from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES @@ -65,9 +65,9 @@ def _errors_with_text( ) -> typing.List[_OpenSSLErrorWithText]: errors_with_text = [] for err in errors: - buf = ffi.new("char[]", 256) - lib.ERR_error_string_n(err.code, buf, len(buf)) - err_text_reason: bytes = ffi.string(buf) + buf = _openssl.ffi.new("char[]", 256) + _openssl.lib.ERR_error_string_n(err.code, buf, len(buf)) + err_text_reason: bytes = _openssl.ffi.string(buf) errors_with_text.append( _OpenSSLErrorWithText( @@ -137,7 +137,7 @@ class Binding: """ lib: typing.ClassVar = None - ffi = ffi + ffi = _openssl.ffi _lib_loaded = False _init_lock = threading.Lock() _legacy_provider: typing.Any = ffi.NULL @@ -179,7 +179,9 @@ def _register_osrandom_engine(cls) -> None: def _ensure_ffi_initialized(cls) -> None: with cls._init_lock: if not cls._lib_loaded: - cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES) + cls.lib = build_conditional_library( + _openssl.lib, CONDITIONAL_NAMES + ) cls._lib_loaded = True cls._register_osrandom_engine() # As of OpenSSL 3.0.0 we must register a legacy cipher provider @@ -217,7 +219,9 @@ def _verify_package_version(version: str) -> None: # up later this code checks that the currently imported package and the # shared object that were loaded have the same version and raise an # ImportError if they do not - so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION) + so_package_version = _openssl.ffi.string( + _openssl.lib.CRYPTOGRAPHY_PACKAGE_VERSION + ) if version.encode("ascii") != so_package_version: raise ImportError( "The version of cryptography does not match the loaded " @@ -229,6 +233,11 @@ def _verify_package_version(version: str) -> None: ) ) + _openssl_assert( + _openssl.lib, + _openssl.lib.OpenSSL_version_num() == openssl.openssl_version(), + ) + _verify_package_version(cryptography.__version__) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index aaa43500de7b..fb29e676f646 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -113,8 +113,11 @@ name = "cryptography-rust" version = "0.1.0" dependencies = [ "asn1", + "cc", "chrono", "once_cell", + "openssl", + "openssl-sys", "ouroboros", "pem", "pyo3", @@ -164,6 +167,21 @@ dependencies = [ "syn", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -288,6 +306,45 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +[[package]] +name = "openssl" +version = "0.10.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2523381e46256e40930512c7fd25562b9eae4812cb52078f155e87217c9d1e" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-sys" +version = "0.9.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176be2629957c157240f68f61f2d0053ad3a4ecfdd9ebf1e6521d18d9635cf67" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ouroboros" version = "0.15.6" @@ -364,6 +421,12 @@ dependencies = [ "base64", ] +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -525,6 +588,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 79736d024406..96616baae63e 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,6 +14,11 @@ asn1 = { version = "0.13.0", default-features = false } pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" +openssl = "0.10.46" +openssl-sys = "0.9.72" + +[build-dependencies] +cc = "1.0.72" [features] extension-module = ["pyo3/extension-module"] diff --git a/src/rust/build.rs b/src/rust/build.rs new file mode 100644 index 000000000000..d136a8a74534 --- /dev/null +++ b/src/rust/build.rs @@ -0,0 +1,145 @@ +use std::env; +use std::io::Write; +use std::path::{Path, MAIN_SEPARATOR}; +use std::process::{Command, Stdio}; + +fn main() { + let target = env::var("TARGET").unwrap(); + let openssl_static = env::var("OPENSSL_STATIC") + .map(|x| x == "1") + .unwrap_or(false); + if target.contains("apple") && openssl_static { + // On (older) OSX we need to link against the clang runtime, + // which is hidden in some non-default path. + // + // More details at https://github.com/alexcrichton/curl-rust/issues/279. + if let Some(path) = macos_link_search_path() { + println!("cargo:rustc-link-lib=clang_rt.osx"); + println!("cargo:rustc-link-search={}", path); + } + } + + 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_else(|_| "python3".to_string()); + println!("cargo:rerun-if-changed=../_cffi_src/"); + let python_path = match env::var("PYTHONPATH") { + Ok(mut val) => { + if cfg!(target_os = "windows") { + val.push(';'); + } else { + val.push(':'); + } + val.push_str(".."); + val.push(MAIN_SEPARATOR); + val + } + Err(_) => format!("..{}", MAIN_SEPARATOR), + }; + let output = Command::new(&python) + .env("PYTHONPATH", python_path) + .env("OUT_DIR", &out_dir) + .arg("../_cffi_src/build_openssl.py") + .output() + .expect("failed to execute build_openssl.py"); + if !output.status.success() { + panic!( + "failed to run build_openssl.py, stdout: \n{}\nstderr: \n{}\n", + String::from_utf8(output.stdout).unwrap(), + String::from_utf8(output.stderr).unwrap() + ); + } + + let python_impl = run_python_script( + &python, + "import platform; print(platform.python_implementation(), end='')", + ) + .unwrap(); + println!("cargo:rustc-cfg=python_implementation=\"{}\"", python_impl); + let python_include = run_python_script( + &python, + "import sysconfig; print(sysconfig.get_path('include'), end='')", + ) + .unwrap(); + let openssl_include = + std::env::var_os("DEP_OPENSSL_INCLUDE").expect("unable to find openssl include path"); + let openssl_c = Path::new(&out_dir).join("_openssl.c"); + + let mut build = cc::Build::new(); + build + .file(openssl_c) + .include(python_include) + .include(openssl_include) + .flag_if_supported("-Wconversion") + .flag_if_supported("-Wno-error=sign-conversion"); + + // Enable abi3 mode if we're not using PyPy. + if python_impl != "PyPy" { + // cp36 + build.define("Py_LIMITED_API", "0x030600f0"); + } + + if cfg!(windows) { + build.define("WIN32_LEAN_AND_MEAN", None); + } + + build.compile("_openssl.a"); +} + +/// Run a python script using the specified interpreter binary. +fn run_python_script(interpreter: impl AsRef, script: &str) -> Result { + let interpreter = interpreter.as_ref(); + let out = Command::new(interpreter) + .env("PYTHONIOENCODING", "utf-8") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .and_then(|mut child| { + child + .stdin + .as_mut() + .expect("piped stdin") + .write_all(script.as_bytes())?; + child.wait_with_output() + }); + + match out { + Err(err) => Err(format!( + "failed to run the Python interpreter at {}: {}", + interpreter.display(), + err + )), + Ok(ok) if !ok.status.success() => Err(format!( + "Python script failed: {}", + String::from_utf8(ok.stderr).expect("failed to parse Python script stderr as utf-8") + )), + Ok(ok) => Ok( + String::from_utf8(ok.stdout).expect("failed to parse Python script stdout as utf-8") + ), + } +} + +fn macos_link_search_path() -> Option { + let output = Command::new("clang") + .arg("--print-search-dirs") + .output() + .ok()?; + if !output.status.success() { + println!( + "failed to run 'clang --print-search-dirs', continuing without a link search path" + ); + return None; + } + + let stdout = String::from_utf8_lossy(&output.stdout); + for line in stdout.lines() { + if line.contains("libraries: =") { + let path = line.split('=').nth(1)?; + return Some(format!("{}/lib/darwin", path)); + } + } + + println!("failed to determine link search path, continuing without it"); + None +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index afc96ed8ab28..c3cb25154cff 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -16,8 +16,19 @@ mod pkcs7; mod pool; mod x509; +#[cfg(not(python_implementation = "PyPy"))] +use pyo3::FromPyPointer; use std::convert::TryInto; +#[cfg(python_implementation = "PyPy")] +extern "C" { + fn Cryptography_make_openssl_module() -> std::os::raw::c_int; +} +#[cfg(not(python_implementation = "PyPy"))] +extern "C" { + fn PyInit__openssl() -> *mut pyo3::ffi::PyObject; +} + /// Returns the value of the input with the most-significant-bit copied to all /// of the bits. fn duplicate_msb_to_all(a: u8) -> u8 { @@ -79,6 +90,11 @@ fn check_ansix923_padding(data: &[u8]) -> bool { (mismatch & 1) == 0 } +#[pyo3::prelude::pyfunction] +fn openssl_version() -> i64 { + openssl::version::number() +} + #[pyo3::prelude::pymodule] fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { m.add_function(pyo3::wrap_pyfunction!(check_pkcs7_padding, m)?)?; @@ -102,6 +118,23 @@ 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)?; + #[cfg(python_implementation = "PyPy")] + let openssl_mod = unsafe { + let res = Cryptography_make_openssl_module(); + assert_eq!(res, 0); + pyo3::types::PyModule::import(py, "_openssl")? + }; + #[cfg(not(python_implementation = "PyPy"))] + let openssl_mod = unsafe { + let ptr = PyInit__openssl(); + pyo3::types::PyModule::from_owned_ptr(py, ptr) + }; + m.add_submodule(openssl_mod)?; + + let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?; + openssl_mod.add_function(pyo3::wrap_pyfunction!(openssl_version, m)?)?; + m.add_submodule(openssl_mod)?; + Ok(()) } diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index 6ffe1a40635a..02b89232c0d4 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -23,7 +23,7 @@ def main(argv): import cffi - from cryptography.hazmat.bindings._openssl import ffi, lib + from cryptography.hazmat.bindings._rust import _openssl heap = {} start_heap = {} @@ -50,7 +50,9 @@ def symbolize_backtrace(trace): backtrace_ffi.string(symbols[i]).decode() for i in range(length) ] - lib.Cryptography_free_wrapper(symbols, backtrace_ffi.NULL, 0) + _openssl.lib.Cryptography_free_wrapper( + symbols, backtrace_ffi.NULL, 0 + ) return stack else: def backtrace(): @@ -59,17 +61,19 @@ def backtrace(): def symbolize_backtrace(trace): return None - @ffi.callback("void *(size_t, const char *, int)") + @_openssl.ffi.callback("void *(size_t, const char *, int)") def malloc(size, path, line): - ptr = lib.Cryptography_malloc_wrapper(size, path, line) + ptr = _openssl.lib.Cryptography_malloc_wrapper(size, path, line) heap[ptr] = (size, path, line, backtrace()) return ptr - @ffi.callback("void *(void *, size_t, const char *, int)") + @_openssl.ffi.callback("void *(void *, size_t, const char *, int)") def realloc(ptr, size, path, line): - if ptr != ffi.NULL: + if ptr != _openssl.ffi.NULL: del heap[ptr] - new_ptr = lib.Cryptography_realloc_wrapper(ptr, size, path, line) + new_ptr = _openssl.lib.Cryptography_realloc_wrapper( + ptr, size, path, line + ) heap[new_ptr] = (size, path, line, backtrace()) # It is possible that something during the test will cause a @@ -87,13 +91,15 @@ def realloc(ptr, size, path, line): return new_ptr - @ffi.callback("void(void *, const char *, int)") + @_openssl.ffi.callback("void(void *, const char *, int)") def free(ptr, path, line): - if ptr != ffi.NULL: + if ptr != _openssl.ffi.NULL: del heap[ptr] - lib.Cryptography_free_wrapper(ptr, path, line) + _openssl.lib.Cryptography_free_wrapper(ptr, path, line) - result = lib.Cryptography_CRYPTO_set_mem_functions(malloc, realloc, free) + result = _openssl.lib.Cryptography_CRYPTO_set_mem_functions( + malloc, realloc, free + ) assert result == 1 # Trigger a bunch of initialization stuff. @@ -111,20 +117,24 @@ def free(ptr, path, line): gc.collect() gc.collect() - if lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: - lib.OSSL_PROVIDER_unload(backend._binding._legacy_provider) - lib.OSSL_PROVIDER_unload(backend._binding._default_provider) + if _openssl.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: + _openssl.lib.OSSL_PROVIDER_unload(backend._binding._legacy_provider) + _openssl.lib.OSSL_PROVIDER_unload(backend._binding._default_provider) - if lib.Cryptography_HAS_OPENSSL_CLEANUP: - lib.OPENSSL_cleanup() + if _openssl.lib.Cryptography_HAS_OPENSSL_CLEANUP: + _openssl.lib.OPENSSL_cleanup() # Swap back to the original functions so that if OpenSSL tries to free # something from its atexit handle it won't be going through a Python # function, which will be deallocated when this function returns - result = lib.Cryptography_CRYPTO_set_mem_functions( - ffi.addressof(lib, "Cryptography_malloc_wrapper"), - ffi.addressof(lib, "Cryptography_realloc_wrapper"), - ffi.addressof(lib, "Cryptography_free_wrapper"), + result = _openssl.lib.Cryptography_CRYPTO_set_mem_functions( + _openssl.ffi.addressof( + _openssl.lib, "Cryptography_malloc_wrapper" + ), + _openssl.ffi.addressof( + _openssl.lib, "Cryptography_realloc_wrapper" + ), + _openssl.ffi.addressof(_openssl.lib, "Cryptography_free_wrapper"), ) assert result == 1 @@ -134,9 +144,9 @@ def free(ptr, path, line): # consumption that are allowed in reallocs of start_heap memory. if remaining or start_heap_realloc_delta[0] > 3072: info = dict( - (int(ffi.cast("size_t", ptr)), { + (int(_openssl.ffi.cast("size_t", ptr)), { "size": heap[ptr][0], - "path": ffi.string(heap[ptr][1]).decode(), + "path": _openssl.ffi.string(heap[ptr][1]).decode(), "line": heap[ptr][2], "backtrace": symbolize_backtrace(heap[ptr][3]), }) diff --git a/tox.ini b/tox.ini index 3a8737f28443..505bccba49b1 100644 --- a/tox.ini +++ b/tox.ini @@ -30,6 +30,7 @@ passenv = CRYPTOGRAPHY_OPENSSL_NO_LEGACY OPENSSL_ENABLE_SHA1_SIGNATURES CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS + OPENSSL_DIR setenv = PIP_CONSTRAINT=ci-constraints-requirements.txt commands = @@ -73,7 +74,6 @@ commands = [testenv:rust] basepython = python3 -skip_install = True extras = deps = changedir = src/rust/ From c5eb29860e63e5099d0802fc44ea756260e6775e Mon Sep 17 00:00:00 2001 From: Matthew Ryan <54719826+akamaryan@users.noreply.github.com> Date: Wed, 15 Mar 2023 03:47:58 -0700 Subject: [PATCH 452/827] Python 3.6 compatibility fix. (#8516) * Python 3.6 compatibility fix. The capture_output argument to subprocess.run() was not introduced until Python 3.7. Use stdout=subprocess.PIPE and stderr=subprocess.PIPE instead, which is equivalent. * Update pyproject.toml * Black --------- Co-authored-by: Matthew Ryan Co-authored-by: Paul Kehrer --- pyproject.toml | 3 ++- setup.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d79a4d314d7a..6844bc096894 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,8 @@ exclude_lines = [ [tool.ruff] # UP006: Minimum Python 3.9 # UP007, UP038: Minimum Python 3.10 -ignore = ['N818', 'UP006', 'UP007', 'UP038'] +# UP022: Minimum Python 3.7 +ignore = ['N818', 'UP006', 'UP007', 'UP038', 'UP022'] select = ['E', 'F', 'I', 'N', 'W', 'UP'] line-length = 79 diff --git a/setup.py b/setup.py index 2d084d1efbe7..e1adff269ed6 100644 --- a/setup.py +++ b/setup.py @@ -101,7 +101,8 @@ # If for any reason `rustc --version` fails, silently ignore it rustc_output = subprocess.run( ["rustc", "--version"], - capture_output=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, timeout=0.5, encoding="utf8", check=True, From 67e48d71b22b8a46fd544d8316ce3c35ced7d157 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:55:28 +0000 Subject: [PATCH 453/827] Bump ruff from 0.0.255 to 0.0.256 (#8521) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.255 to 0.0.256. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.255...v0.0.256) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b335d11141e1..26487c0dc50e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.2 # via twine -ruff==0.0.255 +ruff==0.0.256 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 88f2930658f349cf66621587ce90382f13c2318c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:55:51 +0000 Subject: [PATCH 454/827] Bump hypothesis from 6.68.2 to 6.68.3 (#8523) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.68.2 to 6.68.3. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.68.2...hypothesis-python-6.68.3) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 26487c0dc50e..3f1c9df4e5fc 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.68.2; python_version >= "3.7" +hypothesis==6.68.3; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From 9abcd51faf16ca0df9373185eace7137bff4102d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:56:03 +0000 Subject: [PATCH 455/827] Bump filelock from 3.9.0 to 3.9.1 (#8520) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.9.0 to 3.9.1. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.9.0...3.9.1) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3f1c9df4e5fc..49b7b60e84b9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -48,7 +48,7 @@ exceptiongroup==1.1.1 # pytest execnet==1.9.0 # via pytest-xdist -filelock==3.9.0; python_version >= "3.7" +filelock==3.9.1; python_version >= "3.7" # via # tox # virtualenv From 84ac151b1034f906044b885881a7fcaf0f8c080f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:56:27 +0000 Subject: [PATCH 456/827] Bump peter-evans/create-pull-request from 4.2.3 to 4.2.4 (#8524) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.2.3 to 4.2.4. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/2b011faafdcbc9ceb11414d64d0573f37c774b04...38e0b6e68b4c852a5500a94740f0e535e0d7ba54) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/boring-open-version-bump.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 87ac8501ca92..d9c38a25f5c4 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -58,7 +58,7 @@ jobs: private_key: ${{ secrets.BORINGBOT_PRIVATE_KEY }} if: steps.check-sha-boring.outputs.COMMIT_SHA || steps.check-sha-openssl.outputs.COMMIT_SHA - name: Create Pull Request - uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04 + uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 with: commit-message: "Bump BoringSSL and/or OpenSSL in CI" title: "Bump BoringSSL and/or OpenSSL in CI" From 4b9c490f00f12cca5c6e882f498daa3226684bb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:14:41 +0000 Subject: [PATCH 457/827] Bump pkg-config from 0.3.25 to 0.3.26 in /src/rust (#8526) Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.25 to 0.3.26. - [Release notes](https://github.com/rust-lang/pkg-config-rs/releases) - [Changelog](https://github.com/rust-lang/pkg-config-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/pkg-config-rs/compare/0.3.25...0.3.26) --- updated-dependencies: - dependency-name: pkg-config dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index fb29e676f646..b16487d9ac7d 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "proc-macro-error" From ec63e632743d1bc16bc57658a85aa8f865088cbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 19:18:24 +0000 Subject: [PATCH 458/827] Bump pathspec from 0.11.0 to 0.11.1 (#8522) Bumps [pathspec](https://github.com/cpburnz/python-pathspec) from 0.11.0 to 0.11.1. - [Release notes](https://github.com/cpburnz/python-pathspec/releases) - [Changelog](https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst) - [Commits](https://github.com/cpburnz/python-pathspec/compare/v0.11.0...v0.11.1) --- updated-dependencies: - dependency-name: pathspec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 49b7b60e84b9..b6680b530135 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -94,7 +94,7 @@ packaging==23.0; python_version >= "3.7" # pytest # sphinx # tox -pathspec==0.11.0 +pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine From 2b68cb616f5d8b6a386ba2a32eee1261d8e03bc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 15:20:27 -0400 Subject: [PATCH 459/827] Bump sphinxcontrib-jquery from 2.0.0 to 4.1 (#8525) Bumps [sphinxcontrib-jquery](https://github.com/sphinx-contrib/jquery) from 2.0.0 to 4.1. - [Release notes](https://github.com/sphinx-contrib/jquery/releases) - [Changelog](https://github.com/sphinx-contrib/jquery/blob/master/CHANGES.rst) - [Commits](https://github.com/sphinx-contrib/jquery/compare/v2.0.0...v4.1) --- updated-dependencies: - dependency-name: sphinxcontrib-jquery dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b6680b530135..99898eb93fd9 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -182,7 +182,7 @@ sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.1 # via sphinx -sphinxcontrib-jquery==2.0.0 +sphinxcontrib-jquery==4.1 # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx From 76209cfb40e0ca0e2f895a069b02ee28371f06ea Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 15 Mar 2023 19:21:07 -0400 Subject: [PATCH 460/827] Rename PyAsn1Error, it's getting more general (#8527) --- src/rust/src/asn1.rs | 93 +++++++++++++------------ src/rust/src/oid.rs | 4 +- src/rust/src/pkcs7.rs | 6 +- src/rust/src/x509/certificate.rs | 115 ++++++++++++++++++------------- src/rust/src/x509/common.rs | 74 +++++++++++--------- src/rust/src/x509/crl.rs | 31 +++++---- src/rust/src/x509/csr.rs | 55 +++++++++------ src/rust/src/x509/extensions.rs | 8 ++- src/rust/src/x509/ocsp.rs | 6 +- src/rust/src/x509/ocsp_req.rs | 25 ++++--- src/rust/src/x509/ocsp_resp.rs | 77 +++++++++++++-------- src/rust/src/x509/sct.rs | 22 +++--- src/rust/src/x509/sign.rs | 12 ++-- 13 files changed, 306 insertions(+), 222 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 522e21ac6222..72dc7101d1ce 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -7,68 +7,67 @@ use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; -pub enum PyAsn1Error { +pub enum CryptographyError { Asn1Parse(asn1::ParseError), Asn1Write(asn1::WriteError), Py(pyo3::PyErr), } -impl From for PyAsn1Error { - fn from(e: asn1::ParseError) -> PyAsn1Error { - PyAsn1Error::Asn1Parse(e) +impl From for CryptographyError { + fn from(e: asn1::ParseError) -> CryptographyError { + CryptographyError::Asn1Parse(e) } } -impl From for PyAsn1Error { - fn from(e: asn1::WriteError) -> PyAsn1Error { - PyAsn1Error::Asn1Write(e) +impl From for CryptographyError { + fn from(e: asn1::WriteError) -> CryptographyError { + CryptographyError::Asn1Write(e) } } -impl From for PyAsn1Error { - fn from(e: pyo3::PyErr) -> PyAsn1Error { - PyAsn1Error::Py(e) +impl From for CryptographyError { + fn from(e: pyo3::PyErr) -> CryptographyError { + CryptographyError::Py(e) } } -impl From> for PyAsn1Error { - fn from(e: pyo3::PyDowncastError<'_>) -> PyAsn1Error { - PyAsn1Error::Py(e.into()) +impl From> for CryptographyError { + fn from(e: pyo3::PyDowncastError<'_>) -> CryptographyError { + CryptographyError::Py(e.into()) } } -impl From for PyAsn1Error { - fn from(e: pem::PemError) -> PyAsn1Error { - PyAsn1Error::Py(pyo3::exceptions::PyValueError::new_err(format!( +impl From for CryptographyError { + fn from(e: pem::PemError) -> CryptographyError { + CryptographyError::Py(pyo3::exceptions::PyValueError::new_err(format!( "Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. {:?}", e ))) } } -impl From for pyo3::PyErr { - fn from(e: PyAsn1Error) -> pyo3::PyErr { +impl From for pyo3::PyErr { + fn from(e: CryptographyError) -> pyo3::PyErr { match e { - PyAsn1Error::Asn1Parse(asn1_error) => pyo3::exceptions::PyValueError::new_err(format!( - "error parsing asn1 value: {:?}", - asn1_error - )), - PyAsn1Error::Asn1Write(asn1::WriteError::AllocationError) => { + CryptographyError::Asn1Parse(asn1_error) => pyo3::exceptions::PyValueError::new_err( + format!("error parsing asn1 value: {:?}", asn1_error), + ), + CryptographyError::Asn1Write(asn1::WriteError::AllocationError) => { pyo3::exceptions::PyMemoryError::new_err( "failed to allocate memory while performing ASN.1 serialization", ) } - PyAsn1Error::Py(py_error) => py_error, + CryptographyError::Py(py_error) => py_error, } } } -impl PyAsn1Error { +impl CryptographyError { pub(crate) fn add_location(self, loc: asn1::ParseLocation) -> Self { match self { - PyAsn1Error::Py(e) => PyAsn1Error::Py(e), - PyAsn1Error::Asn1Parse(e) => PyAsn1Error::Asn1Parse(e.add_location(loc)), - PyAsn1Error::Asn1Write(e) => PyAsn1Error::Asn1Write(e), + CryptographyError::Py(e) => CryptographyError::Py(e), + CryptographyError::Asn1Parse(e) => CryptographyError::Asn1Parse(e.add_location(loc)), + CryptographyError::Asn1Write(e) => CryptographyError::Asn1Write(e), } } } @@ -76,7 +75,7 @@ impl PyAsn1Error { // The primary purpose of this alias is for brevity to keep function signatures // to a single-line as a work around for coverage issues. See // https://github.com/pyca/cryptography/pull/6173 -pub(crate) type PyAsn1Result = Result; +pub(crate) type CryptographyResult = Result; pub(crate) fn py_oid_to_oid(py_oid: &pyo3::PyAny) -> pyo3::PyResult { Ok(py_oid @@ -106,7 +105,10 @@ struct Spki<'a> { } #[pyo3::prelude::pyfunction] -fn parse_spki_for_data(py: pyo3::Python<'_>, data: &[u8]) -> Result { +fn parse_spki_for_data( + py: pyo3::Python<'_>, + data: &[u8], +) -> Result { let spki = asn1::parse_single::>(data)?; if spki.data.padding_bits() != 0 { return Err(pyo3::exceptions::PyValueError::new_err("Invalid public key encoding").into()); @@ -131,7 +133,10 @@ pub(crate) fn big_byte_slice_to_py_int<'p>( } #[pyo3::prelude::pyfunction] -fn decode_dss_signature(py: pyo3::Python<'_>, data: &[u8]) -> Result { +fn decode_dss_signature( + py: pyo3::Python<'_>, + data: &[u8], +) -> Result { let sig = asn1::parse_single::>(data)?; Ok(( @@ -164,7 +169,7 @@ pub(crate) fn encode_der_data<'p>( pem_tag: String, data: Vec, encoding: &'p pyo3::PyAny, -) -> PyAsn1Result<&'p pyo3::types::PyBytes> { +) -> CryptographyResult<&'p pyo3::types::PyBytes> { let encoding_class = py .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))?; @@ -198,7 +203,7 @@ fn encode_dss_signature( py: pyo3::Python<'_>, r: &pyo3::types::PyLong, s: &pyo3::types::PyLong, -) -> PyAsn1Result { +) -> CryptographyResult { let sig = DssSignature { r: asn1::BigUint::new(py_uint_to_big_endian_bytes(py, r)?).unwrap(), s: asn1::BigUint::new(py_uint_to_big_endian_bytes(py, s)?).unwrap(), @@ -264,7 +269,7 @@ fn parse_name_value_tags(rdns: &mut Name<'_>) -> Vec { } #[pyo3::prelude::pyfunction] -fn test_parse_certificate(data: &[u8]) -> Result { +fn test_parse_certificate(data: &[u8]) -> Result { let mut asn1_cert = asn1::parse_single::>(data)?; Ok(TestCertificate { @@ -295,31 +300,33 @@ pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::pr #[cfg(test)] mod tests { - use super::PyAsn1Error; + use super::CryptographyError; #[test] - fn test_pyasn1error_from() { + fn test_cryptographyerror_from() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let e: PyAsn1Error = asn1::WriteError::AllocationError.into(); + let e: CryptographyError = asn1::WriteError::AllocationError.into(); assert!(matches!( e, - PyAsn1Error::Asn1Write(asn1::WriteError::AllocationError) + CryptographyError::Asn1Write(asn1::WriteError::AllocationError) )); let py_e: pyo3::PyErr = e.into(); assert!(py_e.is_instance::(py)); - let e: PyAsn1Error = pyo3::PyDowncastError::new(py.None().as_ref(py), "abc").into(); - assert!(matches!(e, PyAsn1Error::Py(_))); + let e: CryptographyError = + pyo3::PyDowncastError::new(py.None().as_ref(py), "abc").into(); + assert!(matches!(e, CryptographyError::Py(_))); }) } #[test] - fn test_pyasn1error_add_location() { + fn test_cryptographyerror_add_location() { let py_err = pyo3::PyErr::new::("Error!"); - PyAsn1Error::Py(py_err).add_location(asn1::ParseLocation::Field("meh")); + CryptographyError::Py(py_err).add_location(asn1::ParseLocation::Field("meh")); let asn1_write_err = asn1::WriteError::AllocationError; - PyAsn1Error::Asn1Write(asn1_write_err).add_location(asn1::ParseLocation::Field("meh")); + CryptographyError::Asn1Write(asn1_write_err) + .add_location(asn1::ParseLocation::Field("meh")); } } diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index 724f78eaac32..c172310c0669 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::PyAsn1Result; +use crate::asn1::CryptographyResult; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -14,7 +14,7 @@ pub(crate) struct ObjectIdentifier { #[pyo3::pymethods] impl ObjectIdentifier { #[new] - fn new(value: &str) -> PyAsn1Result { + fn new(value: &str) -> CryptographyResult { let oid = asn1::ObjectIdentifier::from_string(value) .ok_or_else(|| asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue))?; Ok(ObjectIdentifier { oid }) diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 48eb099325b0..557c09be10b4 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{encode_der_data, PyAsn1Result}; +use crate::asn1::{encode_der_data, CryptographyResult}; use crate::x509; use chrono::Timelike; @@ -87,7 +87,7 @@ fn serialize_certificates<'p>( py: pyo3::Python<'p>, py_certs: Vec>, encoding: &'p pyo3::PyAny, -) -> PyAsn1Result<&'p pyo3::types::PyBytes> { +) -> CryptographyResult<&'p pyo3::types::PyBytes> { if py_certs.is_empty() { return Err(pyo3::exceptions::PyTypeError::new_err( "certs must be a list of certs with length >= 1", @@ -129,7 +129,7 @@ fn sign_and_serialize<'p>( builder: &'p pyo3::PyAny, encoding: &'p pyo3::PyAny, options: &'p pyo3::types::PyList, -) -> PyAsn1Result<&'p pyo3::types::PyBytes> { +) -> CryptographyResult<&'p pyo3::types::PyBytes> { let pkcs7_options = py .import("cryptography.hazmat.primitives.serialization.pkcs7")? .getattr(crate::intern!(py, "PKCS7Options"))?; diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index d47c9b2c3e25..39d0ebfb5ccc 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -4,7 +4,7 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, - PyAsn1Error, PyAsn1Result, + CryptographyError, CryptographyResult, }; use crate::x509; use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; @@ -121,7 +121,7 @@ impl Certificate { slf } - fn public_key<'p>(&self, py: pyo3::Python<'p>) -> PyAsn1Result<&'p pyo3::PyAny> { + fn public_key<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { // This makes an unnecessary copy. It'd be nice to get rid of it. let serialized = pyo3::types::PyBytes::new( py, @@ -137,7 +137,7 @@ impl Certificate { &self, py: pyo3::Python<'p>, algorithm: pyo3::PyObject, - ) -> PyAsn1Result<&'p pyo3::PyAny> { + ) -> CryptographyResult<&'p pyo3::PyAny> { let hasher = py .import("cryptography.hazmat.primitives.hashes")? .getattr(crate::intern!(py, "Hash"))? @@ -153,21 +153,24 @@ impl Certificate { &self, py: pyo3::Python<'p>, encoding: &'p pyo3::PyAny, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let result = asn1::write_single(self.raw.borrow_value())?; encode_der_data(py, "CERTIFICATE".to_string(), result, encoding) } #[getter] - fn serial_number<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn serial_number<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let bytes = self.raw.borrow_value().tbs_cert.serial.as_bytes(); warn_if_negative_serial(py, bytes)?; Ok(big_byte_slice_to_py_int(py, bytes)?) } #[getter] - fn version<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn version<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, CryptographyError> { let version = &self.raw.borrow_value().tbs_cert.version; cert_version(py, *version) } @@ -192,7 +195,7 @@ impl Certificate { fn tbs_certificate_bytes<'p>( &self, py: pyo3::Python<'p>, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let result = asn1::write_single(&self.raw.borrow_value().tbs_cert)?; Ok(pyo3::types::PyBytes::new(py, &result)) } @@ -201,7 +204,7 @@ impl Certificate { fn tbs_precertificate_bytes<'p>( &self, py: pyo3::Python<'p>, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let val = self.raw.borrow_value(); let mut tbs_precert = val.tbs_cert.clone(); // Remove the SCT list extension @@ -213,9 +216,11 @@ impl Certificate { .filter(|x| x.extn_id != oid::PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID) .collect(); if filtered_extensions.len() == ext_count { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Could not find pre-certificate SCT list extension", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Could not find pre-certificate SCT list extension", + ), + )); } let filtered_extensions: x509::Extensions<'_> = Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(filtered_extensions), @@ -224,9 +229,11 @@ impl Certificate { let result = asn1::write_single(&tbs_precert)?; Ok(pyo3::types::PyBytes::new(py, &result)) } - None => Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Could not find any extensions in TBS certificate", - ))), + None => Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Could not find any extensions in TBS certificate", + ), + )), } } @@ -263,14 +270,14 @@ impl Certificate { fn signature_hash_algorithm<'p>( &self, py: pyo3::Python<'p>, - ) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_instance( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", (format!( @@ -324,16 +331,18 @@ impl Certificate { &self, py: pyo3::Python<'_>, issuer: pyo3::PyRef<'_, Certificate>, - ) -> PyAsn1Result<()> { + ) -> CryptographyResult<()> { if self.raw.borrow_value().tbs_cert.signature_alg != self.raw.borrow_value().signature_alg { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( "Inner and outer signature algorithms do not match. This is an invalid certificate." ))); }; if self.raw.borrow_value().tbs_cert.issuer != issuer.raw.borrow_value().tbs_cert.subject { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Issuer certificate subject does not match certificate issuer.", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Issuer certificate subject does not match certificate issuer.", + ), + )); }; sign::verify_signature_with_oid( py, @@ -345,7 +354,7 @@ impl Certificate { } } -fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, PyAsn1Error> { +fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, CryptographyError> { let x509_module = py.import("cryptography.x509")?; match version { 0 => Ok(x509_module @@ -354,7 +363,7 @@ fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, PyAsn 2 => Ok(x509_module .getattr(crate::intern!(py, "Version"))? .get_item("v3")?), - _ => Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + _ => Err(CryptographyError::from(pyo3::PyErr::from_instance( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid X509 version", version), version))?, @@ -363,7 +372,7 @@ fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, PyAsn } #[pyo3::prelude::pyfunction] -fn load_pem_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result { +fn load_pem_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> CryptographyResult { // We support both PEM header strings that OpenSSL does // https://github.com/openssl/openssl/blob/5e2d22d53ed322a7124e26a4fbd116a8210eb77a/include/openssl/pem.h#L32-L33 let parsed = x509::find_in_pem( @@ -375,7 +384,10 @@ fn load_pem_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result< } #[pyo3::prelude::pyfunction] -fn load_pem_x509_certificates(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result> { +fn load_pem_x509_certificates( + py: pyo3::Python<'_>, + data: &[u8], +) -> CryptographyResult> { let certs = pem::parse_many(data)? .iter() .filter(|p| p.tag == "CERTIFICATE" || p.tag == "X509 CERTIFICATE") @@ -383,14 +395,14 @@ fn load_pem_x509_certificates(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result .collect::, _>>()?; if certs.is_empty() { - return Err(PyAsn1Error::from(pem::PemError::MalformedFraming)); + return Err(CryptographyError::from(pem::PemError::MalformedFraming)); } Ok(certs) } #[pyo3::prelude::pyfunction] -fn load_der_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result { +fn load_der_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> CryptographyResult { let raw = OwnedRawCertificate::try_new(Arc::from(data), |data| asn1::parse_single(data))?; // Parse cert version immediately so we can raise error on parse if it is invalid. cert_version(py, raw.borrow_value().tbs_cert.version)?; @@ -493,7 +505,7 @@ fn parse_display_text( fn parse_user_notice( py: pyo3::Python<'_>, un: UserNotice<'_>, -) -> Result { +) -> Result { let x509_module = py.import("cryptography.x509")?; let et = match un.explicit_text { Some(data) => parse_display_text(py, data)?, @@ -520,7 +532,7 @@ fn parse_user_notice( fn parse_policy_qualifiers<'a>( py: pyo3::Python<'_>, policy_qualifiers: &asn1::SequenceOf<'a, PolicyQualifierInfo<'a>>, -) -> Result { +) -> Result { let py_pq = pyo3::types::PyList::empty(py); for pqi in policy_qualifiers.clone() { let qualifier = match pqi.qualifier { @@ -528,16 +540,20 @@ fn parse_policy_qualifiers<'a>( if pqi.policy_qualifier_id == oid::CP_CPS_URI_OID { pyo3::types::PyString::new(py, data.as_str()).to_object(py) } else { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "CpsUri ASN.1 structure found but OID did not match", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "CpsUri ASN.1 structure found but OID did not match", + ), + )); } } Qualifier::UserNotice(un) => { if pqi.policy_qualifier_id != oid::CP_USER_NOTICE_OID { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "UserNotice ASN.1 structure found but OID did not match", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "UserNotice ASN.1 structure found but OID did not match", + ), + )); } parse_user_notice(py, un)? } @@ -547,7 +563,7 @@ fn parse_policy_qualifiers<'a>( Ok(py_pq.to_object(py)) } -fn parse_cp(py: pyo3::Python<'_>, ext_data: &[u8]) -> Result { +fn parse_cp(py: pyo3::Python<'_>, ext_data: &[u8]) -> Result { let cp = asn1::parse_single::>>(ext_data)?; let x509_module = py.import("cryptography.x509")?; let certificate_policies = pyo3::types::PyList::empty(py); @@ -598,7 +614,7 @@ pub(crate) struct GeneralSubtree<'a> { fn parse_general_subtrees( py: pyo3::Python<'_>, subtrees: SequenceOfSubtrees<'_>, -) -> Result { +) -> Result { let gns = pyo3::types::PyList::empty(py); for gs in subtrees.unwrap_read().clone() { gns.append(x509::parse_general_name(py, gs.base)?)?; @@ -646,7 +662,7 @@ pub(crate) struct AuthorityKeyIdentifier<'a> { pub(crate) fn parse_distribution_point_name( py: pyo3::Python<'_>, dp: DistributionPointName<'_>, -) -> Result<(pyo3::PyObject, pyo3::PyObject), PyAsn1Error> { +) -> Result<(pyo3::PyObject, pyo3::PyObject), CryptographyError> { Ok(match dp { DistributionPointName::FullName(data) => ( x509::parse_general_names(py, data.unwrap_read())?, @@ -661,7 +677,7 @@ pub(crate) fn parse_distribution_point_name( fn parse_distribution_point( py: pyo3::Python<'_>, dp: DistributionPoint<'_>, -) -> Result { +) -> Result { let (full_name, relative_name) = match dp.distribution_point { Some(data) => parse_distribution_point_name(py, data)?, None => (py.None(), py.None()), @@ -682,7 +698,7 @@ fn parse_distribution_point( pub(crate) fn parse_distribution_points( py: pyo3::Python<'_>, data: &[u8], -) -> Result { +) -> Result { let dps = asn1::parse_single::>>(data)?; let py_dps = pyo3::types::PyList::empty(py); for dp in dps { @@ -695,7 +711,7 @@ pub(crate) fn parse_distribution_points( pub(crate) fn parse_distribution_point_reasons( py: pyo3::Python<'_>, reasons: Option<&asn1::BitString<'_>>, -) -> Result { +) -> Result { let reason_bit_mapping = py .import("cryptography.x509.extensions")? .getattr(crate::intern!(py, "_REASON_BIT_MAPPING"))?; @@ -753,7 +769,7 @@ pub(crate) struct PolicyConstraints { pub(crate) fn parse_authority_key_identifier<'p>( py: pyo3::Python<'p>, ext_data: &[u8], -) -> Result<&'p pyo3::PyAny, PyAsn1Error> { +) -> Result<&'p pyo3::PyAny, CryptographyError> { let x509_module = py.import("cryptography.x509")?; let aki = asn1::parse_single::>(ext_data)?; let serial = match aki.authority_cert_serial_number { @@ -772,7 +788,7 @@ pub(crate) fn parse_authority_key_identifier<'p>( pub(crate) fn parse_access_descriptions( py: pyo3::Python<'_>, ext_data: &[u8], -) -> Result { +) -> Result { let x509_module = py.import("cryptography.x509")?; let ads = pyo3::types::PyList::empty(py); let parsed = asn1::parse_single::>(ext_data)?; @@ -792,7 +808,7 @@ pub fn parse_cert_ext<'p>( py: pyo3::Python<'p>, oid: asn1::ObjectIdentifier, ext_data: &[u8], -) -> PyAsn1Result> { +) -> CryptographyResult> { let x509_module = py.import("cryptography.x509")?; match oid { oid::SUBJECT_ALTERNATIVE_NAME_OID => { @@ -973,12 +989,17 @@ pub fn parse_cert_ext<'p>( } } -pub(crate) fn time_from_py(py: pyo3::Python<'_>, val: &pyo3::PyAny) -> PyAsn1Result { +pub(crate) fn time_from_py( + py: pyo3::Python<'_>, + val: &pyo3::PyAny, +) -> CryptographyResult { let dt = x509::py_to_chrono(py, val)?; time_from_chrono(dt) } -pub(crate) fn time_from_chrono(dt: chrono::DateTime) -> PyAsn1Result { +pub(crate) fn time_from_chrono( + dt: chrono::DateTime, +) -> CryptographyResult { if dt.year() >= 2050 { Ok(x509::Time::GeneralizedTime(asn1::GeneralizedTime::new(dt)?)) } else { @@ -992,7 +1013,7 @@ fn create_x509_certificate( builder: &pyo3::PyAny, private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, -) -> PyAsn1Result { +) -> CryptographyResult { let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let der_encoding = serialization_mod diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index b4ffc41b28fc..e93ec7ec0775 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{oid_to_py_oid, py_oid_to_oid, PyAsn1Error, PyAsn1Result}; +use crate::asn1::{oid_to_py_oid, py_oid_to_oid, CryptographyError, CryptographyResult}; use crate::x509; use chrono::{Datelike, TimeZone, Timelike}; use pyo3::types::IntoPyDict; @@ -17,15 +17,14 @@ pub(crate) fn find_in_pem( data: &[u8], filter_fn: fn(&pem::Pem) -> bool, no_match_err: &'static str, -) -> Result { +) -> Result { let all_sections = pem::parse_many(data)?; if all_sections.is_empty() { - return Err(PyAsn1Error::from(pem::PemError::MalformedFraming)); + return Err(CryptographyError::from(pem::PemError::MalformedFraming)); } - all_sections - .into_iter() - .find(filter_fn) - .ok_or_else(|| PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err(no_match_err))) + all_sections.into_iter().find(filter_fn).ok_or_else(|| { + CryptographyError::from(pyo3::exceptions::PyValueError::new_err(no_match_err)) + }) } pub(crate) type Name<'a> = Asn1ReadableOrWritable< @@ -103,7 +102,7 @@ pub(crate) fn encode_name<'p>( pub(crate) fn encode_name_entry<'p>( py: pyo3::Python<'p>, py_name_entry: &'p pyo3::PyAny, -) -> PyAsn1Result> { +) -> CryptographyResult> { let asn1_type = py .import("cryptography.x509.name")? .getattr(crate::intern!(py, "_ASN1Type"))?; @@ -141,7 +140,7 @@ pub(crate) fn encode_name_entry<'p>( fn encode_name_bytes<'p>( py: pyo3::Python<'p>, py_name: &'p pyo3::PyAny, -) -> PyAsn1Result<&'p pyo3::types::PyBytes> { +) -> CryptographyResult<&'p pyo3::types::PyBytes> { let name = encode_name(py, py_name)?; let result = asn1::write_single(&name)?; Ok(pyo3::types::PyBytes::new(py, &result)) @@ -217,7 +216,7 @@ pub(crate) type SequenceOfGeneralName<'a> = Asn1ReadableOrWritable< pub(crate) fn encode_general_names<'a>( py: pyo3::Python<'a>, py_gns: &'a pyo3::PyAny, -) -> Result>, PyAsn1Error> { +) -> Result>, CryptographyError> { let mut gns = vec![]; for el in py_gns.iter()? { let gn = encode_general_name(py, el?)?; @@ -229,7 +228,7 @@ pub(crate) fn encode_general_names<'a>( pub(crate) fn encode_general_name<'a>( py: pyo3::Python<'a>, gn: &'a pyo3::PyAny, -) -> Result, PyAsn1Error> { +) -> Result, CryptographyError> { let gn_module = py.import("cryptography.x509.general_name")?; let gn_type = gn.get_type().as_ref(); let gn_value = gn.getattr(crate::intern!(py, "value"))?; @@ -266,9 +265,9 @@ pub(crate) fn encode_general_name<'a>( let oid = py_oid_to_oid(gn_value)?; Ok(GeneralName::RegisteredID(oid)) } else { - Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Unsupported GeneralName type", - ))) + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Unsupported GeneralName type"), + )) } } @@ -287,7 +286,7 @@ pub(crate) type SequenceOfAccessDescriptions<'a> = Asn1ReadableOrWritable< pub(crate) fn encode_access_descriptions<'a>( py: pyo3::Python<'a>, py_ads: &'a pyo3::PyAny, -) -> Result, PyAsn1Error> { +) -> Result, CryptographyError> { let mut ads = vec![]; for py_ad in py_ads.iter()? { let py_ad = py_ad?; @@ -342,7 +341,7 @@ pub(crate) struct Extension<'a> { pub(crate) fn parse_name<'p>( py: pyo3::Python<'p>, name: &Name<'_>, -) -> Result<&'p pyo3::PyAny, PyAsn1Error> { +) -> Result<&'p pyo3::PyAny, CryptographyError> { let x509_module = py.import("cryptography.x509")?; let py_rdns = pyo3::types::PyList::empty(py); for rdn in name.unwrap_read().clone() { @@ -355,7 +354,7 @@ pub(crate) fn parse_name<'p>( fn parse_name_attribute( py: pyo3::Python<'_>, attribute: AttributeTypeValue<'_>, -) -> Result { +) -> Result { let x509_module = py.import("cryptography.x509")?; let oid = oid_to_py_oid(py, &attribute.type_id)?.to_object(py); let tag_enum = py @@ -366,7 +365,7 @@ fn parse_name_attribute( .tag() .as_u8() .ok_or_else(|| { - PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + CryptographyError::from(pyo3::exceptions::PyValueError::new_err( "Long-form tags are not supported in NameAttribute values", )) })? @@ -400,7 +399,7 @@ fn parse_name_attribute( pub(crate) fn parse_rdn<'a>( py: pyo3::Python<'_>, rdn: &asn1::SetOf<'a, AttributeTypeValue<'a>>, -) -> Result { +) -> Result { let x509_module = py.import("cryptography.x509")?; let py_attrs = pyo3::types::PySet::empty(py)?; for attribute in rdn.clone() { @@ -415,7 +414,7 @@ pub(crate) fn parse_rdn<'a>( pub(crate) fn parse_general_name( py: pyo3::Python<'_>, gn: GeneralName<'_>, -) -> Result { +) -> Result { let x509_module = py.import("cryptography.x509")?; let py_gn = match gn { GeneralName::OtherName(data) => { @@ -462,7 +461,7 @@ pub(crate) fn parse_general_name( .to_object(py) } _ => { - return Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_instance( x509_module.call_method1( "UnsupportedGeneralNameType", ("x400Address/EDIPartyName are not supported types",), @@ -476,7 +475,7 @@ pub(crate) fn parse_general_name( pub(crate) fn parse_general_names<'a>( py: pyo3::Python<'_>, gn_seq: &asn1::SequenceOf<'a, GeneralName<'a>>, -) -> Result { +) -> Result { let gns = pyo3::types::PyList::empty(py); for gn in gn_seq.clone() { let py_gn = parse_general_name(py, gn)?; @@ -485,7 +484,10 @@ pub(crate) fn parse_general_names<'a>( Ok(gns.to_object(py)) } -fn create_ip_network(py: pyo3::Python<'_>, data: &[u8]) -> Result { +fn create_ip_network( + py: pyo3::Python<'_>, + data: &[u8], +) -> Result { let ip_module = py.import("ipaddress")?; let x509_module = py.import("cryptography.x509")?; let prefix = match data.len() { @@ -497,7 +499,7 @@ fn create_ip_network(py: pyo3::Python<'_>, data: &[u8]) -> Result Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + _ => Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( format!("Invalid IPNetwork, must be 8 bytes for IPv4 and 32 bytes for IPv6. Found length: {}", data.len()), ))), }; @@ -517,31 +519,31 @@ fn create_ip_network(py: pyo3::Python<'_>, data: &[u8]) -> Result Result { +fn ipv4_netmask(num: u32) -> Result { // we invert and check leading zeros because leading_ones wasn't stabilized // until 1.46.0. When we raise our MSRV we should change this if (!num).leading_zeros() + num.trailing_zeros() != 32 { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Invalid netmask", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Invalid netmask"), + )); } Ok((!num).leading_zeros()) } -fn ipv6_netmask(num: u128) -> Result { +fn ipv6_netmask(num: u128) -> Result { // we invert and check leading zeros because leading_ones wasn't stabilized // until 1.46.0. When we raise our MSRV we should change this if (!num).leading_zeros() + num.trailing_zeros() != 128 { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Invalid netmask", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Invalid netmask"), + )); } Ok((!num).leading_zeros()) } pub(crate) fn parse_and_cache_extensions< 'p, - F: Fn(&asn1::ObjectIdentifier, &[u8]) -> Result, PyAsn1Error>, + F: Fn(&asn1::ObjectIdentifier, &[u8]) -> Result, CryptographyError>, >( py: pyo3::Python<'p>, cached_extensions: &mut Option, @@ -589,7 +591,11 @@ pub(crate) fn parse_and_cache_extensions< pub(crate) fn encode_extensions< 'p, - F: Fn(pyo3::Python<'_>, &asn1::ObjectIdentifier, &pyo3::PyAny) -> PyAsn1Result>>, + F: Fn( + pyo3::Python<'_>, + &asn1::ObjectIdentifier, + &pyo3::PyAny, + ) -> CryptographyResult>>, >( py: pyo3::Python<'p>, py_exts: &'p pyo3::PyAny, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 5f4ff09e7a26..75ac22541721 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -4,7 +4,7 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, - PyAsn1Error, PyAsn1Result, + CryptographyError, CryptographyResult, }; use crate::x509; use crate::x509::{certificate, extensions, oid, sign}; @@ -16,7 +16,7 @@ use std::sync::Arc; fn load_der_x509_crl( py: pyo3::Python<'_>, data: &[u8], -) -> Result { +) -> Result { let raw = OwnedRawCertificateRevocationList::try_new( Arc::from(data), |data| asn1::parse_single(data), @@ -26,7 +26,7 @@ fn load_der_x509_crl( let version = raw.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { let x509_module = py.import("cryptography.x509")?; - return Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_instance( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CRL version", version), version))?, @@ -43,7 +43,7 @@ fn load_der_x509_crl( fn load_pem_x509_crl( py: pyo3::Python<'_>, data: &[u8], -) -> Result { +) -> Result { let block = x509::find_in_pem( data, |p| p.tag == "X509 CRL", @@ -72,7 +72,7 @@ struct CertificateRevocationList { } impl CertificateRevocationList { - fn public_bytes_der(&self) -> PyAsn1Result> { + fn public_bytes_der(&self) -> CryptographyResult> { Ok(asn1::write_single(self.raw.borrow_value())?) } @@ -208,7 +208,7 @@ impl CertificateRevocationList { fn tbs_certlist_bytes<'p>( &self, py: pyo3::Python<'p>, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let b = asn1::write_single(&self.raw.borrow_value().tbs_cert_list)?; Ok(pyo3::types::PyBytes::new(py, &b)) } @@ -217,7 +217,7 @@ impl CertificateRevocationList { &self, py: pyo3::Python<'p>, encoding: &'p pyo3::PyAny, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let result = asn1::write_single(self.raw.borrow_value())?; encode_der_data(py, "X509 CRL".to_string(), result, encoding) @@ -373,7 +373,7 @@ impl CertificateRevocationList { slf: pyo3::PyRef<'_, Self>, py: pyo3::Python<'p>, public_key: &'p pyo3::PyAny, - ) -> PyAsn1Result { + ) -> CryptographyResult { if slf.raw.borrow_value().tbs_cert_list.signature != slf.raw.borrow_value().signature_algorithm { @@ -588,7 +588,7 @@ pub(crate) type CRLReason = asn1::Enumerated; pub(crate) fn parse_crl_reason_flags<'p>( py: pyo3::Python<'p>, reason: &CRLReason, -) -> PyAsn1Result<&'p pyo3::PyAny> { +) -> CryptographyResult<&'p pyo3::PyAny> { let x509_module = py.import("cryptography.x509")?; let flag_name = match reason.value() { 0 => "unspecified", @@ -602,9 +602,12 @@ pub(crate) fn parse_crl_reason_flags<'p>( 9 => "privilege_withdrawn", 10 => "aa_compromise", value => { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - format!("Unsupported reason code: {}", value), - ))) + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "Unsupported reason code: {}", + value + )), + )) } }; Ok(x509_module @@ -616,7 +619,7 @@ pub fn parse_crl_entry_ext<'p>( py: pyo3::Python<'p>, oid: asn1::ObjectIdentifier, data: &[u8], -) -> PyAsn1Result> { +) -> CryptographyResult> { let x509_module = py.import("cryptography.x509")?; match oid { oid::CRL_REASON_OID => { @@ -655,7 +658,7 @@ fn create_x509_crl( builder: &pyo3::PyAny, private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, -) -> PyAsn1Result { +) -> CryptographyResult { let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; let mut revoked_certs = vec![]; diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index cb9056c80b23..66ce3413bf49 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -2,7 +2,9 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid, PyAsn1Error, PyAsn1Result}; +use crate::asn1::{ + encode_der_data, oid_to_py_oid, py_oid_to_oid, CryptographyError, CryptographyResult, +}; use crate::x509; use crate::x509::{certificate, oid, sign}; use asn1::SimpleAsn1Readable; @@ -41,18 +43,20 @@ pub(crate) struct Attribute<'a> { >, } -fn check_attribute_length<'a>(values: asn1::SetOf<'a, asn1::Tlv<'a>>) -> Result<(), PyAsn1Error> { +fn check_attribute_length<'a>( + values: asn1::SetOf<'a, asn1::Tlv<'a>>, +) -> Result<(), CryptographyError> { if values.count() > 1 { - Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Only single-valued attributes are supported", - ))) + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Only single-valued attributes are supported"), + )) } else { Ok(()) } } impl CertificationRequestInfo<'_> { - fn get_extension_attribute(&self) -> Result>, PyAsn1Error> { + fn get_extension_attribute(&self) -> Result>, CryptographyError> { for attribute in self.attributes.unwrap_read().clone() { if attribute.type_id == oid::EXTENSION_REQUEST || attribute.type_id == oid::MS_EXTENSION_REQUEST @@ -106,7 +110,7 @@ impl pyo3::basic::PyObjectProtocol for CertificateSigningRequest { #[pyo3::prelude::pymethods] impl CertificateSigningRequest { - fn public_key<'p>(&self, py: pyo3::Python<'p>) -> PyAsn1Result<&'p pyo3::PyAny> { + fn public_key<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { // This makes an unnecessary copy. It'd be nice to get rid of it. let serialized = pyo3::types::PyBytes::new( py, @@ -130,7 +134,7 @@ impl CertificateSigningRequest { fn tbs_certrequest_bytes<'p>( &self, py: pyo3::Python<'p>, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let result = asn1::write_single(&self.raw.borrow_value().csr_info)?; Ok(pyo3::types::PyBytes::new(py, &result)) } @@ -144,14 +148,14 @@ impl CertificateSigningRequest { fn signature_hash_algorithm<'p>( &self, py: pyo3::Python<'p>, - ) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_instance( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", (format!( @@ -172,7 +176,7 @@ impl CertificateSigningRequest { &self, py: pyo3::Python<'p>, encoding: &'p pyo3::PyAny, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let result = asn1::write_single(self.raw.borrow_value())?; encode_der_data(py, "CERTIFICATE REQUEST".to_string(), result, encoding) @@ -243,7 +247,7 @@ impl CertificateSigningRequest { let val = attribute.values.unwrap_read().clone().next().unwrap(); let serialized = pyo3::types::PyBytes::new(py, val.data()); let tag = val.tag().as_u8().ok_or_else(|| { - PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( + CryptographyError::from(pyo3::exceptions::PyValueError::new_err( "Long-form tags are not supported in CSR attribute values", )) })?; @@ -266,7 +270,10 @@ impl CertificateSigningRequest { } #[getter] - fn is_signature_valid(slf: pyo3::PyRef<'_, Self>, py: pyo3::Python<'_>) -> PyAsn1Result { + fn is_signature_valid( + slf: pyo3::PyRef<'_, Self>, + py: pyo3::Python<'_>, + ) -> CryptographyResult { Ok(sign::verify_signature_with_oid( py, slf.public_key(py)?, @@ -279,7 +286,10 @@ impl CertificateSigningRequest { } #[pyo3::prelude::pyfunction] -fn load_pem_x509_csr(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result { +fn load_pem_x509_csr( + py: pyo3::Python<'_>, + data: &[u8], +) -> CryptographyResult { // We support both PEM header strings that OpenSSL does // https://github.com/openssl/openssl/blob/5e2d22d53ed322a7124e26a4fbd116a8210eb77a/include/openssl/pem.h#L35-L36 let parsed = x509::find_in_pem( @@ -291,13 +301,16 @@ fn load_pem_x509_csr(py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result, data: &[u8]) -> PyAsn1Result { +fn load_der_x509_csr( + py: pyo3::Python<'_>, + data: &[u8], +) -> CryptographyResult { let raw = OwnedRawCsr::try_new(data.to_vec(), |data| asn1::parse_single(data))?; let version = raw.borrow_value().csr_info.version; if version != 0 { let x509_module = py.import("cryptography.x509")?; - return Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_instance( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CSR version", version), version))?, @@ -316,7 +329,7 @@ fn create_x509_csr( builder: &pyo3::PyAny, private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, -) -> PyAsn1Result { +) -> CryptographyResult { let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let der_encoding = serialization_mod @@ -354,9 +367,11 @@ fn create_x509_csr( asn1::Tag::from_bytes(&[tag])?.0 } else { if std::str::from_utf8(value).is_err() { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Attribute values must be valid utf-8.", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Attribute values must be valid utf-8.", + ), + )); } asn1::Utf8String::TAG }; diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 537106a3663a..f8dd28a45215 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -2,14 +2,16 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{py_oid_to_oid, py_uint_to_big_endian_bytes, PyAsn1Error, PyAsn1Result}; +use crate::asn1::{ + py_oid_to_oid, py_uint_to_big_endian_bytes, CryptographyError, CryptographyResult, +}; use crate::x509; use crate::x509::{certificate, crl, oid, sct}; fn encode_general_subtrees<'a>( py: pyo3::Python<'a>, subtrees: &'a pyo3::PyAny, -) -> Result>, PyAsn1Error> { +) -> Result>, CryptographyError> { if subtrees.is_none() { Ok(None) } else { @@ -120,7 +122,7 @@ pub(crate) fn encode_extension( py: pyo3::Python<'_>, oid: &asn1::ObjectIdentifier, ext: &pyo3::PyAny, -) -> PyAsn1Result>> { +) -> CryptographyResult>> { match oid { &oid::BASIC_CONSTRAINTS_OID => { let bc = ext.extract::()?; diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index de5ace7d069e..d06487021023 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::PyAsn1Result; +use crate::asn1::CryptographyResult; use crate::x509; use crate::x509::oid; use once_cell::sync::Lazy; @@ -42,7 +42,7 @@ impl CertID<'_> { cert: &'p x509::Certificate, issuer: &'p x509::Certificate, hash_algorithm: &'p pyo3::PyAny, - ) -> PyAsn1Result> { + ) -> CryptographyResult> { let issuer_der = asn1::write_single(&cert.raw.borrow_value_public().tbs_cert.issuer)?; let issuer_name_hash = hash_data(py, hash_algorithm, &issuer_der)?; let issuer_key_hash = hash_data( @@ -77,7 +77,7 @@ impl CertID<'_> { issuer_key_hash: &'p [u8], serial_number: asn1::BigInt<'p>, hash_algorithm: &'p pyo3::PyAny, - ) -> PyAsn1Result> { + ) -> CryptographyResult> { Ok(CertID { hash_algorithm: x509::AlgorithmIdentifier { oid: HASH_NAME_TO_OIDS[hash_algorithm diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 0f7e8f86992e..078df60503c6 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -3,7 +3,7 @@ // for complete details. use crate::asn1::{ - big_byte_slice_to_py_int, py_uint_to_big_endian_bytes, PyAsn1Error, PyAsn1Result, + big_byte_slice_to_py_int, py_uint_to_big_endian_bytes, CryptographyError, CryptographyResult, }; use crate::x509; use crate::x509::{extensions, ocsp, oid}; @@ -18,7 +18,7 @@ struct OwnedRawOCSPRequest { } #[pyo3::prelude::pyfunction] -fn load_der_ocsp_request(_py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result { +fn load_der_ocsp_request(_py: pyo3::Python<'_>, data: &[u8]) -> CryptographyResult { let raw = OwnedRawOCSPRequest::try_new(Arc::from(data), |data| asn1::parse_single(data))?; if raw @@ -29,7 +29,7 @@ fn load_der_ocsp_request(_py: pyo3::Python<'_>, data: &[u8]) -> PyAsn1Result(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn hash_algorithm<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let cert_id = self.cert_id(); let hashes = py.import("cryptography.hazmat.primitives.hashes")?; @@ -84,7 +87,7 @@ impl OCSPRequest { Some(alg_name) => Ok(hashes.getattr(alg_name)?.call0()?), None => { let exceptions = py.import("cryptography.exceptions")?; - Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_instance( exceptions .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( @@ -97,7 +100,10 @@ impl OCSPRequest { } #[getter] - fn serial_number<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn serial_number<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let bytes = self.cert_id().serial_number.as_bytes(); Ok(big_byte_slice_to_py_int(py, bytes)?) } @@ -131,7 +137,7 @@ impl OCSPRequest { &self, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))? @@ -181,7 +187,10 @@ struct Request<'a> { } #[pyo3::prelude::pyfunction] -fn create_ocsp_request(py: pyo3::Python<'_>, builder: &pyo3::PyAny) -> PyAsn1Result { +fn create_ocsp_request( + py: pyo3::Python<'_>, + builder: &pyo3::PyAny, +) -> CryptographyResult { let builder_request = builder.getattr(crate::intern!(py, "_request"))?; // Declare outside the if-block so the lifetimes are right. diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 90ced614cf9b..35e1d672b081 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, PyAsn1Error, PyAsn1Result}; +use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_chrono, sct}; use chrono::Timelike; @@ -11,7 +11,10 @@ use std::sync::Arc; const BASIC_RESPONSE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 1); #[pyo3::prelude::pyfunction] -fn load_der_ocsp_response(_py: pyo3::Python<'_>, data: &[u8]) -> Result { +fn load_der_ocsp_response( + _py: pyo3::Python<'_>, + data: &[u8], +) -> Result { let raw = OwnedRawOCSPResponse::try_new(Arc::from(data), |data| asn1::parse_single(data))?; let response = raw.borrow_value(); @@ -19,15 +22,19 @@ fn load_der_ocsp_response(_py: pyo3::Python<'_>, data: &[u8]) -> Result match response.response_bytes { Some(ref bytes) => { if bytes.response_type != BASIC_RESPONSE_OID { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Successful OCSP response does not contain a BasicResponse", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Successful OCSP response does not contain a BasicResponse", + ), + )); } } None => { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Successful OCSP response does not contain a BasicResponse", - ))) + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Successful OCSP response does not contain a BasicResponse", + ), + )) } }, MALFORMED_REQUEST_RESPOSNE @@ -36,9 +43,9 @@ fn load_der_ocsp_response(_py: pyo3::Python<'_>, data: &[u8]) -> Result {} _ => { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "OCSP response has an unknown status code", - ))) + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("OCSP response has an unknown status code"), + )) } }; Ok(OCSPResponse { @@ -86,7 +93,7 @@ const UNAUTHORIZED_RESPONSE: u32 = 6; #[pyo3::prelude::pymethods] impl OCSPResponse { #[getter] - fn responses(&self) -> Result { + fn responses(&self) -> Result { self.requires_successful_response()?; Ok(OCSPResponseIterator { contents: OwnedOCSPResponseIteratorData::try_new(Arc::clone(&self.raw), |v| { @@ -163,7 +170,7 @@ impl OCSPResponse { fn signature_hash_algorithm<'p>( &self, py: pyo3::Python<'p>, - ) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; @@ -175,7 +182,7 @@ impl OCSPResponse { "Signature algorithm OID: {} not recognized", self.requires_successful_response()?.signature_algorithm.oid ); - Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_instance( py.import("cryptography.exceptions")? .call_method1("UnsupportedAlgorithm", (exc_messsage,))?, ))) @@ -193,14 +200,14 @@ impl OCSPResponse { fn tbs_response_bytes<'p>( &self, py: pyo3::Python<'p>, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let resp = self.requires_successful_response()?; let result = asn1::write_single(&resp.tbs_response_data)?; Ok(pyo3::types::PyBytes::new(py, &result)) } #[getter] - fn certificates<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn certificates<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, CryptographyError> { let resp = self.requires_successful_response()?; let py_certs = pyo3::types::PyList::empty(py); let certs = match &resp.certs { @@ -242,21 +249,24 @@ impl OCSPResponse { } #[getter] - fn issuer_key_hash(&self) -> Result<&[u8], PyAsn1Error> { + fn issuer_key_hash(&self) -> Result<&[u8], CryptographyError> { let resp = self.requires_successful_response()?; let single_resp = resp.single_response()?; Ok(single_resp.cert_id.issuer_key_hash) } #[getter] - fn issuer_name_hash(&self) -> Result<&[u8], PyAsn1Error> { + fn issuer_name_hash(&self) -> Result<&[u8], CryptographyError> { let resp = self.requires_successful_response()?; let single_resp = resp.single_response()?; Ok(single_resp.cert_id.issuer_name_hash) } #[getter] - fn hash_algorithm<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn hash_algorithm<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let resp = self.requires_successful_response()?; let single_resp = resp.single_response()?; single_resp.py_hash_algorithm(py) @@ -276,7 +286,7 @@ impl OCSPResponse { } #[getter] - fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> PyAsn1Result<&'p pyo3::PyAny> { + fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; let single_resp = resp.single_response()?; single_resp.py_revocation_reason(py) @@ -367,7 +377,7 @@ impl OCSPResponse { &self, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, - ) -> PyAsn1Result<&'p pyo3::types::PyBytes> { + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))? @@ -443,12 +453,12 @@ struct BasicOCSPResponse<'a> { } impl BasicOCSPResponse<'_> { - fn single_response(&self) -> Result, PyAsn1Error> { + fn single_response(&self) -> Result, CryptographyError> { let responses = self.tbs_response_data.responses.unwrap_read(); let num_responses = responses.len(); if num_responses != 1 { - return Err(PyAsn1Error::from( + return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err(format!( "OCSP response contains {} SINGLERESP structures. Use .response_iter to iterate through them", num_responses @@ -511,13 +521,16 @@ impl SingleResponse<'_> { .getattr(attr) } - fn py_hash_algorithm<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn py_hash_algorithm<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { let hashes = py.import("cryptography.hazmat.primitives.hashes")?; match ocsp::OIDS_TO_HASH.get(&self.cert_id.hash_algorithm.oid) { Some(alg_name) => Ok(hashes.getattr(alg_name)?.call0()?), None => { let exceptions = py.import("cryptography.exceptions")?; - Err(PyAsn1Error::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_instance( exceptions .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( @@ -540,7 +553,10 @@ impl SingleResponse<'_> { } } - fn py_revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> PyAsn1Result<&'p pyo3::PyAny> { + fn py_revocation_reason<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::PyAny> { match &self.cert_status { CertStatus::Revoked(revoked_info) => match revoked_info.revocation_reason { Some(ref v) => crl::parse_crl_reason_flags(py, v), @@ -584,7 +600,7 @@ fn create_ocsp_response( builder: &pyo3::PyAny, private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, -) -> PyAsn1Result { +) -> CryptographyResult { let response_status = status .getattr(crate::intern!(py, "value"))? .extract::()?; @@ -842,7 +858,10 @@ impl OCSPSingleResponse { } #[getter] - fn hash_algorithm<'p>(&self, py: pyo3::Python<'p>) -> Result<&'p pyo3::PyAny, PyAsn1Error> { + fn hash_algorithm<'p>( + &self, + py: pyo3::Python<'p>, + ) -> Result<&'p pyo3::PyAny, CryptographyError> { self.single_response().py_hash_algorithm(py) } @@ -857,7 +876,7 @@ impl OCSPSingleResponse { } #[getter] - fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> PyAsn1Result<&'p pyo3::PyAny> { + fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { self.single_response().py_revocation_reason(py) } diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index aaa374b93223..363a8187d060 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::PyAsn1Error; +use crate::asn1::CryptographyError; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::hash_map::DefaultHasher; @@ -22,22 +22,22 @@ impl<'a> TLSReader<'a> { self.data.is_empty() } - fn read_byte(&mut self) -> Result { + fn read_byte(&mut self) -> Result { Ok(self.read_exact(1)?[0]) } - fn read_exact(&mut self, length: usize) -> Result<&'a [u8], PyAsn1Error> { + fn read_exact(&mut self, length: usize) -> Result<&'a [u8], CryptographyError> { if length > self.data.len() { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Invalid SCT length", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Invalid SCT length"), + )); } let (result, data) = self.data.split_at(length); self.data = data; Ok(result) } - fn read_length_prefixed(&mut self) -> Result, PyAsn1Error> { + fn read_length_prefixed(&mut self) -> Result, CryptographyError> { let length = u16::from_be_bytes(self.read_exact(2)?.try_into().unwrap()); Ok(TLSReader::new(self.read_exact(length.into())?)) } @@ -236,7 +236,7 @@ pub(crate) fn parse_scts( py: pyo3::Python<'_>, data: &[u8], entry_type: LogEntryType, -) -> Result { +) -> Result { let mut reader = TLSReader::new(data).read_length_prefixed()?; let py_scts = pyo3::types::PyList::empty(py); @@ -245,9 +245,9 @@ pub(crate) fn parse_scts( let raw_sct_data = sct_data.data.to_vec(); let version = sct_data.read_byte()?; if version != 0 { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Invalid SCT version", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Invalid SCT version"), + )); } let log_id = sct_data.read_exact(32)?.try_into().unwrap(); let timestamp = u64::from_be_bytes(sct_data.read_exact(8)?.try_into().unwrap()); diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 3a1e0e9a3def..4c1e9664fb38 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{PyAsn1Error, PyAsn1Result}; +use crate::asn1::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::oid; @@ -287,13 +287,15 @@ pub(crate) fn verify_signature_with_oid<'p>( signature_oid: &asn1::ObjectIdentifier, signature: &[u8], data: &[u8], -) -> PyAsn1Result<()> { +) -> CryptographyResult<()> { let key_type = identify_public_key_type(py, issuer_public_key)?; let (sig_key_type, sig_hash_type) = identify_key_hash_type_for_oid(signature_oid)?; if key_type != sig_key_type { - return Err(PyAsn1Error::from(pyo3::exceptions::PyValueError::new_err( - "Signature algorithm does not match issuer key type", - ))); + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Signature algorithm does not match issuer key type", + ), + )); } let sig_hash_name = py_hash_name_from_hash_type(sig_hash_type); let hashes = py.import("cryptography.hazmat.primitives.hashes")?; From 9938f981e0cf20c28554f3955788b67cea00ce11 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 16 Mar 2023 07:47:35 +0800 Subject: [PATCH 461/827] modify the python path in build_openssl.py instead of build.rs (#8528) * modify the python path in build_openssl.py instead of build.rs * Remove unused import --- src/_cffi_src/build_openssl.py | 7 ++++++- src/rust/build.rs | 16 +--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index ab23e04b28c8..5f191ce2ed40 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -4,13 +4,18 @@ import os +import pathlib import platform import sys from distutils import dist from distutils.ccompiler import get_default_compiler from distutils.command.config import config -from _cffi_src.utils import build_ffi_for_binding, compiler_type +# Add the src directory to the path so we can import _cffi_src.utils +src_dir = str(pathlib.Path(__file__).parent.parent) +sys.path.insert(0, src_dir) + +from _cffi_src.utils import build_ffi_for_binding, compiler_type # noqa: E402 def _get_openssl_libraries(platform): diff --git a/src/rust/build.rs b/src/rust/build.rs index d136a8a74534..8dbda20a6ea4 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -1,6 +1,6 @@ use std::env; use std::io::Write; -use std::path::{Path, MAIN_SEPARATOR}; +use std::path::Path; use std::process::{Command, Stdio}; fn main() { @@ -23,21 +23,7 @@ fn main() { // FIXME: maybe pyo3-build-config should provide a way to do this? let python = env::var("PYO3_PYTHON").unwrap_or_else(|_| "python3".to_string()); println!("cargo:rerun-if-changed=../_cffi_src/"); - let python_path = match env::var("PYTHONPATH") { - Ok(mut val) => { - if cfg!(target_os = "windows") { - val.push(';'); - } else { - val.push(':'); - } - val.push_str(".."); - val.push(MAIN_SEPARATOR); - val - } - Err(_) => format!("..{}", MAIN_SEPARATOR), - }; let output = Command::new(&python) - .env("PYTHONPATH", python_path) .env("OUT_DIR", &out_dir) .arg("../_cffi_src/build_openssl.py") .output() From d6866c82b48283ee773054ba95b76b5f315ee556 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 00:34:52 +0000 Subject: [PATCH 462/827] Bump BoringSSL and/or OpenSSL in CI (#8529) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 492e543bbcc2..30b2e05a9e5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 15, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "50bc2ea0e8f60fec17dad62ef6e54a8aed284511"}} - # Latest commit on the OpenSSL master branch, as of Mar 15, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "4a3b6266604ca447e0b3a14f1dbc8052e1498819"}} + # Latest commit on the BoringSSL master branch, as of Mar 16, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "74646566e93de7551bfdfc5f49de7462f13d1d05"}} + # Latest commit on the OpenSSL master branch, as of Mar 16, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "738d43634a5192b1be0869f151682bb8e9157d5a"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 8882c3c88d082f29b66fd2e72cb92273da96c427 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 16 Mar 2023 01:05:33 -0400 Subject: [PATCH 463/827] Support handling OpenSSL errors from Rust code (#8530) --- .../hazmat/backends/openssl/backend.py | 4 +- .../{openssl.pyi => openssl/__init__.pyi} | 3 + .../hazmat/bindings/openssl/binding.py | 41 +++-- src/rust/src/asn1.rs | 104 +---------- src/rust/src/error.rs | 167 ++++++++++++++++++ src/rust/src/lib.rs | 7 + src/rust/src/oid.rs | 2 +- src/rust/src/pkcs7.rs | 3 +- src/rust/src/x509/certificate.rs | 2 +- src/rust/src/x509/common.rs | 3 +- src/rust/src/x509/crl.rs | 2 +- src/rust/src/x509/csr.rs | 5 +- src/rust/src/x509/extensions.rs | 5 +- src/rust/src/x509/ocsp.rs | 2 +- src/rust/src/x509/ocsp_req.rs | 5 +- src/rust/src/x509/ocsp_resp.rs | 3 +- src/rust/src/x509/sct.rs | 2 +- src/rust/src/x509/sign.rs | 2 +- tests/hazmat/bindings/test_openssl.py | 26 ++- 19 files changed, 246 insertions(+), 142 deletions(-) rename src/cryptography/hazmat/bindings/_rust/{openssl.pyi => openssl/__init__.pyi} (76%) create mode 100644 src/rust/src/error.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index a8964f365148..0610b254eab6 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -485,12 +485,12 @@ def derive_pbkdf2_hmac( return self._ffi.buffer(buf)[:] def _consume_errors(self) -> typing.List[binding._OpenSSLError]: - return binding._consume_errors(self._lib) + return binding._consume_errors() def _consume_errors_with_text( self, ) -> typing.List[binding._OpenSSLErrorWithText]: - return binding._consume_errors_with_text(self._lib) + return binding._consume_errors_with_text() def _bn_to_int(self, bn) -> int: assert bn != self._ffi.NULL diff --git a/src/cryptography/hazmat/bindings/_rust/openssl.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi similarity index 76% rename from src/cryptography/hazmat/bindings/_rust/openssl.pyi rename to src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 8cd7b30627e2..0e292a2fe224 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -2,4 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import typing + def openssl_version() -> int: ... +def raise_openssl_error() -> typing.NoReturn: ... diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 680164f41841..b0fc8de28a14 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -22,6 +22,16 @@ class _OpenSSLErrorWithText(typing.NamedTuple): reason: int reason_text: bytes + @classmethod + def from_err(cls, err: "_OpenSSLError") -> "_OpenSSLErrorWithText": + buf = _openssl.ffi.new("char[]", 256) + _openssl.lib.ERR_error_string_n(err.code, buf, len(buf)) + err_text_reason: bytes = _openssl.ffi.string(buf) + + return _OpenSSLErrorWithText( + err.code, err.lib, err.reason, err_text_reason + ) + class _OpenSSLError: def __init__(self, code: int, lib: int, reason: int): @@ -29,6 +39,12 @@ def __init__(self, code: int, lib: int, reason: int): self._lib = lib self._reason = reason + @classmethod + def from_code(cls, code: int) -> "_OpenSSLError": + err_lib: int = _openssl.lib.ERR_GET_LIB(code) + err_reason: int = _openssl.lib.ERR_GET_REASON(code) + return cls(code, err_lib, err_reason) + def _lib_reason_match(self, lib: int, reason: int) -> bool: return lib == self.lib and reason == self.reason @@ -45,17 +61,14 @@ def reason(self) -> int: return self._reason -def _consume_errors(lib) -> typing.List[_OpenSSLError]: +def _consume_errors() -> typing.List[_OpenSSLError]: errors = [] while True: - code: int = lib.ERR_get_error() + code: int = _openssl.lib.ERR_get_error() if code == 0: break - err_lib: int = lib.ERR_GET_LIB(code) - err_reason: int = lib.ERR_GET_REASON(code) - - errors.append(_OpenSSLError(code, err_lib, err_reason)) + errors.append(_OpenSSLError.from_code(code)) return errors @@ -65,21 +78,13 @@ def _errors_with_text( ) -> typing.List[_OpenSSLErrorWithText]: errors_with_text = [] for err in errors: - buf = _openssl.ffi.new("char[]", 256) - _openssl.lib.ERR_error_string_n(err.code, buf, len(buf)) - err_text_reason: bytes = _openssl.ffi.string(buf) - - errors_with_text.append( - _OpenSSLErrorWithText( - err.code, err.lib, err.reason, err_text_reason - ) - ) + errors_with_text.append(_OpenSSLErrorWithText.from_err(err)) return errors_with_text -def _consume_errors_with_text(lib): - return _errors_with_text(_consume_errors(lib)) +def _consume_errors_with_text(): + return _errors_with_text(_consume_errors()) def _openssl_assert( @@ -87,7 +92,7 @@ def _openssl_assert( ) -> None: if not ok: if errors is None: - errors = _consume_errors(lib) + errors = _consume_errors() errors_with_text = _errors_with_text(errors) raise InternalError( diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 72dc7101d1ce..0bc57341e592 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -2,81 +2,12 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509::Name; use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; -pub enum CryptographyError { - Asn1Parse(asn1::ParseError), - Asn1Write(asn1::WriteError), - Py(pyo3::PyErr), -} - -impl From for CryptographyError { - fn from(e: asn1::ParseError) -> CryptographyError { - CryptographyError::Asn1Parse(e) - } -} - -impl From for CryptographyError { - fn from(e: asn1::WriteError) -> CryptographyError { - CryptographyError::Asn1Write(e) - } -} - -impl From for CryptographyError { - fn from(e: pyo3::PyErr) -> CryptographyError { - CryptographyError::Py(e) - } -} - -impl From> for CryptographyError { - fn from(e: pyo3::PyDowncastError<'_>) -> CryptographyError { - CryptographyError::Py(e.into()) - } -} - -impl From for CryptographyError { - fn from(e: pem::PemError) -> CryptographyError { - CryptographyError::Py(pyo3::exceptions::PyValueError::new_err(format!( - "Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. {:?}", - e - ))) - } -} - -impl From for pyo3::PyErr { - fn from(e: CryptographyError) -> pyo3::PyErr { - match e { - CryptographyError::Asn1Parse(asn1_error) => pyo3::exceptions::PyValueError::new_err( - format!("error parsing asn1 value: {:?}", asn1_error), - ), - CryptographyError::Asn1Write(asn1::WriteError::AllocationError) => { - pyo3::exceptions::PyMemoryError::new_err( - "failed to allocate memory while performing ASN.1 serialization", - ) - } - CryptographyError::Py(py_error) => py_error, - } - } -} - -impl CryptographyError { - pub(crate) fn add_location(self, loc: asn1::ParseLocation) -> Self { - match self { - CryptographyError::Py(e) => CryptographyError::Py(e), - CryptographyError::Asn1Parse(e) => CryptographyError::Asn1Parse(e.add_location(loc)), - CryptographyError::Asn1Write(e) => CryptographyError::Asn1Write(e), - } - } -} - -// The primary purpose of this alias is for brevity to keep function signatures -// to a single-line as a work around for coverage issues. See -// https://github.com/pyca/cryptography/pull/6173 -pub(crate) type CryptographyResult = Result; - pub(crate) fn py_oid_to_oid(py_oid: &pyo3::PyAny) -> pyo3::PyResult { Ok(py_oid .downcast::>()? @@ -297,36 +228,3 @@ pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::pr Ok(submod) } - -#[cfg(test)] -mod tests { - use super::CryptographyError; - - #[test] - fn test_cryptographyerror_from() { - pyo3::prepare_freethreaded_python(); - pyo3::Python::with_gil(|py| { - let e: CryptographyError = asn1::WriteError::AllocationError.into(); - assert!(matches!( - e, - CryptographyError::Asn1Write(asn1::WriteError::AllocationError) - )); - let py_e: pyo3::PyErr = e.into(); - assert!(py_e.is_instance::(py)); - - let e: CryptographyError = - pyo3::PyDowncastError::new(py.None().as_ref(py), "abc").into(); - assert!(matches!(e, CryptographyError::Py(_))); - }) - } - - #[test] - fn test_cryptographyerror_add_location() { - let py_err = pyo3::PyErr::new::("Error!"); - CryptographyError::Py(py_err).add_location(asn1::ParseLocation::Field("meh")); - - let asn1_write_err = asn1::WriteError::AllocationError; - CryptographyError::Asn1Write(asn1_write_err) - .add_location(asn1::ParseLocation::Field("meh")); - } -} diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs new file mode 100644 index 000000000000..ac3da6bd05e1 --- /dev/null +++ b/src/rust/src/error.rs @@ -0,0 +1,167 @@ +// 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. + +pub enum CryptographyError { + Asn1Parse(asn1::ParseError), + Asn1Write(asn1::WriteError), + Py(pyo3::PyErr), + OpenSSL(openssl::error::ErrorStack), +} + +impl From for CryptographyError { + fn from(e: asn1::ParseError) -> CryptographyError { + CryptographyError::Asn1Parse(e) + } +} + +impl From for CryptographyError { + fn from(e: asn1::WriteError) -> CryptographyError { + CryptographyError::Asn1Write(e) + } +} + +impl From for CryptographyError { + fn from(e: pyo3::PyErr) -> CryptographyError { + CryptographyError::Py(e) + } +} + +impl From> for CryptographyError { + fn from(e: pyo3::PyDowncastError<'_>) -> CryptographyError { + CryptographyError::Py(e.into()) + } +} + +impl From for CryptographyError { + fn from(e: openssl::error::ErrorStack) -> CryptographyError { + CryptographyError::OpenSSL(e) + } +} + +impl From for CryptographyError { + fn from(e: pem::PemError) -> CryptographyError { + CryptographyError::Py(pyo3::exceptions::PyValueError::new_err(format!( + "Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. {:?}", + e + ))) + } +} + +impl From for pyo3::PyErr { + fn from(e: CryptographyError) -> pyo3::PyErr { + match e { + CryptographyError::Asn1Parse(asn1_error) => pyo3::exceptions::PyValueError::new_err( + format!("error parsing asn1 value: {:?}", asn1_error), + ), + CryptographyError::Asn1Write(asn1::WriteError::AllocationError) => { + pyo3::exceptions::PyMemoryError::new_err( + "failed to allocate memory while performing ASN.1 serialization", + ) + } + CryptographyError::Py(py_error) => py_error, + CryptographyError::OpenSSL(error_stack) => { + let gil = pyo3::Python::acquire_gil(); + let py = gil.python(); + + let internal_error = py + .import("cryptography.exceptions") + .expect("Failed to import cryptography module") + .getattr(crate::intern!(py, "InternalError")) + .expect("Failed to get InternalError attribute"); + + let binding_mod = py + .import("cryptography.hazmat.bindings.openssl.binding") + .expect("Failed to import cryptography module"); + + let openssl_error = binding_mod + .getattr(crate::intern!(py, "_OpenSSLError")) + .expect("Failed to get _OpenSSL attribute"); + let openssl_error_with_text = binding_mod + .getattr(crate::intern!(py, "_OpenSSLErrorWithText")) + .expect("Failed to get _OpenSSLErrorWithText attribute"); + + let errors = pyo3::types::PyList::empty(py); + for e in error_stack.errors() { + let err = openssl_error + .call_method1("from_code", (e.code(),)) + .expect("Failed to call from_code"); + + errors + .append( + openssl_error_with_text + .call_method1("from_err", (err,)) + .expect("Failed to call from_err"), + ) + .expect("List append failed"); + } + pyo3::PyErr::from_instance( + internal_error + .call1(( + "Unknown OpenSSL error. This error is commonly encountered + when another library is not cleaning up the OpenSSL error + stack. If you are using cryptography with another library + that uses OpenSSL try disabling it before reporting a bug. + Otherwise please file an issue at + https://github.com/pyca/cryptography/issues with + information on how to reproduce this.", + errors, + )) + .expect("Failed to create InternalError"), + ) + } + } + } +} + +impl CryptographyError { + pub(crate) fn add_location(self, loc: asn1::ParseLocation) -> Self { + match self { + CryptographyError::Py(e) => CryptographyError::Py(e), + CryptographyError::Asn1Parse(e) => CryptographyError::Asn1Parse(e.add_location(loc)), + CryptographyError::Asn1Write(e) => CryptographyError::Asn1Write(e), + CryptographyError::OpenSSL(e) => CryptographyError::OpenSSL(e), + } + } +} + +// The primary purpose of this alias is for brevity to keep function signatures +// to a single-line as a work around for coverage issues. See +// https://github.com/pyca/cryptography/pull/6173 +pub(crate) type CryptographyResult = Result; + +#[cfg(test)] +mod tests { + use super::CryptographyError; + + #[test] + fn test_cryptographyerror_from() { + pyo3::prepare_freethreaded_python(); + pyo3::Python::with_gil(|py| { + let e: CryptographyError = asn1::WriteError::AllocationError.into(); + assert!(matches!( + e, + CryptographyError::Asn1Write(asn1::WriteError::AllocationError) + )); + let py_e: pyo3::PyErr = e.into(); + assert!(py_e.is_instance::(py)); + + let e: CryptographyError = + pyo3::PyDowncastError::new(py.None().as_ref(py), "abc").into(); + assert!(matches!(e, CryptographyError::Py(_))); + }) + } + + #[test] + fn test_cryptographyerror_add_location() { + let py_err = pyo3::PyErr::new::("Error!"); + CryptographyError::Py(py_err).add_location(asn1::ParseLocation::Field("meh")); + + let asn1_write_err = asn1::WriteError::AllocationError; + CryptographyError::Asn1Write(asn1_write_err) + .add_location(asn1::ParseLocation::Field("meh")); + + let openssl_error = openssl::error::ErrorStack::get(); + CryptographyError::from(openssl_error).add_location(asn1::ParseLocation::Field("meh")); + } +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index c3cb25154cff..d5de059320ac 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -10,6 +10,7 @@ #![allow(unknown_lints, clippy::borrow_deref_ref)] mod asn1; +mod error; mod intern; pub(crate) mod oid; mod pkcs7; @@ -95,6 +96,11 @@ fn openssl_version() -> i64 { openssl::version::number() } +#[pyo3::prelude::pyfunction] +fn raise_openssl_error() -> crate::error::CryptographyResult<()> { + Err(openssl::error::ErrorStack::get().into()) +} + #[pyo3::prelude::pymodule] fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { m.add_function(pyo3::wrap_pyfunction!(check_pkcs7_padding, m)?)?; @@ -133,6 +139,7 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?; openssl_mod.add_function(pyo3::wrap_pyfunction!(openssl_version, m)?)?; + openssl_mod.add_function(pyo3::wrap_pyfunction!(raise_openssl_error, m)?)?; m.add_submodule(openssl_mod)?; Ok(()) diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index c172310c0669..a13668579a74 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::CryptographyResult; +use crate::error::CryptographyResult; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 557c09be10b4..93d9a11e4cad 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -2,7 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{encode_der_data, CryptographyResult}; +use crate::asn1::encode_der_data; +use crate::error::CryptographyResult; use crate::x509; use chrono::Timelike; diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 39d0ebfb5ccc..1a9820e5ea06 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -4,8 +4,8 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, - CryptographyError, CryptographyResult, }; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; use chrono::Datelike; diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index e93ec7ec0775..a765d614457c 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -2,7 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{oid_to_py_oid, py_oid_to_oid, CryptographyError, CryptographyResult}; +use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use chrono::{Datelike, TimeZone, Timelike}; use pyo3::types::IntoPyDict; diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 75ac22541721..c1b5c8c48d86 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -4,8 +4,8 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, - CryptographyError, CryptographyResult, }; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, extensions, oid, sign}; use pyo3::ToPyObject; diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 66ce3413bf49..e16a58164c17 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -2,9 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{ - encode_der_data, oid_to_py_oid, py_oid_to_oid, CryptographyError, CryptographyResult, -}; +use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, oid, sign}; use asn1::SimpleAsn1Readable; diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index f8dd28a45215..d93e87c0f1a3 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -2,9 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{ - py_oid_to_oid, py_uint_to_big_endian_bytes, CryptographyError, CryptographyResult, -}; +use crate::asn1::{py_oid_to_oid, py_uint_to_big_endian_bytes}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, oid, sct}; diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index d06487021023..a06e7f1cc278 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::CryptographyResult; +use crate::error::CryptographyResult; use crate::x509; use crate::x509::oid; use once_cell::sync::Lazy; diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 078df60503c6..638caf9b2494 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -2,9 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{ - big_byte_slice_to_py_int, py_uint_to_big_endian_bytes, CryptographyError, CryptographyResult, -}; +use crate::asn1::{big_byte_slice_to_py_int, py_uint_to_big_endian_bytes}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{extensions, ocsp, oid}; use std::sync::Arc; diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 35e1d672b081..2f878b2c4c3e 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -2,7 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, CryptographyError, CryptographyResult}; +use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_chrono, sct}; use chrono::Timelike; diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index 363a8187d060..e3f7be4d9036 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::CryptographyError; +use crate::error::CryptographyError; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::hash_map::DefaultHasher; diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 4c1e9664fb38..33d293b21527 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{CryptographyError, CryptographyResult}; +use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::oid; diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 0721fc09a966..c80753bd04e5 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -5,6 +5,7 @@ import pytest from cryptography.exceptions import InternalError +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl.binding import ( Binding, _consume_errors, @@ -95,7 +96,7 @@ def test_check_startup_errors_are_allowed(self): -1, ) b._register_osrandom_engine() - assert _consume_errors(b.lib) == [] + assert _consume_errors() == [] def test_version_mismatch(self): with pytest.raises(ImportError): @@ -106,3 +107,26 @@ def test_legacy_provider_error(self): _legacy_provider_error(False) _legacy_provider_error(True) + + def test_rust_internal_error(self): + with pytest.raises(InternalError) as exc_info: + rust_openssl.raise_openssl_error() + + assert len(exc_info.value.err_code) == 0 + + b = Binding() + b.lib.ERR_put_error( + b.lib.ERR_LIB_EVP, + b.lib.EVP_F_EVP_ENCRYPTFINAL_EX, + b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, + b"", + -1, + ) + with pytest.raises(InternalError) as exc_info: + rust_openssl.raise_openssl_error() + + error = exc_info.value.err_code[0] + assert error.lib == b.lib.ERR_LIB_EVP + assert error.reason == b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: + assert b"data not multiple of block length" in error.reason_text From 22c29e1a1cf65875a0b71753be27237a041e54db Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 16 Mar 2023 07:31:19 -0400 Subject: [PATCH 464/827] Enable cargo sparse registry on ubuntu (#8532) --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30b2e05a9e5b..b85a0c3212cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "738d43634a5192b1be0869f151682bb8e9157d5a"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.3.0 timeout-minutes: 3 @@ -524,6 +526,8 @@ jobs: - '3.11' name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.3.0 timeout-minutes: 3 @@ -567,6 +571,8 @@ jobs: runs-on: ubuntu-latest name: "linkcheck" timeout-minutes: 10 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.3.0 with: From 44f1b331e79f968087ceacf117ba66e276463a86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:15:59 +0000 Subject: [PATCH 465/827] Bump actions/checkout from 3.3.0 to 3.4.0 (#8533) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.3.0...v3.4.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 4 ++-- .github/workflows/boring-open-version-bump.yml | 2 +- .github/workflows/ci.yml | 18 +++++++++--------- .github/workflows/wheel-builder.yml | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 75adcd394e21..7f332cc11800 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,12 +17,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false path: "cryptography-pr" - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: repository: "pyca/cryptography" diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index d9c38a25f5c4..353015d9be32 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 - id: check-sha-boring run: | SHA=$(git ls-remote https://boringssl.googlesource.com/boringssl refs/heads/master | cut -f1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b85a0c3212cd..26ecf43129aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -160,7 +160,7 @@ jobs: sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release if: matrix.IMAGE.IMAGE == 'alpine:aarch64' - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -223,7 +223,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -273,7 +273,7 @@ jobs: env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -386,7 +386,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -453,7 +453,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -529,7 +529,7 @@ jobs: env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false @@ -574,7 +574,7 @@ jobs: env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 with: persist-credentials: false fetch-depth: 0 @@ -610,7 +610,7 @@ jobs: needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 timeout-minutes: 3 with: persist-credentials: false diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index ea18da168cd9..b81de2063f27 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest name: sdists steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} From 709514c99f5171042ab136aee52c33dda243f586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:20:36 +0000 Subject: [PATCH 466/827] Bump hypothesis from 6.68.3 to 6.70.0 (#8534) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.68.3 to 6.70.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.68.3...hypothesis-python-6.70.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 99898eb93fd9..3881794aef1e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -52,7 +52,7 @@ filelock==3.9.1; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.68.3; python_version >= "3.7" +hypothesis==6.70.0; python_version >= "3.7" # via cryptography (setup.cfg) idna==3.4 # via requests From b7eec88d335dbaa036eed58094e138dac8695e13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:46:55 +0000 Subject: [PATCH 467/827] Bump actions/checkout from 3.3.0 to 3.4.0 in /.github/actions/wycheproof (#8536) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.3.0...v3.4.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/wycheproof/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/wycheproof/action.yml b/.github/actions/wycheproof/action.yml index 9ba060abddc0..5a1042c10c4e 100644 --- a/.github/actions/wycheproof/action.yml +++ b/.github/actions/wycheproof/action.yml @@ -5,7 +5,7 @@ runs: using: "composite" steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.4.0 with: repository: "google/wycheproof" path: "wycheproof" From c640735d7a173f9e0c5723c4d0b4fa99c91e2dff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:53:12 +0000 Subject: [PATCH 468/827] Bump filelock from 3.9.1 to 3.10.0 (#8535) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.9.1 to 3.10.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.9.1...3.10.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3881794aef1e..ffc03a020e81 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -48,7 +48,7 @@ exceptiongroup==1.1.1 # pytest execnet==1.9.0 # via pytest-xdist -filelock==3.9.1; python_version >= "3.7" +filelock==3.10.0; python_version >= "3.7" # via # tox # virtualenv From 9216a82de8acdbb43de15f2d766890dc85320ea9 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 00:20:38 +0000 Subject: [PATCH 469/827] Bump BoringSSL and/or OpenSSL in CI (#8537) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26ecf43129aa..e54fe5144d84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 16, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "74646566e93de7551bfdfc5f49de7462f13d1d05"}} - # Latest commit on the OpenSSL master branch, as of Mar 16, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "738d43634a5192b1be0869f151682bb8e9157d5a"}} + # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "898de8d09e10960e64901e2d9836cdea5dd1d1a6"}} + # Latest commit on the OpenSSL master branch, as of Mar 17, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c879f8ac56170a5cf929fab8067beb2a5902be2b"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 011b2d80f24787ffd23026afe173364a677e6668 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Mar 2023 08:08:33 -0400 Subject: [PATCH 470/827] enable cargo sparse registries on windows (#8538) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e54fe5144d84..0e190f8bba0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -452,6 +452,8 @@ jobs: JOB_NUMBER: [0, 1] name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 timeout-minutes: 3 From ed92532ae7657c0226726079436d1d9e612e50a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 12:04:28 -0400 Subject: [PATCH 471/827] Bump coverage from 7.2.1 to 7.2.2 (#8539) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.1 to 7.2.2. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.1...7.2.2) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ffc03a020e81..51da9653c267 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -33,7 +33,7 @@ click==8.1.3 # via black colorama==0.4.6; python_version >= "3.7" # via tox -coverage==7.2.1; python_version >= "3.7" +coverage==7.2.2; python_version >= "3.7" # via pytest-cov distlib==0.3.6 # via virtualenv From 80acb6a54f3341fa0c2705ddc6bb556efee310d6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Mar 2023 17:34:15 -0400 Subject: [PATCH 472/827] skip memleak tests on pypy (#8540) See: https://github.com/pyca/cryptography/pull/7933#issuecomment-1471865194 + https://foss.heptapod.net/pypy/pypy/-/issues/3905#note_290457 to understand why --- tests/hazmat/backends/test_openssl_memleak.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index 02b89232c0d4..b03cc0f2c807 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -5,6 +5,7 @@ import json import os +import platform import subprocess import sys import textwrap @@ -204,8 +205,9 @@ def assert_no_memory_leaks(s, argv=[]): def skip_if_memtesting_not_supported(): return pytest.mark.skipif( - not Binding().lib.Cryptography_HAS_MEM_FUNCTIONS, - reason="Requires OpenSSL memory functions (>=1.1.0)", + not Binding().lib.Cryptography_HAS_MEM_FUNCTIONS + and platform.python_implementation() != "PyPy", + reason="Requires OpenSSL memory functions (>=1.1.0) and not PyPy", ) From f40265df236b3aeb55fc5c3d1c53a440005d94a2 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 18 Mar 2023 01:11:07 +0000 Subject: [PATCH 473/827] Bump BoringSSL and/or OpenSSL in CI (#8541) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e190f8bba0e..2eea949c1318 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "898de8d09e10960e64901e2d9836cdea5dd1d1a6"}} - # Latest commit on the OpenSSL master branch, as of Mar 17, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "c879f8ac56170a5cf929fab8067beb2a5902be2b"}} + # Latest commit on the OpenSSL master branch, as of Mar 18, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e5dd732749f524e2a0aaa67f8d514d34863dd89f"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 8b45a09f14964f5e06dfffda19bb5fbbb0e3946d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 17 Mar 2023 22:09:00 -0400 Subject: [PATCH 474/827] fix logic for this skip (#8542) --- tests/hazmat/backends/test_openssl_memleak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index b03cc0f2c807..755f1827d278 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -206,7 +206,7 @@ def assert_no_memory_leaks(s, argv=[]): def skip_if_memtesting_not_supported(): return pytest.mark.skipif( not Binding().lib.Cryptography_HAS_MEM_FUNCTIONS - and platform.python_implementation() != "PyPy", + or platform.python_implementation() == "PyPy", reason="Requires OpenSSL memory functions (>=1.1.0) and not PyPy", ) From 0e42aa86697ca01b7fdfa69ebd30821065ab6013 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 18 Mar 2023 18:33:27 +0000 Subject: [PATCH 475/827] Bump ruff from 0.0.256 to 0.0.257 (#8543) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.256 to 0.0.257. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.256...v0.0.257) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 51da9653c267..31920ac7534f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -161,7 +161,7 @@ rfc3986==2.0.0 # via twine rich==13.3.2 # via twine -ruff==0.0.256 +ruff==0.0.257 # via cryptography (setup.cfg) six==1.16.0 # via bleach From b7c57f6c741d705fc8b8c12c26680291c12cf351 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 18 Mar 2023 18:37:37 +0000 Subject: [PATCH 476/827] Bump importlib-metadata from 6.0.0 to 6.1.0 (#8544) Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v6.0.0...v6.1.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 31920ac7534f..60ae0230c51b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -58,7 +58,7 @@ idna==3.4 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==6.0.0; python_version >= "3.7" +importlib-metadata==6.1.0; python_version >= "3.7" # via # keyring # twine From 0dc2b568aa2781b2e641aa5fa2d163aab74783aa Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 19 Mar 2023 00:19:59 +0000 Subject: [PATCH 477/827] Bump BoringSSL and/or OpenSSL in CI (#8548) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eea949c1318..2571733e351b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "898de8d09e10960e64901e2d9836cdea5dd1d1a6"}} - # Latest commit on the OpenSSL master branch, as of Mar 18, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "e5dd732749f524e2a0aaa67f8d514d34863dd89f"}} + # Latest commit on the OpenSSL master branch, as of Mar 19, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6821acbffda908ec69769ed7f110cfde57d8ca58"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 75f13bf9ceaade90f081462d43598a7f4f98fb1a Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 19 Mar 2023 20:40:42 -0400 Subject: [PATCH 478/827] Bump BoringSSL and/or OpenSSL in CI (#8549) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2571733e351b..57bb7a3705ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "898de8d09e10960e64901e2d9836cdea5dd1d1a6"}} - # Latest commit on the OpenSSL master branch, as of Mar 19, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6821acbffda908ec69769ed7f110cfde57d8ca58"}} + # Latest commit on the OpenSSL master branch, as of Mar 20, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d293ebde01fc14dabbd64fd6e42dc837be7b1fad"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 7a5170629f0ba7ce4a8b46b005cd9a5c35e06d3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 00:52:04 +0000 Subject: [PATCH 479/827] Bump openssl from 0.10.46 to 0.10.47 in /src/rust (#8550) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.46 to 0.10.47. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.46...openssl-v0.10.47) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b16487d9ac7d..c37fa68d83af 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -308,9 +308,9 @@ checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "openssl" -version = "0.10.46" +version = "0.10.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2523381e46256e40930512c7fd25562b9eae4812cb52078f155e87217c9d1e" +checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" dependencies = [ "bitflags", "cfg-if", @@ -334,9 +334,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.81" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176be2629957c157240f68f61f2d0053ad3a4ecfdd9ebf1e6521d18d9635cf67" +checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ "autocfg", "cc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 96616baae63e..0887bd793b82 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,7 +14,7 @@ asn1 = { version = "0.13.0", default-features = false } pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" -openssl = "0.10.46" +openssl = "0.10.47" openssl-sys = "0.9.72" [build-dependencies] From 45a5100e4ee2c154981aa0d6fbcf8d2f751f50f8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Mar 2023 21:41:48 -0400 Subject: [PATCH 480/827] Simplify/unify Rust and Python OpenSSL error handling (#8552) --- src/cryptography/exceptions.py | 6 +- .../hazmat/backends/openssl/backend.py | 21 ++--- .../hazmat/backends/openssl/dh.py | 4 +- .../hazmat/backends/openssl/rsa.py | 6 +- .../hazmat/backends/openssl/utils.py | 4 +- .../bindings/_rust/openssl/__init__.pyi | 10 +++ .../hazmat/bindings/openssl/binding.py | 82 ++----------------- src/rust/build.rs | 3 +- src/rust/src/error.rs | 24 ++---- src/rust/src/lib.rs | 51 ++++++++++++ tests/conftest.py | 4 +- tests/hazmat/bindings/test_openssl.py | 3 +- 12 files changed, 94 insertions(+), 124 deletions(-) diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py index b0e2b4dac791..5e69c1192434 100644 --- a/src/cryptography/exceptions.py +++ b/src/cryptography/exceptions.py @@ -8,9 +8,7 @@ from cryptography import utils if typing.TYPE_CHECKING: - from cryptography.hazmat.bindings.openssl.binding import ( - _OpenSSLErrorWithText, - ) + from cryptography.hazmat.bindings._rust import openssl as rust_openssl class _Reasons(utils.Enum): @@ -58,7 +56,7 @@ class InvalidSignature(Exception): class InternalError(Exception): def __init__( - self, msg: str, err_code: typing.List["_OpenSSLErrorWithText"] + self, msg: str, err_code: typing.List["rust_openssl.OpenSSLError"] ) -> None: super().__init__(msg) self.err_code = err_code diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 0610b254eab6..3415863b33d8 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -57,6 +57,7 @@ _X25519PrivateKey, _X25519PublicKey, ) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl import binding from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding @@ -209,7 +210,7 @@ def __repr__(self) -> str: def openssl_assert( self, ok: bool, - errors: typing.Optional[typing.List[binding._OpenSSLError]] = None, + errors: typing.Optional[typing.List[rust_openssl.OpenSSLError]] = None, ) -> None: return binding._openssl_assert(self._lib, ok, errors=errors) @@ -484,13 +485,8 @@ def derive_pbkdf2_hmac( self.openssl_assert(res == 1) return self._ffi.buffer(buf)[:] - def _consume_errors(self) -> typing.List[binding._OpenSSLError]: - return binding._consume_errors() - - def _consume_errors_with_text( - self, - ) -> typing.List[binding._OpenSSLErrorWithText]: - return binding._consume_errors_with_text() + def _consume_errors(self) -> typing.List[rust_openssl.OpenSSLError]: + return rust_openssl.capture_error_stack() def _bn_to_int(self, bn) -> int: assert bn != self._ffi.NULL @@ -760,7 +756,7 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: elif key_type == self._lib.EVP_PKEY_EC: ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) if ec_cdata == self._ffi.NULL: - errors = self._consume_errors_with_text() + errors = self._consume_errors() raise ValueError("Unable to load EC key", errors) ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) @@ -1208,13 +1204,12 @@ def _handle_key_loading_error(self) -> typing.NoReturn: raise ValueError("Unsupported public key algorithm.") else: - errors_with_text = binding._errors_with_text(errors) raise ValueError( "Could not deserialize key data. The data may be in an " "incorrect format, it may be encrypted with an unsupported " "algorithm, or it may be an unsupported key type (e.g. EC " "curves with explicit parameters).", - errors_with_text, + errors, ) def elliptic_curve_supported(self, curve: ec.EllipticCurve) -> bool: @@ -1708,7 +1703,7 @@ def generate_dh_parameters( dh_param_cdata, key_size, generator, self._ffi.NULL ) if res != 1: - errors = self._consume_errors_with_text() + errors = self._consume_errors() raise ValueError("Unable to generate DH parameters", errors) return _DHParameters(self, dh_param_cdata) @@ -2051,7 +2046,7 @@ def derive_scrypt( length, ) if res != 1: - errors = self._consume_errors_with_text() + errors = self._consume_errors() # memory required formula explained here: # https://blog.filippo.io/the-scrypt-parameters/ min_memory = 128 * n * r // (1024**2) diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py index c429c023916b..87d6fb8af694 100644 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ b/src/cryptography/hazmat/backends/openssl/dh.py @@ -188,10 +188,10 @@ def exchange(self, peer_public_key: dh.DHPublicKey) -> bytes: def _exchange_assert(self, ok: bool) -> None: if not ok: - errors_with_text = self._backend._consume_errors_with_text() + errors = self._backend._consume_errors() raise ValueError( "Error computing shared key.", - errors_with_text, + errors, ) def public_key(self) -> dh.DHPublicKey: diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index c04cae029e64..c960105e718e 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -285,7 +285,7 @@ def _rsa_sig_sign( buf = backend._ffi.new("unsigned char[]", buflen[0]) res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data)) if res != 1: - errors = backend._consume_errors_with_text() + errors = backend._consume_errors() raise ValueError( "Digest or salt length too long for key size. Use a larger key " "or shorter salt length if you are specifying a PSS salt", @@ -380,7 +380,7 @@ def __init__( if not unsafe_skip_rsa_key_validation: res = backend._lib.RSA_check_key(rsa_cdata) if res != 1: - errors = backend._consume_errors_with_text() + errors = backend._consume_errors() raise ValueError("Invalid private key", errors) # 2 is prime and passes an RSA key check, so we also check # if p and q are odd just to be safe. @@ -392,7 +392,7 @@ def __init__( p_odd = backend._lib.BN_is_odd(p[0]) q_odd = backend._lib.BN_is_odd(q[0]) if p_odd != 1 or q_odd != 1: - errors = backend._consume_errors_with_text() + errors = backend._consume_errors() raise ValueError("Invalid private key", errors) self._backend = backend diff --git a/src/cryptography/hazmat/backends/openssl/utils.py b/src/cryptography/hazmat/backends/openssl/utils.py index 019f412c7ee9..64b4a8334b51 100644 --- a/src/cryptography/hazmat/backends/openssl/utils.py +++ b/src/cryptography/hazmat/backends/openssl/utils.py @@ -35,8 +35,8 @@ def _evp_pkey_derive(backend: "Backend", evp_pkey, peer_public_key) -> bytes: buf = backend._ffi.new("unsigned char[]", keylen[0]) res = backend._lib.EVP_PKEY_derive(ctx, buf, keylen) if res != 1: - errors_with_text = backend._consume_errors_with_text() - raise ValueError("Error computing shared key.", errors_with_text) + errors = backend._consume_errors() + raise ValueError("Error computing shared key.", errors) return backend._ffi.buffer(buf, keylen[0])[:] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 0e292a2fe224..d583500dfc86 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -6,3 +6,13 @@ import typing def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... +def capture_error_stack() -> typing.List[OpenSSLError]: ... + +class OpenSSLError: + @property + def lib(self) -> int: ... + @property + def reason(self) -> int: ... + @property + def reason_text(self) -> bytes: ... + def _lib_reason_match(self, lib: int, reason: int) -> bool: ... diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index b0fc8de28a14..7327157fd8d5 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -16,84 +16,14 @@ from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES -class _OpenSSLErrorWithText(typing.NamedTuple): - code: int - lib: int - reason: int - reason_text: bytes - - @classmethod - def from_err(cls, err: "_OpenSSLError") -> "_OpenSSLErrorWithText": - buf = _openssl.ffi.new("char[]", 256) - _openssl.lib.ERR_error_string_n(err.code, buf, len(buf)) - err_text_reason: bytes = _openssl.ffi.string(buf) - - return _OpenSSLErrorWithText( - err.code, err.lib, err.reason, err_text_reason - ) - - -class _OpenSSLError: - def __init__(self, code: int, lib: int, reason: int): - self._code = code - self._lib = lib - self._reason = reason - - @classmethod - def from_code(cls, code: int) -> "_OpenSSLError": - err_lib: int = _openssl.lib.ERR_GET_LIB(code) - err_reason: int = _openssl.lib.ERR_GET_REASON(code) - return cls(code, err_lib, err_reason) - - def _lib_reason_match(self, lib: int, reason: int) -> bool: - return lib == self.lib and reason == self.reason - - @property - def code(self) -> int: - return self._code - - @property - def lib(self) -> int: - return self._lib - - @property - def reason(self) -> int: - return self._reason - - -def _consume_errors() -> typing.List[_OpenSSLError]: - errors = [] - while True: - code: int = _openssl.lib.ERR_get_error() - if code == 0: - break - - errors.append(_OpenSSLError.from_code(code)) - - return errors - - -def _errors_with_text( - errors: typing.List[_OpenSSLError], -) -> typing.List[_OpenSSLErrorWithText]: - errors_with_text = [] - for err in errors: - errors_with_text.append(_OpenSSLErrorWithText.from_err(err)) - - return errors_with_text - - -def _consume_errors_with_text(): - return _errors_with_text(_consume_errors()) - - def _openssl_assert( - lib, ok: bool, errors: typing.Optional[typing.List[_OpenSSLError]] = None + lib, + ok: bool, + errors: typing.Optional[typing.List[openssl.OpenSSLError]] = None, ) -> None: if not ok: if errors is None: - errors = _consume_errors() - errors_with_text = _errors_with_text(errors) + errors = openssl.capture_error_stack() raise InternalError( "Unknown OpenSSL error. This error is commonly encountered when " @@ -102,8 +32,8 @@ def _openssl_assert( "OpenSSL try disabling it before reporting a bug. Otherwise " "please file an issue at https://github.com/pyca/cryptography/" "issues with information on how to reproduce " - "this. ({!r})".format(errors_with_text), - errors_with_text, + "this. ({!r})".format(errors), + errors, ) diff --git a/src/rust/build.rs b/src/rust/build.rs index 8dbda20a6ea4..0b43d04cdf42 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -57,7 +57,8 @@ fn main() { .include(python_include) .include(openssl_include) .flag_if_supported("-Wconversion") - .flag_if_supported("-Wno-error=sign-conversion"); + .flag_if_supported("-Wno-error=sign-conversion") + .flag_if_supported("-Wno-unused-parameter"); // Enable abi3 mode if we're not using PyPy. if python_impl != "PyPy" { diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index ac3da6bd05e1..6c6440c8d33c 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -2,6 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::OpenSSLError; + pub enum CryptographyError { Asn1Parse(asn1::ParseError), Asn1Write(asn1::WriteError), @@ -70,30 +72,14 @@ impl From for pyo3::PyErr { .getattr(crate::intern!(py, "InternalError")) .expect("Failed to get InternalError attribute"); - let binding_mod = py - .import("cryptography.hazmat.bindings.openssl.binding") - .expect("Failed to import cryptography module"); - - let openssl_error = binding_mod - .getattr(crate::intern!(py, "_OpenSSLError")) - .expect("Failed to get _OpenSSL attribute"); - let openssl_error_with_text = binding_mod - .getattr(crate::intern!(py, "_OpenSSLErrorWithText")) - .expect("Failed to get _OpenSSLErrorWithText attribute"); - let errors = pyo3::types::PyList::empty(py); for e in error_stack.errors() { - let err = openssl_error - .call_method1("from_code", (e.code(),)) - .expect("Failed to call from_code"); - errors .append( - openssl_error_with_text - .call_method1("from_err", (err,)) - .expect("Failed to call from_err"), + pyo3::PyCell::new(py, OpenSSLError { e: e.clone() }) + .expect("Failed to create OpenSSLError"), ) - .expect("List append failed"); + .expect("Failed to append to list"); } pyo3::PyErr::from_instance( internal_error diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index d5de059320ac..90ff4609610e 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -101,6 +101,55 @@ fn raise_openssl_error() -> crate::error::CryptographyResult<()> { Err(openssl::error::ErrorStack::get().into()) } +#[pyo3::prelude::pyclass] +struct OpenSSLError { + e: openssl::error::Error, +} + +#[pyo3::pymethods] +impl OpenSSLError { + #[getter] + fn lib(&self) -> i32 { + self.e.library_code() + } + + #[getter] + fn reason(&self) -> i32 { + self.e.reason_code() + } + + #[getter] + fn reason_text(&self) -> &[u8] { + self.e.reason().unwrap_or("").as_bytes() + } + + fn _lib_reason_match(&self, lib: i32, reason: i32) -> bool { + self.e.library_code() == lib && self.e.reason_code() == reason + } +} + +#[pyo3::prelude::pyproto] +impl pyo3::PyObjectProtocol for OpenSSLError { + fn __repr__(&self) -> pyo3::PyResult { + Ok(format!( + "", + self.e.code(), + self.e.library_code(), + self.e.reason_code(), + self.e.reason().unwrap_or("") + )) + } +} + +#[pyo3::prelude::pyfunction] +fn capture_error_stack(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::types::PyList> { + let errs = pyo3::types::PyList::empty(py); + for e in openssl::error::ErrorStack::get().errors() { + errs.append(pyo3::PyCell::new(py, OpenSSLError { e: e.clone() })?)?; + } + Ok(errs) +} + #[pyo3::prelude::pymodule] fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { m.add_function(pyo3::wrap_pyfunction!(check_pkcs7_padding, m)?)?; @@ -140,6 +189,8 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?; openssl_mod.add_function(pyo3::wrap_pyfunction!(openssl_version, m)?)?; openssl_mod.add_function(pyo3::wrap_pyfunction!(raise_openssl_error, m)?)?; + openssl_mod.add_function(pyo3::wrap_pyfunction!(capture_error_stack, m)?)?; + openssl_mod.add_class::()?; m.add_submodule(openssl_mod)?; Ok(()) diff --git a/tests/conftest.py b/tests/conftest.py index 4b215802bc73..98f60959e413 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -46,9 +46,9 @@ def backend(request): check_backend_support(openssl_backend, request) # Ensure the error stack is clear before the test - errors = openssl_backend._consume_errors_with_text() + errors = openssl_backend._consume_errors() assert not errors yield openssl_backend # Ensure the error stack is clear after the test - errors = openssl_backend._consume_errors_with_text() + errors = openssl_backend._consume_errors() assert not errors diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index c80753bd04e5..118b850ee3ff 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -8,7 +8,6 @@ from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl.binding import ( Binding, - _consume_errors, _legacy_provider_error, _openssl_assert, _verify_package_version, @@ -96,7 +95,7 @@ def test_check_startup_errors_are_allowed(self): -1, ) b._register_osrandom_engine() - assert _consume_errors() == [] + assert rust_openssl.capture_error_stack() == [] def test_version_mismatch(self): with pytest.raises(ImportError): From 328f04dd8a575540ef493613c08f3a521365ce8f Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Mar 2023 21:42:28 -0400 Subject: [PATCH 481/827] libressl 3.7.1 (#8553) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57bb7a3705ef..3ae6a2c52e0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.0"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. From f371af837a6785959e52ac4c84e80f0453c542f1 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 20 Mar 2023 20:16:53 -0400 Subject: [PATCH 482/827] Added support for handling python buffers in Rust code (#8556) This is extra mega cursed, and strictly speaking unsound. It does, however, match the status quo ante, where someone mutating a buffer while its being used in cffi code will basically always be UB. --- docs/glossary.rst | 6 ++- docs/spelling_wordlist.txt | 1 + .../hazmat/primitives/serialization/pkcs7.py | 2 +- src/cryptography/utils.py | 7 +++ src/rust/src/buf.rs | 45 +++++++++++++++++++ src/rust/src/lib.rs | 1 + src/rust/src/pkcs7.rs | 10 +++-- tests/hazmat/primitives/test_pkcs7.py | 25 +++++++++++ 8 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 src/rust/src/buf.rs diff --git a/docs/glossary.rst b/docs/glossary.rst index 0fa40245d1b8..86718cc0d675 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -93,7 +93,10 @@ Glossary bytes-like A bytes-like object contains binary data and supports the `buffer protocol`_. This includes ``bytes``, ``bytearray``, and - ``memoryview`` objects. + ``memoryview`` objects. It is :term:`unsafe` to pass a mutable object + (e.g., a ``bytearray`` or other implementor of the buffer protocol) + and to `mutate it concurrently`_ with the operation it has been + provided for. U-label The presentational unicode form of an internationalized domain @@ -108,3 +111,4 @@ Glossary .. _`hardware security module`: https://en.wikipedia.org/wiki/Hardware_security_module .. _`idna`: https://pypi.org/project/idna/ .. _`buffer protocol`: https://docs.python.org/3/c-api/buffer.html +.. _`mutate it concurrently`: https://alexgaynor.net/2022/oct/23/buffers-on-the-edge/ diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index b4b8685deecc..ea485aaef77a 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -61,6 +61,7 @@ hazmat Homebrew hostname hostnames +implementor incrementing indistinguishability initialisms diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 59b3ab99d534..0a72e0df80d5 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -78,7 +78,7 @@ def set_data(self, data: bytes) -> "PKCS7SignatureBuilder": if self._data is not None: raise ValueError("data may only be set once") - return PKCS7SignatureBuilder(bytes(data), self._signers) + return PKCS7SignatureBuilder(data, self._signers) def add_signer( self, diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index b8da26bdd8ae..a84069f1c822 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -43,6 +43,13 @@ def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: ) +def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[int, int]: + from cryptography.hazmat.bindings._rust import _openssl + + buf = _openssl.ffi.from_buffer(obj) + return int(_openssl.ffi.cast("intptr_t", buf)), len(buf) + + class InterfaceNotImplemented(Exception): pass diff --git a/src/rust/src/buf.rs b/src/rust/src/buf.rs new file mode 100644 index 000000000000..23dddfd26993 --- /dev/null +++ b/src/rust/src/buf.rs @@ -0,0 +1,45 @@ +// 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. + +use std::{ptr, slice}; + +pub(crate) struct CffiBuf<'p> { + _pyobj: &'p pyo3::PyAny, + buf: &'p [u8], +} + +impl CffiBuf<'_> { + pub(crate) fn as_bytes(&self) -> &[u8] { + self.buf + } +} + +impl<'a> pyo3::conversion::FromPyObject<'a> for CffiBuf<'a> { + fn extract(pyobj: &'a pyo3::PyAny) -> pyo3::PyResult { + let py = pyobj.py(); + + let (ptrval, len): (usize, usize) = py + .import("cryptography.utils")? + .call_method1("_extract_buffer_length", (pyobj,))? + .extract()?; + let ptr = if len == 0 { + ptr::NonNull::dangling().as_ptr() + } else { + ptrval as *const u8 + }; + + Ok(CffiBuf { + _pyobj: pyobj, + // SAFETY: _extract_buffer_length ensures that we have a valid ptr + // and length (and we ensure we meet slice's requirements for + // 0-length slices above), we're keeping pyobj alive which ensures + // the buffer is valid. But! There is no actually guarantee + // against concurrent mutation. See + // https://alexgaynor.net/2022/oct/23/buffers-on-the-edge/ + // for details. This is the same as our cffi status quo ante, so + // we're doing an unsound thing and living with it. + buf: unsafe { slice::from_raw_parts(ptr, len) }, + }) + } +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 90ff4609610e..cec55262123c 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -10,6 +10,7 @@ #![allow(unknown_lints, clippy::borrow_deref_ref)] mod asn1; +mod buf; mod error; mod intern; pub(crate) mod oid; diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 93d9a11e4cad..da2a6561b69a 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -3,6 +3,7 @@ // for complete details. use crate::asn1::encode_der_data; +use crate::buf::CffiBuf; use crate::error::CryptographyResult; use crate::x509; @@ -135,13 +136,16 @@ fn sign_and_serialize<'p>( .import("cryptography.hazmat.primitives.serialization.pkcs7")? .getattr(crate::intern!(py, "PKCS7Options"))?; - let raw_data = builder.getattr(crate::intern!(py, "_data"))?.extract()?; + let raw_data: CffiBuf<'p> = builder.getattr(crate::intern!(py, "_data"))?.extract()?; let text_mode = options.contains(pkcs7_options.getattr(crate::intern!(py, "Text"))?)?; let (data_with_header, data_without_header) = if options.contains(pkcs7_options.getattr(crate::intern!(py, "Binary"))?)? { - (Cow::Borrowed(raw_data), Cow::Borrowed(raw_data)) + ( + Cow::Borrowed(raw_data.as_bytes()), + Cow::Borrowed(raw_data.as_bytes()), + ) } else { - smime_canonicalize(raw_data, text_mode) + smime_canonicalize(raw_data.as_bytes(), text_mode) }; let content_type_bytes = asn1::write_single(&PKCS7_DATA_OID)?; diff --git a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py index 88de12ff5bb9..4e61c5ef55e8 100644 --- a/tests/hazmat/primitives/test_pkcs7.py +++ b/tests/hazmat/primitives/test_pkcs7.py @@ -334,6 +334,31 @@ def test_sign_byteslike(self, backend): sig = builder.sign(serialization.Encoding.SMIME, options) assert bytes(data) in sig + _pkcs7_verify( + serialization.Encoding.SMIME, + sig, + data, + [cert], + options, + backend, + ) + + data = bytearray(b"") + builder = ( + pkcs7.PKCS7SignatureBuilder() + .set_data(data) + .add_signer(cert, key, hashes.SHA256()) + ) + + sig = builder.sign(serialization.Encoding.SMIME, options) + _pkcs7_verify( + serialization.Encoding.SMIME, + sig, + data, + [cert], + options, + backend, + ) def test_sign_pem(self, backend): data = b"hello world" From cd96243bc59f6fa4e89dcfbc75324d3ecc43baf4 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 00:26:01 +0000 Subject: [PATCH 483/827] Bump BoringSSL and/or OpenSSL in CI (#8557) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ae6a2c52e0c..19775b36fdc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,10 +40,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 17, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "898de8d09e10960e64901e2d9836cdea5dd1d1a6"}} - # Latest commit on the OpenSSL master branch, as of Mar 20, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "d293ebde01fc14dabbd64fd6e42dc837be7b1fad"}} + # Latest commit on the BoringSSL master branch, as of Mar 21, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "92de195169d26d9f5cec7ef34df9194e614e50f8"}} + # Latest commit on the OpenSSL master branch, as of Mar 21, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6ec3d3125f76aa9f11c133333f868c42b9b585c4"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 760ef96e8084b70a76db997a3d7be7aa85ab7b35 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 21 Mar 2023 19:16:45 +0800 Subject: [PATCH 484/827] no more types-requests (#8559) --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 75204cfd7d6a..3cbb25507d23 100644 --- a/setup.cfg +++ b/setup.cfg @@ -83,7 +83,6 @@ pep8test = black ruff mypy - types-requests check-manifest # This extra is for OpenSSH private keys that use bcrypt KDF # Versions: v3.1.3 - ignore_few_rounds, v3.1.5 - abi3 From 2daf74aabf2404f2249979763ffffab5d73cdf00 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 21 Mar 2023 19:29:52 +0800 Subject: [PATCH 485/827] update docs about testing, switch to 3.1.0 across more of our CI (#8558) --- .github/workflows/ci.yml | 11 +++++------ docs/installation.rst | 10 ++++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19775b36fdc3..80c72b109ead 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,16 +25,15 @@ jobs: PYTHON: - {VERSION: "3.11", TOXENV: "flake"} - {VERSION: "3.11", TOXENV: "rust"} - - {VERSION: "3.11", TOXENV: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} + - {VERSION: "3.11", TOXENV: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - {VERSION: "pypy-3.8", TOXENV: "pypy3-nocoverage"} - {VERSION: "pypy-3.9", TOXENV: "pypy3-nocoverage"} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} - - {VERSION: "3.11", TOXENV: "py311-ssh", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.0.8"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} + - {VERSION: "3.11", TOXENV: "py311-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} + - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} diff --git a/docs/installation.rst b/docs/installation.rst index 210a372eb041..e659668b26a4 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -30,14 +30,16 @@ operating systems. * 32-bit and 64-bit Python on 64-bit Windows Server 2022 We test compiling with ``clang`` as well as ``gcc`` and use the following -OpenSSL releases: +OpenSSL releases in addition to distribution provided releases from the +above supported platforms: * ``OpenSSL 1.1.1-latest`` * ``OpenSSL 3.0-latest`` +* ``OpenSSL 3.1-latest`` -In addition we test against versions of LibreSSL that are available in -versions of OpenBSD that are receiving security support at the time of a given -``cryptography`` release, and the latest commit in BoringSSL. +We also test against the latest commit of BoringSSL as well as versions of +LibreSSL that are receiving security support at the time of a given +``cryptography`` release. Building cryptography on Windows From 28c5b8f6f8f1bc8467066bc1139358ec651df67e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 21 Mar 2023 19:54:09 +0800 Subject: [PATCH 486/827] remove hypothesis from our test suite (#8560) we weren't really getting any value from it and we haven't expanded our use in numerous years --- ci-constraints-requirements.txt | 6 ------ setup.cfg | 1 - tests/hypothesis/__init__.py | 3 --- tests/hypothesis/test_fernet.py | 16 --------------- tests/hypothesis/test_padding.py | 34 -------------------------------- tests/hypothesis/test_x509.py | 22 --------------------- 6 files changed, 82 deletions(-) delete mode 100644 tests/hypothesis/__init__.py delete mode 100644 tests/hypothesis/test_fernet.py delete mode 100644 tests/hypothesis/test_padding.py delete mode 100644 tests/hypothesis/test_x509.py diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 60ae0230c51b..0f051df07522 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -9,7 +9,6 @@ alabaster==0.7.13 # via sphinx attrs==22.2.0 # via - # hypothesis # pytest babel==2.12.1 # via sphinx @@ -44,7 +43,6 @@ docutils==0.18.1 # sphinx-rtd-theme exceptiongroup==1.1.1 # via - # hypothesis # pytest execnet==1.9.0 # via pytest-xdist @@ -52,8 +50,6 @@ filelock==3.10.0; python_version >= "3.7" # via # tox # virtualenv -hypothesis==6.70.0; python_version >= "3.7" - # via cryptography (setup.cfg) idna==3.4 # via requests imagesize==1.4.1 @@ -167,8 +163,6 @@ six==1.16.0 # via bleach snowballstemmer==2.2.0 # via sphinx -sortedcontainers==2.4.0 - # via hypothesis sphinx==6.1.3 # via # cryptography (setup.cfg) diff --git a/setup.cfg b/setup.cfg index 3cbb25507d23..172ac932ae31 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,7 +67,6 @@ test = pytest-xdist pretend iso8601 - hypothesis>=1.11.4,!=3.79.2 test-randomorder: pytest-randomly docs = diff --git a/tests/hypothesis/__init__.py b/tests/hypothesis/__init__.py deleted file mode 100644 index b509336233c2..000000000000 --- a/tests/hypothesis/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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. diff --git a/tests/hypothesis/test_fernet.py b/tests/hypothesis/test_fernet.py deleted file mode 100644 index 75195f5304a5..000000000000 --- a/tests/hypothesis/test_fernet.py +++ /dev/null @@ -1,16 +0,0 @@ -# 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. - -from hypothesis import HealthCheck, given, settings -from hypothesis.strategies import binary - -from cryptography.fernet import Fernet - - -@settings(suppress_health_check=[HealthCheck.too_slow], deadline=None) -@given(binary()) -def test_fernet(data): - f = Fernet(Fernet.generate_key()) - ct = f.encrypt(data) - assert f.decrypt(ct) == data diff --git a/tests/hypothesis/test_padding.py b/tests/hypothesis/test_padding.py deleted file mode 100644 index 74a58eb8c2c5..000000000000 --- a/tests/hypothesis/test_padding.py +++ /dev/null @@ -1,34 +0,0 @@ -# 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. - -from hypothesis import HealthCheck, given, settings -from hypothesis.strategies import binary, integers - -from cryptography.hazmat.primitives.padding import ANSIX923, PKCS7 - - -@settings(suppress_health_check=[HealthCheck.too_slow], deadline=None) -@given(integers(min_value=1, max_value=255), binary()) -def test_pkcs7(block_size, data): - # Generate in [1, 31] so we can easily get block_size in bits by - # multiplying by 8. - p = PKCS7(block_size=block_size * 8) - padder = p.padder() - unpadder = p.unpadder() - - padded = padder.update(data) + padder.finalize() - - assert unpadder.update(padded) + unpadder.finalize() == data - - -@settings(suppress_health_check=[HealthCheck.too_slow]) -@given(integers(min_value=1, max_value=255), binary()) -def test_ansix923(block_size, data): - a = ANSIX923(block_size=block_size * 8) - padder = a.padder() - unpadder = a.unpadder() - - padded = padder.update(data) + padder.finalize() - - assert unpadder.update(padded) + unpadder.finalize() == data diff --git a/tests/hypothesis/test_x509.py b/tests/hypothesis/test_x509.py deleted file mode 100644 index 02d6725972bd..000000000000 --- a/tests/hypothesis/test_x509.py +++ /dev/null @@ -1,22 +0,0 @@ -# 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. - -from hypothesis import HealthCheck, example, given, settings -from hypothesis.strategies import text - -from cryptography import x509 - - -@settings(suppress_health_check=[HealthCheck.too_slow], deadline=None) -@given(text()) -@example("CN=cryptography.io") -def test_name_from_rfc4514(data): - try: - x509.Name.from_rfc4514_string(data) - except ValueError: - return - - # Can't assert that it round-trips because of things like "OID=value" - # where OID is one of the known OIDs that serializes to a known value - # (e.g. CN) From a1d04fe5178cac8da99bc2ea5607081e82cd065d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 13:10:44 +0000 Subject: [PATCH 487/827] Bump iana-time-zone from 0.1.53 to 0.1.54 in /src/rust (#8561) Bumps [iana-time-zone](https://github.com/strawlab/iana-time-zone) from 0.1.53 to 0.1.54. - [Release notes](https://github.com/strawlab/iana-time-zone/releases) - [Changelog](https://github.com/strawlab/iana-time-zone/blob/main/CHANGELOG.md) - [Commits](https://github.com/strawlab/iana-time-zone/compare/v0.1.53...v0.1.54) --- updated-dependencies: - dependency-name: iana-time-zone dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 72 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c37fa68d83af..1ef2d417a194 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -184,16 +184,16 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] @@ -684,3 +684,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" From 6461a448ac49f40881e50b800ce7527817421b0f Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 21:08:09 -0400 Subject: [PATCH 488/827] Bump BoringSSL and/or OpenSSL in CI (#8562) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80c72b109ead..7fd5d25959dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,10 +39,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 21, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "92de195169d26d9f5cec7ef34df9194e614e50f8"}} - # Latest commit on the OpenSSL master branch, as of Mar 21, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "6ec3d3125f76aa9f11c133333f868c42b9b585c4"}} + # Latest commit on the BoringSSL master branch, as of Mar 22, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "8ebfea76db79bc5b1646fbe76e681f58b3363e9d"}} + # Latest commit on the OpenSSL master branch, as of Mar 22, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "03fa5127ded6ba0dc9f178090eca0dbe70769c0e"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From 98dc45ea758f87dc4ebdefa5236c745a438f951b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 12:04:52 +0000 Subject: [PATCH 489/827] Bump proc-macro2 from 1.0.52 to 1.0.53 in /src/rust (#8565) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.52 to 1.0.53. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.52...1.0.53) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 1ef2d417a194..e3542f98f39f 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -459,9 +459,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" dependencies = [ "unicode-ident", ] From e09fccc74964753d53a642f3a7afa245b1b4ee3a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 22 Mar 2023 08:25:45 -0400 Subject: [PATCH 490/827] Remove unused error bindings (#8568) --- src/_cffi_src/openssl/err.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index a38ad7326987..be8c0774c945 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -31,7 +31,6 @@ """ FUNCTIONS = """ -void ERR_error_string_n(unsigned long, char *, size_t); const char *ERR_lib_error_string(unsigned long); const char *ERR_func_error_string(unsigned long); const char *ERR_reason_error_string(unsigned long); @@ -40,9 +39,7 @@ void ERR_clear_error(void); void ERR_put_error(int, int, int, const char *, int); -int ERR_GET_LIB(unsigned long); int ERR_GET_REASON(unsigned long); - """ CUSTOMIZATIONS = """ From 0ff4eb208dbaf26b2b24e08e4e43549adb998e74 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 22 Mar 2023 08:27:36 -0400 Subject: [PATCH 491/827] also update mtimes on src/_cffi_src (#8567) --- .github/actions/mtime-fix/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/mtime-fix/action.yml b/.github/actions/mtime-fix/action.yml index b7ab3b9b5c37..4589aece1b8b 100644 --- a/.github/actions/mtime-fix/action.yml +++ b/.github/actions/mtime-fix/action.yml @@ -11,7 +11,7 @@ runs: echo "The git available is probably too old so checkout didn't create a real git clone, skipping mtime fix" exit 0 fi - ls -Rla src/rust/src + ls -Rla src/rust/src src/_cffi_src echo "Verifying commits are monotonic because if they're not caching gets wrecked" COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5) SORTED_COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5 | sort -rn) @@ -19,8 +19,8 @@ runs: echo "Commits are not monotonic, git may have changed how date formatting works" exit 1 fi - echo "Setting mtimes for rust dirs" - for f in $(git ls-files src/rust); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done + echo "Setting mtimes for dirs" + for f in $(git ls-files src/rust src/_cffi_src); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done echo "Done" - ls -Rla src/rust/src + ls -Rla src/rust/src src/_cffi_src shell: bash From ddb4c38a03c512cdbc4acd281b368f60c7d603c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 17:42:11 -0400 Subject: [PATCH 492/827] Bump actions/stale from 7.0.0 to 8.0.0 (#8569) Bumps [actions/stale](https://github.com/actions/stale) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v7.0.0...v8.0.0) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/auto-close-stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-close-stale.yml b/.github/workflows/auto-close-stale.yml index a08b2d9cae9f..2dd48549fd6c 100644 --- a/.github/workflows/auto-close-stale.yml +++ b/.github/workflows/auto-close-stale.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/stale@v7.0.0 + - uses: actions/stale@v8.0.0 with: only-labels: waiting-on-reporter days-before-stale: 5 From 3e9d6b72aab4cb9449f72f87f7094e7bf95dcebd Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 23 Mar 2023 05:58:25 +0800 Subject: [PATCH 493/827] handle case where WIN32_LEAN_AND_MEAN may already be defined (#8571) --- src/_cffi_src/openssl/cryptography.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py index 84c0cf360727..6a79091c81c4 100644 --- a/src/_cffi_src/openssl/cryptography.py +++ b/src/_cffi_src/openssl/cryptography.py @@ -9,7 +9,9 @@ #define OPENSSL_API_COMPAT 0x10100000L #if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include #include #include From 5e081e54958e0c5068e2fcae9f0f8a9e0812321d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 22 Mar 2023 18:03:50 -0400 Subject: [PATCH 494/827] Refs #8570 -- lower cxx version to match our MSRV (#8572) --- src/rust/Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index e3542f98f39f..3b93cdfa82fa 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.92" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72" +checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" dependencies = [ "cc", "cxxbridge-flags", @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.92" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613" +checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" dependencies = [ "cc", "codespan-reporting", @@ -152,15 +152,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.92" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97" +checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" [[package]] name = "cxxbridge-macro" -version = "1.0.92" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" +checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" dependencies = [ "proc-macro2", "quote", From 6cdec1bace1b90ff62ab1bf32c151abc5a622251 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:17:56 +0000 Subject: [PATCH 495/827] Bump BoringSSL and/or OpenSSL in CI (#8573) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fd5d25959dc..d1e90f831b0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,10 +39,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 22, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "8ebfea76db79bc5b1646fbe76e681f58b3363e9d"}} - # Latest commit on the OpenSSL master branch, as of Mar 22, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "03fa5127ded6ba0dc9f178090eca0dbe70769c0e"}} + # Latest commit on the BoringSSL master branch, as of Mar 23, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "b6a50fd62d1ae44ad211ebe26f803c66db444302"}} + # Latest commit on the OpenSSL master branch, as of Mar 23, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "8bdc3708964814ea0b7002df020fbd459e3a813f"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From c45706e265bccdd10afd4e04fa29e2387620028a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:48:30 +0000 Subject: [PATCH 496/827] Bump ruff from 0.0.257 to 0.0.258 (#8574) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.257 to 0.0.258. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.257...v0.0.258) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 0f051df07522..e65bc0823988 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -157,7 +157,7 @@ rfc3986==2.0.0 # via twine rich==13.3.2 # via twine -ruff==0.0.257 +ruff==0.0.258 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 9b906f00d6bded9b45a34d01d22d5752d0f73fa8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 23 Mar 2023 19:55:21 +0800 Subject: [PATCH 497/827] we don't need these in the constraints since we no longer depend on them (#8577) --- ci-constraints-requirements.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e65bc0823988..85fa74b14aab 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -201,10 +201,6 @@ tox==4.4.7; python_version >= "3.7" # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -types-requests==2.28.11.15 - # via cryptography (setup.cfg) -types-urllib3==1.26.25.8 - # via types-requests typing-extensions==4.5.0; python_version >= "3.7" # via mypy urllib3==1.26.15 From 41ebbe7de97a83037cbe54f301b19fad3fbe0893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:58:01 +0000 Subject: [PATCH 498/827] Bump filelock from 3.10.0 to 3.10.2 (#8575) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.0 to 3.10.2. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.0...3.10.2) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 85fa74b14aab..790b63602776 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.0; python_version >= "3.7" +filelock==3.10.2; python_version >= "3.7" # via # tox # virtualenv From 005bbe05595f9c3efec04af9772014f14d2150e9 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 00:20:55 +0000 Subject: [PATCH 499/827] Bump BoringSSL and/or OpenSSL in CI (#8578) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1e90f831b0a..2295d18ac607 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,8 +41,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 23, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "b6a50fd62d1ae44ad211ebe26f803c66db444302"}} - # Latest commit on the OpenSSL master branch, as of Mar 23, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "8bdc3708964814ea0b7002df020fbd459e3a813f"}} + # Latest commit on the OpenSSL master branch, as of Mar 24, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "908ba3ed9adbb3df90f7684a3111ca916a45202d"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 env: From f147302e0053843bc0fd189e47fd5052b56f1263 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 02:10:05 +0000 Subject: [PATCH 500/827] Bump filelock from 3.10.2 to 3.10.3 (#8579) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.2 to 3.10.3. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.2...3.10.3) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 790b63602776..dc54768edc10 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.2; python_version >= "3.7" +filelock==3.10.3; python_version >= "3.7" # via # tox # virtualenv From 1a911a0e304803ad5601f0c447f5f4e11520d6b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 02:16:38 +0000 Subject: [PATCH 501/827] Bump openssl from 0.10.47 to 0.10.48 in /src/rust (#8581) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.47 to 0.10.48. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.47...openssl-v0.10.48) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 3b93cdfa82fa..2ce5c9dfa209 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -308,9 +308,9 @@ checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "openssl" -version = "0.10.47" +version = "0.10.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" +checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ "bitflags", "cfg-if", @@ -334,9 +334,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.82" +version = "0.9.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" +checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" dependencies = [ "autocfg", "cc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 0887bd793b82..0ef74bd1be91 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,7 +14,7 @@ asn1 = { version = "0.13.0", default-features = false } pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" -openssl = "0.10.47" +openssl = "0.10.48" openssl-sys = "0.9.72" [build-dependencies] From 6a900fefc1023a5efd7f1cf07ebc5107458713a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 02:21:46 +0000 Subject: [PATCH 502/827] Bump ruff from 0.0.258 to 0.0.259 (#8580) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.258 to 0.0.259. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.258...v0.0.259) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index dc54768edc10..7494fbb6d14e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -157,7 +157,7 @@ rfc3986==2.0.0 # via twine rich==13.3.2 # via twine -ruff==0.0.258 +ruff==0.0.259 # via cryptography (setup.cfg) six==1.16.0 # via bleach From 370280bb73d9c96e352c3bed2a2a1000667d26a4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 23 Mar 2023 23:37:34 -0400 Subject: [PATCH 503/827] fixes #8450 -- enable sparse registry everywhere (#8566) --- .github/workflows/ci.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2295d18ac607..f5323c56d7a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true +env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + jobs: linux: runs-on: ubuntu-latest @@ -45,8 +48,6 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "908ba3ed9adbb3df90f7684a3111ca916a45202d"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 timeout-minutes: 3 @@ -147,8 +148,6 @@ jobs: - {IMAGE: "ubuntu-jammy:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - name: Ridiculous alpine workaround for actions support on arm64 run: | @@ -269,8 +268,6 @@ jobs: - nightly name: "Rust Coverage" timeout-minutes: 15 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 timeout-minutes: 3 @@ -451,8 +448,6 @@ jobs: JOB_NUMBER: [0, 1] name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 timeout-minutes: 3 @@ -527,8 +522,6 @@ jobs: - '3.11' name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 timeout-minutes: 3 @@ -572,8 +565,6 @@ jobs: runs-on: ubuntu-latest name: "linkcheck" timeout-minutes: 10 - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse steps: - uses: actions/checkout@v3.4.0 with: From c8328c03aff86351b58e47f0e03199a42291082c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 23 Mar 2023 23:48:40 -0400 Subject: [PATCH 504/827] Migrate x25519 to use rust-openssl (#7933) --- src/_cffi_src/openssl/nid.py | 1 - .../hazmat/backends/openssl/backend.py | 37 +-- .../hazmat/backends/openssl/x25519.py | 120 ------- .../bindings/_rust/openssl/__init__.pyi | 4 + .../hazmat/bindings/_rust/openssl/x25519.pyi | 14 + .../hazmat/primitives/asymmetric/x25519.py | 21 +- src/rust/Cargo.lock | 1 + src/rust/Cargo.toml | 1 + src/rust/build.rs | 10 + src/rust/src/backend/mod.rs | 13 + src/rust/src/backend/x25519.rs | 297 ++++++++++++++++++ src/rust/src/lib.rs | 2 + tests/hazmat/primitives/test_x25519.py | 47 ++- 13 files changed, 410 insertions(+), 158 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/x25519.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi create mode 100644 src/rust/src/backend/mod.rs create mode 100644 src/rust/src/backend/x25519.rs diff --git a/src/_cffi_src/openssl/nid.py b/src/_cffi_src/openssl/nid.py index 309991273c83..28135b428d46 100644 --- a/src/_cffi_src/openssl/nid.py +++ b/src/_cffi_src/openssl/nid.py @@ -15,7 +15,6 @@ static const int NID_undef; static const int NID_aes_256_cbc; static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -static const int NID_X25519; static const int NID_X448; static const int NID_ED25519; static const int NID_ED448; diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 3415863b33d8..53e3486c0da2 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -53,10 +53,6 @@ _X448PrivateKey, _X448PublicKey, ) -from cryptography.hazmat.backends.openssl.x25519 import ( - _X25519PrivateKey, - _X25519PublicKey, -) from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl import binding from cryptography.hazmat.primitives import hashes, serialization @@ -715,7 +711,9 @@ def _evp_pkey_to_private_key( # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return _X448PrivateKey(self, evp_pkey) elif key_type == self._lib.EVP_PKEY_X25519: - return _X25519PrivateKey(self, evp_pkey) + return rust_openssl.x25519.private_key_from_ptr( + int(self._ffi.cast("intptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return _Ed448PrivateKey(self, evp_pkey) @@ -772,7 +770,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return _X448PublicKey(self, evp_pkey) elif key_type == self._lib.EVP_PKEY_X25519: - return _X25519PublicKey(self, evp_pkey) + return rust_openssl.x25519.public_key_from_ptr( + int(self._ffi.cast("intptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return _Ed448PublicKey(self, evp_pkey) @@ -1860,30 +1860,12 @@ def dh_x942_serialization_supported(self) -> bool: return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1 def x25519_load_public_bytes(self, data: bytes) -> x25519.X25519PublicKey: - if len(data) != 32: - raise ValueError("An X25519 public key is 32 bytes long") - - data_ptr = self._ffi.from_buffer(data) - evp_pkey = self._lib.EVP_PKEY_new_raw_public_key( - self._lib.NID_X25519, self._ffi.NULL, data_ptr, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return _X25519PublicKey(self, evp_pkey) + return rust_openssl.x25519.from_public_bytes(data) def x25519_load_private_bytes( self, data: bytes ) -> x25519.X25519PrivateKey: - if len(data) != 32: - raise ValueError("An X25519 private key is 32 bytes long") - - data_ptr = self._ffi.from_buffer(data) - evp_pkey = self._lib.EVP_PKEY_new_raw_private_key( - self._lib.NID_X25519, self._ffi.NULL, data_ptr, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return _X25519PrivateKey(self, evp_pkey) + return rust_openssl.x25519.from_private_bytes(data) def _evp_pkey_keygen_gc(self, nid): evp_pkey_ctx = self._lib.EVP_PKEY_CTX_new_id(nid, self._ffi.NULL) @@ -1899,8 +1881,7 @@ def _evp_pkey_keygen_gc(self, nid): return evp_pkey def x25519_generate_key(self) -> x25519.X25519PrivateKey: - evp_pkey = self._evp_pkey_keygen_gc(self._lib.NID_X25519) - return _X25519PrivateKey(self, evp_pkey) + return rust_openssl.x25519.generate_key() def x25519_supported(self) -> bool: if self._fips_enabled: diff --git a/src/cryptography/hazmat/backends/openssl/x25519.py b/src/cryptography/hazmat/backends/openssl/x25519.py deleted file mode 100644 index b7f9406c7b2a..000000000000 --- a/src/cryptography/hazmat/backends/openssl/x25519.py +++ /dev/null @@ -1,120 +0,0 @@ -# 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. - -import typing - -from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric.x25519 import ( - X25519PrivateKey, - X25519PublicKey, -) - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -_X25519_KEY_SIZE = 32 - - -class _X25519PublicKey(X25519PublicKey): - def __init__(self, backend: "Backend", evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PublicFormat.Raw - ): - if ( - encoding is not serialization.Encoding.Raw - or format is not serialization.PublicFormat.Raw - ): - raise ValueError( - "When using Raw both encoding and format must be Raw" - ) - - return self._raw_public_bytes() - - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def _raw_public_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE) - return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:] - - -class _X25519PrivateKey(X25519PrivateKey): - def __init__(self, backend: "Backend", evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_key(self) -> X25519PublicKey: - bio = self._backend._create_mem_bio_gc() - res = self._backend._lib.i2d_PUBKEY_bio(bio, self._evp_pkey) - self._backend.openssl_assert(res == 1) - evp_pkey = self._backend._lib.d2i_PUBKEY_bio( - bio, self._backend._ffi.NULL - ) - self._backend.openssl_assert(evp_pkey != self._backend._ffi.NULL) - evp_pkey = self._backend._ffi.gc( - evp_pkey, self._backend._lib.EVP_PKEY_free - ) - return _X25519PublicKey(self._backend, evp_pkey) - - def exchange(self, peer_public_key: X25519PublicKey) -> bytes: - if not isinstance(peer_public_key, X25519PublicKey): - raise TypeError("peer_public_key must be X25519PublicKey.") - - return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PrivateFormat.Raw - ): - if ( - format is not serialization.PrivateFormat.Raw - or encoding is not serialization.Encoding.Raw - or not isinstance( - encryption_algorithm, serialization.NoEncryption - ) - ): - raise ValueError( - "When using Raw both encoding and format must be Raw " - "and encryption_algorithm must be NoEncryption()" - ) - - return self._raw_private_bytes() - - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self, self._evp_pkey, None - ) - - def _raw_private_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_private_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE) - return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index d583500dfc86..c19b6a9bcbeb 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -4,6 +4,10 @@ import typing +from cryptography.hazmat.bindings._rust.openssl import x25519 + +__all__ = ["openssl_version", "raise_openssl_error", "x25519"] + def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... def capture_error_stack() -> typing.List[OpenSSLError]: ... diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi new file mode 100644 index 000000000000..90f7cbdda950 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import x25519 + +class X25519PrivateKey: ... +class X25519PublicKey: ... + +def generate_key() -> x25519.X25519PrivateKey: ... +def private_key_from_ptr(ptr: int) -> x25519.X25519PrivateKey: ... +def public_key_from_ptr(ptr: int) -> x25519.X25519PublicKey: ... +def from_private_bytes(data: bytes) -> x25519.X25519PrivateKey: ... +def from_public_bytes(data: bytes) -> x25519.X25519PublicKey: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index eb964f465316..fb21fe1749a5 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -6,6 +6,7 @@ import abc from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization @@ -32,14 +33,17 @@ def public_bytes( The serialized bytes of the public key. """ + @abc.abstractmethod def public_bytes_raw(self) -> bytes: """ The raw bytes of the public key. Equivalent to public_bytes(Raw, Raw). """ - return self.public_bytes( - _serialization.Encoding.Raw, _serialization.PublicFormat.Raw - ) + + +# For LibreSSL +if hasattr(rust_openssl, "x25519"): + X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey) class X25519PrivateKey(metaclass=abc.ABCMeta): @@ -83,19 +87,20 @@ def private_bytes( The serialized bytes of the private key. """ + @abc.abstractmethod def private_bytes_raw(self) -> bytes: """ The raw bytes of the private key. Equivalent to private_bytes(Raw, Raw, NoEncryption()). """ - return self.private_bytes( - _serialization.Encoding.Raw, - _serialization.PrivateFormat.Raw, - _serialization.NoEncryption(), - ) @abc.abstractmethod def exchange(self, peer_public_key: X25519PublicKey) -> bytes: """ Performs a key exchange operation using the provided peer's public key. """ + + +# For LibreSSL +if hasattr(rust_openssl, "x25519"): + X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2ce5c9dfa209..dd8c6b0c6fb2 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "asn1", "cc", "chrono", + "foreign-types-shared", "once_cell", "openssl", "openssl-sys", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 0ef74bd1be91..2b1b94001683 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -16,6 +16,7 @@ chrono = { version = "0.4.24", default-features = false, features = ["alloc", "c ouroboros = "0.15" openssl = "0.10.48" openssl-sys = "0.9.72" +foreign-types-shared = "0.1" [build-dependencies] cc = "1.0.72" diff --git a/src/rust/build.rs b/src/rust/build.rs index 0b43d04cdf42..01177ac0e96c 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -3,6 +3,7 @@ use std::io::Write; use std::path::Path; use std::process::{Command, Stdio}; +#[allow(clippy::unusual_byte_groupings)] fn main() { let target = env::var("TARGET").unwrap(); let openssl_static = env::var("OPENSSL_STATIC") @@ -71,6 +72,15 @@ fn main() { } build.compile("_openssl.a"); + + if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { + let version = u64::from_str_radix(&version, 16).unwrap(); + + println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_LIBRESSL"); + if version >= 0x3_07_00_00_0 { + println!("cargo:rustc-cfg=CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER") + } + } } /// Run a python script using the specified interpreter binary. diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs new file mode 100644 index 000000000000..c7e086b56efb --- /dev/null +++ b/src/rust/src/backend/mod.rs @@ -0,0 +1,13 @@ +// 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. + +#[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] +pub(crate) mod x25519; + +pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] + module.add_submodule(x25519::create_module(module.py())?)?; + + Ok(()) +} diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs new file mode 100644 index 000000000000..96a2c7a5cc6e --- /dev/null +++ b/src/rust/src/backend/x25519.rs @@ -0,0 +1,297 @@ +// 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. + +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; +use foreign_types_shared::ForeignTypeRef; + +#[pyo3::prelude::pyclass] +struct X25519PrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass] +struct X25519PublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyfunction] +fn generate_key() -> CryptographyResult { + Ok(X25519PrivateKey { + pkey: openssl::pkey::PKey::generate_x25519()?, + }) +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> X25519PrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + X25519PrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> X25519PublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + X25519PublicKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn from_private_bytes(data: CffiBuf<'_>) -> pyo3::PyResult { + let pkey = + openssl::pkey::PKey::private_key_from_raw_bytes(data.as_bytes(), openssl::pkey::Id::X25519) + .map_err(|e| { + pyo3::exceptions::PyValueError::new_err(format!( + "An X25519 private key is 32 bytes long: {}", + e + )) + })?; + Ok(X25519PrivateKey { pkey }) +} +#[pyo3::prelude::pyfunction] +fn from_public_bytes(data: &[u8]) -> pyo3::PyResult { + let pkey = openssl::pkey::PKey::public_key_from_raw_bytes(data, openssl::pkey::Id::X25519) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An X25519 public key is 32 bytes long") + })?; + Ok(X25519PublicKey { pkey }) +} + +#[pyo3::prelude::pymethods] +impl X25519PrivateKey { + fn exchange<'p>( + &self, + py: pyo3::Python<'p>, + public_key: &X25519PublicKey, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut deriver = openssl::derive::Deriver::new(&self.pkey)?; + deriver.set_peer(&public_key.pkey)?; + + Ok(pyo3::types::PyBytes::new_with(py, deriver.len()?, |b| { + let n = deriver.derive(b).map_err(|_| { + pyo3::exceptions::PyValueError::new_err("Error computing shared key.") + })?; + assert_eq!(n, b.len()); + Ok(()) + })?) + } + + fn public_key(&self) -> CryptographyResult { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(X25519PublicKey { + pkey: openssl::pkey::PKey::public_key_from_raw_bytes( + &raw_bytes, + openssl::pkey::Id::X25519, + )?, + }) + } + + fn private_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_private_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn private_bytes<'p>( + &self, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let encoding_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "Encoding"))? + .extract()?; + let private_format_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "PrivateFormat"))? + .extract()?; + let no_encryption_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "NoEncryption"))? + .extract()?; + let best_available_encryption_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "BestAvailableEncryption"))? + .extract()?; + + if !encoding_class.is_instance(encoding)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "encoding must be an item from the Encoding enum", + ), + )); + } + if !private_format_class.is_instance(format)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "format must be an item from the PrivateFormat enum", + ), + )); + } + + if encoding == encoding_class.getattr(crate::intern!(py, "Raw"))? + || format == private_format_class.getattr(crate::intern!(py, "Raw"))? + { + if encoding != encoding_class.getattr(crate::intern!(py, "Raw"))? + || format != private_format_class.getattr(crate::intern!(py, "Raw"))? + || !no_encryption_class.is_instance(encryption_algorithm)? + { + return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( + "When using Raw both encoding and format must be Raw and encryption_algorithm must be NoEncryption()" + ))); + } + let raw_bytes = self.pkey.raw_private_key()?; + return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); + } + + let password = if no_encryption_class.is_instance(encryption_algorithm)? { + b"" + } else if best_available_encryption_class.is_instance(encryption_algorithm)? { + encryption_algorithm + .getattr(crate::intern!(py, "password"))? + .extract::<&[u8]>()? + } else { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "Encryption algorithm must be a KeySerializationEncryption instance", + ), + )); + }; + + if password.len() > 1023 { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Passwords longer than 1023 bytes are not supported by this backend", + ), + )); + } + + if format == private_format_class.getattr(crate::intern!(py, "PKCS8"))? { + if encoding == encoding_class.getattr(crate::intern!(py, "PEM"))? { + let pem_bytes = if password.is_empty() { + self.pkey.private_key_to_pem_pkcs8()? + } else { + self.pkey.private_key_to_pem_pkcs8_passphrase( + openssl::symm::Cipher::aes_256_cbc(), + password, + )? + }; + return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); + } else if encoding == encoding_class.getattr(crate::intern!(py, "DER"))? { + let der_bytes = if password.is_empty() { + self.pkey.private_key_to_pkcs8()? + } else { + self.pkey.private_key_to_pkcs8_passphrase( + openssl::symm::Cipher::aes_256_cbc(), + password, + )? + }; + return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); + } else { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Unsupported encoding for PKCS8"), + )); + } + } + + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), + )) + } +} + +#[pyo3::prelude::pymethods] +impl X25519PublicKey { + fn public_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn public_bytes<'p>( + &self, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let encoding_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "Encoding"))? + .extract()?; + let public_format_class: &pyo3::types::PyType = serialization_mod + .getattr(crate::intern!(py, "PublicFormat"))? + .extract()?; + + if !encoding_class.is_instance(encoding)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "encoding must be an item from the Encoding enum", + ), + )); + } + if !public_format_class.is_instance(format)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "format must be an item from the PublicFormat enum", + ), + )); + } + + if encoding == encoding_class.getattr(crate::intern!(py, "Raw"))? + || format == public_format_class.getattr(crate::intern!(py, "Raw"))? + { + if encoding != encoding_class.getattr(crate::intern!(py, "Raw"))? + || format != public_format_class.getattr(crate::intern!(py, "Raw"))? + { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "When using Raw both encoding and format must be Raw", + ), + )); + } + let raw_bytes = self.pkey.raw_public_key()?; + return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); + } + + // SubjectPublicKeyInfo + PEM/DER + if format == public_format_class.getattr(crate::intern!(py, "SubjectPublicKeyInfo"))? { + if encoding == encoding_class.getattr(crate::intern!(py, "PEM"))? { + let pem_bytes = self.pkey.public_key_to_pem()?; + return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); + } else if encoding == encoding_class.getattr(crate::intern!(py, "DER"))? { + let der_bytes = self.pkey.public_key_to_der()?; + return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); + } else { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "SubjectPublicKeyInfo works only with PEM or DER encoding", + ), + )); + } + } + + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), + )) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "x25519")?; + m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; + m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + + m.add_class::()?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index cec55262123c..2ec4e66bb5c2 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -10,6 +10,7 @@ #![allow(unknown_lints, clippy::borrow_deref_ref)] mod asn1; +mod backend; mod buf; mod error; mod intern; @@ -192,6 +193,7 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> openssl_mod.add_function(pyo3::wrap_pyfunction!(raise_openssl_error, m)?)?; openssl_mod.add_function(pyo3::wrap_pyfunction!(capture_error_stack, m)?)?; openssl_mod.add_class::()?; + crate::backend::add_to_module(openssl_mod)?; m.add_submodule(openssl_mod)?; Ok(()) diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index a0a5083f35e1..3eb642df5542 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -96,10 +96,24 @@ def test_null_shared_key_raises_error(self, backend): def test_public_bytes_bad_args(self, backend): key = X25519PrivateKey.generate().public_key() - with pytest.raises(ValueError): + with pytest.raises(TypeError): key.public_bytes( None, serialization.PublicFormat.Raw # type: ignore[arg-type] ) + with pytest.raises(ValueError): + key.public_bytes( + serialization.Encoding.DER, serialization.PublicFormat.Raw + ) + with pytest.raises(TypeError): + key.public_bytes( + serialization.Encoding.DER, + None, # type: ignore[arg-type] + ) + with pytest.raises(ValueError): + key.public_bytes( + serialization.Encoding.SMIME, + serialization.PublicFormat.SubjectPublicKeyInfo, + ) # These vectors are also from RFC 7748 # https://tools.ietf.org/html/rfc7748#section-6.1 @@ -202,6 +216,37 @@ def test_invalid_private_bytes(self, backend): serialization.NoEncryption(), ) + with pytest.raises(TypeError): + key.private_bytes(None, None, None) # type: ignore[arg-type] + + with pytest.raises(TypeError): + key.private_bytes( + serialization.Encoding.Raw, + None, # type: ignore[arg-type] + None, # type: ignore[arg-type] + ) + + with pytest.raises(TypeError): + key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.PKCS8, + object(), # type: ignore[arg-type] + ) + + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.PKCS8, + serialization.BestAvailableEncryption(b"a" * 1024), + ) + + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.SMIME, + serialization.PrivateFormat.PKCS8, + serialization.NoEncryption(), + ) + def test_invalid_public_bytes(self, backend): key = X25519PrivateKey.generate().public_key() with pytest.raises(ValueError): From 45e37718098edca2c5ac2135394bcf17fd7982f0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 12:22:14 +0800 Subject: [PATCH 505/827] version bump and changelog for 40.0.0 (#8583) --- CHANGELOG.rst | 6 +++--- src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index deac7aedf93f..7bf627776069 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,10 +3,9 @@ Changelog .. _v40-0-0: -40.0.0 - `main`_ -~~~~~~~~~~~~~~~~ +40.0.0 - 2023-03-24 +~~~~~~~~~~~~~~~~~~~ -.. note:: This version is not yet released and is under active development. * **BACKWARDS INCOMPATIBLE:** As announced in the 39.0.0 changelog, the way ``cryptography`` links OpenSSL has changed. This only impacts users who @@ -33,6 +32,7 @@ Changelog and :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. * The minimum supported version of PyPy3 is now 7.3.10. +* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.1.0. * Added support for parsing SSH certificates in addition to public keys with :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_identity`. :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 48d5c220045c..20d197b6bbe7 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -9,7 +9,7 @@ "__copyright__", ] -__version__ = "40.0.0.dev1" +__version__ = "40.0.0" __author__ = "The Python Cryptographic Authority and individual contributors" __copyright__ = f"Copyright 2013-2022 {__author__}" diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index 46c562addb25..e99963664735 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "40.0.0.dev1" +__version__ = "40.0.0" From 4157ead1e04778fcebc40c288f9d71721b6dd8cf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 13:01:01 +0800 Subject: [PATCH 506/827] reopen main for 41 dev (#8584) --- CHANGELOG.rst | 7 +++++++ src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7bf627776069..5afb57d52a33 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog ========= +.. _v41-0-0: + +41.0.0 - `main`_ +~~~~~~~~~~~~~~~~ + +.. note:: This version is not yet released and is under active development. + .. _v40-0-0: 40.0.0 - 2023-03-24 diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 20d197b6bbe7..489579eb635f 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -9,7 +9,7 @@ "__copyright__", ] -__version__ = "40.0.0" +__version__ = "41.0.0.dev1" __author__ = "The Python Cryptographic Authority and individual contributors" __copyright__ = f"Copyright 2013-2022 {__author__}" diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index e99963664735..24340ac421e4 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "40.0.0" +__version__ = "41.0.0.dev1" From fc7a8717cef0ea8be9dc17698cce84768324a50d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:25:59 +0000 Subject: [PATCH 507/827] Bump actions/checkout from 3.4.0 to 3.5.0 in /.github/actions/wycheproof (#8588) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/wycheproof/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/wycheproof/action.yml b/.github/actions/wycheproof/action.yml index 5a1042c10c4e..a7f265e12f29 100644 --- a/.github/actions/wycheproof/action.yml +++ b/.github/actions/wycheproof/action.yml @@ -5,7 +5,7 @@ runs: using: "composite" steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 with: repository: "google/wycheproof" path: "wycheproof" From fd70d79bf61cf661dccb684198051a06eebd6d2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:38:53 +0000 Subject: [PATCH 508/827] Bump actions/checkout from 3.4.0 to 3.5.0 (#8590) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 4 ++-- .github/workflows/boring-open-version-bump.yml | 2 +- .github/workflows/ci.yml | 18 +++++++++--------- .github/workflows/wheel-builder.yml | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 7f332cc11800..ced2eee2ab75 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,12 +17,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false path: "cryptography-pr" - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: repository: "pyca/cryptography" diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 353015d9be32..66a9ad5b0c28 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 - id: check-sha-boring run: | SHA=$(git ls-remote https://boringssl.googlesource.com/boringssl refs/heads/master | cut -f1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5323c56d7a3..504acdb56bd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -158,7 +158,7 @@ jobs: sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release if: matrix.IMAGE.IMAGE == 'alpine:aarch64' - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -221,7 +221,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -269,7 +269,7 @@ jobs: name: "Rust Coverage" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -382,7 +382,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -449,7 +449,7 @@ jobs: name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -523,7 +523,7 @@ jobs: name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false @@ -566,7 +566,7 @@ jobs: name: "linkcheck" timeout-minutes: 10 steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 with: persist-credentials: false fetch-depth: 0 @@ -602,7 +602,7 @@ jobs: needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 timeout-minutes: 3 with: persist-credentials: false diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index b81de2063f27..36df9f926a79 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest name: sdists steps: - - uses: actions/checkout@v3.4.0 + - uses: actions/checkout@v3.5.0 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} From 4c24dd05eb99c0f6f02d243168d0a4916d5abbf3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 20:33:48 +0800 Subject: [PATCH 509/827] get the proper workflow id for publishing (#8586) does this fix #8585? maybe. --- .github/workflows/pypi-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 8a90d24a93ba..f12b7244c32b 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -28,7 +28,7 @@ jobs: - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 with: path: dist/ - run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.event.id }} + run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.id }} - run: pip install twine requests - run: | From 5e6476a4c6e094926a983dcf5cbe9488c30aeb53 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 20:36:58 +0800 Subject: [PATCH 510/827] drop support for openssl < 1.1.1d (#8449) This removes the OS random engine, which contained the only CPython PSF licensed code in the repository. Accordingly, that license has now been removed. --- .github/workflows/ci.yml | 16 +- CHANGELOG.rst | 3 + LICENSE | 3 - LICENSE.PSF | 41 -- MANIFEST.in | 1 - docs/openssl.rst | 82 +-- setup.cfg | 2 +- src/_cffi_src/build_openssl.py | 1 - src/_cffi_src/openssl/cryptography.py | 23 +- src/_cffi_src/openssl/err.py | 2 +- src/_cffi_src/openssl/osrandom_engine.py | 23 - src/_cffi_src/openssl/src/osrandom_engine.c | 627 ------------------ src/_cffi_src/openssl/src/osrandom_engine.h | 116 ---- .../hazmat/backends/openssl/backend.py | 64 +- .../hazmat/backends/openssl/ciphers.py | 2 +- .../hazmat/bindings/openssl/_conditional.py | 1 - .../hazmat/bindings/openssl/binding.py | 31 - tests/hazmat/backends/test_openssl.py | 155 ----- tests/hazmat/bindings/test_openssl.py | 17 - tests/hazmat/primitives/test_aes.py | 4 +- 20 files changed, 20 insertions(+), 1194 deletions(-) delete mode 100644 LICENSE.PSF delete mode 100644 src/_cffi_src/openssl/osrandom_engine.py delete mode 100644 src/_cffi_src/openssl/src/osrandom_engine.c delete mode 100644 src/_cffi_src/openssl/src/osrandom_engine.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 504acdb56bd0..1824b269aa9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,6 @@ jobs: - {IMAGE: "bullseye", TOXENV: "py39", RUNNER: "ubuntu-latest"} - {IMAGE: "bookworm", TOXENV: "py311", RUNNER: "ubuntu-latest"} - {IMAGE: "sid", TOXENV: "py311", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-bionic", TOXENV: "py36", RUNNER: "ubuntu-latest"} - {IMAGE: "ubuntu-focal", TOXENV: "py38", RUNNER: "ubuntu-latest"} - {IMAGE: "ubuntu-jammy", TOXENV: "py310", RUNNER: "ubuntu-latest"} - {IMAGE: "ubuntu-rolling", TOXENV: "py310", RUNNER: "ubuntu-latest"} @@ -182,7 +181,6 @@ jobs: run: mkdir -p "${HOME}/.cache/pip" - run: | echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV - echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage - run: '/venv/bin/tox -vvv --notest' @@ -373,11 +371,11 @@ jobs: - {OS: 'macos-12', ARCH: 'x86_64'} - {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} PYTHON: - - {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""} - - {VERSION: "3.11", TOXENV: "py311", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"} + - {VERSION: "3.6", TOXENV: "py36-nocoverage"} + - {VERSION: "3.11", TOXENV: "py311"} exclude: # We only test latest Python on arm64. The py36 won't work since there's no universal2 binary - - PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""} + - PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage"} RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 @@ -420,11 +418,10 @@ jobs: run: | OPENSSL_DIR=$(readlink -f ../openssl-macos-universal2/) \ OPENSSL_STATIC=1 \ - CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \ + CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12" \ tox -vvv --notest env: TOXENV: ${{ matrix.PYTHON.TOXENV }} - EXTRA_CFLAGS: ${{ matrix.PYTHON.EXTRA_CFLAGS }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof @@ -443,8 +440,8 @@ jobs: - {ARCH: 'x86', WINDOWS: 'win32'} - {ARCH: 'x64', WINDOWS: 'win64'} PYTHON: - - {VERSION: "3.6", TOXENV: "py36-nocoverage", CL_FLAGS: ""} - - {VERSION: "3.11", TOXENV: "py311", CL_FLAGS: "/D USE_OSRANDOM_RNG_FOR_TESTING"} + - {VERSION: "3.6", TOXENV: "py36-nocoverage"} + - {VERSION: "3.11", TOXENV: "py311"} JOB_NUMBER: [0, 1] name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 @@ -481,7 +478,6 @@ jobs: - name: Configure run: | echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV - echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV shell: bash - name: Clone wycheproof diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5afb57d52a33..40426a6745a0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,9 @@ Changelog .. note:: This version is not yet released and is under active development. +* **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been + removed. Users on older version of OpenSSL will need to upgrade. + .. _v40-0-0: 40.0.0 - 2023-03-24 diff --git a/LICENSE b/LICENSE index 07074259b61a..b11f379efe15 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,3 @@ This software is made available under the terms of *either* of the licenses found in LICENSE.APACHE or LICENSE.BSD. Contributions to cryptography are made under the terms of *both* these licenses. - -The code used in the OS random engine is derived from CPython, and is licensed -under the terms of the PSF License Agreement. diff --git a/LICENSE.PSF b/LICENSE.PSF deleted file mode 100644 index 4d3a4f57dea9..000000000000 --- a/LICENSE.PSF +++ /dev/null @@ -1,41 +0,0 @@ -1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and - the Individual or Organization ("Licensee") accessing and otherwise using Python - 2.7.12 software in source or binary form and its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, PSF hereby - grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, - analyze, test, perform and/or display publicly, prepare derivative works, - distribute, and otherwise use Python 2.7.12 alone or in any derivative - version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2016 Python Software Foundation; All Rights - Reserved" are retained in Python 2.7.12 alone or in any derivative version - prepared by Licensee. - -3. In the event Licensee prepares a derivative work that is based on or - incorporates Python 2.7.12 or any part thereof, and wants to make the - derivative work available to others as provided herein, then Licensee hereby - agrees to include in any such work a brief summary of the changes made to Python - 2.7.12. - -4. PSF is making Python 2.7.12 available to Licensee on an "AS IS" basis. - PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF - EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR - WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE - USE OF PYTHON 2.7.12 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. - -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7.12 - FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF - MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7.12, OR ANY DERIVATIVE - THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material breach of - its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any relationship - of agency, partnership, or joint venture between PSF and Licensee. This License - Agreement does not grant permission to use PSF trademarks or trade name in a - trademark sense to endorse or promote products or services of Licensee, or any - third party. - -8. By copying, installing or otherwise using Python 2.7.12, Licensee agrees - to be bound by the terms and conditions of this License Agreement. diff --git a/MANIFEST.in b/MANIFEST.in index 995e3b0cedc2..c171033124b4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,7 +3,6 @@ include CONTRIBUTING.rst include LICENSE include LICENSE.APACHE include LICENSE.BSD -include LICENSE.PSF include README.rst include tox.ini diff --git a/docs/openssl.rst b/docs/openssl.rst index edf185d2e10e..d4e69f4c86f6 100644 --- a/docs/openssl.rst +++ b/docs/openssl.rst @@ -10,8 +10,8 @@ A list of supported versions can be found in our :doc:`/installation` documentation. In general the backend should be considered an internal implementation detail -of the project, but there are some public methods available for more advanced -control. +of the project, but there are some public methods available for debugging +purposes. .. data:: cryptography.hazmat.backends.openssl.backend @@ -29,21 +29,6 @@ control. typically shown in hexadecimal (e.g. ``0x1010003f``). This is not necessarily the same version as it was compiled against. - .. method:: activate_osrandom_engine() - - Activates the OS random engine. This will effectively disable OpenSSL's - default CSPRNG. - - .. method:: osrandom_engine_implementation() - - .. versionadded:: 1.7 - - Returns the implementation of OS random engine. - - .. method:: activate_builtin_random() - - This will activate the default OpenSSL CSPRNG. - .. _legacy-provider: Legacy provider in OpenSSL 3.x @@ -56,68 +41,5 @@ disable the legacy provider in OpenSSL 3.x. This will disable legacy cryptographic algorithms, including ``Blowfish``, ``CAST5``, ``SEED``, ``ARC4``, and ``RC2`` (which is used by some encrypted serialization formats). -OS random engine ----------------- - -.. note:: - - As of OpenSSL 1.1.1d its CSPRNG is fork-safe by default. - ``cryptography`` does not compile or load the custom engine on - >= 1.1.1d. - -By default OpenSSL uses a user-space CSPRNG that is seeded from system random ( -``/dev/urandom`` or ``CryptGenRandom``). This CSPRNG is not reseeded -automatically when a process calls ``fork()``. This can result in situations -where two different processes can return similar or identical keys and -compromise the security of the system. - -The approach this project has chosen to mitigate this vulnerability is to -include an engine that replaces the OpenSSL default CSPRNG with one that -sources its entropy from ``/dev/urandom`` on UNIX-like operating systems and -uses ``CryptGenRandom`` on Windows. This method of pulling from the system pool -allows us to avoid potential issues with `initializing the RNG`_ as well as -protecting us from the ``fork()`` weakness. - -This engine is **active** by default when importing the OpenSSL backend. When -active this engine will be used to generate all the random data OpenSSL -requests. - -When importing only the binding it is added to the engine list but -**not activated**. - - -OS random sources ------------------ - -On macOS and FreeBSD ``/dev/urandom`` is an alias for ``/dev/random``. The -implementation on macOS uses the `Yarrow`_ algorithm. FreeBSD uses the -`Fortuna`_ algorithm. - -On Windows the implementation of ``CryptGenRandom`` depends on which version of -the operation system you are using. See the `Microsoft documentation`_ for more -details. - -Linux uses its own PRNG design. ``/dev/urandom`` is a non-blocking source -seeded from the same pool as ``/dev/random``. - -+------------------------------------------+------------------------------+ -| Windows | ``CryptGenRandom()`` | -+------------------------------------------+------------------------------+ -| Linux >= 3.17 with working | ``getrandom()`` | -| ``SYS_getrandom`` syscall | | -+------------------------------------------+------------------------------+ -| OpenBSD >= 5.6 | ``getentropy()`` | -+------------------------------------------+------------------------------+ -| BSD family (including macOS 10.12+) with | ``getentropy()`` | -| ``SYS_getentropy`` in ``sys/syscall.h`` | | -+------------------------------------------+------------------------------+ -| fallback | ``/dev/urandom`` with | -| | cached file descriptor | -+------------------------------------------+------------------------------+ - .. _`OpenSSL`: https://www.openssl.org/ -.. _`initializing the RNG`: https://en.wikipedia.org/wiki/OpenSSL#Predictable_private_keys_.28Debian-specific.29 -.. _`Fortuna`: https://en.wikipedia.org/wiki/Fortuna_(PRNG) -.. _`Yarrow`: https://en.wikipedia.org/wiki/Yarrow_algorithm -.. _`Microsoft documentation`: https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptgenrandom diff --git a/setup.cfg b/setup.cfg index 172ac932ae31..416206fb271a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,7 +4,7 @@ version = attr: cryptography.__version__ description = cryptography is a package which provides cryptographic recipes and primitives to Python developers. long_description = file: README.rst long_description_content_type = text/x-rst -license = (Apache-2.0 OR BSD-3-Clause) AND PSF-2.0 +license = Apache-2.0 OR BSD-3-Clause url = https://github.com/pyca/cryptography author = The Python Cryptographic Authority and individual contributors author_email = cryptography-dev@python.org diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index 5f191ce2ed40..e971fd955882 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -100,7 +100,6 @@ def _extra_compile_args(platform): "nid", "objects", "opensslv", - "osrandom_engine", "pem", "pkcs12", "rand", diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py index 6a79091c81c4..40e6ce9846fd 100644 --- a/src/_cffi_src/openssl/cryptography.py +++ b/src/_cffi_src/openssl/cryptography.py @@ -52,40 +52,25 @@ #define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 (0) #endif -#if OPENSSL_VERSION_NUMBER < 0x10101000 - #error "pyca/cryptography MUST be linked with Openssl 1.1.1 or later" +#if OPENSSL_VERSION_NUMBER < 0x10101040 + #error "pyca/cryptography MUST be linked with Openssl 1.1.1d or later" #endif -#define CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER \ - (OPENSSL_VERSION_NUMBER >= 0x10101040 && !CRYPTOGRAPHY_IS_LIBRESSL) #define CRYPTOGRAPHY_OPENSSL_300_OR_GREATER \ (OPENSSL_VERSION_NUMBER >= 0x30000000 && !CRYPTOGRAPHY_IS_LIBRESSL) -#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B \ - (OPENSSL_VERSION_NUMBER < 0x10101020 || CRYPTOGRAPHY_IS_LIBRESSL) -#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D \ - (OPENSSL_VERSION_NUMBER < 0x10101040 || CRYPTOGRAPHY_IS_LIBRESSL) #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E \ (OPENSSL_VERSION_NUMBER < 0x10101050 || CRYPTOGRAPHY_IS_LIBRESSL) -#if (CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D && !CRYPTOGRAPHY_IS_LIBRESSL && \ - !defined(OPENSSL_NO_ENGINE)) || defined(USE_OSRANDOM_RNG_FOR_TESTING) -#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 1 -#else -#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 0 -#endif -/* Ed25519 support is available from OpenSSL 1.1.1b and LibreSSL 3.7.0. */ +/* Ed25519 support is in all supported OpenSSLs as well as LibreSSL 3.7.0. */ #define CRYPTOGRAPHY_HAS_WORKING_ED25519 \ - (!CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B || \ + (!CRYPTOGRAPHY_IS_LIBRESSL || \ (CRYPTOGRAPHY_IS_LIBRESSL && !CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370)) """ TYPES = """ -static const int CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER; static const int CRYPTOGRAPHY_OPENSSL_300_OR_GREATER; -static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B; static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E; -static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE; static const int CRYPTOGRAPHY_HAS_WORKING_ED25519; static const int CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370; diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index be8c0774c945..ebe6c3559837 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -49,7 +49,7 @@ #define ERR_LIB_PROV 0 #endif -#if !CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER || CRYPTOGRAPHY_IS_BORINGSSL +#ifndef EVP_R_XTS_DUPLICATED_KEYS static const int EVP_R_XTS_DUPLICATED_KEYS = 0; #endif diff --git a/src/_cffi_src/openssl/osrandom_engine.py b/src/_cffi_src/openssl/osrandom_engine.py deleted file mode 100644 index dbc304b399c7..000000000000 --- a/src/_cffi_src/openssl/osrandom_engine.py +++ /dev/null @@ -1,23 +0,0 @@ -# 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. - - -import os - -HERE = os.path.dirname(os.path.abspath(__file__)) - -with open(os.path.join(HERE, "src/osrandom_engine.h")) as f: - INCLUDES = f.read() - -TYPES = """ -static const char *const Cryptography_osrandom_engine_name; -static const char *const Cryptography_osrandom_engine_id; -""" - -FUNCTIONS = """ -int Cryptography_add_osrandom_engine(void); -""" - -with open(os.path.join(HERE, "src/osrandom_engine.c")) as f: - CUSTOMIZATIONS = f.read() diff --git a/src/_cffi_src/openssl/src/osrandom_engine.c b/src/_cffi_src/openssl/src/osrandom_engine.c deleted file mode 100644 index 257fcd50968f..000000000000 --- a/src/_cffi_src/openssl/src/osrandom_engine.c +++ /dev/null @@ -1,627 +0,0 @@ -/* osurandom engine - * - * Windows CryptGenRandom() - * macOS >= 10.12 getentropy() - * OpenBSD 5.6+ getentropy() - * other BSD getentropy() if SYS_getentropy is defined - * Linux 3.17+ getrandom() with fallback to /dev/urandom - * other /dev/urandom with cached fd - * - * The /dev/urandom, getrandom and getentropy code is derived from Python's - * Python/random.c, written by Antoine Pitrou and Victor Stinner. - * - * Copyright 2001-2016 Python Software Foundation; All Rights Reserved. - */ - -#ifdef __linux__ -#include -#endif - -#if CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE -/* OpenSSL has ENGINE support and is older than 1.1.1d (the first version that - * properly implements fork safety in its RNG) so build the engine. */ -static const char *Cryptography_osrandom_engine_id = "osrandom"; - -/**************************************************************************** - * Windows - */ -#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM -static const char *Cryptography_osrandom_engine_name = "osrandom_engine CryptGenRandom()"; -static HCRYPTPROV hCryptProv = 0; - -static int osrandom_init(ENGINE *e) { - if (hCryptProv != 0) { - return 1; - } - if (CryptAcquireContext(&hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - return 1; - } else { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_INIT, - CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT, - __FILE__, __LINE__ - ); - return 0; - } -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - if (hCryptProv == 0) { - return 0; - } - - if (!CryptGenRandom(hCryptProv, (DWORD)size, buffer)) { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES, - CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM, - __FILE__, __LINE__ - ); - return 0; - } - return 1; -} - -static int osrandom_finish(ENGINE *e) { - if (CryptReleaseContext(hCryptProv, 0)) { - hCryptProv = 0; - return 1; - } else { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_FINISH, - CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT, - __FILE__, __LINE__ - ); - return 0; - } -} - -static int osrandom_rand_status(void) { - return hCryptProv != 0; -} - -static const char *osurandom_get_implementation(void) { - return "CryptGenRandom"; -} - -#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM */ - -/**************************************************************************** - * /dev/urandom helpers for all non-BSD Unix platforms - */ -#ifdef CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM - -static struct { - int fd; - dev_t st_dev; - ino_t st_ino; -} urandom_cache = { -1 }; - -static int open_cloexec(const char *path) { - int open_flags = O_RDONLY; -#ifdef O_CLOEXEC - open_flags |= O_CLOEXEC; -#endif - - int fd = open(path, open_flags); - if (fd == -1) { - return -1; - } - -#ifndef O_CLOEXEC - int flags = fcntl(fd, F_GETFD); - if (flags == -1) { - return -1; - } - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { - return -1; - } -#endif - return fd; -} - -#ifdef __linux__ -/* On Linux, we open("/dev/random") and use poll() to wait until it's readable - * before we read from /dev/urandom, this ensures that we don't read from - * /dev/urandom before the kernel CSPRNG is initialized. This isn't necessary on - * other platforms because they don't have the same _bug_ as Linux does with - * /dev/urandom and early boot. */ -static int wait_on_devrandom(void) { - struct pollfd pfd = {}; - int ret = 0; - int random_fd = open_cloexec("/dev/random"); - if (random_fd < 0) { - return -1; - } - pfd.fd = random_fd; - pfd.events = POLLIN; - pfd.revents = 0; - do { - ret = poll(&pfd, 1, -1); - } while (ret < 0 && (errno == EINTR || errno == EAGAIN)); - close(random_fd); - return ret; -} -#endif - -/* return -1 on error */ -static int dev_urandom_fd(void) { - int fd = -1; - struct stat st; - - /* Check that fd still points to the correct device */ - if (urandom_cache.fd >= 0) { - if (fstat(urandom_cache.fd, &st) - || st.st_dev != urandom_cache.st_dev - || st.st_ino != urandom_cache.st_ino) { - /* Somebody replaced our FD. Invalidate our cache but don't - * close the fd. */ - urandom_cache.fd = -1; - } - } - if (urandom_cache.fd < 0) { -#ifdef __linux__ - if (wait_on_devrandom() < 0) { - goto error; - } -#endif - - fd = open_cloexec("/dev/urandom"); - if (fd < 0) { - goto error; - } - if (fstat(fd, &st)) { - goto error; - } - /* Another thread initialized the fd */ - if (urandom_cache.fd >= 0) { - close(fd); - return urandom_cache.fd; - } - urandom_cache.st_dev = st.st_dev; - urandom_cache.st_ino = st.st_ino; - urandom_cache.fd = fd; - } - return urandom_cache.fd; - - error: - if (fd != -1) { - close(fd); - } - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD, - CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED, - __FILE__, __LINE__ - ); - return -1; -} - -static int dev_urandom_read(unsigned char *buffer, int size) { - int fd; - int n; - - fd = dev_urandom_fd(); - if (fd < 0) { - return 0; - } - - while (size > 0) { - do { - n = (int)read(fd, buffer, (size_t)size); - } while (n < 0 && errno == EINTR); - - if (n <= 0) { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ, - CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED, - __FILE__, __LINE__ - ); - return 0; - } - buffer += n; - size -= n; - } - return 1; -} - -static void dev_urandom_close(void) { - if (urandom_cache.fd >= 0) { - int fd; - struct stat st; - - if (fstat(urandom_cache.fd, &st) - && st.st_dev == urandom_cache.st_dev - && st.st_ino == urandom_cache.st_ino) { - fd = urandom_cache.fd; - urandom_cache.fd = -1; - close(fd); - } - } -} -#endif /* CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM */ - -/**************************************************************************** - * BSD getentropy - */ -#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY -static const char *Cryptography_osrandom_engine_name = "osrandom_engine getentropy()"; - -static int osrandom_init(ENGINE *e) { - return 1; -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - int len; - int res; - - while (size > 0) { - /* OpenBSD and macOS restrict maximum buffer size to 256. */ - len = size > 256 ? 256 : size; - res = getentropy(buffer, (size_t)len); - if (res < 0) { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES, - CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED, - __FILE__, __LINE__ - ); - return 0; - } - buffer += len; - size -= len; - } - return 1; -} - -static int osrandom_finish(ENGINE *e) { - return 1; -} - -static int osrandom_rand_status(void) { - return 1; -} - -static const char *osurandom_get_implementation(void) { - return "getentropy"; -} -#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY */ - -/**************************************************************************** - * Linux getrandom engine with fallback to dev_urandom - */ - -#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM -static const char *Cryptography_osrandom_engine_name = "osrandom_engine getrandom()"; - -static int getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT; - -static int osrandom_init(ENGINE *e) { - /* We try to detect working getrandom until we succeed. */ - if (getrandom_works != CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS) { - long n; - char dest[1]; - /* if the kernel CSPRNG is not initialized this will block */ - n = syscall(SYS_getrandom, dest, sizeof(dest), 0); - if (n == sizeof(dest)) { - getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS; - } else { - int e = errno; - switch(e) { - case ENOSYS: - /* Fallback: Kernel does not support the syscall. */ - getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK; - break; - case EPERM: - /* Fallback: seccomp prevents syscall */ - getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK; - break; - default: - /* EINTR cannot occur for buflen < 256. */ - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_INIT, - CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED, - "errno", e - ); - getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED; - break; - } - } - } - - /* fallback to dev urandom */ - if (getrandom_works == CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK) { - int fd = dev_urandom_fd(); - if (fd < 0) { - return 0; - } - } - return 1; -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - long n; - - switch(getrandom_works) { - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED: - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES, - CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED, - __FILE__, __LINE__ - ); - return 0; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT: - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES, - CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT, - __FILE__, __LINE__ - ); - return 0; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK: - return dev_urandom_read(buffer, size); - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS: - while (size > 0) { - do { - n = syscall(SYS_getrandom, buffer, size, 0); - } while (n < 0 && errno == EINTR); - - if (n <= 0) { - ERR_Cryptography_OSRandom_error( - CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES, - CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED, - __FILE__, __LINE__ - ); - return 0; - } - buffer += n; - size -= (int)n; - } - return 1; - } - __builtin_unreachable(); -} - -static int osrandom_finish(ENGINE *e) { - dev_urandom_close(); - return 1; -} - -static int osrandom_rand_status(void) { - switch(getrandom_works) { - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED: - return 0; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT: - return 0; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK: - return urandom_cache.fd >= 0; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS: - return 1; - } - __builtin_unreachable(); -} - -static const char *osurandom_get_implementation(void) { - switch(getrandom_works) { - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED: - return ""; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT: - return ""; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK: - return "/dev/urandom"; - case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS: - return "getrandom"; - } - __builtin_unreachable(); -} -#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM */ - -/**************************************************************************** - * dev_urandom engine for all remaining platforms - */ - -#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM -static const char *Cryptography_osrandom_engine_name = "osrandom_engine /dev/urandom"; - -static int osrandom_init(ENGINE *e) { - int fd = dev_urandom_fd(); - if (fd < 0) { - return 0; - } - return 1; -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - return dev_urandom_read(buffer, size); -} - -static int osrandom_finish(ENGINE *e) { - dev_urandom_close(); - return 1; -} - -static int osrandom_rand_status(void) { - return urandom_cache.fd >= 0; -} - -static const char *osurandom_get_implementation(void) { - return "/dev/urandom"; -} -#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM */ - -/**************************************************************************** - * ENGINE boiler plate - */ - -/* This replicates the behavior of the OpenSSL FIPS RNG, which returns a - -1 in the event that there is an error when calling RAND_pseudo_bytes. */ -static int osrandom_pseudo_rand_bytes(unsigned char *buffer, int size) { - int res = osrandom_rand_bytes(buffer, size); - if (res == 0) { - return -1; - } else { - return res; - } -} - -static RAND_METHOD osrandom_rand = { - NULL, - osrandom_rand_bytes, - NULL, - NULL, - osrandom_pseudo_rand_bytes, - osrandom_rand_status, -}; - -static const ENGINE_CMD_DEFN osrandom_cmd_defns[] = { - {CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION, - "get_implementation", - "Get CPRNG implementation.", - ENGINE_CMD_FLAG_NO_INPUT}, - {0, NULL, NULL, 0} -}; - -static int osrandom_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) { - const char *name; - size_t len; - - switch (cmd) { - case CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION: - /* i: buffer size, p: char* buffer */ - name = osurandom_get_implementation(); - len = strlen(name); - if ((p == NULL) && (i == 0)) { - /* return required buffer len */ - return (int)len; - } - if ((p == NULL) || i < 0 || ((size_t)i <= len)) { - /* no buffer or buffer too small */ - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_INVALID_ARGUMENT); - return 0; - } - strcpy((char *)p, name); - return (int)len; - default: - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; - } -} - -/* error reporting */ -#define ERR_FUNC(func) ERR_PACK(0, func, 0) -#define ERR_REASON(reason) ERR_PACK(0, 0, reason) - -static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_lib_name[] = { - {0, "osrandom_engine"}, - {0, NULL} -}; - -static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_str_funcs[] = { - {ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_INIT), - "osrandom_init"}, - {ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES), - "osrandom_rand_bytes"}, - {ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_FINISH), - "osrandom_finish"}, - {ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD), - "dev_urandom_fd"}, - {ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ), - "dev_urandom_read"}, - {0, NULL} -}; - -static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_str_reasons[] = { - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT), - "CryptAcquireContext() failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM), - "CryptGenRandom() failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT), - "CryptReleaseContext() failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED), - "getentropy() failed"}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED), - "open('/dev/urandom') failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED), - "Reading from /dev/urandom fd failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED), - "getrandom() initialization failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED), - "getrandom() initialization failed with unexpected errno."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED), - "getrandom() syscall failed."}, - {ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT), - "getrandom() engine was not properly initialized."}, - {0, NULL} -}; - -static int Cryptography_OSRandom_lib_error_code = 0; - -static void ERR_load_Cryptography_OSRandom_strings(void) -{ - if (Cryptography_OSRandom_lib_error_code == 0) { - Cryptography_OSRandom_lib_error_code = ERR_get_next_error_library(); - ERR_load_strings(Cryptography_OSRandom_lib_error_code, - CRYPTOGRAPHY_OSRANDOM_lib_name); - ERR_load_strings(Cryptography_OSRandom_lib_error_code, - CRYPTOGRAPHY_OSRANDOM_str_funcs); - ERR_load_strings(Cryptography_OSRandom_lib_error_code, - CRYPTOGRAPHY_OSRANDOM_str_reasons); - } -} - -static void ERR_Cryptography_OSRandom_error(int function, int reason, - char *file, int line) -{ - ERR_PUT_error(Cryptography_OSRandom_lib_error_code, function, reason, - file, line); -} - -/* Returns 1 if successfully added, 2 if engine has previously been added, - and 0 for error. */ -int Cryptography_add_osrandom_engine(void) { - ENGINE *e; - - ERR_load_Cryptography_OSRandom_strings(); - - e = ENGINE_by_id(Cryptography_osrandom_engine_id); - if (e != NULL) { - ENGINE_free(e); - return 2; - } else { - ERR_clear_error(); - } - - e = ENGINE_new(); - if (e == NULL) { - return 0; - } - if (!ENGINE_set_id(e, Cryptography_osrandom_engine_id) || - !ENGINE_set_name(e, Cryptography_osrandom_engine_name) || - !ENGINE_set_RAND(e, &osrandom_rand) || - !ENGINE_set_init_function(e, osrandom_init) || - !ENGINE_set_finish_function(e, osrandom_finish) || - !ENGINE_set_cmd_defns(e, osrandom_cmd_defns) || - !ENGINE_set_ctrl_function(e, osrandom_ctrl)) { - ENGINE_free(e); - return 0; - } - if (!ENGINE_add(e)) { - ENGINE_free(e); - return 0; - } - if (!ENGINE_free(e)) { - return 0; - } - - return 1; -} - -#else -/* If OpenSSL has no ENGINE support then we don't want - * to compile the osrandom engine, but we do need some - * placeholders */ -static const char *Cryptography_osrandom_engine_id = "no-engine-support"; -static const char *Cryptography_osrandom_engine_name = "osrandom_engine disabled"; - -int Cryptography_add_osrandom_engine(void) { - return 0; -} - -#endif diff --git a/src/_cffi_src/openssl/src/osrandom_engine.h b/src/_cffi_src/openssl/src/osrandom_engine.h deleted file mode 100644 index 89e45265186f..000000000000 --- a/src/_cffi_src/openssl/src/osrandom_engine.h +++ /dev/null @@ -1,116 +0,0 @@ -#if CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE -/* OpenSSL has ENGINE support so include all of this. */ -#ifdef _WIN32 - #include -#else - #include - #include - /* for defined(BSD) */ - #ifndef __MVS__ - #include - #endif - - #ifdef BSD - /* for SYS_getentropy */ - #include - #endif - - #ifdef __APPLE__ - #include - /* To support weak linking we need to declare this as a weak import even if - * it's not present in sys/random (e.g. macOS < 10.12). */ - extern int getentropy(void *buffer, size_t size) __attribute((weak_import)); - #endif - - #ifdef __linux__ - /* for SYS_getrandom */ - #include - #ifndef GRND_NONBLOCK - #define GRND_NONBLOCK 0x0001 - #endif /* GRND_NONBLOCK */ - - #ifndef SYS_getrandom - /* We only bother to define the constants for platforms where we ship - * wheels, since that's the predominant way you get a situation where - * you don't have SYS_getrandom at compile time but do have the syscall - * at runtime */ - #if defined(__x86_64__) - #define SYS_getrandom 318 - #elif defined(__i386__) - #define SYS_getrandom 355 - #elif defined(__aarch64__) - #define SYS_getrandom 278 - #endif - #endif - #endif /* __linux__ */ -#endif /* _WIN32 */ - -#define CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM 1 -#define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY 2 -#define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM 3 -#define CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM 4 - -#ifndef CRYPTOGRAPHY_OSRANDOM_ENGINE - #if defined(_WIN32) - /* Windows */ - #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM - #elif defined(BSD) && defined(SYS_getentropy) - /* OpenBSD 5.6+ & macOS with SYS_getentropy defined, although < 10.12 will fallback - * to urandom */ - #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY - #elif defined(__linux__) && defined(SYS_getrandom) - /* Linux 3.17+ */ - #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM - #else - /* Keep this as last entry, fall back to /dev/urandom */ - #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM - #endif -#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE */ - -/* Fallbacks need /dev/urandom helper functions. */ -#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM || \ - CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM - #define CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM 1 -#endif - -enum { - CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED = -2, - CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT, - CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK, - CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS -}; - -enum { - CRYPTOGRAPHY_OSRANDOM_GETENTROPY_NOT_INIT, - CRYPTOGRAPHY_OSRANDOM_GETENTROPY_FALLBACK, - CRYPTOGRAPHY_OSRANDOM_GETENTROPY_WORKS -}; - -/* engine ctrl */ -#define CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION ENGINE_CMD_BASE - -/* error reporting */ -static void ERR_load_Cryptography_OSRandom_strings(void); -static void ERR_Cryptography_OSRandom_error(int function, int reason, - char *file, int line); - -#define CRYPTOGRAPHY_OSRANDOM_F_INIT 100 -#define CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES 101 -#define CRYPTOGRAPHY_OSRANDOM_F_FINISH 102 -#define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD 300 -#define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ 301 - -#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT 100 -#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM 101 -#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT 102 - -#define CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED 200 - -#define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED 300 -#define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED 301 - -#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED 400 -#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED 402 -#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED 403 -#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT 404 -#endif diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 53e3486c0da2..facdb48a03a8 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -7,7 +7,6 @@ import contextlib import itertools import typing -import warnings from contextlib import contextmanager from cryptography import utils, x509 @@ -185,13 +184,6 @@ def __init__(self) -> None: typing.Callable, ] = {} self._register_default_ciphers() - if self._fips_enabled and self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE: - warnings.warn( - "OpenSSL FIPS mode is enabled. Can't enable DRBG fork safety.", - UserWarning, - ) - else: - self.activate_osrandom_engine() self._dh_types = [self._lib.EVP_PKEY_DH] if self._lib.Cryptography_HAS_EVP_PKEY_DHX: self._dh_types.append(self._lib.EVP_PKEY_DHX) @@ -230,60 +222,6 @@ def _enable_fips(self) -> None: assert self._is_fips_enabled() self._fips_enabled = self._is_fips_enabled() - def activate_builtin_random(self) -> None: - if self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE: - # Obtain a new structural reference. - e = self._lib.ENGINE_get_default_RAND() - if e != self._ffi.NULL: - self._lib.ENGINE_unregister_RAND(e) - # Reset the RNG to use the built-in. - res = self._lib.RAND_set_rand_method(self._ffi.NULL) - self.openssl_assert(res == 1) - # decrement the structural reference from get_default_RAND - res = self._lib.ENGINE_finish(e) - self.openssl_assert(res == 1) - - @contextlib.contextmanager - def _get_osurandom_engine(self): - # Fetches an engine by id and returns it. This creates a structural - # reference. - e = self._lib.ENGINE_by_id(self._lib.Cryptography_osrandom_engine_id) - self.openssl_assert(e != self._ffi.NULL) - # Initialize the engine for use. This adds a functional reference. - res = self._lib.ENGINE_init(e) - self.openssl_assert(res == 1) - - try: - yield e - finally: - # Decrement the structural ref incremented by ENGINE_by_id. - res = self._lib.ENGINE_free(e) - self.openssl_assert(res == 1) - # Decrement the functional ref incremented by ENGINE_init. - res = self._lib.ENGINE_finish(e) - self.openssl_assert(res == 1) - - def activate_osrandom_engine(self) -> None: - if self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE: - # Unregister and free the current engine. - self.activate_builtin_random() - with self._get_osurandom_engine() as e: - # Set the engine as the default RAND provider. - res = self._lib.ENGINE_set_default_RAND(e) - self.openssl_assert(res == 1) - # Reset the RNG to use the engine - res = self._lib.RAND_set_rand_method(self._ffi.NULL) - self.openssl_assert(res == 1) - - def osrandom_engine_implementation(self) -> str: - buf = self._ffi.new("char[]", 64) - with self._get_osurandom_engine() as e: - res = self._lib.ENGINE_ctrl_cmd( - e, b"get_implementation", len(buf), buf, self._ffi.NULL, 0 - ) - self.openssl_assert(res > 0) - return self._ffi.string(buf).decode("ascii") - def openssl_version_text(self) -> str: """ Friendly string name of the loaded OpenSSL library. This is not @@ -1968,7 +1906,7 @@ def ed448_supported(self) -> bool: if self._fips_enabled: return False return ( - not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B + not self._lib.CRYPTOGRAPHY_IS_LIBRESSL and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL ) diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index 075d68fb9057..8d4b8dc3bbf1 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -119,7 +119,7 @@ def __init__( lib = self._backend._lib if res == 0 and ( ( - lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER + not lib.CRYPTOGRAPHY_IS_LIBRESSL and errors[0]._lib_reason_match( lib.ERR_LIB_EVP, lib.EVP_R_XTS_DUPLICATED_KEYS ) diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index c34fc3ae6960..35829a2821da 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -162,7 +162,6 @@ def cryptography_has_engine() -> typing.List[str]: "ENGINE_ctrl_cmd", "ENGINE_free", "ENGINE_get_name", - "Cryptography_add_osrandom_engine", "ENGINE_ctrl_cmd_string", "ENGINE_load_builtin_engines", "ENGINE_load_private_key", diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 7327157fd8d5..99061e21b421 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -10,7 +10,6 @@ import warnings import cryptography -from cryptography import utils from cryptography.exceptions import InternalError from cryptography.hazmat.bindings._rust import _openssl, openssl from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES @@ -98,18 +97,6 @@ def _enable_fips(self) -> None: res = self.lib.EVP_default_properties_enable_fips(self.ffi.NULL, 1) _openssl_assert(self.lib, res == 1) - @classmethod - def _register_osrandom_engine(cls) -> None: - # Clear any errors extant in the queue before we start. In many - # scenarios other things may be interacting with OpenSSL in the same - # process space and it has proven untenable to assume that they will - # reliably clear the error queue. Once we clear it here we will - # error on any subsequent unexpected item in the stack. - cls.lib.ERR_clear_error() - if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE: - result = cls.lib.Cryptography_add_osrandom_engine() - _openssl_assert(cls.lib, result in (1, 2)) - @classmethod def _ensure_ffi_initialized(cls) -> None: with cls._init_lock: @@ -118,7 +105,6 @@ def _ensure_ffi_initialized(cls) -> None: _openssl.lib, CONDITIONAL_NAMES ) cls._lib_loaded = True - cls._register_osrandom_engine() # As of OpenSSL 3.0.0 we must register a legacy cipher provider # to get RC2 (needed for junk asymmetric private key # serialization), RC4, Blowfish, IDEA, SEED, etc. These things @@ -189,20 +175,3 @@ def _verify_package_version(version: str) -> None: UserWarning, stacklevel=2, ) - - -def _verify_openssl_version(lib): - if ( - not lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER - and not lib.CRYPTOGRAPHY_IS_LIBRESSL - and not lib.CRYPTOGRAPHY_IS_BORINGSSL - ): - warnings.warn( - "Support for OpenSSL less than version 1.1.1d is deprecated and " - "the next release of cryptography will drop support. Please " - "upgrade your OpenSSL to version 1.1.1d or newer.", - utils.DeprecatedIn40, - ) - - -_verify_openssl_version(Binding.lib) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 6f3f4a2bf508..572431ebbd4a 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -5,9 +5,6 @@ import itertools import os -import subprocess -import sys -import textwrap import pytest @@ -179,158 +176,6 @@ def test_bn_to_int(self): assert backend._bn_to_int(bn) == 0 -@pytest.mark.skipif( - not backend._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE, - reason="Requires OpenSSL with ENGINE support and OpenSSL < 1.1.1d", -) -@pytest.mark.skip_fips(reason="osrandom engine disabled for FIPS") -class TestOpenSSLRandomEngine: - def setup_method(self): - # The default RAND engine is global and shared between - # tests. We make sure that the default engine is osrandom - # before we start each test and restore the global state to - # that engine in teardown. - current_default = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(current_default) - assert name == backend._lib.Cryptography_osrandom_engine_name - - def teardown_method(self): - # we need to reset state to being default. backend is a shared global - # for all these tests. - backend.activate_osrandom_engine() - current_default = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(current_default) - assert name == backend._lib.Cryptography_osrandom_engine_name - - @pytest.mark.skipif( - sys.executable is None, reason="No Python interpreter available." - ) - def test_osrandom_engine_is_default(self, tmpdir): - engine_printer = textwrap.dedent( - """ - import sys - from cryptography.hazmat.backends.openssl.backend import backend - - e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - sys.stdout.write(backend._ffi.string(name).decode('ascii')) - res = backend._lib.ENGINE_free(e) - assert res == 1 - """ - ) - engine_name = tmpdir.join("engine_name") - - # If we're running tests via ``python setup.py test`` in a clean - # environment then all of our dependencies are going to be installed - # into either the current directory or the .eggs directory. However the - # subprocess won't know to activate these dependencies, so we'll get it - # to do so by passing our entire sys.path into the subprocess via the - # PYTHONPATH environment variable. - env = os.environ.copy() - env["PYTHONPATH"] = os.pathsep.join(sys.path) - - with engine_name.open("w") as out: - subprocess.check_call( - [sys.executable, "-c", engine_printer], - env=env, - stdout=out, - stderr=subprocess.PIPE, - ) - - osrandom_engine_name = backend._ffi.string( - backend._lib.Cryptography_osrandom_engine_name - ) - - assert engine_name.read().encode("ascii") == osrandom_engine_name - - def test_osrandom_sanity_check(self): - # This test serves as a check against catastrophic failure. - buf = backend._ffi.new("unsigned char[]", 500) - res = backend._lib.RAND_bytes(buf, 500) - assert res == 1 - assert backend._ffi.buffer(buf)[:] != "\x00" * 500 - - def test_activate_osrandom_no_default(self): - backend.activate_builtin_random() - e = backend._lib.ENGINE_get_default_RAND() - assert e == backend._ffi.NULL - backend.activate_osrandom_engine() - e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name - res = backend._lib.ENGINE_free(e) - assert res == 1 - - def test_activate_builtin_random(self): - e = backend._lib.ENGINE_get_default_RAND() - assert e != backend._ffi.NULL - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name - res = backend._lib.ENGINE_free(e) - assert res == 1 - backend.activate_builtin_random() - e = backend._lib.ENGINE_get_default_RAND() - assert e == backend._ffi.NULL - - def test_activate_builtin_random_already_active(self): - backend.activate_builtin_random() - e = backend._lib.ENGINE_get_default_RAND() - assert e == backend._ffi.NULL - backend.activate_builtin_random() - e = backend._lib.ENGINE_get_default_RAND() - assert e == backend._ffi.NULL - - def test_osrandom_engine_implementation(self): - name = backend.osrandom_engine_implementation() - assert name in [ - "/dev/urandom", - "CryptGenRandom", - "getentropy", - "getrandom", - ] - if sys.platform.startswith("linux"): - assert name in ["getrandom", "/dev/urandom"] - if sys.platform == "darwin": - assert name in ["getentropy"] - if sys.platform == "win32": - assert name == "CryptGenRandom" - - def test_activate_osrandom_already_default(self): - e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name - res = backend._lib.ENGINE_free(e) - assert res == 1 - backend.activate_osrandom_engine() - e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name - res = backend._lib.ENGINE_free(e) - assert res == 1 - - -@pytest.mark.skipif( - backend._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE, - reason="Requires OpenSSL without ENGINE support or OpenSSL >=1.1.1d", -) -class TestOpenSSLNoEngine: - def test_no_engine_support(self): - assert ( - backend._ffi.string(backend._lib.Cryptography_osrandom_engine_id) - == b"no-engine-support" - ) - assert ( - backend._ffi.string(backend._lib.Cryptography_osrandom_engine_name) - == b"osrandom_engine disabled" - ) - - def test_activate_builtin_random_does_nothing(self): - backend.activate_builtin_random() - - def test_activate_osrandom_does_nothing(self): - backend.activate_osrandom_engine() - - class TestOpenSSLRSA: def test_generate_rsa_parameters_supported(self): assert backend.generate_rsa_parameters_supported(1, 1024) is False diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 118b850ee3ff..c061c9bf11b0 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -21,11 +21,6 @@ def test_binding_loads(self): assert binding.lib assert binding.ffi - def test_add_engine_more_than_once(self): - b = Binding() - b._register_osrandom_engine() - assert b.lib.ERR_get_error() == 0 - def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() @@ -85,18 +80,6 @@ def test_openssl_assert_error_on_stack(self): if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b"data not multiple of block length" in error.reason_text - def test_check_startup_errors_are_allowed(self): - b = Binding() - b.lib.ERR_put_error( - b.lib.ERR_LIB_EVP, - b.lib.EVP_F_EVP_ENCRYPTFINAL_EX, - b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, - b"", - -1, - ) - b._register_osrandom_engine() - assert rust_openssl.capture_error_stack() == [] - def test_version_mismatch(self): with pytest.raises(ImportError): _verify_package_version("nottherightversion") diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 5322f8f4afea..1f3dfd0014b4 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -61,9 +61,7 @@ def test_xts_too_short(self, backend): enc.update(b"0" * 15) @pytest.mark.supported( - only_if=lambda backend: ( - backend._lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER - ), + only_if=lambda backend: (not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL), skip_message="duplicate key encryption error added in OpenSSL 1.1.1d", ) def test_xts_no_duplicate_keys_encryption(self, backend): From b5170bf26dcc2834e2279e1e739d94916e5a5fc3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 21:15:13 +0800 Subject: [PATCH 511/827] drop python 3.6 support (#8448) * drop python 3.6 support * Update tests/hazmat/bindings/test_openssl.py Co-authored-by: Alex Gaynor --------- Co-authored-by: Alex Gaynor --- .github/workflows/ci.yml | 10 +++----- .github/workflows/wheel-builder.yml | 20 +++++++-------- CHANGELOG.rst | 1 + README.rst | 2 +- ci-constraints-requirements.txt | 38 ++++++++++++++--------------- docs/installation.rst | 6 ++--- pyproject.toml | 5 ++-- setup.cfg | 6 ++--- setup.py | 3 +-- src/cryptography/__init__.py | 13 ---------- src/rust/build.rs | 4 +-- tests/conftest.py | 6 ----- tox.ini | 4 +-- 13 files changed, 47 insertions(+), 71 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1824b269aa9b..8553a79d16a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,8 +128,6 @@ jobs: fail-fast: false matrix: IMAGE: - - {IMAGE: "rhel8", TOXENV: "py36", RUNNER: "ubuntu-latest"} - - {IMAGE: "rhel8-fips", TOXENV: "py36", RUNNER: "ubuntu-latest", FIPS: true} - {IMAGE: "rhel8", TOXENV: "py38", RUNNER: "ubuntu-latest"} - {IMAGE: "rhel8-fips", TOXENV: "py38", RUNNER: "ubuntu-latest", FIPS: true} - {IMAGE: "buster", TOXENV: "py37", RUNNER: "ubuntu-latest"} @@ -371,11 +369,11 @@ jobs: - {OS: 'macos-12', ARCH: 'x86_64'} - {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} PYTHON: - - {VERSION: "3.6", TOXENV: "py36-nocoverage"} + - {VERSION: "3.7", TOXENV: "py37-nocoverage"} - {VERSION: "3.11", TOXENV: "py311"} exclude: - # We only test latest Python on arm64. The py36 won't work since there's no universal2 binary - - PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage"} + # We only test latest Python on arm64. py37 won't work since there's no universal2 binary + - PYTHON: {VERSION: "3.7", TOXENV: "py37-nocoverage"} RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 @@ -440,7 +438,7 @@ jobs: - {ARCH: 'x86', WINDOWS: 'win32'} - {ARCH: 'x64', WINDOWS: 'win64'} PYTHON: - - {VERSION: "3.6", TOXENV: "py36-nocoverage"} + - {VERSION: "3.7", TOXENV: "py37-nocoverage"} - {VERSION: "3.11", TOXENV: "py311"} JOB_NUMBER: [0, 1] name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 36df9f926a79..1aec8c5cf439 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -58,7 +58,7 @@ jobs: fail-fast: false matrix: PYTHON: - - { VERSION: "cp36-cp36m", ABI_VERSION: 'cp36' } + - { VERSION: "cp37-cp37m", ABI_VERSION: 'cp37' } - { VERSION: "pp38-pypy38_pp73" } - { VERSION: "pp39-pypy39_pp73" } MANYLINUX: @@ -145,11 +145,11 @@ jobs: fail-fast: false matrix: PYTHON: - - VERSION: '3.10' - ABI_VERSION: 'cp36' + - VERSION: '3.11' + ABI_VERSION: 'cp37' # Despite the name, this is built for the macOS 11 SDK on arm64 and 10.9+ on intel - DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.10.9/python-3.10.9-macos11.pkg' - BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.10/bin/python3' + DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.2/python-3.11.2-macos11.pkg' + BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' DEPLOYMENT_TARGET: '10.12' # This archflags is default, but let's be explicit ARCHFLAGS: '-arch x86_64 -arch arm64' @@ -157,10 +157,10 @@ jobs: # This will change in the future as we change the base Python we # build against _PYTHON_HOST_PLATFORM: 'macosx-10.9-universal2' - - VERSION: '3.10' - ABI_VERSION: 'cp36' - DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.10.9/python-3.10.9-macos11.pkg' - BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.10/bin/python3' + - VERSION: '3.11' + ABI_VERSION: 'cp37' + DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.2/python-3.11.2-macos11.pkg' + BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' DEPLOYMENT_TARGET: '10.12' # We continue to build a non-universal2 for a bit to see metrics on # download counts (this is a proxy for pip version since universal2 @@ -249,7 +249,7 @@ jobs: - {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} - {ARCH: 'x64', WINDOWS: 'win64', RUST_TRIPLE: 'x86_64-pc-windows-msvc'} PYTHON: - - {VERSION: "3.8", "ABI_VERSION": "cp36"} + - {VERSION: "3.11", "ABI_VERSION": "cp37"} - {VERSION: "pypy-3.8"} - {VERSION: "pypy-3.9"} exclude: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 40426a6745a0..13ea2ef6e1c3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,7 @@ Changelog * **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been removed. Users on older version of OpenSSL will need to upgrade. +* **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. .. _v40-0-0: diff --git a/README.rst b/README.rst index e03cfcdff8a9..d71765b8dba3 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ pyca/cryptography ``cryptography`` is a package which provides cryptographic recipes and primitives to Python developers. Our goal is for it to be your "cryptographic -standard library". It supports Python 3.6+ and PyPy3 7.3.10+. +standard library". It supports Python 3.7+ and PyPy3 7.3.10+. ``cryptography`` includes both high level recipes and low level interfaces to common cryptographic algorithms such as symmetric ciphers, message digests, and diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7494fbb6d14e..0ae7fa2f88ed 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -24,15 +24,15 @@ certifi==2022.12.7 # via requests chardet==5.1.0 # via tox -charset-normalizer==3.1.0; python_version >= "3.7" +charset-normalizer==3.1.0 # via requests check-manifest==0.49 # via cryptography (setup.cfg) click==8.1.3 # via black -colorama==0.4.6; python_version >= "3.7" +colorama==0.4.6 # via tox -coverage==7.2.2; python_version >= "3.7" +coverage==7.2.2 # via pytest-cov distlib==0.3.6 # via virtualenv @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.3; python_version >= "3.7" +filelock==3.10.3 # via # tox # virtualenv @@ -54,11 +54,11 @@ idna==3.4 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==6.1.0; python_version >= "3.7" +importlib-metadata==6.1.0 # via # keyring # twine -iniconfig==2.0.0; python_version >= "3.7" +iniconfig==2.0.0 # via pytest iso8601==1.1.0 # via cryptography (setup.cfg) @@ -82,7 +82,7 @@ mypy-extensions==1.0.0 # via # black # mypy -packaging==23.0; python_version >= "3.7" +packaging==23.0 # via # black # build @@ -94,12 +94,12 @@ pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine -platformdirs==3.1.1; python_version >= "3.7" +platformdirs==3.1.1 # via # black # tox # virtualenv -pluggy==1.0.0; python_version >= "3.7" +pluggy==1.0.0 # via # pytest # tox @@ -120,7 +120,7 @@ pyproject-api==1.5.1 # via tox pyproject-hooks==1.0.0 # via build -pytest==7.2.2; python_version >= "3.7" +pytest==7.2.2 # via # cryptography (setup.cfg) # pytest-benchmark @@ -129,7 +129,7 @@ pytest==7.2.2; python_version >= "3.7" # pytest-shard # pytest-subtests # pytest-xdist -pytest-benchmark==4.0.0; python_version >= "3.7" +pytest-benchmark==4.0.0 # via cryptography (setup.cfg) pytest-cov==4.0.0 # via cryptography (setup.cfg) @@ -137,16 +137,16 @@ pytest-randomly==3.12.0 # via cryptography (setup.cfg) pytest-shard==0.1.2 # via cryptography (setup.cfg) -pytest-subtests==0.10.0; python_version >= "3.7" +pytest-subtests==0.10.0 # via cryptography (setup.cfg) -pytest-xdist==3.2.1; python_version >= "3.7" +pytest-xdist==3.2.1 # via cryptography (setup.cfg) pytz==2022.7.1 # via # babel readme-renderer==37.3 # via twine -requests==2.28.2; python_version >= "3.7" +requests==2.28.2 # via # requests-toolbelt # sphinx @@ -186,7 +186,7 @@ sphinxcontrib-serializinghtml==1.1.5 # via sphinx sphinxcontrib-spelling==8.0.0 # via cryptography (setup.cfg) -tomli==2.0.1; python_version >= "3.7" +tomli==2.0.1 # via # black # build @@ -197,21 +197,21 @@ tomli==2.0.1; python_version >= "3.7" # pyproject-hooks # pytest # tox -tox==4.4.7; python_version >= "3.7" +tox==4.4.7 # via cryptography (setup.cfg) twine==4.0.2 # via cryptography (setup.cfg) -typing-extensions==4.5.0; python_version >= "3.7" +typing-extensions==4.5.0 # via mypy urllib3==1.26.15 # via # requests # twine -virtualenv==20.21.0; python_version >= "3.7" +virtualenv==20.21.0 # via tox webencodings==0.5.1 # via bleach -zipp==3.15.0; python_version >= "3.7" +zipp==3.15.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/docs/installation.rst b/docs/installation.rst index e659668b26a4..83c8313b9b48 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -13,7 +13,7 @@ single most common cause of installation problems. Supported platforms ------------------- -Currently we test ``cryptography`` on Python 3.6+ and PyPy3 7.3.10+ on these +Currently we test ``cryptography`` on Python 3.7+ and PyPy3 7.3.10+ on these operating systems. * x86-64 RHEL 8.x @@ -21,7 +21,7 @@ operating systems. * x86-64 Fedora (latest) * x86-64 macOS 12 Monterey * ARM64 macOS 13 Ventura -* x86-64 Ubuntu 18.04, 20.04, 22.04, rolling +* x86-64 Ubuntu 20.04, 22.04, rolling * ARM64 Ubuntu 22.04 * x86-64 Debian Buster (10.x), Bullseye (11.x), Bookworm (12.x) and Sid (unstable) @@ -56,7 +56,7 @@ just run If you prefer to compile it yourself you'll need to have OpenSSL installed. You can compile OpenSSL yourself as well or use `a binary distribution`_. Be sure to download the proper version for your architecture and Python -(VC2015 is required for 3.6 and above). Wherever you place your copy of OpenSSL +(VC2015 is required for 3.7 and above). Wherever you place your copy of OpenSSL you'll need to set the ``OPENSSL_DIR`` environment variable to include the proper location. For example: diff --git a/pyproject.toml b/pyproject.toml index 6844bc096894..5ee817601047 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta" [tool.black] line-length = 79 -target-version = ["py36"] +target-version = ["py37"] [tool.pytest.ini_options] addopts = "-r s --capture=no --strict-markers --benchmark-disable --no-subtests-shortletter" @@ -67,8 +67,7 @@ exclude_lines = [ [tool.ruff] # UP006: Minimum Python 3.9 # UP007, UP038: Minimum Python 3.10 -# UP022: Minimum Python 3.7 -ignore = ['N818', 'UP006', 'UP007', 'UP038', 'UP022'] +ignore = ['N818', 'UP006', 'UP007', 'UP038'] select = ['E', 'F', 'I', 'N', 'W', 'UP'] line-length = 79 diff --git a/setup.cfg b/setup.cfg index 416206fb271a..3cdae292d92e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,6 @@ classifiers = Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 @@ -38,7 +37,7 @@ classifiers = Topic :: Security :: Cryptography [options] -python_requires = >=3.6 +python_requires = >=3.7 include_package_data = True zip_safe = False package_dir = @@ -62,8 +61,7 @@ test = pytest-shard>=0.1.2 pytest-benchmark pytest-cov - # pytest-subtests needs >=0.10.0 when we drop py36 support - pytest-subtests + pytest-subtests>=0.10.0 pytest-xdist pretend iso8601 diff --git a/setup.py b/setup.py index e1adff269ed6..2d084d1efbe7 100644 --- a/setup.py +++ b/setup.py @@ -101,8 +101,7 @@ # If for any reason `rustc --version` fails, silently ignore it rustc_output = subprocess.run( ["rustc", "--version"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, timeout=0.5, encoding="utf8", check=True, diff --git a/src/cryptography/__init__.py b/src/cryptography/__init__.py index 7f8a25c6ed9c..ffa979a4ea9d 100644 --- a/src/cryptography/__init__.py +++ b/src/cryptography/__init__.py @@ -2,23 +2,10 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import sys -import warnings - from cryptography.__about__ import __author__, __copyright__, __version__ -from cryptography.utils import CryptographyDeprecationWarning __all__ = [ "__version__", "__author__", "__copyright__", ] - -if sys.version_info[:2] == (3, 6): - warnings.warn( - "Python 3.6 is no longer supported by the Python core team. " - "Therefore, support for it is deprecated in cryptography. The next " - "release of cryptography will remove support for Python 3.6.", - CryptographyDeprecationWarning, - stacklevel=2, - ) diff --git a/src/rust/build.rs b/src/rust/build.rs index 01177ac0e96c..4f0f39aae6b1 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -63,8 +63,8 @@ fn main() { // Enable abi3 mode if we're not using PyPy. if python_impl != "PyPy" { - // cp36 - build.define("Py_LIMITED_API", "0x030600f0"); + // cp37 (Python 3.7 to help our grep when we some day drop 3.7 support) + build.define("Py_LIMITED_API", "0x030700f0"); } if cfg!(windows) { diff --git a/tests/conftest.py b/tests/conftest.py index 98f60959e413..51dca19850a3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,6 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import sys import pytest @@ -28,11 +27,6 @@ def pytest_report_header(config): def pytest_addoption(parser): parser.addoption("--wycheproof-root", default=None) parser.addoption("--enable-fips", default=False) - # REMOVE ME WHEN WE DROP PYTHON 3.6 SUPPORT - # This just adds a no-op flag so that we don't error on py36 where - # pytest-subtests is stuck on 0.8.0 - if sys.version_info[:2] == (3, 6): - parser.addoption("--no-subtests-shortletter", action="store_true") def pytest_runtest_setup(item): diff --git a/tox.ini b/tox.ini index 505bccba49b1..0a8806afce09 100644 --- a/tox.ini +++ b/tox.ini @@ -35,8 +35,8 @@ setenv = PIP_CONSTRAINT=ci-constraints-requirements.txt commands = pip list - !nocoverage: pytest -n auto --cov=cryptography --cov=tests --durations=10 {posargs} tests/ - nocoverage: pytest -n auto --durations=10 {posargs} tests/ + !nocoverage: pytest -n auto --dist=worksteal --cov=cryptography --cov=tests --durations=10 {posargs} tests/ + nocoverage: pytest -n auto --dist=worksteal --durations=10 {posargs} tests/ [testenv:docs] extras = From 0794b0e31aae4c550a009550f55f0976ae700083 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 21:36:14 +0800 Subject: [PATCH 512/827] update MSRV 1.48.0 -> 1.56.0 (#8587) * update MSRV 1.48.0 -> 1.56.0 * bump some deps for MSRV --- .github/workflows/ci.yml | 12 +++--------- CHANGELOG.rst | 1 + docs/installation.rst | 4 ++-- setup.py | 2 +- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- 6 files changed, 12 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8553a79d16a5..9d9f7ed9f0ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,16 +204,8 @@ jobs: PYTHON: - {VERSION: "3.11", TOXENV: "py311"} RUST: - # Cover MSRV (and likely next MSRV). In-dev versions are below in - # the linux-rust-coverage section. Once our MSRV is 1.60 we can - # remove this section entirely. - - 1.48.0 - # 1.49.0 is the MSRV for parking_lot 0.12 - # 1.51 - const generics (for rust-asn1) - # 1.56 - new versions of once_cell and bumpalo + # Cover MSRV. 1.60+ and beta/nightly are in the linux-rust-coverage section. - 1.56.0 - # Potential future MSRVs - # 1.60 - new version of cxx name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: @@ -260,6 +252,8 @@ jobs: PYTHON: - {VERSION: "3.11", TOXENV: "py311"} RUST: + # 1.60 - new version of cxx + - 1.60.0 - beta - nightly name: "Rust Coverage" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 13ea2ef6e1c3..02f12738c1d3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,7 @@ Changelog * **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been removed. Users on older version of OpenSSL will need to upgrade. * **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. +* Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. .. _v40-0-0: diff --git a/docs/installation.rst b/docs/installation.rst index 83c8313b9b48..0023187f9b7d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -137,7 +137,7 @@ Fedora/RHEL/CentOS .. warning:: For RHEL and CentOS you must be on version 8.3 or newer for the command - below to install a sufficiently new Rust. If your Rust is less than 1.48.0 + below to install a sufficiently new Rust. If your Rust is less than 1.56.0 please see the :ref:`Rust installation instructions ` for information about installing a newer Rust. @@ -315,7 +315,7 @@ Rust a Rust toolchain. Building ``cryptography`` requires having a working Rust toolchain. The current -minimum supported Rust version is 1.48.0. **This is newer than the Rust some +minimum supported Rust version is 1.56.0. **This is newer than the Rust some package managers ship**, so users may need to install with the instructions below. diff --git a/setup.py b/setup.py index 2d084d1efbe7..662f483af3e3 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ if platform.python_implementation() == "PyPy" else ["pyo3/abi3-py36"] ), - rust_version=">=1.48.0", + rust_version=">=1.56.0", ) ], ) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index dd8c6b0c6fb2..72a8c60a81ad 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -64,9 +64,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "cc" @@ -303,9 +303,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.14.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 2b1b94001683..dcd754a2876e 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -5,7 +5,7 @@ authors = ["The cryptography developers "] edition = "2018" publish = false # This specifies the MSRV -rust-version = "1.48.0" +rust-version = "1.56.0" [dependencies] once_cell = "1" From ffc10f9bb0f71102b743a7b8f2fa4a9a33e86d60 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Mar 2023 21:41:35 +0800 Subject: [PATCH 513/827] remove a test dep (#8446) --- ci-constraints-requirements.txt | 2 -- setup.cfg | 1 - tests/test_fernet.py | 9 ++++----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 0ae7fa2f88ed..1f72e311b1f7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -60,8 +60,6 @@ importlib-metadata==6.1.0 # twine iniconfig==2.0.0 # via pytest -iso8601==1.1.0 - # via cryptography (setup.cfg) jaraco-classes==3.2.3 # via keyring jinja2==3.1.2 diff --git a/setup.cfg b/setup.cfg index 3cdae292d92e..610ce986d7c4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -64,7 +64,6 @@ test = pytest-subtests>=0.10.0 pytest-xdist pretend - iso8601 test-randomorder: pytest-randomly docs = diff --git a/tests/test_fernet.py b/tests/test_fernet.py index d4b1561a0af6..89908e2793b8 100644 --- a/tests/test_fernet.py +++ b/tests/test_fernet.py @@ -4,12 +4,11 @@ import base64 -import calendar +import datetime import json import os import time -import iso8601 import pretend import pytest @@ -46,7 +45,7 @@ def test_generate(self, secret, now, iv, src, token, backend): f = Fernet(secret.encode("ascii"), backend=backend) actual_token = f._encrypt_from_parts( src.encode("ascii"), - calendar.timegm(iso8601.parse_date(now).utctimetuple()), + int(datetime.datetime.fromisoformat(now).timestamp()), bytes(iv), ) assert actual_token == token.encode("ascii") @@ -60,7 +59,7 @@ def test_verify( ): # secret & token are both str f = Fernet(secret.encode("ascii"), backend=backend) - current_time = calendar.timegm(iso8601.parse_date(now).utctimetuple()) + current_time = int(datetime.datetime.fromisoformat(now).timestamp()) payload = f.decrypt_at_time( token, # str ttl=ttl_sec, @@ -86,7 +85,7 @@ def test_verify( @json_parametrize(("secret", "token", "now", "ttl_sec"), "invalid.json") def test_invalid(self, secret, token, now, ttl_sec, backend, monkeypatch): f = Fernet(secret.encode("ascii"), backend=backend) - current_time = calendar.timegm(iso8601.parse_date(now).utctimetuple()) + current_time = int(datetime.datetime.fromisoformat(now).timestamp()) with pytest.raises(InvalidToken): f.decrypt_at_time( token.encode("ascii"), From e030da4b541be839516129b132b5febde2ce7562 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 16:50:08 -0400 Subject: [PATCH 514/827] fix copyright years (#8595) * fix copyright year in docs * update copyright year --- docs/conf.py | 2 +- src/cryptography/__about__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 4764cd70540a..0d8f866362a3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -72,7 +72,7 @@ # General information about the project. project = "Cryptography" -copyright = "2013-2022, Individual Contributors" +copyright = "2013-2023, Individual Contributors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 489579eb635f..ef6399c179b5 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -12,4 +12,4 @@ __version__ = "41.0.0.dev1" __author__ = "The Python Cryptographic Authority and individual contributors" -__copyright__ = f"Copyright 2013-2022 {__author__}" +__copyright__ = f"Copyright 2013-2023 {__author__}" From 378068948d64d706c2ef57878d2c7ca682732199 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 16:51:56 -0400 Subject: [PATCH 515/827] remove unused warning constant (#8594) --- src/cryptography/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index a84069f1c822..da4067a8e6ed 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -21,7 +21,6 @@ class CryptographyDeprecationWarning(UserWarning): # cycle ends. DeprecatedIn36 = CryptographyDeprecationWarning DeprecatedIn37 = CryptographyDeprecationWarning -DeprecatedIn39 = CryptographyDeprecationWarning DeprecatedIn40 = CryptographyDeprecationWarning From dcada6b3e4a5d8e4f41dae72377b65537ecd774a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 16:52:28 -0400 Subject: [PATCH 516/827] remove unused binding (#8593) --- src/_cffi_src/openssl/rand.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/rand.py b/src/_cffi_src/openssl/rand.py index 9e95fe792a7a..a2cce0ad201e 100644 --- a/src/_cffi_src/openssl/rand.py +++ b/src/_cffi_src/openssl/rand.py @@ -12,7 +12,6 @@ """ FUNCTIONS = """ -int RAND_set_rand_method(const RAND_METHOD *); void RAND_add(const void *, int, double); int RAND_status(void); int RAND_bytes(unsigned char *, int); From baea42771ad1a545f14b39bf6ab1aaf2af231216 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 16:55:43 -0400 Subject: [PATCH 517/827] Use the DEFINED BY functionality from rust-asn1 in pkcs7.rs (#7848) --- src/rust/Cargo.toml | 2 +- src/rust/src/pkcs7.rs | 42 ++++++++++++++++++++---------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index dcd754a2876e..2c3e1ae93f65 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" pyo3 = { version = "0.15.2" } -asn1 = { version = "0.13.0", default-features = false } +asn1 = { version = "0.13.0", default-features = false, features = ["const-generics"] } pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index da2a6561b69a..c23300ac49a3 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -25,13 +25,6 @@ const AES_256_CBC_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3 const AES_192_CBC_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 1, 22); const AES_128_CBC_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 1, 2); -static EMPTY_STRING_DER: Lazy> = Lazy::new(|| { - // TODO: kind of verbose way to say "\x04\x00". - asn1::write_single(&(&[] as &[u8])).unwrap() -}); -static EMPTY_STRING_TLV: Lazy> = - Lazy::new(|| asn1::parse_single(&EMPTY_STRING_DER).unwrap()); - static OIDS_TO_MIC_NAME: Lazy> = Lazy::new(|| { let mut h = HashMap::new(); h.insert(&x509::oid::SHA224_OID, "sha-224"); @@ -43,9 +36,18 @@ static OIDS_TO_MIC_NAME: Lazy> = Lazy::ne #[derive(asn1::Asn1Write)] struct ContentInfo<'a> { - content_type: asn1::ObjectIdentifier, - #[explicit(0)] - content: Option>, + _content_type: asn1::DefinedByMarker, + + #[defined_by(_content_type)] + content: Content<'a>, +} + +#[derive(asn1::Asn1DefinedByWrite)] +enum Content<'a> { + #[defined_by(PKCS7_SIGNED_DATA_OID)] + SignedData(asn1::Explicit<'a, Box>, 0>), + #[defined_by(PKCS7_DATA_OID)] + Data(Option>), } #[derive(asn1::Asn1Write)] @@ -106,19 +108,17 @@ fn serialize_certificates<'p>( version: 1, digest_algorithms: asn1::SetOfWriter::new(&[]), content_info: ContentInfo { - content_type: PKCS7_DATA_OID, - content: Some(*EMPTY_STRING_TLV), + _content_type: asn1::DefinedByMarker::marker(), + content: Content::Data(Some(asn1::Explicit::new(b""))), }, certificates: Some(asn1::SetOfWriter::new(&raw_certs)), crls: None, signer_infos: asn1::SetOfWriter::new(&[]), }; - let signed_data_bytes = asn1::write_single(&signed_data)?; - let content_info = ContentInfo { - content_type: PKCS7_SIGNED_DATA_OID, - content: Some(asn1::parse_single(&signed_data_bytes).unwrap()), + _content_type: asn1::DefinedByMarker::marker(), + content: Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), }; let content_info_bytes = asn1::write_single(&content_info)?; @@ -276,8 +276,8 @@ fn sign_and_serialize<'p>( version: 1, digest_algorithms: asn1::SetOfWriter::new(&digest_algs), content_info: ContentInfo { - content_type: PKCS7_DATA_OID, - content, + _content_type: asn1::DefinedByMarker::marker(), + content: Content::Data(content.map(asn1::Explicit::new)), }, certificates: if options.contains(pkcs7_options.getattr(crate::intern!(py, "NoCerts"))?)? { None @@ -288,11 +288,9 @@ fn sign_and_serialize<'p>( signer_infos: asn1::SetOfWriter::new(&signer_infos), }; - let signed_data_bytes = asn1::write_single(&signed_data)?; - let content_info = ContentInfo { - content_type: PKCS7_SIGNED_DATA_OID, - content: Some(asn1::parse_single(&signed_data_bytes).unwrap()), + _content_type: asn1::DefinedByMarker::marker(), + content: Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), }; let ci_bytes = asn1::write_single(&content_info)?; From 7e19ff0229a0a8d9263e126a01b11299221a0741 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 16:59:44 -0400 Subject: [PATCH 518/827] Migrate from setup.cfg to pyproject.toml completely (#8116) One less file? --- .github/workflows/wheel-builder.yml | 1 - ci-constraints-requirements.txt | 46 ++++++++------- pyproject.toml | 86 +++++++++++++++++++++++++++-- setup.cfg | 86 ----------------------------- setup.py | 2 +- 5 files changed, 105 insertions(+), 116 deletions(-) delete mode 100644 setup.cfg diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 1aec8c5cf439..e7b7ace10347 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -16,7 +16,6 @@ on: paths: - .github/workflows/wheel-builder.yml - setup.py - - setup.cfg - pyproject.toml - src/cryptography/__about__.py diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1f72e311b1f7..d55b250ebfb3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -1,7 +1,7 @@ # 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=tox --resolver=backtracking --strip-extras --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools setup.cfg +# pip-compile --extra=docs --extra=docstest --extra=pep8test --extra=test --extra=test-randomorder --extra=tox --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 @@ -10,10 +10,11 @@ alabaster==0.7.13 attrs==22.2.0 # via # pytest + # pytest-subtests babel==2.12.1 # via sphinx black==23.1.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) bleach==6.0.0 # via readme-renderer build==0.10.0 @@ -27,7 +28,7 @@ chardet==5.1.0 charset-normalizer==3.1.0 # via requests check-manifest==0.49 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) click==8.1.3 # via black colorama==0.4.6 @@ -42,8 +43,7 @@ docutils==0.18.1 # sphinx # sphinx-rtd-theme exceptiongroup==1.1.1 - # via - # pytest + # via pytest execnet==1.9.0 # via pytest-xdist filelock==3.10.3 @@ -75,7 +75,7 @@ mdurl==0.1.2 more-itertools==9.1.0 # via jaraco-classes mypy==1.1.1 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) mypy-extensions==1.0.0 # via # black @@ -102,12 +102,12 @@ pluggy==1.0.0 # pytest # tox pretend==1.0.9 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) py-cpuinfo==9.0.0 # via pytest-benchmark pyenchant==3.2.2 # via - # cryptography (setup.cfg) + # cryptography (pyproject.toml) # sphinxcontrib-spelling pygments==2.14.0 # via @@ -120,7 +120,7 @@ pyproject-hooks==1.0.0 # via build pytest==7.2.2 # via - # cryptography (setup.cfg) + # cryptography (pyproject.toml) # pytest-benchmark # pytest-cov # pytest-randomly @@ -128,20 +128,17 @@ pytest==7.2.2 # pytest-subtests # pytest-xdist pytest-benchmark==4.0.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) pytest-cov==4.0.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) pytest-randomly==3.12.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) pytest-shard==0.1.2 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) pytest-subtests==0.10.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) pytest-xdist==3.2.1 - # via cryptography (setup.cfg) -pytz==2022.7.1 - # via - # babel + # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine requests==2.28.2 @@ -156,18 +153,19 @@ rfc3986==2.0.0 rich==13.3.2 # via twine ruff==0.0.259 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) six==1.16.0 # via bleach snowballstemmer==2.2.0 # via sphinx sphinx==6.1.3 # via - # cryptography (setup.cfg) + # cryptography (pyproject.toml) # sphinx-rtd-theme + # sphinxcontrib-jquery # sphinxcontrib-spelling sphinx-rtd-theme==1.2.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 @@ -183,7 +181,7 @@ sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 # via sphinx sphinxcontrib-spelling==8.0.0 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) tomli==2.0.1 # via # black @@ -196,9 +194,9 @@ tomli==2.0.1 # pytest # tox tox==4.4.7 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) twine==4.0.2 - # via cryptography (setup.cfg) + # via cryptography (pyproject.toml) typing-extensions==4.5.0 # via mypy urllib3==1.26.15 diff --git a/pyproject.toml b/pyproject.toml index 5ee817601047..2a94aa26405b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,93 @@ [build-system] requires = [ - # The minimum setuptools version is specific to the PEP 517 backend, - # and may be stricter than the version required in `setup.cfg` - "setuptools>=40.6.0,!=60.9.0", + # First version of setuptools to support pyproject.toml configuration + "setuptools>=61.0.0", "wheel", - # Must be kept in sync with the `install_requirements` in `setup.cfg` + # Must be kept in sync with `project.dependencies` "cffi>=1.12; platform_python_implementation != 'PyPy'", "setuptools-rust>=0.11.4", ] build-backend = "setuptools.build_meta" +[project] +name = "cryptography" +authors = [ + {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} +] +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +license = {text = "Apache-2.0 OR BSD-3-Clause"} +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", + "Operating System :: POSIX :: BSD", + "Operating System :: POSIX :: Linux", + 'Operating System :: Microsoft :: Windows', + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Security :: Cryptography", +] +requires-python = ">=3.7" +dependencies = [ + # Must be kept in sync with `build-system.requires` + "cffi >=1.12", +] +dynamic = ["version", "readme"] + +[project.urls] +homepage = "https://github.com/pyca/cryptography" +documentation = "https://cryptography.io/" +source = "https://github.com/pyca/cryptography/" +issues = "https://github.com/pyca/cryptography/issues" +changelog = "https://cryptography.io/en/latest/changelog/" + +[tool.setuptools] +zip-safe = false +package-dir = {"" = "src"} + +[tool.setuptools.packages.find] +where = ["src"] +exclude = [ + "_cffi_src", + "_cffi_src.*", +] + +[tool.setuptools.dynamic] +version = {attr = "cryptography.__version__"} +readme = {file = "README.rst", content-type = "text/x-rst"} + +[project.optional-dependencies] +ssh = ["bcrypt >=3.1.5"] + +# All the following are used for our own testing. +tox = ["tox"] +test = [ + "pytest >=6.2.0", + "pytest-shard >=0.1.2", + "pytest-benchmark", + "pytest-cov", + "pytest-subtests >=0.10.0", + "pytest-xdist", + "pretend", +] +test-randomorder = ["pytest-randomly"] +docs = ["sphinx >=5.3.0", "sphinx-rtd-theme >=1.1.1"] +docstest = ["pyenchant >=1.6.11", "twine >=1.12.0", "sphinxcontrib-spelling >=4.0.1"] +sdist = ["setuptools_rust >=0.11.4"] +pep8test = ["black", "ruff", "mypy", "check-manifest"] + [tool.black] line-length = 79 target-version = ["py37"] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 610ce986d7c4..000000000000 --- a/setup.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[metadata] -name = cryptography -version = attr: cryptography.__version__ -description = cryptography is a package which provides cryptographic recipes and primitives to Python developers. -long_description = file: README.rst -long_description_content_type = text/x-rst -license = Apache-2.0 OR BSD-3-Clause -url = https://github.com/pyca/cryptography -author = The Python Cryptographic Authority and individual contributors -author_email = cryptography-dev@python.org -project_urls = - Documentation=https://cryptography.io/ - Source=https://github.com/pyca/cryptography/ - Issues=https://github.com/pyca/cryptography/issues - Changelog=https://cryptography.io/en/latest/changelog/ -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - License :: OSI Approved :: BSD License - Natural Language :: English - Operating System :: MacOS :: MacOS X - Operating System :: POSIX - Operating System :: POSIX :: BSD - Operating System :: POSIX :: Linux - Operating System :: Microsoft :: Windows - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Programming Language :: Python :: Implementation :: PyPy - Topic :: Security :: Cryptography - -[options] -python_requires = >=3.7 -include_package_data = True -zip_safe = False -package_dir = - =src -packages = find: -# `install_requires` must be kept in sync with `pyproject.toml` -install_requires = - cffi >=1.12 - -[options.packages.find] -where = src -exclude = - _cffi_src - _cffi_src.* - -[options.extras_require] -tox = - tox -test = - pytest>=6.2.0 - pytest-shard>=0.1.2 - pytest-benchmark - pytest-cov - pytest-subtests>=0.10.0 - pytest-xdist - pretend -test-randomorder: - pytest-randomly -docs = - sphinx >= 5.3.0 - sphinx-rtd-theme>=1.1.1 -docstest = - pyenchant >= 1.6.11 - twine >= 1.12.0 - sphinxcontrib-spelling >= 4.0.1 -sdist = - setuptools_rust >= 0.11.4 -pep8test = - black - ruff - mypy - check-manifest -# This extra is for OpenSSH private keys that use bcrypt KDF -# Versions: v3.1.3 - ignore_few_rounds, v3.1.5 - abi3 -ssh = - bcrypt >= 3.1.5 diff --git a/setup.py b/setup.py index 662f483af3e3..8ccc0c1f1de5 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ sys.path.insert(0, src_dir) try: - # See setup.cfg for most of the config metadata. + # See pyproject.toml for most of the config metadata. setup( rust_extensions=[ RustExtension( From 7e62312797cc018891fa4ffcfd9485fafacd3dfe Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 17:23:13 -0400 Subject: [PATCH 519/827] Upgrade to pyo3 0.18 (#6935) * Upgrade to pyo3 0.16 * Upgrade to pyo3 0.17 * Upgrade to pyo3 0.18 --- MANIFEST.in | 2 + setup.py | 2 +- src/rust/Cargo.lock | 90 ++++++++++++--------------- src/rust/Cargo.toml | 2 +- src/rust/src/asn1.rs | 4 +- src/rust/src/backend/x25519.rs | 42 ++++++------- src/rust/src/error.rs | 23 +++---- src/rust/src/lib.rs | 3 - src/rust/src/oid.rs | 10 +-- src/rust/src/pkcs7.rs | 2 +- src/rust/src/x509/certificate.rs | 22 +++---- src/rust/src/x509/common.rs | 26 ++++---- src/rust/src/x509/crl.rs | 79 ++++++++++------------- src/rust/src/x509/csr.rs | 15 ++--- src/rust/src/x509/extensions.rs | 2 +- src/rust/src/x509/ocsp_req.rs | 6 +- src/rust/src/x509/ocsp_resp.rs | 39 ++++++------ src/rust/src/x509/sct.rs | 43 ++++++------- src/rust/src/x509/sign.rs | 26 ++++---- tests/hazmat/primitives/test_pkcs7.py | 2 +- 20 files changed, 196 insertions(+), 244 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index c171033124b4..2417dd9d3088 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -16,6 +16,8 @@ prune docs/_build recursive-include tests *.py exclude vectors recursive-exclude vectors * +exclude src/rust/target +recursive-exclude src/rust/target * recursive-exclude .github * diff --git a/setup.py b/setup.py index 8ccc0c1f1de5..b3a7cf9b241e 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ features=( [] if platform.python_implementation() == "PyPy" - else ["pyo3/abi3-py36"] + else ["pyo3/abi3-py37"] ), rust_version=">=1.56.0", ) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 72a8c60a81ad..2aabfbb66e66 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -209,24 +209,10 @@ dependencies = [ [[package]] name = "indoc" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8" -dependencies = [ - "indoc-impl", - "proc-macro-hack", -] - -[[package]] -name = "indoc-impl" -version = "0.3.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0" +checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e" dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", "unindent", ] @@ -282,6 +268,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -394,25 +389,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "paste" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" -dependencies = [ - "paste-impl", - "proc-macro-hack", -] - -[[package]] -name = "paste-impl" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" -dependencies = [ - "proc-macro-hack", -] - [[package]] name = "pem" version = "1.1.1" @@ -452,12 +428,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.53" @@ -469,35 +439,48 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.15.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41d50a7271e08c7c8a54cd24af5d62f73ee3a6f6a314215281ebdec421d5752" +checksum = "06a3d8e8a46ab2738109347433cb7b96dffda2e4a218b03ef27090238886b147" dependencies = [ "cfg-if", "indoc", "libc", + "memoffset", "parking_lot", - "paste", "pyo3-build-config", + "pyo3-ffi", "pyo3-macros", "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.15.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779239fc40b8e18bc8416d3a37d280ca9b9fb04bda54b98037bb6748595c2410" +checksum = "75439f995d07ddfad42b192dfcf3bc66a7ecfd8b4a1f5f6f046aa5c2c5d7677d" dependencies = [ "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "839526a5c07a17ff44823679b68add4a58004de00512a95b6c1c98a6dcac0ee5" +dependencies = [ + "libc", + "pyo3-build-config", ] [[package]] name = "pyo3-macros" -version = "0.15.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b247e8c664be87998d8628e86f282c25066165f1f8dda66100c48202fdb93a" +checksum = "bd44cf207476c6a9760c4653559be4f206efafb924d3e4cbf2721475fc0d6cc5" dependencies = [ + "proc-macro2", "pyo3-macros-backend", "quote", "syn", @@ -505,12 +488,11 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.15.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a8c2812c412e00e641d99eeb79dd478317d981d938aa60325dfa7157b607095" +checksum = "dc1f43d8e30460f36350d18631ccf85ded64c059829208fe680904c65bcd0a4c" dependencies = [ "proc-macro2", - "pyo3-build-config", "quote", "syn", ] @@ -562,6 +544,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "target-lexicon" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" + [[package]] name = "termcolor" version = "1.2.0" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 2c3e1ae93f65..5de812febf45 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" -pyo3 = { version = "0.15.2" } +pyo3 = { version = "0.18" } asn1 = { version = "0.13.0", default-features = false, features = ["const-generics"] } pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 0bc57341e592..9d034ab77332 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -105,9 +105,9 @@ pub(crate) fn encode_der_data<'p>( .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))?; - if encoding == encoding_class.getattr(crate::intern!(py, "DER"))? { + if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { Ok(pyo3::types::PyBytes::new(py, &data)) - } else if encoding == encoding_class.getattr(crate::intern!(py, "PEM"))? { + } else if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { Ok(pyo3::types::PyBytes::new( py, &pem::encode_config( diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 96a2c7a5cc6e..72649ec7bdc1 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -118,14 +118,14 @@ impl X25519PrivateKey { .getattr(crate::intern!(py, "BestAvailableEncryption"))? .extract()?; - if !encoding_class.is_instance(encoding)? { + if !encoding.is_instance(encoding_class)? { return Err(CryptographyError::from( pyo3::exceptions::PyTypeError::new_err( "encoding must be an item from the Encoding enum", ), )); } - if !private_format_class.is_instance(format)? { + if !format.is_instance(private_format_class)? { return Err(CryptographyError::from( pyo3::exceptions::PyTypeError::new_err( "format must be an item from the PrivateFormat enum", @@ -133,12 +133,12 @@ impl X25519PrivateKey { )); } - if encoding == encoding_class.getattr(crate::intern!(py, "Raw"))? - || format == private_format_class.getattr(crate::intern!(py, "Raw"))? + if encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) + || format.is(private_format_class.getattr(crate::intern!(py, "Raw"))?) { - if encoding != encoding_class.getattr(crate::intern!(py, "Raw"))? - || format != private_format_class.getattr(crate::intern!(py, "Raw"))? - || !no_encryption_class.is_instance(encryption_algorithm)? + if !encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) + || !format.is(private_format_class.getattr(crate::intern!(py, "Raw"))?) + || !encryption_algorithm.is_instance(no_encryption_class)? { return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( "When using Raw both encoding and format must be Raw and encryption_algorithm must be NoEncryption()" @@ -148,9 +148,9 @@ impl X25519PrivateKey { return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); } - let password = if no_encryption_class.is_instance(encryption_algorithm)? { + let password = if encryption_algorithm.is_instance(no_encryption_class)? { b"" - } else if best_available_encryption_class.is_instance(encryption_algorithm)? { + } else if encryption_algorithm.is_instance(best_available_encryption_class)? { encryption_algorithm .getattr(crate::intern!(py, "password"))? .extract::<&[u8]>()? @@ -170,8 +170,8 @@ impl X25519PrivateKey { )); } - if format == private_format_class.getattr(crate::intern!(py, "PKCS8"))? { - if encoding == encoding_class.getattr(crate::intern!(py, "PEM"))? { + if format.is(private_format_class.getattr(crate::intern!(py, "PKCS8"))?) { + if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { let pem_bytes = if password.is_empty() { self.pkey.private_key_to_pem_pkcs8()? } else { @@ -181,7 +181,7 @@ impl X25519PrivateKey { )? }; return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding == encoding_class.getattr(crate::intern!(py, "DER"))? { + } else if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { let der_bytes = if password.is_empty() { self.pkey.private_key_to_pkcs8()? } else { @@ -228,14 +228,14 @@ impl X25519PublicKey { .getattr(crate::intern!(py, "PublicFormat"))? .extract()?; - if !encoding_class.is_instance(encoding)? { + if !encoding.is_instance(encoding_class)? { return Err(CryptographyError::from( pyo3::exceptions::PyTypeError::new_err( "encoding must be an item from the Encoding enum", ), )); } - if !public_format_class.is_instance(format)? { + if !format.is_instance(public_format_class)? { return Err(CryptographyError::from( pyo3::exceptions::PyTypeError::new_err( "format must be an item from the PublicFormat enum", @@ -243,11 +243,11 @@ impl X25519PublicKey { )); } - if encoding == encoding_class.getattr(crate::intern!(py, "Raw"))? - || format == public_format_class.getattr(crate::intern!(py, "Raw"))? + if encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) + || format.is(public_format_class.getattr(crate::intern!(py, "Raw"))?) { - if encoding != encoding_class.getattr(crate::intern!(py, "Raw"))? - || format != public_format_class.getattr(crate::intern!(py, "Raw"))? + if !encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) + || !format.is(public_format_class.getattr(crate::intern!(py, "Raw"))?) { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( @@ -260,11 +260,11 @@ impl X25519PublicKey { } // SubjectPublicKeyInfo + PEM/DER - if format == public_format_class.getattr(crate::intern!(py, "SubjectPublicKeyInfo"))? { - if encoding == encoding_class.getattr(crate::intern!(py, "PEM"))? { + if format.is(public_format_class.getattr(crate::intern!(py, "SubjectPublicKeyInfo"))?) { + if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { let pem_bytes = self.pkey.public_key_to_pem()?; return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding == encoding_class.getattr(crate::intern!(py, "DER"))? { + } else if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { let der_bytes = self.pkey.public_key_to_der()?; return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); } else { diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index 6c6440c8d33c..35713bbab75a 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -62,10 +62,7 @@ impl From for pyo3::PyErr { ) } CryptographyError::Py(py_error) => py_error, - CryptographyError::OpenSSL(error_stack) => { - let gil = pyo3::Python::acquire_gil(); - let py = gil.python(); - + CryptographyError::OpenSSL(error_stack) => pyo3::Python::with_gil(|py| { let internal_error = py .import("cryptography.exceptions") .expect("Failed to import cryptography module") @@ -81,21 +78,21 @@ impl From for pyo3::PyErr { ) .expect("Failed to append to list"); } - pyo3::PyErr::from_instance( + pyo3::PyErr::from_value( internal_error .call1(( "Unknown OpenSSL error. This error is commonly encountered - when another library is not cleaning up the OpenSSL error - stack. If you are using cryptography with another library - that uses OpenSSL try disabling it before reporting a bug. - Otherwise please file an issue at - https://github.com/pyca/cryptography/issues with - information on how to reproduce this.", + when another library is not cleaning up the OpenSSL error + stack. If you are using cryptography with another library + that uses OpenSSL try disabling it before reporting a bug. + Otherwise please file an issue at + https://github.com/pyca/cryptography/issues with + information on how to reproduce this.", errors, )) .expect("Failed to create InternalError"), ) - } + }), } } } @@ -130,7 +127,7 @@ mod tests { CryptographyError::Asn1Write(asn1::WriteError::AllocationError) )); let py_e: pyo3::PyErr = e.into(); - assert!(py_e.is_instance::(py)); + assert!(py_e.is_instance_of::(py)); let e: CryptographyError = pyo3::PyDowncastError::new(py.None().as_ref(py), "abc").into(); diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 2ec4e66bb5c2..dae286cc0d56 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -128,10 +128,7 @@ impl OpenSSLError { fn _lib_reason_match(&self, lib: i32, reason: i32) -> bool { self.e.library_code() == lib && self.e.reason_code() == reason } -} -#[pyo3::prelude::pyproto] -impl pyo3::PyObjectProtocol for OpenSSLError { fn __repr__(&self) -> pyo3::PyResult { Ok(format!( "", diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index a13668579a74..43d26802aaed 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -39,14 +39,8 @@ impl ObjectIdentifier { fn __deepcopy__(slf: pyo3::PyRef<'_, Self>, _memo: pyo3::PyObject) -> pyo3::PyRef<'_, Self> { slf } -} - -#[pyo3::prelude::pyproto] -impl pyo3::PyObjectProtocol for ObjectIdentifier { - fn __repr__(&self) -> pyo3::PyResult { - let gil = pyo3::Python::acquire_gil(); - let py = gil.python(); + fn __repr__(&self, py: pyo3::Python<'_>) -> pyo3::PyResult { let self_clone = pyo3::PyCell::new( py, ObjectIdentifier { @@ -62,7 +56,7 @@ impl pyo3::PyObjectProtocol for ObjectIdentifier { fn __richcmp__( &self, - other: pyo3::PyRef, + other: pyo3::PyRef<'_, ObjectIdentifier>, op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index c23300ac49a3..53e479e5b3e2 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -298,7 +298,7 @@ fn sign_and_serialize<'p>( .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))?; - if encoding == encoding_class.getattr(crate::intern!(py, "SMIME"))? { + if encoding.is(encoding_class.getattr(crate::intern!(py, "SMIME"))?) { let mic_algs = digest_algs .iter() .map(|d| OIDS_TO_MIC_NAME[&d.oid]) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 1a9820e5ea06..2e0378ff9d40 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -83,8 +83,8 @@ pub(crate) struct Certificate { pub(crate) cached_extensions: Option, } -#[pyo3::prelude::pyproto] -impl pyo3::PyObjectProtocol for Certificate { +#[pyo3::prelude::pymethods] +impl Certificate { fn __hash__(&self) -> u64 { let mut hasher = DefaultHasher::new(); self.raw.borrow_value().hash(&mut hasher); @@ -93,7 +93,7 @@ impl pyo3::PyObjectProtocol for Certificate { fn __richcmp__( &self, - other: pyo3::PyRef, + other: pyo3::PyRef<'_, Certificate>, op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { @@ -105,18 +105,12 @@ impl pyo3::PyObjectProtocol for Certificate { } } - fn __repr__(&self) -> pyo3::PyResult { - let gil = pyo3::Python::acquire_gil(); - let py = gil.python(); - + fn __repr__(&self, py: pyo3::Python<'_>) -> pyo3::PyResult { let subject = self.subject(py)?; let subject_repr = subject.repr()?.extract::<&str>()?; Ok(format!("", subject_repr)) } -} -#[pyo3::prelude::pymethods] -impl Certificate { fn __deepcopy__(slf: pyo3::PyRef<'_, Self>, _memo: pyo3::PyObject) -> pyo3::PyRef<'_, Self> { slf } @@ -277,7 +271,7 @@ impl Certificate { let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_instance( + Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", (format!( @@ -359,11 +353,11 @@ fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, Crypt match version { 0 => Ok(x509_module .getattr(crate::intern!(py, "Version"))? - .get_item("v1")?), + .get_item(crate::intern!(py, "v1"))?), 2 => Ok(x509_module .getattr(crate::intern!(py, "Version"))? - .get_item("v3")?), - _ => Err(CryptographyError::from(pyo3::PyErr::from_instance( + .get_item(crate::intern!(py, "v3"))?), + _ => Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid X509 version", version), version))?, diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index a765d614457c..59710a3aed17 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -112,10 +112,10 @@ pub(crate) fn encode_name_entry<'p>( let tag = attr_type .getattr(crate::intern!(py, "value"))? .extract::()?; - let value: &[u8] = if attr_type != asn1_type.getattr(crate::intern!(py, "BitString"))? { - let encoding = if attr_type == asn1_type.getattr(crate::intern!(py, "BMPString"))? { + let value: &[u8] = if !attr_type.is(asn1_type.getattr(crate::intern!(py, "BitString"))?) { + let encoding = if attr_type.is(asn1_type.getattr(crate::intern!(py, "BMPString"))?) { "utf_16_be" - } else if attr_type == asn1_type.getattr(crate::intern!(py, "UniversalString"))? { + } else if attr_type.is(asn1_type.getattr(crate::intern!(py, "UniversalString"))?) { "utf_32_be" } else { "utf8" @@ -233,18 +233,18 @@ pub(crate) fn encode_general_name<'a>( let gn_module = py.import("cryptography.x509.general_name")?; let gn_type = gn.get_type().as_ref(); let gn_value = gn.getattr(crate::intern!(py, "value"))?; - if gn_type == gn_module.getattr(crate::intern!(py, "DNSName"))? { + if gn_type.is(gn_module.getattr(crate::intern!(py, "DNSName"))?) { Ok(GeneralName::DNSName(UnvalidatedIA5String( gn_value.extract::<&str>()?, ))) - } else if gn_type == gn_module.getattr(crate::intern!(py, "RFC822Name"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "RFC822Name"))?) { Ok(GeneralName::RFC822Name(UnvalidatedIA5String( gn_value.extract::<&str>()?, ))) - } else if gn_type == gn_module.getattr(crate::intern!(py, "DirectoryName"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "DirectoryName"))?) { let name = encode_name(py, gn_value)?; Ok(GeneralName::DirectoryName(name)) - } else if gn_type == gn_module.getattr(crate::intern!(py, "OtherName"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "OtherName"))?) { Ok(GeneralName::OtherName(OtherName { type_id: py_oid_to_oid(gn.getattr(crate::intern!(py, "type_id"))?)?, value: asn1::parse_single(gn_value.extract::<&[u8]>()?).map_err(|e| { @@ -254,15 +254,15 @@ pub(crate) fn encode_general_name<'a>( )) })?, })) - } else if gn_type == gn_module.getattr(crate::intern!(py, "UniformResourceIdentifier"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "UniformResourceIdentifier"))?) { Ok(GeneralName::UniformResourceIdentifier( UnvalidatedIA5String(gn_value.extract::<&str>()?), )) - } else if gn_type == gn_module.getattr(crate::intern!(py, "IPAddress"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "IPAddress"))?) { Ok(GeneralName::IPAddress( gn.call_method0("_packed")?.extract::<&[u8]>()?, )) - } else if gn_type == gn_module.getattr(crate::intern!(py, "RegisteredID"))? { + } else if gn_type.is(gn_module.getattr(crate::intern!(py, "RegisteredID"))?) { let oid = py_oid_to_oid(gn_value)?; Ok(GeneralName::RegisteredID(oid)) } else { @@ -462,7 +462,7 @@ pub(crate) fn parse_general_name( .to_object(py) } _ => { - return Err(CryptographyError::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module.call_method1( "UnsupportedGeneralNameType", ("x400Address/EDIPartyName are not supported types",), @@ -563,7 +563,7 @@ pub(crate) fn parse_and_cache_extensions< let oid_obj = oid_to_py_oid(py, &raw_ext.extn_id)?; if seen_oids.contains(&raw_ext.extn_id) { - return Err(pyo3::PyErr::from_instance(x509_module.call_method1( + return Err(pyo3::PyErr::from_value(x509_module.call_method1( "DuplicateExtension", ( format!("Duplicate {} extension found", raw_ext.extn_id), @@ -613,7 +613,7 @@ pub(crate) fn encode_extensions< let oid = py_oid_to_oid(py_ext.getattr(crate::intern!(py, "oid"))?)?; let ext_val = py_ext.getattr(crate::intern!(py, "value"))?; - if unrecognized_extension_type.is_instance(ext_val)? { + if ext_val.is_instance(unrecognized_extension_type)? { exts.push(Extension { extn_id: oid, critical: py_ext.getattr(crate::intern!(py, "critical"))?.extract()?, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index c1b5c8c48d86..37a4902aea2b 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -26,7 +26,7 @@ fn load_der_x509_crl( let version = raw.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { let x509_module = py.import("cryptography.x509")?; - return Err(CryptographyError::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CRL version", version), version))?, @@ -97,11 +97,11 @@ impl CertificateRevocationList { } } -#[pyo3::prelude::pyproto] -impl pyo3::PyObjectProtocol for CertificateRevocationList { +#[pyo3::prelude::pymethods] +impl CertificateRevocationList { fn __richcmp__( &self, - other: pyo3::PyRef, + other: pyo3::PyRef<'_, CertificateRevocationList>, op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { @@ -112,18 +112,31 @@ impl pyo3::PyObjectProtocol for CertificateRevocationList { )), } } -} -#[pyo3::prelude::pyproto] -impl pyo3::PyMappingProtocol for CertificateRevocationList { fn __len__(&self) -> usize { self.len() } - fn __getitem__(&self, idx: &pyo3::PyAny) -> pyo3::PyResult { - let gil = pyo3::Python::acquire_gil(); - let py = gil.python(); + fn __iter__(&self) -> CRLIterator { + CRLIterator { + contents: OwnedCRLIteratorData::try_new(Arc::clone(&self.raw), |v| { + Ok::<_, ()>( + v.borrow_value() + .tbs_cert_list + .revoked_certificates + .as_ref() + .map(|v| v.unwrap_read().clone()), + ) + }) + .unwrap(), + } + } + fn __getitem__( + &self, + py: pyo3::Python<'_>, + idx: &pyo3::PyAny, + ) -> pyo3::PyResult { self.raw.with(|val| { val.revoked_certs.get_or_init(py, || { match &val.value.tbs_cert_list.revoked_certificates { @@ -133,7 +146,7 @@ impl pyo3::PyMappingProtocol for CertificateRevocationList { }); }); - if idx.is_instance::()? { + if idx.is_instance_of::()? { let indices = idx .downcast::()? .indices(self.len().try_into().unwrap())?; @@ -154,10 +167,7 @@ impl pyo3::PyMappingProtocol for CertificateRevocationList { Ok(pyo3::PyCell::new(py, self.revoked_cert(py, idx as usize)?)?.to_object(py)) } } -} -#[pyo3::prelude::pymethods] -impl CertificateRevocationList { fn fingerprint<'p>( &self, py: pyo3::Python<'p>, @@ -189,7 +199,7 @@ impl CertificateRevocationList { .get_item(oid) { Ok(v) => Ok(v), - Err(_) => Err(pyo3::PyErr::from_instance(exceptions_module.call_method1( + Err(_) => Err(pyo3::PyErr::from_value(exceptions_module.call_method1( "UnsupportedAlgorithm", (format!( "Signature algorithm OID:{} not recognized", @@ -395,24 +405,6 @@ impl CertificateRevocationList { } } -#[pyo3::prelude::pyproto] -impl pyo3::PyIterProtocol<'_> for CertificateRevocationList { - fn __iter__(slf: pyo3::PyRef<'p, Self>) -> CRLIterator { - CRLIterator { - contents: OwnedCRLIteratorData::try_new(Arc::clone(&slf.raw), |v| { - Ok::<_, ()>( - v.borrow_value() - .tbs_cert_list - .revoked_certificates - .as_ref() - .map(|v| v.unwrap_read().clone()), - ) - }) - .unwrap(), - } - } -} - #[ouroboros::self_referencing] struct OwnedCRLIteratorData { data: Arc, @@ -455,14 +447,18 @@ fn try_map_arc_data_mut_crl_iterator( }) } -#[pyo3::prelude::pyproto] -impl pyo3::PyIterProtocol<'_> for CRLIterator { - fn __iter__(slf: pyo3::PyRef<'p, Self>) -> pyo3::PyRef<'p, Self> { +#[pyo3::prelude::pymethods] +impl CRLIterator { + fn __len__(&self) -> usize { + self.contents.borrow_value().clone().map_or(0, |v| v.len()) + } + + fn __iter__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } - fn __next__(mut slf: pyo3::PyRefMut<'p, Self>) -> Option { - let revoked = try_map_arc_data_mut_crl_iterator(&mut slf.contents, |_data, v| match v { + fn __next__(&mut self) -> Option { + let revoked = try_map_arc_data_mut_crl_iterator(&mut self.contents, |_data, v| match v { Some(v) => match v.next() { Some(revoked) => Ok(revoked), None => Err(()), @@ -477,13 +473,6 @@ impl pyo3::PyIterProtocol<'_> for CRLIterator { } } -#[pyo3::prelude::pyproto] -impl pyo3::PySequenceProtocol<'_> for CRLIterator { - fn __len__(&self) -> usize { - self.contents.borrow_value().clone().map_or(0, |v| v.len()) - } -} - #[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] struct RawCertificateRevocationList<'a> { tbs_cert_list: TBSCertList<'a>, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index e16a58164c17..8a7f533041c1 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -84,8 +84,8 @@ struct CertificateSigningRequest { cached_extensions: Option, } -#[pyo3::prelude::pyproto] -impl pyo3::basic::PyObjectProtocol for CertificateSigningRequest { +#[pyo3::prelude::pymethods] +impl CertificateSigningRequest { fn __hash__(&self) -> u64 { let mut hasher = DefaultHasher::new(); self.raw.borrow_data().hash(&mut hasher); @@ -94,7 +94,7 @@ impl pyo3::basic::PyObjectProtocol for CertificateSigningRequest { fn __richcmp__( &self, - other: pyo3::PyRef, + other: pyo3::PyRef<'_, CertificateSigningRequest>, op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { @@ -105,10 +105,7 @@ impl pyo3::basic::PyObjectProtocol for CertificateSigningRequest { )), } } -} -#[pyo3::prelude::pymethods] -impl CertificateSigningRequest { fn public_key<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { // This makes an unnecessary copy. It'd be nice to get rid of it. let serialized = pyo3::types::PyBytes::new( @@ -154,7 +151,7 @@ impl CertificateSigningRequest { let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_instance( + Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", (format!( @@ -222,7 +219,7 @@ impl CertificateSigningRequest { } } } - Err(pyo3::PyErr::from_instance( + Err(pyo3::PyErr::from_value( py.import("cryptography.x509")?.call_method1( "AttributeNotFound", (format!("No {} attribute was found", oid), oid), @@ -309,7 +306,7 @@ fn load_der_x509_csr( let version = raw.borrow_value().csr_info.version; if version != 0 { let x509_module = py.import("cryptography.x509")?; - return Err(CryptographyError::from(pyo3::PyErr::from_instance( + return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module .getattr(crate::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CSR version", version), version))?, diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index d93e87c0f1a3..1af8d389de72 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -229,7 +229,7 @@ pub(crate) fn encode_extension( let mut qualifiers = vec![]; for py_qualifier in py_policy_qualifiers.iter()? { let py_qualifier = py_qualifier?; - let qualifier = if py_qualifier.is_instance::()? { + let qualifier = if py_qualifier.is_instance_of::()? { let cps_uri = match asn1::IA5String::new(py_qualifier.extract()?) { Some(s) => s, None => { diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 638caf9b2494..5711dd4a9546 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -83,10 +83,10 @@ impl OCSPRequest { let hashes = py.import("cryptography.hazmat.primitives.hashes")?; match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid) { - Some(alg_name) => Ok(hashes.getattr(alg_name)?.call0()?), + Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => { let exceptions = py.import("cryptography.exceptions")?; - Err(CryptographyError::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( @@ -141,7 +141,7 @@ impl OCSPRequest { .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))? .getattr(crate::intern!(py, "DER"))?; - if encoding != der { + if !encoding.is(der) { return Err(pyo3::exceptions::PyValueError::new_err( "The only allowed encoding value is Encoding.DER", ) diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 2f878b2c4c3e..9f38282931bc 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -183,7 +183,7 @@ impl OCSPResponse { "Signature algorithm OID: {} not recognized", self.requires_successful_response()?.signature_algorithm.oid ); - Err(CryptographyError::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_value( py.import("cryptography.exceptions")? .call_method1("UnsupportedAlgorithm", (exc_messsage,))?, ))) @@ -383,7 +383,7 @@ impl OCSPResponse { .import("cryptography.hazmat.primitives.serialization")? .getattr(crate::intern!(py, "Encoding"))? .getattr(crate::intern!(py, "DER"))?; - if encoding != der { + if !encoding.is(der) { return Err(pyo3::exceptions::PyValueError::new_err( "The only allowed encoding value is Encoding.DER", ) @@ -528,10 +528,10 @@ impl SingleResponse<'_> { ) -> Result<&'p pyo3::PyAny, CryptographyError> { let hashes = py.import("cryptography.hazmat.primitives.hashes")?; match ocsp::OIDS_TO_HASH.get(&self.cert_id.hash_algorithm.oid) { - Some(alg_name) => Ok(hashes.getattr(alg_name)?.call0()?), + Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => { let exceptions = py.import("cryptography.exceptions")?; - Err(CryptographyError::from(pyo3::PyErr::from_instance( + Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( @@ -627,16 +627,14 @@ fn create_ocsp_response( .extract()?; let py_cert_status = py_single_resp.getattr(crate::intern!(py, "_cert_status"))?; - let cert_status = if py_cert_status - == ocsp_mod - .getattr(crate::intern!(py, "OCSPCertStatus"))? - .getattr(crate::intern!(py, "GOOD"))? + let cert_status = if py_cert_status.is(ocsp_mod + .getattr(crate::intern!(py, "OCSPCertStatus"))? + .getattr(crate::intern!(py, "GOOD"))?) { CertStatus::Good(()) - } else if py_cert_status - == ocsp_mod - .getattr(crate::intern!(py, "OCSPCertStatus"))? - .getattr(crate::intern!(py, "UNKNOWN"))? + } else if py_cert_status.is(ocsp_mod + .getattr(crate::intern!(py, "OCSPCertStatus"))? + .getattr(crate::intern!(py, "UNKNOWN"))?) { CertStatus::Unknown(()) } else { @@ -687,10 +685,9 @@ fn create_ocsp_response( }]; borrowed_cert = responder_cert.borrow(); - let responder_id = if responder_encoding - == ocsp_mod - .getattr(crate::intern!(py, "OCSPResponderEncoding"))? - .getattr(crate::intern!(py, "HASH"))? + let responder_id = if responder_encoding.is(ocsp_mod + .getattr(crate::intern!(py, "OCSPResponderEncoding"))? + .getattr(crate::intern!(py, "HASH"))?) { let sha1 = py .import("cryptography.hazmat.primitives.hashes")? @@ -801,15 +798,15 @@ struct OCSPResponseIterator { contents: OwnedOCSPResponseIteratorData, } -#[pyo3::prelude::pyproto] -impl pyo3::PyIterProtocol<'_> for OCSPResponseIterator { - fn __iter__(slf: pyo3::PyRef<'p, Self>) -> pyo3::PyRef<'p, Self> { +#[pyo3::prelude::pymethods] +impl OCSPResponseIterator { + fn __iter__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } - fn __next__(mut slf: pyo3::PyRefMut<'p, Self>) -> Option { + fn __next__(&mut self) -> Option { let single_resp = - try_map_arc_data_mut_ocsp_response_iterator(&mut slf.contents, |_data, v| { + try_map_arc_data_mut_ocsp_response_iterator(&mut self.contents, |_data, v| { match v.next() { Some(single_resp) => Ok(single_resp), None => Err(()), diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index e3f7be4d9036..b6b2e56dab86 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -143,6 +143,26 @@ pub(crate) struct Sct { #[pyo3::prelude::pymethods] impl Sct { + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, Sct>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.sct_data == other.sct_data), + pyo3::basic::CompareOp::Ne => Ok(self.sct_data != other.sct_data), + _ => Err(pyo3::exceptions::PyTypeError::new_err( + "SCTs cannot be ordered", + )), + } + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.sct_data.hash(&mut hasher); + hasher.finish() + } + #[getter] fn version<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { py.import("cryptography.x509.certificate_transparency")? @@ -209,29 +229,6 @@ impl Sct { } } -#[pyo3::prelude::pyproto] -impl pyo3::PyObjectProtocol for Sct { - fn __richcmp__( - &self, - other: pyo3::PyRef, - op: pyo3::basic::CompareOp, - ) -> pyo3::PyResult { - match op { - pyo3::basic::CompareOp::Eq => Ok(self.sct_data == other.sct_data), - pyo3::basic::CompareOp::Ne => Ok(self.sct_data != other.sct_data), - _ => Err(pyo3::exceptions::PyTypeError::new_err( - "SCTs cannot be ordered", - )), - } - } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.sct_data.hash(&mut hasher); - hasher.finish() - } -} - pub(crate) fn parse_scts( py: pyo3::Python<'_>, data: &[u8], diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 33d293b21527..4d505ece7886 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -59,15 +59,15 @@ fn identify_key_type(py: pyo3::Python<'_>, private_key: &pyo3::PyAny) -> pyo3::P .getattr(crate::intern!(py, "Ed448PrivateKey"))? .extract()?; - if rsa_private_key.is_instance(private_key)? { + if private_key.is_instance(rsa_private_key)? { Ok(KeyType::Rsa) - } else if dsa_key_type.is_instance(private_key)? { + } else if private_key.is_instance(dsa_key_type)? { Ok(KeyType::Dsa) - } else if ec_key_type.is_instance(private_key)? { + } else if private_key.is_instance(ec_key_type)? { Ok(KeyType::Ec) - } else if ed25519_key_type.is_instance(private_key)? { + } else if private_key.is_instance(ed25519_key_type)? { Ok(KeyType::Ed25519) - } else if ed448_key_type.is_instance(private_key)? { + } else if private_key.is_instance(ed448_key_type)? { Ok(KeyType::Ed448) } else { Err(pyo3::exceptions::PyTypeError::new_err( @@ -88,7 +88,7 @@ fn identify_hash_type( .import("cryptography.hazmat.primitives.hashes")? .getattr(crate::intern!(py, "HashAlgorithm"))? .extract()?; - if !hash_algorithm_type.is_instance(hash_algorithm)? { + if !hash_algorithm.is_instance(hash_algorithm_type)? { return Err(pyo3::exceptions::PyTypeError::new_err( "Algorithm must be a registered hash algorithm.", )); @@ -106,7 +106,7 @@ fn identify_hash_type( "sha3-256" => Ok(HashType::Sha3_256), "sha3-384" => Ok(HashType::Sha3_384), "sha3-512" => Ok(HashType::Sha3_512), - name => Err(pyo3::PyErr::from_instance( + name => Err(pyo3::PyErr::from_value( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", (format!( @@ -226,7 +226,7 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Dsa, HashType::Sha3_224) | (KeyType::Dsa, HashType::Sha3_256) | (KeyType::Dsa, HashType::Sha3_384) - | (KeyType::Dsa, HashType::Sha3_512) => Err(pyo3::PyErr::from_instance( + | (KeyType::Dsa, HashType::Sha3_512) => Err(pyo3::PyErr::from_value( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", ("SHA3 hashes are not supported with DSA keys",), @@ -354,15 +354,15 @@ pub(crate) fn identify_public_key_type( .getattr(crate::intern!(py, "Ed448PublicKey"))? .extract()?; - if rsa_key_type.is_instance(public_key)? { + if public_key.is_instance(rsa_key_type)? { Ok(KeyType::Rsa) - } else if dsa_key_type.is_instance(public_key)? { + } else if public_key.is_instance(dsa_key_type)? { Ok(KeyType::Dsa) - } else if ec_key_type.is_instance(public_key)? { + } else if public_key.is_instance(ec_key_type)? { Ok(KeyType::Ec) - } else if ed25519_key_type.is_instance(public_key)? { + } else if public_key.is_instance(ed25519_key_type)? { Ok(KeyType::Ed25519) - } else if ed448_key_type.is_instance(public_key)? { + } else if public_key.is_instance(ed448_key_type)? { Ok(KeyType::Ed448) } else { Err(pyo3::exceptions::PyTypeError::new_err( diff --git a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py index 4e61c5ef55e8..172cf40bd6e4 100644 --- a/tests/hazmat/primitives/test_pkcs7.py +++ b/tests/hazmat/primitives/test_pkcs7.py @@ -807,7 +807,7 @@ def test_invalid_types(self): ) with pytest.raises(TypeError): pkcs7.serialize_certificates( - "not a list of certs", # type: ignore[arg-type] + object(), # type: ignore[arg-type] serialization.Encoding.PEM, ) From 3df3fc8987d72560fd6c8434e535f6f88fc6cb60 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 17:46:25 -0400 Subject: [PATCH 520/827] Drop our own intern! macro in favor of pyo3's (#8596) --- src/rust/src/asn1.rs | 6 +- src/rust/src/backend/x25519.rs | 42 ++++++------ src/rust/src/error.rs | 2 +- src/rust/src/intern.rs | 44 ------------ src/rust/src/lib.rs | 1 - src/rust/src/oid.rs | 2 +- src/rust/src/pkcs7.rs | 28 ++++---- src/rust/src/x509/certificate.rs | 112 +++++++++++++++---------------- src/rust/src/x509/common.rs | 80 +++++++++++----------- src/rust/src/x509/crl.rs | 42 ++++++------ src/rust/src/x509/csr.rs | 22 +++--- src/rust/src/x509/extensions.rs | 86 +++++++++++------------- src/rust/src/x509/ocsp.rs | 6 +- src/rust/src/x509/ocsp_req.rs | 12 ++-- src/rust/src/x509/ocsp_resp.rs | 62 ++++++++--------- src/rust/src/x509/sct.rs | 10 +-- src/rust/src/x509/sign.rs | 32 ++++----- 17 files changed, 266 insertions(+), 323 deletions(-) delete mode 100644 src/rust/src/intern.rs diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 9d034ab77332..2cc9431bb5fd 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -103,11 +103,11 @@ pub(crate) fn encode_der_data<'p>( ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let encoding_class = py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "Encoding"))?; + .getattr(pyo3::intern!(py, "Encoding"))?; - if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { Ok(pyo3::types::PyBytes::new(py, &data)) - } else if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { Ok(pyo3::types::PyBytes::new( py, &pem::encode_config( diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 72649ec7bdc1..94af22636b00 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -106,16 +106,16 @@ impl X25519PrivateKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let encoding_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "Encoding"))? .extract()?; let private_format_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "PrivateFormat"))? + .getattr(pyo3::intern!(py, "PrivateFormat"))? .extract()?; let no_encryption_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "NoEncryption"))? + .getattr(pyo3::intern!(py, "NoEncryption"))? .extract()?; let best_available_encryption_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "BestAvailableEncryption"))? + .getattr(pyo3::intern!(py, "BestAvailableEncryption"))? .extract()?; if !encoding.is_instance(encoding_class)? { @@ -133,11 +133,11 @@ impl X25519PrivateKey { )); } - if encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) - || format.is(private_format_class.getattr(crate::intern!(py, "Raw"))?) + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) { - if !encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) - || !format.is(private_format_class.getattr(crate::intern!(py, "Raw"))?) + if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || !format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) || !encryption_algorithm.is_instance(no_encryption_class)? { return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( @@ -152,7 +152,7 @@ impl X25519PrivateKey { b"" } else if encryption_algorithm.is_instance(best_available_encryption_class)? { encryption_algorithm - .getattr(crate::intern!(py, "password"))? + .getattr(pyo3::intern!(py, "password"))? .extract::<&[u8]>()? } else { return Err(CryptographyError::from( @@ -170,8 +170,8 @@ impl X25519PrivateKey { )); } - if format.is(private_format_class.getattr(crate::intern!(py, "PKCS8"))?) { - if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { + if format.is(private_format_class.getattr(pyo3::intern!(py, "PKCS8"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { let pem_bytes = if password.is_empty() { self.pkey.private_key_to_pem_pkcs8()? } else { @@ -181,7 +181,7 @@ impl X25519PrivateKey { )? }; return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { let der_bytes = if password.is_empty() { self.pkey.private_key_to_pkcs8()? } else { @@ -222,10 +222,10 @@ impl X25519PublicKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let encoding_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "Encoding"))? .extract()?; let public_format_class: &pyo3::types::PyType = serialization_mod - .getattr(crate::intern!(py, "PublicFormat"))? + .getattr(pyo3::intern!(py, "PublicFormat"))? .extract()?; if !encoding.is_instance(encoding_class)? { @@ -243,11 +243,11 @@ impl X25519PublicKey { )); } - if encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) - || format.is(public_format_class.getattr(crate::intern!(py, "Raw"))?) + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) { - if !encoding.is(encoding_class.getattr(crate::intern!(py, "Raw"))?) - || !format.is(public_format_class.getattr(crate::intern!(py, "Raw"))?) + if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || !format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( @@ -260,11 +260,11 @@ impl X25519PublicKey { } // SubjectPublicKeyInfo + PEM/DER - if format.is(public_format_class.getattr(crate::intern!(py, "SubjectPublicKeyInfo"))?) { - if encoding.is(encoding_class.getattr(crate::intern!(py, "PEM"))?) { + if format.is(public_format_class.getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { let pem_bytes = self.pkey.public_key_to_pem()?; return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding.is(encoding_class.getattr(crate::intern!(py, "DER"))?) { + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { let der_bytes = self.pkey.public_key_to_der()?; return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); } else { diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index 35713bbab75a..1cabbb11a948 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -66,7 +66,7 @@ impl From for pyo3::PyErr { let internal_error = py .import("cryptography.exceptions") .expect("Failed to import cryptography module") - .getattr(crate::intern!(py, "InternalError")) + .getattr(pyo3::intern!(py, "InternalError")) .expect("Failed to get InternalError attribute"); let errors = pyo3::types::PyList::empty(py); diff --git a/src/rust/src/intern.rs b/src/rust/src/intern.rs deleted file mode 100644 index 94f2118334e6..000000000000 --- a/src/rust/src/intern.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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. - -// This file is a backport of `pyo3::intern!` from pyo3 0.16. - -#[macro_export] -macro_rules! intern { - ($py: expr, $text: expr) => {{ - static INTERNED: $crate::intern::Interned = $crate::intern::Interned::new($text); - INTERNED.get($py) - }}; -} - -#[doc(hidden)] -pub struct Interned( - &'static str, - pyo3::once_cell::GILOnceCell>, -); - -impl Interned { - pub const fn new(value: &'static str) -> Self { - Interned(value, pyo3::once_cell::GILOnceCell::new()) - } - - #[inline] - pub fn get<'py>(&'py self, py: pyo3::Python<'py>) -> &'py pyo3::types::PyString { - self.1 - .get_or_init(py, || pyo3::types::PyString::new(py, self.0).into()) - .as_ref(py) - } -} - -#[cfg(test)] -mod tests { - use super::Interned; - - #[test] - fn test_interned_new() { - for s in ["abc", "123"] { - Interned::new(s); - } - } -} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index dae286cc0d56..d7dbbba6067d 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -13,7 +13,6 @@ mod asn1; mod backend; mod buf; mod error; -mod intern; pub(crate) mod oid; mod pkcs7; mod pool; diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index 43d26802aaed..1c12f775a621 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -32,7 +32,7 @@ impl ObjectIdentifier { ) -> pyo3::PyResult<&'p pyo3::PyAny> { let oid_names = py .import("cryptography.hazmat._oid")? - .getattr(crate::intern!(py, "_OID_NAMES"))?; + .getattr(pyo3::intern!(py, "_OID_NAMES"))?; oid_names.call_method1("get", (slf, "Unknown OID")) } diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 53e479e5b3e2..4904dd8cc250 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -134,12 +134,12 @@ fn sign_and_serialize<'p>( ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let pkcs7_options = py .import("cryptography.hazmat.primitives.serialization.pkcs7")? - .getattr(crate::intern!(py, "PKCS7Options"))?; + .getattr(pyo3::intern!(py, "PKCS7Options"))?; - let raw_data: CffiBuf<'p> = builder.getattr(crate::intern!(py, "_data"))?.extract()?; - let text_mode = options.contains(pkcs7_options.getattr(crate::intern!(py, "Text"))?)?; + let raw_data: CffiBuf<'p> = builder.getattr(pyo3::intern!(py, "_data"))?.extract()?; + let text_mode = options.contains(pkcs7_options.getattr(pyo3::intern!(py, "Text"))?)?; let (data_with_header, data_without_header) = - if options.contains(pkcs7_options.getattr(crate::intern!(py, "Binary"))?)? { + if options.contains(pkcs7_options.getattr(pyo3::intern!(py, "Binary"))?)? { ( Cow::Borrowed(raw_data.as_bytes()), Cow::Borrowed(raw_data.as_bytes()), @@ -165,10 +165,10 @@ fn sign_and_serialize<'p>( pyo3::PyRef<'p, x509::Certificate>, &pyo3::PyAny, &pyo3::PyAny, - )> = builder.getattr(crate::intern!(py, "_signers"))?.extract()?; + )> = builder.getattr(pyo3::intern!(py, "_signers"))?.extract()?; let py_certs: Vec> = builder - .getattr(crate::intern!(py, "_additional_certs"))? + .getattr(pyo3::intern!(py, "_additional_certs"))? .extract()?; let mut signer_infos = vec![]; @@ -179,7 +179,7 @@ fn sign_and_serialize<'p>( .collect::>(); for (cert, py_private_key, py_hash_alg) in &py_signers { let (authenticated_attrs, signature) = if options - .contains(pkcs7_options.getattr(crate::intern!(py, "NoAttributes"))?)? + .contains(pkcs7_options.getattr(pyo3::intern!(py, "NoAttributes"))?)? { ( None, @@ -212,7 +212,7 @@ fn sign_and_serialize<'p>( ])), }); - if !options.contains(pkcs7_options.getattr(crate::intern!(py, "NoCapabilities"))?)? { + if !options.contains(pkcs7_options.getattr(pyo3::intern!(py, "NoCapabilities"))?)? { authenticated_attrs.push(x509::csr::Attribute { type_id: PKCS7_SMIME_CAP_OID, values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ @@ -234,7 +234,7 @@ fn sign_and_serialize<'p>( let digest_alg = x509::AlgorithmIdentifier { oid: x509::ocsp::HASH_NAME_TO_OIDS[py_hash_alg - .getattr(crate::intern!(py, "name"))? + .getattr(pyo3::intern!(py, "name"))? .extract::<&str>()?] .clone(), params: Some(*x509::sign::NULL_TLV), @@ -265,7 +265,7 @@ fn sign_and_serialize<'p>( let data_tlv_bytes; let content = - if options.contains(pkcs7_options.getattr(crate::intern!(py, "DetachedSignature"))?)? { + if options.contains(pkcs7_options.getattr(pyo3::intern!(py, "DetachedSignature"))?)? { None } else { data_tlv_bytes = asn1::write_single(&data_with_header.deref())?; @@ -279,7 +279,7 @@ fn sign_and_serialize<'p>( _content_type: asn1::DefinedByMarker::marker(), content: Content::Data(content.map(asn1::Explicit::new)), }, - certificates: if options.contains(pkcs7_options.getattr(crate::intern!(py, "NoCerts"))?)? { + certificates: if options.contains(pkcs7_options.getattr(pyo3::intern!(py, "NoCerts"))?)? { None } else { Some(asn1::SetOfWriter::new(&certs)) @@ -296,9 +296,9 @@ fn sign_and_serialize<'p>( let encoding_class = py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "Encoding"))?; + .getattr(pyo3::intern!(py, "Encoding"))?; - if encoding.is(encoding_class.getattr(crate::intern!(py, "SMIME"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "SMIME"))?) { let mic_algs = digest_algs .iter() .map(|d| OIDS_TO_MIC_NAME[&d.oid]) @@ -306,7 +306,7 @@ fn sign_and_serialize<'p>( .join(","); let smime_encode = py .import("cryptography.hazmat.primitives.serialization.pkcs7")? - .getattr(crate::intern!(py, "_smime_encode"))?; + .getattr(pyo3::intern!(py, "_smime_encode"))?; Ok(smime_encode .call1((&*data_without_header, &*ci_bytes, mic_algs, text_mode))? .extract()?) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 2e0378ff9d40..219698fa54d5 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -123,7 +123,7 @@ impl Certificate { ); Ok(py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "load_der_public_key"))? + .getattr(pyo3::intern!(py, "load_der_public_key"))? .call1((serialized,))?) } @@ -134,7 +134,7 @@ impl Certificate { ) -> CryptographyResult<&'p pyo3::PyAny> { let hasher = py .import("cryptography.hazmat.primitives.hashes")? - .getattr(crate::intern!(py, "Hash"))? + .getattr(pyo3::intern!(py, "Hash"))? .call1((algorithm,))?; // This makes an unnecessary copy. It'd be nice to get rid of it. let serialized = @@ -267,7 +267,7 @@ impl Certificate { ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? - .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), @@ -300,7 +300,7 @@ impl Certificate { asn1::parse_single::<()>(ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "PrecertPoison"))? + .getattr(pyo3::intern!(py, "PrecertPoison"))? .call0()?, )) } @@ -309,7 +309,7 @@ impl Certificate { let scts = sct::parse_scts(py, contents, sct::LogEntryType::PreCertificate)?; Ok(Some( x509_module - .getattr(crate::intern!( + .getattr(pyo3::intern!( py, "PrecertificateSignedCertificateTimestamps" ))? @@ -352,14 +352,14 @@ fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, Crypt let x509_module = py.import("cryptography.x509")?; match version { 0 => Ok(x509_module - .getattr(crate::intern!(py, "Version"))? - .get_item(crate::intern!(py, "v1"))?), + .getattr(pyo3::intern!(py, "Version"))? + .get_item(pyo3::intern!(py, "v1"))?), 2 => Ok(x509_module - .getattr(crate::intern!(py, "Version"))? - .get_item(crate::intern!(py, "v3"))?), + .getattr(pyo3::intern!(py, "Version"))? + .get_item(pyo3::intern!(py, "v3"))?), _ => Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module - .getattr(crate::intern!(py, "InvalidVersion"))? + .getattr(pyo3::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid X509 version", version), version))?, ))), } @@ -414,7 +414,7 @@ fn warn_if_negative_serial(py: pyo3::Python<'_>, bytes: &'_ [u8]) -> pyo3::PyRes if bytes[0] & 0x80 != 0 { let cryptography_warning = py .import("cryptography.utils")? - .getattr(crate::intern!(py, "DeprecatedIn36"))?; + .getattr(pyo3::intern!(py, "DeprecatedIn36"))?; pyo3::PyErr::warn( py, cryptography_warning, @@ -684,7 +684,7 @@ fn parse_distribution_point( }; let x509_module = py.import("cryptography.x509")?; Ok(x509_module - .getattr(crate::intern!(py, "DistributionPoint"))? + .getattr(pyo3::intern!(py, "DistributionPoint"))? .call1((full_name, relative_name, reasons, crl_issuer))? .to_object(py)) } @@ -708,7 +708,7 @@ pub(crate) fn parse_distribution_point_reasons( ) -> Result { let reason_bit_mapping = py .import("cryptography.x509.extensions")? - .getattr(crate::intern!(py, "_REASON_BIT_MAPPING"))?; + .getattr(pyo3::intern!(py, "_REASON_BIT_MAPPING"))?; Ok(match reasons { Some(bs) => { let mut vec = Vec::new(); @@ -729,7 +729,7 @@ pub(crate) fn encode_distribution_point_reasons( ) -> pyo3::PyResult { let reason_flag_mapping = py .import("cryptography.x509.extensions")? - .getattr(crate::intern!(py, "_CRLREASONFLAGS"))?; + .getattr(pyo3::intern!(py, "_CRLREASONFLAGS"))?; let mut bits = vec![0, 0]; for py_reason in py_reasons.iter()? { @@ -775,7 +775,7 @@ pub(crate) fn parse_authority_key_identifier<'p>( None => py.None(), }; Ok(x509_module - .getattr(crate::intern!(py, "AuthorityKeyIdentifier"))? + .getattr(pyo3::intern!(py, "AuthorityKeyIdentifier"))? .call1((aki.key_identifier, issuer, serial))?) } @@ -790,7 +790,7 @@ pub(crate) fn parse_access_descriptions( let py_oid = oid_to_py_oid(py, &access.access_method)?.to_object(py); let gn = x509::parse_general_name(py, access.access_location)?; let ad = x509_module - .getattr(crate::intern!(py, "AccessDescription"))? + .getattr(pyo3::intern!(py, "AccessDescription"))? .call1((py_oid, gn))? .to_object(py); ads.append(ad)?; @@ -811,7 +811,7 @@ pub fn parse_cert_ext<'p>( let sans = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "SubjectAlternativeName"))? + .getattr(pyo3::intern!(py, "SubjectAlternativeName"))? .call1((sans,))?, )) } @@ -821,14 +821,14 @@ pub fn parse_cert_ext<'p>( let ians = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "IssuerAlternativeName"))? + .getattr(pyo3::intern!(py, "IssuerAlternativeName"))? .call1((ians,))?, )) } oid::TLS_FEATURE_OID => { let tls_feature_type_to_enum = py .import("cryptography.x509.extensions")? - .getattr(crate::intern!(py, "_TLS_FEATURE_TYPE_TO_ENUM"))?; + .getattr(pyo3::intern!(py, "_TLS_FEATURE_TYPE_TO_ENUM"))?; let features = pyo3::types::PyList::empty(py); for feature in asn1::parse_single::>(ext_data)? { @@ -837,7 +837,7 @@ pub fn parse_cert_ext<'p>( } Ok(Some( x509_module - .getattr(crate::intern!(py, "TLSFeature"))? + .getattr(pyo3::intern!(py, "TLSFeature"))? .call1((features,))?, )) } @@ -845,7 +845,7 @@ pub fn parse_cert_ext<'p>( let identifier = asn1::parse_single::<&[u8]>(ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "SubjectKeyIdentifier"))? + .getattr(pyo3::intern!(py, "SubjectKeyIdentifier"))? .call1((identifier,))?, )) } @@ -858,7 +858,7 @@ pub fn parse_cert_ext<'p>( } Ok(Some( x509_module - .getattr(crate::intern!(py, "ExtendedKeyUsage"))? + .getattr(pyo3::intern!(py, "ExtendedKeyUsage"))? .call1((ekus,))?, )) } @@ -874,26 +874,24 @@ pub fn parse_cert_ext<'p>( let encipher_only = kus.has_bit_set(7); let decipher_only = kus.has_bit_set(8); Ok(Some( - x509_module - .getattr(crate::intern!(py, "KeyUsage"))? - .call1(( - digital_signature, - content_comitment, - key_encipherment, - data_encipherment, - key_agreement, - key_cert_sign, - crl_sign, - encipher_only, - decipher_only, - ))?, + x509_module.getattr(pyo3::intern!(py, "KeyUsage"))?.call1(( + digital_signature, + content_comitment, + key_encipherment, + data_encipherment, + key_agreement, + key_cert_sign, + crl_sign, + encipher_only, + decipher_only, + ))?, )) } oid::AUTHORITY_INFORMATION_ACCESS_OID => { let ads = parse_access_descriptions(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "AuthorityInformationAccess"))? + .getattr(pyo3::intern!(py, "AuthorityInformationAccess"))? .call1((ads,))?, )) } @@ -901,7 +899,7 @@ pub fn parse_cert_ext<'p>( let ads = parse_access_descriptions(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "SubjectInformationAccess"))? + .getattr(pyo3::intern!(py, "SubjectInformationAccess"))? .call1((ads,))?, )) } @@ -915,7 +913,7 @@ pub fn parse_cert_ext<'p>( let pc = asn1::parse_single::(ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "PolicyConstraints"))? + .getattr(pyo3::intern!(py, "PolicyConstraints"))? .call1((pc.require_explicit_policy, pc.inhibit_policy_mapping))?, )) } @@ -923,7 +921,7 @@ pub fn parse_cert_ext<'p>( asn1::parse_single::<()>(ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "OCSPNoCheck"))? + .getattr(pyo3::intern!(py, "OCSPNoCheck"))? .call0()?, )) } @@ -932,7 +930,7 @@ pub fn parse_cert_ext<'p>( let pynum = big_byte_slice_to_py_int(py, bignum.as_bytes())?; Ok(Some( x509_module - .getattr(crate::intern!(py, "InhibitAnyPolicy"))? + .getattr(pyo3::intern!(py, "InhibitAnyPolicy"))? .call1((pynum,))?, )) } @@ -940,7 +938,7 @@ pub fn parse_cert_ext<'p>( let bc = asn1::parse_single::(ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "BasicConstraints"))? + .getattr(pyo3::intern!(py, "BasicConstraints"))? .call1((bc.ca, bc.path_length))?, )) } @@ -951,7 +949,7 @@ pub fn parse_cert_ext<'p>( let dp = parse_distribution_points(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "CRLDistributionPoints"))? + .getattr(pyo3::intern!(py, "CRLDistributionPoints"))? .call1((dp,))?, )) } @@ -959,7 +957,7 @@ pub fn parse_cert_ext<'p>( let dp = parse_distribution_points(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "FreshestCRL"))? + .getattr(pyo3::intern!(py, "FreshestCRL"))? .call1((dp,))?, )) } @@ -975,7 +973,7 @@ pub fn parse_cert_ext<'p>( }; Ok(Some( x509_module - .getattr(crate::intern!(py, "NameConstraints"))? + .getattr(pyo3::intern!(py, "NameConstraints"))? .call1((permitted_subtrees, excluded_subtrees))?, )) } @@ -1011,30 +1009,30 @@ fn create_x509_certificate( let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let der_encoding = serialization_mod - .getattr(crate::intern!(py, "Encoding"))? - .getattr(crate::intern!(py, "DER"))?; + .getattr(pyo3::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "DER"))?; let spki_format = serialization_mod - .getattr(crate::intern!(py, "PublicFormat"))? - .getattr(crate::intern!(py, "SubjectPublicKeyInfo"))?; + .getattr(pyo3::intern!(py, "PublicFormat"))? + .getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?; let spki_bytes = builder - .getattr(crate::intern!(py, "_public_key"))? + .getattr(pyo3::intern!(py, "_public_key"))? .call_method1("public_bytes", (der_encoding, spki_format))? .extract::<&[u8]>()?; let py_serial = builder - .getattr(crate::intern!(py, "_serial_number"))? + .getattr(pyo3::intern!(py, "_serial_number"))? .extract()?; - let py_issuer_name = builder.getattr(crate::intern!(py, "_issuer_name"))?; - let py_subject_name = builder.getattr(crate::intern!(py, "_subject_name"))?; - let py_not_before = builder.getattr(crate::intern!(py, "_not_valid_before"))?; - let py_not_after = builder.getattr(crate::intern!(py, "_not_valid_after"))?; + let py_issuer_name = builder.getattr(pyo3::intern!(py, "_issuer_name"))?; + let py_subject_name = builder.getattr(pyo3::intern!(py, "_subject_name"))?; + let py_not_before = builder.getattr(pyo3::intern!(py, "_not_valid_before"))?; + let py_not_after = builder.getattr(pyo3::intern!(py, "_not_valid_after"))?; let tbs_cert = TbsCertificate { version: builder - .getattr(crate::intern!(py, "_version"))? - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "_version"))? + .getattr(pyo3::intern!(py, "value"))? .extract()?, serial: asn1::BigInt::new(py_uint_to_big_endian_bytes(py, py_serial)?).unwrap(), signature_alg: sigalg.clone(), @@ -1049,7 +1047,7 @@ fn create_x509_certificate( subject_unique_id: None, extensions: x509::common::encode_extensions( py, - builder.getattr(crate::intern!(py, "_extensions"))?, + builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, )?, }; diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 59710a3aed17..a5f642e0d1ef 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -86,7 +86,7 @@ pub(crate) fn encode_name<'p>( ) -> pyo3::PyResult> { let mut rdns = vec![]; - for py_rdn in py_name.getattr(crate::intern!(py, "rdns"))?.iter()? { + for py_rdn in py_name.getattr(pyo3::intern!(py, "rdns"))?.iter()? { let py_rdn = py_rdn?; let mut attrs = vec![]; @@ -106,30 +106,30 @@ pub(crate) fn encode_name_entry<'p>( ) -> CryptographyResult> { let asn1_type = py .import("cryptography.x509.name")? - .getattr(crate::intern!(py, "_ASN1Type"))?; + .getattr(pyo3::intern!(py, "_ASN1Type"))?; - let attr_type = py_name_entry.getattr(crate::intern!(py, "_type"))?; + let attr_type = py_name_entry.getattr(pyo3::intern!(py, "_type"))?; let tag = attr_type - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "value"))? .extract::()?; - let value: &[u8] = if !attr_type.is(asn1_type.getattr(crate::intern!(py, "BitString"))?) { - let encoding = if attr_type.is(asn1_type.getattr(crate::intern!(py, "BMPString"))?) { + let value: &[u8] = if !attr_type.is(asn1_type.getattr(pyo3::intern!(py, "BitString"))?) { + let encoding = if attr_type.is(asn1_type.getattr(pyo3::intern!(py, "BMPString"))?) { "utf_16_be" - } else if attr_type.is(asn1_type.getattr(crate::intern!(py, "UniversalString"))?) { + } else if attr_type.is(asn1_type.getattr(pyo3::intern!(py, "UniversalString"))?) { "utf_32_be" } else { "utf8" }; py_name_entry - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "value"))? .call_method1("encode", (encoding,))? .extract()? } else { py_name_entry - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "value"))? .extract()? }; - let oid = py_oid_to_oid(py_name_entry.getattr(crate::intern!(py, "oid"))?)?; + let oid = py_oid_to_oid(py_name_entry.getattr(pyo3::intern!(py, "oid"))?)?; Ok(AttributeTypeValue { type_id: oid, @@ -232,21 +232,21 @@ pub(crate) fn encode_general_name<'a>( ) -> Result, CryptographyError> { let gn_module = py.import("cryptography.x509.general_name")?; let gn_type = gn.get_type().as_ref(); - let gn_value = gn.getattr(crate::intern!(py, "value"))?; - if gn_type.is(gn_module.getattr(crate::intern!(py, "DNSName"))?) { + let gn_value = gn.getattr(pyo3::intern!(py, "value"))?; + if gn_type.is(gn_module.getattr(pyo3::intern!(py, "DNSName"))?) { Ok(GeneralName::DNSName(UnvalidatedIA5String( gn_value.extract::<&str>()?, ))) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "RFC822Name"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "RFC822Name"))?) { Ok(GeneralName::RFC822Name(UnvalidatedIA5String( gn_value.extract::<&str>()?, ))) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "DirectoryName"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "DirectoryName"))?) { let name = encode_name(py, gn_value)?; Ok(GeneralName::DirectoryName(name)) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "OtherName"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "OtherName"))?) { Ok(GeneralName::OtherName(OtherName { - type_id: py_oid_to_oid(gn.getattr(crate::intern!(py, "type_id"))?)?, + type_id: py_oid_to_oid(gn.getattr(pyo3::intern!(py, "type_id"))?)?, value: asn1::parse_single(gn_value.extract::<&[u8]>()?).map_err(|e| { pyo3::exceptions::PyValueError::new_err(format!( "OtherName value must be valid DER: {:?}", @@ -254,15 +254,15 @@ pub(crate) fn encode_general_name<'a>( )) })?, })) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "UniformResourceIdentifier"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "UniformResourceIdentifier"))?) { Ok(GeneralName::UniformResourceIdentifier( UnvalidatedIA5String(gn_value.extract::<&str>()?), )) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "IPAddress"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "IPAddress"))?) { Ok(GeneralName::IPAddress( gn.call_method0("_packed")?.extract::<&[u8]>()?, )) - } else if gn_type.is(gn_module.getattr(crate::intern!(py, "RegisteredID"))?) { + } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "RegisteredID"))?) { let oid = py_oid_to_oid(gn_value)?; Ok(GeneralName::RegisteredID(oid)) } else { @@ -291,9 +291,9 @@ pub(crate) fn encode_access_descriptions<'a>( let mut ads = vec![]; for py_ad in py_ads.iter()? { let py_ad = py_ad?; - let access_method = py_oid_to_oid(py_ad.getattr(crate::intern!(py, "access_method"))?)?; + let access_method = py_oid_to_oid(py_ad.getattr(pyo3::intern!(py, "access_method"))?)?; let access_location = - encode_general_name(py, py_ad.getattr(crate::intern!(py, "access_location"))?)?; + encode_general_name(py, py_ad.getattr(pyo3::intern!(py, "access_location"))?)?; ads.push(AccessDescription { access_method, access_location, @@ -360,7 +360,7 @@ fn parse_name_attribute( let oid = oid_to_py_oid(py, &attribute.type_id)?.to_object(py); let tag_enum = py .import("cryptography.x509.name")? - .getattr(crate::intern!(py, "_ASN1_TYPE_TO_ENUM"))?; + .getattr(pyo3::intern!(py, "_ASN1_TYPE_TO_ENUM"))?; let tag_val = attribute .value .tag() @@ -425,11 +425,11 @@ pub(crate) fn parse_general_name( .to_object(py) } GeneralName::RFC822Name(data) => x509_module - .getattr(crate::intern!(py, "RFC822Name"))? + .getattr(pyo3::intern!(py, "RFC822Name"))? .call_method1("_init_without_validation", (data.0,))? .to_object(py), GeneralName::DNSName(data) => x509_module - .getattr(crate::intern!(py, "DNSName"))? + .getattr(pyo3::intern!(py, "DNSName"))? .call_method1("_init_without_validation", (data.0,))? .to_object(py), GeneralName::DirectoryName(data) => { @@ -439,7 +439,7 @@ pub(crate) fn parse_general_name( .to_object(py) } GeneralName::UniformResourceIdentifier(data) => x509_module - .getattr(crate::intern!(py, "UniformResourceIdentifier"))? + .getattr(pyo3::intern!(py, "UniformResourceIdentifier"))? .call_method1("_init_without_validation", (data.0,))? .to_object(py), GeneralName::IPAddress(data) => { @@ -510,7 +510,7 @@ fn create_ip_network( )?; let net = format!( "{}/{}", - base.getattr(crate::intern!(py, "exploded"))? + base.getattr(pyo3::intern!(py, "exploded"))? .extract::<&str>()?, prefix? ); @@ -604,21 +604,21 @@ pub(crate) fn encode_extensions< ) -> pyo3::PyResult>> { let unrecognized_extension_type: &pyo3::types::PyType = py .import("cryptography.x509")? - .getattr(crate::intern!(py, "UnrecognizedExtension"))? + .getattr(pyo3::intern!(py, "UnrecognizedExtension"))? .extract()?; let mut exts = vec![]; for py_ext in py_exts.iter()? { let py_ext = py_ext?; - let oid = py_oid_to_oid(py_ext.getattr(crate::intern!(py, "oid"))?)?; + let oid = py_oid_to_oid(py_ext.getattr(pyo3::intern!(py, "oid"))?)?; - let ext_val = py_ext.getattr(crate::intern!(py, "value"))?; + let ext_val = py_ext.getattr(pyo3::intern!(py, "value"))?; if ext_val.is_instance(unrecognized_extension_type)? { exts.push(Extension { extn_id: oid, - critical: py_ext.getattr(crate::intern!(py, "critical"))?.extract()?, + critical: py_ext.getattr(pyo3::intern!(py, "critical"))?.extract()?, extn_value: ext_val - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "value"))? .extract::<&[u8]>()?, }); continue; @@ -629,7 +629,7 @@ pub(crate) fn encode_extensions< let py_data = pyo3::types::PyBytes::new(py, &data); exts.push(Extension { extn_id: oid, - critical: py_ext.getattr(crate::intern!(py, "critical"))?.extract()?, + critical: py_ext.getattr(pyo3::intern!(py, "critical"))?.extract()?, extn_value: py_data.as_bytes(), }) } @@ -654,7 +654,7 @@ fn encode_extension_value<'p>( py: pyo3::Python<'p>, py_ext: &'p pyo3::PyAny, ) -> pyo3::PyResult<&'p pyo3::types::PyBytes> { - let oid = py_oid_to_oid(py_ext.getattr(crate::intern!(py, "oid"))?)?; + let oid = py_oid_to_oid(py_ext.getattr(pyo3::intern!(py, "oid"))?)?; if let Some(data) = x509::extensions::encode_extension(py, &oid, py_ext)? { // TODO: extra copy @@ -674,7 +674,7 @@ pub(crate) fn chrono_to_py<'p>( ) -> pyo3::PyResult<&'p pyo3::PyAny> { let datetime_module = py.import("datetime")?; datetime_module - .getattr(crate::intern!(py, "datetime"))? + .getattr(pyo3::intern!(py, "datetime"))? .call1(( dt.year(), dt.month(), @@ -691,12 +691,12 @@ pub(crate) fn py_to_chrono( ) -> pyo3::PyResult> { Ok(chrono::Utc .with_ymd_and_hms( - val.getattr(crate::intern!(py, "year"))?.extract()?, - val.getattr(crate::intern!(py, "month"))?.extract()?, - val.getattr(crate::intern!(py, "day"))?.extract()?, - val.getattr(crate::intern!(py, "hour"))?.extract()?, - val.getattr(crate::intern!(py, "minute"))?.extract()?, - val.getattr(crate::intern!(py, "second"))?.extract()?, + val.getattr(pyo3::intern!(py, "year"))?.extract()?, + val.getattr(pyo3::intern!(py, "month"))?.extract()?, + val.getattr(pyo3::intern!(py, "day"))?.extract()?, + val.getattr(pyo3::intern!(py, "hour"))?.extract()?, + val.getattr(pyo3::intern!(py, "minute"))?.extract()?, + val.getattr(pyo3::intern!(py, "second"))?.extract()?, ) .unwrap()) } diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 37a4902aea2b..5100c3afb6db 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -28,7 +28,7 @@ fn load_der_x509_crl( let x509_module = py.import("cryptography.x509")?; return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module - .getattr(crate::intern!(py, "InvalidVersion"))? + .getattr(pyo3::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CRL version", version), version))?, ))); } @@ -175,7 +175,7 @@ impl CertificateRevocationList { ) -> pyo3::PyResult<&'p pyo3::PyAny> { let hashes_mod = py.import("cryptography.hazmat.primitives.hashes")?; let h = hashes_mod - .getattr(crate::intern!(py, "Hash"))? + .getattr(pyo3::intern!(py, "Hash"))? .call1((algorithm,))?; h.call_method1("update", (self.public_bytes_der()?.as_slice(),))?; h.call_method0("finalize") @@ -195,7 +195,7 @@ impl CertificateRevocationList { let oid_module = py.import("cryptography.hazmat._oid")?; let exceptions_module = py.import("cryptography.exceptions")?; match oid_module - .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))? + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))? .get_item(oid) { Ok(v) => Ok(v), @@ -274,7 +274,7 @@ impl CertificateRevocationList { let pynum = big_byte_slice_to_py_int(py, bignum.as_bytes())?; Ok(Some( x509_module - .getattr(crate::intern!(py, "CRLNumber"))? + .getattr(pyo3::intern!(py, "CRLNumber"))? .call1((pynum,))?, )) } @@ -283,7 +283,7 @@ impl CertificateRevocationList { let pynum = big_byte_slice_to_py_int(py, bignum.as_bytes())?; Ok(Some( x509_module - .getattr(crate::intern!(py, "DeltaCRLIndicator"))? + .getattr(pyo3::intern!(py, "DeltaCRLIndicator"))? .call1((pynum,))?, )) } @@ -294,7 +294,7 @@ impl CertificateRevocationList { let ians = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "IssuerAlternativeName"))? + .getattr(pyo3::intern!(py, "IssuerAlternativeName"))? .call1((ians,))?, )) } @@ -302,7 +302,7 @@ impl CertificateRevocationList { let ads = certificate::parse_access_descriptions(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "AuthorityInformationAccess"))? + .getattr(pyo3::intern!(py, "AuthorityInformationAccess"))? .call1((ads,))?, )) } @@ -325,7 +325,7 @@ impl CertificateRevocationList { }; Ok(Some( x509_module - .getattr(crate::intern!(py, "IssuingDistributionPoint"))? + .getattr(pyo3::intern!(py, "IssuingDistributionPoint"))? .call1(( full_name, relative_name, @@ -341,7 +341,7 @@ impl CertificateRevocationList { let dp = certificate::parse_distribution_points(py, ext_data)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "FreshestCRL"))? + .getattr(pyo3::intern!(py, "FreshestCRL"))? .call1((dp,))?, )) } @@ -600,7 +600,7 @@ pub(crate) fn parse_crl_reason_flags<'p>( } }; Ok(x509_module - .getattr(crate::intern!(py, "ReasonFlags"))? + .getattr(pyo3::intern!(py, "ReasonFlags"))? .getattr(flag_name)?) } @@ -615,7 +615,7 @@ pub fn parse_crl_entry_ext<'p>( let flags = parse_crl_reason_flags(py, &asn1::parse_single::(data)?)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "CRLReason"))? + .getattr(pyo3::intern!(py, "CRLReason"))? .call1((flags,))?, )) } @@ -624,7 +624,7 @@ pub fn parse_crl_entry_ext<'p>( let gns = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "CertificateIssuer"))? + .getattr(pyo3::intern!(py, "CertificateIssuer"))? .call1((gns,))?, )) } @@ -633,7 +633,7 @@ pub fn parse_crl_entry_ext<'p>( let py_dt = x509::chrono_to_py(py, time.as_chrono())?; Ok(Some( x509_module - .getattr(crate::intern!(py, "InvalidityDate"))? + .getattr(pyo3::intern!(py, "InvalidityDate"))? .call1((py_dt,))?, )) } @@ -652,29 +652,29 @@ fn create_x509_crl( let mut revoked_certs = vec![]; for py_revoked_cert in builder - .getattr(crate::intern!(py, "_revoked_certificates"))? + .getattr(pyo3::intern!(py, "_revoked_certificates"))? .iter()? { let py_revoked_cert = py_revoked_cert?; let serial_number = py_revoked_cert - .getattr(crate::intern!(py, "serial_number"))? + .getattr(pyo3::intern!(py, "serial_number"))? .extract()?; - let py_revocation_date = py_revoked_cert.getattr(crate::intern!(py, "revocation_date"))?; + let py_revocation_date = py_revoked_cert.getattr(pyo3::intern!(py, "revocation_date"))?; revoked_certs.push(RawRevokedCertificate { user_certificate: asn1::BigUint::new(py_uint_to_big_endian_bytes(py, serial_number)?) .unwrap(), revocation_date: x509::certificate::time_from_py(py, py_revocation_date)?, crl_entry_extensions: x509::common::encode_extensions( py, - py_revoked_cert.getattr(crate::intern!(py, "extensions"))?, + py_revoked_cert.getattr(pyo3::intern!(py, "extensions"))?, extensions::encode_extension, )?, }); } - let py_issuer_name = builder.getattr(crate::intern!(py, "_issuer_name"))?; - let py_this_update = builder.getattr(crate::intern!(py, "_last_update"))?; - let py_next_update = builder.getattr(crate::intern!(py, "_next_update"))?; + let py_issuer_name = builder.getattr(pyo3::intern!(py, "_issuer_name"))?; + let py_this_update = builder.getattr(pyo3::intern!(py, "_last_update"))?; + let py_next_update = builder.getattr(pyo3::intern!(py, "_next_update"))?; let tbs_cert_list = TBSCertList { version: Some(1), signature: sigalg.clone(), @@ -690,7 +690,7 @@ fn create_x509_crl( }, crl_extensions: x509::common::encode_extensions( py, - builder.getattr(crate::intern!(py, "_extensions"))?, + builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, )?, }; diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 8a7f533041c1..0a6c7cbd8fc1 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -114,7 +114,7 @@ impl CertificateSigningRequest { ); Ok(py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "load_der_public_key"))? + .getattr(pyo3::intern!(py, "load_der_public_key"))? .call1((serialized,))?) } @@ -147,7 +147,7 @@ impl CertificateSigningRequest { ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? - .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), @@ -185,7 +185,7 @@ impl CertificateSigningRequest { ) -> pyo3::PyResult<&'p pyo3::PyAny> { let cryptography_warning = py .import("cryptography.utils")? - .getattr(crate::intern!(py, "DeprecatedIn36"))?; + .getattr(pyo3::intern!(py, "DeprecatedIn36"))?; pyo3::PyErr::warn( py, cryptography_warning, @@ -308,7 +308,7 @@ fn load_der_x509_csr( let x509_module = py.import("cryptography.x509")?; return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module - .getattr(crate::intern!(py, "InvalidVersion"))? + .getattr(pyo3::intern!(py, "InvalidVersion"))? .call1((format!("{} is not a valid CSR version", version), version))?, ))); } @@ -329,11 +329,11 @@ fn create_x509_csr( let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let der_encoding = serialization_mod - .getattr(crate::intern!(py, "Encoding"))? - .getattr(crate::intern!(py, "DER"))?; + .getattr(pyo3::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "DER"))?; let spki_format = serialization_mod - .getattr(crate::intern!(py, "PublicFormat"))? - .getattr(crate::intern!(py, "SubjectPublicKeyInfo"))?; + .getattr(pyo3::intern!(py, "PublicFormat"))? + .getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?; let spki_bytes = private_key .call_method0("public_key")? @@ -344,7 +344,7 @@ fn create_x509_csr( let ext_bytes; if let Some(exts) = x509::common::encode_extensions( py, - builder.getattr(crate::intern!(py, "_extensions"))?, + builder.getattr(pyo3::intern!(py, "_extensions"))?, x509::extensions::encode_extension, )? { ext_bytes = asn1::write_single(&exts)?; @@ -356,7 +356,7 @@ fn create_x509_csr( }) } - for py_attr in builder.getattr(crate::intern!(py, "_attributes"))?.iter()? { + for py_attr in builder.getattr(pyo3::intern!(py, "_attributes"))?.iter()? { let (py_oid, value, tag): (&pyo3::PyAny, &[u8], Option) = py_attr?.extract()?; let oid = py_oid_to_oid(py_oid)?; let tag = if let Some(tag) = tag { @@ -380,7 +380,7 @@ fn create_x509_csr( }) } - let py_subject_name = builder.getattr(crate::intern!(py, "_subject_name"))?; + let py_subject_name = builder.getattr(pyo3::intern!(py, "_subject_name"))?; let csr_info = CertificationRequestInfo { version: 0, diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 1af8d389de72..d5473a576735 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -129,7 +129,7 @@ pub(crate) fn encode_extension( } &oid::SUBJECT_KEY_IDENTIFIER_OID => { let digest = ext - .getattr(crate::intern!(py, "digest"))? + .getattr(pyo3::intern!(py, "digest"))? .extract::<&[u8]>()?; Ok(Some(asn1::write_single(&digest)?)) } @@ -138,59 +138,52 @@ pub(crate) fn encode_extension( certificate::set_bit( &mut bs, 0, - ext.getattr(crate::intern!(py, "digital_signature"))? + ext.getattr(pyo3::intern!(py, "digital_signature"))? .is_true()?, ); certificate::set_bit( &mut bs, 1, - ext.getattr(crate::intern!(py, "content_commitment"))? + ext.getattr(pyo3::intern!(py, "content_commitment"))? .is_true()?, ); certificate::set_bit( &mut bs, 2, - ext.getattr(crate::intern!(py, "key_encipherment"))? + ext.getattr(pyo3::intern!(py, "key_encipherment"))? .is_true()?, ); certificate::set_bit( &mut bs, 3, - ext.getattr(crate::intern!(py, "data_encipherment"))? + ext.getattr(pyo3::intern!(py, "data_encipherment"))? .is_true()?, ); certificate::set_bit( &mut bs, 4, - ext.getattr(crate::intern!(py, "key_agreement"))? - .is_true()?, + ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()?, ); certificate::set_bit( &mut bs, 5, - ext.getattr(crate::intern!(py, "key_cert_sign"))? - .is_true()?, + ext.getattr(pyo3::intern!(py, "key_cert_sign"))?.is_true()?, ); certificate::set_bit( &mut bs, 6, - ext.getattr(crate::intern!(py, "crl_sign"))?.is_true()?, + ext.getattr(pyo3::intern!(py, "crl_sign"))?.is_true()?, ); - if ext - .getattr(crate::intern!(py, "key_agreement"))? - .is_true()? - { + if ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()? { certificate::set_bit( &mut bs, 7, - ext.getattr(crate::intern!(py, "encipher_only"))? - .is_true()?, + ext.getattr(pyo3::intern!(py, "encipher_only"))?.is_true()?, ); certificate::set_bit( &mut bs, 8, - ext.getattr(crate::intern!(py, "decipher_only"))? - .is_true()?, + ext.getattr(pyo3::intern!(py, "decipher_only"))?.is_true()?, ); } let (bits, unused_bits) = if bs[1] == 0 { @@ -224,7 +217,7 @@ pub(crate) fn encode_extension( for py_policy_info in ext.iter()? { let py_policy_info = py_policy_info?; let py_policy_qualifiers = - py_policy_info.getattr(crate::intern!(py, "policy_qualifiers"))?; + py_policy_info.getattr(pyo3::intern!(py, "policy_qualifiers"))?; let qualifiers = if py_policy_qualifiers.is_true()? { let mut qualifiers = vec![]; for py_qualifier in py_policy_qualifiers.iter()? { @@ -245,11 +238,11 @@ pub(crate) fn encode_extension( } } else { let py_notice = - py_qualifier.getattr(crate::intern!(py, "notice_reference"))?; + py_qualifier.getattr(pyo3::intern!(py, "notice_reference"))?; let notice_ref = if py_notice.is_true()? { let mut notice_numbers = vec![]; for py_num in py_notice - .getattr(crate::intern!(py, "notice_numbers"))? + .getattr(pyo3::intern!(py, "notice_numbers"))? .iter()? { let bytes = @@ -261,7 +254,7 @@ pub(crate) fn encode_extension( organization: certificate::DisplayText::Utf8String( asn1::Utf8String::new( py_notice - .getattr(crate::intern!(py, "organization"))? + .getattr(pyo3::intern!(py, "organization"))? .extract()?, ), ), @@ -273,7 +266,7 @@ pub(crate) fn encode_extension( None }; let py_explicit_text = - py_qualifier.getattr(crate::intern!(py, "explicit_text"))?; + py_qualifier.getattr(pyo3::intern!(py, "explicit_text"))?; let explicit_text = if py_explicit_text.is_true()? { Some(certificate::DisplayText::Utf8String(asn1::Utf8String::new( py_explicit_text.extract()?, @@ -301,7 +294,7 @@ pub(crate) fn encode_extension( None }; let py_policy_id = - py_policy_info.getattr(crate::intern!(py, "policy_identifier"))?; + py_policy_info.getattr(pyo3::intern!(py, "policy_identifier"))?; policy_informations.push(certificate::PolicyInformation { policy_identifier: py_oid_to_oid(py_policy_id)?, policy_qualifiers: qualifiers, @@ -314,17 +307,17 @@ pub(crate) fn encode_extension( &oid::POLICY_CONSTRAINTS_OID => { let pc = certificate::PolicyConstraints { require_explicit_policy: ext - .getattr(crate::intern!(py, "require_explicit_policy"))? + .getattr(pyo3::intern!(py, "require_explicit_policy"))? .extract()?, inhibit_policy_mapping: ext - .getattr(crate::intern!(py, "inhibit_policy_mapping"))? + .getattr(pyo3::intern!(py, "inhibit_policy_mapping"))? .extract()?, }; Ok(Some(asn1::write_single(&pc)?)) } &oid::NAME_CONSTRAINTS_OID => { - let permitted = ext.getattr(crate::intern!(py, "permitted_subtrees"))?; - let excluded = ext.getattr(crate::intern!(py, "excluded_subtrees"))?; + let permitted = ext.getattr(pyo3::intern!(py, "permitted_subtrees"))?; + let excluded = ext.getattr(pyo3::intern!(py, "excluded_subtrees"))?; let nc = certificate::NameConstraints { permitted_subtrees: encode_general_subtrees(ext.py(), permitted)?, excluded_subtrees: encode_general_subtrees(ext.py(), excluded)?, @@ -333,7 +326,7 @@ pub(crate) fn encode_extension( } &oid::INHIBIT_ANY_POLICY_OID => { let intval = ext - .getattr(crate::intern!(py, "skip_certs"))? + .getattr(pyo3::intern!(py, "skip_certs"))? .downcast::()?; let bytes = py_uint_to_big_endian_bytes(ext.py(), intval)?; Ok(Some(asn1::write_single( @@ -360,7 +353,7 @@ pub(crate) fn encode_extension( // from Python. let mut els = vec![]; for el in ext.iter()? { - els.push(el?.getattr(crate::intern!(py, "value"))?.extract::()?); + els.push(el?.getattr(pyo3::intern!(py, "value"))?.extract::()?); } Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(els))?)) @@ -387,8 +380,8 @@ pub(crate) fn encode_extension( let value = ext .py() .import("cryptography.hazmat.backends.openssl.decode_asn1")? - .getattr(crate::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? - .get_item(ext.getattr(crate::intern!(py, "reason"))?)? + .getattr(pyo3::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? + .get_item(ext.getattr(pyo3::intern!(py, "reason"))?)? .extract::()?; Ok(Some(asn1::write_single(&asn1::Enumerated::new(value))?)) } @@ -398,14 +391,14 @@ pub(crate) fn encode_extension( } &oid::INVALIDITY_DATE_OID => { let chrono_dt = - x509::py_to_chrono(py, ext.getattr(crate::intern!(py, "invalidity_date"))?)?; + x509::py_to_chrono(py, ext.getattr(pyo3::intern!(py, "invalidity_date"))?)?; Ok(Some(asn1::write_single(&asn1::GeneralizedTime::new( chrono_dt, )?)?)) } &oid::CRL_NUMBER_OID | &oid::DELTA_CRL_INDICATOR_OID => { let intval = ext - .getattr(crate::intern!(py, "crl_number"))? + .getattr(pyo3::intern!(py, "crl_number"))? .downcast::()?; let bytes = py_uint_to_big_endian_bytes(ext.py(), intval)?; Ok(Some(asn1::write_single( @@ -414,27 +407,24 @@ pub(crate) fn encode_extension( } &oid::ISSUING_DISTRIBUTION_POINT_OID => { let only_some_reasons = if ext - .getattr(crate::intern!(py, "only_some_reasons"))? + .getattr(pyo3::intern!(py, "only_some_reasons"))? .is_true()? { - let py_reasons = ext.getattr(crate::intern!(py, "only_some_reasons"))?; + let py_reasons = ext.getattr(pyo3::intern!(py, "only_some_reasons"))?; let reasons = certificate::encode_distribution_point_reasons(ext.py(), py_reasons)?; Some(x509::Asn1ReadableOrWritable::new_write(reasons)) } else { None }; - let distribution_point = if ext.getattr(crate::intern!(py, "full_name"))?.is_true()? { - let py_full_name = ext.getattr(crate::intern!(py, "full_name"))?; + let distribution_point = if ext.getattr(pyo3::intern!(py, "full_name"))?.is_true()? { + let py_full_name = ext.getattr(pyo3::intern!(py, "full_name"))?; let gns = x509::common::encode_general_names(ext.py(), py_full_name)?; Some(certificate::DistributionPointName::FullName( x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), )) - } else if ext - .getattr(crate::intern!(py, "relative_name"))? - .is_true()? - { + } else if ext.getattr(pyo3::intern!(py, "relative_name"))?.is_true()? { let mut name_entries = vec![]; - for py_name_entry in ext.getattr(crate::intern!(py, "relative_name"))?.iter()? { + for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? { name_entries.push(x509::common::encode_name_entry(ext.py(), py_name_entry?)?); } Some(certificate::DistributionPointName::NameRelativeToCRLIssuer( @@ -446,15 +436,15 @@ pub(crate) fn encode_extension( let idp = crl::IssuingDistributionPoint { distribution_point, - indirect_crl: ext.getattr(crate::intern!(py, "indirect_crl"))?.extract()?, + indirect_crl: ext.getattr(pyo3::intern!(py, "indirect_crl"))?.extract()?, only_contains_attribute_certs: ext - .getattr(crate::intern!(py, "only_contains_attribute_certs"))? + .getattr(pyo3::intern!(py, "only_contains_attribute_certs"))? .extract()?, only_contains_ca_certs: ext - .getattr(crate::intern!(py, "only_contains_ca_certs"))? + .getattr(pyo3::intern!(py, "only_contains_ca_certs"))? .extract()?, only_contains_user_certs: ext - .getattr(crate::intern!(py, "only_contains_user_certs"))? + .getattr(pyo3::intern!(py, "only_contains_user_certs"))? .extract()?, only_some_reasons, }; @@ -462,7 +452,7 @@ pub(crate) fn encode_extension( } &oid::NONCE_OID => { let nonce = ext - .getattr(crate::intern!(py, "nonce"))? + .getattr(pyo3::intern!(py, "nonce"))? .extract::<&[u8]>()?; Ok(Some(asn1::write_single(&nonce)?)) } diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index a06e7f1cc278..2b10291b8c1e 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -60,7 +60,7 @@ impl CertID<'_> { Ok(CertID { hash_algorithm: x509::AlgorithmIdentifier { oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(crate::intern!(py, "name"))? + .getattr(pyo3::intern!(py, "name"))? .extract::<&str>()?] .clone(), params: Some(*x509::sign::NULL_TLV), @@ -81,7 +81,7 @@ impl CertID<'_> { Ok(CertID { hash_algorithm: x509::AlgorithmIdentifier { oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(crate::intern!(py, "name"))? + .getattr(pyo3::intern!(py, "name"))? .extract::<&str>()?] .clone(), params: Some(*x509::sign::NULL_TLV), @@ -100,7 +100,7 @@ pub(crate) fn hash_data<'p>( ) -> pyo3::PyResult<&'p [u8]> { let hash = py .import("cryptography.hazmat.primitives.hashes")? - .getattr(crate::intern!(py, "Hash"))? + .getattr(pyo3::intern!(py, "Hash"))? .call1((py_hash_alg,))?; hash.call_method1("update", (data,))?; hash.call_method0("finalize")?.extract() diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 5711dd4a9546..66dc862fd96b 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -88,7 +88,7 @@ impl OCSPRequest { let exceptions = py.import("cryptography.exceptions")?; Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions - .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? + .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( "Signature algorithm OID: {} not recognized", cert_id.hash_algorithm.oid @@ -139,8 +139,8 @@ impl OCSPRequest { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "Encoding"))? - .getattr(crate::intern!(py, "DER"))?; + .getattr(pyo3::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "DER"))?; if !encoding.is(der) { return Err(pyo3::exceptions::PyValueError::new_err( "The only allowed encoding value is Encoding.DER", @@ -190,7 +190,7 @@ fn create_ocsp_request( py: pyo3::Python<'_>, builder: &pyo3::PyAny, ) -> CryptographyResult { - let builder_request = builder.getattr(crate::intern!(py, "_request"))?; + let builder_request = builder.getattr(pyo3::intern!(py, "_request"))?; // Declare outside the if-block so the lifetimes are right. let (py_cert, py_issuer, py_hash): ( @@ -215,7 +215,7 @@ fn create_ocsp_request( &pyo3::types::PyLong, &pyo3::PyAny, ) = builder - .getattr(crate::intern!(py, "_request_hash"))? + .getattr(pyo3::intern!(py, "_request_hash"))? .extract()?; let serial_number = asn1::BigInt::new(py_uint_to_big_endian_bytes(py, py_serial)?).unwrap(); ocsp::CertID::new_from_hash( @@ -229,7 +229,7 @@ fn create_ocsp_request( let extensions = x509::common::encode_extensions( py, - builder.getattr(crate::intern!(py, "_extensions"))?, + builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, )?; let reqs = [Request { diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 9f38282931bc..ff8050abe0b0 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -133,7 +133,7 @@ impl OCSPResponse { "UNAUTHORIZED" }; py.import("cryptography.x509.ocsp")? - .getattr(crate::intern!(py, "OCSPResponseStatus"))? + .getattr(pyo3::intern!(py, "OCSPResponseStatus"))? .getattr(attr) } @@ -174,7 +174,7 @@ impl OCSPResponse { ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py .import("cryptography.hazmat._oid")? - .getattr(crate::intern!(py, "_SIG_OIDS_TO_HASH"))?; + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), @@ -365,7 +365,7 @@ impl OCSPResponse { let scts = sct::parse_scts(py, contents, sct::LogEntryType::Certificate)?; Ok(Some( x509_module - .getattr(crate::intern!(py, "SignedCertificateTimestamps"))? + .getattr(pyo3::intern!(py, "SignedCertificateTimestamps"))? .call1((scts,))?, )) } @@ -381,8 +381,8 @@ impl OCSPResponse { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py .import("cryptography.hazmat.primitives.serialization")? - .getattr(crate::intern!(py, "Encoding"))? - .getattr(crate::intern!(py, "DER"))?; + .getattr(pyo3::intern!(py, "Encoding"))? + .getattr(pyo3::intern!(py, "DER"))?; if !encoding.is(der) { return Err(pyo3::exceptions::PyValueError::new_err( "The only allowed encoding value is Encoding.DER", @@ -518,7 +518,7 @@ impl SingleResponse<'_> { CertStatus::Unknown(_) => "UNKNOWN", }; py.import("cryptography.x509.ocsp")? - .getattr(crate::intern!(py, "OCSPCertStatus"))? + .getattr(pyo3::intern!(py, "OCSPCertStatus"))? .getattr(attr) } @@ -533,7 +533,7 @@ impl SingleResponse<'_> { let exceptions = py.import("cryptography.exceptions")?; Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions - .getattr(crate::intern!(py, "UnsupportedAlgorithm"))? + .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? .call1((format!( "Signature algorithm OID: {} not recognized", self.cert_id.hash_algorithm.oid @@ -603,7 +603,7 @@ fn create_ocsp_response( hash_algorithm: &pyo3::PyAny, ) -> CryptographyResult { let response_status = status - .getattr(crate::intern!(py, "value"))? + .getattr(pyo3::intern!(py, "value"))? .extract::()?; let py_cert: pyo3::PyRef<'_, x509::Certificate>; @@ -613,39 +613,39 @@ fn create_ocsp_response( let response_bytes = if response_status == SUCCESSFUL_RESPONSE { let ocsp_mod = py.import("cryptography.x509.ocsp")?; - let py_single_resp = builder.getattr(crate::intern!(py, "_response"))?; + let py_single_resp = builder.getattr(pyo3::intern!(py, "_response"))?; py_cert = py_single_resp - .getattr(crate::intern!(py, "_cert"))? + .getattr(pyo3::intern!(py, "_cert"))? .extract()?; py_issuer = py_single_resp - .getattr(crate::intern!(py, "_issuer"))? + .getattr(pyo3::intern!(py, "_issuer"))? .extract()?; - let py_cert_hash_algorithm = py_single_resp.getattr(crate::intern!(py, "_algorithm"))?; + let py_cert_hash_algorithm = py_single_resp.getattr(pyo3::intern!(py, "_algorithm"))?; let (responder_cert, responder_encoding): (&pyo3::PyCell, &pyo3::PyAny) = builder - .getattr(crate::intern!(py, "_responder_id"))? + .getattr(pyo3::intern!(py, "_responder_id"))? .extract()?; - let py_cert_status = py_single_resp.getattr(crate::intern!(py, "_cert_status"))?; + let py_cert_status = py_single_resp.getattr(pyo3::intern!(py, "_cert_status"))?; let cert_status = if py_cert_status.is(ocsp_mod - .getattr(crate::intern!(py, "OCSPCertStatus"))? - .getattr(crate::intern!(py, "GOOD"))?) + .getattr(pyo3::intern!(py, "OCSPCertStatus"))? + .getattr(pyo3::intern!(py, "GOOD"))?) { CertStatus::Good(()) } else if py_cert_status.is(ocsp_mod - .getattr(crate::intern!(py, "OCSPCertStatus"))? - .getattr(crate::intern!(py, "UNKNOWN"))?) + .getattr(pyo3::intern!(py, "OCSPCertStatus"))? + .getattr(pyo3::intern!(py, "UNKNOWN"))?) { CertStatus::Unknown(()) } else { let revocation_reason = if !py_single_resp - .getattr(crate::intern!(py, "_revocation_reason"))? + .getattr(pyo3::intern!(py, "_revocation_reason"))? .is_none() { let value = py .import("cryptography.hazmat.backends.openssl.decode_asn1")? - .getattr(crate::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? - .get_item(py_single_resp.getattr(crate::intern!(py, "_revocation_reason"))?)? + .getattr(pyo3::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? + .get_item(py_single_resp.getattr(pyo3::intern!(py, "_revocation_reason"))?)? .extract::()?; Some(asn1::Enumerated::new(value)) } else { @@ -653,7 +653,7 @@ fn create_ocsp_response( }; // REVOKED let py_revocation_time = - py_single_resp.getattr(crate::intern!(py, "_revocation_time"))?; + py_single_resp.getattr(pyo3::intern!(py, "_revocation_time"))?; let revocation_time = asn1::GeneralizedTime::new(py_to_chrono(py, py_revocation_time)?)?; CertStatus::Revoked(RevokedInfo { @@ -662,10 +662,10 @@ fn create_ocsp_response( }) }; let next_update = if !py_single_resp - .getattr(crate::intern!(py, "_next_update"))? + .getattr(pyo3::intern!(py, "_next_update"))? .is_none() { - let py_next_update = py_single_resp.getattr(crate::intern!(py, "_next_update"))?; + let py_next_update = py_single_resp.getattr(pyo3::intern!(py, "_next_update"))?; Some(asn1::GeneralizedTime::new(py_to_chrono( py, py_next_update, @@ -673,7 +673,7 @@ fn create_ocsp_response( } else { None }; - let py_this_update = py_single_resp.getattr(crate::intern!(py, "_this_update"))?; + let py_this_update = py_single_resp.getattr(pyo3::intern!(py, "_this_update"))?; let this_update = asn1::GeneralizedTime::new(py_to_chrono(py, py_this_update)?)?; let responses = vec![SingleResponse { @@ -686,12 +686,12 @@ fn create_ocsp_response( borrowed_cert = responder_cert.borrow(); let responder_id = if responder_encoding.is(ocsp_mod - .getattr(crate::intern!(py, "OCSPResponderEncoding"))? - .getattr(crate::intern!(py, "HASH"))?) + .getattr(pyo3::intern!(py, "OCSPResponderEncoding"))? + .getattr(pyo3::intern!(py, "HASH"))?) { let sha1 = py .import("cryptography.hazmat.primitives.hashes")? - .getattr(crate::intern!(py, "SHA1"))? + .getattr(pyo3::intern!(py, "SHA1"))? .call0()?; ResponderId::ByKey(ocsp::hash_data( py, @@ -726,7 +726,7 @@ fn create_ocsp_response( )), response_extensions: x509::common::encode_extensions( py, - builder.getattr(crate::intern!(py, "_extensions"))?, + builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, )?, }; @@ -736,7 +736,7 @@ fn create_ocsp_response( let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; py.import("cryptography.hazmat.backends.openssl.backend")? - .getattr(crate::intern!(py, "backend"))? + .getattr(pyo3::intern!(py, "backend"))? .call_method1( "_check_keys_correspond", ( @@ -745,7 +745,7 @@ fn create_ocsp_response( ), )?; - py_certs = builder.getattr(crate::intern!(py, "_certs"))?.extract()?; + py_certs = builder.getattr(pyo3::intern!(py, "_certs"))?.extract()?; let certs = py_certs.as_ref().map(|py_certs| { x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( py_certs diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index b6b2e56dab86..4b8414e109d3 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -166,8 +166,8 @@ impl Sct { #[getter] fn version<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { py.import("cryptography.x509.certificate_transparency")? - .getattr(crate::intern!(py, "Version"))? - .getattr(crate::intern!(py, "v1")) + .getattr(pyo3::intern!(py, "Version"))? + .getattr(pyo3::intern!(py, "v1")) } #[getter] @@ -179,7 +179,7 @@ impl Sct { fn timestamp<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let datetime_class = py .import("datetime")? - .getattr(crate::intern!(py, "datetime"))?; + .getattr(pyo3::intern!(py, "datetime"))?; datetime_class .call_method1("utcfromtimestamp", (self.timestamp / 1000,))? .call_method( @@ -193,7 +193,7 @@ impl Sct { fn entry_type<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let et_class = py .import("cryptography.x509.certificate_transparency")? - .getattr(crate::intern!(py, "LogEntryType"))?; + .getattr(pyo3::intern!(py, "LogEntryType"))?; let attr_name = match self.entry_type { LogEntryType::Certificate => "X509_CERTIFICATE", LogEntryType::PreCertificate => "PRE_CERTIFICATE", @@ -214,7 +214,7 @@ impl Sct { fn signature_algorithm<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let sa_class = py .import("cryptography.x509.certificate_transparency")? - .getattr(crate::intern!(py, "SignatureAlgorithm"))?; + .getattr(pyo3::intern!(py, "SignatureAlgorithm"))?; sa_class.getattr(self.signature_algorithm.to_attr()) } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 4d505ece7886..7a788300ebbf 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -40,23 +40,23 @@ enum HashType { fn identify_key_type(py: pyo3::Python<'_>, private_key: &pyo3::PyAny) -> pyo3::PyResult { let rsa_private_key: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.rsa")? - .getattr(crate::intern!(py, "RSAPrivateKey"))? + .getattr(pyo3::intern!(py, "RSAPrivateKey"))? .extract()?; let dsa_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.dsa")? - .getattr(crate::intern!(py, "DSAPrivateKey"))? + .getattr(pyo3::intern!(py, "DSAPrivateKey"))? .extract()?; let ec_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ec")? - .getattr(crate::intern!(py, "EllipticCurvePrivateKey"))? + .getattr(pyo3::intern!(py, "EllipticCurvePrivateKey"))? .extract()?; let ed25519_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ed25519")? - .getattr(crate::intern!(py, "Ed25519PrivateKey"))? + .getattr(pyo3::intern!(py, "Ed25519PrivateKey"))? .extract()?; let ed448_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ed448")? - .getattr(crate::intern!(py, "Ed448PrivateKey"))? + .getattr(pyo3::intern!(py, "Ed448PrivateKey"))? .extract()?; if private_key.is_instance(rsa_private_key)? { @@ -86,7 +86,7 @@ fn identify_hash_type( let hash_algorithm_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.hashes")? - .getattr(crate::intern!(py, "HashAlgorithm"))? + .getattr(pyo3::intern!(py, "HashAlgorithm"))? .extract()?; if !hash_algorithm.is_instance(hash_algorithm_type)? { return Err(pyo3::exceptions::PyTypeError::new_err( @@ -95,7 +95,7 @@ fn identify_hash_type( } match hash_algorithm - .getattr(crate::intern!(py, "name"))? + .getattr(pyo3::intern!(py, "name"))? .extract()? { "sha224" => Ok(HashType::Sha224), @@ -251,14 +251,14 @@ pub(crate) fn sign_data<'p>( KeyType::Ec => { let ec_mod = py.import("cryptography.hazmat.primitives.asymmetric.ec")?; let ecdsa = ec_mod - .getattr(crate::intern!(py, "ECDSA"))? + .getattr(pyo3::intern!(py, "ECDSA"))? .call1((hash_algorithm,))?; private_key.call_method1("sign", (data, ecdsa))? } KeyType::Rsa => { let padding_mod = py.import("cryptography.hazmat.primitives.asymmetric.padding")?; let pkcs1v15 = padding_mod - .getattr(crate::intern!(py, "PKCS1v15"))? + .getattr(pyo3::intern!(py, "PKCS1v15"))? .call0()?; private_key.call_method1("sign", (data, pkcs1v15, hash_algorithm))? } @@ -311,14 +311,14 @@ pub(crate) fn verify_signature_with_oid<'p>( KeyType::Ec => { let ec_mod = py.import("cryptography.hazmat.primitives.asymmetric.ec")?; let ecdsa = ec_mod - .getattr(crate::intern!(py, "ECDSA"))? + .getattr(pyo3::intern!(py, "ECDSA"))? .call1((signature_hash,))?; issuer_public_key.call_method1("verify", (signature, data, ecdsa))? } KeyType::Rsa => { let padding_mod = py.import("cryptography.hazmat.primitives.asymmetric.padding")?; let pkcs1v15 = padding_mod - .getattr(crate::intern!(py, "PKCS1v15"))? + .getattr(pyo3::intern!(py, "PKCS1v15"))? .call0()?; issuer_public_key.call_method1("verify", (signature, data, pkcs1v15, signature_hash))? } @@ -335,23 +335,23 @@ pub(crate) fn identify_public_key_type( ) -> pyo3::PyResult { let rsa_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.rsa")? - .getattr(crate::intern!(py, "RSAPublicKey"))? + .getattr(pyo3::intern!(py, "RSAPublicKey"))? .extract()?; let dsa_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.dsa")? - .getattr(crate::intern!(py, "DSAPublicKey"))? + .getattr(pyo3::intern!(py, "DSAPublicKey"))? .extract()?; let ec_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ec")? - .getattr(crate::intern!(py, "EllipticCurvePublicKey"))? + .getattr(pyo3::intern!(py, "EllipticCurvePublicKey"))? .extract()?; let ed25519_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ed25519")? - .getattr(crate::intern!(py, "Ed25519PublicKey"))? + .getattr(pyo3::intern!(py, "Ed25519PublicKey"))? .extract()?; let ed448_key_type: &pyo3::types::PyType = py .import("cryptography.hazmat.primitives.asymmetric.ed448")? - .getattr(crate::intern!(py, "Ed448PublicKey"))? + .getattr(pyo3::intern!(py, "Ed448PublicKey"))? .extract()?; if public_key.is_instance(rsa_key_type)? { From e565402f2fed15fad00680e40b8c78dfd4c08d58 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 18:16:56 -0400 Subject: [PATCH 521/827] Add benchmark for loading DER certificates (#8597) --- tests/bench/test_x509.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/bench/test_x509.py b/tests/bench/test_x509.py index 8a36d3b5fa48..87a60af0f597 100644 --- a/tests/bench/test_x509.py +++ b/tests/bench/test_x509.py @@ -22,6 +22,16 @@ def test_aki_public_bytes(benchmark): benchmark(aki.public_bytes) +def test_load_der_certificate(benchmark): + cert_bytes = load_vectors_from_file( + os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), + loader=lambda pemfile: pemfile.read(), + mode="rb", + ) + + benchmark(x509.load_der_x509_certificate, cert_bytes) + + def test_load_pem_certificate(benchmark): cert_bytes = load_vectors_from_file( os.path.join("x509", "cryptography.io.pem"), From ddb95f53a86b4d5bcc3905d76e1ace75edcef34d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 18:42:27 -0400 Subject: [PATCH 522/827] Use sparse protocol in bench (#8599) --- .github/workflows/benchmark.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index ced2eee2ab75..325d4e81eb1a 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -12,6 +12,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true +env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + jobs: benchmark: runs-on: ubuntu-latest From 9091c369476a59edbac7c373a936341cb6daf1b0 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 00:21:25 +0000 Subject: [PATCH 523/827] Bump BoringSSL and/or OpenSSL in CI (#8601) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d9f7ed9f0ad..c164da3f4b9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 23, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "b6a50fd62d1ae44ad211ebe26f803c66db444302"}} + # Latest commit on the BoringSSL master branch, as of Mar 25, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "2e13e36e7477cfe2ef48312634b1c34103da4899"}} # Latest commit on the OpenSSL master branch, as of Mar 24, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "908ba3ed9adbb3df90f7684a3111ca916a45202d"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" From 0f0247198decdaa4c26fbdf85534ae3929f4fef6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 24 Mar 2023 20:51:14 -0400 Subject: [PATCH 524/827] Fix handling very large pointer values (32-bit) (#8602) --- src/cryptography/hazmat/backends/openssl/backend.py | 4 ++-- src/cryptography/utils.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index facdb48a03a8..5876563695b5 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -650,7 +650,7 @@ def _evp_pkey_to_private_key( return _X448PrivateKey(self, evp_pkey) elif key_type == self._lib.EVP_PKEY_X25519: return rust_openssl.x25519.private_key_from_ptr( - int(self._ffi.cast("intptr_t", evp_pkey)) + int(self._ffi.cast("uintptr_t", evp_pkey)) ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL @@ -709,7 +709,7 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: return _X448PublicKey(self, evp_pkey) elif key_type == self._lib.EVP_PKEY_X25519: return rust_openssl.x25519.public_key_from_ptr( - int(self._ffi.cast("intptr_t", evp_pkey)) + int(self._ffi.cast("uintptr_t", evp_pkey)) ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index da4067a8e6ed..9beea653e330 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -46,7 +46,7 @@ def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[int, int]: from cryptography.hazmat.bindings._rust import _openssl buf = _openssl.ffi.from_buffer(obj) - return int(_openssl.ffi.cast("intptr_t", buf)), len(buf) + return int(_openssl.ffi.cast("uintptr_t", buf)), len(buf) class InterfaceNotImplemented(Exception): From ed037df90e36cb9c3351254ab305883f12d250e5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 25 Mar 2023 09:25:51 +0800 Subject: [PATCH 525/827] port 40.0.1 changelog to main (#8604) --- CHANGELOG.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 02f12738c1d3..a0b5bf719a26 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,14 @@ Changelog * **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. * Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. +.. _v40-0-1: + +40.0.1 - 2023-03-24 +~~~~~~~~~~~~~~~~~~~ + +* Fixed a bug where certain operations would fail if an object happened to be + in the top-half of the memory-space. This only impacted 32-bit systems. + .. _v40-0-0: 40.0.0 - 2023-03-24 From 46509ea575baa3091540a659d6bcc5ab90aeae24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 01:59:22 +0000 Subject: [PATCH 526/827] Bump parking_lot from 0.11.2 to 0.12.1 in /src/rust (#8606) Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.11.2 to 0.12.1. - [Release notes](https://github.com/Amanieu/parking_lot/releases) - [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md) - [Commits](https://github.com/Amanieu/parking_lot/compare/0.11.2...0.12.1) --- updated-dependencies: - dependency-name: parking_lot dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2aabfbb66e66..96c12cb554a0 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -216,15 +216,6 @@ dependencies = [ "unindent", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "js-sys" version = "0.3.61" @@ -366,27 +357,25 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] @@ -683,6 +672,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.42.2" From 91cc99118e059c101387844eb4e24808437bda6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 01:59:33 +0000 Subject: [PATCH 527/827] Bump pyo3 from 0.18.1 to 0.18.2 in /src/rust (#8607) Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.18.1 to 0.18.2. - [Release notes](https://github.com/pyo3/pyo3/releases) - [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md) - [Commits](https://github.com/pyo3/pyo3/compare/v0.18.1...v0.18.2) --- updated-dependencies: - dependency-name: pyo3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 96c12cb554a0..d9733c38330b 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -428,9 +428,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06a3d8e8a46ab2738109347433cb7b96dffda2e4a218b03ef27090238886b147" +checksum = "cfb848f80438f926a9ebddf0a539ed6065434fd7aae03a89312a9821f81b8501" dependencies = [ "cfg-if", "indoc", @@ -445,9 +445,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75439f995d07ddfad42b192dfcf3bc66a7ecfd8b4a1f5f6f046aa5c2c5d7677d" +checksum = "98a42e7f42e917ce6664c832d5eee481ad514c98250c49e0b03b20593e2c7ed0" dependencies = [ "once_cell", "target-lexicon", @@ -455,9 +455,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "839526a5c07a17ff44823679b68add4a58004de00512a95b6c1c98a6dcac0ee5" +checksum = "a0707f0ab26826fe4ccd59b69106e9df5e12d097457c7b8f9c0fd1d2743eec4d" dependencies = [ "libc", "pyo3-build-config", @@ -465,9 +465,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd44cf207476c6a9760c4653559be4f206efafb924d3e4cbf2721475fc0d6cc5" +checksum = "978d18e61465ecd389e1f235ff5a467146dc4e3c3968b90d274fe73a5dd4a438" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -477,9 +477,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1f43d8e30460f36350d18631ccf85ded64c059829208fe680904c65bcd0a4c" +checksum = "8e0e1128f85ce3fca66e435e08aa2089a2689c1c48ce97803e13f63124058462" dependencies = [ "proc-macro2", "quote", From cfaaf82e44c0fbbc421693667b45be2871f84f9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 02:15:43 +0000 Subject: [PATCH 528/827] Bump filelock from 3.10.3 to 3.10.4 (#8605) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.3 to 3.10.4. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.3...3.10.4) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d55b250ebfb3..8f59ed792e57 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # via pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.3 +filelock==3.10.4 # via # tox # virtualenv From e2b7fc4b53fef2848dc9567d9915aae9804203ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 02:24:38 +0000 Subject: [PATCH 529/827] Bump indoc from 1.0.4 to 1.0.9 in /src/rust (#8610) Bumps [indoc](https://github.com/dtolnay/indoc) from 1.0.4 to 1.0.9. - [Release notes](https://github.com/dtolnay/indoc/releases) - [Commits](https://github.com/dtolnay/indoc/compare/1.0.4...1.0.9) --- updated-dependencies: - dependency-name: indoc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index d9733c38330b..ac34af03f27d 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -209,12 +209,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e" -dependencies = [ - "unindent", -] +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "js-sys" From 1c0c2d41561fc911469425ee9a6a617b865e42a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Mar 2023 02:28:29 +0000 Subject: [PATCH 530/827] Bump target-lexicon from 0.12.4 to 0.12.6 in /src/rust (#8608) Bumps [target-lexicon](https://github.com/bytecodealliance/target-lexicon) from 0.12.4 to 0.12.6. - [Release notes](https://github.com/bytecodealliance/target-lexicon/releases) - [Commits](https://github.com/bytecodealliance/target-lexicon/compare/v0.12.4...v0.12.6) --- updated-dependencies: - dependency-name: target-lexicon dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index ac34af03f27d..927039d5f424 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -532,9 +532,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" +checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" [[package]] name = "termcolor" From d5ca0d8c9b57203ee6022d7289dcdeb4e0d22450 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 25 Mar 2023 02:35:52 -0400 Subject: [PATCH 531/827] Additional MSRV comments (#8611) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c164da3f4b9b..2d89e25133d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -252,8 +252,10 @@ jobs: PYTHON: - {VERSION: "3.11", TOXENV: "py311"} RUST: + # Potential future MSRVs: # 1.60 - new version of cxx - 1.60.0 + # 1.67 - new version of pem - beta - nightly name: "Rust Coverage" From 4ea157805fe4c86b1230eee791cf404aef61c376 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 25 Mar 2023 06:57:32 -0400 Subject: [PATCH 532/827] Store X.509 structure contents as PyBytes (#8598) This avoids a copy when we're loading from DER. There's still an extra copy when loading from PEM. --- src/rust/src/x509/certificate.rs | 30 +++++++++++++++++++----------- src/rust/src/x509/crl.rs | 19 ++++++++++--------- src/rust/src/x509/csr.rs | 28 ++++++++++++++++++---------- src/rust/src/x509/ocsp_req.rs | 14 ++++++++------ src/rust/src/x509/ocsp_resp.rs | 23 ++++++++++++++--------- 5 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 219698fa54d5..3a76571e98c9 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -9,10 +9,9 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; use chrono::Datelike; -use pyo3::ToPyObject; +use pyo3::{IntoPy, ToPyObject}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -use std::sync::Arc; #[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] pub(crate) struct RawCertificate<'a> { @@ -56,7 +55,7 @@ pub(crate) struct SubjectPublicKeyInfo<'a> { #[ouroboros::self_referencing] pub(crate) struct OwnedRawCertificate { - data: Arc<[u8]>, + data: pyo3::Py, #[borrows(data)] #[covariant] @@ -66,8 +65,10 @@ pub(crate) struct OwnedRawCertificate { impl OwnedRawCertificate { // Re-expose ::new with `pub(crate)` visibility. pub(crate) fn new_public( - data: Arc<[u8]>, - value_ref_builder: impl for<'this> FnOnce(&'this Arc<[u8]>) -> RawCertificate<'this>, + data: pyo3::Py, + value_ref_builder: impl for<'this> FnOnce( + &'this pyo3::Py, + ) -> RawCertificate<'this>, ) -> OwnedRawCertificate { OwnedRawCertificate::new(data, value_ref_builder) } @@ -374,7 +375,10 @@ fn load_pem_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> CryptographyR |p| p.tag == "CERTIFICATE" || p.tag == "X509 CERTIFICATE", "Valid PEM but no BEGIN CERTIFICATE/END CERTIFICATE delimiters. Are you sure this is a certificate?", )?; - load_der_x509_certificate(py, &parsed.contents) + load_der_x509_certificate( + py, + pyo3::types::PyBytes::new(py, &parsed.contents).into_py(py), + ) } #[pyo3::prelude::pyfunction] @@ -385,7 +389,9 @@ fn load_pem_x509_certificates( let certs = pem::parse_many(data)? .iter() .filter(|p| p.tag == "CERTIFICATE" || p.tag == "X509 CERTIFICATE") - .map(|p| load_der_x509_certificate(py, &p.contents)) + .map(|p| { + load_der_x509_certificate(py, pyo3::types::PyBytes::new(py, &p.contents).into_py(py)) + }) .collect::, _>>()?; if certs.is_empty() { @@ -396,8 +402,11 @@ fn load_pem_x509_certificates( } #[pyo3::prelude::pyfunction] -fn load_der_x509_certificate(py: pyo3::Python<'_>, data: &[u8]) -> CryptographyResult { - let raw = OwnedRawCertificate::try_new(Arc::from(data), |data| asn1::parse_single(data))?; +fn load_der_x509_certificate( + py: pyo3::Python<'_>, + data: pyo3::Py, +) -> CryptographyResult { + let raw = OwnedRawCertificate::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; // Parse cert version immediately so we can raise error on parse if it is invalid. cert_version(py, raw.borrow_value().tbs_cert.version)?; // determine if the serial is negative and raise a warning if it is. We want to drop support @@ -1059,8 +1068,7 @@ fn create_x509_certificate( signature_alg: sigalg, signature: asn1::BitString::new(signature, 0).unwrap(), })?; - // TODO: extra copy as we round-trip through a slice - load_der_x509_certificate(py, &data) + load_der_x509_certificate(py, pyo3::types::PyBytes::new(py, &data).into_py(py)) } pub(crate) fn set_bit(vals: &mut [u8], n: usize, set: bool) { diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 5100c3afb6db..601268746459 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -8,18 +8,18 @@ use crate::asn1::{ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, extensions, oid, sign}; -use pyo3::ToPyObject; +use pyo3::{IntoPy, ToPyObject}; use std::convert::TryInto; use std::sync::Arc; #[pyo3::prelude::pyfunction] fn load_der_x509_crl( py: pyo3::Python<'_>, - data: &[u8], + data: pyo3::Py, ) -> Result { let raw = OwnedRawCertificateRevocationList::try_new( - Arc::from(data), - |data| asn1::parse_single(data), + data, + |data| asn1::parse_single(data.as_bytes(py)), |_| Ok(pyo3::once_cell::GILOnceCell::new()), )?; @@ -49,13 +49,15 @@ fn load_pem_x509_crl( |p| p.tag == "X509 CRL", "Valid PEM but no BEGIN X509 CRL/END X509 delimiters. Are you sure this is a CRL?", )?; - // TODO: Produces an extra copy - load_der_x509_crl(py, &block.contents) + load_der_x509_crl( + py, + pyo3::types::PyBytes::new(py, &block.contents).into_py(py), + ) } #[ouroboros::self_referencing] struct OwnedRawCertificateRevocationList { - data: Arc<[u8]>, + data: pyo3::Py, #[borrows(data)] #[covariant] value: RawCertificateRevocationList<'this>, @@ -702,8 +704,7 @@ fn create_x509_crl( signature_algorithm: sigalg, signature_value: asn1::BitString::new(signature, 0).unwrap(), })?; - // TODO: extra copy as we round-trip through a slice - load_der_x509_crl(py, &data) + load_der_x509_crl(py, pyo3::types::PyBytes::new(py, &data).into_py(py)) } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 0a6c7cbd8fc1..b920e5fe72f1 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -7,6 +7,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, oid, sign}; use asn1::SimpleAsn1Readable; +use pyo3::IntoPy; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -72,7 +73,7 @@ impl CertificationRequestInfo<'_> { #[ouroboros::self_referencing] struct OwnedRawCsr { - data: Vec, + data: pyo3::Py, #[borrows(data)] #[covariant] value: RawCsr<'this>, @@ -86,20 +87,25 @@ struct CertificateSigningRequest { #[pyo3::prelude::pymethods] impl CertificateSigningRequest { - fn __hash__(&self) -> u64 { + fn __hash__(&self, py: pyo3::Python<'_>) -> u64 { let mut hasher = DefaultHasher::new(); - self.raw.borrow_data().hash(&mut hasher); + self.raw.borrow_data().as_bytes(py).hash(&mut hasher); hasher.finish() } fn __richcmp__( &self, + py: pyo3::Python<'_>, other: pyo3::PyRef<'_, CertificateSigningRequest>, op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { - pyo3::basic::CompareOp::Eq => Ok(self.raw.borrow_data() == other.raw.borrow_data()), - pyo3::basic::CompareOp::Ne => Ok(self.raw.borrow_data() != other.raw.borrow_data()), + pyo3::basic::CompareOp::Eq => { + Ok(self.raw.borrow_data().as_bytes(py) == other.raw.borrow_data().as_bytes(py)) + } + pyo3::basic::CompareOp::Ne => { + Ok(self.raw.borrow_data().as_bytes(py) != other.raw.borrow_data().as_bytes(py)) + } _ => Err(pyo3::exceptions::PyTypeError::new_err( "CSRs cannot be ordered", )), @@ -293,15 +299,18 @@ fn load_pem_x509_csr( |p| p.tag == "CERTIFICATE REQUEST" || p.tag == "NEW CERTIFICATE REQUEST", "Valid PEM but no BEGIN CERTIFICATE REQUEST/END CERTIFICATE REQUEST delimiters. Are you sure this is a CSR?", )?; - load_der_x509_csr(py, &parsed.contents) + load_der_x509_csr( + py, + pyo3::types::PyBytes::new(py, &parsed.contents).into_py(py), + ) } #[pyo3::prelude::pyfunction] fn load_der_x509_csr( py: pyo3::Python<'_>, - data: &[u8], + data: pyo3::Py, ) -> CryptographyResult { - let raw = OwnedRawCsr::try_new(data.to_vec(), |data| asn1::parse_single(data))?; + let raw = OwnedRawCsr::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; let version = raw.borrow_value().csr_info.version; if version != 0 { @@ -396,8 +405,7 @@ fn create_x509_csr( signature_alg: sigalg, signature: asn1::BitString::new(signature, 0).unwrap(), })?; - // TODO: extra copy as we round-trip through a slice - load_der_x509_csr(py, &data) + load_der_x509_csr(py, pyo3::types::PyBytes::new(py, &data).into_py(py)) } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 66dc862fd96b..b239869d900d 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -6,19 +6,22 @@ use crate::asn1::{big_byte_slice_to_py_int, py_uint_to_big_endian_bytes}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{extensions, ocsp, oid}; -use std::sync::Arc; +use pyo3::IntoPy; #[ouroboros::self_referencing] struct OwnedRawOCSPRequest { - data: Arc<[u8]>, + data: pyo3::Py, #[borrows(data)] #[covariant] value: RawOCSPRequest<'this>, } #[pyo3::prelude::pyfunction] -fn load_der_ocsp_request(_py: pyo3::Python<'_>, data: &[u8]) -> CryptographyResult { - let raw = OwnedRawOCSPRequest::try_new(Arc::from(data), |data| asn1::parse_single(data))?; +fn load_der_ocsp_request( + py: pyo3::Python<'_>, + data: pyo3::Py, +) -> CryptographyResult { + let raw = OwnedRawOCSPRequest::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; if raw .borrow_value() @@ -248,8 +251,7 @@ fn create_ocsp_request( optional_signature: None, }; let data = asn1::write_single(&ocsp_req)?; - // TODO: extra copy as we round-trip through a slice - load_der_ocsp_request(py, &data) + load_der_ocsp_request(py, pyo3::types::PyBytes::new(py, &data).into_py(py)) } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index ff8050abe0b0..6913f5b177f6 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -7,16 +7,17 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_chrono, sct}; use chrono::Timelike; +use pyo3::IntoPy; use std::sync::Arc; const BASIC_RESPONSE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 1); #[pyo3::prelude::pyfunction] fn load_der_ocsp_response( - _py: pyo3::Python<'_>, - data: &[u8], + py: pyo3::Python<'_>, + data: pyo3::Py, ) -> Result { - let raw = OwnedRawOCSPResponse::try_new(Arc::from(data), |data| asn1::parse_single(data))?; + let raw = OwnedRawOCSPResponse::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; let response = raw.borrow_value(); match response.response_status.value() { @@ -58,7 +59,7 @@ fn load_der_ocsp_response( #[ouroboros::self_referencing] struct OwnedRawOCSPResponse { - data: Arc<[u8]>, + data: pyo3::Py, #[borrows(data)] #[covariant] value: RawOCSPResponse<'this>, @@ -217,7 +218,7 @@ impl OCSPResponse { }; for i in 0..certs.len() { // TODO: O(n^2), don't have too many certificates! - let raw_cert = map_arc_data_ocsp_response(&self.raw, |_data, resp| { + let raw_cert = map_arc_data_ocsp_response(py, &self.raw, |_data, resp| { resp.response_bytes .as_ref() .unwrap() @@ -397,14 +398,19 @@ impl OCSPResponse { // Open-coded implementation of the API discussed in // https://github.com/joshua-maros/ouroboros/issues/38 fn map_arc_data_ocsp_response( + py: pyo3::Python<'_>, it: &OwnedRawOCSPResponse, f: impl for<'this> FnOnce( &'this [u8], &RawOCSPResponse<'this>, ) -> certificate::RawCertificate<'this>, ) -> certificate::OwnedRawCertificate { - certificate::OwnedRawCertificate::new_public(Arc::clone(it.borrow_data()), |inner_it| { - it.with(|value| f(inner_it, unsafe { std::mem::transmute(value.value) })) + certificate::OwnedRawCertificate::new_public(it.borrow_data().clone_ref(py), |inner_it| { + it.with(|value| { + f(inner_it.as_bytes(py), unsafe { + std::mem::transmute(value.value) + }) + }) }) } fn try_map_arc_data_mut_ocsp_response_iterator( @@ -774,8 +780,7 @@ fn create_ocsp_response( response_bytes, }; let data = asn1::write_single(&resp)?; - // TODO: extra copy as we round-trip through a slice - load_der_ocsp_response(py, &data) + load_der_ocsp_response(py, pyo3::types::PyBytes::new(py, &data).into_py(py)) } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { From 232875752ef45af0b1f054265a3e1dd6d0f9f2c6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 25 Mar 2023 17:13:03 -0400 Subject: [PATCH 533/827] Make CffiBuf implementation sounder (#8612) This keeps the buffer object alive, in addition to the original object. Some buffer-implementors have different behavior based on whether there's a buffer object alive. --- src/cryptography/utils.py | 4 ++-- src/rust/src/buf.rs | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 9beea653e330..c8a5ee83139b 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -42,11 +42,11 @@ def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: ) -def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[int, int]: +def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[typing.Any, int]: from cryptography.hazmat.bindings._rust import _openssl buf = _openssl.ffi.from_buffer(obj) - return int(_openssl.ffi.cast("uintptr_t", buf)), len(buf) + return buf, int(_openssl.ffi.cast("uintptr_t", buf)) class InterfaceNotImplemented(Exception): diff --git a/src/rust/src/buf.rs b/src/rust/src/buf.rs index 23dddfd26993..b45e1b5c342e 100644 --- a/src/rust/src/buf.rs +++ b/src/rust/src/buf.rs @@ -6,6 +6,7 @@ use std::{ptr, slice}; pub(crate) struct CffiBuf<'p> { _pyobj: &'p pyo3::PyAny, + _bufobj: &'p pyo3::PyAny, buf: &'p [u8], } @@ -19,10 +20,12 @@ impl<'a> pyo3::conversion::FromPyObject<'a> for CffiBuf<'a> { fn extract(pyobj: &'a pyo3::PyAny) -> pyo3::PyResult { let py = pyobj.py(); - let (ptrval, len): (usize, usize) = py + let (bufobj, ptrval): (&pyo3::PyAny, usize) = py .import("cryptography.utils")? .call_method1("_extract_buffer_length", (pyobj,))? .extract()?; + + let len = bufobj.len()?; let ptr = if len == 0 { ptr::NonNull::dangling().as_ptr() } else { @@ -31,6 +34,7 @@ impl<'a> pyo3::conversion::FromPyObject<'a> for CffiBuf<'a> { Ok(CffiBuf { _pyobj: pyobj, + _bufobj: bufobj, // SAFETY: _extract_buffer_length ensures that we have a valid ptr // and length (and we ensure we meet slice's requirements for // 0-length slices above), we're keeping pyobj alive which ensures From c012d7c9467173286bf3d70201b6a3ab93accd94 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 26 Mar 2023 10:00:48 +0900 Subject: [PATCH 534/827] Bump BoringSSL and/or OpenSSL in CI (#8615) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d89e25133d8..72caeec0b85b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 25, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "2e13e36e7477cfe2ef48312634b1c34103da4899"}} - # Latest commit on the OpenSSL master branch, as of Mar 24, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "908ba3ed9adbb3df90f7684a3111ca916a45202d"}} + # Latest commit on the OpenSSL master branch, as of Mar 26, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "46032426e42238ca8662b98752f9bc8d44512f29"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 829ccf65de0504231a879b967edd1ef8dcfa4ea6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 26 Mar 2023 17:05:53 -0400 Subject: [PATCH 535/827] Close stale issues more quickly (#8616) This is still more than one week of no response --- .github/workflows/auto-close-stale.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto-close-stale.yml b/.github/workflows/auto-close-stale.yml index 2dd48549fd6c..46b4d3e2a9cf 100644 --- a/.github/workflows/auto-close-stale.yml +++ b/.github/workflows/auto-close-stale.yml @@ -16,8 +16,8 @@ jobs: - uses: actions/stale@v8.0.0 with: only-labels: waiting-on-reporter - days-before-stale: 5 - days-before-close: 7 - stale-issue-message: "This issue has been waiting for a reporter response for 5 days. It will be auto-closed if no activity occurs in the next week." + days-before-stale: 3 + days-before-close: 5 + stale-issue-message: "This issue has been waiting for a reporter response for 3 days. It will be auto-closed if no activity occurs in the next 5 days." close-issue-message: "This issue has not received a reporter response and has been auto-closed. If the issue is still relevant please leave a comment and we can reopen it." close-issue-reason: completed From f208befa25131fcbd3fd809c6fc2471ac72ca381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:35:18 +0000 Subject: [PATCH 536/827] Bump filelock from 3.10.4 to 3.10.6 (#8618) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.4 to 3.10.6. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.4...3.10.6) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8f59ed792e57..bd9c0cbac95b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # via pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.4 +filelock==3.10.6 # via # tox # virtualenv From 64e2d9b554b954a0329554a5f01b95f6969570a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:35:33 +0000 Subject: [PATCH 537/827] Bump platformdirs from 3.1.1 to 3.2.0 (#8620) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.1.1...3.2.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index bd9c0cbac95b..452cc1e40ea0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -92,7 +92,7 @@ pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine -platformdirs==3.1.1 +platformdirs==3.2.0 # via # black # tox From 06fd7706a71a1370f9048468775498579dc4b580 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:36:10 +0000 Subject: [PATCH 538/827] Bump tox from 4.4.7 to 4.4.8 (#8619) Bumps [tox](https://github.com/tox-dev/tox) from 4.4.7 to 4.4.8. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.4.7...4.4.8) --- updated-dependencies: - dependency-name: tox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 452cc1e40ea0..2ea238f89d60 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -193,7 +193,7 @@ tomli==2.0.1 # pyproject-hooks # pytest # tox -tox==4.4.7 +tox==4.4.8 # via cryptography (pyproject.toml) twine==4.0.2 # via cryptography (pyproject.toml) From 55c13c31148d54516dcc18ecc936f9657af05071 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:52:12 +0000 Subject: [PATCH 539/827] Bump proc-macro2 from 1.0.53 to 1.0.54 in /src/rust (#8621) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.53 to 1.0.54. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.53...1.0.54) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 927039d5f424..49988efec0c5 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -416,9 +416,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] From 89228a9deb9a0901c87329414b4d8a062bd38bae Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 26 Mar 2023 20:51:04 -0400 Subject: [PATCH 540/827] Added support for OCSP AcceptableResponses extension (#8617) fixes #8589 --- CHANGELOG.rst | 2 + docs/development/test-vectors.rst | 4 +- docs/x509/reference.rst | 29 ++++++++ src/cryptography/hazmat/_oid.py | 1 + src/cryptography/x509/__init__.py | 2 + src/cryptography/x509/extensions.py | 29 ++++++++ src/rust/src/x509/extensions.rs | 2 +- src/rust/src/x509/ocsp_req.rs | 19 ++++- src/rust/src/x509/oid.rs | 2 + tests/x509/test_ocsp.py | 12 ++++ tests/x509/test_x509_ext.py | 67 ++++++++++++++++++ .../x509/ocsp/req-acceptable-responses.der | Bin 0 -> 116 bytes 12 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 vectors/cryptography_vectors/x509/ocsp/req-acceptable-responses.der diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a0b5bf719a26..ec7a3db5ddc9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,8 @@ Changelog removed. Users on older version of OpenSSL will need to upgrade. * **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. * Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. +* Added support for the :class:`~cryptography.x509.OCSPAcceptableResponses` + OCSP extension. .. _v40-0-1: diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 72fdf7fabac1..2cb822306707 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -658,8 +658,10 @@ Custom X.509 OCSP Test Vectors extensions. * ``x509/ocsp/resp-unknown-extension.der`` - An OCSP response containing an extension with an unknown OID. -* ``x509/ocsp/resp-unknown-hash-alg.der`` - AN OCSP response containing an +* ``x509/ocsp/resp-unknown-hash-alg.der`` - An OCSP response containing an invalid hash algorithm OID. +* ``x509/ocsp/req-acceptable-responses.der`` - An OCSP request containing an + acceptable responses extension. Custom PKCS12 Test Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 12ac440cb8ba..d0f864b56a5b 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -2874,6 +2874,29 @@ OCSP Extensions :type: bytes +.. class:: OCSPAcceptableResponses(response) + :canonical: cryptography.x509.extensions.OCSPAcceptableResponses + + .. versionadded:: 41.0.0 + + OCSP acceptable responses is an extension that is only valid inside + :class:`~cryptography.x509.ocsp.OCSPRequest` objects. This allows an OCSP + client to tell the server what types of responses it supports. In practice + this is rarely used, because there is only one kind of OCSP response in + wide use. + + .. attribute:: oid + + :type: :class:`ObjectIdentifier` + + Returns + :attr:`~cryptography.x509.oid.OCSPExtensionOID.ACCEPTABLE_RESPONSES`. + + .. attribute:: nonce + + :type: bytes + + X.509 Request Attributes ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3509,6 +3532,12 @@ instances. The following common OIDs are available as constants. Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1.2"``. + .. attribute:: ACCEPTABLE_RESPONSES + + .. versionadded:: 41.0.0 + + Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1.4"``. + .. class:: AttributeOID :canonical: cryptography.hazmat._oid.AttributeOID diff --git a/src/cryptography/hazmat/_oid.py b/src/cryptography/hazmat/_oid.py index 927ffc4c5412..bc9c046c6a78 100644 --- a/src/cryptography/hazmat/_oid.py +++ b/src/cryptography/hazmat/_oid.py @@ -42,6 +42,7 @@ class ExtensionOID: class OCSPExtensionOID: NONCE = ObjectIdentifier("1.3.6.1.5.5.7.48.1.2") + ACCEPTABLE_RESPONSES = ObjectIdentifier("1.3.6.1.5.5.7.48.1.4") class CRLEntryExtensionOID: diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index ad924ad42dff..df7fd3fbb5bb 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -54,6 +54,7 @@ KeyUsage, NameConstraints, NoticeReference, + OCSPAcceptableResponses, OCSPNoCheck, OCSPNonce, PolicyConstraints, @@ -196,6 +197,7 @@ "IssuingDistributionPoint", "TLSFeature", "TLSFeatureType", + "OCSPAcceptableResponses", "OCSPNoCheck", "BasicConstraints", "CRLNumber", diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 551887b4a60d..6fe3888bf788 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -1932,6 +1932,35 @@ def public_bytes(self) -> bytes: return rust_x509.encode_extension_value(self) +class OCSPAcceptableResponses(ExtensionType): + oid = OCSPExtensionOID.ACCEPTABLE_RESPONSES + + def __init__(self, responses: typing.Iterable[ObjectIdentifier]) -> None: + responses = list(responses) + if any(not isinstance(r, ObjectIdentifier) for r in responses): + raise TypeError("All responses must be ObjectIdentifiers") + + self._responses = responses + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OCSPAcceptableResponses): + return NotImplemented + + return self._responses == other._responses + + def __hash__(self) -> int: + return hash(tuple(self._responses)) + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> typing.Iterator[ObjectIdentifier]: + return iter(self._responses) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + class IssuingDistributionPoint(ExtensionType): oid = ExtensionOID.ISSUING_DISTRIBUTION_POINT diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index d5473a576735..79170a616612 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -202,7 +202,7 @@ pub(crate) fn encode_extension( let ads = x509::common::encode_access_descriptions(ext.py(), ext)?; Ok(Some(asn1::write_single(&ads)?)) } - &oid::EXTENDED_KEY_USAGE_OID => { + &oid::EXTENDED_KEY_USAGE_OID | &oid::ACCEPTABLE_RESPONSES_OID => { let mut oids = vec![]; for el in ext.iter()? { let oid = py_oid_to_oid(el?)?; diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index b239869d900d..47810a023d68 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -2,7 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::asn1::{big_byte_slice_to_py_int, py_uint_to_big_endian_bytes}; +use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, py_uint_to_big_endian_bytes}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{extensions, ocsp, oid}; @@ -118,8 +118,8 @@ impl OCSPRequest { &mut self.cached_extensions, &self.raw.borrow_value().tbs_request.request_extensions, |oid, value| { - match oid { - &oid::NONCE_OID => { + match *oid { + oid::NONCE_OID => { // This is a disaster. RFC 2560 says that the contents of the nonce is // just the raw extension value. This is nonsense, since they're always // supposed to be ASN.1 TLVs. RFC 6960 correctly specifies that the @@ -129,6 +129,19 @@ impl OCSPRequest { let nonce = asn1::parse_single::<&[u8]>(value).unwrap_or(value); Ok(Some(x509_module.call_method1("OCSPNonce", (nonce,))?)) } + oid::ACCEPTABLE_RESPONSES_OID => { + let oids = asn1::parse_single::< + asn1::SequenceOf<'_, asn1::ObjectIdentifier>, + >(value)?; + let py_oids = pyo3::types::PyList::empty(py); + for oid in oids { + py_oids.append(oid_to_py_oid(py, &oid)?)?; + } + + Ok(Some( + x509_module.call_method1("OCSPAcceptableResponses", (py_oids,))?, + )) + } _ => Ok(None), } }, diff --git a/src/rust/src/x509/oid.rs b/src/rust/src/x509/oid.rs index 55477c60826a..2c9b36d0a186 100644 --- a/src/rust/src/x509/oid.rs +++ b/src/rust/src/x509/oid.rs @@ -41,6 +41,8 @@ pub(crate) const POLICY_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, pub(crate) const EXTENDED_KEY_USAGE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 37); pub(crate) const FRESHEST_CRL_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 46); pub(crate) const INHIBIT_ANY_POLICY_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 54); +pub(crate) const ACCEPTABLE_RESPONSES_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 4); // Signing methods pub(crate) const ECDSA_WITH_SHA224_OID: asn1::ObjectIdentifier = diff --git a/tests/x509/test_ocsp.py b/tests/x509/test_ocsp.py index fd8bbfc1babe..2c595db324f5 100644 --- a/tests/x509/test_ocsp.py +++ b/tests/x509/test_ocsp.py @@ -102,6 +102,18 @@ def test_load_request_with_extensions(self): b"{\x80Z\x1d7&\xb8\xb8OH\xd2\xf8\xbf\xd7-\xfd" ) + def test_load_request_with_acceptable_responses(self): + req = _load_data( + os.path.join("x509", "ocsp", "req-acceptable-responses.der"), + ocsp.load_der_ocsp_request, + ) + assert len(req.extensions) == 1 + ext = req.extensions[0] + assert ext.critical is False + assert ext.value == x509.OCSPAcceptableResponses( + [x509.ObjectIdentifier("1.3.6.1.5.5.7.48.1.1")] + ) + def test_load_request_with_unknown_extension(self): req = _load_data( os.path.join("x509", "ocsp", "req-ext-unknown-oid.der"), diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py index a4f0f0f8b6a0..d11ba3db0408 100644 --- a/tests/x509/test_x509_ext.py +++ b/tests/x509/test_x509_ext.py @@ -6132,6 +6132,73 @@ def test_public_bytes(self): assert ext.public_bytes() == b"\x04\x0500000" +class TestOCSPAcceptableResponses: + def test_invalid_types(self): + with pytest.raises(TypeError): + x509.OCSPAcceptableResponses(38) # type:ignore[arg-type] + with pytest.raises(TypeError): + x509.OCSPAcceptableResponses([38]) # type:ignore[list-item] + + def test_eq(self): + acceptable_responses1 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + acceptable_responses2 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + assert acceptable_responses1 == acceptable_responses2 + + def test_ne(self): + acceptable_responses1 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + acceptable_responses2 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.4")] + ) + assert acceptable_responses1 != acceptable_responses2 + assert acceptable_responses1 != object() + + def test_repr(self): + acceptable_responses = x509.OCSPAcceptableResponses([]) + assert ( + repr(acceptable_responses) + == "" + ) + + def test_hash(self): + acceptable_responses1 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + acceptable_responses2 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + acceptable_responses3 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.4")] + ) + + assert hash(acceptable_responses1) == hash(acceptable_responses2) + assert hash(acceptable_responses1) != hash(acceptable_responses3) + + def test_iter(self): + acceptable_responses1 = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.2.3")] + ) + + assert list(acceptable_responses1) == [ObjectIdentifier("1.2.3")] + + def test_public_bytes(self): + ext = x509.OCSPAcceptableResponses([]) + assert ext.public_bytes() == b"\x30\x00" + + ext = x509.OCSPAcceptableResponses( + [ObjectIdentifier("1.3.6.1.5.5.7.48.1.1")] + ) + assert ( + ext.public_bytes() + == b"\x30\x0b\x06\t+\x06\x01\x05\x05\x07\x30\x01\x01" + ) + + def test_all_extension_oid_members_have_names_defined(): for oid in dir(ExtensionOID): if oid.startswith("__"): diff --git a/vectors/cryptography_vectors/x509/ocsp/req-acceptable-responses.der b/vectors/cryptography_vectors/x509/ocsp/req-acceptable-responses.der new file mode 100644 index 0000000000000000000000000000000000000000..0afa906d2f558528b77ba93b8fa2a54cc1b12d9c GIT binary patch literal 116 zcmXpgGAJxm)#hVnl450G5s6aXRa5WAVcM&5`m?6)qnz{X+}l}1l;S*} zth&+vAUD~&L3m@-L;Zb`3QU3wPgUmMTCt_3?fID Date: Mon, 27 Mar 2023 20:49:14 +0000 Subject: [PATCH 541/827] Bump rich from 13.3.2 to 13.3.3 (#8624) Bumps [rich](https://github.com/Textualize/rich) from 13.3.2 to 13.3.3. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.2...v13.3.3) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2ea238f89d60..c69473a6678b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -150,7 +150,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.3.2 +rich==13.3.3 # via twine ruff==0.0.259 # via cryptography (pyproject.toml) From fa62d75f617be26f649204ccbbfc6576ffabf128 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Mon, 27 Mar 2023 23:16:29 -0400 Subject: [PATCH 542/827] Restore the x509 error verification codes (#8626) * Restore the x509 error verification codes. This is necessary for custom TLS certificate validation logic; see https://github.com/pyca/pyopenssl/issues/1201 * Remove changelog entry. --------- Co-authored-by: Itamar Turner-Trauring --- src/_cffi_src/openssl/x509_vfy.py | 61 ++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 69c31c966185..71d0cec38d4f 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -30,12 +30,69 @@ typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **, X509_STORE_CTX *, X509 *); +static const int X509_V_OK; +static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; +static const int X509_V_ERR_UNABLE_TO_GET_CRL; +static const int X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; +static const int X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; +static const int X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; +static const int X509_V_ERR_CERT_SIGNATURE_FAILURE; +static const int X509_V_ERR_CRL_SIGNATURE_FAILURE; +static const int X509_V_ERR_CERT_NOT_YET_VALID; +static const int X509_V_ERR_CERT_HAS_EXPIRED; +static const int X509_V_ERR_CRL_NOT_YET_VALID; +static const int X509_V_ERR_CRL_HAS_EXPIRED; +static const int X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; +static const int X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; +static const int X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; +static const int X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; +static const int X509_V_ERR_OUT_OF_MEM; +static const int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; +static const int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; +static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; +static const int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; +static const int X509_V_ERR_CERT_CHAIN_TOO_LONG; +static const int X509_V_ERR_CERT_REVOKED; +static const int X509_V_ERR_INVALID_CA; +static const int X509_V_ERR_PATH_LENGTH_EXCEEDED; +static const int X509_V_ERR_INVALID_PURPOSE; +static const int X509_V_ERR_CERT_UNTRUSTED; +static const int X509_V_ERR_CERT_REJECTED; +static const int X509_V_ERR_SUBJECT_ISSUER_MISMATCH; +static const int X509_V_ERR_AKID_SKID_MISMATCH; +static const int X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; +static const int X509_V_ERR_KEYUSAGE_NO_CERTSIGN; +static const int X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; +static const int X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; +static const int X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; +static const int X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; +static const int X509_V_ERR_INVALID_NON_CA; +static const int X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; +static const int X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; +static const int X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; +static const int X509_V_ERR_INVALID_EXTENSION; +static const int X509_V_ERR_INVALID_POLICY_EXTENSION; +static const int X509_V_ERR_NO_EXPLICIT_POLICY; +static const int X509_V_ERR_DIFFERENT_CRL_SCOPE; +static const int X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; +static const int X509_V_ERR_UNNESTED_RESOURCE; +static const int X509_V_ERR_PERMITTED_VIOLATION; +static const int X509_V_ERR_EXCLUDED_VIOLATION; +static const int X509_V_ERR_SUBTREE_MINMAX; +static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; +static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; +static const int X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; +static const int X509_V_ERR_CRL_PATH_VALIDATION_ERROR; +static const int X509_V_ERR_HOSTNAME_MISMATCH; +static const int X509_V_ERR_EMAIL_MISMATCH; +static const int X509_V_ERR_IP_ADDRESS_MISMATCH; +static const int X509_V_ERR_APPLICATION_VERIFICATION; + + /* While these are defined in the source as ints, they're tagged here as longs, just in case they ever grow to large, such as what we saw with OP_ALL. */ -static const int X509_V_OK; - /* Verification parameters */ static const long X509_V_FLAG_CRL_CHECK; static const long X509_V_FLAG_CRL_CHECK_ALL; From bf688c9294f7f807e27e1575112b254597a18524 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 03:17:03 +0000 Subject: [PATCH 543/827] Bump BoringSSL and/or OpenSSL in CI (#8627) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72caeec0b85b..c86c1ad0114d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: - {VERSION: "3.12-dev", TOXENV: "py312"} # Latest commit on the BoringSSL master branch, as of Mar 25, 2023. - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "2e13e36e7477cfe2ef48312634b1c34103da4899"}} - # Latest commit on the OpenSSL master branch, as of Mar 26, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "46032426e42238ca8662b98752f9bc8d44512f29"}} + # Latest commit on the OpenSSL master branch, as of Mar 28, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "864c70e43ea5f1d7fe20bfea457e53e79fd46b6e"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 29508fcf126d3dd4a8120d14be426dee2dacc346 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 13:17:33 +0000 Subject: [PATCH 544/827] Bump filelock from 3.10.6 to 3.10.7 (#8630) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.6 to 3.10.7. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.6...3.10.7) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c69473a6678b..29ca1f3f38b5 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,7 +46,7 @@ exceptiongroup==1.1.1 # via pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.6 +filelock==3.10.7 # via # tox # virtualenv From 8158e45ee746faea3fcf43e23a339bb02145a7af Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 29 Mar 2023 10:46:50 +0900 Subject: [PATCH 545/827] certbot moved their tests to an internal package (#8632) --- .github/downstream.d/certbot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/downstream.d/certbot.sh b/.github/downstream.d/certbot.sh index e2f2203bbf0a..13508c87a0c8 100755 --- a/.github/downstream.d/certbot.sh +++ b/.github/downstream.d/certbot.sh @@ -14,7 +14,7 @@ case "${1}" in # Ignore some warnings for now since they're now automatically promoted # to errors. We can probably remove this when acme gets split into # its own repo - pytest -Wignore certbot/tests + pytest -Wignore certbot pytest acme ;; *) From 60d3f709eb96ba5df9bdfede5c024c1f2db9f0e5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 28 Mar 2023 22:11:23 -0400 Subject: [PATCH 546/827] Error cleanly in setup.py when using a too-old PyPy (#8634) --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index b3a7cf9b241e..b05dc2f129c3 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,9 @@ # means that we need to add the src/ directory to the sys.path. sys.path.insert(0, src_dir) +if hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (7, 3, 10): + raise RuntimeError("cryptography is not compatible with PyPy3 < 7.3.10") + try: # See pyproject.toml for most of the config metadata. setup( From f8514b30dfe2872653caeb6bf6776367c2d66671 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 02:20:09 +0000 Subject: [PATCH 547/827] Bump BoringSSL and/or OpenSSL in CI (#8631) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c86c1ad0114d..ac3e1644a4e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 25, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "2e13e36e7477cfe2ef48312634b1c34103da4899"}} - # Latest commit on the OpenSSL master branch, as of Mar 28, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "864c70e43ea5f1d7fe20bfea457e53e79fd46b6e"}} + # Latest commit on the BoringSSL master branch, as of Mar 29, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "678bae408369d614e0777bc5cd5a380dac35ed59"}} + # Latest commit on the OpenSSL master branch, as of Mar 29, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "30ab774770a7e8547b0d6363b63a73cc80f33a7b"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 59a749333e336b5aa1f9864fe01d67ec11c3a065 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 29 Mar 2023 11:20:33 +0900 Subject: [PATCH 548/827] define path for type for rust classes (no more builtins) (#8635) --- src/rust/src/asn1.rs | 2 +- src/rust/src/backend/x25519.rs | 4 ++-- src/rust/src/lib.rs | 2 +- src/rust/src/oid.rs | 2 +- src/rust/src/pool.rs | 4 ++-- src/rust/src/x509/certificate.rs | 2 +- src/rust/src/x509/crl.rs | 6 +++--- src/rust/src/x509/csr.rs | 2 +- src/rust/src/x509/ocsp_req.rs | 2 +- src/rust/src/x509/ocsp_resp.rs | 6 +++--- src/rust/src/x509/sct.rs | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 2cc9431bb5fd..833a72031e16 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -143,7 +143,7 @@ fn encode_dss_signature( Ok(pyo3::types::PyBytes::new(py, &result).to_object(py)) } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.asn1")] struct TestCertificate { #[pyo3(get)] not_before_tag: u8, diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 94af22636b00..988d0076ef5f 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -6,12 +6,12 @@ use crate::buf::CffiBuf; use crate::error::{CryptographyError, CryptographyResult}; use foreign_types_shared::ForeignTypeRef; -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.x25519")] struct X25519PrivateKey { pkey: openssl::pkey::PKey, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.x25519")] struct X25519PublicKey { pkey: openssl::pkey::PKey, } diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index d7dbbba6067d..e8608150421c 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -102,7 +102,7 @@ fn raise_openssl_error() -> crate::error::CryptographyResult<()> { Err(openssl::error::ErrorStack::get().into()) } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl")] struct OpenSSLError { e: openssl::error::Error, } diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index 1c12f775a621..23bdd7362dd0 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -6,7 +6,7 @@ use crate::error::CryptographyResult; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust")] pub(crate) struct ObjectIdentifier { pub(crate) oid: asn1::ObjectIdentifier, } diff --git a/src/rust/src/pool.rs b/src/rust/src/pool.rs index 384273a69b57..b9e6e27cd4af 100644 --- a/src/rust/src/pool.rs +++ b/src/rust/src/pool.rs @@ -7,14 +7,14 @@ use std::cell::Cell; // An object pool that can contain a single object and will dynamically // allocate new objects to fulfill requests if the pool'd object is already in // use. -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust")] pub(crate) struct FixedPool { create_fn: pyo3::PyObject, value: Cell>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust")] struct PoolAcquisition { pool: pyo3::Py, diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 3a76571e98c9..efbab2449780 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -78,7 +78,7 @@ impl OwnedRawCertificate { } } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] pub(crate) struct Certificate { pub(crate) raw: OwnedRawCertificate, pub(crate) cached_extensions: Option, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 601268746459..7644cfd2715a 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -66,7 +66,7 @@ struct OwnedRawCertificateRevocationList { revoked_certs: pyo3::once_cell::GILOnceCell>>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CertificateRevocationList { raw: Arc, @@ -415,7 +415,7 @@ struct OwnedCRLIteratorData { value: Option>>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CRLIterator { contents: OwnedCRLIteratorData, } @@ -517,7 +517,7 @@ struct OwnedRawRevokedCertificate { value: RawRevokedCertificate<'this>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct RevokedCertificate { raw: OwnedRawRevokedCertificate, cached_extensions: Option, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index b920e5fe72f1..b90e49e3e0ee 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -79,7 +79,7 @@ struct OwnedRawCsr { value: RawCsr<'this>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CertificateSigningRequest { raw: OwnedRawCsr, cached_extensions: Option, diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 47810a023d68..0eef4bccb2ef 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -44,7 +44,7 @@ fn load_der_ocsp_request( }) } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPRequest { raw: OwnedRawOCSPRequest, diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 6913f5b177f6..e8f864c42f1e 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -65,7 +65,7 @@ struct OwnedRawOCSPResponse { value: RawOCSPResponse<'this>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPResponse { raw: Arc, @@ -798,7 +798,7 @@ struct OwnedOCSPResponseIteratorData { value: asn1::SequenceOf<'this, SingleResponse<'this>>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPResponseIterator { contents: OwnedOCSPResponseIteratorData, } @@ -830,7 +830,7 @@ struct OwnedSingleResponse { value: SingleResponse<'this>, } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPSingleResponse { raw: OwnedSingleResponse, } diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index 4b8414e109d3..09e1ae4486c9 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -128,7 +128,7 @@ impl TryFrom for SignatureAlgorithm { } } -#[pyo3::prelude::pyclass] +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] pub(crate) struct Sct { log_id: [u8; 32], timestamp: u64, From 22759dbab0bc85da995febcc3e82680fe6b2804a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 28 Mar 2023 22:28:17 -0400 Subject: [PATCH 549/827] Switch from pytest-subtests to a mini-version that's faster (#8613) --- ci-constraints-requirements.txt | 4 ---- pyproject.toml | 3 +-- tests/conftest.py | 19 +++++++++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 29ca1f3f38b5..1054e9d91042 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -10,7 +10,6 @@ alabaster==0.7.13 attrs==22.2.0 # via # pytest - # pytest-subtests babel==2.12.1 # via sphinx black==23.1.0 @@ -125,7 +124,6 @@ pytest==7.2.2 # pytest-cov # pytest-randomly # pytest-shard - # pytest-subtests # pytest-xdist pytest-benchmark==4.0.0 # via cryptography (pyproject.toml) @@ -135,8 +133,6 @@ pytest-randomly==3.12.0 # via cryptography (pyproject.toml) pytest-shard==0.1.2 # via cryptography (pyproject.toml) -pytest-subtests==0.10.0 - # via cryptography (pyproject.toml) pytest-xdist==3.2.1 # via cryptography (pyproject.toml) readme-renderer==37.3 diff --git a/pyproject.toml b/pyproject.toml index 2a94aa26405b..7bdf2a5cfaa4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,6 @@ test = [ "pytest-shard >=0.1.2", "pytest-benchmark", "pytest-cov", - "pytest-subtests >=0.10.0", "pytest-xdist", "pretend", ] @@ -93,7 +92,7 @@ line-length = 79 target-version = ["py37"] [tool.pytest.ini_options] -addopts = "-r s --capture=no --strict-markers --benchmark-disable --no-subtests-shortletter" +addopts = "-r s --capture=no --strict-markers --benchmark-disable" console_output_style = "progress-even-when-capture-no" markers = [ "skip_fips: this test is not executed in FIPS mode", diff --git a/tests/conftest.py b/tests/conftest.py index 51dca19850a3..0e128a16513e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import contextlib import pytest @@ -46,3 +47,21 @@ def backend(request): # Ensure the error stack is clear after the test errors = openssl_backend._consume_errors() assert not errors + + +@pytest.fixture() +def subtests(): + # This is a miniature version of the pytest-subtests package, but + # optimized for lower overhead. + # + # When tests are skipped, these are not logged in the final pytest output. + yield SubTests() + + +class SubTests: + @contextlib.contextmanager + def test(self): + try: + yield + except pytest.skip.Exception: + pass From 24463e35882a1b7152f9fc8b2a2cb22fe3bc8805 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 05:40:02 +0900 Subject: [PATCH 550/827] Bump black from 23.1.0 to 23.3.0 (#8636) Bumps [black](https://github.com/psf/black) from 23.1.0 to 23.3.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.1.0...23.3.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1054e9d91042..a0ae6856e7a0 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -12,7 +12,7 @@ attrs==22.2.0 # pytest babel==2.12.1 # via sphinx -black==23.1.0 +black==23.3.0 # via cryptography (pyproject.toml) bleach==6.0.0 # via readme-renderer From 92f2932ace9ec316952e1c3653de8c22b183680c Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 00:18:39 +0000 Subject: [PATCH 551/827] Bump BoringSSL and/or OpenSSL in CI (#8638) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac3e1644a4e2..8be80dc30c31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 29, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "678bae408369d614e0777bc5cd5a380dac35ed59"}} - # Latest commit on the OpenSSL master branch, as of Mar 29, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "30ab774770a7e8547b0d6363b63a73cc80f33a7b"}} + # Latest commit on the BoringSSL master branch, as of Mar 30, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "fca688f26b939db9c9981204373cecbd108b5d6c"}} + # Latest commit on the OpenSSL master branch, as of Mar 30, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "09cb8718fd65dc7126247808cb96b05147bb923f"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 61ffde1f66b4d0f798044195e8eaee172a8865e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:09:44 +0000 Subject: [PATCH 552/827] Bump iana-time-zone from 0.1.54 to 0.1.55 in /src/rust (#8641) Bumps [iana-time-zone](https://github.com/strawlab/iana-time-zone) from 0.1.54 to 0.1.55. - [Release notes](https://github.com/strawlab/iana-time-zone/releases) - [Changelog](https://github.com/strawlab/iana-time-zone/blob/main/CHANGELOG.md) - [Commits](https://github.com/strawlab/iana-time-zone/compare/v0.1.54...v0.1.55) --- updated-dependencies: - dependency-name: iana-time-zone dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 83 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 49988efec0c5..24a98758c1f4 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -185,9 +185,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "iana-time-zone" -version = "0.1.54" +version = "0.1.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" +checksum = "716f12fbcfac6ffab0a5e9ec51d0a0ff70503742bb2dc7b99396394c9dc323f0" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -662,11 +662,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "2649ff315bee4c98757f15dac226efe3d81927adbb6e882084bb1ee3e0c330a7" dependencies = [ - "windows-targets", + "windows-targets 0.47.0", ] [[package]] @@ -675,7 +675,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", ] [[package]] @@ -684,13 +684,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f8996d3f43b4b2d44327cd71b7b0efd1284ab60e6e9d0e8b630e18555d87d3e" +dependencies = [ + "windows_aarch64_gnullvm 0.47.0", + "windows_aarch64_msvc 0.47.0", + "windows_i686_gnu 0.47.0", + "windows_i686_msvc 0.47.0", + "windows_x86_64_gnu 0.47.0", + "windows_x86_64_gnullvm 0.47.0", + "windows_x86_64_msvc 0.47.0", ] [[package]] @@ -699,38 +714,80 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7" From 5890361c5fa70e3c48d863a383a9d5a2586039ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:33:16 +0000 Subject: [PATCH 553/827] Bump ruff from 0.0.259 to 0.0.260 (#8642) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.259 to 0.0.260. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.259...v0.0.260) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index a0ae6856e7a0..11f850c7efbc 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -148,7 +148,7 @@ rfc3986==2.0.0 # via twine rich==13.3.3 # via twine -ruff==0.0.259 +ruff==0.0.260 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From 394ae30408f4286bddac211afe67cbdcb545dcac Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 30 Mar 2023 17:46:16 -0400 Subject: [PATCH 554/827] Use from __future__ import annotations everywhere (#8643) --- src/_cffi_src/build_openssl.py | 1 + src/_cffi_src/openssl/asn1.py | 1 + src/_cffi_src/openssl/bignum.py | 1 + src/_cffi_src/openssl/bio.py | 1 + src/_cffi_src/openssl/callbacks.py | 1 + src/_cffi_src/openssl/cmac.py | 1 + src/_cffi_src/openssl/crypto.py | 1 + src/_cffi_src/openssl/cryptography.py | 1 + src/_cffi_src/openssl/dh.py | 1 + src/_cffi_src/openssl/dsa.py | 1 + src/_cffi_src/openssl/ec.py | 1 + src/_cffi_src/openssl/ecdsa.py | 1 + src/_cffi_src/openssl/engine.py | 1 + src/_cffi_src/openssl/err.py | 1 + src/_cffi_src/openssl/evp.py | 1 + src/_cffi_src/openssl/fips.py | 1 + src/_cffi_src/openssl/hmac.py | 1 + src/_cffi_src/openssl/nid.py | 1 + src/_cffi_src/openssl/objects.py | 1 + src/_cffi_src/openssl/opensslv.py | 1 + src/_cffi_src/openssl/pem.py | 1 + src/_cffi_src/openssl/pkcs12.py | 1 + src/_cffi_src/openssl/pkcs7.py | 1 + src/_cffi_src/openssl/provider.py | 1 + src/_cffi_src/openssl/rand.py | 1 + src/_cffi_src/openssl/rsa.py | 1 + src/_cffi_src/openssl/ssl.py | 1 + src/_cffi_src/openssl/x509.py | 1 + src/_cffi_src/openssl/x509_vfy.py | 1 + src/_cffi_src/openssl/x509name.py | 1 + src/_cffi_src/openssl/x509v3.py | 1 + src/_cffi_src/utils.py | 1 + src/cryptography/__about__.py | 1 + src/cryptography/__init__.py | 2 + src/cryptography/exceptions.py | 3 +- src/cryptography/fernet.py | 1 + src/cryptography/hazmat/__init__.py | 3 ++ src/cryptography/hazmat/_oid.py | 2 + src/cryptography/hazmat/backends/__init__.py | 3 ++ .../hazmat/backends/openssl/__init__.py | 1 + .../hazmat/backends/openssl/aead.py | 26 ++++++------ .../hazmat/backends/openssl/backend.py | 1 + .../hazmat/backends/openssl/ciphers.py | 6 +-- .../hazmat/backends/openssl/cmac.py | 8 ++-- .../hazmat/backends/openssl/decode_asn1.py | 1 + .../hazmat/backends/openssl/dh.py | 12 +++--- .../hazmat/backends/openssl/dsa.py | 13 +++--- .../hazmat/backends/openssl/ec.py | 20 +++++---- .../hazmat/backends/openssl/ed25519.py | 6 ++- .../hazmat/backends/openssl/ed448.py | 6 ++- .../hazmat/backends/openssl/hashes.py | 6 ++- .../hazmat/backends/openssl/hmac.py | 6 ++- .../hazmat/backends/openssl/poly1305.py | 4 +- .../hazmat/backends/openssl/rsa.py | 36 ++++++++-------- .../hazmat/backends/openssl/utils.py | 4 +- .../hazmat/backends/openssl/x448.py | 6 ++- .../hazmat/bindings/openssl/_conditional.py | 2 + .../hazmat/bindings/openssl/binding.py | 2 + .../hazmat/primitives/_asymmetric.py | 2 + .../hazmat/primitives/_cipheralgorithm.py | 2 + .../hazmat/primitives/_serialization.py | 10 +++-- .../hazmat/primitives/asymmetric/dh.py | 11 ++--- .../hazmat/primitives/asymmetric/dsa.py | 11 ++--- .../hazmat/primitives/asymmetric/ec.py | 11 ++--- .../hazmat/primitives/asymmetric/ed25519.py | 7 ++-- .../hazmat/primitives/asymmetric/ed448.py | 7 ++-- .../hazmat/primitives/asymmetric/padding.py | 7 ++-- .../hazmat/primitives/asymmetric/rsa.py | 11 ++--- .../hazmat/primitives/asymmetric/types.py | 2 + .../hazmat/primitives/asymmetric/utils.py | 1 + .../hazmat/primitives/asymmetric/x25519.py | 7 ++-- .../hazmat/primitives/asymmetric/x448.py | 7 ++-- .../hazmat/primitives/ciphers/__init__.py | 1 + .../hazmat/primitives/ciphers/aead.py | 1 + .../hazmat/primitives/ciphers/algorithms.py | 1 + .../hazmat/primitives/ciphers/base.py | 19 +++++---- .../hazmat/primitives/ciphers/modes.py | 1 + src/cryptography/hazmat/primitives/cmac.py | 7 ++-- .../hazmat/primitives/constant_time.py | 1 + src/cryptography/hazmat/primitives/hashes.py | 8 ++-- src/cryptography/hazmat/primitives/hmac.py | 3 +- .../hazmat/primitives/kdf/__init__.py | 1 + .../hazmat/primitives/kdf/concatkdf.py | 1 + .../hazmat/primitives/kdf/hkdf.py | 1 + .../hazmat/primitives/kdf/kbkdf.py | 2 + .../hazmat/primitives/kdf/pbkdf2.py | 1 + .../hazmat/primitives/kdf/scrypt.py | 1 + .../hazmat/primitives/kdf/x963kdf.py | 1 + src/cryptography/hazmat/primitives/keywrap.py | 1 + src/cryptography/hazmat/primitives/padding.py | 1 + .../hazmat/primitives/poly1305.py | 2 + .../primitives/serialization/__init__.py | 1 + .../hazmat/primitives/serialization/base.py | 5 ++- .../hazmat/primitives/serialization/pkcs12.py | 2 + .../hazmat/primitives/serialization/pkcs7.py | 8 ++-- .../hazmat/primitives/serialization/ssh.py | 23 ++++++----- .../hazmat/primitives/twofactor/__init__.py | 2 + .../hazmat/primitives/twofactor/hotp.py | 3 +- .../hazmat/primitives/twofactor/totp.py | 2 + src/cryptography/utils.py | 1 + src/cryptography/x509/__init__.py | 1 + src/cryptography/x509/base.py | 41 +++++++++---------- .../x509/certificate_transparency.py | 1 + src/cryptography/x509/extensions.py | 41 ++++++++++--------- src/cryptography/x509/general_name.py | 9 ++-- src/cryptography/x509/name.py | 4 +- src/cryptography/x509/ocsp.py | 15 +++---- src/cryptography/x509/oid.py | 2 + 108 files changed, 330 insertions(+), 194 deletions(-) diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index e971fd955882..42754fb6417b 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import os import pathlib diff --git a/src/_cffi_src/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py index 4927432898eb..d2be452a687b 100644 --- a/src/_cffi_src/openssl/asn1.py +++ b/src/_cffi_src/openssl/asn1.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py index 1e9f81128271..9ea729001433 100644 --- a/src/_cffi_src/openssl/bignum.py +++ b/src/_cffi_src/openssl/bignum.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 899856d355c2..1742e348122a 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/callbacks.py b/src/_cffi_src/openssl/callbacks.py index 57a393686197..ddb764283920 100644 --- a/src/_cffi_src/openssl/callbacks.py +++ b/src/_cffi_src/openssl/callbacks.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/cmac.py b/src/_cffi_src/openssl/cmac.py index a25426305131..7095066dac54 100644 --- a/src/_cffi_src/openssl/cmac.py +++ b/src/_cffi_src/openssl/cmac.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #if !defined(OPENSSL_NO_CMAC) diff --git a/src/_cffi_src/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py index 63843e02ee26..f36a0fa17616 100644 --- a/src/_cffi_src/openssl/crypto.py +++ b/src/_cffi_src/openssl/crypto.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py index 40e6ce9846fd..05d3e0e50165 100644 --- a/src/_cffi_src/openssl/cryptography.py +++ b/src/_cffi_src/openssl/cryptography.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ /* define our OpenSSL API compatibility level to 1.1.0. Any symbols older than diff --git a/src/_cffi_src/openssl/dh.py b/src/_cffi_src/openssl/dh.py index 44b3d817ae7e..1a75b6d22879 100644 --- a/src/_cffi_src/openssl/dh.py +++ b/src/_cffi_src/openssl/dh.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/dsa.py b/src/_cffi_src/openssl/dsa.py index cf34913b530b..04478a0e577b 100644 --- a/src/_cffi_src/openssl/dsa.py +++ b/src/_cffi_src/openssl/dsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/ec.py b/src/_cffi_src/openssl/ec.py index b037675f0d68..e745b3efcd14 100644 --- a/src/_cffi_src/openssl/ec.py +++ b/src/_cffi_src/openssl/ec.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/ecdsa.py b/src/_cffi_src/openssl/ecdsa.py index 53294afc60f7..716b5d03016f 100644 --- a/src/_cffi_src/openssl/ecdsa.py +++ b/src/_cffi_src/openssl/ecdsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py index 9931639b4828..609313ec57ae 100644 --- a/src/_cffi_src/openssl/engine.py +++ b/src/_cffi_src/openssl/engine.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index ebe6c3559837..2bb2545fc932 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index b8a38995c00b..aa92f1ddb968 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/fips.py b/src/_cffi_src/openssl/fips.py index 9fb1e7aed0bb..9e3ce9524b44 100644 --- a/src/_cffi_src/openssl/fips.py +++ b/src/_cffi_src/openssl/fips.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/hmac.py b/src/_cffi_src/openssl/hmac.py index 8b1915361be3..8fbc2b411608 100644 --- a/src/_cffi_src/openssl/hmac.py +++ b/src/_cffi_src/openssl/hmac.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/nid.py b/src/_cffi_src/openssl/nid.py index 28135b428d46..8933c95d82f0 100644 --- a/src/_cffi_src/openssl/nid.py +++ b/src/_cffi_src/openssl/nid.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/objects.py b/src/_cffi_src/openssl/objects.py index cfa7fac21268..5f9bdb3361d0 100644 --- a/src/_cffi_src/openssl/objects.py +++ b/src/_cffi_src/openssl/objects.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/opensslv.py b/src/_cffi_src/openssl/opensslv.py index 630ebd7a1b91..7957bd7dd58c 100644 --- a/src/_cffi_src/openssl/opensslv.py +++ b/src/_cffi_src/openssl/opensslv.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/pem.py b/src/_cffi_src/openssl/pem.py index 62253da7a544..aac77ac71111 100644 --- a/src/_cffi_src/openssl/pem.py +++ b/src/_cffi_src/openssl/pem.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/pkcs12.py b/src/_cffi_src/openssl/pkcs12.py index 135afc94b47a..234f97b3ea65 100644 --- a/src/_cffi_src/openssl/pkcs12.py +++ b/src/_cffi_src/openssl/pkcs12.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/pkcs7.py b/src/_cffi_src/openssl/pkcs7.py index e0d52322f7e1..60741bbac19d 100644 --- a/src/_cffi_src/openssl/pkcs7.py +++ b/src/_cffi_src/openssl/pkcs7.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/provider.py b/src/_cffi_src/openssl/provider.py index d741ad7e4f55..769fded96d23 100644 --- a/src/_cffi_src/openssl/provider.py +++ b/src/_cffi_src/openssl/provider.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #if CRYPTOGRAPHY_OPENSSL_300_OR_GREATER diff --git a/src/_cffi_src/openssl/rand.py b/src/_cffi_src/openssl/rand.py index a2cce0ad201e..ee00fe68d821 100644 --- a/src/_cffi_src/openssl/rand.py +++ b/src/_cffi_src/openssl/rand.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/rsa.py b/src/_cffi_src/openssl/rsa.py index a7a3256b71bb..eea6e396e3fb 100644 --- a/src/_cffi_src/openssl/rsa.py +++ b/src/_cffi_src/openssl/rsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 3e1b09209e3b..1b59e97ff083 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 06445f12c4af..66e8592042fd 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 71d0cec38d4f..0337afa3497d 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py index 9eca79e38e7c..876af17f2d5e 100644 --- a/src/_cffi_src/openssl/x509name.py +++ b/src/_cffi_src/openssl/x509name.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 838bda2903ec..dae98da1bf4e 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations INCLUDES = """ #include diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index 5d2c4224a12b..cc2a2fb5f050 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import os import platform diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index ef6399c179b5..9ab3785b18f7 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations __all__ = [ "__version__", diff --git a/src/cryptography/__init__.py b/src/cryptography/__init__.py index ffa979a4ea9d..86b9a25726d1 100644 --- a/src/cryptography/__init__.py +++ b/src/cryptography/__init__.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + from cryptography.__about__ import __author__, __copyright__, __version__ __all__ = [ diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py index 5e69c1192434..59c7ebaff43c 100644 --- a/src/cryptography/exceptions.py +++ b/src/cryptography/exceptions.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing @@ -56,7 +57,7 @@ class InvalidSignature(Exception): class InternalError(Exception): def __init__( - self, msg: str, err_code: typing.List["rust_openssl.OpenSSLError"] + self, msg: str, err_code: typing.List[rust_openssl.OpenSSLError] ) -> None: super().__init__(msg) self.err_code = err_code diff --git a/src/cryptography/fernet.py b/src/cryptography/fernet.py index a2601f80f680..ad8fb40b9d44 100644 --- a/src/cryptography/fernet.py +++ b/src/cryptography/fernet.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import base64 import binascii diff --git a/src/cryptography/hazmat/__init__.py b/src/cryptography/hazmat/__init__.py index 007694bc5060..b9f1187011bd 100644 --- a/src/cryptography/hazmat/__init__.py +++ b/src/cryptography/hazmat/__init__.py @@ -1,6 +1,9 @@ # 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. + +from __future__ import annotations + """ Hazardous Materials diff --git a/src/cryptography/hazmat/_oid.py b/src/cryptography/hazmat/_oid.py index bc9c046c6a78..82a6498f92c2 100644 --- a/src/cryptography/hazmat/_oid.py +++ b/src/cryptography/hazmat/_oid.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.hazmat.bindings._rust import ( diff --git a/src/cryptography/hazmat/backends/__init__.py b/src/cryptography/hazmat/backends/__init__.py index 3926f85f1d18..b4400aa03745 100644 --- a/src/cryptography/hazmat/backends/__init__.py +++ b/src/cryptography/hazmat/backends/__init__.py @@ -1,6 +1,9 @@ # 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. + +from __future__ import annotations + from typing import Any diff --git a/src/cryptography/hazmat/backends/openssl/__init__.py b/src/cryptography/hazmat/backends/openssl/__init__.py index 42c4539df3ed..51b04476cbb7 100644 --- a/src/cryptography/hazmat/backends/openssl/__init__.py +++ b/src/cryptography/hazmat/backends/openssl/__init__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography.hazmat.backends.openssl.backend import backend diff --git a/src/cryptography/hazmat/backends/openssl/aead.py b/src/cryptography/hazmat/backends/openssl/aead.py index d43deb432a16..7361f227914d 100644 --- a/src/cryptography/hazmat/backends/openssl/aead.py +++ b/src/cryptography/hazmat/backends/openssl/aead.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import InvalidTag @@ -24,7 +26,7 @@ _DECRYPT = 0 -def _aead_cipher_name(cipher: "_AEADTypes") -> bytes: +def _aead_cipher_name(cipher: _AEADTypes) -> bytes: from cryptography.hazmat.primitives.ciphers.aead import ( AESCCM, AESGCM, @@ -46,7 +48,7 @@ def _aead_cipher_name(cipher: "_AEADTypes") -> bytes: return f"aes-{len(cipher._key) * 8}-gcm".encode("ascii") -def _evp_cipher(cipher_name: bytes, backend: "Backend"): +def _evp_cipher(cipher_name: bytes, backend: Backend): if cipher_name.endswith(b"-siv"): evp_cipher = backend._lib.EVP_CIPHER_fetch( backend._ffi.NULL, @@ -63,8 +65,8 @@ def _evp_cipher(cipher_name: bytes, backend: "Backend"): def _aead_create_ctx( - backend: "Backend", - cipher: "_AEADTypes", + backend: Backend, + cipher: _AEADTypes, key: bytes, ): ctx = backend._lib.EVP_CIPHER_CTX_new() @@ -86,7 +88,7 @@ def _aead_create_ctx( def _aead_setup( - backend: "Backend", + backend: Backend, cipher_name: bytes, key: bytes, nonce: bytes, @@ -158,7 +160,7 @@ def _set_nonce_operation(backend, ctx, nonce: bytes, operation: int) -> None: backend.openssl_assert(res != 0) -def _set_length(backend: "Backend", ctx, data_len: int) -> None: +def _set_length(backend: Backend, ctx, data_len: int) -> None: intptr = backend._ffi.new("int *") res = backend._lib.EVP_CipherUpdate( ctx, backend._ffi.NULL, intptr, backend._ffi.NULL, data_len @@ -166,7 +168,7 @@ def _set_length(backend: "Backend", ctx, data_len: int) -> None: backend.openssl_assert(res != 0) -def _process_aad(backend: "Backend", ctx, associated_data: bytes) -> None: +def _process_aad(backend: Backend, ctx, associated_data: bytes) -> None: outlen = backend._ffi.new("int *") a_data_ptr = backend._ffi.from_buffer(associated_data) res = backend._lib.EVP_CipherUpdate( @@ -175,7 +177,7 @@ def _process_aad(backend: "Backend", ctx, associated_data: bytes) -> None: backend.openssl_assert(res != 0) -def _process_data(backend: "Backend", ctx, data: bytes) -> bytes: +def _process_data(backend: Backend, ctx, data: bytes) -> bytes: outlen = backend._ffi.new("int *") buf = backend._ffi.new("unsigned char[]", len(data)) data_ptr = backend._ffi.from_buffer(data) @@ -188,8 +190,8 @@ def _process_data(backend: "Backend", ctx, data: bytes) -> bytes: def _encrypt( - backend: "Backend", - cipher: "_AEADTypes", + backend: Backend, + cipher: _AEADTypes, nonce: bytes, data: bytes, associated_data: typing.List[bytes], @@ -246,8 +248,8 @@ def _encrypt( def _decrypt( - backend: "Backend", - cipher: "_AEADTypes", + backend: Backend, + cipher: _AEADTypes, nonce: bytes, data: bytes, associated_data: typing.List[bytes], diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 5876563695b5..ac464e75a809 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import collections import contextlib diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index 8d4b8dc3bbf1..bc42adbd49a5 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons @@ -17,9 +19,7 @@ class _CipherContext: _DECRYPT = 0 _MAX_CHUNK_SIZE = 2**30 - 1 - def __init__( - self, backend: "Backend", cipher, mode, operation: int - ) -> None: + def __init__(self, backend: Backend, cipher, mode, operation: int) -> None: self._backend = backend self._cipher = cipher self._mode = mode diff --git a/src/cryptography/hazmat/backends/openssl/cmac.py b/src/cryptography/hazmat/backends/openssl/cmac.py index 6f7363294179..bdd7fec611d1 100644 --- a/src/cryptography/hazmat/backends/openssl/cmac.py +++ b/src/cryptography/hazmat/backends/openssl/cmac.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import ( @@ -20,8 +22,8 @@ class _CMACContext: def __init__( self, - backend: "Backend", - algorithm: "ciphers.BlockCipherAlgorithm", + backend: Backend, + algorithm: ciphers.BlockCipherAlgorithm, ctx=None, ) -> None: if not backend.cmac_algorithm_supported(algorithm): @@ -72,7 +74,7 @@ def finalize(self) -> bytes: return self._backend._ffi.buffer(buf)[:] - def copy(self) -> "_CMACContext": + def copy(self) -> _CMACContext: copied_ctx = self._backend._lib.CMAC_CTX_new() copied_ctx = self._backend._ffi.gc( copied_ctx, self._backend._lib.CMAC_CTX_free diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py index df91d6d8a73e..bf123b6285b6 100644 --- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography import x509 diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py index 87d6fb8af694..6c1889bc3ac2 100644 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ b/src/cryptography/hazmat/backends/openssl/dh.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import UnsupportedAlgorithm, _Reasons @@ -12,7 +14,7 @@ from cryptography.hazmat.backends.openssl.backend import Backend -def _dh_params_dup(dh_cdata, backend: "Backend"): +def _dh_params_dup(dh_cdata, backend: Backend): lib = backend._lib ffi = backend._ffi @@ -30,13 +32,13 @@ def _dh_params_dup(dh_cdata, backend: "Backend"): return param_cdata -def _dh_cdata_to_parameters(dh_cdata, backend: "Backend") -> "_DHParameters": +def _dh_cdata_to_parameters(dh_cdata, backend: Backend) -> _DHParameters: param_cdata = _dh_params_dup(dh_cdata, backend) return _DHParameters(backend, param_cdata) class _DHParameters(dh.DHParameters): - def __init__(self, backend: "Backend", dh_cdata): + def __init__(self, backend: Backend, dh_cdata): self._backend = backend self._dh_cdata = dh_cdata @@ -112,7 +114,7 @@ def _get_dh_num_bits(backend, dh_cdata) -> int: class _DHPrivateKey(dh.DHPrivateKey): - def __init__(self, backend: "Backend", dh_cdata, evp_pkey): + def __init__(self, backend: Backend, dh_cdata, evp_pkey): self._backend = backend self._dh_cdata = dh_cdata self._evp_pkey = evp_pkey @@ -249,7 +251,7 @@ def private_bytes( class _DHPublicKey(dh.DHPublicKey): - def __init__(self, backend: "Backend", dh_cdata, evp_pkey): + def __init__(self, backend: Backend, dh_cdata, evp_pkey): self._backend = backend self._dh_cdata = dh_cdata self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py index 15bd84a7b5a5..be0500152aeb 100644 --- a/src/cryptography/hazmat/backends/openssl/dsa.py +++ b/src/cryptography/hazmat/backends/openssl/dsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing @@ -18,7 +19,7 @@ def _dsa_sig_sign( - backend: "Backend", private_key: "_DSAPrivateKey", data: bytes + backend: Backend, private_key: _DSAPrivateKey, data: bytes ) -> bytes: sig_buf_len = backend._lib.DSA_size(private_key._dsa_cdata) sig_buf = backend._ffi.new("unsigned char[]", sig_buf_len) @@ -36,8 +37,8 @@ def _dsa_sig_sign( def _dsa_sig_verify( - backend: "Backend", - public_key: "_DSAPublicKey", + backend: Backend, + public_key: _DSAPublicKey, signature: bytes, data: bytes, ) -> None: @@ -53,7 +54,7 @@ def _dsa_sig_verify( class _DSAParameters(dsa.DSAParameters): - def __init__(self, backend: "Backend", dsa_cdata): + def __init__(self, backend: Backend, dsa_cdata): self._backend = backend self._dsa_cdata = dsa_cdata @@ -78,7 +79,7 @@ def generate_private_key(self) -> dsa.DSAPrivateKey: class _DSAPrivateKey(dsa.DSAPrivateKey): _key_size: int - def __init__(self, backend: "Backend", dsa_cdata, evp_pkey): + def __init__(self, backend: Backend, dsa_cdata, evp_pkey): self._backend = backend self._dsa_cdata = dsa_cdata self._evp_pkey = evp_pkey @@ -173,7 +174,7 @@ def sign( class _DSAPublicKey(dsa.DSAPublicKey): _key_size: int - def __init__(self, backend: "Backend", dsa_cdata, evp_pkey): + def __init__(self, backend: Backend, dsa_cdata, evp_pkey): self._backend = backend self._dsa_cdata = dsa_cdata self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 969306bcb893..90a7b6fa3fc1 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import ( @@ -30,7 +32,7 @@ def _check_signature_algorithm( ) -def _ec_key_curve_sn(backend: "Backend", ec_key) -> str: +def _ec_key_curve_sn(backend: Backend, ec_key) -> str: group = backend._lib.EC_KEY_get0_group(ec_key) backend.openssl_assert(group != backend._ffi.NULL) @@ -60,7 +62,7 @@ def _ec_key_curve_sn(backend: "Backend", ec_key) -> str: return sn -def _mark_asn1_named_ec_curve(backend: "Backend", ec_cdata): +def _mark_asn1_named_ec_curve(backend: Backend, ec_cdata): """ Set the named curve flag on the EC_KEY. This causes OpenSSL to serialize EC keys along with their curve OID which makes @@ -72,7 +74,7 @@ def _mark_asn1_named_ec_curve(backend: "Backend", ec_cdata): ) -def _check_key_infinity(backend: "Backend", ec_cdata) -> None: +def _check_key_infinity(backend: Backend, ec_cdata) -> None: point = backend._lib.EC_KEY_get0_public_key(ec_cdata) backend.openssl_assert(point != backend._ffi.NULL) group = backend._lib.EC_KEY_get0_group(ec_cdata) @@ -83,7 +85,7 @@ def _check_key_infinity(backend: "Backend", ec_cdata) -> None: ) -def _sn_to_elliptic_curve(backend: "Backend", sn: str) -> ec.EllipticCurve: +def _sn_to_elliptic_curve(backend: Backend, sn: str) -> ec.EllipticCurve: try: return ec._CURVE_TYPES[sn]() except KeyError: @@ -94,7 +96,7 @@ def _sn_to_elliptic_curve(backend: "Backend", sn: str) -> ec.EllipticCurve: def _ecdsa_sig_sign( - backend: "Backend", private_key: "_EllipticCurvePrivateKey", data: bytes + backend: Backend, private_key: _EllipticCurvePrivateKey, data: bytes ) -> bytes: max_size = backend._lib.ECDSA_size(private_key._ec_key) backend.openssl_assert(max_size > 0) @@ -109,8 +111,8 @@ def _ecdsa_sig_sign( def _ecdsa_sig_verify( - backend: "Backend", - public_key: "_EllipticCurvePublicKey", + backend: Backend, + public_key: _EllipticCurvePublicKey, signature: bytes, data: bytes, ) -> None: @@ -123,7 +125,7 @@ def _ecdsa_sig_verify( class _EllipticCurvePrivateKey(ec.EllipticCurvePrivateKey): - def __init__(self, backend: "Backend", ec_key_cdata, evp_pkey): + def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): self._backend = backend self._ec_key = ec_key_cdata self._evp_pkey = evp_pkey @@ -215,7 +217,7 @@ def sign( class _EllipticCurvePublicKey(ec.EllipticCurvePublicKey): - def __init__(self, backend: "Backend", ec_key_cdata, evp_pkey): + def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): self._backend = backend self._ec_key = ec_key_cdata self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/ed25519.py b/src/cryptography/hazmat/backends/openssl/ed25519.py index 6f393e5b6aa9..4e33a78f35f3 100644 --- a/src/cryptography/hazmat/backends/openssl/ed25519.py +++ b/src/cryptography/hazmat/backends/openssl/ed25519.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import exceptions @@ -18,7 +20,7 @@ class _Ed25519PublicKey(Ed25519PublicKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey @@ -78,7 +80,7 @@ def verify(self, signature: bytes, data: bytes) -> None: class _Ed25519PrivateKey(Ed25519PrivateKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/ed448.py b/src/cryptography/hazmat/backends/openssl/ed448.py index 0d27ea638ad6..b2300367697c 100644 --- a/src/cryptography/hazmat/backends/openssl/ed448.py +++ b/src/cryptography/hazmat/backends/openssl/ed448.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import exceptions @@ -19,7 +21,7 @@ class _Ed448PublicKey(Ed448PublicKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey @@ -79,7 +81,7 @@ def verify(self, signature: bytes, data: bytes) -> None: class _Ed448PrivateKey(Ed448PrivateKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py index 52d4646a7ab0..370407aac58d 100644 --- a/src/cryptography/hazmat/backends/openssl/hashes.py +++ b/src/cryptography/hazmat/backends/openssl/hashes.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import UnsupportedAlgorithm, _Reasons @@ -13,7 +15,7 @@ class _HashContext(hashes.HashContext): def __init__( - self, backend: "Backend", algorithm: hashes.HashAlgorithm, ctx=None + self, backend: Backend, algorithm: hashes.HashAlgorithm, ctx=None ) -> None: self._algorithm = algorithm @@ -43,7 +45,7 @@ def __init__( def algorithm(self) -> hashes.HashAlgorithm: return self._algorithm - def copy(self) -> "_HashContext": + def copy(self) -> _HashContext: copied_ctx = self._backend._lib.EVP_MD_CTX_new() copied_ctx = self._backend._ffi.gc( copied_ctx, self._backend._lib.EVP_MD_CTX_free diff --git a/src/cryptography/hazmat/backends/openssl/hmac.py b/src/cryptography/hazmat/backends/openssl/hmac.py index ba3dfb53f8b3..669f380705e1 100644 --- a/src/cryptography/hazmat/backends/openssl/hmac.py +++ b/src/cryptography/hazmat/backends/openssl/hmac.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import ( @@ -18,7 +20,7 @@ class _HMACContext(hashes.HashContext): def __init__( self, - backend: "Backend", + backend: Backend, key: bytes, algorithm: hashes.HashAlgorithm, ctx=None, @@ -51,7 +53,7 @@ def __init__( def algorithm(self) -> hashes.HashAlgorithm: return self._algorithm - def copy(self) -> "_HMACContext": + def copy(self) -> _HMACContext: copied_ctx = self._backend._lib.HMAC_CTX_new() self._backend.openssl_assert(copied_ctx != self._backend._ffi.NULL) copied_ctx = self._backend._ffi.gc( diff --git a/src/cryptography/hazmat/backends/openssl/poly1305.py b/src/cryptography/hazmat/backends/openssl/poly1305.py index d0d44f6fd96e..bb0c3738b667 100644 --- a/src/cryptography/hazmat/backends/openssl/poly1305.py +++ b/src/cryptography/hazmat/backends/openssl/poly1305.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.exceptions import InvalidSignature @@ -16,7 +18,7 @@ class _Poly1305Context: - def __init__(self, backend: "Backend", key: bytes) -> None: + def __init__(self, backend: Backend, key: bytes) -> None: self._backend = backend key_ptr = self._backend._ffi.from_buffer(key) diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index c960105e718e..f8ca3341af85 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import threading import typing @@ -38,7 +40,7 @@ def _get_rsa_pss_salt_length( - backend: "Backend", + backend: Backend, pss: PSS, key: typing.Union[RSAPrivateKey, RSAPublicKey], hash_algorithm: hashes.HashAlgorithm, @@ -60,8 +62,8 @@ def _get_rsa_pss_salt_length( def _enc_dec_rsa( - backend: "Backend", - key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"], + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], data: bytes, padding: AsymmetricPadding, ) -> bytes: @@ -96,8 +98,8 @@ def _enc_dec_rsa( def _enc_dec_rsa_pkey_ctx( - backend: "Backend", - key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"], + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], data: bytes, padding_enum: int, padding: AsymmetricPadding, @@ -163,8 +165,8 @@ def _enc_dec_rsa_pkey_ctx( def _rsa_sig_determine_padding( - backend: "Backend", - key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"], + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], padding: AsymmetricPadding, algorithm: typing.Optional[hashes.HashAlgorithm], ) -> int: @@ -211,10 +213,10 @@ def _rsa_sig_determine_padding( # padding type, where it means that the signature data is encoded/decoded # as provided, without being wrapped in a DigestInfo structure. def _rsa_sig_setup( - backend: "Backend", + backend: Backend, padding: AsymmetricPadding, algorithm: typing.Optional[hashes.HashAlgorithm], - key: typing.Union["_RSAPublicKey", "_RSAPrivateKey"], + key: typing.Union[_RSAPublicKey, _RSAPrivateKey], init_func: typing.Callable[[typing.Any], int], ): padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm) @@ -264,10 +266,10 @@ def _rsa_sig_setup( def _rsa_sig_sign( - backend: "Backend", + backend: Backend, padding: AsymmetricPadding, algorithm: hashes.HashAlgorithm, - private_key: "_RSAPrivateKey", + private_key: _RSAPrivateKey, data: bytes, ) -> bytes: pkey_ctx = _rsa_sig_setup( @@ -296,10 +298,10 @@ def _rsa_sig_sign( def _rsa_sig_verify( - backend: "Backend", + backend: Backend, padding: AsymmetricPadding, algorithm: hashes.HashAlgorithm, - public_key: "_RSAPublicKey", + public_key: _RSAPublicKey, signature: bytes, data: bytes, ) -> None: @@ -323,10 +325,10 @@ def _rsa_sig_verify( def _rsa_sig_recover( - backend: "Backend", + backend: Backend, padding: AsymmetricPadding, algorithm: typing.Optional[hashes.HashAlgorithm], - public_key: "_RSAPublicKey", + public_key: _RSAPublicKey, signature: bytes, ) -> bytes: pkey_ctx = _rsa_sig_setup( @@ -365,7 +367,7 @@ class _RSAPrivateKey(RSAPrivateKey): def __init__( self, - backend: "Backend", + backend: Backend, rsa_cdata, evp_pkey, *, @@ -516,7 +518,7 @@ class _RSAPublicKey(RSAPublicKey): _rsa_cdata: object _key_size: int - def __init__(self, backend: "Backend", rsa_cdata, evp_pkey): + def __init__(self, backend: Backend, rsa_cdata, evp_pkey): self._backend = backend self._rsa_cdata = rsa_cdata self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/backends/openssl/utils.py b/src/cryptography/hazmat/backends/openssl/utils.py index 64b4a8334b51..5b404defde33 100644 --- a/src/cryptography/hazmat/backends/openssl/utils.py +++ b/src/cryptography/hazmat/backends/openssl/utils.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.hazmat.primitives import hashes @@ -11,7 +13,7 @@ from cryptography.hazmat.backends.openssl.backend import Backend -def _evp_pkey_derive(backend: "Backend", evp_pkey, peer_public_key) -> bytes: +def _evp_pkey_derive(backend: Backend, evp_pkey, peer_public_key) -> bytes: ctx = backend._lib.EVP_PKEY_CTX_new(evp_pkey, backend._ffi.NULL) backend.openssl_assert(ctx != backend._ffi.NULL) ctx = backend._ffi.gc(ctx, backend._lib.EVP_PKEY_CTX_free) diff --git a/src/cryptography/hazmat/backends/openssl/x448.py b/src/cryptography/hazmat/backends/openssl/x448.py index d738188c71f7..5c91fba45279 100644 --- a/src/cryptography/hazmat/backends/openssl/x448.py +++ b/src/cryptography/hazmat/backends/openssl/x448.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive @@ -18,7 +20,7 @@ class _X448PublicKey(X448PublicKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey @@ -57,7 +59,7 @@ def _raw_public_bytes(self) -> bytes: class _X448PrivateKey(X448PrivateKey): - def __init__(self, backend: "Backend", evp_pkey): + def __init__(self, backend: Backend, evp_pkey): self._backend = backend self._evp_pkey = evp_pkey diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 35829a2821da..95d5297d5711 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 99061e21b421..b50d631518c1 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import os import sys import threading diff --git a/src/cryptography/hazmat/primitives/_asymmetric.py b/src/cryptography/hazmat/primitives/_asymmetric.py index fb815a0e9154..ea55ffdf1a72 100644 --- a/src/cryptography/hazmat/primitives/_asymmetric.py +++ b/src/cryptography/hazmat/primitives/_asymmetric.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import abc # This exists to break an import cycle. It is normally accessible from the diff --git a/src/cryptography/hazmat/primitives/_cipheralgorithm.py b/src/cryptography/hazmat/primitives/_cipheralgorithm.py index b36dccfb3427..3b880b648849 100644 --- a/src/cryptography/hazmat/primitives/_cipheralgorithm.py +++ b/src/cryptography/hazmat/primitives/_cipheralgorithm.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import abc import typing diff --git a/src/cryptography/hazmat/primitives/_serialization.py b/src/cryptography/hazmat/primitives/_serialization.py index aa41f30d2586..34f3fbc86026 100644 --- a/src/cryptography/hazmat/primitives/_serialization.py +++ b/src/cryptography/hazmat/primitives/_serialization.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import abc import typing @@ -33,7 +35,7 @@ class PrivateFormat(utils.Enum): OpenSSH = "OpenSSH" PKCS12 = "PKCS12" - def encryption_builder(self) -> "KeySerializationEncryptionBuilder": + def encryption_builder(self) -> KeySerializationEncryptionBuilder: if self not in (PrivateFormat.OpenSSH, PrivateFormat.PKCS12): raise ValueError( "encryption_builder only supported with PrivateFormat.OpenSSH" @@ -86,7 +88,7 @@ def __init__( self._hmac_hash = _hmac_hash self._key_cert_algorithm = _key_cert_algorithm - def kdf_rounds(self, rounds: int) -> "KeySerializationEncryptionBuilder": + def kdf_rounds(self, rounds: int) -> KeySerializationEncryptionBuilder: if self._kdf_rounds is not None: raise ValueError("kdf_rounds already set") @@ -105,7 +107,7 @@ def kdf_rounds(self, rounds: int) -> "KeySerializationEncryptionBuilder": def hmac_hash( self, algorithm: HashAlgorithm - ) -> "KeySerializationEncryptionBuilder": + ) -> KeySerializationEncryptionBuilder: if self._format is not PrivateFormat.PKCS12: raise TypeError( "hmac_hash only supported with PrivateFormat.PKCS12" @@ -122,7 +124,7 @@ def hmac_hash( def key_cert_algorithm( self, algorithm: PBES - ) -> "KeySerializationEncryptionBuilder": + ) -> KeySerializationEncryptionBuilder: if self._format is not PrivateFormat.PKCS12: raise TypeError( "key_cert_algorithm only supported with " diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index debf01e134fa..272cc5e54671 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -13,7 +14,7 @@ def generate_parameters( generator: int, key_size: int, backend: typing.Any = None -) -> "DHParameters": +) -> DHParameters: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.generate_dh_parameters(generator, key_size) @@ -46,7 +47,7 @@ def __eq__(self, other: object) -> bool: self._p == other._p and self._g == other._g and self._q == other._q ) - def parameters(self, backend: typing.Any = None) -> "DHParameters": + def parameters(self, backend: typing.Any = None) -> DHParameters: from cryptography.hazmat.backends.openssl.backend import ( backend as ossl, ) @@ -88,7 +89,7 @@ def __eq__(self, other: object) -> bool: and self._parameter_numbers == other._parameter_numbers ) - def public_key(self, backend: typing.Any = None) -> "DHPublicKey": + def public_key(self, backend: typing.Any = None) -> DHPublicKey: from cryptography.hazmat.backends.openssl.backend import ( backend as ossl, ) @@ -126,7 +127,7 @@ def __eq__(self, other: object) -> bool: and self._public_numbers == other._public_numbers ) - def private_key(self, backend: typing.Any = None) -> "DHPrivateKey": + def private_key(self, backend: typing.Any = None) -> DHPrivateKey: from cryptography.hazmat.backends.openssl.backend import ( backend as ossl, ) @@ -144,7 +145,7 @@ def x(self) -> int: class DHParameters(metaclass=abc.ABCMeta): @abc.abstractmethod - def generate_private_key(self) -> "DHPrivateKey": + def generate_private_key(self) -> DHPrivateKey: """ Generates and returns a DHPrivateKey. """ diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 6103d809355f..e846d3e83a9c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -12,13 +13,13 @@ class DSAParameters(metaclass=abc.ABCMeta): @abc.abstractmethod - def generate_private_key(self) -> "DSAPrivateKey": + def generate_private_key(self) -> DSAPrivateKey: """ Generates and returns a DSAPrivateKey. """ @abc.abstractmethod - def parameter_numbers(self) -> "DSAParameterNumbers": + def parameter_numbers(self) -> DSAParameterNumbers: """ Returns a DSAParameterNumbers. """ @@ -36,7 +37,7 @@ def key_size(self) -> int: """ @abc.abstractmethod - def public_key(self) -> "DSAPublicKey": + def public_key(self) -> DSAPublicKey: """ The DSAPublicKey associated with this private key. """ @@ -58,7 +59,7 @@ def sign( """ @abc.abstractmethod - def private_numbers(self) -> "DSAPrivateNumbers": + def private_numbers(self) -> DSAPrivateNumbers: """ Returns a DSAPrivateNumbers. """ @@ -93,7 +94,7 @@ def parameters(self) -> DSAParameters: """ @abc.abstractmethod - def public_numbers(self) -> "DSAPublicNumbers": + def public_numbers(self) -> DSAPublicNumbers: """ Returns a DSAPublicNumbers. """ diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index c5df2c27a6e8..2e3b0108b194 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -64,7 +65,7 @@ def algorithm( class EllipticCurvePrivateKey(metaclass=abc.ABCMeta): @abc.abstractmethod def exchange( - self, algorithm: "ECDH", peer_public_key: "EllipticCurvePublicKey" + self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey ) -> bytes: """ Performs a key exchange operation using the provided algorithm with the @@ -72,7 +73,7 @@ def exchange( """ @abc.abstractmethod - def public_key(self) -> "EllipticCurvePublicKey": + def public_key(self) -> EllipticCurvePublicKey: """ The EllipticCurvePublicKey for this private key. """ @@ -102,7 +103,7 @@ def sign( """ @abc.abstractmethod - def private_numbers(self) -> "EllipticCurvePrivateNumbers": + def private_numbers(self) -> EllipticCurvePrivateNumbers: """ Returns an EllipticCurvePrivateNumbers. """ @@ -138,7 +139,7 @@ def key_size(self) -> int: """ @abc.abstractmethod - def public_numbers(self) -> "EllipticCurvePublicNumbers": + def public_numbers(self) -> EllipticCurvePublicNumbers: """ Returns an EllipticCurvePublicNumbers. """ @@ -167,7 +168,7 @@ def verify( @classmethod def from_encoded_point( cls, curve: EllipticCurve, data: bytes - ) -> "EllipticCurvePublicKey": + ) -> EllipticCurvePublicKey: utils._check_bytes("data", data) if not isinstance(curve, EllipticCurve): diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index df34159ec7e0..83aa9d310e85 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc @@ -14,7 +15,7 @@ class Ed25519PublicKey(metaclass=abc.ABCMeta): @classmethod - def from_public_bytes(cls, data: bytes) -> "Ed25519PublicKey": + def from_public_bytes(cls, data: bytes) -> Ed25519PublicKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed25519_supported(): @@ -53,7 +54,7 @@ def verify(self, signature: bytes, data: bytes) -> None: class Ed25519PrivateKey(metaclass=abc.ABCMeta): @classmethod - def generate(cls) -> "Ed25519PrivateKey": + def generate(cls) -> Ed25519PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed25519_supported(): @@ -65,7 +66,7 @@ def generate(cls) -> "Ed25519PrivateKey": return backend.ed25519_generate_key() @classmethod - def from_private_bytes(cls, data: bytes) -> "Ed25519PrivateKey": + def from_private_bytes(cls, data: bytes) -> Ed25519PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed25519_supported(): diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed448.py b/src/cryptography/hazmat/primitives/asymmetric/ed448.py index 8b0ac1fd87a3..c2a64796c2f4 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc @@ -11,7 +12,7 @@ class Ed448PublicKey(metaclass=abc.ABCMeta): @classmethod - def from_public_bytes(cls, data: bytes) -> "Ed448PublicKey": + def from_public_bytes(cls, data: bytes) -> Ed448PublicKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed448_supported(): @@ -50,7 +51,7 @@ def verify(self, signature: bytes, data: bytes) -> None: class Ed448PrivateKey(metaclass=abc.ABCMeta): @classmethod - def generate(cls) -> "Ed448PrivateKey": + def generate(cls) -> Ed448PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed448_supported(): @@ -61,7 +62,7 @@ def generate(cls) -> "Ed448PrivateKey": return backend.ed448_generate_key() @classmethod - def from_private_bytes(cls, data: bytes) -> "Ed448PrivateKey": + def from_private_bytes(cls, data: bytes) -> Ed448PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.ed448_supported(): diff --git a/src/cryptography/hazmat/primitives/asymmetric/padding.py b/src/cryptography/hazmat/primitives/asymmetric/padding.py index dd3c648f165e..7198808effd0 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/padding.py +++ b/src/cryptography/hazmat/primitives/asymmetric/padding.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -38,7 +39,7 @@ class PSS(AsymmetricPadding): def __init__( self, - mgf: "MGF", + mgf: MGF, salt_length: typing.Union[int, _MaxLength, _Auto, _DigestLength], ) -> None: self._mgf = mgf @@ -62,7 +63,7 @@ class OAEP(AsymmetricPadding): def __init__( self, - mgf: "MGF", + mgf: MGF, algorithm: hashes.HashAlgorithm, label: typing.Optional[bytes], ): @@ -89,7 +90,7 @@ def __init__(self, algorithm: hashes.HashAlgorithm): def calculate_max_pss_salt_length( - key: typing.Union["rsa.RSAPrivateKey", "rsa.RSAPublicKey"], + key: typing.Union[rsa.RSAPrivateKey, rsa.RSAPublicKey], hash_algorithm: hashes.HashAlgorithm, ) -> int: if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 81f5a0ec639f..c83f7fc88999 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -27,7 +28,7 @@ def key_size(self) -> int: """ @abc.abstractmethod - def public_key(self) -> "RSAPublicKey": + def public_key(self) -> RSAPublicKey: """ The RSAPublicKey associated with this private key. """ @@ -44,7 +45,7 @@ def sign( """ @abc.abstractmethod - def private_numbers(self) -> "RSAPrivateNumbers": + def private_numbers(self) -> RSAPrivateNumbers: """ Returns an RSAPrivateNumbers. """ @@ -79,7 +80,7 @@ def key_size(self) -> int: """ @abc.abstractmethod - def public_numbers(self) -> "RSAPublicNumbers": + def public_numbers(self) -> RSAPublicNumbers: """ Returns an RSAPublicNumbers """ @@ -297,7 +298,7 @@ def __init__( dmp1: int, dmq1: int, iqmp: int, - public_numbers: "RSAPublicNumbers", + public_numbers: RSAPublicNumbers, ): if ( not isinstance(p, int) @@ -351,7 +352,7 @@ def iqmp(self) -> int: return self._iqmp @property - def public_numbers(self) -> "RSAPublicNumbers": + def public_numbers(self) -> RSAPublicNumbers: return self._public_numbers def private_key( diff --git a/src/cryptography/hazmat/primitives/asymmetric/types.py b/src/cryptography/hazmat/primitives/asymmetric/types.py index e911a9f602c2..1fe4eaf51d85 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/types.py +++ b/src/cryptography/hazmat/primitives/asymmetric/types.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import utils diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py index 140ca1960d9f..826b9567b47b 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/utils.py +++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography.hazmat.bindings._rust import asn1 from cryptography.hazmat.primitives import hashes diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index fb21fe1749a5..5455751508c4 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc @@ -12,7 +13,7 @@ class X25519PublicKey(metaclass=abc.ABCMeta): @classmethod - def from_public_bytes(cls, data: bytes) -> "X25519PublicKey": + def from_public_bytes(cls, data: bytes) -> X25519PublicKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x25519_supported(): @@ -48,7 +49,7 @@ def public_bytes_raw(self) -> bytes: class X25519PrivateKey(metaclass=abc.ABCMeta): @classmethod - def generate(cls) -> "X25519PrivateKey": + def generate(cls) -> X25519PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x25519_supported(): @@ -59,7 +60,7 @@ def generate(cls) -> "X25519PrivateKey": return backend.x25519_generate_key() @classmethod - def from_private_bytes(cls, data: bytes) -> "X25519PrivateKey": + def from_private_bytes(cls, data: bytes) -> X25519PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x25519_supported(): diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index dcab0445a4f7..25ff4c6ec36a 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc @@ -11,7 +12,7 @@ class X448PublicKey(metaclass=abc.ABCMeta): @classmethod - def from_public_bytes(cls, data: bytes) -> "X448PublicKey": + def from_public_bytes(cls, data: bytes) -> X448PublicKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x448_supported(): @@ -44,7 +45,7 @@ def public_bytes_raw(self) -> bytes: class X448PrivateKey(metaclass=abc.ABCMeta): @classmethod - def generate(cls) -> "X448PrivateKey": + def generate(cls) -> X448PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x448_supported(): @@ -55,7 +56,7 @@ def generate(cls) -> "X448PrivateKey": return backend.x448_generate_key() @classmethod - def from_private_bytes(cls, data: bytes) -> "X448PrivateKey": + def from_private_bytes(cls, data: bytes) -> X448PrivateKey: from cryptography.hazmat.backends.openssl.backend import backend if not backend.x448_supported(): diff --git a/src/cryptography/hazmat/primitives/ciphers/__init__.py b/src/cryptography/hazmat/primitives/ciphers/__init__.py index 95f02842ad1a..cc88fbf2c4c3 100644 --- a/src/cryptography/hazmat/primitives/ciphers/__init__.py +++ b/src/cryptography/hazmat/primitives/ciphers/__init__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography.hazmat.primitives._cipheralgorithm import ( BlockCipherAlgorithm, diff --git a/src/cryptography/hazmat/primitives/ciphers/aead.py b/src/cryptography/hazmat/primitives/ciphers/aead.py index f2e206bbfa5d..957b2d221b62 100644 --- a/src/cryptography/hazmat/primitives/ciphers/aead.py +++ b/src/cryptography/hazmat/primitives/ciphers/aead.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import os import typing diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py index 4357c17acab0..4bfc5d840d67 100644 --- a/src/cryptography/hazmat/primitives/ciphers/algorithms.py +++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography import utils from cryptography.hazmat.primitives.ciphers import ( diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index d80ef3f15d34..38a2ebbe081e 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing @@ -95,13 +96,13 @@ def __init__( @typing.overload def encryptor( - self: "Cipher[modes.ModeWithAuthenticationTag]", + self: Cipher[modes.ModeWithAuthenticationTag], ) -> AEADEncryptionContext: ... @typing.overload def encryptor( - self: "_CIPHER_TYPE", + self: _CIPHER_TYPE, ) -> CipherContext: ... @@ -120,13 +121,13 @@ def encryptor(self): @typing.overload def decryptor( - self: "Cipher[modes.ModeWithAuthenticationTag]", + self: Cipher[modes.ModeWithAuthenticationTag], ) -> AEADDecryptionContext: ... @typing.overload def decryptor( - self: "_CIPHER_TYPE", + self: _CIPHER_TYPE, ) -> CipherContext: ... @@ -139,7 +140,7 @@ def decryptor(self): return self._wrap_ctx(ctx, encrypt=False) def _wrap_ctx( - self, ctx: "_BackendCipherContext", encrypt: bool + self, ctx: _BackendCipherContext, encrypt: bool ) -> typing.Union[ AEADEncryptionContext, AEADDecryptionContext, CipherContext ]: @@ -164,9 +165,9 @@ def _wrap_ctx( class _CipherContext(CipherContext): - _ctx: typing.Optional["_BackendCipherContext"] + _ctx: typing.Optional[_BackendCipherContext] - def __init__(self, ctx: "_BackendCipherContext") -> None: + def __init__(self, ctx: _BackendCipherContext) -> None: self._ctx = ctx def update(self, data: bytes) -> bytes: @@ -188,10 +189,10 @@ def finalize(self) -> bytes: class _AEADCipherContext(AEADCipherContext): - _ctx: typing.Optional["_BackendCipherContext"] + _ctx: typing.Optional[_BackendCipherContext] _tag: typing.Optional[bytes] - def __init__(self, ctx: "_BackendCipherContext") -> None: + def __init__(self, ctx: _BackendCipherContext) -> None: self._ctx = ctx self._bytes_processed = 0 self._aad_bytes_processed = 0 diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index 1fba397feb7a..d8ea1888d67b 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing diff --git a/src/cryptography/hazmat/primitives/cmac.py b/src/cryptography/hazmat/primitives/cmac.py index 00c4bd11d877..8aa1d791acdd 100644 --- a/src/cryptography/hazmat/primitives/cmac.py +++ b/src/cryptography/hazmat/primitives/cmac.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing @@ -14,14 +15,14 @@ class CMAC: - _ctx: typing.Optional["_CMACContext"] + _ctx: typing.Optional[_CMACContext] _algorithm: ciphers.BlockCipherAlgorithm def __init__( self, algorithm: ciphers.BlockCipherAlgorithm, backend: typing.Any = None, - ctx: typing.Optional["_CMACContext"] = None, + ctx: typing.Optional[_CMACContext] = None, ) -> None: if not isinstance(algorithm, ciphers.BlockCipherAlgorithm): raise TypeError("Expected instance of BlockCipherAlgorithm.") @@ -58,7 +59,7 @@ def verify(self, signature: bytes) -> None: ctx, self._ctx = self._ctx, None ctx.verify(signature) - def copy(self) -> "CMAC": + def copy(self) -> CMAC: if self._ctx is None: raise AlreadyFinalized("Context was already finalized.") return CMAC(self._algorithm, ctx=self._ctx.copy()) diff --git a/src/cryptography/hazmat/primitives/constant_time.py b/src/cryptography/hazmat/primitives/constant_time.py index a02fa9c45345..3975c7147eb9 100644 --- a/src/cryptography/hazmat/primitives/constant_time.py +++ b/src/cryptography/hazmat/primitives/constant_time.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import hmac diff --git a/src/cryptography/hazmat/primitives/hashes.py b/src/cryptography/hazmat/primitives/hashes.py index 6bbab4c0b92a..c4b7d1060ada 100644 --- a/src/cryptography/hazmat/primitives/hashes.py +++ b/src/cryptography/hazmat/primitives/hashes.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import abc import typing @@ -54,7 +56,7 @@ def finalize(self) -> bytes: """ @abc.abstractmethod - def copy(self) -> "HashContext": + def copy(self) -> HashContext: """ Return a HashContext that is a copy of the current context. """ @@ -73,7 +75,7 @@ def __init__( self, algorithm: HashAlgorithm, backend: typing.Any = None, - ctx: typing.Optional["HashContext"] = None, + ctx: typing.Optional[HashContext] = None, ) -> None: if not isinstance(algorithm, HashAlgorithm): raise TypeError("Expected instance of hashes.HashAlgorithm.") @@ -98,7 +100,7 @@ def update(self, data: bytes) -> None: utils._check_byteslike("data", data) self._ctx.update(data) - def copy(self) -> "Hash": + def copy(self) -> Hash: if self._ctx is None: raise AlreadyFinalized("Context was already finalized.") return Hash(self.algorithm, ctx=self._ctx.copy()) diff --git a/src/cryptography/hazmat/primitives/hmac.py b/src/cryptography/hazmat/primitives/hmac.py index 8f1c0eae6e1f..6627f57499ec 100644 --- a/src/cryptography/hazmat/primitives/hmac.py +++ b/src/cryptography/hazmat/primitives/hmac.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing @@ -45,7 +46,7 @@ def update(self, data: bytes) -> None: utils._check_byteslike("data", data) self._ctx.update(data) - def copy(self) -> "HMAC": + def copy(self) -> HMAC: if self._ctx is None: raise AlreadyFinalized("Context was already finalized.") return HMAC( diff --git a/src/cryptography/hazmat/primitives/kdf/__init__.py b/src/cryptography/hazmat/primitives/kdf/__init__.py index 38e2f8bc4d66..79bb459f01ec 100644 --- a/src/cryptography/hazmat/primitives/kdf/__init__.py +++ b/src/cryptography/hazmat/primitives/kdf/__init__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc diff --git a/src/cryptography/hazmat/primitives/kdf/concatkdf.py b/src/cryptography/hazmat/primitives/kdf/concatkdf.py index 7bbce4ffcdbc..d5ea58a94522 100644 --- a/src/cryptography/hazmat/primitives/kdf/concatkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/concatkdf.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py index 7d59a7ef77b9..d47689443631 100644 --- a/src/cryptography/hazmat/primitives/kdf/hkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing diff --git a/src/cryptography/hazmat/primitives/kdf/kbkdf.py b/src/cryptography/hazmat/primitives/kdf/kbkdf.py index 7f185a9af8d1..967763828f3f 100644 --- a/src/cryptography/hazmat/primitives/kdf/kbkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/kbkdf.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import utils diff --git a/src/cryptography/hazmat/primitives/kdf/pbkdf2.py b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py index 8d23f8c250d1..2caa50e80a19 100644 --- a/src/cryptography/hazmat/primitives/kdf/pbkdf2.py +++ b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing diff --git a/src/cryptography/hazmat/primitives/kdf/scrypt.py b/src/cryptography/hazmat/primitives/kdf/scrypt.py index 286f4388cb2a..6443832aa382 100644 --- a/src/cryptography/hazmat/primitives/kdf/scrypt.py +++ b/src/cryptography/hazmat/primitives/kdf/scrypt.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import sys import typing diff --git a/src/cryptography/hazmat/primitives/kdf/x963kdf.py b/src/cryptography/hazmat/primitives/kdf/x963kdf.py index 4ab64d08b1c5..17acc5174bb0 100644 --- a/src/cryptography/hazmat/primitives/kdf/x963kdf.py +++ b/src/cryptography/hazmat/primitives/kdf/x963kdf.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing diff --git a/src/cryptography/hazmat/primitives/keywrap.py b/src/cryptography/hazmat/primitives/keywrap.py index 64771ca3c5b0..59b0326c2a86 100644 --- a/src/cryptography/hazmat/primitives/keywrap.py +++ b/src/cryptography/hazmat/primitives/keywrap.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py index d6c1d9152820..fde3094b00ae 100644 --- a/src/cryptography/hazmat/primitives/padding.py +++ b/src/cryptography/hazmat/primitives/padding.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import typing diff --git a/src/cryptography/hazmat/primitives/poly1305.py b/src/cryptography/hazmat/primitives/poly1305.py index 7fcf4a50f575..77df07f02e68 100644 --- a/src/cryptography/hazmat/primitives/poly1305.py +++ b/src/cryptography/hazmat/primitives/poly1305.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import utils diff --git a/src/cryptography/hazmat/primitives/serialization/__init__.py b/src/cryptography/hazmat/primitives/serialization/__init__.py index 213c49958a74..b6c9a5cdc520 100644 --- a/src/cryptography/hazmat/primitives/serialization/__init__.py +++ b/src/cryptography/hazmat/primitives/serialization/__init__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography.hazmat.primitives._serialization import ( BestAvailableEncryption, diff --git a/src/cryptography/hazmat/primitives/serialization/base.py b/src/cryptography/hazmat/primitives/serialization/base.py index 7956ce0feb3f..18a96ccfd5cd 100644 --- a/src/cryptography/hazmat/primitives/serialization/base.py +++ b/src/cryptography/hazmat/primitives/serialization/base.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import typing @@ -36,7 +37,7 @@ def load_pem_public_key( def load_pem_parameters( data: bytes, backend: typing.Any = None -) -> "dh.DHParameters": +) -> dh.DHParameters: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_pem_parameters(data) @@ -66,7 +67,7 @@ def load_der_public_key( def load_der_parameters( data: bytes, backend: typing.Any = None -) -> "dh.DHParameters": +) -> dh.DHParameters: from cryptography.hazmat.backends.openssl.backend import backend as ossl return ossl.load_der_parameters(data) diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs12.py b/src/cryptography/hazmat/primitives/serialization/pkcs12.py index 1d36146a97e4..27133a3fa851 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs12.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs12.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography import x509 diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py index 0a72e0df80d5..9998bcaa1131 100644 --- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import email.base64mime import email.generator import email.message @@ -73,7 +75,7 @@ def __init__( self._signers = signers self._additional_certs = additional_certs - def set_data(self, data: bytes) -> "PKCS7SignatureBuilder": + def set_data(self, data: bytes) -> PKCS7SignatureBuilder: _check_byteslike("data", data) if self._data is not None: raise ValueError("data may only be set once") @@ -85,7 +87,7 @@ def add_signer( certificate: x509.Certificate, private_key: PKCS7PrivateKeyTypes, hash_algorithm: PKCS7HashTypes, - ) -> "PKCS7SignatureBuilder": + ) -> PKCS7SignatureBuilder: if not isinstance( hash_algorithm, ( @@ -114,7 +116,7 @@ def add_signer( def add_certificate( self, certificate: x509.Certificate - ) -> "PKCS7SignatureBuilder": + ) -> PKCS7SignatureBuilder: if not isinstance(certificate, x509.Certificate): raise TypeError("certificate must be a x509.Certificate") diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index fa278d9ed47a..90261845143a 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import binascii import enum @@ -100,7 +101,7 @@ def _bcrypt_kdf( def _get_ssh_key_type( - key: typing.Union["SSHPrivateKeyTypes", "SSHPublicKeyTypes"] + key: typing.Union[SSHPrivateKeyTypes, SSHPublicKeyTypes] ) -> bytes: if isinstance(key, ec.EllipticCurvePrivateKey): key_type = _ecdsa_key_type(key.public_key()) @@ -229,7 +230,7 @@ def put_u64(self, val: int) -> None: """Big-endian uint64""" self.flist.append(val.to_bytes(length=8, byteorder="big")) - def put_sshstr(self, val: typing.Union[bytes, "_FragList"]) -> None: + def put_sshstr(self, val: typing.Union[bytes, _FragList]) -> None: """Bytes prefixed with u32 length""" if isinstance(val, (bytes, memoryview, bytearray)): self.put_u32(len(val)) @@ -1084,7 +1085,7 @@ def __init__( def public_key( self, public_key: SSHCertPublicKeyTypes - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if not isinstance( public_key, ( @@ -1110,7 +1111,7 @@ def public_key( _extensions=self._extensions, ) - def serial(self, serial: int) -> "SSHCertificateBuilder": + def serial(self, serial: int) -> SSHCertificateBuilder: if not isinstance(serial, int): raise TypeError("serial must be an integer") if not 0 <= serial < 2**64: @@ -1131,7 +1132,7 @@ def serial(self, serial: int) -> "SSHCertificateBuilder": _extensions=self._extensions, ) - def type(self, type: SSHCertificateType) -> "SSHCertificateBuilder": + def type(self, type: SSHCertificateType) -> SSHCertificateBuilder: if not isinstance(type, SSHCertificateType): raise TypeError("type must be an SSHCertificateType") if self._type is not None: @@ -1150,7 +1151,7 @@ def type(self, type: SSHCertificateType) -> "SSHCertificateBuilder": _extensions=self._extensions, ) - def key_id(self, key_id: bytes) -> "SSHCertificateBuilder": + def key_id(self, key_id: bytes) -> SSHCertificateBuilder: if not isinstance(key_id, bytes): raise TypeError("key_id must be bytes") if self._key_id is not None: @@ -1171,7 +1172,7 @@ def key_id(self, key_id: bytes) -> "SSHCertificateBuilder": def valid_principals( self, valid_principals: typing.List[bytes] - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if self._valid_for_all_principals: raise ValueError( "Principals can't be set because the cert is valid " @@ -1229,7 +1230,7 @@ def valid_for_all_principals(self): def valid_before( self, valid_before: typing.Union[int, float] - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if not isinstance(valid_before, (int, float)): raise TypeError("valid_before must be an int or float") valid_before = int(valid_before) @@ -1253,7 +1254,7 @@ def valid_before( def valid_after( self, valid_after: typing.Union[int, float] - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if not isinstance(valid_after, (int, float)): raise TypeError("valid_after must be an int or float") valid_after = int(valid_after) @@ -1277,7 +1278,7 @@ def valid_after( def add_critical_option( self, name: bytes, value: bytes - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if not isinstance(name, bytes) or not isinstance(value, bytes): raise TypeError("name and value must be bytes") # This is O(n**2) @@ -1299,7 +1300,7 @@ def add_critical_option( def add_extension( self, name: bytes, value: bytes - ) -> "SSHCertificateBuilder": + ) -> SSHCertificateBuilder: if not isinstance(name, bytes) or not isinstance(value, bytes): raise TypeError("name and value must be bytes") # This is O(n**2) diff --git a/src/cryptography/hazmat/primitives/twofactor/__init__.py b/src/cryptography/hazmat/primitives/twofactor/__init__.py index 8a8b30f2aa8f..c1af42300486 100644 --- a/src/cryptography/hazmat/primitives/twofactor/__init__.py +++ b/src/cryptography/hazmat/primitives/twofactor/__init__.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + class InvalidToken(Exception): pass diff --git a/src/cryptography/hazmat/primitives/twofactor/hotp.py b/src/cryptography/hazmat/primitives/twofactor/hotp.py index 260822214db9..2067108a63d6 100644 --- a/src/cryptography/hazmat/primitives/twofactor/hotp.py +++ b/src/cryptography/hazmat/primitives/twofactor/hotp.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import base64 import typing @@ -15,7 +16,7 @@ def _generate_uri( - hotp: "HOTP", + hotp: HOTP, type_name: str, account_name: str, issuer: typing.Optional[str], diff --git a/src/cryptography/hazmat/primitives/twofactor/totp.py b/src/cryptography/hazmat/primitives/twofactor/totp.py index c66fa1de13c9..daddcea2f77e 100644 --- a/src/cryptography/hazmat/primitives/twofactor/totp.py +++ b/src/cryptography/hazmat/primitives/twofactor/totp.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import typing from cryptography.hazmat.primitives import constant_time diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index c8a5ee83139b..651e8509acf4 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import enum import sys diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index df7fd3fbb5bb..6d4a10eab579 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations from cryptography.x509 import certificate_transparency from cryptography.x509.base import ( diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 35c846d34eda..63eaa6bd4013 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import datetime @@ -279,7 +280,7 @@ def public_bytes(self, encoding: serialization.Encoding) -> bytes: """ @abc.abstractmethod - def verify_directly_issued_by(self, issuer: "Certificate") -> None: + def verify_directly_issued_by(self, issuer: Certificate) -> None: """ This method verifies that certificate issuer name matches the issuer subject name and that the certificate is signed by the @@ -627,7 +628,7 @@ def __init__( self._extensions = extensions self._attributes = attributes - def subject_name(self, name: Name) -> "CertificateSigningRequestBuilder": + def subject_name(self, name: Name) -> CertificateSigningRequestBuilder: """ Sets the certificate requestor's distinguished name. """ @@ -641,7 +642,7 @@ def subject_name(self, name: Name) -> "CertificateSigningRequestBuilder": def add_extension( self, extval: ExtensionType, critical: bool - ) -> "CertificateSigningRequestBuilder": + ) -> CertificateSigningRequestBuilder: """ Adds an X.509 extension to the certificate request. """ @@ -663,7 +664,7 @@ def add_attribute( value: bytes, *, _tag: typing.Optional[_ASN1Type] = None, - ) -> "CertificateSigningRequestBuilder": + ) -> CertificateSigningRequestBuilder: """ Adds an X.509 attribute with an OID and associated value. """ @@ -725,7 +726,7 @@ def __init__( self._not_valid_after = not_valid_after self._extensions = extensions - def issuer_name(self, name: Name) -> "CertificateBuilder": + def issuer_name(self, name: Name) -> CertificateBuilder: """ Sets the CA's distinguished name. """ @@ -743,7 +744,7 @@ def issuer_name(self, name: Name) -> "CertificateBuilder": self._extensions, ) - def subject_name(self, name: Name) -> "CertificateBuilder": + def subject_name(self, name: Name) -> CertificateBuilder: """ Sets the requestor's distinguished name. """ @@ -764,7 +765,7 @@ def subject_name(self, name: Name) -> "CertificateBuilder": def public_key( self, key: CertificatePublicKeyTypes, - ) -> "CertificateBuilder": + ) -> CertificateBuilder: """ Sets the requestor's public key (as found in the signing request). """ @@ -798,7 +799,7 @@ def public_key( self._extensions, ) - def serial_number(self, number: int) -> "CertificateBuilder": + def serial_number(self, number: int) -> CertificateBuilder: """ Sets the certificate serial number. """ @@ -825,9 +826,7 @@ def serial_number(self, number: int) -> "CertificateBuilder": self._extensions, ) - def not_valid_before( - self, time: datetime.datetime - ) -> "CertificateBuilder": + def not_valid_before(self, time: datetime.datetime) -> CertificateBuilder: """ Sets the certificate activation time. """ @@ -856,7 +855,7 @@ def not_valid_before( self._extensions, ) - def not_valid_after(self, time: datetime.datetime) -> "CertificateBuilder": + def not_valid_after(self, time: datetime.datetime) -> CertificateBuilder: """ Sets the certificate expiration time. """ @@ -890,7 +889,7 @@ def not_valid_after(self, time: datetime.datetime) -> "CertificateBuilder": def add_extension( self, extval: ExtensionType, critical: bool - ) -> "CertificateBuilder": + ) -> CertificateBuilder: """ Adds an X.509 extension to the certificate. """ @@ -960,7 +959,7 @@ def __init__( def issuer_name( self, issuer_name: Name - ) -> "CertificateRevocationListBuilder": + ) -> CertificateRevocationListBuilder: if not isinstance(issuer_name, Name): raise TypeError("Expecting x509.Name object.") if self._issuer_name is not None: @@ -975,7 +974,7 @@ def issuer_name( def last_update( self, last_update: datetime.datetime - ) -> "CertificateRevocationListBuilder": + ) -> CertificateRevocationListBuilder: if not isinstance(last_update, datetime.datetime): raise TypeError("Expecting datetime object.") if self._last_update is not None: @@ -999,7 +998,7 @@ def last_update( def next_update( self, next_update: datetime.datetime - ) -> "CertificateRevocationListBuilder": + ) -> CertificateRevocationListBuilder: if not isinstance(next_update, datetime.datetime): raise TypeError("Expecting datetime object.") if self._next_update is not None: @@ -1023,7 +1022,7 @@ def next_update( def add_extension( self, extval: ExtensionType, critical: bool - ) -> "CertificateRevocationListBuilder": + ) -> CertificateRevocationListBuilder: """ Adds an X.509 extension to the certificate revocation list. """ @@ -1042,7 +1041,7 @@ def add_extension( def add_revoked_certificate( self, revoked_certificate: RevokedCertificate - ) -> "CertificateRevocationListBuilder": + ) -> CertificateRevocationListBuilder: """ Adds a revoked certificate to the CRL. """ @@ -1086,7 +1085,7 @@ def __init__( self._revocation_date = revocation_date self._extensions = extensions - def serial_number(self, number: int) -> "RevokedCertificateBuilder": + def serial_number(self, number: int) -> RevokedCertificateBuilder: if not isinstance(number, int): raise TypeError("Serial number must be of integral type.") if self._serial_number is not None: @@ -1106,7 +1105,7 @@ def serial_number(self, number: int) -> "RevokedCertificateBuilder": def revocation_date( self, time: datetime.datetime - ) -> "RevokedCertificateBuilder": + ) -> RevokedCertificateBuilder: if not isinstance(time, datetime.datetime): raise TypeError("Expecting datetime object.") if self._revocation_date is not None: @@ -1122,7 +1121,7 @@ def revocation_date( def add_extension( self, extval: ExtensionType, critical: bool - ) -> "RevokedCertificateBuilder": + ) -> RevokedCertificateBuilder: if not isinstance(extval, ExtensionType): raise TypeError("extension must be an ExtensionType") diff --git a/src/cryptography/x509/certificate_transparency.py b/src/cryptography/x509/certificate_transparency.py index a67709865d44..73647ee716fc 100644 --- a/src/cryptography/x509/certificate_transparency.py +++ b/src/cryptography/x509/certificate_transparency.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import datetime diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 6fe3888bf788..981161a63b5b 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import datetime @@ -111,13 +112,13 @@ def public_bytes(self) -> bytes: class Extensions: def __init__( - self, extensions: typing.Iterable["Extension[ExtensionType]"] + self, extensions: typing.Iterable[Extension[ExtensionType]] ) -> None: self._extensions = list(extensions) def get_extension_for_oid( self, oid: ObjectIdentifier - ) -> "Extension[ExtensionType]": + ) -> Extension[ExtensionType]: for ext in self: if ext.oid == oid: return ext @@ -126,7 +127,7 @@ def get_extension_for_oid( def get_extension_for_class( self, extclass: typing.Type[ExtensionTypeVar] - ) -> "Extension[ExtensionTypeVar]": + ) -> Extension[ExtensionTypeVar]: if extclass is UnrecognizedExtension: raise TypeError( "UnrecognizedExtension can't be used with " @@ -221,7 +222,7 @@ def __init__( @classmethod def from_issuer_public_key( cls, public_key: CertificateIssuerPublicKeyTypes - ) -> "AuthorityKeyIdentifier": + ) -> AuthorityKeyIdentifier: digest = _key_identifier_from_public_key(public_key) return cls( key_identifier=digest, @@ -231,8 +232,8 @@ def from_issuer_public_key( @classmethod def from_issuer_subject_key_identifier( - cls, ski: "SubjectKeyIdentifier" - ) -> "AuthorityKeyIdentifier": + cls, ski: SubjectKeyIdentifier + ) -> AuthorityKeyIdentifier: return cls( key_identifier=ski.digest, authority_cert_issuer=None, @@ -294,7 +295,7 @@ def __init__(self, digest: bytes) -> None: @classmethod def from_public_key( cls, public_key: CertificatePublicKeyTypes - ) -> "SubjectKeyIdentifier": + ) -> SubjectKeyIdentifier: return cls(_key_identifier_from_public_key(public_key)) @property @@ -325,7 +326,7 @@ class AuthorityInformationAccess(ExtensionType): oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS def __init__( - self, descriptions: typing.Iterable["AccessDescription"] + self, descriptions: typing.Iterable[AccessDescription] ) -> None: descriptions = list(descriptions) if not all(isinstance(x, AccessDescription) for x in descriptions): @@ -358,7 +359,7 @@ class SubjectInformationAccess(ExtensionType): oid = ExtensionOID.SUBJECT_INFORMATION_ACCESS def __init__( - self, descriptions: typing.Iterable["AccessDescription"] + self, descriptions: typing.Iterable[AccessDescription] ) -> None: descriptions = list(descriptions) if not all(isinstance(x, AccessDescription) for x in descriptions): @@ -506,7 +507,7 @@ class CRLDistributionPoints(ExtensionType): oid = ExtensionOID.CRL_DISTRIBUTION_POINTS def __init__( - self, distribution_points: typing.Iterable["DistributionPoint"] + self, distribution_points: typing.Iterable[DistributionPoint] ) -> None: distribution_points = list(distribution_points) if not all( @@ -543,7 +544,7 @@ class FreshestCRL(ExtensionType): oid = ExtensionOID.FRESHEST_CRL def __init__( - self, distribution_points: typing.Iterable["DistributionPoint"] + self, distribution_points: typing.Iterable[DistributionPoint] ) -> None: distribution_points = list(distribution_points) if not all( @@ -581,7 +582,7 @@ def __init__( self, full_name: typing.Optional[typing.Iterable[GeneralName]], relative_name: typing.Optional[RelativeDistinguishedName], - reasons: typing.Optional[typing.FrozenSet["ReasonFlags"]], + reasons: typing.Optional[typing.FrozenSet[ReasonFlags]], crl_issuer: typing.Optional[typing.Iterable[GeneralName]], ) -> None: if full_name and relative_name: @@ -679,7 +680,7 @@ def relative_name(self) -> typing.Optional[RelativeDistinguishedName]: return self._relative_name @property - def reasons(self) -> typing.Optional[typing.FrozenSet["ReasonFlags"]]: + def reasons(self) -> typing.Optional[typing.FrozenSet[ReasonFlags]]: return self._reasons @property @@ -803,7 +804,7 @@ def public_bytes(self) -> bytes: class CertificatePolicies(ExtensionType): oid = ExtensionOID.CERTIFICATE_POLICIES - def __init__(self, policies: typing.Iterable["PolicyInformation"]) -> None: + def __init__(self, policies: typing.Iterable[PolicyInformation]) -> None: policies = list(policies) if not all(isinstance(x, PolicyInformation) for x in policies): raise TypeError( @@ -836,7 +837,7 @@ def __init__( self, policy_identifier: ObjectIdentifier, policy_qualifiers: typing.Optional[ - typing.Iterable[typing.Union[str, "UserNotice"]] + typing.Iterable[typing.Union[str, UserNotice]] ], ) -> None: if not isinstance(policy_identifier, ObjectIdentifier): @@ -874,7 +875,7 @@ def __eq__(self, other: object) -> bool: def __hash__(self) -> int: if self.policy_qualifiers is not None: pq: typing.Optional[ - typing.Tuple[typing.Union[str, "UserNotice"], ...] + typing.Tuple[typing.Union[str, UserNotice], ...] ] = tuple(self.policy_qualifiers) else: pq = None @@ -888,14 +889,14 @@ def policy_identifier(self) -> ObjectIdentifier: @property def policy_qualifiers( self, - ) -> typing.Optional[typing.List[typing.Union[str, "UserNotice"]]]: + ) -> typing.Optional[typing.List[typing.Union[str, UserNotice]]]: return self._policy_qualifiers class UserNotice: def __init__( self, - notice_reference: typing.Optional["NoticeReference"], + notice_reference: typing.Optional[NoticeReference], explicit_text: typing.Optional[str], ) -> None: if notice_reference and not isinstance( @@ -927,7 +928,7 @@ def __hash__(self) -> int: return hash((self.notice_reference, self.explicit_text)) @property - def notice_reference(self) -> typing.Optional["NoticeReference"]: + def notice_reference(self) -> typing.Optional[NoticeReference]: return self._notice_reference @property @@ -1046,7 +1047,7 @@ def public_bytes(self) -> bytes: class TLSFeature(ExtensionType): oid = ExtensionOID.TLS_FEATURE - def __init__(self, features: typing.Iterable["TLSFeatureType"]) -> None: + def __init__(self, features: typing.Iterable[TLSFeatureType]) -> None: features = list(features) if ( not all(isinstance(x, TLSFeatureType) for x in features) diff --git a/src/cryptography/x509/general_name.py b/src/cryptography/x509/general_name.py index ce8367b078d1..79271afbf91e 100644 --- a/src/cryptography/x509/general_name.py +++ b/src/cryptography/x509/general_name.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import ipaddress @@ -59,7 +60,7 @@ def value(self) -> str: return self._value @classmethod - def _init_without_validation(cls, value: str) -> "RFC822Name": + def _init_without_validation(cls, value: str) -> RFC822Name: instance = cls.__new__(cls) instance._value = value return instance @@ -98,7 +99,7 @@ def value(self) -> str: return self._value @classmethod - def _init_without_validation(cls, value: str) -> "DNSName": + def _init_without_validation(cls, value: str) -> DNSName: instance = cls.__new__(cls) instance._value = value return instance @@ -137,9 +138,7 @@ def value(self) -> str: return self._value @classmethod - def _init_without_validation( - cls, value: str - ) -> "UniformResourceIdentifier": + def _init_without_validation(cls, value: str) -> UniformResourceIdentifier: instance = cls.__new__(cls) instance._value = value return instance diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index fd0782026392..ff98e8724af1 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + import binascii import re import sys @@ -300,7 +302,7 @@ def from_rfc4514_string( cls, data: str, attr_name_overrides: typing.Optional[_NameOidMap] = None, - ) -> "Name": + ) -> Name: return _RFC4514NameParser(data, attr_name_overrides or {}).parse() def rfc4514_string( diff --git a/src/cryptography/x509/ocsp.py b/src/cryptography/x509/ocsp.py index 857e75afc191..7054795fcda8 100644 --- a/src/cryptography/x509/ocsp.py +++ b/src/cryptography/x509/ocsp.py @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations import abc import datetime @@ -423,7 +424,7 @@ def add_certificate( cert: x509.Certificate, issuer: x509.Certificate, algorithm: hashes.HashAlgorithm, - ) -> "OCSPRequestBuilder": + ) -> OCSPRequestBuilder: if self._request is not None or self._request_hash is not None: raise ValueError("Only one certificate can be added to a request") @@ -443,7 +444,7 @@ def add_certificate_by_hash( issuer_key_hash: bytes, serial_number: int, algorithm: hashes.HashAlgorithm, - ) -> "OCSPRequestBuilder": + ) -> OCSPRequestBuilder: if self._request is not None or self._request_hash is not None: raise ValueError("Only one certificate can be added to a request") @@ -469,7 +470,7 @@ def add_certificate_by_hash( def add_extension( self, extval: x509.ExtensionType, critical: bool - ) -> "OCSPRequestBuilder": + ) -> OCSPRequestBuilder: if not isinstance(extval, x509.ExtensionType): raise TypeError("extension must be an ExtensionType") @@ -512,7 +513,7 @@ def add_response( next_update: typing.Optional[datetime.datetime], revocation_time: typing.Optional[datetime.datetime], revocation_reason: typing.Optional[x509.ReasonFlags], - ) -> "OCSPResponseBuilder": + ) -> OCSPResponseBuilder: if self._response is not None: raise ValueError("Only one response per OCSPResponse.") @@ -535,7 +536,7 @@ def add_response( def responder_id( self, encoding: OCSPResponderEncoding, responder_cert: x509.Certificate - ) -> "OCSPResponseBuilder": + ) -> OCSPResponseBuilder: if self._responder_id is not None: raise ValueError("responder_id can only be set once") if not isinstance(responder_cert, x509.Certificate): @@ -554,7 +555,7 @@ def responder_id( def certificates( self, certs: typing.Iterable[x509.Certificate] - ) -> "OCSPResponseBuilder": + ) -> OCSPResponseBuilder: if self._certs is not None: raise ValueError("certificates may only be set once") certs = list(certs) @@ -571,7 +572,7 @@ def certificates( def add_extension( self, extval: x509.ExtensionType, critical: bool - ) -> "OCSPResponseBuilder": + ) -> OCSPResponseBuilder: if not isinstance(extval, x509.ExtensionType): raise TypeError("extension must be an ExtensionType") diff --git a/src/cryptography/x509/oid.py b/src/cryptography/x509/oid.py index 0d91a5469503..cda50cced5c4 100644 --- a/src/cryptography/x509/oid.py +++ b/src/cryptography/x509/oid.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations + from cryptography.hazmat._oid import ( AttributeOID, AuthorityInformationAccessOID, From 14d45c2259b01f1459eeab8bb7d85ce4cfb0841b Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 30 Mar 2023 15:30:32 -0700 Subject: [PATCH 555/827] do not use pip_install_editable (#8644) --- .github/downstream.d/certbot.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/downstream.d/certbot.sh b/.github/downstream.d/certbot.sh index 13508c87a0c8..561251d5b1d5 100755 --- a/.github/downstream.d/certbot.sh +++ b/.github/downstream.d/certbot.sh @@ -5,8 +5,8 @@ case "${1}" in git clone --depth=1 https://github.com/certbot/certbot cd certbot git rev-parse HEAD - tools/pip_install_editable.py ./acme[test] - tools/pip_install_editable.py ./certbot[test] + tools/pip_install.py -e ./acme[test] + tools/pip_install.py -e ./certbot[test] pip install -U pyopenssl ;; run) From 3622cb389709e632678bf80649fcf26833572da8 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:18:29 +0000 Subject: [PATCH 556/827] Bump BoringSSL and/or OpenSSL in CI (#8645) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8be80dc30c31..6d19bcec980c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 30, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "fca688f26b939db9c9981204373cecbd108b5d6c"}} - # Latest commit on the OpenSSL master branch, as of Mar 30, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "09cb8718fd65dc7126247808cb96b05147bb923f"}} + # Latest commit on the BoringSSL master branch, as of Mar 31, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "58472cc752c92554343d032ab34c683005f63e30"}} + # Latest commit on the OpenSSL master branch, as of Mar 31, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "bbe9d2de6c643a2c6758fae4274c307943a59624"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 35ef119e2fbc0263077bae319e22d2f12767efe9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 31 Mar 2023 02:13:40 -0400 Subject: [PATCH 557/827] Make the readme metadata static (#8639) --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7bdf2a5cfaa4..230f2fecda50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +readme = "README.rst" license = {text = "Apache-2.0 OR BSD-3-Clause"} classifiers = [ "Development Status :: 5 - Production/Stable", @@ -44,7 +45,7 @@ dependencies = [ # Must be kept in sync with `build-system.requires` "cffi >=1.12", ] -dynamic = ["version", "readme"] +dynamic = ["version"] [project.urls] homepage = "https://github.com/pyca/cryptography" @@ -66,7 +67,6 @@ exclude = [ [tool.setuptools.dynamic] version = {attr = "cryptography.__version__"} -readme = {file = "README.rst", content-type = "text/x-rst"} [project.optional-dependencies] ssh = ["bcrypt >=3.1.5"] From ab26f4fa9a09225bfa9db5a53de1081ecd8153eb Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 00:18:28 +0000 Subject: [PATCH 558/827] Bump BoringSSL and/or OpenSSL in CI (#8647) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d19bcec980c..995bb987db76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", TOXENV: "py311-randomorder"} - {VERSION: "3.12-dev", TOXENV: "py312"} - # Latest commit on the BoringSSL master branch, as of Mar 31, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "58472cc752c92554343d032ab34c683005f63e30"}} - # Latest commit on the OpenSSL master branch, as of Mar 31, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "bbe9d2de6c643a2c6758fae4274c307943a59624"}} + # Latest commit on the BoringSSL master branch, as of Apr 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "d89702704febab30774e8af22450899af297bfb0"}} + # Latest commit on the OpenSSL master branch, as of Apr 01, 2023. + - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9559ad0e8d433a2a212b63cc848fa2ac82a9b048"}} name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" timeout-minutes: 15 steps: From 4e6bfbb98f7f303d6e5171002834a578d7ba71a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:17:25 +0000 Subject: [PATCH 559/827] Bump openssl-macros from 0.1.0 to 0.1.1 in /src/rust (#8648) Bumps openssl-macros from 0.1.0 to 0.1.1. --- updated-dependencies: - dependency-name: openssl-macros dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 24a98758c1f4..de146f162f96 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -41,7 +41,7 @@ checksum = "bfab79c195875e5aef2bd20b4c8ed8d43ef9610bcffefbbcf66f88f555cc78af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -148,7 +148,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.109", ] [[package]] @@ -165,7 +165,7 @@ checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -307,13 +307,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.12", ] [[package]] @@ -349,7 +349,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -399,7 +399,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -469,7 +469,7 @@ dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -480,7 +480,7 @@ checksum = "8e0e1128f85ce3fca66e435e08aa2089a2689c1c48ce97803e13f63124058462" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -530,6 +530,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "target-lexicon" version = "0.12.6" @@ -596,7 +607,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] @@ -618,7 +629,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From b4a63a5c301b270c513dd799deec286999355853 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:24:24 +0000 Subject: [PATCH 560/827] Bump openssl-sys from 0.9.83 to 0.9.84 in /src/rust (#8649) Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.83 to 0.9.84. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.83...openssl-sys-v0.9.84) --- updated-dependencies: - dependency-name: openssl-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 5 ++--- src/rust/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index de146f162f96..00e50d8da71a 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -318,11 +318,10 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.83" +version = "0.9.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" +checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 5de812febf45..f922111b4301 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -15,7 +15,7 @@ pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" openssl = "0.10.48" -openssl-sys = "0.9.72" +openssl-sys = "0.9.84" foreign-types-shared = "0.1" [build-dependencies] From dd513528ecd81b98909ce9e237352dd276bce8a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:41:12 +0000 Subject: [PATCH 561/827] Bump openssl from 0.10.48 to 0.10.49 in /src/rust (#8650) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.48 to 0.10.49. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.48...openssl-v0.10.49) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 00e50d8da71a..955b8b01770a 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -292,9 +292,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.48" +version = "0.10.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" +checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" dependencies = [ "bitflags", "cfg-if", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index f922111b4301..5b5a671d497b 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,7 +14,7 @@ asn1 = { version = "0.13.0", default-features = false, features = ["const-generi pem = "1.1" chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" -openssl = "0.10.48" +openssl = "0.10.49" openssl-sys = "0.9.84" foreign-types-shared = "0.1" From 045287a86f223c912975eb909a3d0dcc5f07b385 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 1 Apr 2023 17:19:25 -0400 Subject: [PATCH 562/827] Update cargo packages that dependabot couldn't handle (#8646) --- src/rust/Cargo.lock | 83 +++++++-------------------------------------- 1 file changed, 13 insertions(+), 70 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 955b8b01770a..8abe5121f2a1 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -185,9 +185,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "iana-time-zone" -version = "0.1.55" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716f12fbcfac6ffab0a5e9ec51d0a0ff70503742bb2dc7b99396394c9dc323f0" +checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -672,11 +672,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.47.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2649ff315bee4c98757f15dac226efe3d81927adbb6e882084bb1ee3e0c330a7" +checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" dependencies = [ - "windows-targets 0.47.0", + "windows-targets", ] [[package]] @@ -685,7 +685,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets 0.42.2", + "windows-targets", ] [[package]] @@ -694,28 +694,13 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8996d3f43b4b2d44327cd71b7b0efd1284ab60e6e9d0e8b630e18555d87d3e" -dependencies = [ - "windows_aarch64_gnullvm 0.47.0", - "windows_aarch64_msvc 0.47.0", - "windows_i686_gnu 0.47.0", - "windows_i686_msvc 0.47.0", - "windows_x86_64_gnu 0.47.0", - "windows_x86_64_gnullvm 0.47.0", - "windows_x86_64_msvc 0.47.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -724,80 +709,38 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf" - [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3" - [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7" From 4a95379c5698b62aac8b1ec2bdbee6d4ba0602d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 21:36:57 +0000 Subject: [PATCH 563/827] Bump proc-macro2 from 1.0.54 to 1.0.55 in /src/rust (#8652) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.54 to 1.0.55. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.54...1.0.55) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 8abe5121f2a1..03939c106b2e 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -415,9 +415,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" dependencies = [ "unicode-ident", ] From 1e49cb9c13845ee973e74d1ffca6fe8ca47c0a35 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 2 Apr 2023 03:28:22 -0400 Subject: [PATCH 564/827] Switch from tox to nox (#8651) --- .github/actions/mtime-fix/action.yml | 2 +- .github/workflows/ci.yml | 192 ++++++++++++------------ MANIFEST.in | 2 +- ci-constraints-requirements.txt | 38 ++--- docs/development/getting-started.rst | 41 ++--- docs/development/submitting-patches.rst | 6 +- docs/spelling_wordlist.txt | 1 + noxfile.py | 147 ++++++++++++++++++ pyproject.toml | 8 +- tox.ini | 85 ----------- 10 files changed, 271 insertions(+), 251 deletions(-) create mode 100644 noxfile.py delete mode 100644 tox.ini diff --git a/.github/actions/mtime-fix/action.yml b/.github/actions/mtime-fix/action.yml index 4589aece1b8b..0690132db689 100644 --- a/.github/actions/mtime-fix/action.yml +++ b/.github/actions/mtime-fix/action.yml @@ -20,7 +20,7 @@ runs: exit 1 fi echo "Setting mtimes for dirs" - for f in $(git ls-files src/rust src/_cffi_src); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done + for f in $(git ls-tree -t -r --name-only HEAD src/rust src/_cffi_src); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done echo "Done" ls -Rla src/rust/src src/_cffi_src shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 995bb987db76..51c532929c57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,27 +26,26 @@ jobs: fail-fast: false matrix: PYTHON: - - {VERSION: "3.11", TOXENV: "flake"} - - {VERSION: "3.11", TOXENV: "rust"} - - {VERSION: "3.11", TOXENV: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - - {VERSION: "pypy-3.8", TOXENV: "pypy3-nocoverage"} - - {VERSION: "pypy-3.9", TOXENV: "pypy3-nocoverage"} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} - - {VERSION: "3.11", TOXENV: "py311-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - - {VERSION: "3.11", TOXENV: "py311", TOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - - {VERSION: "3.11", TOXENV: "py311-randomorder"} - - {VERSION: "3.12-dev", TOXENV: "py312"} + - {VERSION: "3.11", NOXSESSION: "flake"} + - {VERSION: "3.11", NOXSESSION: "rust"} + - {VERSION: "3.11", NOXSESSION: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} + - {VERSION: "pypy-3.8", NOXSESSION: "tests-nocoverage"} + - {VERSION: "pypy-3.9", NOXSESSION: "tests-nocoverage"} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} + - {VERSION: "3.11", NOXSESSION: "tests-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} + - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} + - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} + - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "boringssl", VERSION: "d89702704febab30774e8af22450899af297bfb0"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d89702704febab30774e8af22450899af297bfb0"}} # Latest commit on the OpenSSL master branch, as of Apr 01, 2023. - - {VERSION: "3.11", TOXENV: "py311", OPENSSL: {TYPE: "openssl", VERSION: "9559ad0e8d433a2a212b63cc848fa2ac82a9b048"}} - name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.TOXARGS }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}" + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "9559ad0e8d433a2a212b63cc848fa2ac82a9b048"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 @@ -61,24 +60,18 @@ jobs: uses: actions/setup-python@v4.5.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - - name: Cache rust and pip - uses: ./.github/actions/cache - timeout-minutes: 2 - with: - key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - name: Compute config hash and set config vars run: | DEFAULT_CONFIG_FLAGS="shared no-ssl2 no-ssl3" CONFIG_FLAGS="$DEFAULT_CONFIG_FLAGS $CONFIG_FLAGS" - CONFIG_HASH=$(echo "$CONFIG_FLAGS" | sha1sum | sed 's/ .*$//') + OPENSSL_HASH=$(echo "${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-$CONFIG_FLAGS" | sha1sum | sed 's/ .*$//') echo "CONFIG_FLAGS=${CONFIG_FLAGS}" >> $GITHUB_ENV - echo "CONFIG_HASH=${CONFIG_HASH}" >> $GITHUB_ENV + echo "OPENSSL_HASH=${OPENSSL_HASH}" >> $GITHUB_ENV echo "OSSL_INFO=${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${CONFIG_FLAGS}" >> $GITHUB_ENV - echo "OSSL_PATH=${{ github.workspace }}/osslcache/${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${CONFIG_HASH}" >> $GITHUB_ENV + echo "OSSL_PATH=${{ github.workspace }}/osslcache/${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${OPENSSL_HASH}" >> $GITHUB_ENV env: CONFIG_FLAGS: ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }} if: matrix.PYTHON.OPENSSL @@ -90,7 +83,7 @@ jobs: path: ${{ github.workspace }}/osslcache # When altering the openssl build process you may need to increment the value on the end of this cache key # so that you can prevent it from fetching the cache and skipping the build step. - key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.CONFIG_HASH }}-8 + key: ${{ matrix.PYTHON.OPENSSL.TYPE }}-${{ matrix.PYTHON.OPENSSL.VERSION }}-${{ env.OPENSSL_HASH }}-8 if: matrix.PYTHON.OPENSSL - name: Build custom OpenSSL/LibreSSL run: .github/workflows/build_openssl.sh @@ -104,17 +97,27 @@ jobs: echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration" >> $GITHUB_ENV echo "RUSTFLAGS=-Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib -Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV if: matrix.PYTHON.OPENSSL - - name: Build toxenv + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 + with: + # We have both the Python version from the matrix and from the + # setup-python step because the latter doesn't distinguish + # pypy3-3.8 and pypy3-3.9 -- both of them show up as 7.3.11. + key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-${{ matrix.PYTHON.NOXSESSION }}-${{ env.OPENSSL_HASH }} + + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] + - name: Create nox environment run: | - tox -vvv --notest + nox -v --install-only env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests run: | - tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof ${{ matrix.PYTHON.TOXARGS }} + nox --no-install -- --color=yes --wycheproof-root=wycheproof ${{ matrix.PYTHON.NOXARGS }} env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} COLUMNS: 80 CRYPTOGRAPHY_OPENSSL_NO_LEGACY: ${{ matrix.PYTHON.OPENSSL.NO_LEGACY }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} @@ -128,22 +131,22 @@ jobs: fail-fast: false matrix: IMAGE: - - {IMAGE: "rhel8", TOXENV: "py38", RUNNER: "ubuntu-latest"} - - {IMAGE: "rhel8-fips", TOXENV: "py38", RUNNER: "ubuntu-latest", FIPS: true} - - {IMAGE: "buster", TOXENV: "py37", RUNNER: "ubuntu-latest"} - - {IMAGE: "bullseye", TOXENV: "py39", RUNNER: "ubuntu-latest"} - - {IMAGE: "bookworm", TOXENV: "py311", RUNNER: "ubuntu-latest"} - - {IMAGE: "sid", TOXENV: "py311", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-focal", TOXENV: "py38", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-jammy", TOXENV: "py310", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-rolling", TOXENV: "py310", RUNNER: "ubuntu-latest"} - - {IMAGE: "fedora", TOXENV: "py311", RUNNER: "ubuntu-latest"} - - {IMAGE: "alpine", TOXENV: "py310", RUNNER: "ubuntu-latest"} - - {IMAGE: "centos-stream9", TOXENV: "py39", RUNNER: "ubuntu-latest"} - - {IMAGE: "centos-stream9-fips", TOXENV: "py39", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "rhel8", RUNNER: "ubuntu-latest"} + - {IMAGE: "rhel8-fips", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "buster", RUNNER: "ubuntu-latest"} + - {IMAGE: "bullseye", RUNNER: "ubuntu-latest"} + - {IMAGE: "bookworm", RUNNER: "ubuntu-latest"} + - {IMAGE: "sid", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-focal", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-jammy", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-rolling", RUNNER: "ubuntu-latest"} + - {IMAGE: "fedora", RUNNER: "ubuntu-latest"} + - {IMAGE: "alpine", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9-fips", RUNNER: "ubuntu-latest", FIPS: true} - - {IMAGE: "ubuntu-jammy:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} - - {IMAGE: "alpine:aarch64", TOXENV: "py310", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "ubuntu-jammy:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "alpine:aarch64", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 steps: - name: Ridiculous alpine workaround for actions support on arm64 @@ -180,17 +183,15 @@ jobs: - run: | echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage - - run: '/venv/bin/tox -vvv --notest' + - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' coverage + - run: '/venv/bin/nox -v --install-only -s tests' env: - TOXENV: ${{ matrix.IMAGE.TOXENV }} RUSTUP_HOME: /root/.rustup CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 - - run: '/venv/bin/tox --skip-pkg-install -- --color=yes --wycheproof-root="wycheproof"' + - run: '/venv/bin/nox --no-install -s tests -- --color=yes --wycheproof-root="wycheproof"' env: - TOXENV: ${{ matrix.IMAGE.TOXENV }} COLUMNS: 80 # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 @@ -202,11 +203,11 @@ jobs: fail-fast: false matrix: PYTHON: - - {VERSION: "3.11", TOXENV: "py311"} + - "3.11" RUST: # Cover MSRV. 1.60+ and beta/nightly are in the linux-rust-coverage section. - 1.56.0 - name: "${{ matrix.PYTHON.TOXENV }} with Rust ${{ matrix.RUST }}" + name: "${{ matrix.PYTHON }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 @@ -224,23 +225,21 @@ jobs: - name: Setup python uses: actions/setup-python@v4.5.0 with: - python-version: ${{ matrix.PYTHON.VERSION }} + python-version: ${{ matrix.PYTHON }} - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff with: toolchain: ${{ matrix.RUST }} - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] - - name: Create toxenv - run: tox -vvv --notest + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] + - name: Create nox environment + run: nox -v --install-only -s tests env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof + run: nox --no-install -s tests -- --color=yes --wycheproof-root=wycheproof env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} COLUMNS: 80 - uses: ./.github/actions/upload-coverage @@ -250,7 +249,7 @@ jobs: fail-fast: false matrix: PYTHON: - - {VERSION: "3.11", TOXENV: "py311"} + - "3.11" RUST: # Potential future MSRVs: # 1.60 - new version of cxx @@ -302,25 +301,23 @@ jobs: - name: Setup python uses: actions/setup-python@v4.5.0 with: - python-version: ${{ matrix.PYTHON.VERSION }} + python-version: ${{ matrix.PYTHON }} - run: cargo install cargo-binutils if: steps.cargo-cache.outputs.cache-hit != 'true' - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] cffi - - name: Create toxenv - run: tox -vvv --notest + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] cffi + - name: Create nox environment + run: nox -v --install-only -s tests env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} RUSTFLAGS: "-Cinstrument-coverage" LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - name: Tests - run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof + run: nox --no-install -s tests -- --color=yes --wycheproof-root=wycheproof env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} RUSTFLAGS: "-Cinstrument-coverage" @@ -341,7 +338,7 @@ jobs: COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") cargo cov -- export \ - ../../.tox/${{ matrix.PYTHON.TOXENV }}/lib/python${{ matrix.PYTHON.VERSION }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ + ../../.nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ -instr-profile=pytest-rust-cov.profdata \ --ignore-filename-regex='/.cargo/registry' \ --ignore-filename-regex='/rustc/' \ @@ -365,13 +362,12 @@ jobs: - {OS: 'macos-12', ARCH: 'x86_64'} - {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} PYTHON: - - {VERSION: "3.7", TOXENV: "py37-nocoverage"} - - {VERSION: "3.11", TOXENV: "py311"} + - {VERSION: "3.7", NOXSESSION: "tests-nocoverage"} + - {VERSION: "3.11", NOXSESSION: "tests"} exclude: # We only test latest Python on arm64. py37 won't work since there's no universal2 binary - - PYTHON: {VERSION: "3.7", TOXENV: "py37-nocoverage"} + - PYTHON: {VERSION: "3.7", NOXSESSION: "tests-nocoverage"} RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} - name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}" timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 @@ -385,7 +381,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.PYTHON.VERSION }} + key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.PYTHON.VERSION }} - name: Setup python uses: actions/setup-python@v4.5.0 @@ -393,7 +389,7 @@ jobs: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 - - run: python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] - name: Clone wycheproof timeout-minutes: 2 @@ -408,19 +404,19 @@ jobs: name: openssl-macos-universal2 path: "../openssl-macos-universal2/" github_token: ${{ secrets.GITHUB_TOKEN }} - - name: Build toxenv + - name: Build nox environment run: | OPENSSL_DIR=$(readlink -f ../openssl-macos-universal2/) \ OPENSSL_STATIC=1 \ CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12" \ - tox -vvv --notest + nox -v --install-only env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof + run: nox --no-install -- --color=yes --wycheproof-root=wycheproof env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} COLUMNS: 80 - uses: ./.github/actions/upload-coverage @@ -434,10 +430,9 @@ jobs: - {ARCH: 'x86', WINDOWS: 'win32'} - {ARCH: 'x64', WINDOWS: 'win64'} PYTHON: - - {VERSION: "3.7", TOXENV: "py37-nocoverage"} - - {VERSION: "3.11", TOXENV: "py311"} + - {VERSION: "3.7", NOXSESSION: "tests-nocoverage"} + - {VERSION: "3.11", NOXSESSION: "tests"} JOB_NUMBER: [0, 1] - name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})" timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 @@ -457,8 +452,8 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - - run: python -m pip install -c ci-constraints-requirements.txt "tox>3" coverage[toml] + key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} + - run: python -m pip install -c ci-constraints-requirements.txt "nox" coverage[toml] - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 with: @@ -478,15 +473,15 @@ jobs: timeout-minutes: 2 uses: ./.github/actions/wycheproof - - name: Build toxenv - run: tox -vvv --notest + - name: Build nox environment + run: nox -v --install-only env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof --num-shards=2 --shard-id=${{ matrix.JOB_NUMBER }} + run: nox --no-install -- --color=yes --wycheproof-root=wycheproof --num-shards=2 --shard-id=${{ matrix.JOB_NUMBER }} env: - TOXENV: ${{ matrix.PYTHON.TOXENV }} + NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} @@ -574,17 +569,14 @@ jobs: # This creates the same key as the docs job (as long as they have the same # python version) key: 3.11-${{ steps.setup-python.outputs.python-version }} - - run: python -m pip install -c ci-constraints-requirements.txt tox - - name: Build toxenv + - run: python -m pip install -c ci-constraints-requirements.txt nox + - name: Build nox environment run: | - tox -vvv --notest + nox -v --install-only -s docs-linkcheck env: - TOXENV: docs-linkcheck CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: linkcheck - run: tox --skip-pkg-install -- --color=yes - env: - TOXENV: docs-linkcheck + run: nox --no-install -s docs-linkcheck -- --color=yes all-green: # https://github.community/t/is-it-possible-to-require-all-github-actions-tasks-to-pass-without-enumerating-them/117957/4?u=graingert diff --git a/MANIFEST.in b/MANIFEST.in index 2417dd9d3088..dcffd6024d1c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,7 +4,7 @@ include LICENSE include LICENSE.APACHE include LICENSE.BSD include README.rst -include tox.ini +include noxfile.py include pyproject.toml recursive-include src py.typed *.pyi diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 11f850c7efbc..20bf7a5cedce 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -1,12 +1,14 @@ # 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=tox --resolver=backtracking --strip-extras --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools pyproject.toml +# pip-compile --extra=docs --extra=docstest --extra=pep8test --extra=test --extra=test-randomorder --extra=nox --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==0.7.13 # via sphinx +argcomplete==2.1.2 + # via nox attrs==22.2.0 # via # pytest @@ -18,20 +20,16 @@ bleach==6.0.0 # via readme-renderer build==0.10.0 # via check-manifest -cachetools==5.3.0 - # via tox certifi==2022.12.7 # via requests -chardet==5.1.0 - # via tox charset-normalizer==3.1.0 # via requests check-manifest==0.49 # via cryptography (pyproject.toml) click==8.1.3 # via black -colorama==0.4.6 - # via tox +colorlog==6.7.0 + # via nox coverage==7.2.2 # via pytest-cov distlib==0.3.6 @@ -46,17 +44,11 @@ exceptiongroup==1.1.1 execnet==1.9.0 # via pytest-xdist filelock==3.10.7 - # via - # tox - # virtualenv + # via virtualenv idna==3.4 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==6.1.0 - # via - # keyring - # twine iniconfig==2.0.0 # via pytest jaraco-classes==3.2.3 @@ -79,14 +71,15 @@ mypy-extensions==1.0.0 # via # black # mypy +nox==2022.11.21 + # via cryptography (pyproject.toml) packaging==23.0 # via # black # build - # pyproject-api + # nox # pytest # sphinx - # tox pathspec==0.11.1 # via black pkginfo==1.9.6 @@ -94,12 +87,9 @@ pkginfo==1.9.6 platformdirs==3.2.0 # via # black - # tox # virtualenv pluggy==1.0.0 - # via - # pytest - # tox + # via pytest pretend==1.0.9 # via cryptography (pyproject.toml) py-cpuinfo==9.0.0 @@ -113,8 +103,6 @@ pygments==2.14.0 # readme-renderer # rich # sphinx -pyproject-api==1.5.1 - # via tox pyproject-hooks==1.0.0 # via build pytest==7.2.2 @@ -185,12 +173,8 @@ tomli==2.0.1 # check-manifest # coverage # mypy - # pyproject-api # pyproject-hooks # pytest - # tox -tox==4.4.8 - # via cryptography (pyproject.toml) twine==4.0.2 # via cryptography (pyproject.toml) typing-extensions==4.5.0 @@ -200,7 +184,7 @@ urllib3==1.26.15 # requests # twine virtualenv==20.21.0 - # via tox + # via nox webencodings==0.5.1 # via bleach zipp==3.15.0 diff --git a/docs/development/getting-started.rst b/docs/development/getting-started.rst index 00638aa576d1..782c731102a0 100644 --- a/docs/development/getting-started.rst +++ b/docs/development/getting-started.rst @@ -6,22 +6,22 @@ Development dependencies Working on ``cryptography`` requires the installation of a small number of development dependencies in addition to the dependencies for -:doc:`/installation`. These are handled by the use of ``tox``, which can be +:doc:`/installation`. These are handled by the use of ``nox``, which can be installed with ``pip``. .. code-block:: console $ # Create a virtualenv and activate it $ # Set up your cryptography build environment - $ pip install tox + $ pip install nox $ # Specify your Python version here. - $ tox -e py310 + $ nox -e tests -p py310 OpenSSL on macOS ~~~~~~~~~~~~~~~~ You must have installed `OpenSSL`_ via `Homebrew`_ or `MacPorts`_ and must set -``CFLAGS`` and ``LDFLAGS`` environment variables before running ``tox`` +``CFLAGS`` and ``LDFLAGS`` environment variables before running ``nox`` otherwise pip will fail with include errors. For example, with `Homebrew`_: @@ -30,7 +30,7 @@ For example, with `Homebrew`_: $ env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" \ CFLAGS="-I$(brew --prefix openssl@1.1)/include" \ - tox -e py310 + nox -e tests -p py310 Alternatively for a static build you can specify ``CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1`` and ensure ``LDFLAGS`` points to the @@ -43,32 +43,14 @@ Running tests ------------- ``cryptography`` unit tests are found in the ``tests/`` directory and are -designed to be run using `pytest`_. ``tox`` automatically invokes ``pytest``: +designed to be run using `pytest`_. ``nox`` automatically invokes ``pytest``: .. code-block:: console - $ tox -e py310 + $ nox -e tests -p py310 ... 62746 passed in 220.43 seconds -You can also verify that the tests pass on other supported Python interpreters -with ``tox``. For example: - -.. code-block:: console - - $ tox - ... - ERROR: pypy: InterpreterNotFound: pypy - py38: commands succeeded - py39: commands succeeded - py310: commands succeeded - py311: commands succeeded - docs: commands succeeded - pep8: commands succeeded - -You may not have all the required Python versions installed, in which case you -will see one or more ``InterpreterNotFound`` errors. - Building documentation ---------------------- @@ -76,14 +58,13 @@ Building documentation ``cryptography`` documentation is stored in the ``docs/`` directory. It is written in `reStructured Text`_ and rendered using `Sphinx`_. -Use `tox`_ to build the documentation. For example: +Use `nox`_ to build the documentation. For example: .. code-block:: console - $ tox -e docs + $ nox -e docs ... - docs: commands succeeded - congratulations :) + nox > Session docs was successful. The HTML documentation index can now be found at ``docs/_build/html/index.html``. @@ -92,7 +73,7 @@ The HTML documentation index can now be found at .. _`MacPorts`: https://www.macports.org .. _`OpenSSL`: https://www.openssl.org .. _`pytest`: https://pypi.org/project/pytest/ -.. _`tox`: https://pypi.org/project/tox/ +.. _`nox`: https://pypi.org/project/nox/ .. _`virtualenv`: https://pypi.org/project/virtualenv/ .. _`pip`: https://pypi.org/project/pip/ .. _`sphinx`: https://pypi.org/project/Sphinx/ diff --git a/docs/development/submitting-patches.rst b/docs/development/submitting-patches.rst index 4deaafe09e0f..6148419ce134 100644 --- a/docs/development/submitting-patches.rst +++ b/docs/development/submitting-patches.rst @@ -21,8 +21,8 @@ Code When in doubt, refer to :pep:`8` for Python code. You can check if your code meets our automated requirements by formatting it with ``black`` and running ``ruff`` against it. If you've installed the development requirements this -will automatically use our configuration. You can also run the ``tox`` job with -``tox -e flake``. +will automatically use our configuration. You can also run the ``nox`` job with +``nox -e flake``. `Write comments as complete sentences.`_ @@ -95,7 +95,7 @@ Documentation ------------- All features should be documented with prose in the ``docs`` section. To ensure -it builds you can run ``tox -e docs``. +it builds you can run ``nox -e docs``. Because of the inherent challenges in implementing correct cryptographic systems, we want to make our documentation point people in the right directions diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index ea485aaef77a..d581d3d4c490 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -129,6 +129,7 @@ unencrypted unicode unpadded unpadding +Ventura verifier Verifier Verisign diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 000000000000..8f2a38ab9176 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,147 @@ +# 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. + +from __future__ import annotations + +import nox + +nox.options.reuse_existing_virtualenvs = True + + +def install(session: nox.Session, *args: str) -> None: + session.install( + "-v", + "-c", + "ci-constraints-requirements.txt", + *args, + ) + + +@nox.session +@nox.session(name="tests-ssh") +@nox.session(name="tests-randomorder") +@nox.session(name="tests-nocoverage") +def tests(session: nox.Session) -> None: + extras = "test" + if session.name == "tests-ssh": + extras += ",ssh" + if session.name == "tests-randomorder": + extras += ",test-randomorder" + + install(session, f".[{extras}]") + install(session, "-e", "./vectors") + + session.run("pip", "list") + + if session.name != "tests-nocoverage": + session.run( + "pytest", + "-n", + "auto", + "--dist=worksteal", + "--cov=cryptography", + "--cov=tests", + "--durations=10", + *session.posargs, + "tests/", + ) + else: + session.run( + "pytest", + "-n", + "auto", + "--dist=worksteal", + "--durations=10", + *session.posargs, + "tests/", + ) + + +@nox.session +def docs(session: nox.Session) -> None: + install(session, ".[docs,docstest,sdist,ssh]") + + temp_dir = session.create_tmp() + session.run( + "sphinx-build", + "-T", + "-W", + "-b", + "html", + "-d", + f"{temp_dir}/doctrees", + "docs", + "docs/_build/html", + ) + session.run( + "sphinx-build", + "-T", + "-W", + "-b", + "latex", + "-d", + f"{temp_dir}/doctrees", + "docs", + "docs/_build/latex", + ) + + session.run( + "sphinx-build", + "-T", + "-W", + "-b", + "doctest", + "-d", + f"{temp_dir}/doctrees", + "docs", + "docs/_build/html", + ) + session.run( + "sphinx-build", + "-T", + "-W", + "-b", + "spelling", + "docs", + "docs/_build/html", + ) + + session.run("python", "setup.py", "sdist") + session.run("twine", "check", "dist/*") + + +@nox.session(name="docs-linkcheck") +def docs_linkcheck(session: nox.Session) -> None: + install(session, ".[docs]") + + session.run( + "sphinx-build", "-W", "-b", "linkcheck", "docs", "docs/_build/html" + ) + + +@nox.session +def flake(session: nox.Session) -> None: + install(session, ".[pep8test,test,ssh,nox]") + + session.run("ruff", ".") + session.run("black", "--check", ".") + session.run("check-manifest") + session.run( + "mypy", + "src/cryptography/", + "vectors/cryptography_vectors/", + "tests/", + "release.py", + "noxfile.py", + ) + + +@nox.session +def rust(session: nox.Session) -> None: + install(session, ".") + + with session.chdir("src/rust/"): + session.run("cargo", "fmt", "--all", "--", "--check") + session.run("cargo", "clippy", "--", "-D", "warnings") + session.run("cargo", "test", "--no-default-features") diff --git a/pyproject.toml b/pyproject.toml index 230f2fecda50..480b4fbbeb3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ version = {attr = "cryptography.__version__"} ssh = ["bcrypt >=3.1.5"] # All the following are used for our own testing. -tox = ["tox"] +nox = ["nox"] test = [ "pytest >=6.2.0", "pytest-shard >=0.1.2", @@ -125,9 +125,9 @@ source = [ [tool.coverage.paths] source = [ "src/cryptography", - "*.tox/*/lib*/python*/site-packages/cryptography", - "*.tox\\*\\Lib\\site-packages\\cryptography", - "*.tox/pypy/site-packages/cryptography", + "*.nox/*/lib*/python*/site-packages/cryptography", + "*.nox\\*\\Lib\\site-packages\\cryptography", + "*.nox/pypy/site-packages/cryptography", ] tests =[ "tests/", diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 0a8806afce09..000000000000 --- a/tox.ini +++ /dev/null @@ -1,85 +0,0 @@ -[tox] -minversion = 2.4 -isolated_build = True - -[testenv] -# This is the default install_command but with -v added -install_command = python -I -m pip install -v {opts} {packages} -extras = - test - ssh: ssh - randomorder: test-randomorder -deps = - -e ./vectors -passenv = - ARCHFLAGS - LDFLAGS - CFLAGS - CL - COLUMNS - INCLUDE - LIB - LD_LIBRARY_PATH - RUSTFLAGS - RUSTUP_HOME - CARGO_TARGET_DIR - CARGO_REGISTRIES_CRATES_IO_PROTOCOL - LLVM_PROFILE_FILE - OPENSSL_FORCE_FIPS_MODE - RUSTUP_TOOLCHAIN - CRYPTOGRAPHY_OPENSSL_NO_LEGACY - OPENSSL_ENABLE_SHA1_SIGNATURES - CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS - OPENSSL_DIR -setenv = - PIP_CONSTRAINT=ci-constraints-requirements.txt -commands = - pip list - !nocoverage: pytest -n auto --dist=worksteal --cov=cryptography --cov=tests --durations=10 {posargs} tests/ - nocoverage: pytest -n auto --dist=worksteal --durations=10 {posargs} tests/ - -[testenv:docs] -extras = - docs - docstest - sdist - ssh -basepython = python3 -commands = - sphinx-build -T -W -b html -d {envtmpdir}/doctrees docs docs/_build/html - sphinx-build -T -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex - sphinx-build -T -W -b doctest -d {envtmpdir}/doctrees docs docs/_build/html - sphinx-build -T -W -b spelling docs docs/_build/html - python setup.py sdist - twine check dist/* - -[testenv:docs-linkcheck] -extras = - docs -basepython = python3 -commands = - sphinx-build -W -b linkcheck docs docs/_build/html - -[testenv:flake] -basepython = python3 -extras = - pep8test - test - ssh -commands = - ruff . - black --check . - check-manifest - mypy src/cryptography/ vectors/cryptography_vectors/ tests/ release.py - -[testenv:rust] -basepython = python3 -extras = -deps = -changedir = src/rust/ -allowlist_externals = - cargo -commands = - cargo fmt --all -- --check - cargo clippy -- -D warnings - cargo test --no-default-features From 5fef27733c6cf52d54626ca775c2899c31a3f65b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 2 Apr 2023 22:01:31 +0900 Subject: [PATCH 565/827] update docs for macOS dev with rust openssl (#8653) --- docs/development/getting-started.rst | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/docs/development/getting-started.rst b/docs/development/getting-started.rst index 782c731102a0..a4283469b5cc 100644 --- a/docs/development/getting-started.rst +++ b/docs/development/getting-started.rst @@ -20,24 +20,9 @@ installed with ``pip``. OpenSSL on macOS ~~~~~~~~~~~~~~~~ -You must have installed `OpenSSL`_ via `Homebrew`_ or `MacPorts`_ and must set -``CFLAGS`` and ``LDFLAGS`` environment variables before running ``nox`` -otherwise pip will fail with include errors. - -For example, with `Homebrew`_: - -.. code-block:: console - - $ env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" \ - CFLAGS="-I$(brew --prefix openssl@1.1)/include" \ - nox -e tests -p py310 - -Alternatively for a static build you can specify -``CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1`` and ensure ``LDFLAGS`` points to the -absolute path for the `OpenSSL`_ libraries before calling pip. - -.. tip:: - You will also need to set these values when `Building documentation`_. +You must have installed `OpenSSL`_ (via `Homebrew`_ , `MacPorts`_, or a custom +build) and must configure the build `as documented here`_ before calling +``nox`` or else pip will fail to compile. Running tests ------------- @@ -78,3 +63,4 @@ The HTML documentation index can now be found at .. _`pip`: https://pypi.org/project/pip/ .. _`sphinx`: https://pypi.org/project/Sphinx/ .. _`reStructured Text`: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html +.. _`as documented here`: https://docs.rs/openssl/latest/openssl/#automatic \ No newline at end of file From b3782ca0334a9300a18736814e7910dfa43b6628 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 2 Apr 2023 22:03:45 +0900 Subject: [PATCH 566/827] remove cffi helper funcs and args that are no longer needed (#8654) --- src/_cffi_src/build_openssl.py | 65 +--------------------------------- src/_cffi_src/utils.py | 23 ------------ 2 files changed, 1 insertion(+), 87 deletions(-) diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index 42754fb6417b..3ff1332e2772 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -8,73 +8,12 @@ import pathlib import platform import sys -from distutils import dist -from distutils.ccompiler import get_default_compiler -from distutils.command.config import config # Add the src directory to the path so we can import _cffi_src.utils src_dir = str(pathlib.Path(__file__).parent.parent) sys.path.insert(0, src_dir) -from _cffi_src.utils import build_ffi_for_binding, compiler_type # noqa: E402 - - -def _get_openssl_libraries(platform): - if os.environ.get("CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS", None): - return [] - # OpenSSL goes by a different library name on different operating systems. - if platform == "win32" and compiler_type() == "msvc": - return [ - "libssl", - "libcrypto", - "advapi32", - "crypt32", - "gdi32", - "user32", - "ws2_32", - ] - else: - # darwin, linux, mingw all use this path - # In some circumstances, the order in which these libs are - # specified on the linker command-line is significant; - # libssl must come before libcrypto - # (https://marc.info/?l=openssl-users&m=135361825921871) - # -lpthread required due to usage of pthread an potential - # existence of a static part containing e.g. pthread_atfork - # (https://github.com/pyca/cryptography/issues/5084) - if sys.platform == "zos": - return ["ssl", "crypto"] - else: - return ["ssl", "crypto", "pthread"] - - -def _extra_compile_args(platform): - """ - We set -Wconversion args here so that we only do Wconversion checks on the - code we're compiling and not on cffi itself (as passing -Wconversion in - CFLAGS would do). We set no error on sign conversion because some - function signatures in LibreSSL differ from OpenSSL have changed on long - vs. unsigned long in the past. Since that isn't a precision issue we don't - care. - """ - # make sure the compiler used supports the flags to be added - is_gcc = False - if get_default_compiler() == "unix": - d = dist.Distribution() - cmd = config(d) - cmd._check_compiler() - is_gcc = ( - "gcc" in cmd.compiler.compiler[0] - or "clang" in cmd.compiler.compiler[0] - ) - if is_gcc or not ( - platform in ["win32", "hp-ux11", "sunos5"] - or platform.startswith("aix") - ): - return ["-Wconversion", "-Wno-error=sign-conversion"] - else: - return [] - +from _cffi_src.utils import build_ffi_for_binding # noqa: E402 ffi = build_ffi_for_binding( module_name="_openssl", @@ -113,8 +52,6 @@ def _extra_compile_args(platform): "pkcs7", "callbacks", ], - libraries=_get_openssl_libraries(sys.platform), - extra_compile_args=_extra_compile_args(sys.platform), ) if __name__ == "__main__": diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index cc2a2fb5f050..9eb782686eae 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -7,8 +7,6 @@ import os import platform import sys -from distutils.ccompiler import new_compiler -from distutils.dist import Distribution from cffi import FFI @@ -23,8 +21,6 @@ def build_ffi_for_binding( module_name, module_prefix, modules, - libraries, - extra_compile_args, ): """ Modules listed in ``modules`` should have the following attributes: @@ -54,8 +50,6 @@ def build_ffi_for_binding( module_name, cdef_source="\n".join(types + functions), verify_source=verify_source, - libraries=libraries, - extra_compile_args=extra_compile_args, ) @@ -63,8 +57,6 @@ def build_ffi( module_name, cdef_source, verify_source, - libraries, - extra_compile_args, ): ffi = FFI() # Always add the CRYPTOGRAPHY_PACKAGE_VERSION to the shared object @@ -88,20 +80,5 @@ def build_ffi( ffi.set_source( module_name, verify_source, - libraries=libraries, - extra_compile_args=extra_compile_args, ) return ffi - - -def compiler_type(): - """ - Gets the compiler type from distutils. On Windows with MSVC it will be - "msvc". On macOS and linux it is "unix". - """ - dist = Distribution() - dist.parse_config_files() - cmd = dist.get_command_obj("build") - cmd.ensure_finalized() - compiler = new_compiler(compiler=cmd.compiler) - return compiler.compiler_type From 963add367b4e3de70d80916c83335551b5c2830b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 2 Apr 2023 17:17:37 -0400 Subject: [PATCH 567/827] Several improvements to our noxfile (#8655) 1. Stream the output of pip install, don't blit it all out at the end 2. Reduce duplication in test job 3. Add an explanatory comment to the docs job --- noxfile.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/noxfile.py b/noxfile.py index 8f2a38ab9176..62634b03fe43 100644 --- a/noxfile.py +++ b/noxfile.py @@ -15,6 +15,7 @@ def install(session: nox.Session, *args: str) -> None: "-c", "ci-constraints-requirements.txt", *args, + silent=False, ) @@ -35,27 +36,23 @@ def tests(session: nox.Session) -> None: session.run("pip", "list") if session.name != "tests-nocoverage": - session.run( - "pytest", - "-n", - "auto", - "--dist=worksteal", + cov_args = [ "--cov=cryptography", "--cov=tests", - "--durations=10", - *session.posargs, - "tests/", - ) + ] else: - session.run( - "pytest", - "-n", - "auto", - "--dist=worksteal", - "--durations=10", - *session.posargs, - "tests/", - ) + cov_args = [] + + session.run( + "pytest", + "-n", + "auto", + "--dist=worksteal", + *cov_args, + "--durations=10", + *session.posargs, + "tests/", + ) @nox.session @@ -107,6 +104,8 @@ def docs(session: nox.Session) -> None: "docs/_build/html", ) + # This is in the docs job because `twine check` verifies that the README + # is valid reStructuredText. session.run("python", "setup.py", "sdist") session.run("twine", "check", "dist/*") From 5a0ca4e25d177926a9ec94562a9e6a3d937f78aa Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 2 Apr 2023 17:19:38 -0400 Subject: [PATCH 568/827] Drop usage of clock feature of chrono (#8657) It adds a zillion dependencies, we can just let python get the current time --- .github/workflows/ci.yml | 1 - src/rust/Cargo.lock | 243 --------------------------------- src/rust/Cargo.toml | 2 +- src/rust/src/pkcs7.rs | 6 +- src/rust/src/x509/common.rs | 9 ++ src/rust/src/x509/ocsp_resp.rs | 5 +- 6 files changed, 13 insertions(+), 253 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51c532929c57..1ac9b63b9c50 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -252,7 +252,6 @@ jobs: - "3.11" RUST: # Potential future MSRVs: - # 1.60 - new version of cxx - 1.60.0 # 1.67 - new version of pem - beta diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 03939c106b2e..df2b1abaf649 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -14,15 +14,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "asn1" version = "0.13.0" @@ -62,12 +53,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bumpalo" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" - [[package]] name = "cc" version = "1.0.79" @@ -86,28 +71,10 @@ version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "iana-time-zone", "num-integer", "num-traits", - "winapi", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - [[package]] name = "cryptography-rust" version = "0.1.0" @@ -124,50 +91,6 @@ dependencies = [ "pyo3", ] -[[package]] -name = "cxx" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 1.0.109", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -183,60 +106,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "iana-time-zone" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" -dependencies = [ - "cxx", - "cxx-build", -] - [[package]] name = "indoc" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" -[[package]] -name = "js-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "libc" version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] - [[package]] name = "lock_api" version = "0.4.9" @@ -247,15 +128,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -506,12 +378,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "smallvec" version = "1.10.0" @@ -546,27 +412,12 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "unicode-ident" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "unindent" version = "0.1.11" @@ -585,100 +436,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasm-bindgen" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 5b5a671d497b..e7f0e1baddd6 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -12,7 +12,7 @@ once_cell = "1" pyo3 = { version = "0.18" } asn1 = { version = "0.13.0", default-features = false, features = ["const-generics"] } pem = "1.1" -chrono = { version = "0.4.24", default-features = false, features = ["alloc", "clock"] } +chrono = { version = "0.4.24", default-features = false } ouroboros = "0.15" openssl = "0.10.49" openssl-sys = "0.9.84" diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 4904dd8cc250..9b1920f1d2ed 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -7,7 +7,6 @@ use crate::buf::CffiBuf; use crate::error::CryptographyResult; use crate::x509; -use chrono::Timelike; use once_cell::sync::Lazy; use std::borrow::Cow; use std::collections::HashMap; @@ -149,9 +148,8 @@ fn sign_and_serialize<'p>( }; let content_type_bytes = asn1::write_single(&PKCS7_DATA_OID)?; - let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_chrono( - chrono::Utc::now().with_nanosecond(0).unwrap(), - )?)?; + let now = x509::common::chrono_now(py)?; + let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_chrono(now)?)?; let smime_cap_bytes = asn1::write_single(&asn1::SequenceOfWriter::new([ // Subset of values OpenSSL provides: // https://github.com/openssl/openssl/blob/667a8501f0b6e5705fd611d5bb3ca24848b07154/crypto/pkcs7/pk7_smime.c#L150 diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index a5f642e0d1ef..9bed702d7991 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -701,6 +701,15 @@ pub(crate) fn py_to_chrono( .unwrap()) } +pub(crate) fn chrono_now(py: pyo3::Python<'_>) -> pyo3::PyResult> { + py_to_chrono( + py, + py.import(pyo3::intern!(py, "datetime"))? + .getattr(pyo3::intern!(py, "datetime"))? + .call_method0(pyo3::intern!(py, "utcnow"))?, + ) +} + #[derive(Hash, PartialEq, Clone)] pub(crate) enum Asn1ReadableOrWritable<'a, T, U> { Read(T, PhantomData<&'a ()>), diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index e8f864c42f1e..1679503b6b2a 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -6,7 +6,6 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_chrono, sct}; -use chrono::Timelike; use pyo3::IntoPy; use std::sync::Arc; @@ -723,9 +722,7 @@ fn create_ocsp_response( let tbs_response_data = ResponseData { version: 0, - produced_at: asn1::GeneralizedTime::new( - chrono::Utc::now().with_nanosecond(0).unwrap(), - )?, + produced_at: asn1::GeneralizedTime::new(x509::common::chrono_now(py)?)?, responder_id, responses: x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( responses, From 5a2c495b2962332816da00dbefc644dc1c92a8f5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 2 Apr 2023 17:31:26 -0400 Subject: [PATCH 569/827] Upgrade to Rust 2021 edition (#8656) --- src/rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index e7f0e1baddd6..4608a992eb2c 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -2,7 +2,7 @@ name = "cryptography-rust" version = "0.1.0" authors = ["The cryptography developers "] -edition = "2018" +edition = "2021" publish = false # This specifies the MSRV rust-version = "1.56.0" From 48c3226bf4d59240cc9fba1e3648ed19d121eece Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 00:17:08 +0000 Subject: [PATCH 570/827] Bump BoringSSL and/or OpenSSL in CI (#8659) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ac9b63b9c50..38ded9a1ec2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 01, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d89702704febab30774e8af22450899af297bfb0"}} - # Latest commit on the OpenSSL master branch, as of Apr 01, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "9559ad0e8d433a2a212b63cc848fa2ac82a9b048"}} + # Latest commit on the OpenSSL master branch, as of Apr 03, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "eb52450f5151e8e78743ab05de21a344823316f5"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 From 84ffbe3c6bdc5d1e9a892432f4563740d7b540c9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 2 Apr 2023 23:38:22 -0400 Subject: [PATCH 571/827] Several rust cleanups suggested by clippy in pedantic mode (#8658) --- src/rust/build.rs | 2 +- src/rust/src/backend/x25519.rs | 18 ++++++++---------- src/rust/src/lib.rs | 1 - src/rust/src/x509/common.rs | 1 - src/rust/src/x509/crl.rs | 1 - src/rust/src/x509/csr.rs | 11 +++++------ src/rust/src/x509/sct.rs | 1 - src/rust/src/x509/sign.rs | 16 +++++++--------- 8 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/rust/build.rs b/src/rust/build.rs index 4f0f39aae6b1..faddff8eceb4 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -78,7 +78,7 @@ fn main() { println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_LIBRESSL"); if version >= 0x3_07_00_00_0 { - println!("cargo:rustc-cfg=CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER") + println!("cargo:rustc-cfg=CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER"); } } } diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 988d0076ef5f..7fb6ca2fc4b1 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -191,11 +191,10 @@ impl X25519PrivateKey { )? }; return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); - } else { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err("Unsupported encoding for PKCS8"), - )); } + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Unsupported encoding for PKCS8"), + )); } Err(CryptographyError::from( @@ -267,13 +266,12 @@ impl X25519PublicKey { } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { let der_bytes = self.pkey.public_key_to_der()?; return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); - } else { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err( - "SubjectPublicKeyInfo works only with PEM or DER encoding", - ), - )); } + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "SubjectPublicKeyInfo works only with PEM or DER encoding", + ), + )); } Err(CryptographyError::from( diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index e8608150421c..74989350bad7 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -20,7 +20,6 @@ mod x509; #[cfg(not(python_implementation = "PyPy"))] use pyo3::FromPyPointer; -use std::convert::TryInto; #[cfg(python_implementation = "PyPy")] extern "C" { diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 9bed702d7991..608a4bb6d4d7 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -9,7 +9,6 @@ use chrono::{Datelike, TimeZone, Timelike}; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::HashSet; -use std::convert::TryInto; use std::marker::PhantomData; /// Parse all sections in a PEM file and return the first matching section. diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 7644cfd2715a..fbe27501db2e 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -9,7 +9,6 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, extensions, oid, sign}; use pyo3::{IntoPy, ToPyObject}; -use std::convert::TryInto; use std::sync::Arc; #[pyo3::prelude::pyfunction] diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index b90e49e3e0ee..d9eeb400ac66 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -216,13 +216,12 @@ impl CertificateSigningRequest { || val.tag() == asn1::IA5String::TAG { return Ok(pyo3::types::PyBytes::new(py, val.data())); - } else { - return Err(pyo3::exceptions::PyValueError::new_err(format!( - "OID {} has a disallowed ASN.1 type: {:?}", - oid, - val.tag() - ))); } + return Err(pyo3::exceptions::PyValueError::new_err(format!( + "OID {} has a disallowed ASN.1 type: {:?}", + oid, + val.tag() + ))); } } Err(pyo3::PyErr::from_value( diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index 09e1ae4486c9..35ae088c0b85 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -6,7 +6,6 @@ use crate::error::CryptographyError; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::hash_map::DefaultHasher; -use std::convert::{TryFrom, TryInto}; use std::hash::{Hash, Hasher}; struct TLSReader<'a> { diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 7a788300ebbf..fb46c5c8fb1d 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -135,11 +135,9 @@ pub(crate) fn compute_signature_algorithm<'p>( oid: (oid::ED448_OID).clone(), params: None, }), - (KeyType::Ed25519, _) | (KeyType::Ed448, _) => { - Err(pyo3::exceptions::PyValueError::new_err( - "Algorithm must be None when signing via ed25519 or ed448", - )) - } + (KeyType::Ed25519 | KeyType::Ed448, _) => Err(pyo3::exceptions::PyValueError::new_err( + "Algorithm must be None when signing via ed25519 or ed448", + )), (KeyType::Ec, HashType::Sha224) => Ok(x509::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA224_OID).clone(), @@ -223,10 +221,10 @@ pub(crate) fn compute_signature_algorithm<'p>( oid: (oid::DSA_WITH_SHA512_OID).clone(), params: None, }), - (KeyType::Dsa, HashType::Sha3_224) - | (KeyType::Dsa, HashType::Sha3_256) - | (KeyType::Dsa, HashType::Sha3_384) - | (KeyType::Dsa, HashType::Sha3_512) => Err(pyo3::PyErr::from_value( + ( + KeyType::Dsa, + HashType::Sha3_224 | HashType::Sha3_256 | HashType::Sha3_384 | HashType::Sha3_512, + ) => Err(pyo3::PyErr::from_value( py.import("cryptography.exceptions")?.call_method1( "UnsupportedAlgorithm", ("SHA3 hashes are not supported with DSA keys",), From 0e2421c810747ff09755d36e65b78abd753c7720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 20:54:18 +0000 Subject: [PATCH 572/827] Bump proc-macro2 from 1.0.55 to 1.0.56 in /src/rust (#8661) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.55 to 1.0.56. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.55...1.0.56) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index df2b1abaf649..8c60123ac456 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -287,9 +287,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.55" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] From a4fae22d7ccc6764d41117ebf764eadb0604111e Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 00:58:20 +0000 Subject: [PATCH 573/827] Bump BoringSSL and/or OpenSSL in CI (#8663) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38ded9a1ec2c..e8a3320c3e47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 01, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d89702704febab30774e8af22450899af297bfb0"}} - # Latest commit on the OpenSSL master branch, as of Apr 03, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "eb52450f5151e8e78743ab05de21a344823316f5"}} + # Latest commit on the BoringSSL master branch, as of Apr 04, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6e723e5b37f7387f1c787a57c63e6d993d0c0d92"}} + # Latest commit on the OpenSSL master branch, as of Apr 04, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "418c6c520764491262018c45481a20ef10cd3bca"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 From eb59d966b6ba7e34071088de16f33d9cee682102 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 4 Apr 2023 19:51:51 +0900 Subject: [PATCH 574/827] remove pytest-shard (#8665) --- .github/workflows/ci.yml | 3 +-- ci-constraints-requirements.txt | 3 --- pyproject.toml | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8a3320c3e47..16787de8cefc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -431,7 +431,6 @@ jobs: PYTHON: - {VERSION: "3.7", NOXSESSION: "tests-nocoverage"} - {VERSION: "3.11", NOXSESSION: "tests"} - JOB_NUMBER: [0, 1] timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 @@ -478,7 +477,7 @@ jobs: NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: nox --no-install -- --color=yes --wycheproof-root=wycheproof --num-shards=2 --shard-id=${{ matrix.JOB_NUMBER }} + run: nox --no-install -- --color=yes --wycheproof-root=wycheproof env: NOXSESSION: ${{ matrix.PYTHON.NOXSESSION }} COLUMNS: 80 diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 20bf7a5cedce..92fb5fc9d4c3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -111,7 +111,6 @@ pytest==7.2.2 # pytest-benchmark # pytest-cov # pytest-randomly - # pytest-shard # pytest-xdist pytest-benchmark==4.0.0 # via cryptography (pyproject.toml) @@ -119,8 +118,6 @@ pytest-cov==4.0.0 # via cryptography (pyproject.toml) pytest-randomly==3.12.0 # via cryptography (pyproject.toml) -pytest-shard==0.1.2 - # via cryptography (pyproject.toml) pytest-xdist==3.2.1 # via cryptography (pyproject.toml) readme-renderer==37.3 diff --git a/pyproject.toml b/pyproject.toml index 480b4fbbeb3d..8024179a9738 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,6 @@ ssh = ["bcrypt >=3.1.5"] nox = ["nox"] test = [ "pytest >=6.2.0", - "pytest-shard >=0.1.2", "pytest-benchmark", "pytest-cov", "pytest-xdist", From eeca346f23d2595864ec3cff86d562974cff480a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 4 Apr 2023 20:04:55 +0900 Subject: [PATCH 575/827] upgrade rust-asn1, which removes chrono dep (#8664) * use new rust-asn1 non-chrono path * bump asn1 * oh yeah, remove that --- src/rust/Cargo.lock | 41 ++++------------------------- src/rust/Cargo.toml | 3 +-- src/rust/src/pkcs7.rs | 4 +-- src/rust/src/x509/certificate.rs | 21 +++++++-------- src/rust/src/x509/common.rs | 44 ++++++++++++++++---------------- src/rust/src/x509/crl.rs | 10 ++++---- src/rust/src/x509/extensions.rs | 7 ++--- src/rust/src/x509/mod.rs | 6 ++--- src/rust/src/x509/ocsp_resp.rs | 18 ++++++------- 9 files changed, 58 insertions(+), 96 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 8c60123ac456..b24b3373933e 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -16,23 +16,22 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "asn1" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2affba5e62ee09eeba078f01a00c4aed45ac4287e091298eccbb0d4802efbdc5" +checksum = "48a34f02cde9e43d380b3c72f3deb14b9ef8bf262bd3c92426437b21e74a509a" dependencies = [ "asn1_derive", - "chrono", ] [[package]] name = "asn1_derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfab79c195875e5aef2bd20b4c8ed8d43ef9610bcffefbbcf66f88f555cc78af" +checksum = "ee4d9abdcc064cc9568bff2599089bb497a7de2c4b59608de35e3380b496617a" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.12", ] [[package]] @@ -65,23 +64,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" -dependencies = [ - "num-integer", - "num-traits", -] - [[package]] name = "cryptography-rust" version = "0.1.0" dependencies = [ "asn1", "cc", - "chrono", "foreign-types-shared", "once_cell", "openssl", @@ -137,25 +125,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.17.1" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 4608a992eb2c..5fa9c31df72d 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,9 +10,8 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" pyo3 = { version = "0.18" } -asn1 = { version = "0.13.0", default-features = false, features = ["const-generics"] } +asn1 = { version = "0.14.0", default-features = false } pem = "1.1" -chrono = { version = "0.4.24", default-features = false } ouroboros = "0.15" openssl = "0.10.49" openssl-sys = "0.9.84" diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 9b1920f1d2ed..360c767b36cd 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -148,8 +148,8 @@ fn sign_and_serialize<'p>( }; let content_type_bytes = asn1::write_single(&PKCS7_DATA_OID)?; - let now = x509::common::chrono_now(py)?; - let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_chrono(now)?)?; + let now = x509::common::datetime_now(py)?; + let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_datetime(now)?)?; let smime_cap_bytes = asn1::write_single(&asn1::SequenceOfWriter::new([ // Subset of values OpenSSL provides: // https://github.com/openssl/openssl/blob/667a8501f0b6e5705fd611d5bb3ca24848b07154/crypto/pkcs7/pk7_smime.c#L150 diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index efbab2449780..160048436e24 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -8,7 +8,6 @@ use crate::asn1::{ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; -use chrono::Datelike; use pyo3::{IntoPy, ToPyObject}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -239,26 +238,26 @@ impl Certificate { #[getter] fn not_valid_before<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - let chrono = &self + let dt = &self .raw .borrow_value() .tbs_cert .validity .not_before - .as_chrono(); - x509::chrono_to_py(py, chrono) + .as_datetime(); + x509::datetime_to_py(py, dt) } #[getter] fn not_valid_after<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - let chrono = &self + let dt = &self .raw .borrow_value() .tbs_cert .validity .not_after - .as_chrono(); - x509::chrono_to_py(py, chrono) + .as_datetime(); + x509::datetime_to_py(py, dt) } #[getter] @@ -994,13 +993,11 @@ pub(crate) fn time_from_py( py: pyo3::Python<'_>, val: &pyo3::PyAny, ) -> CryptographyResult { - let dt = x509::py_to_chrono(py, val)?; - time_from_chrono(dt) + let dt = x509::py_to_datetime(py, val)?; + time_from_datetime(dt) } -pub(crate) fn time_from_chrono( - dt: chrono::DateTime, -) -> CryptographyResult { +pub(crate) fn time_from_datetime(dt: asn1::DateTime) -> CryptographyResult { if dt.year() >= 2050 { Ok(x509::Time::GeneralizedTime(asn1::GeneralizedTime::new(dt)?)) } else { diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 608a4bb6d4d7..fe3c21768ab2 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -5,7 +5,6 @@ use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use chrono::{Datelike, TimeZone, Timelike}; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::HashSet; @@ -310,10 +309,10 @@ pub(crate) enum Time { } impl Time { - pub(crate) fn as_chrono(&self) -> &chrono::DateTime { + pub(crate) fn as_datetime(&self) -> &asn1::DateTime { match self { - Time::UtcTime(data) => data.as_chrono(), - Time::GeneralizedTime(data) => data.as_chrono(), + Time::UtcTime(data) => data.as_datetime(), + Time::GeneralizedTime(data) => data.as_datetime(), } } } @@ -667,9 +666,9 @@ fn encode_extension_value<'p>( ))) } -pub(crate) fn chrono_to_py<'p>( +pub(crate) fn datetime_to_py<'p>( py: pyo3::Python<'p>, - dt: &chrono::DateTime, + dt: &asn1::DateTime, ) -> pyo3::PyResult<&'p pyo3::PyAny> { let datetime_module = py.import("datetime")?; datetime_module @@ -684,24 +683,25 @@ pub(crate) fn chrono_to_py<'p>( )) } -pub(crate) fn py_to_chrono( +// TODO +pub(crate) fn py_to_datetime( py: pyo3::Python<'_>, val: &pyo3::PyAny, -) -> pyo3::PyResult> { - Ok(chrono::Utc - .with_ymd_and_hms( - val.getattr(pyo3::intern!(py, "year"))?.extract()?, - val.getattr(pyo3::intern!(py, "month"))?.extract()?, - val.getattr(pyo3::intern!(py, "day"))?.extract()?, - val.getattr(pyo3::intern!(py, "hour"))?.extract()?, - val.getattr(pyo3::intern!(py, "minute"))?.extract()?, - val.getattr(pyo3::intern!(py, "second"))?.extract()?, - ) - .unwrap()) -} - -pub(crate) fn chrono_now(py: pyo3::Python<'_>) -> pyo3::PyResult> { - py_to_chrono( +) -> pyo3::PyResult { + Ok(asn1::DateTime::new( + val.getattr(pyo3::intern!(py, "year"))?.extract()?, + val.getattr(pyo3::intern!(py, "month"))?.extract()?, + val.getattr(pyo3::intern!(py, "day"))?.extract()?, + val.getattr(pyo3::intern!(py, "hour"))?.extract()?, + val.getattr(pyo3::intern!(py, "minute"))?.extract()?, + val.getattr(pyo3::intern!(py, "second"))?.extract()?, + ) + .unwrap()) +} + +// TODO +pub(crate) fn datetime_now(py: pyo3::Python<'_>) -> pyo3::PyResult { + py_to_datetime( py, py.import(pyo3::intern!(py, "datetime"))? .getattr(pyo3::intern!(py, "datetime"))? diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index fbe27501db2e..50beb85ecda2 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -245,20 +245,20 @@ impl CertificateRevocationList { #[getter] fn next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { match &self.raw.borrow_value().tbs_cert_list.next_update { - Some(t) => x509::chrono_to_py(py, t.as_chrono()), + Some(t) => x509::datetime_to_py(py, t.as_datetime()), None => Ok(py.None().into_ref(py)), } } #[getter] fn last_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - x509::chrono_to_py( + x509::datetime_to_py( py, self.raw .borrow_value() .tbs_cert_list .this_update - .as_chrono(), + .as_datetime(), ) } @@ -531,7 +531,7 @@ impl RevokedCertificate { #[getter] fn revocation_date<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - x509::chrono_to_py(py, self.raw.borrow_value().revocation_date.as_chrono()) + x509::datetime_to_py(py, self.raw.borrow_value().revocation_date.as_datetime()) } #[getter] @@ -631,7 +631,7 @@ pub fn parse_crl_entry_ext<'p>( } oid::INVALIDITY_DATE_OID => { let time = asn1::parse_single::(data)?; - let py_dt = x509::chrono_to_py(py, time.as_chrono())?; + let py_dt = x509::datetime_to_py(py, time.as_datetime())?; Ok(Some( x509_module .getattr(pyo3::intern!(py, "InvalidityDate"))? diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 79170a616612..cded8890dbac 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -390,11 +390,8 @@ pub(crate) fn encode_extension( Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?)) } &oid::INVALIDITY_DATE_OID => { - let chrono_dt = - x509::py_to_chrono(py, ext.getattr(pyo3::intern!(py, "invalidity_date"))?)?; - Ok(Some(asn1::write_single(&asn1::GeneralizedTime::new( - chrono_dt, - )?)?)) + let dt = x509::py_to_datetime(py, ext.getattr(pyo3::intern!(py, "invalidity_date"))?)?; + Ok(Some(asn1::write_single(&asn1::GeneralizedTime::new(dt)?)?)) } &oid::CRL_NUMBER_OID | &oid::DELTA_CRL_INDICATOR_OID => { let intval = ext diff --git a/src/rust/src/x509/mod.rs b/src/rust/src/x509/mod.rs index 8c7b39f4b369..2ad15c6e6dbc 100644 --- a/src/rust/src/x509/mod.rs +++ b/src/rust/src/x509/mod.rs @@ -16,7 +16,7 @@ pub(crate) mod sign; pub(crate) use certificate::Certificate; pub(crate) use common::{ - chrono_to_py, find_in_pem, parse_and_cache_extensions, parse_general_name, parse_general_names, - parse_name, parse_rdn, py_to_chrono, AlgorithmIdentifier, Asn1ReadableOrWritable, - AttributeTypeValue, Extensions, GeneralName, Name, Time, + datetime_to_py, find_in_pem, parse_and_cache_extensions, parse_general_name, + parse_general_names, parse_name, parse_rdn, py_to_datetime, AlgorithmIdentifier, + Asn1ReadableOrWritable, AttributeTypeValue, Extensions, GeneralName, Name, Time, }; diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 1679503b6b2a..cec07a2ffbd8 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -5,7 +5,7 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_chrono, sct}; +use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_datetime, sct}; use pyo3::IntoPy; use std::sync::Arc; @@ -158,7 +158,7 @@ impl OCSPResponse { #[getter] fn produced_at<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - x509::chrono_to_py(py, resp.tbs_response_data.produced_at.as_chrono()) + x509::datetime_to_py(py, resp.tbs_response_data.produced_at.as_datetime()) } #[getter] @@ -549,12 +549,12 @@ impl SingleResponse<'_> { } fn py_this_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - x509::chrono_to_py(py, self.this_update.as_chrono()) + x509::datetime_to_py(py, self.this_update.as_datetime()) } fn py_next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { match &self.next_update { - Some(v) => x509::chrono_to_py(py, v.as_chrono()), + Some(v) => x509::datetime_to_py(py, v.as_datetime()), None => Ok(py.None().into_ref(py)), } } @@ -575,7 +575,7 @@ impl SingleResponse<'_> { fn py_revocation_time<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { match &self.cert_status { CertStatus::Revoked(revoked_info) => { - x509::chrono_to_py(py, revoked_info.revocation_time.as_chrono()) + x509::datetime_to_py(py, revoked_info.revocation_time.as_datetime()) } CertStatus::Good(_) | CertStatus::Unknown(_) => Ok(py.None().into_ref(py)), } @@ -660,7 +660,7 @@ fn create_ocsp_response( let py_revocation_time = py_single_resp.getattr(pyo3::intern!(py, "_revocation_time"))?; let revocation_time = - asn1::GeneralizedTime::new(py_to_chrono(py, py_revocation_time)?)?; + asn1::GeneralizedTime::new(py_to_datetime(py, py_revocation_time)?)?; CertStatus::Revoked(RevokedInfo { revocation_time, revocation_reason, @@ -671,7 +671,7 @@ fn create_ocsp_response( .is_none() { let py_next_update = py_single_resp.getattr(pyo3::intern!(py, "_next_update"))?; - Some(asn1::GeneralizedTime::new(py_to_chrono( + Some(asn1::GeneralizedTime::new(py_to_datetime( py, py_next_update, )?)?) @@ -679,7 +679,7 @@ fn create_ocsp_response( None }; let py_this_update = py_single_resp.getattr(pyo3::intern!(py, "_this_update"))?; - let this_update = asn1::GeneralizedTime::new(py_to_chrono(py, py_this_update)?)?; + let this_update = asn1::GeneralizedTime::new(py_to_datetime(py, py_this_update)?)?; let responses = vec![SingleResponse { cert_id: ocsp::CertID::new(py, &py_cert, &py_issuer, py_cert_hash_algorithm)?, @@ -722,7 +722,7 @@ fn create_ocsp_response( let tbs_response_data = ResponseData { version: 0, - produced_at: asn1::GeneralizedTime::new(x509::common::chrono_now(py)?)?, + produced_at: asn1::GeneralizedTime::new(x509::common::datetime_now(py)?)?, responder_id, responses: x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( responses, From 57be62f356e2b8e9bfb02099348b1ff2508aac68 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 4 Apr 2023 07:32:17 -0400 Subject: [PATCH 576/827] Remove accidentally left-over TODO comments (#8666) --- src/rust/src/x509/common.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index fe3c21768ab2..a4ac9b3d4cd9 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -683,7 +683,6 @@ pub(crate) fn datetime_to_py<'p>( )) } -// TODO pub(crate) fn py_to_datetime( py: pyo3::Python<'_>, val: &pyo3::PyAny, @@ -699,7 +698,6 @@ pub(crate) fn py_to_datetime( .unwrap()) } -// TODO pub(crate) fn datetime_now(py: pyo3::Python<'_>) -> pyo3::PyResult { py_to_datetime( py, From 634471258ff755c45b90f59d9a10b3b535f7b4d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 13:07:18 +0000 Subject: [PATCH 577/827] Bump libc from 0.2.140 to 0.2.141 in /src/rust (#8667) Bumps [libc](https://github.com/rust-lang/libc) from 0.2.140 to 0.2.141. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/commits) --- updated-dependencies: - dependency-name: libc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b24b3373933e..fd554872706f 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -102,9 +102,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "lock_api" From e970aefaaf94c5b010593dcbcc03a5d7adabea52 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:28:20 +0900 Subject: [PATCH 578/827] Bump BoringSSL and/or OpenSSL in CI (#8670) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16787de8cefc..51196e4f3bd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 04, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6e723e5b37f7387f1c787a57c63e6d993d0c0d92"}} - # Latest commit on the OpenSSL master branch, as of Apr 04, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "418c6c520764491262018c45481a20ef10cd3bca"}} + # Latest commit on the OpenSSL master branch, as of Apr 05, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f06ef1657a3d4322153b26231a7afa3d55724e52"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 From 0d4f9013d5fe09c9151e25fdba37d02044561931 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:06:58 +0000 Subject: [PATCH 579/827] Bump peter-evans/create-pull-request from 4.2.4 to 5.0.0 (#8672) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.2.4 to 5.0.0. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/38e0b6e68b4c852a5500a94740f0e535e0d7ba54...5b4a9f6a9e2af26e5f02351490b90d01eb8ec1e5) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/boring-open-version-bump.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 66a9ad5b0c28..5e96a3e3ba8a 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -58,7 +58,7 @@ jobs: private_key: ${{ secrets.BORINGBOT_PRIVATE_KEY }} if: steps.check-sha-boring.outputs.COMMIT_SHA || steps.check-sha-openssl.outputs.COMMIT_SHA - name: Create Pull Request - uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 + uses: peter-evans/create-pull-request@5b4a9f6a9e2af26e5f02351490b90d01eb8ec1e5 with: commit-message: "Bump BoringSSL and/or OpenSSL in CI" title: "Bump BoringSSL and/or OpenSSL in CI" From 074e0a41288e9b4c8655e26cd81e198a14df933e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:07:27 +0000 Subject: [PATCH 580/827] Bump dawidd6/action-download-artifact from 2.26.0 to 2.26.1 (#8673) Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2.26.0 to 2.26.1. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/5e780fc7bbd0cac69fc73271ed86edf5dcb72d67...7132ab516fba5f602fafae6fdd4822afa10db76f) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/pypi-publish.yml | 2 +- .github/workflows/wheel-builder.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51196e4f3bd0..e8aeacc5344d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -394,7 +394,7 @@ jobs: timeout-minutes: 2 uses: ./.github/actions/wycheproof - - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f with: repo: pyca/infra workflow: build-macos-openssl.yml @@ -453,7 +453,7 @@ jobs: key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - run: python -m pip install -c ci-constraints-requirements.txt "nox" coverage[toml] - - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f with: repo: pyca/infra workflow: build-windows-openssl.yml diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index f12b7244c32b..172bb131a9b9 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -25,7 +25,7 @@ jobs: permissions: id-token: "write" steps: - - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f with: path: dist/ run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.id }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index e7b7ace10347..62af5f7d8322 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -194,7 +194,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') - - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f with: repo: pyca/infra workflow: build-macos-openssl.yml @@ -273,7 +273,7 @@ jobs: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} - - uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 + - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f with: repo: pyca/infra workflow: build-windows-openssl.yml From 4ca343eec771d9f0c1a907e19168b57ceeb5b528 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:15:23 +0000 Subject: [PATCH 581/827] Bump ruff from 0.0.260 to 0.0.261 (#8674) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.260 to 0.0.261. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.260...v0.0.261) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 92fb5fc9d4c3..5e509a81d637 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -133,7 +133,7 @@ rfc3986==2.0.0 # via twine rich==13.3.3 # via twine -ruff==0.0.260 +ruff==0.0.261 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From 88f0df598da153f8cfab37b43420140ccb4bb59d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 6 Apr 2023 17:21:02 -0500 Subject: [PATCH 582/827] Update MSRV comment (#8678) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8aeacc5344d..d2a1118103ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -252,8 +252,8 @@ jobs: - "3.11" RUST: # Potential future MSRVs: + # 1.60 - pem 2.0.1 - 1.60.0 - # 1.67 - new version of pem - beta - nightly name: "Rust Coverage" From c70fdad216f56b1fe92875638fdc039c45986da4 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 6 Apr 2023 22:14:02 -0500 Subject: [PATCH 583/827] Bump BoringSSL and/or OpenSSL in CI (#8681) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2a1118103ea..26549f45f1df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 04, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6e723e5b37f7387f1c787a57c63e6d993d0c0d92"}} - # Latest commit on the OpenSSL master branch, as of Apr 05, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f06ef1657a3d4322153b26231a7afa3d55724e52"}} + # Latest commit on the OpenSSL master branch, as of Apr 07, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f309b3f6087db6c83126f8f227f1fc4984cf24b1"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 From f1b3858afe7fe670bc1eaa06ac87210d49e12a45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:11:59 +0000 Subject: [PATCH 584/827] Bump coverage from 7.2.2 to 7.2.3 (#8683) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.2 to 7.2.3. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.2...7.2.3) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5e509a81d637..ef8e883478d8 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -30,7 +30,7 @@ click==8.1.3 # via black colorlog==6.7.0 # via nox -coverage==7.2.2 +coverage==7.2.3 # via pytest-cov distlib==0.3.6 # via virtualenv From 58f34d5b52d99b121a50fc4fc143307bbe5c9f37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:14:33 +0000 Subject: [PATCH 585/827] Bump mypy from 1.1.1 to 1.2.0 (#8684) Bumps [mypy](https://github.com/python/mypy) from 1.1.1 to 1.2.0. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.1.1...v1.2.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ef8e883478d8..91fbf1f314f8 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -65,7 +65,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.1.0 # via jaraco-classes -mypy==1.1.1 +mypy==1.2.0 # via cryptography (pyproject.toml) mypy-extensions==1.0.0 # via From 21c681ac880fc4009a760ca5bc7d9d6560944be4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:15:11 +0000 Subject: [PATCH 586/827] Bump filelock from 3.10.7 to 3.11.0 (#8685) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.7 to 3.11.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.7...3.11.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 91fbf1f314f8..e119b6a70783 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -43,7 +43,7 @@ exceptiongroup==1.1.1 # via pytest execnet==1.9.0 # via pytest-xdist -filelock==3.10.7 +filelock==3.11.0 # via virtualenv idna==3.4 # via requests From 9077391b9057892303518b1c184d9917b28a2c21 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 8 Apr 2023 00:13:53 +0000 Subject: [PATCH 587/827] Bump BoringSSL and/or OpenSSL in CI (#8687) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26549f45f1df..accb44b8faf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 04, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6e723e5b37f7387f1c787a57c63e6d993d0c0d92"}} + # Latest commit on the BoringSSL master branch, as of Apr 08, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "44a389a7fce31013b5953038d4231f33cbf2ba9d"}} # Latest commit on the OpenSSL master branch, as of Apr 07, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f309b3f6087db6c83126f8f227f1fc4984cf24b1"}} timeout-minutes: 15 From 9f36c3fe69644ba0d0d880f8472d4b9a8677f384 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Apr 2023 23:27:03 +0000 Subject: [PATCH 588/827] Bump pytest from 7.2.2 to 7.3.0 (#8689) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.2 to 7.3.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.2...7.3.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e119b6a70783..b6b9289cb6e2 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -105,7 +105,7 @@ pygments==2.14.0 # sphinx pyproject-hooks==1.0.0 # via build -pytest==7.2.2 +pytest==7.3.0 # via # cryptography (pyproject.toml) # pytest-benchmark From 86ec17028522926bb21ee7bf49b0a1cf6b0477d6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 8 Apr 2023 18:29:06 -0500 Subject: [PATCH 589/827] silence noxfile warnings running cargo (#8688) --- noxfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index 62634b03fe43..b60d6a602e63 100644 --- a/noxfile.py +++ b/noxfile.py @@ -141,6 +141,6 @@ def rust(session: nox.Session) -> None: install(session, ".") with session.chdir("src/rust/"): - session.run("cargo", "fmt", "--all", "--", "--check") - session.run("cargo", "clippy", "--", "-D", "warnings") - session.run("cargo", "test", "--no-default-features") + session.run("cargo", "fmt", "--all", "--", "--check", external=True) + session.run("cargo", "clippy", "--", "-D", "warnings", external=True) + session.run("cargo", "test", "--no-default-features", external=True) From 122211bb457a86f6588deb40242869449077d8e5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 9 Apr 2023 16:48:42 -0500 Subject: [PATCH 590/827] Remove coverage workaround that might not be required anymore (#8690) --- tests/utils.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 10f73c7ebd92..c87df65c1507 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -243,9 +243,6 @@ def load_pkcs1_vectors(vector_data): attr = None if private_key_vector is None or public_key_vector is None: - # Random garbage to defeat CPython's peephole optimizer so that - # coverage records correctly: https://bugs.python.org/issue2506 - 1 + 1 continue if line.startswith("# Private key"): From 84f69b169d10ee9985e7cc32f56b8afafb7d5595 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 9 Apr 2023 18:33:45 -0500 Subject: [PATCH 591/827] Migrate x448 to Rust (#8691) --- .../hazmat/backends/openssl/backend.py | 36 +--- .../hazmat/backends/openssl/x448.py | 119 ------------ .../bindings/_rust/openssl/__init__.pyi | 4 +- .../hazmat/bindings/_rust/openssl/x448.pyi | 14 ++ .../hazmat/primitives/asymmetric/x448.py | 19 +- src/rust/build.rs | 3 + src/rust/src/backend/mod.rs | 6 + src/rust/src/backend/utils.rs | 176 ++++++++++++++++++ src/rust/src/backend/x25519.rs | 159 +--------------- src/rust/src/backend/x448.rs | 144 ++++++++++++++ 10 files changed, 369 insertions(+), 311 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/x448.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/x448.pyi create mode 100644 src/rust/src/backend/utils.rs create mode 100644 src/rust/src/backend/x448.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index ac464e75a809..adda33285676 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -49,10 +49,6 @@ _RSAPrivateKey, _RSAPublicKey, ) -from cryptography.hazmat.backends.openssl.x448 import ( - _X448PrivateKey, - _X448PublicKey, -) from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl import binding from cryptography.hazmat.primitives import hashes, serialization @@ -648,7 +644,9 @@ def _evp_pkey_to_private_key( return _Ed25519PrivateKey(self, evp_pkey) elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _X448PrivateKey(self, evp_pkey) + return rust_openssl.x448.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == self._lib.EVP_PKEY_X25519: return rust_openssl.x25519.private_key_from_ptr( int(self._ffi.cast("uintptr_t", evp_pkey)) @@ -707,7 +705,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: return _Ed25519PublicKey(self, evp_pkey) elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _X448PublicKey(self, evp_pkey) + return rust_openssl.x448.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == self._lib.EVP_PKEY_X25519: return rust_openssl.x25519.public_key_from_ptr( int(self._ffi.cast("uintptr_t", evp_pkey)) @@ -1828,31 +1828,13 @@ def x25519_supported(self) -> bool: return not self._lib.CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 def x448_load_public_bytes(self, data: bytes) -> x448.X448PublicKey: - if len(data) != 56: - raise ValueError("An X448 public key is 56 bytes long") - - evp_pkey = self._lib.EVP_PKEY_new_raw_public_key( - self._lib.NID_X448, self._ffi.NULL, data, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return _X448PublicKey(self, evp_pkey) + return rust_openssl.x448.from_public_bytes(data) def x448_load_private_bytes(self, data: bytes) -> x448.X448PrivateKey: - if len(data) != 56: - raise ValueError("An X448 private key is 56 bytes long") - - data_ptr = self._ffi.from_buffer(data) - evp_pkey = self._lib.EVP_PKEY_new_raw_private_key( - self._lib.NID_X448, self._ffi.NULL, data_ptr, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return _X448PrivateKey(self, evp_pkey) + return rust_openssl.x448.from_private_bytes(data) def x448_generate_key(self) -> x448.X448PrivateKey: - evp_pkey = self._evp_pkey_keygen_gc(self._lib.NID_X448) - return _X448PrivateKey(self, evp_pkey) + return rust_openssl.x448.generate_key() def x448_supported(self) -> bool: if self._fips_enabled: diff --git a/src/cryptography/hazmat/backends/openssl/x448.py b/src/cryptography/hazmat/backends/openssl/x448.py deleted file mode 100644 index 5c91fba45279..000000000000 --- a/src/cryptography/hazmat/backends/openssl/x448.py +++ /dev/null @@ -1,119 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric.x448 import ( - X448PrivateKey, - X448PublicKey, -) - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - -_X448_KEY_SIZE = 56 - - -class _X448PublicKey(X448PublicKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PublicFormat.Raw - ): - if ( - encoding is not serialization.Encoding.Raw - or format is not serialization.PublicFormat.Raw - ): - raise ValueError( - "When using Raw both encoding and format must be Raw" - ) - - return self._raw_public_bytes() - - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def _raw_public_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) - return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:] - - -class _X448PrivateKey(X448PrivateKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_key(self) -> X448PublicKey: - buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) - public_bytes = self._backend._ffi.buffer(buf)[:] - return self._backend.x448_load_public_bytes(public_bytes) - - def exchange(self, peer_public_key: X448PublicKey) -> bytes: - if not isinstance(peer_public_key, X448PublicKey): - raise TypeError("peer_public_key must be X448PublicKey.") - - return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PrivateFormat.Raw - ): - if ( - format is not serialization.PrivateFormat.Raw - or encoding is not serialization.Encoding.Raw - or not isinstance( - encryption_algorithm, serialization.NoEncryption - ) - ): - raise ValueError( - "When using Raw both encoding and format must be Raw " - "and encryption_algorithm must be NoEncryption()" - ) - - return self._raw_private_bytes() - - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self, self._evp_pkey, None - ) - - def _raw_private_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_private_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) - return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index c19b6a9bcbeb..31e682b9ae36 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -4,9 +4,9 @@ import typing -from cryptography.hazmat.bindings._rust.openssl import x25519 +from cryptography.hazmat.bindings._rust.openssl import x448, x25519 -__all__ = ["openssl_version", "raise_openssl_error", "x25519"] +__all__ = ["openssl_version", "raise_openssl_error", "x448", "x25519"] def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/x448.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/x448.pyi new file mode 100644 index 000000000000..d326c8d2d7c5 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/x448.pyi @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import x448 + +class X448PrivateKey: ... +class X448PublicKey: ... + +def generate_key() -> x448.X448PrivateKey: ... +def private_key_from_ptr(ptr: int) -> x448.X448PrivateKey: ... +def public_key_from_ptr(ptr: int) -> x448.X448PublicKey: ... +def from_private_bytes(data: bytes) -> x448.X448PrivateKey: ... +def from_public_bytes(data: bytes) -> x448.X448PublicKey: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index 25ff4c6ec36a..06b55d44b2a6 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -7,6 +7,7 @@ import abc from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization @@ -33,14 +34,16 @@ def public_bytes( The serialized bytes of the public key. """ + @abc.abstractmethod def public_bytes_raw(self) -> bytes: """ The raw bytes of the public key. Equivalent to public_bytes(Raw, Raw). """ - return self.public_bytes( - _serialization.Encoding.Raw, _serialization.PublicFormat.Raw - ) + + +if hasattr(rust_openssl, "x448"): + X448PublicKey.register(rust_openssl.x448.X448PublicKey) class X448PrivateKey(metaclass=abc.ABCMeta): @@ -84,19 +87,19 @@ def private_bytes( The serialized bytes of the private key. """ + @abc.abstractmethod def private_bytes_raw(self) -> bytes: """ The raw bytes of the private key. Equivalent to private_bytes(Raw, Raw, NoEncryption()). """ - return self.private_bytes( - _serialization.Encoding.Raw, - _serialization.PrivateFormat.Raw, - _serialization.NoEncryption(), - ) @abc.abstractmethod def exchange(self, peer_public_key: X448PublicKey) -> bytes: """ Performs a key exchange operation using the provided peer's public key. """ + + +if hasattr(rust_openssl, "x448"): + X448PrivateKey.register(rust_openssl.x448.X448PrivateKey) diff --git a/src/rust/build.rs b/src/rust/build.rs index faddff8eceb4..d315ec62d869 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -81,6 +81,9 @@ fn main() { println!("cargo:rustc-cfg=CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER"); } } + if env::var("DEP_OPENSSL_BORINGSSL").is_ok() { + println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_BORINGSSL"); + } } /// Run a python script using the specified interpreter binary. diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index c7e086b56efb..82beb444a2cb 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -2,12 +2,18 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +#[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] +pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod x25519; +#[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] +pub(crate) mod x448; pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(x25519::create_module(module.py())?)?; + #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] + module.add_submodule(x448::create_module(module.py())?)?; Ok(()) } diff --git a/src/rust/src/backend/utils.rs b/src/rust/src/backend/utils.rs new file mode 100644 index 000000000000..97b2b0c64a63 --- /dev/null +++ b/src/rust/src/backend/utils.rs @@ -0,0 +1,176 @@ +// 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. + +use crate::error::{CryptographyError, CryptographyResult}; + +pub(crate) fn pkey_private_bytes<'p>( + py: pyo3::Python<'p>, + pkey: &openssl::pkey::PKey, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, +) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let encoding_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "Encoding"))? + .extract()?; + let private_format_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "PrivateFormat"))? + .extract()?; + let no_encryption_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "NoEncryption"))? + .extract()?; + let best_available_encryption_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "BestAvailableEncryption"))? + .extract()?; + + if !encoding.is_instance(encoding_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "encoding must be an item from the Encoding enum", + ), + )); + } + if !format.is_instance(private_format_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "format must be an item from the PrivateFormat enum", + ), + )); + } + + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) + { + if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || !format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) + || !encryption_algorithm.is_instance(no_encryption_class)? + { + return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( + "When using Raw both encoding and format must be Raw and encryption_algorithm must be NoEncryption()" + ))); + } + let raw_bytes = pkey.raw_private_key()?; + return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); + } + + let password = if encryption_algorithm.is_instance(no_encryption_class)? { + b"" + } else if encryption_algorithm.is_instance(best_available_encryption_class)? { + encryption_algorithm + .getattr(pyo3::intern!(py, "password"))? + .extract::<&[u8]>()? + } else { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "Encryption algorithm must be a KeySerializationEncryption instance", + ), + )); + }; + + if password.len() > 1023 { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Passwords longer than 1023 bytes are not supported by this backend", + ), + )); + } + + if format.is(private_format_class.getattr(pyo3::intern!(py, "PKCS8"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { + let pem_bytes = if password.is_empty() { + pkey.private_key_to_pem_pkcs8()? + } else { + pkey.private_key_to_pem_pkcs8_passphrase( + openssl::symm::Cipher::aes_256_cbc(), + password, + )? + }; + return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { + let der_bytes = if password.is_empty() { + pkey.private_key_to_pkcs8()? + } else { + pkey.private_key_to_pkcs8_passphrase( + openssl::symm::Cipher::aes_256_cbc(), + password, + )? + }; + return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); + } + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Unsupported encoding for PKCS8"), + )); + } + + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), + )) +} + +pub(crate) fn pkey_public_bytes<'p>( + py: pyo3::Python<'p>, + pkey: &openssl::pkey::PKey, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, +) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let encoding_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "Encoding"))? + .extract()?; + let public_format_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "PublicFormat"))? + .extract()?; + + if !encoding.is_instance(encoding_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "encoding must be an item from the Encoding enum", + ), + )); + } + if !format.is_instance(public_format_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "format must be an item from the PublicFormat enum", + ), + )); + } + + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) + { + if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || !format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) + { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "When using Raw both encoding and format must be Raw", + ), + )); + } + let raw_bytes = pkey.raw_public_key()?; + return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); + } + + // SubjectPublicKeyInfo + PEM/DER + if format.is(public_format_class.getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { + let pem_bytes = pkey.public_key_to_pem()?; + return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { + let der_bytes = pkey.public_key_to_der()?; + return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); + } + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "SubjectPublicKeyInfo works only with PEM or DER encoding", + ), + )); + } + + Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), + )) +} diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 7fb6ca2fc4b1..9cd86b00af8f 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -2,8 +2,9 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::backend::utils; use crate::buf::CffiBuf; -use crate::error::{CryptographyError, CryptographyResult}; +use crate::error::CryptographyResult; use foreign_types_shared::ForeignTypeRef; #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.x25519")] @@ -104,102 +105,7 @@ impl X25519PrivateKey { format: &pyo3::PyAny, encryption_algorithm: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; - let encoding_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "Encoding"))? - .extract()?; - let private_format_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "PrivateFormat"))? - .extract()?; - let no_encryption_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "NoEncryption"))? - .extract()?; - let best_available_encryption_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "BestAvailableEncryption"))? - .extract()?; - - if !encoding.is_instance(encoding_class)? { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "encoding must be an item from the Encoding enum", - ), - )); - } - if !format.is_instance(private_format_class)? { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "format must be an item from the PrivateFormat enum", - ), - )); - } - - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) - { - if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || !format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) - || !encryption_algorithm.is_instance(no_encryption_class)? - { - return Err(CryptographyError::from(pyo3::exceptions::PyValueError::new_err( - "When using Raw both encoding and format must be Raw and encryption_algorithm must be NoEncryption()" - ))); - } - let raw_bytes = self.pkey.raw_private_key()?; - return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); - } - - let password = if encryption_algorithm.is_instance(no_encryption_class)? { - b"" - } else if encryption_algorithm.is_instance(best_available_encryption_class)? { - encryption_algorithm - .getattr(pyo3::intern!(py, "password"))? - .extract::<&[u8]>()? - } else { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "Encryption algorithm must be a KeySerializationEncryption instance", - ), - )); - }; - - if password.len() > 1023 { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err( - "Passwords longer than 1023 bytes are not supported by this backend", - ), - )); - } - - if format.is(private_format_class.getattr(pyo3::intern!(py, "PKCS8"))?) { - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { - let pem_bytes = if password.is_empty() { - self.pkey.private_key_to_pem_pkcs8()? - } else { - self.pkey.private_key_to_pem_pkcs8_passphrase( - openssl::symm::Cipher::aes_256_cbc(), - password, - )? - }; - return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { - let der_bytes = if password.is_empty() { - self.pkey.private_key_to_pkcs8()? - } else { - self.pkey.private_key_to_pkcs8_passphrase( - openssl::symm::Cipher::aes_256_cbc(), - password, - )? - }; - return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); - } - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err("Unsupported encoding for PKCS8"), - )); - } - - Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), - )) + utils::pkey_private_bytes(py, &self.pkey, encoding, format, encryption_algorithm) } } @@ -219,64 +125,7 @@ impl X25519PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; - let encoding_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "Encoding"))? - .extract()?; - let public_format_class: &pyo3::types::PyType = serialization_mod - .getattr(pyo3::intern!(py, "PublicFormat"))? - .extract()?; - - if !encoding.is_instance(encoding_class)? { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "encoding must be an item from the Encoding enum", - ), - )); - } - if !format.is_instance(public_format_class)? { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "format must be an item from the PublicFormat enum", - ), - )); - } - - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) - { - if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || !format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) - { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err( - "When using Raw both encoding and format must be Raw", - ), - )); - } - let raw_bytes = self.pkey.raw_public_key()?; - return Ok(pyo3::types::PyBytes::new(py, &raw_bytes)); - } - - // SubjectPublicKeyInfo + PEM/DER - if format.is(public_format_class.getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?) { - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { - let pem_bytes = self.pkey.public_key_to_pem()?; - return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); - } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { - let der_bytes = self.pkey.public_key_to_der()?; - return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); - } - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err( - "SubjectPublicKeyInfo works only with PEM or DER encoding", - ), - )); - } - - Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), - )) + utils::pkey_public_bytes(py, &self.pkey, encoding, format) } } diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs new file mode 100644 index 000000000000..ff6d7f5b685c --- /dev/null +++ b/src/rust/src/backend/x448.rs @@ -0,0 +1,144 @@ +// 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. + +use crate::backend::utils; +use crate::buf::CffiBuf; +use crate::error::CryptographyResult; +use foreign_types_shared::ForeignTypeRef; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.x448")] +struct X448PrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.x448")] +struct X448PublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyfunction] +fn generate_key() -> CryptographyResult { + Ok(X448PrivateKey { + pkey: openssl::pkey::PKey::generate_x448()?, + }) +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> X448PrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + X448PrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> X448PublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + X448PublicKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn from_private_bytes(data: CffiBuf<'_>) -> pyo3::PyResult { + let pkey = + openssl::pkey::PKey::private_key_from_raw_bytes(data.as_bytes(), openssl::pkey::Id::X448) + .map_err(|e| { + pyo3::exceptions::PyValueError::new_err(format!( + "An X448 private key is 56 bytes long: {}", + e + )) + })?; + Ok(X448PrivateKey { pkey }) +} +#[pyo3::prelude::pyfunction] +fn from_public_bytes(data: &[u8]) -> pyo3::PyResult { + let pkey = openssl::pkey::PKey::public_key_from_raw_bytes(data, openssl::pkey::Id::X448) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An X448 public key is 32 bytes long") + })?; + Ok(X448PublicKey { pkey }) +} + +#[pyo3::prelude::pymethods] +impl X448PrivateKey { + fn exchange<'p>( + &self, + py: pyo3::Python<'p>, + public_key: &X448PublicKey, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut deriver = openssl::derive::Deriver::new(&self.pkey)?; + deriver.set_peer(&public_key.pkey)?; + + Ok(pyo3::types::PyBytes::new_with(py, deriver.len()?, |b| { + let n = deriver.derive(b).map_err(|_| { + pyo3::exceptions::PyValueError::new_err("Error computing shared key.") + })?; + assert_eq!(n, b.len()); + Ok(()) + })?) + } + + fn public_key(&self) -> CryptographyResult { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(X448PublicKey { + pkey: openssl::pkey::PKey::public_key_from_raw_bytes( + &raw_bytes, + openssl::pkey::Id::X448, + )?, + }) + } + + fn private_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_private_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn private_bytes<'p>( + &self, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_private_bytes(py, &self.pkey, encoding, format, encryption_algorithm) + } +} + +#[pyo3::prelude::pymethods] +impl X448PublicKey { + fn public_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn public_bytes<'p>( + &self, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_public_bytes(py, &self.pkey, encoding, format) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "x448")?; + m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; + m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + + m.add_class::()?; + m.add_class::()?; + + Ok(m) +} From 684b710bea009efb062e5a5502583afe43390956 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 00:29:59 +0000 Subject: [PATCH 592/827] Bump openssl from 0.10.49 to 0.10.50 in /src/rust (#8693) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.49 to 0.10.50. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.49...openssl-v0.10.50) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index fd554872706f..2cf3919ebc5a 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -133,9 +133,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.49" +version = "0.10.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" +checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" dependencies = [ "bitflags", "cfg-if", @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.84" +version = "0.9.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" +checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" dependencies = [ "cc", "libc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 5fa9c31df72d..1e188960257d 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -13,7 +13,7 @@ pyo3 = { version = "0.18" } asn1 = { version = "0.14.0", default-features = false } pem = "1.1" ouroboros = "0.15" -openssl = "0.10.49" +openssl = "0.10.50" openssl-sys = "0.9.84" foreign-types-shared = "0.1" From 253fb2abcf2bbf1184661020374eb75c0dc8bdd2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 9 Apr 2023 20:45:31 -0400 Subject: [PATCH 593/827] libressl 3.7.2 (#8692) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index accb44b8faf7..ac4c512496bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.1"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 08, 2023. From f724c9b2fd424c6ac318951fb348a6a2d667b385 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Apr 2023 11:10:41 +0800 Subject: [PATCH 594/827] Support msCertificateTemplate extension (#8695) * support ms certificate template * contortions for rust coverage * review feedback --- CHANGELOG.rst | 2 + docs/development/test-vectors.rst | 2 + docs/x509/reference.rst | 34 ++++++++ src/cryptography/hazmat/_oid.py | 2 + src/cryptography/x509/__init__.py | 2 + src/cryptography/x509/extensions.py | 59 +++++++++++++ src/rust/src/x509/certificate.rs | 16 ++++ src/rust/src/x509/extensions.rs | 9 ++ src/rust/src/x509/oid.rs | 2 + tests/x509/test_x509.py | 16 ++++ tests/x509/test_x509_ext.py | 83 +++++++++++++++++++ .../x509/custom/ms-certificate-template.pem | 9 ++ 12 files changed, 236 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/ms-certificate-template.pem diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ec7a3db5ddc9..7e44bd9061e9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,8 @@ Changelog * Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. * Added support for the :class:`~cryptography.x509.OCSPAcceptableResponses` OCSP extension. +* Added support for the :class:`~cryptography.x509.MSCertificateTemplate` + proprietary Microsoft certificate extension. .. _v40-0-1: diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 2cb822306707..b3a1c301da58 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -483,6 +483,8 @@ Custom X.509 Vectors * ``mismatch_inner_outer_sig_algorithm.der`` - A leaf certificate derived from ``x509/cryptography.io.pem`` but modifying the ``tbs_cert.signature_algorithm`` OID to not match the outer signature algorithm OID. +* ``ms-certificate-template.pem`` - A certificate with a ``msCertificateTemplate`` + extension. Custom X.509 Request Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index d0f864b56a5b..2f7040ebfa12 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -2663,6 +2663,34 @@ X.509 Extensions Returns the DER encoded bytes payload of the extension. +.. class:: MSCertificateTemplate(template_id, major_version, minor_version) + :canonical: cryptography.x509.extensions.MSCertificateTemplate + + .. versionadded:: 41.0.0 + + The Microsoft certificate template extension is a proprietary Microsoft + PKI extension that is used to provide information about the template + associated with the certificate. + + .. attribute:: oid + + :type: :class:`ObjectIdentifier` + + Returns + :attr:`~cryptography.x509.oid.ExtensionOID.MS_CERTIFICATE_TEMPLATE`. + + .. attribute:: template_id + + :type: :class:`ObjectIdentifier` + + .. attribute:: major_version + + :type: int or None + + .. attribute:: minor_version + + :type: int or None + .. class:: CertificatePolicies(policies) :canonical: cryptography.x509.extensions.CertificatePolicies @@ -3504,6 +3532,12 @@ instances. The following common OIDs are available as constants. Corresponds to the dotted string ``"2.5.29.9"``. + .. attribute:: MS_CERTIFICATE_TEMPLATE + + .. versionadded:: 41.0.0 + + Corresponds to the dotted string ``"1.3.6.1.4.1.311.21.7"``. + .. class:: CRLEntryExtensionOID :canonical: cryptography.hazmat._oid.CRLEntryExtensionOID diff --git a/src/cryptography/hazmat/_oid.py b/src/cryptography/hazmat/_oid.py index 82a6498f92c2..908f6206db3f 100644 --- a/src/cryptography/hazmat/_oid.py +++ b/src/cryptography/hazmat/_oid.py @@ -40,6 +40,7 @@ class ExtensionOID: ) PRECERT_POISON = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3") SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5") + MS_CERTIFICATE_TEMPLATE = ObjectIdentifier("1.3.6.1.4.1.311.21.7") class OCSPExtensionOID: @@ -267,6 +268,7 @@ class AttributeOID: "signedCertificateTimestampList" ), ExtensionOID.PRECERT_POISON: "ctPoison", + ExtensionOID.MS_CERTIFICATE_TEMPLATE: "msCertificateTemplate", CRLEntryExtensionOID.CRL_REASON: "cRLReason", CRLEntryExtensionOID.INVALIDITY_DATE: "invalidityDate", CRLEntryExtensionOID.CERTIFICATE_ISSUER: "certificateIssuer", diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index 6d4a10eab579..d77694a29906 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -53,6 +53,7 @@ IssuerAlternativeName, IssuingDistributionPoint, KeyUsage, + MSCertificateTemplate, NameConstraints, NoticeReference, OCSPAcceptableResponses, @@ -250,4 +251,5 @@ "SignedCertificateTimestamps", "SignatureAlgorithmOID", "NameOID", + "MSCertificateTemplate", ] diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 981161a63b5b..ac99592f55a7 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -2122,6 +2122,65 @@ def public_bytes(self) -> bytes: return rust_x509.encode_extension_value(self) +class MSCertificateTemplate(ExtensionType): + oid = ExtensionOID.MS_CERTIFICATE_TEMPLATE + + def __init__( + self, + template_id: ObjectIdentifier, + major_version: typing.Optional[int], + minor_version: typing.Optional[int], + ) -> None: + if not isinstance(template_id, ObjectIdentifier): + raise TypeError("oid must be an ObjectIdentifier") + self._template_id = template_id + if ( + major_version is not None and not isinstance(major_version, int) + ) or ( + minor_version is not None and not isinstance(minor_version, int) + ): + raise TypeError( + "major_version and minor_version must be integers or None" + ) + self._major_version = major_version + self._minor_version = minor_version + + @property + def template_id(self) -> ObjectIdentifier: + return self._template_id + + @property + def major_version(self) -> typing.Optional[int]: + return self._major_version + + @property + def minor_version(self) -> typing.Optional[int]: + return self._minor_version + + def __repr__(self) -> str: + return ( + f"" + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, MSCertificateTemplate): + return NotImplemented + + return ( + self.template_id == other.template_id + and self.major_version == other.major_version + and self.minor_version == other.minor_version + ) + + def __hash__(self) -> int: + return hash((self.template_id, self.major_version, self.minor_version)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + class UnrecognizedExtension(ExtensionType): def __init__(self, oid: ObjectIdentifier, value: bytes) -> None: if not isinstance(oid, ObjectIdentifier): diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 160048436e24..838fa1a1c2ee 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -613,6 +613,13 @@ pub(crate) struct GeneralSubtree<'a> { pub maximum: Option, } +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub(crate) struct MSCertificateTemplate { + pub template_id: asn1::ObjectIdentifier, + pub major_version: Option, + pub minor_version: Option, +} + fn parse_general_subtrees( py: pyo3::Python<'_>, subtrees: SequenceOfSubtrees<'_>, @@ -985,6 +992,15 @@ pub fn parse_cert_ext<'p>( .call1((permitted_subtrees, excluded_subtrees))?, )) } + oid::MS_CERTIFICATE_TEMPLATE => { + let ms_cert_tpl = asn1::parse_single::(ext_data)?; + let py_oid = oid_to_py_oid(py, &ms_cert_tpl.template_id)?; + Ok(Some( + x509_module + .getattr(pyo3::intern!(py, "MSCertificateTemplate"))? + .call1((py_oid, ms_cert_tpl.major_version, ms_cert_tpl.minor_version))?, + )) + } _ => Ok(None), } } diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index cded8890dbac..7f143d852679 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -453,6 +453,15 @@ pub(crate) fn encode_extension( .extract::<&[u8]>()?; Ok(Some(asn1::write_single(&nonce)?)) } + &oid::MS_CERTIFICATE_TEMPLATE => { + let py_template_id = ext.getattr(pyo3::intern!(py, "template_id"))?; + let mstpl = certificate::MSCertificateTemplate { + template_id: py_oid_to_oid(py_template_id)?, + major_version: ext.getattr(pyo3::intern!(py, "major_version"))?.extract()?, + minor_version: ext.getattr(pyo3::intern!(py, "minor_version"))?.extract()?, + }; + Ok(Some(asn1::write_single(&mstpl)?)) + } _ => Ok(None), } } diff --git a/src/rust/src/x509/oid.rs b/src/rust/src/x509/oid.rs index 2c9b36d0a186..b2e3a36acd3e 100644 --- a/src/rust/src/x509/oid.rs +++ b/src/rust/src/x509/oid.rs @@ -6,6 +6,8 @@ pub(crate) const EXTENSION_REQUEST: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 14); pub(crate) const MS_EXTENSION_REQUEST: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 4, 1, 311, 2, 1, 14); +pub(crate) const MS_CERTIFICATE_TEMPLATE: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 311, 21, 7); pub(crate) const PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 2); pub(crate) const PRECERT_POISON_OID: asn1::ObjectIdentifier = diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 736c0113ec82..4a3fb26c63ad 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -4861,6 +4861,22 @@ def test_load_name_attribute_long_form_asn1_tag(self, backend): with pytest.raises(ValueError, match="Long-form"): cert.issuer + def test_ms_certificate_template(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "ms-certificate-template.pem"), + x509.load_pem_x509_certificate, + ) + ext = cert.extensions.get_extension_for_class( + x509.MSCertificateTemplate + ) + tpl = ext.value + assert isinstance(tpl, x509.MSCertificateTemplate) + assert tpl == x509.MSCertificateTemplate( + template_id=x509.ObjectIdentifier("1.2.3.4.5.6.7.8.9.0"), + major_version=1, + minor_version=None, + ) + def test_signature(self, backend): cert = _load_cert( os.path.join("x509", "ecdsa_root.pem"), diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py index d11ba3db0408..fd7ff957b1dd 100644 --- a/tests/x509/test_x509_ext.py +++ b/tests/x509/test_x509_ext.py @@ -6199,6 +6199,89 @@ def test_public_bytes(self): ) +class TestMSCertificateTemplate: + def test_invalid_type(self): + with pytest.raises(TypeError): + x509.MSCertificateTemplate( + "notanoid", None, None # type:ignore[arg-type] + ) + oid = x509.ObjectIdentifier("1.2.3.4") + with pytest.raises(TypeError): + x509.MSCertificateTemplate( + oid, "notanint", None # type:ignore[arg-type] + ) + with pytest.raises(TypeError): + x509.MSCertificateTemplate( + oid, None, "notanint" # type:ignore[arg-type] + ) + + def test_eq(self): + template1 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + template2 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + assert template1 == template2 + + def test_ne(self): + template1 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + template2 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), 1, None + ) + template3 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, 1 + ) + template4 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3"), None, None + ) + assert template1 != template2 + assert template1 != template3 + assert template1 != template4 + assert template1 != object() + + def test_repr(self): + template = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + assert repr(template) == ( + ", major_version=None, minor_version=None)>" + ) + + def test_hash(self): + template1 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + template2 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + template3 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, 1 + ) + template4 = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3"), None, None + ) + + assert hash(template1) == hash(template2) + assert hash(template1) != hash(template3) + assert hash(template1) != hash(template4) + + def test_public_bytes(self): + ext = x509.MSCertificateTemplate( + ObjectIdentifier("1.2.3.4"), None, None + ) + assert ext.public_bytes() == b"0\x05\x06\x03*\x03\x04" + + ext = x509.MSCertificateTemplate(ObjectIdentifier("1.2.3.4"), 1, 0) + assert ( + ext.public_bytes() + == b"0\x0b\x06\x03*\x03\x04\x02\x01\x01\x02\x01\x00" + ) + + def test_all_extension_oid_members_have_names_defined(): for oid in dir(ExtensionOID): if oid.startswith("__"): diff --git a/vectors/cryptography_vectors/x509/custom/ms-certificate-template.pem b/vectors/cryptography_vectors/x509/custom/ms-certificate-template.pem new file mode 100644 index 000000000000..ccf02e58a21f --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/ms-certificate-template.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBKDCB0KADAgECAgEBMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAlVTMB4XDTIz +MDEwMTEyMDEwMFoXDTMzMDEwMTEyMDEwMFowDTELMAkGA1UEBhMCVVMwWTATBgcq +hkjOPQIBBggqhkjOPQMBBwNCAARtDYTQ38TdHTMQb6pr7IAVcFjoW15DPK8V2rsR +kcOS2XJSWVpUkGttfUi1XQyVrIXDBA+Fma4s+lAHO5UrKtR9oyEwHzAdBgkrBgEE +AYI3FQcEEDAOBgkqAwQFBgcICQACAQEwCgYIKoZIzj0EAwIDRwAwRAIgcbUufnLk +Jd23LBlFM1fRhoW8wxi6VuwNCmFqx9n7E+gCIFPAi0/ZhTMyfK/X9BHVtR/B4r84 +R/YOuYr4MtmIMM4Q +-----END CERTIFICATE----- From 40c16dc1800002cf2c2c3046ef466bed2bcd7e37 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Apr 2023 11:32:50 +0800 Subject: [PATCH 595/827] OCSP responses are responses, not certificates (#8696) --- docs/x509/ocsp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/x509/ocsp.rst b/docs/x509/ocsp.rst index 603f9f6dd040..76bfc023f15f 100644 --- a/docs/x509/ocsp.rst +++ b/docs/x509/ocsp.rst @@ -329,7 +329,7 @@ Creating Responses :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`, :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey` or :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey` - that will be used to sign the certificate. + that will be used to sign the response. :param algorithm: The :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` that @@ -804,4 +804,4 @@ Interfaces :type: int - The serial number of the certificate that was checked. \ No newline at end of file + The serial number of the certificate that was checked. From 7d3f8a43d434be3c38d80969bbadcf4516afad82 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Apr 2023 12:13:55 +0800 Subject: [PATCH 596/827] we made WithSerialization an alias to the main types long ago (#8698) stop documenting them entirely --- CHANGELOG.rst | 44 +++++++------------ docs/hazmat/primitives/asymmetric/dh.rst | 21 --------- docs/hazmat/primitives/asymmetric/dsa.rst | 14 ------ docs/hazmat/primitives/asymmetric/ec.rst | 21 +-------- docs/hazmat/primitives/asymmetric/rsa.rst | 14 ------ .../primitives/asymmetric/serialization.rst | 26 +++++------ 6 files changed, 31 insertions(+), 109 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7e44bd9061e9..b1fb92e04c6f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1782,16 +1782,16 @@ Changelog ``no-comp`` (``OPENSSL_NO_COMP``) option. * Support :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER` serialization of public keys using the ``public_bytes`` method of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`, + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`, and - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`. * Support :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER` serialization of private keys using the ``private_bytes`` method of - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization`, + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, and - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`. * Add support for parsing X.509 certificate signing requests (CSRs) with :func:`~cryptography.x509.load_pem_x509_csr` and :func:`~cryptography.x509.load_der_x509_csr`. @@ -1864,42 +1864,32 @@ Changelog and :func:`~cryptography.hazmat.primitives.serialization.load_der_public_key` now support PKCS1 RSA public keys (in addition to the previous support for SubjectPublicKeyInfo format for RSA, EC, and DSA). -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization` - and deprecated ``EllipticCurvePrivateKeyWithNumbers``. +* Added ``EllipticCurvePrivateKeyWithSerialization`` and deprecated + ``EllipticCurvePrivateKeyWithNumbers``. * Added :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.private_bytes` to :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`. -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` - and deprecated ``RSAPrivateKeyWithNumbers``. +* Added ``RSAPrivateKeyWithSerialization`` and deprecated ``RSAPrivateKeyWithNumbers``. * Added :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.private_bytes` to :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`. -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization` - and deprecated ``DSAPrivateKeyWithNumbers``. +* Added ``DSAPrivateKeyWithSerialization`` and deprecated ``DSAPrivateKeyWithNumbers``. * Added :meth:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey.private_bytes` to :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization` - and deprecated ``RSAPublicKeyWithNumbers``. +* Added ``RSAPublicKeyWithSerialization`` and deprecated ``RSAPublicKeyWithNumbers``. * Added ``public_bytes`` to - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization`. -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization` - and deprecated ``EllipticCurvePublicKeyWithNumbers``. + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`. +* Added ``EllipticCurvePublicKeyWithSerialization`` and deprecated + ``EllipticCurvePublicKeyWithNumbers``. * Added ``public_bytes`` to - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization`. -* Added - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization` - and deprecated ``DSAPublicKeyWithNumbers``. + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`. +* Added ``DSAPublicKeyWithSerialization`` and deprecated ``DSAPublicKeyWithNumbers``. * Added ``public_bytes`` to - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`. * :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` and :class:`~cryptography.hazmat.primitives.hashes.HashContext` were moved from ``cryptography.hazmat.primitives.interfaces`` to diff --git a/docs/hazmat/primitives/asymmetric/dh.rst b/docs/hazmat/primitives/asymmetric/dh.rst index e880b8145899..361aa6dff82b 100644 --- a/docs/hazmat/primitives/asymmetric/dh.rst +++ b/docs/hazmat/primitives/asymmetric/dh.rst @@ -174,13 +174,6 @@ Group parameters :return bytes: Serialized parameters. -.. class:: DHParametersWithSerialization - - .. versionadded:: 1.7 - - Alias for :class:`DHParameters`. - - Key interfaces ~~~~~~~~~~~~~~ @@ -247,13 +240,6 @@ Key interfaces :return bytes: Serialized key. -.. class:: DHPrivateKeyWithSerialization - - .. versionadded:: 1.7 - - Alias for :class:`DHPrivateKey`. - - .. class:: DHPublicKey .. versionadded:: 1.7 @@ -293,13 +279,6 @@ Key interfaces :return bytes: Serialized key. -.. class:: DHPublicKeyWithSerialization - - .. versionadded:: 1.7 - - Alias for :class:`DHPublicKey`. - - Numbers ~~~~~~~ diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst index e70312cc3baa..5df80149bb9b 100644 --- a/docs/hazmat/primitives/asymmetric/dsa.rst +++ b/docs/hazmat/primitives/asymmetric/dsa.rst @@ -336,13 +336,6 @@ Key interfaces :return bytes: Serialized key. -.. class:: DSAPrivateKeyWithSerialization - - .. versionadded:: 0.8 - - Alias for :class:`DSAPrivateKey`. - - .. class:: DSAPublicKey .. versionadded:: 0.3 @@ -412,13 +405,6 @@ Key interfaces not validate. -.. class:: DSAPublicKeyWithSerialization - - .. versionadded:: 0.8 - - Alias for :class:`DSAPublicKey`. - - .. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography .. _`FIPS 186-4`: https://csrc.nist.gov/publications/detail/fips/186/4/final diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index 8da29eea142a..5842e9ca1667 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -534,11 +534,7 @@ Key Interfaces .. versionadded:: 0.5 - An elliptic curve private key for use with an algorithm such as `ECDSA`_ or - `EdDSA`_. An elliptic curve private key that is not an - :term:`opaque key` also implements - :class:`EllipticCurvePrivateKeyWithSerialization` to provide serialization - methods. + An elliptic curve private key for use with an algorithm such as `ECDSA`_. .. method:: exchange(algorithm, peer_public_key) @@ -632,13 +628,6 @@ Key Interfaces :return bytes: Serialized key. -.. class:: EllipticCurvePrivateKeyWithSerialization - - .. versionadded:: 0.8 - - Alias for :class:`EllipticCurvePrivateKey`. - - .. class:: EllipticCurvePublicKey .. versionadded:: 0.5 @@ -734,13 +723,6 @@ Key Interfaces :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`. -.. class:: EllipticCurvePublicKeyWithSerialization - - .. versionadded:: 0.6 - - Alias for :class:`EllipticCurvePublicKey`. - - Serialization ~~~~~~~~~~~~~ @@ -937,7 +919,6 @@ Elliptic Curve Object Identifiers .. _`minimize the number of security concerns for elliptic-curve cryptography`: https://cr.yp.to/ecdh/curve25519-20060209.pdf .. _`SafeCurves`: https://safecurves.cr.yp.to/ .. _`ECDSA`: https://en.wikipedia.org/wiki/ECDSA -.. _`EdDSA`: https://en.wikipedia.org/wiki/EdDSA .. _`forward secrecy`: https://en.wikipedia.org/wiki/Forward_secrecy .. _`SEC 1 v2.0`: https://www.secg.org/sec1-v2.pdf .. _`bad cryptographic practice`: https://crypto.stackexchange.com/a/3313 diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 7c268320ae21..23401f52793a 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -642,13 +642,6 @@ Key interfaces :return bytes: Serialized key. -.. class:: RSAPrivateKeyWithSerialization - - .. versionadded:: 0.8 - - Alias for :class:`RSAPrivateKey`. - - .. class:: RSAPublicKey .. versionadded:: 0.2 @@ -783,13 +776,6 @@ Key interfaces :raises cryptography.exceptions.UnsupportedAlgorithm: If signature data recovery is not supported with the provided ``padding`` type. -.. class:: RSAPublicKeyWithSerialization - - .. versionadded:: 0.8 - - Alias for :class:`RSAPublicKey`. - - .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem) .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography .. _`specific mathematical properties`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 5fb248b554f9..c60accca6b40 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -1219,12 +1219,12 @@ Serialization Formats An enumeration for private key formats. Used with the ``private_bytes`` method available on - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` , - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization` - , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKeyWithSerialization` + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKey` and - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`. .. attribute:: TraditionalOpenSSL @@ -1326,12 +1326,12 @@ Serialization Formats An enumeration for public key formats. Used with the ``public_bytes`` method available on - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization` + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` , - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization` - , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKeyWithSerialization` + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` + , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKey` , and - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`. .. attribute:: SubjectPublicKeyInfo @@ -1390,7 +1390,7 @@ Serialization Formats An enumeration for parameters formats. Used with the ``parameter_bytes`` method available on - :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHParametersWithSerialization`. + :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHParameters`. .. attribute:: PKCS3 @@ -1404,11 +1404,11 @@ Serialization Encodings An enumeration for encoding types. Used with the ``private_bytes`` method available on - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` , - :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization` - , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKeyWithSerialization`, - :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey` + , :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKey`, + :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, and :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey` as well as ``public_bytes`` on From 577c9bb7a89dd1fb0849311be0e765f04128f0a5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Apr 2023 20:13:21 +0800 Subject: [PATCH 597/827] support equality checks on all public asymmetric key types (#8700) * support equality checks on all public asymmetric key types * review feedback --- CHANGELOG.rst | 1 + .../hazmat/backends/openssl/backend.py | 4 ---- .../hazmat/backends/openssl/dh.py | 12 ++++++++++ .../hazmat/backends/openssl/dsa.py | 9 ++++++++ .../hazmat/backends/openssl/ec.py | 9 ++++++++ .../hazmat/backends/openssl/ed25519.py | 6 +++++ .../hazmat/backends/openssl/ed448.py | 6 +++++ .../hazmat/backends/openssl/rsa.py | 9 ++++++++ .../hazmat/primitives/asymmetric/dh.py | 6 +++++ .../hazmat/primitives/asymmetric/dsa.py | 6 +++++ .../hazmat/primitives/asymmetric/ec.py | 6 +++++ .../hazmat/primitives/asymmetric/ed25519.py | 6 +++++ .../hazmat/primitives/asymmetric/ed448.py | 6 +++++ .../hazmat/primitives/asymmetric/rsa.py | 6 +++++ .../hazmat/primitives/asymmetric/x25519.py | 6 +++++ .../hazmat/primitives/asymmetric/x448.py | 6 +++++ src/rust/src/backend/x25519.rs | 12 ++++++++++ src/rust/src/backend/x448.rs | 12 ++++++++++ src/rust/src/x509/ocsp_resp.rs | 17 +++++++------- tests/hazmat/primitives/test_dh.py | 22 +++++++++++++++++++ tests/hazmat/primitives/test_dsa.py | 12 ++++++++++ tests/hazmat/primitives/test_ec.py | 15 ++++++++++++- tests/hazmat/primitives/test_ed25519.py | 18 +++++++++++++++ tests/hazmat/primitives/test_ed448.py | 18 +++++++++++++++ tests/hazmat/primitives/test_rsa.py | 12 ++++++++++ tests/hazmat/primitives/test_x25519.py | 20 +++++++++++++++++ tests/hazmat/primitives/test_x448.py | 20 +++++++++++++++++ 27 files changed, 269 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b1fb92e04c6f..9387ea6a9c0e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,7 @@ Changelog OCSP extension. * Added support for the :class:`~cryptography.x509.MSCertificateTemplate` proprietary Microsoft certificate extension. +* Implemented support for equality checks on all asymmetric public key types. .. _v40-0-1: diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index adda33285676..9c414e1a9c83 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1049,10 +1049,6 @@ def _ossl2cert(self, x509_ptr: typing.Any) -> x509.Certificate: self.openssl_assert(res == 1) return x509.load_der_x509_certificate(self._read_mem_bio(bio)) - def _check_keys_correspond(self, key1, key2) -> None: - if self._lib.EVP_PKEY_cmp(key1._evp_pkey, key2._evp_pkey) != 1: - raise ValueError("Keys do not correspond") - def _load_key( self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation ) -> PrivateKeyTypes: diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py index 6c1889bc3ac2..42a92bcc1cd6 100644 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ b/src/cryptography/hazmat/backends/openssl/dh.py @@ -261,6 +261,18 @@ def __init__(self, backend: Backend, dh_cdata, evp_pkey): def key_size(self) -> int: return self._key_size_bits + def __eq__(self, other: object) -> bool: + if not isinstance(other, _DHPublicKey): + return NotImplemented + + res = self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + if res < 0: + # DH public keys have two types (DH, DHX) that OpenSSL + # considers different types but we do not. Mismatched types + # push an error on the stack, so we need to consume it. + self._backend._consume_errors() + return res == 1 + def public_numbers(self) -> dh.DHPublicNumbers: p = self._backend._ffi.new("BIGNUM **") g = self._backend._ffi.new("BIGNUM **") diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py index be0500152aeb..411a80820e85 100644 --- a/src/cryptography/hazmat/backends/openssl/dsa.py +++ b/src/cryptography/hazmat/backends/openssl/dsa.py @@ -189,6 +189,15 @@ def __init__(self, backend: Backend, dsa_cdata, evp_pkey): def key_size(self) -> int: return self._key_size + def __eq__(self, other: object) -> bool: + if not isinstance(other, _DSAPublicKey): + return NotImplemented + + return ( + self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + == 1 + ) + def public_numbers(self) -> dsa.DSAPublicNumbers: p = self._backend._ffi.new("BIGNUM **") q = self._backend._ffi.new("BIGNUM **") diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 90a7b6fa3fc1..9821bd193e29 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -235,6 +235,15 @@ def curve(self) -> ec.EllipticCurve: def key_size(self) -> int: return self.curve.key_size + def __eq__(self, other: object) -> bool: + if not isinstance(other, _EllipticCurvePublicKey): + return NotImplemented + + return ( + self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + == 1 + ) + def public_numbers(self) -> ec.EllipticCurvePublicNumbers: group = self._backend._lib.EC_KEY_get0_group(self._ec_key) self._backend.openssl_assert(group != self._backend._ffi.NULL) diff --git a/src/cryptography/hazmat/backends/openssl/ed25519.py b/src/cryptography/hazmat/backends/openssl/ed25519.py index 4e33a78f35f3..72678c87721c 100644 --- a/src/cryptography/hazmat/backends/openssl/ed25519.py +++ b/src/cryptography/hazmat/backends/openssl/ed25519.py @@ -78,6 +78,12 @@ def verify(self, signature: bytes, data: bytes) -> None: self._backend._consume_errors() raise exceptions.InvalidSignature + def __eq__(self, other: object) -> bool: + if not isinstance(other, Ed25519PublicKey): + return NotImplemented + + return self.public_bytes_raw() == other.public_bytes_raw() + class _Ed25519PrivateKey(Ed25519PrivateKey): def __init__(self, backend: Backend, evp_pkey): diff --git a/src/cryptography/hazmat/backends/openssl/ed448.py b/src/cryptography/hazmat/backends/openssl/ed448.py index b2300367697c..1f829420d143 100644 --- a/src/cryptography/hazmat/backends/openssl/ed448.py +++ b/src/cryptography/hazmat/backends/openssl/ed448.py @@ -79,6 +79,12 @@ def verify(self, signature: bytes, data: bytes) -> None: self._backend._consume_errors() raise exceptions.InvalidSignature + def __eq__(self, other: object) -> bool: + if not isinstance(other, Ed448PublicKey): + return NotImplemented + + return self.public_bytes_raw() == other.public_bytes_raw() + class _Ed448PrivateKey(Ed448PrivateKey): def __init__(self, backend: Backend, evp_pkey): diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index f8ca3341af85..ef27d4ead570 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -537,6 +537,15 @@ def __init__(self, backend: Backend, rsa_cdata, evp_pkey): def key_size(self) -> int: return self._key_size + def __eq__(self, other: object) -> bool: + if not isinstance(other, _RSAPublicKey): + return NotImplemented + + return ( + self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + == 1 + ) + def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: return _enc_dec_rsa(self._backend, self, plaintext, padding) diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index 272cc5e54671..02feb5f2ed4c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -200,6 +200,12 @@ def public_bytes( Returns the key serialized as bytes. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + DHPublicKeyWithSerialization = DHPublicKey diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index e846d3e83a9c..1ebfcd52ad13 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -120,6 +120,12 @@ def verify( Verifies the signature of the data. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + DSAPublicKeyWithSerialization = DSAPublicKey diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 2e3b0108b194..ddfaabf4f3e4 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -184,6 +184,12 @@ def from_encoded_point( return backend.load_elliptic_curve_public_bytes(curve, data) + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index 83aa9d310e85..1e435fece6eb 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -51,6 +51,12 @@ def verify(self, signature: bytes, data: bytes) -> None: Verify the signature. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + class Ed25519PrivateKey(metaclass=abc.ABCMeta): @classmethod diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed448.py b/src/cryptography/hazmat/primitives/asymmetric/ed448.py index c2a64796c2f4..40c7e090257e 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -48,6 +48,12 @@ def verify(self, signature: bytes, data: bytes) -> None: Verify the signature. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + class Ed448PrivateKey(metaclass=abc.ABCMeta): @classmethod diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index c83f7fc88999..b740f01f7c4c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -118,6 +118,12 @@ def recover_data_from_signature( Recovers the original data from the signature. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + RSAPublicKeyWithSerialization = RSAPublicKey diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index 5455751508c4..699054c9689b 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -41,6 +41,12 @@ def public_bytes_raw(self) -> bytes: Equivalent to public_bytes(Raw, Raw). """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + # For LibreSSL if hasattr(rust_openssl, "x25519"): diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index 06b55d44b2a6..abf7848550b8 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -41,6 +41,12 @@ def public_bytes_raw(self) -> bytes: Equivalent to public_bytes(Raw, Raw). """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + if hasattr(rust_openssl, "x448"): X448PublicKey.register(rust_openssl.x448.X448PublicKey) diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 9cd86b00af8f..a20e7092beb8 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -127,6 +127,18 @@ impl X25519PublicKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_public_bytes(py, &self.pkey, encoding, format) } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, X25519PublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } } pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index ff6d7f5b685c..1361b1da1bdd 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -127,6 +127,18 @@ impl X448PublicKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_public_bytes(py, &self.pkey, encoding, format) } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, X448PublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } } pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index cec07a2ffbd8..33eac6ed8bba 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -738,15 +738,16 @@ fn create_ocsp_response( let tbs_bytes = asn1::write_single(&tbs_response_data)?; let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; - py.import("cryptography.hazmat.backends.openssl.backend")? - .getattr(pyo3::intern!(py, "backend"))? - .call_method1( - "_check_keys_correspond", - ( - responder_cert.call_method0("public_key")?, - private_key.call_method0("public_key")?, + if !responder_cert + .call_method0("public_key")? + .eq(private_key.call_method0("public_key")?)? + { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Certificate public key and provided private key do not match", ), - )?; + )); + } py_certs = builder.getattr(pyo3::intern!(py, "_certs"))?.extract()?; let certs = py_certs.as_ref().map(|py_certs| { diff --git a/tests/hazmat/primitives/test_dh.py b/tests/hazmat/primitives/test_dh.py index 9a28d6114dc2..d47739ac07e8 100644 --- a/tests/hazmat/primitives/test_dh.py +++ b/tests/hazmat/primitives/test_dh.py @@ -464,6 +464,28 @@ def test_dh_vectors_with_q(self, backend, vector): assert int.from_bytes(symkey1, "big") == int(vector["z"], 16) assert int.from_bytes(symkey2, "big") == int(vector["z"], 16) + @pytest.mark.supported( + only_if=lambda backend: backend.dh_x942_serialization_supported(), + skip_message="DH X9.42 not supported", + ) + def test_public_key_equality(self, backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhpub.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + key_bytes_2 = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhpub_rfc5114_2.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + key1 = serialization.load_pem_public_key(key_bytes) + key2 = serialization.load_pem_public_key(key_bytes) + key3 = serialization.load_pem_public_key(key_bytes_2) + assert key1 == key2 + assert key1 != key3 + assert key1 != object() + @pytest.mark.supported( only_if=lambda backend: backend.dh_supported(), diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index a1814c08209d..b97d7634396e 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -384,6 +384,18 @@ def test_large_p(self, backend): x=pn.x, ).private_key(backend) + def test_public_key_equality(self, backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None).public_key() + key2 = serialization.load_pem_private_key(key_bytes, None).public_key() + key3 = DSA_KEY_2048.private_key().public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() + @pytest.mark.supported( only_if=lambda backend: backend.dsa_supported(), diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 142024459cf2..601edcc48bd4 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -565,7 +565,7 @@ def test_verify_prehashed_digest_mismatch(self, backend): ) -class TestECNumbersEquality: +class TestECEquality: def test_public_numbers_eq(self): pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) assert pub == ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) @@ -601,6 +601,19 @@ def test_private_numbers_ne(self): ) assert priv != object() + def test_public_key_equality(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None).public_key() + key2 = serialization.load_pem_private_key(key_bytes, None).public_key() + key3 = ec.generate_private_key(ec.SECP256R1()).public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() + class TestECSerialization: @pytest.mark.parametrize( diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 5833c5c327b9..ca27544c730c 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -247,3 +247,21 @@ def test_buffer_protocol(self, backend): ) == private_bytes ) + + +@pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", +) +def test_public_key_equality(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed25519", "ed25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + key2 = serialization.load_der_private_key(key_bytes, None).public_key() + key3 = Ed25519PrivateKey.generate().public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index ac915c79953c..5658b2b00821 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -260,3 +260,21 @@ def test_malleability(self, backend): key = Ed448PublicKey.from_public_bytes(public_bytes) with pytest.raises(InvalidSignature): key.verify(signature, b"8") + + +@pytest.mark.supported( + only_if=lambda backend: backend.ed448_supported(), + skip_message="Requires OpenSSL with Ed448 support", +) +def test_public_key_equality(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed448", "ed448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + key2 = serialization.load_der_private_key(key_bytes, None).public_key() + key3 = Ed448PrivateKey.generate().public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 36e65359bf51..017e02d424b2 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -2763,3 +2763,15 @@ def test_public_bytes_rejects_invalid( key = rsa_key_2048.public_key() with pytest.raises(ValueError): key.public_bytes(encoding, fmt) + + def test_public_key_equality(self, rsa_key_2048: rsa.RSAPrivateKey): + key1 = rsa_key_2048.public_key() + key2 = RSA_KEY_2048.private_key( + unsafe_skip_rsa_key_validation=True + ).public_key() + key3 = RSA_KEY_2048_ALT.private_key( + unsafe_skip_rsa_key_validation=True + ).public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index 3eb642df5542..21cc55edfc03 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -317,3 +317,23 @@ def test_buffer_protocol(self, backend): ) == private_bytes ) + + +@pytest.mark.supported( + only_if=lambda backend: backend.x25519_supported(), + skip_message="Requires OpenSSL with X25519 support", +) +def test_public_key_equality(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X25519", "x25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + key2 = serialization.load_der_private_key(key_bytes, None).public_key() + key3 = X25519PrivateKey.generate().public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 3e6506732b5f..c9d92112b698 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -253,3 +253,23 @@ def test_buffer_protocol(self, backend): ) == private_bytes ) + + +@pytest.mark.supported( + only_if=lambda backend: backend.x448_supported(), + skip_message="Requires OpenSSL with X448 support", +) +def test_public_key_equality(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X448", "x448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + key2 = serialization.load_der_private_key(key_bytes, None).public_key() + key3 = X448PrivateKey.generate().public_key() + assert key1 == key2 + assert key1 != key3 + assert key1 != object() + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] From f8e929a22599c7c312785ac686bfada1d525c9c6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 10 Apr 2023 08:28:50 -0400 Subject: [PATCH 598/827] Fix alpine installation docs (#8701) --- docs/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.rst b/docs/installation.rst index 0023187f9b7d..7bbdddcba2e6 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -106,7 +106,7 @@ Alpine .. warning:: - The Rust available by default in Alpine < 3.14 is older than the minimum + The Rust available by default in Alpine < 3.15 is older than the minimum supported version. See the :ref:`Rust installation instructions ` for information about installing a newer Rust. From 253a97a34b2a66e6df50ac04be1a3197fead60e6 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Apr 2023 20:34:46 +0800 Subject: [PATCH 599/827] update docs for rust versions in debian and rhel (#8702) --- docs/installation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 7bbdddcba2e6..896baf8f6d1d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -121,8 +121,8 @@ Debian/Ubuntu .. warning:: - The Rust available in some Debian versions is older than the minimum - supported version. Debian Bullseye is sufficiently new, but otherwise + The Rust available in most Debian versions is older than the minimum + supported version. Debian Bookworm is sufficiently new, but otherwise please see the :ref:`Rust installation instructions ` for information about installing a newer Rust. @@ -136,7 +136,7 @@ Fedora/RHEL/CentOS .. warning:: - For RHEL and CentOS you must be on version 8.3 or newer for the command + For RHEL and CentOS you must be on version 8.6 or newer for the command below to install a sufficiently new Rust. If your Rust is less than 1.56.0 please see the :ref:`Rust installation instructions ` for information about installing a newer Rust. From d5db3d4bfcf69b5916c7e1513953acef288ab8dd Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 10 Apr 2023 08:39:03 -0400 Subject: [PATCH 600/827] Added extra test cases for Ed25519 serialization (#8703) --- tests/hazmat/primitives/test_ed25519.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index ca27544c730c..6d03332f292e 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -177,6 +177,13 @@ def test_invalid_private_bytes(self, backend): serialization.NoEncryption(), ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.DER, + serialization.PrivateFormat.OpenSSH, + serialization.NoEncryption(), + ) + def test_invalid_public_bytes(self, backend): key = Ed25519PrivateKey.generate().public_key() with pytest.raises(ValueError): @@ -195,6 +202,11 @@ def test_invalid_public_bytes(self, backend): serialization.Encoding.PEM, serialization.PublicFormat.Raw ) + with pytest.raises(ValueError): + key.public_bytes( + serialization.Encoding.DER, serialization.PublicFormat.OpenSSH + ) + @pytest.mark.parametrize( ("encoding", "fmt", "encryption", "passwd", "load_func"), [ From f5c750deab0722ecfd18aa741259e2f1e279a1bc Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 10 Apr 2023 08:55:57 -0400 Subject: [PATCH 601/827] Convert ed25519 to Rust (#8697) --- .../hazmat/backends/openssl/backend.py | 65 +++---- .../hazmat/backends/openssl/ed25519.py | 163 ---------------- .../bindings/_rust/openssl/__init__.pyi | 10 +- .../hazmat/bindings/_rust/openssl/ed25519.pyi | 14 ++ .../hazmat/primitives/asymmetric/ed25519.py | 19 +- src/rust/src/backend/ed25519.rs | 181 ++++++++++++++++++ src/rust/src/backend/mod.rs | 5 + src/rust/src/backend/utils.rs | 45 +++++ src/rust/src/backend/x25519.rs | 17 +- src/rust/src/backend/x448.rs | 16 +- tests/hazmat/primitives/test_ed25519.py | 3 + 11 files changed, 320 insertions(+), 218 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/ed25519.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi create mode 100644 src/rust/src/backend/ed25519.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 9c414e1a9c83..896b0476a9f7 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -35,10 +35,6 @@ _Ed448PrivateKey, _Ed448PublicKey, ) -from cryptography.hazmat.backends.openssl.ed25519 import ( - _Ed25519PrivateKey, - _Ed25519PublicKey, -) from cryptography.hazmat.backends.openssl.hashes import _HashContext from cryptography.hazmat.backends.openssl.hmac import _HMACContext from cryptography.hazmat.backends.openssl.poly1305 import ( @@ -641,7 +637,9 @@ def _evp_pkey_to_private_key( return _DHPrivateKey(self, dh_cdata, evp_pkey) elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _Ed25519PrivateKey(self, evp_pkey) + return rust_openssl.ed25519.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return rust_openssl.x448.private_key_from_ptr( @@ -702,7 +700,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: return _DHPublicKey(self, dh_cdata, evp_pkey) elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _Ed25519PublicKey(self, evp_pkey) + return rust_openssl.ed25519.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL return rust_openssl.x448.public_key_from_ptr( @@ -1049,6 +1049,21 @@ def _ossl2cert(self, x509_ptr: typing.Any) -> x509.Certificate: self.openssl_assert(res == 1) return x509.load_der_x509_certificate(self._read_mem_bio(bio)) + def _key2ossl(self, key: PKCS12PrivateKeyTypes) -> typing.Any: + data = key.private_bytes( + serialization.Encoding.DER, + serialization.PrivateFormat.PKCS8, + serialization.NoEncryption(), + ) + mem_bio = self._bytes_to_bio(data) + + evp_pkey = self._lib.d2i_PrivateKey_bio( + mem_bio.bio, + self._ffi.NULL, + ) + self.openssl_assert(evp_pkey != self._ffi.NULL) + return self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + def _load_key( self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation ) -> PrivateKeyTypes: @@ -1848,38 +1863,15 @@ def ed25519_supported(self) -> bool: def ed25519_load_public_bytes( self, data: bytes ) -> ed25519.Ed25519PublicKey: - utils._check_bytes("data", data) - - if len(data) != ed25519._ED25519_KEY_SIZE: - raise ValueError("An Ed25519 public key is 32 bytes long") - - evp_pkey = self._lib.EVP_PKEY_new_raw_public_key( - self._lib.NID_ED25519, self._ffi.NULL, data, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - return _Ed25519PublicKey(self, evp_pkey) + return rust_openssl.ed25519.from_public_bytes(data) def ed25519_load_private_bytes( self, data: bytes ) -> ed25519.Ed25519PrivateKey: - if len(data) != ed25519._ED25519_KEY_SIZE: - raise ValueError("An Ed25519 private key is 32 bytes long") - - utils._check_byteslike("data", data) - data_ptr = self._ffi.from_buffer(data) - evp_pkey = self._lib.EVP_PKEY_new_raw_private_key( - self._lib.NID_ED25519, self._ffi.NULL, data_ptr, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - return _Ed25519PrivateKey(self, evp_pkey) + return rust_openssl.ed25519.from_private_bytes(data) def ed25519_generate_key(self) -> ed25519.Ed25519PrivateKey: - evp_pkey = self._evp_pkey_keygen_gc(self._lib.NID_ED25519) - return _Ed25519PrivateKey(self, evp_pkey) + return rust_openssl.ed25519.generate_key() def ed448_supported(self) -> bool: if self._fips_enabled: @@ -2207,15 +2199,14 @@ def serialize_key_and_certificates_to_pkcs12( with self._zeroed_null_terminated_buf(password) as password_buf: with self._zeroed_null_terminated_buf(name) as name_buf: ossl_cert = self._cert2ossl(cert) if cert else self._ffi.NULL - if key is not None: - evp_pkey = key._evp_pkey # type: ignore[union-attr] - else: - evp_pkey = self._ffi.NULL + ossl_pkey = ( + self._key2ossl(key) if key is not None else self._ffi.NULL + ) p12 = self._lib.PKCS12_create( password_buf, name_buf, - evp_pkey, + ossl_pkey, ossl_cert, sk_x509, nid_key, diff --git a/src/cryptography/hazmat/backends/openssl/ed25519.py b/src/cryptography/hazmat/backends/openssl/ed25519.py deleted file mode 100644 index 72678c87721c..000000000000 --- a/src/cryptography/hazmat/backends/openssl/ed25519.py +++ /dev/null @@ -1,163 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography import exceptions -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric.ed25519 import ( - _ED25519_KEY_SIZE, - _ED25519_SIG_SIZE, - Ed25519PrivateKey, - Ed25519PublicKey, -) - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -class _Ed25519PublicKey(Ed25519PublicKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PublicFormat.Raw - ): - if ( - encoding is not serialization.Encoding.Raw - or format is not serialization.PublicFormat.Raw - ): - raise ValueError( - "When using Raw both encoding and format must be Raw" - ) - - return self._raw_public_bytes() - - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def _raw_public_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE) - return self._backend._ffi.buffer(buf, _ED25519_KEY_SIZE)[:] - - def verify(self, signature: bytes, data: bytes) -> None: - evp_md_ctx = self._backend._lib.EVP_MD_CTX_new() - self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL) - evp_md_ctx = self._backend._ffi.gc( - evp_md_ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_DigestVerifyInit( - evp_md_ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._evp_pkey, - ) - self._backend.openssl_assert(res == 1) - res = self._backend._lib.EVP_DigestVerify( - evp_md_ctx, signature, len(signature), data, len(data) - ) - if res != 1: - self._backend._consume_errors() - raise exceptions.InvalidSignature - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Ed25519PublicKey): - return NotImplemented - - return self.public_bytes_raw() == other.public_bytes_raw() - - -class _Ed25519PrivateKey(Ed25519PrivateKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_key(self) -> Ed25519PublicKey: - buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE) - public_bytes = self._backend._ffi.buffer(buf)[:] - return self._backend.ed25519_load_public_bytes(public_bytes) - - def sign(self, data: bytes) -> bytes: - evp_md_ctx = self._backend._lib.EVP_MD_CTX_new() - self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL) - evp_md_ctx = self._backend._ffi.gc( - evp_md_ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_DigestSignInit( - evp_md_ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._evp_pkey, - ) - self._backend.openssl_assert(res == 1) - buf = self._backend._ffi.new("unsigned char[]", _ED25519_SIG_SIZE) - buflen = self._backend._ffi.new("size_t *", len(buf)) - res = self._backend._lib.EVP_DigestSign( - evp_md_ctx, buf, buflen, data, len(data) - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED25519_SIG_SIZE) - return self._backend._ffi.buffer(buf, buflen[0])[:] - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PrivateFormat.Raw - ): - if ( - format is not serialization.PrivateFormat.Raw - or encoding is not serialization.Encoding.Raw - or not isinstance( - encryption_algorithm, serialization.NoEncryption - ) - ): - raise ValueError( - "When using Raw both encoding and format must be Raw " - "and encryption_algorithm must be NoEncryption()" - ) - - return self._raw_private_bytes() - - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self, self._evp_pkey, None - ) - - def _raw_private_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_private_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE) - return self._backend._ffi.buffer(buf, _ED25519_KEY_SIZE)[:] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 31e682b9ae36..6ed6f17ade16 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -4,9 +4,15 @@ import typing -from cryptography.hazmat.bindings._rust.openssl import x448, x25519 +from cryptography.hazmat.bindings._rust.openssl import ed25519, x448, x25519 -__all__ = ["openssl_version", "raise_openssl_error", "x448", "x25519"] +__all__ = [ + "openssl_version", + "raise_openssl_error", + "ed25519", + "x448", + "x25519", +] def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi new file mode 100644 index 000000000000..c7f127f0b157 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import ed25519 + +class Ed25519PrivateKey: ... +class Ed25519PublicKey: ... + +def generate_key() -> ed25519.Ed25519PrivateKey: ... +def private_key_from_ptr(ptr: int) -> ed25519.Ed25519PrivateKey: ... +def public_key_from_ptr(ptr: int) -> ed25519.Ed25519PublicKey: ... +def from_private_bytes(data: bytes) -> ed25519.Ed25519PrivateKey: ... +def from_public_bytes(data: bytes) -> ed25519.Ed25519PublicKey: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index 1e435fece6eb..772e5de82362 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -7,6 +7,7 @@ import abc from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization _ED25519_KEY_SIZE = 32 @@ -36,14 +37,12 @@ def public_bytes( The serialized bytes of the public key. """ + @abc.abstractmethod def public_bytes_raw(self) -> bytes: """ The raw bytes of the public key. Equivalent to public_bytes(Raw, Raw). """ - return self.public_bytes( - _serialization.Encoding.Raw, _serialization.PublicFormat.Raw - ) @abc.abstractmethod def verify(self, signature: bytes, data: bytes) -> None: @@ -58,6 +57,10 @@ def __eq__(self, other: object) -> bool: """ +if hasattr(rust_openssl, "ed25519"): + Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey) + + class Ed25519PrivateKey(metaclass=abc.ABCMeta): @classmethod def generate(cls) -> Ed25519PrivateKey: @@ -100,19 +103,19 @@ def private_bytes( The serialized bytes of the private key. """ + @abc.abstractmethod def private_bytes_raw(self) -> bytes: """ The raw bytes of the private key. Equivalent to private_bytes(Raw, Raw, NoEncryption()). """ - return self.private_bytes( - _serialization.Encoding.Raw, - _serialization.PrivateFormat.Raw, - _serialization.NoEncryption(), - ) @abc.abstractmethod def sign(self, data: bytes) -> bytes: """ Signs the data. """ + + +if hasattr(rust_openssl, "x25519"): + Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey) diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs new file mode 100644 index 000000000000..a8d10c880e4c --- /dev/null +++ b/src/rust/src/backend/ed25519.rs @@ -0,0 +1,181 @@ +// 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. + +use crate::backend::utils; +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; +use foreign_types_shared::ForeignTypeRef; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed25519")] +struct Ed25519PrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed25519")] +struct Ed25519PublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyfunction] +fn generate_key() -> CryptographyResult { + Ok(Ed25519PrivateKey { + pkey: openssl::pkey::PKey::generate_ed25519()?, + }) +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> Ed25519PrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + Ed25519PrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> Ed25519PublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + Ed25519PublicKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn from_private_bytes(data: CffiBuf<'_>) -> pyo3::PyResult { + let pkey = openssl::pkey::PKey::private_key_from_raw_bytes( + data.as_bytes(), + openssl::pkey::Id::ED25519, + ) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An Ed25519 private key is 32 bytes long") + })?; + Ok(Ed25519PrivateKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_public_bytes(data: &[u8]) -> pyo3::PyResult { + let pkey = openssl::pkey::PKey::public_key_from_raw_bytes(data, openssl::pkey::Id::ED25519) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An Ed25519 public key is 32 bytes long") + })?; + Ok(Ed25519PublicKey { pkey }) +} + +#[pyo3::prelude::pymethods] +impl Ed25519PrivateKey { + fn sign<'p>( + &self, + py: pyo3::Python<'p>, + data: &[u8], + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut signer = openssl::sign::Signer::new_without_digest(&self.pkey)?; + Ok(pyo3::types::PyBytes::new_with(py, signer.len()?, |b| { + let n = signer + .sign_oneshot(b, data) + .map_err(CryptographyError::from)?; + assert_eq!(n, b.len()); + Ok(()) + })?) + } + + fn public_key(&self) -> CryptographyResult { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(Ed25519PublicKey { + pkey: openssl::pkey::PKey::public_key_from_raw_bytes( + &raw_bytes, + openssl::pkey::Id::ED25519, + )?, + }) + } + + fn private_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_private_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn private_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_private_bytes( + py, + &*slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + true, + ) + } +} + +#[pyo3::prelude::pymethods] +impl Ed25519PublicKey { + fn verify( + &self, + py: pyo3::Python<'_>, + signature: &[u8], + data: &[u8], + ) -> CryptographyResult<()> { + let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)? + .verify_oneshot(signature, data)?; + + if !valid { + return Err(CryptographyError::from(pyo3::PyErr::from_value( + py.import("cryptography.exceptions")? + .call_method1("InvalidSignature", ())?, + ))); + } + + Ok(()) + } + + fn public_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn public_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, true) + } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, Ed25519PublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "ed25519")?; + m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; + m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + + m.add_class::()?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index 82beb444a2cb..95aa08a6e2c3 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -2,6 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +#[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] +pub(crate) mod ed25519; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] @@ -10,6 +12,9 @@ pub(crate) mod x25519; pub(crate) mod x448; pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] + module.add_submodule(ed25519::create_module(module.py())?)?; + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(x25519::create_module(module.py())?)?; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] diff --git a/src/rust/src/backend/utils.rs b/src/rust/src/backend/utils.rs index 97b2b0c64a63..6b41a6548008 100644 --- a/src/rust/src/backend/utils.rs +++ b/src/rust/src/backend/utils.rs @@ -6,10 +6,12 @@ use crate::error::{CryptographyError, CryptographyResult}; pub(crate) fn pkey_private_bytes<'p>( py: pyo3::Python<'p>, + key_obj: &pyo3::PyAny, pkey: &openssl::pkey::PKey, encoding: &pyo3::PyAny, format: &pyo3::PyAny, encryption_algorithm: &pyo3::PyAny, + openssh_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let encoding_class: &pyo3::types::PyType = serialization_mod @@ -104,6 +106,28 @@ pub(crate) fn pkey_private_bytes<'p>( )); } + // OpenSSH + PEM + if openssh_allowed && format.is(private_format_class.getattr(pyo3::intern!(py, "OpenSSH"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { + return Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization.ssh" + ))? + .call_method1( + pyo3::intern!(py, "_serialize_ssh_private_key"), + (key_obj, password, encryption_algorithm), + )? + .extract()?); + } + + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "OpenSSH private key format can only be used with PEM encoding", + ), + )); + } + Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), )) @@ -111,9 +135,11 @@ pub(crate) fn pkey_private_bytes<'p>( pub(crate) fn pkey_public_bytes<'p>( py: pyo3::Python<'p>, + key_obj: &pyo3::PyAny, pkey: &openssl::pkey::PKey, encoding: &pyo3::PyAny, format: &pyo3::PyAny, + openssh_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; let encoding_class: &pyo3::types::PyType = serialization_mod @@ -170,6 +196,25 @@ pub(crate) fn pkey_public_bytes<'p>( )); } + // OpenSSH + OpenSSH + if openssh_allowed && format.is(public_format_class.getattr(pyo3::intern!(py, "OpenSSH"))?) { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "OpenSSH"))?) { + return Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization.ssh" + ))? + .call_method1(pyo3::intern!(py, "serialize_ssh_public_key"), (key_obj,))? + .extract()?); + } + + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "OpenSSH format must be used with OpenSSH encoding", + ), + )); + } + Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err("format is invalid with this key"), )) diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index a20e7092beb8..409f28c87a18 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -52,6 +52,7 @@ fn from_private_bytes(data: CffiBuf<'_>) -> pyo3::PyResult { })?; Ok(X25519PrivateKey { pkey }) } + #[pyo3::prelude::pyfunction] fn from_public_bytes(data: &[u8]) -> pyo3::PyResult { let pkey = openssl::pkey::PKey::public_key_from_raw_bytes(data, openssl::pkey::Id::X25519) @@ -99,13 +100,21 @@ impl X25519PrivateKey { } fn private_bytes<'p>( - &self, + slf: &pyo3::PyCell, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, format: &pyo3::PyAny, encryption_algorithm: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_private_bytes(py, &self.pkey, encoding, format, encryption_algorithm) + utils::pkey_private_bytes( + py, + &*slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + false, + ) } } @@ -120,12 +129,12 @@ impl X25519PublicKey { } fn public_bytes<'p>( - &self, + slf: &pyo3::PyCell, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &self.pkey, encoding, format) + utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, false) } fn __richcmp__( diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index 1361b1da1bdd..acfc9f2a0945 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -99,13 +99,21 @@ impl X448PrivateKey { } fn private_bytes<'p>( - &self, + slf: &pyo3::PyCell, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, format: &pyo3::PyAny, encryption_algorithm: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_private_bytes(py, &self.pkey, encoding, format, encryption_algorithm) + utils::pkey_private_bytes( + py, + &*slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + false, + ) } } @@ -120,12 +128,12 @@ impl X448PublicKey { } fn public_bytes<'p>( - &self, + slf: &pyo3::PyCell, py: pyo3::Python<'p>, encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &self.pkey, encoding, format) + utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, false) } fn __richcmp__( diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 6d03332f292e..7f847078c345 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -277,3 +277,6 @@ def test_public_key_equality(backend): assert key1 == key2 assert key1 != key3 assert key1 != object() + + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] From f82890de4d56d3277521554185b35f53bb90387d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 13:16:14 +0000 Subject: [PATCH 602/827] Bump pygments from 2.14.0 to 2.15.0 (#8704) Bumps [pygments](https://github.com/pygments/pygments) from 2.14.0 to 2.15.0. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](https://github.com/pygments/pygments/compare/2.14.0...2.15.0) --- updated-dependencies: - dependency-name: pygments dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index b6b9289cb6e2..ddb738150e4f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -98,7 +98,7 @@ pyenchant==3.2.2 # via # cryptography (pyproject.toml) # sphinxcontrib-spelling -pygments==2.14.0 +pygments==2.15.0 # via # readme-renderer # rich From cef2be76e891942205ffede30f64016de1b61644 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 10 Apr 2023 19:41:53 -0400 Subject: [PATCH 603/827] Convert ed448 to Rust (#8705) --- .../hazmat/backends/openssl/backend.py | 68 ++----- .../hazmat/backends/openssl/ed448.py | 164 ---------------- .../bindings/_rust/openssl/__init__.pyi | 8 +- .../hazmat/bindings/_rust/openssl/ed448.pyi | 14 ++ .../hazmat/primitives/asymmetric/ed448.py | 19 +- src/rust/src/backend/ed448.rs | 179 ++++++++++++++++++ src/rust/src/backend/mod.rs | 4 + tests/hazmat/primitives/test_ed448.py | 3 + 8 files changed, 231 insertions(+), 228 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/ed448.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi create mode 100644 src/rust/src/backend/ed448.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 896b0476a9f7..256f3a1c1645 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -30,11 +30,6 @@ _EllipticCurvePrivateKey, _EllipticCurvePublicKey, ) -from cryptography.hazmat.backends.openssl.ed448 import ( - _ED448_KEY_SIZE, - _Ed448PrivateKey, - _Ed448PublicKey, -) from cryptography.hazmat.backends.openssl.hashes import _HashContext from cryptography.hazmat.backends.openssl.hmac import _HMACContext from cryptography.hazmat.backends.openssl.poly1305 import ( @@ -651,7 +646,9 @@ def _evp_pkey_to_private_key( ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _Ed448PrivateKey(self, evp_pkey) + return rust_openssl.ed448.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) else: raise UnsupportedAlgorithm("Unsupported key type.") @@ -714,7 +711,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: ) elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return _Ed448PublicKey(self, evp_pkey) + return rust_openssl.ed448.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) else: raise UnsupportedAlgorithm("Unsupported key type.") @@ -1503,12 +1502,9 @@ def _private_key_bytes( write_bio = self._lib.PEM_write_bio_RSAPrivateKey elif key_type == self._lib.EVP_PKEY_DSA: write_bio = self._lib.PEM_write_bio_DSAPrivateKey - elif key_type == self._lib.EVP_PKEY_EC: - write_bio = self._lib.PEM_write_bio_ECPrivateKey else: - raise ValueError( - "Unsupported key type for TraditionalOpenSSL" - ) + assert key_type == self._lib.EVP_PKEY_EC + write_bio = self._lib.PEM_write_bio_ECPrivateKey return self._private_key_bytes_via_bio( write_bio, cdata, password ) @@ -1523,12 +1519,9 @@ def _private_key_bytes( write_bio = self._lib.i2d_RSAPrivateKey_bio elif key_type == self._lib.EVP_PKEY_EC: write_bio = self._lib.i2d_ECPrivateKey_bio - elif key_type == self._lib.EVP_PKEY_DSA: - write_bio = self._lib.i2d_DSAPrivateKey_bio else: - raise ValueError( - "Unsupported key type for TraditionalOpenSSL" - ) + assert key_type == self._lib.EVP_PKEY_DSA + write_bio = self._lib.i2d_DSAPrivateKey_bio return self._bio_func_output(write_bio, cdata) raise ValueError("Unsupported encoding for TraditionalOpenSSL") @@ -1817,19 +1810,6 @@ def x25519_load_private_bytes( ) -> x25519.X25519PrivateKey: return rust_openssl.x25519.from_private_bytes(data) - def _evp_pkey_keygen_gc(self, nid): - evp_pkey_ctx = self._lib.EVP_PKEY_CTX_new_id(nid, self._ffi.NULL) - self.openssl_assert(evp_pkey_ctx != self._ffi.NULL) - evp_pkey_ctx = self._ffi.gc(evp_pkey_ctx, self._lib.EVP_PKEY_CTX_free) - res = self._lib.EVP_PKEY_keygen_init(evp_pkey_ctx) - self.openssl_assert(res == 1) - evp_ppkey = self._ffi.new("EVP_PKEY **") - res = self._lib.EVP_PKEY_keygen(evp_pkey_ctx, evp_ppkey) - self.openssl_assert(res == 1) - self.openssl_assert(evp_ppkey[0] != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_ppkey[0], self._lib.EVP_PKEY_free) - return evp_pkey - def x25519_generate_key(self) -> x25519.X25519PrivateKey: return rust_openssl.x25519.generate_key() @@ -1882,35 +1862,13 @@ def ed448_supported(self) -> bool: ) def ed448_load_public_bytes(self, data: bytes) -> ed448.Ed448PublicKey: - utils._check_bytes("data", data) - if len(data) != _ED448_KEY_SIZE: - raise ValueError("An Ed448 public key is 57 bytes long") - - evp_pkey = self._lib.EVP_PKEY_new_raw_public_key( - self._lib.NID_ED448, self._ffi.NULL, data, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - return _Ed448PublicKey(self, evp_pkey) + return rust_openssl.ed448.from_public_bytes(data) def ed448_load_private_bytes(self, data: bytes) -> ed448.Ed448PrivateKey: - utils._check_byteslike("data", data) - if len(data) != _ED448_KEY_SIZE: - raise ValueError("An Ed448 private key is 57 bytes long") - - data_ptr = self._ffi.from_buffer(data) - evp_pkey = self._lib.EVP_PKEY_new_raw_private_key( - self._lib.NID_ED448, self._ffi.NULL, data_ptr, len(data) - ) - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - return _Ed448PrivateKey(self, evp_pkey) + return rust_openssl.ed448.from_private_bytes(data) def ed448_generate_key(self) -> ed448.Ed448PrivateKey: - evp_pkey = self._evp_pkey_keygen_gc(self._lib.NID_ED448) - return _Ed448PrivateKey(self, evp_pkey) + return rust_openssl.ed448.generate_key() def derive_scrypt( self, diff --git a/src/cryptography/hazmat/backends/openssl/ed448.py b/src/cryptography/hazmat/backends/openssl/ed448.py deleted file mode 100644 index 1f829420d143..000000000000 --- a/src/cryptography/hazmat/backends/openssl/ed448.py +++ /dev/null @@ -1,164 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography import exceptions -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric.ed448 import ( - Ed448PrivateKey, - Ed448PublicKey, -) - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - -_ED448_KEY_SIZE = 57 -_ED448_SIG_SIZE = 114 - - -class _Ed448PublicKey(Ed448PublicKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PublicFormat.Raw - ): - if ( - encoding is not serialization.Encoding.Raw - or format is not serialization.PublicFormat.Raw - ): - raise ValueError( - "When using Raw both encoding and format must be Raw" - ) - - return self._raw_public_bytes() - - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def _raw_public_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE) - return self._backend._ffi.buffer(buf, _ED448_KEY_SIZE)[:] - - def verify(self, signature: bytes, data: bytes) -> None: - evp_md_ctx = self._backend._lib.EVP_MD_CTX_new() - self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL) - evp_md_ctx = self._backend._ffi.gc( - evp_md_ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_DigestVerifyInit( - evp_md_ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._evp_pkey, - ) - self._backend.openssl_assert(res == 1) - res = self._backend._lib.EVP_DigestVerify( - evp_md_ctx, signature, len(signature), data, len(data) - ) - if res != 1: - self._backend._consume_errors() - raise exceptions.InvalidSignature - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Ed448PublicKey): - return NotImplemented - - return self.public_bytes_raw() == other.public_bytes_raw() - - -class _Ed448PrivateKey(Ed448PrivateKey): - def __init__(self, backend: Backend, evp_pkey): - self._backend = backend - self._evp_pkey = evp_pkey - - def public_key(self) -> Ed448PublicKey: - buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_public_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE) - public_bytes = self._backend._ffi.buffer(buf)[:] - return self._backend.ed448_load_public_bytes(public_bytes) - - def sign(self, data: bytes) -> bytes: - evp_md_ctx = self._backend._lib.EVP_MD_CTX_new() - self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL) - evp_md_ctx = self._backend._ffi.gc( - evp_md_ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_DigestSignInit( - evp_md_ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._evp_pkey, - ) - self._backend.openssl_assert(res == 1) - buf = self._backend._ffi.new("unsigned char[]", _ED448_SIG_SIZE) - buflen = self._backend._ffi.new("size_t *", len(buf)) - res = self._backend._lib.EVP_DigestSign( - evp_md_ctx, buf, buflen, data, len(data) - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED448_SIG_SIZE) - return self._backend._ffi.buffer(buf, buflen[0])[:] - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - if ( - encoding is serialization.Encoding.Raw - or format is serialization.PrivateFormat.Raw - ): - if ( - format is not serialization.PrivateFormat.Raw - or encoding is not serialization.Encoding.Raw - or not isinstance( - encryption_algorithm, serialization.NoEncryption - ) - ): - raise ValueError( - "When using Raw both encoding and format must be Raw " - "and encryption_algorithm must be NoEncryption()" - ) - - return self._raw_private_bytes() - - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self, self._evp_pkey, None - ) - - def _raw_private_bytes(self) -> bytes: - buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE) - buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE) - res = self._backend._lib.EVP_PKEY_get_raw_private_key( - self._evp_pkey, buf, buflen - ) - self._backend.openssl_assert(res == 1) - self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE) - return self._backend._ffi.buffer(buf, _ED448_KEY_SIZE)[:] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 6ed6f17ade16..aceb859c63c7 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -4,11 +4,17 @@ import typing -from cryptography.hazmat.bindings._rust.openssl import ed25519, x448, x25519 +from cryptography.hazmat.bindings._rust.openssl import ( + ed448, + ed25519, + x448, + x25519, +) __all__ = [ "openssl_version", "raise_openssl_error", + "ed448", "ed25519", "x448", "x25519", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi new file mode 100644 index 000000000000..1cf5f1773a0b --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import ed448 + +class Ed448PrivateKey: ... +class Ed448PublicKey: ... + +def generate_key() -> ed448.Ed448PrivateKey: ... +def private_key_from_ptr(ptr: int) -> ed448.Ed448PrivateKey: ... +def public_key_from_ptr(ptr: int) -> ed448.Ed448PublicKey: ... +def from_private_bytes(data: bytes) -> ed448.Ed448PrivateKey: ... +def from_public_bytes(data: bytes) -> ed448.Ed448PublicKey: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed448.py b/src/cryptography/hazmat/primitives/asymmetric/ed448.py index 40c7e090257e..a9a34b251b01 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -7,6 +7,7 @@ import abc from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization @@ -33,14 +34,12 @@ def public_bytes( The serialized bytes of the public key. """ + @abc.abstractmethod def public_bytes_raw(self) -> bytes: """ The raw bytes of the public key. Equivalent to public_bytes(Raw, Raw). """ - return self.public_bytes( - _serialization.Encoding.Raw, _serialization.PublicFormat.Raw - ) @abc.abstractmethod def verify(self, signature: bytes, data: bytes) -> None: @@ -55,6 +54,10 @@ def __eq__(self, other: object) -> bool: """ +if hasattr(rust_openssl, "ed448"): + Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey) + + class Ed448PrivateKey(metaclass=abc.ABCMeta): @classmethod def generate(cls) -> Ed448PrivateKey: @@ -102,13 +105,13 @@ def private_bytes( The serialized bytes of the private key. """ + @abc.abstractmethod def private_bytes_raw(self) -> bytes: """ The raw bytes of the private key. Equivalent to private_bytes(Raw, Raw, NoEncryption()). """ - return self.private_bytes( - _serialization.Encoding.Raw, - _serialization.PrivateFormat.Raw, - _serialization.NoEncryption(), - ) + + +if hasattr(rust_openssl, "x448"): + Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey) diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs new file mode 100644 index 000000000000..c0c7d0c6aa74 --- /dev/null +++ b/src/rust/src/backend/ed448.rs @@ -0,0 +1,179 @@ +// 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. + +use crate::backend::utils; +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; +use foreign_types_shared::ForeignTypeRef; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed448")] +struct Ed448PrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed448")] +struct Ed448PublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyfunction] +fn generate_key() -> CryptographyResult { + Ok(Ed448PrivateKey { + pkey: openssl::pkey::PKey::generate_ed448()?, + }) +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> Ed448PrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + Ed448PrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> Ed448PublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + Ed448PublicKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn from_private_bytes(data: CffiBuf<'_>) -> pyo3::PyResult { + let pkey = + openssl::pkey::PKey::private_key_from_raw_bytes(data.as_bytes(), openssl::pkey::Id::ED448) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An Ed448 private key is 56 bytes long") + })?; + Ok(Ed448PrivateKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_public_bytes(data: &[u8]) -> pyo3::PyResult { + let pkey = openssl::pkey::PKey::public_key_from_raw_bytes(data, openssl::pkey::Id::ED448) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("An Ed448 public key is 57 bytes long") + })?; + Ok(Ed448PublicKey { pkey }) +} + +#[pyo3::prelude::pymethods] +impl Ed448PrivateKey { + fn sign<'p>( + &self, + py: pyo3::Python<'p>, + data: &[u8], + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut signer = openssl::sign::Signer::new_without_digest(&self.pkey)?; + Ok(pyo3::types::PyBytes::new_with(py, signer.len()?, |b| { + let n = signer + .sign_oneshot(b, data) + .map_err(CryptographyError::from)?; + assert_eq!(n, b.len()); + Ok(()) + })?) + } + + fn public_key(&self) -> CryptographyResult { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(Ed448PublicKey { + pkey: openssl::pkey::PKey::public_key_from_raw_bytes( + &raw_bytes, + openssl::pkey::Id::ED448, + )?, + }) + } + + fn private_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_private_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn private_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_private_bytes( + py, + &*slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + true, + ) + } +} + +#[pyo3::prelude::pymethods] +impl Ed448PublicKey { + fn verify( + &self, + py: pyo3::Python<'_>, + signature: &[u8], + data: &[u8], + ) -> CryptographyResult<()> { + let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)? + .verify_oneshot(signature, data)?; + + if !valid { + return Err(CryptographyError::from(pyo3::PyErr::from_value( + py.import("cryptography.exceptions")? + .call_method1("InvalidSignature", ())?, + ))); + } + + Ok(()) + } + + fn public_bytes_raw<'p>( + &self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let raw_bytes = self.pkey.raw_public_key()?; + Ok(pyo3::types::PyBytes::new(py, &raw_bytes)) + } + + fn public_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, true) + } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, Ed448PublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "ed448")?; + m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; + m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + + m.add_class::()?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index 95aa08a6e2c3..d2d8cd478548 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -4,6 +4,8 @@ #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod ed25519; +#[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] +pub(crate) mod ed448; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] @@ -14,6 +16,8 @@ pub(crate) mod x448; pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(ed25519::create_module(module.py())?)?; + #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] + module.add_submodule(ed448::create_module(module.py())?)?; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(x25519::create_module(module.py())?)?; diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index 5658b2b00821..e88d3dce2ccc 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -278,3 +278,6 @@ def test_public_key_equality(backend): assert key1 == key2 assert key1 != key3 assert key1 != object() + + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] From ec7dbc4ee7e8c3ed9da71783b1f90d3904ec97d7 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 00:17:11 +0000 Subject: [PATCH 604/827] Bump BoringSSL and/or OpenSSL in CI (#8706) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac4c512496bb..ff830b85c935 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 08, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "44a389a7fce31013b5953038d4231f33cbf2ba9d"}} + # Latest commit on the BoringSSL master branch, as of Apr 11, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "0c069cbf33d6a682e97a12c74284901a9bcd66b9"}} # Latest commit on the OpenSSL master branch, as of Apr 07, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f309b3f6087db6c83126f8f227f1fc4984cf24b1"}} timeout-minutes: 15 From edf5bd5184cdb7c0df0eac5180bfa0818f62f517 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 11 Apr 2023 00:41:16 -0400 Subject: [PATCH 605/827] Remove unused parameter (#8707) --- src/cryptography/hazmat/backends/openssl/backend.py | 9 ++------- tests/hazmat/backends/test_openssl.py | 10 ---------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 256f3a1c1645..71215e6b4c24 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -422,20 +422,15 @@ def _bn_to_int(self, bn) -> int: val = int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big") return val - def _int_to_bn(self, num: int, bn=None): + def _int_to_bn(self, num: int): """ Converts a python integer to a BIGNUM. The returned BIGNUM will not be garbage collected (to support adding them to structs that take ownership of the object). Be sure to register it for GC if it will be discarded after use. """ - assert bn is None or bn != self._ffi.NULL - - if bn is None: - bn = self._ffi.NULL - binary = num.to_bytes(int(num.bit_length() / 8.0 + 1), "big") - bn_ptr = self._lib.BN_bin2bn(binary, len(binary), bn) + bn_ptr = self._lib.BN_bin2bn(binary, len(binary), self._ffi.NULL) self.openssl_assert(bn_ptr != self._ffi.NULL) return bn_ptr diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 572431ebbd4a..27a0b95286ce 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -161,16 +161,6 @@ def test_int_to_bn(self): assert bn assert backend._bn_to_int(bn) == value - def test_int_to_bn_inplace(self): - value = (2**4242) - 4242 - bn_ptr = backend._lib.BN_new() - assert bn_ptr != backend._ffi.NULL - bn_ptr = backend._ffi.gc(bn_ptr, backend._lib.BN_free) - bn = backend._int_to_bn(value, bn_ptr) - - assert bn == bn_ptr - assert backend._bn_to_int(bn_ptr) == value - def test_bn_to_int(self): bn = backend._int_to_bn(0) assert backend._bn_to_int(bn) == 0 From e9bf608d8c31d44c3f38f4c3d87008934b085baf Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 00:16:38 +0000 Subject: [PATCH 606/827] Bump BoringSSL and/or OpenSSL in CI (#8712) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff830b85c935..29a80d797a96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 11, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "0c069cbf33d6a682e97a12c74284901a9bcd66b9"}} - # Latest commit on the OpenSSL master branch, as of Apr 07, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "f309b3f6087db6c83126f8f227f1fc4984cf24b1"}} + # Latest commit on the BoringSSL master branch, as of Apr 12, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "7b9b9baa95449d49019f7ce45b94963f8763005f"}} + # Latest commit on the OpenSSL master branch, as of Apr 12, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "dfb8e185134df90fd3f21fb6ec625e7c295fdcea"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.0 From 58ac802727e96144503b5ed5480e2cfb2c83b6b7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 11 Apr 2023 20:19:48 -0400 Subject: [PATCH 607/827] Use pyo3::intern! comprehensively (#8711) --- src/rust/src/asn1.rs | 16 +++- src/rust/src/backend/ed25519.rs | 4 +- src/rust/src/backend/ed448.rs | 4 +- src/rust/src/backend/utils.rs | 10 ++- src/rust/src/buf.rs | 4 +- src/rust/src/error.rs | 2 +- src/rust/src/oid.rs | 4 +- src/rust/src/pkcs7.rs | 15 +++- src/rust/src/x509/certificate.rs | 80 ++++++++++++-------- src/rust/src/x509/common.rs | 86 ++++++++++++--------- src/rust/src/x509/crl.rs | 20 ++--- src/rust/src/x509/csr.rs | 55 ++++++++------ src/rust/src/x509/extensions.rs | 5 +- src/rust/src/x509/ocsp.rs | 6 +- src/rust/src/x509/ocsp_req.rs | 22 ++++-- src/rust/src/x509/ocsp_resp.rs | 40 ++++++---- src/rust/src/x509/sct.rs | 28 +++++-- src/rust/src/x509/sign.rs | 126 ++++++++++++++++++++++--------- 18 files changed, 337 insertions(+), 190 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 833a72031e16..53981ddac6e8 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -60,7 +60,7 @@ pub(crate) fn big_byte_slice_to_py_int<'p>( ) -> pyo3::PyResult<&'p pyo3::PyAny> { let int_type = py.get_type::(); let kwargs = [("signed", true)].into_py_dict(py); - int_type.call_method("from_bytes", (v, "big"), Some(kwargs)) + int_type.call_method(pyo3::intern!(py, "from_bytes"), (v, "big"), Some(kwargs)) } #[pyo3::prelude::pyfunction] @@ -91,8 +91,13 @@ pub(crate) fn py_uint_to_big_endian_bytes<'p>( // Round the length up so that we prefix an extra \x00. This ensures that // integers that'd have the high bit set in their first octet are not // encoded as negative in DER. - let n = v.call_method0("bit_length")?.extract::()? / 8 + 1; - v.call_method1("to_bytes", (n, "big"))?.extract() + let n = v + .call_method0(pyo3::intern!(py, "bit_length"))? + .extract::()? + / 8 + + 1; + v.call_method1(pyo3::intern!(py, "to_bytes"), (n, "big"))? + .extract() } pub(crate) fn encode_der_data<'p>( @@ -102,7 +107,10 @@ pub(crate) fn encode_der_data<'p>( encoding: &'p pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let encoding_class = py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "Encoding"))?; if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index a8d10c880e4c..09ed9ac10eff 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -128,8 +128,8 @@ impl Ed25519PublicKey { if !valid { return Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")? - .call_method1("InvalidSignature", ())?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1(pyo3::intern!(py, "InvalidSignature"), ())?, ))); } diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index c0c7d0c6aa74..db17a7062bfe 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -126,8 +126,8 @@ impl Ed448PublicKey { if !valid { return Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")? - .call_method1("InvalidSignature", ())?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1(pyo3::intern!(py, "InvalidSignature"), ())?, ))); } diff --git a/src/rust/src/backend/utils.rs b/src/rust/src/backend/utils.rs index 6b41a6548008..25b7a5b9f87e 100644 --- a/src/rust/src/backend/utils.rs +++ b/src/rust/src/backend/utils.rs @@ -13,7 +13,10 @@ pub(crate) fn pkey_private_bytes<'p>( encryption_algorithm: &pyo3::PyAny, openssh_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let serialization_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))?; let encoding_class: &pyo3::types::PyType = serialization_mod .getattr(pyo3::intern!(py, "Encoding"))? .extract()?; @@ -141,7 +144,10 @@ pub(crate) fn pkey_public_bytes<'p>( format: &pyo3::PyAny, openssh_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let serialization_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))?; let encoding_class: &pyo3::types::PyType = serialization_mod .getattr(pyo3::intern!(py, "Encoding"))? .extract()?; diff --git a/src/rust/src/buf.rs b/src/rust/src/buf.rs index b45e1b5c342e..b7afcf047da4 100644 --- a/src/rust/src/buf.rs +++ b/src/rust/src/buf.rs @@ -21,8 +21,8 @@ impl<'a> pyo3::conversion::FromPyObject<'a> for CffiBuf<'a> { let py = pyobj.py(); let (bufobj, ptrval): (&pyo3::PyAny, usize) = py - .import("cryptography.utils")? - .call_method1("_extract_buffer_length", (pyobj,))? + .import(pyo3::intern!(py, "cryptography.utils"))? + .call_method1(pyo3::intern!(py, "_extract_buffer_length"), (pyobj,))? .extract()?; let len = bufobj.len()?; diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index 1cabbb11a948..e484993cced7 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -64,7 +64,7 @@ impl From for pyo3::PyErr { CryptographyError::Py(py_error) => py_error, CryptographyError::OpenSSL(error_stack) => pyo3::Python::with_gil(|py| { let internal_error = py - .import("cryptography.exceptions") + .import(pyo3::intern!(py, "cryptography.exceptions")) .expect("Failed to import cryptography module") .getattr(pyo3::intern!(py, "InternalError")) .expect("Failed to get InternalError attribute"); diff --git a/src/rust/src/oid.rs b/src/rust/src/oid.rs index 23bdd7362dd0..f6dae6122bbf 100644 --- a/src/rust/src/oid.rs +++ b/src/rust/src/oid.rs @@ -31,9 +31,9 @@ impl ObjectIdentifier { py: pyo3::Python<'p>, ) -> pyo3::PyResult<&'p pyo3::PyAny> { let oid_names = py - .import("cryptography.hazmat._oid")? + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? .getattr(pyo3::intern!(py, "_OID_NAMES"))?; - oid_names.call_method1("get", (slf, "Unknown OID")) + oid_names.call_method1(pyo3::intern!(py, "get"), (slf, "Unknown OID")) } fn __deepcopy__(slf: pyo3::PyRef<'_, Self>, _memo: pyo3::PyObject) -> pyo3::PyRef<'_, Self> { diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 360c767b36cd..bb516143425f 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -132,7 +132,10 @@ fn sign_and_serialize<'p>( options: &'p pyo3::types::PyList, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let pkcs7_options = py - .import("cryptography.hazmat.primitives.serialization.pkcs7")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization.pkcs7" + ))? .getattr(pyo3::intern!(py, "PKCS7Options"))?; let raw_data: CffiBuf<'p> = builder.getattr(pyo3::intern!(py, "_data"))?.extract()?; @@ -293,7 +296,10 @@ fn sign_and_serialize<'p>( let ci_bytes = asn1::write_single(&content_info)?; let encoding_class = py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "Encoding"))?; if encoding.is(encoding_class.getattr(pyo3::intern!(py, "SMIME"))?) { @@ -303,7 +309,10 @@ fn sign_and_serialize<'p>( .collect::>() .join(","); let smime_encode = py - .import("cryptography.hazmat.primitives.serialization.pkcs7")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization.pkcs7" + ))? .getattr(pyo3::intern!(py, "_smime_encode"))?; Ok(smime_encode .call1((&*data_without_header, &*ci_bytes, mic_algs, text_mode))? diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 838fa1a1c2ee..6ccde6542cb3 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -122,7 +122,10 @@ impl Certificate { &asn1::write_single(&self.raw.borrow_value().tbs_cert.spki)?, ); Ok(py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "load_der_public_key"))? .call1((serialized,))?) } @@ -133,14 +136,14 @@ impl Certificate { algorithm: pyo3::PyObject, ) -> CryptographyResult<&'p pyo3::PyAny> { let hasher = py - .import("cryptography.hazmat.primitives.hashes")? + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? .getattr(pyo3::intern!(py, "Hash"))? .call1((algorithm,))?; // This makes an unnecessary copy. It'd be nice to get rid of it. let serialized = pyo3::types::PyBytes::new(py, &asn1::write_single(&self.raw.borrow_value())?); - hasher.call_method1("update", (serialized,))?; - Ok(hasher.call_method0("finalize")?) + hasher.call_method1(pyo3::intern!(py, "update"), (serialized,))?; + Ok(hasher.call_method0(pyo3::intern!(py, "finalize"))?) } fn public_bytes<'p>( @@ -266,19 +269,20 @@ impl Certificate { py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py - .import("cryptography.hazmat._oid")? + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")?.call_method1( - "UnsupportedAlgorithm", - (format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid - ),), - )?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + "UnsupportedAlgorithm", + (format!( + "Signature algorithm OID: {} not recognized", + self.raw.borrow_value().signature_alg.oid + ),), + )?, ))), } } @@ -290,7 +294,7 @@ impl Certificate { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, @@ -349,7 +353,7 @@ impl Certificate { } fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, CryptographyError> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; match version { 0 => Ok(x509_module .getattr(pyo3::intern!(py, "Version"))? @@ -421,7 +425,7 @@ fn load_der_x509_certificate( fn warn_if_negative_serial(py: pyo3::Python<'_>, bytes: &'_ [u8]) -> pyo3::PyResult<()> { if bytes[0] & 0x80 != 0 { let cryptography_warning = py - .import("cryptography.utils")? + .import(pyo3::intern!(py, "cryptography.utils"))? .getattr(pyo3::intern!(py, "DeprecatedIn36"))?; pyo3::PyErr::warn( py, @@ -498,7 +502,10 @@ fn parse_display_text( let py_bytes = pyo3::types::PyBytes::new(py, o.as_utf16_be_bytes()); // TODO: do the string conversion in rust perhaps Ok(py_bytes - .call_method1("decode", ("utf_16_be",))? + .call_method1( + pyo3::intern!(py, "decode"), + (pyo3::intern!(py, "utf_16_be"),), + )? .to_object(py)) } } @@ -508,7 +515,7 @@ fn parse_user_notice( py: pyo3::Python<'_>, un: UserNotice<'_>, ) -> Result { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let et = match un.explicit_text { Some(data) => parse_display_text(py, data)?, None => py.None(), @@ -521,13 +528,13 @@ fn parse_user_notice( numbers.append(big_byte_slice_to_py_int(py, num.as_bytes())?.to_object(py))?; } x509_module - .call_method1("NoticeReference", (org, numbers))? + .call_method1(pyo3::intern!(py, "NoticeReference"), (org, numbers))? .to_object(py) } None => py.None(), }; Ok(x509_module - .call_method1("UserNotice", (nr, et))? + .call_method1(pyo3::intern!(py, "UserNotice"), (nr, et))? .to_object(py)) } @@ -567,7 +574,7 @@ fn parse_policy_qualifiers<'a>( fn parse_cp(py: pyo3::Python<'_>, ext_data: &[u8]) -> Result { let cp = asn1::parse_single::>>(ext_data)?; - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let certificate_policies = pyo3::types::PyList::empty(py); for policyinfo in cp { let pi_oid = oid_to_py_oid(py, &policyinfo.policy_identifier)?.to_object(py); @@ -578,7 +585,7 @@ fn parse_cp(py: pyo3::Python<'_>, ext_data: &[u8]) -> Result py.None(), }; let pi = x509_module - .call_method1("PolicyInformation", (pi_oid, py_pqis))? + .call_method1(pyo3::intern!(py, "PolicyInformation"), (pi_oid, py_pqis))? .to_object(py); certificate_policies.append(pi)?; } @@ -697,7 +704,7 @@ fn parse_distribution_point( Some(aci) => x509::parse_general_names(py, aci.unwrap_read())?, None => py.None(), }; - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; Ok(x509_module .getattr(pyo3::intern!(py, "DistributionPoint"))? .call1((full_name, relative_name, reasons, crl_issuer))? @@ -722,7 +729,7 @@ pub(crate) fn parse_distribution_point_reasons( reasons: Option<&asn1::BitString<'_>>, ) -> Result { let reason_bit_mapping = py - .import("cryptography.x509.extensions")? + .import(pyo3::intern!(py, "cryptography.x509.extensions"))? .getattr(pyo3::intern!(py, "_REASON_BIT_MAPPING"))?; Ok(match reasons { Some(bs) => { @@ -743,7 +750,7 @@ pub(crate) fn encode_distribution_point_reasons( py_reasons: &pyo3::PyAny, ) -> pyo3::PyResult { let reason_flag_mapping = py - .import("cryptography.x509.extensions")? + .import(pyo3::intern!(py, "cryptography.x509.extensions"))? .getattr(pyo3::intern!(py, "_CRLREASONFLAGS"))?; let mut bits = vec![0, 0]; @@ -779,7 +786,7 @@ pub(crate) fn parse_authority_key_identifier<'p>( py: pyo3::Python<'p>, ext_data: &[u8], ) -> Result<&'p pyo3::PyAny, CryptographyError> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let aki = asn1::parse_single::>(ext_data)?; let serial = match aki.authority_cert_serial_number { Some(biguint) => big_byte_slice_to_py_int(py, biguint.as_bytes())?.to_object(py), @@ -798,7 +805,7 @@ pub(crate) fn parse_access_descriptions( py: pyo3::Python<'_>, ext_data: &[u8], ) -> Result { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let ads = pyo3::types::PyList::empty(py); let parsed = asn1::parse_single::>(ext_data)?; for access in parsed.unwrap_read().clone() { @@ -818,7 +825,7 @@ pub fn parse_cert_ext<'p>( oid: asn1::ObjectIdentifier, ext_data: &[u8], ) -> CryptographyResult> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; match oid { oid::SUBJECT_ALTERNATIVE_NAME_OID => { let gn_seq = @@ -842,7 +849,7 @@ pub fn parse_cert_ext<'p>( } oid::TLS_FEATURE_OID => { let tls_feature_type_to_enum = py - .import("cryptography.x509.extensions")? + .import(pyo3::intern!(py, "cryptography.x509.extensions"))? .getattr(pyo3::intern!(py, "_TLS_FEATURE_TYPE_TO_ENUM"))?; let features = pyo3::types::PyList::empty(py); @@ -920,9 +927,10 @@ pub fn parse_cert_ext<'p>( } oid::CERTIFICATE_POLICIES_OID => { let cp = parse_cp(py, ext_data)?; - Ok(Some( - x509_module.call_method1("CertificatePolicies", (cp,))?, - )) + Ok(Some(x509_module.call_method1( + pyo3::intern!(py, "CertificatePolicies"), + (cp,), + )?)) } oid::POLICY_CONSTRAINTS_OID => { let pc = asn1::parse_single::(ext_data)?; @@ -1029,7 +1037,10 @@ fn create_x509_certificate( hash_algorithm: &pyo3::PyAny, ) -> CryptographyResult { let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let serialization_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))?; let der_encoding = serialization_mod .getattr(pyo3::intern!(py, "Encoding"))? .getattr(pyo3::intern!(py, "DER"))?; @@ -1039,7 +1050,10 @@ fn create_x509_certificate( let spki_bytes = builder .getattr(pyo3::intern!(py, "_public_key"))? - .call_method1("public_bytes", (der_encoding, spki_format))? + .call_method1( + pyo3::intern!(py, "public_bytes"), + (der_encoding, spki_format), + )? .extract::<&[u8]>()?; let py_serial = builder diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index a4ac9b3d4cd9..3d4aec39cc71 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -103,7 +103,7 @@ pub(crate) fn encode_name_entry<'p>( py_name_entry: &'p pyo3::PyAny, ) -> CryptographyResult> { let asn1_type = py - .import("cryptography.x509.name")? + .import(pyo3::intern!(py, "cryptography.x509.name"))? .getattr(pyo3::intern!(py, "_ASN1Type"))?; let attr_type = py_name_entry.getattr(pyo3::intern!(py, "_type"))?; @@ -120,7 +120,7 @@ pub(crate) fn encode_name_entry<'p>( }; py_name_entry .getattr(pyo3::intern!(py, "value"))? - .call_method1("encode", (encoding,))? + .call_method1(pyo3::intern!(py, "encode"), (encoding,))? .extract()? } else { py_name_entry @@ -228,7 +228,7 @@ pub(crate) fn encode_general_name<'a>( py: pyo3::Python<'a>, gn: &'a pyo3::PyAny, ) -> Result, CryptographyError> { - let gn_module = py.import("cryptography.x509.general_name")?; + let gn_module = py.import(pyo3::intern!(py, "cryptography.x509.general_name"))?; let gn_type = gn.get_type().as_ref(); let gn_value = gn.getattr(pyo3::intern!(py, "value"))?; if gn_type.is(gn_module.getattr(pyo3::intern!(py, "DNSName"))?) { @@ -258,7 +258,8 @@ pub(crate) fn encode_general_name<'a>( )) } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "IPAddress"))?) { Ok(GeneralName::IPAddress( - gn.call_method0("_packed")?.extract::<&[u8]>()?, + gn.call_method0(pyo3::intern!(py, "_packed"))? + .extract::<&[u8]>()?, )) } else if gn_type.is(gn_module.getattr(pyo3::intern!(py, "RegisteredID"))?) { let oid = py_oid_to_oid(gn_value)?; @@ -341,23 +342,23 @@ pub(crate) fn parse_name<'p>( py: pyo3::Python<'p>, name: &Name<'_>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let py_rdns = pyo3::types::PyList::empty(py); for rdn in name.unwrap_read().clone() { let py_rdn = parse_rdn(py, &rdn)?; py_rdns.append(py_rdn)?; } - Ok(x509_module.call_method1("Name", (py_rdns,))?) + Ok(x509_module.call_method1(pyo3::intern!(py, "Name"), (py_rdns,))?) } fn parse_name_attribute( py: pyo3::Python<'_>, attribute: AttributeTypeValue<'_>, ) -> Result { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let oid = oid_to_py_oid(py, &attribute.type_id)?.to_object(py); let tag_enum = py - .import("cryptography.x509.name")? + .import(pyo3::intern!(py, "cryptography.x509.name"))? .getattr(pyo3::intern!(py, "_ASN1_TYPE_TO_ENUM"))?; let tag_val = attribute .value @@ -376,12 +377,12 @@ fn parse_name_attribute( // BMPString tag value Some(30) => { let py_bytes = pyo3::types::PyBytes::new(py, attribute.value.data()); - py_bytes.call_method1("decode", ("utf_16_be",))? + py_bytes.call_method1(pyo3::intern!(py, "decode"), ("utf_16_be",))? } // UniversalString Some(28) => { let py_bytes = pyo3::types::PyBytes::new(py, attribute.value.data()); - py_bytes.call_method1("decode", ("utf_32_be",))? + py_bytes.call_method1(pyo3::intern!(py, "decode"), ("utf_32_be",))? } _ => { let parsed = std::str::from_utf8(attribute.value.data()) @@ -391,7 +392,11 @@ fn parse_name_attribute( }; let kwargs = [("_validate", false)].into_py_dict(py); Ok(x509_module - .call_method("NameAttribute", (oid, py_data, py_tag), Some(kwargs))? + .call_method( + pyo3::intern!(py, "NameAttribute"), + (oid, py_data, py_tag), + Some(kwargs), + )? .to_object(py)) } @@ -399,14 +404,14 @@ pub(crate) fn parse_rdn<'a>( py: pyo3::Python<'_>, rdn: &asn1::SetOf<'a, AttributeTypeValue<'a>>, ) -> Result { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let py_attrs = pyo3::types::PySet::empty(py)?; for attribute in rdn.clone() { let na = parse_name_attribute(py, attribute)?; py_attrs.add(na)?; } Ok(x509_module - .call_method1("RelativeDistinguishedName", (py_attrs,))? + .call_method1(pyo3::intern!(py, "RelativeDistinguishedName"), (py_attrs,))? .to_object(py)) } @@ -414,38 +419,43 @@ pub(crate) fn parse_general_name( py: pyo3::Python<'_>, gn: GeneralName<'_>, ) -> Result { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let py_gn = match gn { GeneralName::OtherName(data) => { let oid = oid_to_py_oid(py, &data.type_id)?.to_object(py); x509_module - .call_method1("OtherName", (oid, data.value.full_data()))? + .call_method1( + pyo3::intern!(py, "OtherName"), + (oid, data.value.full_data()), + )? .to_object(py) } GeneralName::RFC822Name(data) => x509_module .getattr(pyo3::intern!(py, "RFC822Name"))? - .call_method1("_init_without_validation", (data.0,))? + .call_method1(pyo3::intern!(py, "_init_without_validation"), (data.0,))? .to_object(py), GeneralName::DNSName(data) => x509_module .getattr(pyo3::intern!(py, "DNSName"))? - .call_method1("_init_without_validation", (data.0,))? + .call_method1(pyo3::intern!(py, "_init_without_validation"), (data.0,))? .to_object(py), GeneralName::DirectoryName(data) => { let py_name = parse_name(py, &data)?; x509_module - .call_method1("DirectoryName", (py_name,))? + .call_method1(pyo3::intern!(py, "DirectoryName"), (py_name,))? .to_object(py) } GeneralName::UniformResourceIdentifier(data) => x509_module .getattr(pyo3::intern!(py, "UniformResourceIdentifier"))? - .call_method1("_init_without_validation", (data.0,))? + .call_method1(pyo3::intern!(py, "_init_without_validation"), (data.0,))? .to_object(py), GeneralName::IPAddress(data) => { - let ip_module = py.import("ipaddress")?; + let ip_module = py.import(pyo3::intern!(py, "ipaddress"))?; if data.len() == 4 || data.len() == 16 { - let addr = ip_module.call_method1("ip_address", (data,))?.to_object(py); + let addr = ip_module + .call_method1(pyo3::intern!(py, "ip_address"), (data,))? + .to_object(py); x509_module - .call_method1("IPAddress", (addr,))? + .call_method1(pyo3::intern!(py, "IPAddress"), (addr,))? .to_object(py) } else { // if it's not an IPv4 or IPv6 we assume it's an IPNetwork and @@ -456,7 +466,7 @@ pub(crate) fn parse_general_name( GeneralName::RegisteredID(data) => { let oid = oid_to_py_oid(py, &data)?.to_object(py); x509_module - .call_method1("RegisteredID", (oid,))? + .call_method1(pyo3::intern!(py, "RegisteredID"), (oid,))? .to_object(py) } _ => { @@ -487,8 +497,8 @@ fn create_ip_network( py: pyo3::Python<'_>, data: &[u8], ) -> Result { - let ip_module = py.import("ipaddress")?; - let x509_module = py.import("cryptography.x509")?; + let ip_module = py.import(pyo3::intern!(py, "ipaddress"))?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let prefix = match data.len() { 8 => { let num = u32::from_be_bytes(data[4..].try_into().unwrap()); @@ -512,9 +522,11 @@ fn create_ip_network( .extract::<&str>()?, prefix? ); - let addr = ip_module.call_method1("ip_network", (net,))?.to_object(py); + let addr = ip_module + .call_method1(pyo3::intern!(py, "ip_network"), (net,))? + .to_object(py); Ok(x509_module - .call_method1("IPAddress", (addr,))? + .call_method1(pyo3::intern!(py, "IPAddress"), (addr,))? .to_object(py)) } @@ -553,7 +565,7 @@ pub(crate) fn parse_and_cache_extensions< return Ok(cached.clone_ref(py)); } - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let exts = pyo3::types::PyList::empty(py); let mut seen_oids = HashSet::new(); if let Some(raw_exts) = raw_exts { @@ -572,17 +584,21 @@ pub(crate) fn parse_and_cache_extensions< let extn_value = match parse_ext(&raw_ext.extn_id, raw_ext.extn_value)? { Some(e) => e, - None => x509_module - .call_method1("UnrecognizedExtension", (oid_obj, raw_ext.extn_value))?, + None => x509_module.call_method1( + pyo3::intern!(py, "UnrecognizedExtension"), + (oid_obj, raw_ext.extn_value), + )?, }; - let ext_obj = - x509_module.call_method1("Extension", (oid_obj, raw_ext.critical, extn_value))?; + let ext_obj = x509_module.call_method1( + pyo3::intern!(py, "Extension"), + (oid_obj, raw_ext.critical, extn_value), + )?; exts.append(ext_obj)?; seen_oids.insert(raw_ext.extn_id); } } let extensions = x509_module - .call_method1("Extensions", (exts,))? + .call_method1(pyo3::intern!(py, "Extensions"), (exts,))? .to_object(py); *cached_extensions = Some(extensions.clone_ref(py)); Ok(extensions) @@ -601,7 +617,7 @@ pub(crate) fn encode_extensions< encode_ext: F, ) -> pyo3::PyResult>> { let unrecognized_extension_type: &pyo3::types::PyType = py - .import("cryptography.x509")? + .import(pyo3::intern!(py, "cryptography.x509"))? .getattr(pyo3::intern!(py, "UnrecognizedExtension"))? .extract()?; @@ -670,7 +686,7 @@ pub(crate) fn datetime_to_py<'p>( py: pyo3::Python<'p>, dt: &asn1::DateTime, ) -> pyo3::PyResult<&'p pyo3::PyAny> { - let datetime_module = py.import("datetime")?; + let datetime_module = py.import(pyo3::intern!(py, "datetime"))?; datetime_module .getattr(pyo3::intern!(py, "datetime"))? .call1(( diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 50beb85ecda2..f5ab1b0c02da 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -24,7 +24,7 @@ fn load_der_x509_crl( let version = raw.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module .getattr(pyo3::intern!(py, "InvalidVersion"))? @@ -174,12 +174,14 @@ impl CertificateRevocationList { py: pyo3::Python<'p>, algorithm: pyo3::PyObject, ) -> pyo3::PyResult<&'p pyo3::PyAny> { - let hashes_mod = py.import("cryptography.hazmat.primitives.hashes")?; + let hashes_mod = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; let h = hashes_mod .getattr(pyo3::intern!(py, "Hash"))? .call1((algorithm,))?; - h.call_method1("update", (self.public_bytes_der()?.as_slice(),))?; - h.call_method0("finalize") + + let data = self.public_bytes_der()?; + h.call_method1(pyo3::intern!(py, "update"), (data.as_slice(),))?; + h.call_method0(pyo3::intern!(py, "finalize")) } #[getter] @@ -193,8 +195,8 @@ impl CertificateRevocationList { py: pyo3::Python<'p>, ) -> pyo3::PyResult<&'p pyo3::PyAny> { let oid = self.signature_algorithm_oid(py)?; - let oid_module = py.import("cryptography.hazmat._oid")?; - let exceptions_module = py.import("cryptography.exceptions")?; + let oid_module = py.import(pyo3::intern!(py, "cryptography.hazmat._oid"))?; + let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; match oid_module .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))? .get_item(oid) @@ -264,7 +266,7 @@ impl CertificateRevocationList { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, @@ -579,7 +581,7 @@ pub(crate) fn parse_crl_reason_flags<'p>( py: pyo3::Python<'p>, reason: &CRLReason, ) -> CryptographyResult<&'p pyo3::PyAny> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let flag_name = match reason.value() { 0 => "unspecified", 1 => "key_compromise", @@ -610,7 +612,7 @@ pub fn parse_crl_entry_ext<'p>( oid: asn1::ObjectIdentifier, data: &[u8], ) -> CryptographyResult> { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; match oid { oid::CRL_REASON_OID => { let flags = parse_crl_reason_flags(py, &asn1::parse_single::(data)?)?; diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index d9eeb400ac66..2122018e069c 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -119,7 +119,10 @@ impl CertificateSigningRequest { &asn1::write_single(&self.raw.borrow_value().csr_info.spki)?, ); Ok(py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "load_der_public_key"))? .call1((serialized,))?) } @@ -152,19 +155,20 @@ impl CertificateSigningRequest { py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py - .import("cryptography.hazmat._oid")? + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")?.call_method1( - "UnsupportedAlgorithm", - (format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid - ),), - )?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + "UnsupportedAlgorithm", + (format!( + "Signature algorithm OID: {} not recognized", + self.raw.borrow_value().signature_alg.oid + ),), + )?, ))), } } @@ -190,7 +194,7 @@ impl CertificateSigningRequest { oid: &pyo3::PyAny, ) -> pyo3::PyResult<&'p pyo3::PyAny> { let cryptography_warning = py - .import("cryptography.utils")? + .import(pyo3::intern!(py, "cryptography.utils"))? .getattr(pyo3::intern!(py, "DeprecatedIn36"))?; pyo3::PyErr::warn( py, @@ -225,10 +229,11 @@ impl CertificateSigningRequest { } } Err(pyo3::PyErr::from_value( - py.import("cryptography.x509")?.call_method1( - "AttributeNotFound", - (format!("No {} attribute was found", oid), oid), - )?, + py.import(pyo3::intern!(py, "cryptography.x509"))? + .call_method1( + "AttributeNotFound", + (format!("No {} attribute was found", oid), oid), + )?, )) } @@ -253,12 +258,12 @@ impl CertificateSigningRequest { )) })?; let pyattr = py - .import("cryptography.x509")? - .call_method1("Attribute", (oid, serialized, tag))?; + .import(pyo3::intern!(py, "cryptography.x509"))? + .call_method1(pyo3::intern!(py, "Attribute"), (oid, serialized, tag))?; pyattrs.append(pyattr)?; } - py.import("cryptography.x509")? - .call_method1("Attributes", (pyattrs,)) + py.import(pyo3::intern!(py, "cryptography.x509"))? + .call_method1(pyo3::intern!(py, "Attributes"), (pyattrs,)) } #[getter] @@ -313,7 +318,7 @@ fn load_der_x509_csr( let version = raw.borrow_value().csr_info.version; if version != 0 { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; return Err(CryptographyError::from(pyo3::PyErr::from_value( x509_module .getattr(pyo3::intern!(py, "InvalidVersion"))? @@ -335,7 +340,10 @@ fn create_x509_csr( hash_algorithm: &pyo3::PyAny, ) -> CryptographyResult { let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; - let serialization_mod = py.import("cryptography.hazmat.primitives.serialization")?; + let serialization_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))?; let der_encoding = serialization_mod .getattr(pyo3::intern!(py, "Encoding"))? .getattr(pyo3::intern!(py, "DER"))?; @@ -344,8 +352,11 @@ fn create_x509_csr( .getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?; let spki_bytes = private_key - .call_method0("public_key")? - .call_method1("public_bytes", (der_encoding, spki_format))? + .call_method0(pyo3::intern!(py, "public_key"))? + .call_method1( + pyo3::intern!(py, "public_bytes"), + (der_encoding, spki_format), + )? .extract::<&[u8]>()?; let mut attrs = vec![]; diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 7f143d852679..84009b0c7c48 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -379,7 +379,10 @@ pub(crate) fn encode_extension( &oid::CRL_REASON_OID => { let value = ext .py() - .import("cryptography.hazmat.backends.openssl.decode_asn1")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.backends.openssl.decode_asn1" + ))? .getattr(pyo3::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? .get_item(ext.getattr(pyo3::intern!(py, "reason"))?)? .extract::()?; diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index 2b10291b8c1e..e3568ca9df8b 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -99,9 +99,9 @@ pub(crate) fn hash_data<'p>( data: &[u8], ) -> pyo3::PyResult<&'p [u8]> { let hash = py - .import("cryptography.hazmat.primitives.hashes")? + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? .getattr(pyo3::intern!(py, "Hash"))? .call1((py_hash_alg,))?; - hash.call_method1("update", (data,))?; - hash.call_method0("finalize")?.extract() + hash.call_method1(pyo3::intern!(py, "update"), (data,))?; + hash.call_method0(pyo3::intern!(py, "finalize"))?.extract() } diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 0eef4bccb2ef..afd939d478f4 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -84,11 +84,11 @@ impl OCSPRequest { ) -> Result<&'p pyo3::PyAny, CryptographyError> { let cert_id = self.cert_id(); - let hashes = py.import("cryptography.hazmat.primitives.hashes")?; + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => { - let exceptions = py.import("cryptography.exceptions")?; + let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? @@ -112,7 +112,7 @@ impl OCSPRequest { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, @@ -127,7 +127,9 @@ impl OCSPRequest { // the nonce. So we try parsing as a TLV and fall back to just using // the raw value. let nonce = asn1::parse_single::<&[u8]>(value).unwrap_or(value); - Ok(Some(x509_module.call_method1("OCSPNonce", (nonce,))?)) + Ok(Some( + x509_module.call_method1(pyo3::intern!(py, "OCSPNonce"), (nonce,))?, + )) } oid::ACCEPTABLE_RESPONSES_OID => { let oids = asn1::parse_single::< @@ -138,9 +140,10 @@ impl OCSPRequest { py_oids.append(oid_to_py_oid(py, &oid)?)?; } - Ok(Some( - x509_module.call_method1("OCSPAcceptableResponses", (py_oids,))?, - )) + Ok(Some(x509_module.call_method1( + pyo3::intern!(py, "OCSPAcceptableResponses"), + (py_oids,), + )?)) } _ => Ok(None), } @@ -154,7 +157,10 @@ impl OCSPRequest { encoding: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "Encoding"))? .getattr(pyo3::intern!(py, "DER"))?; if !encoding.is(der) { diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 33eac6ed8bba..0b2cab5f0b07 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -132,7 +132,7 @@ impl OCSPResponse { assert_eq!(status, UNAUTHORIZED_RESPONSE); "UNAUTHORIZED" }; - py.import("cryptography.x509.ocsp")? + py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))? .getattr(pyo3::intern!(py, "OCSPResponseStatus"))? .getattr(attr) } @@ -173,7 +173,7 @@ impl OCSPResponse { py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let sig_oids_to_hash = py - .import("cryptography.hazmat._oid")? + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { @@ -184,8 +184,8 @@ impl OCSPResponse { self.requires_successful_response()?.signature_algorithm.oid ); Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")? - .call_method1("UnsupportedAlgorithm", (exc_messsage,))?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1(pyo3::intern!(py, "UnsupportedAlgorithm"), (exc_messsage,))?, ))) } } @@ -310,7 +310,7 @@ impl OCSPResponse { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { self.requires_successful_response()?; - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, @@ -334,7 +334,9 @@ impl OCSPResponse { // the nonce. So we try parsing as a TLV and fall back to just using // the raw value. let nonce = asn1::parse_single::<&[u8]>(ext_data).unwrap_or(ext_data); - Ok(Some(x509_module.call_method1("OCSPNonce", (nonce,))?)) + Ok(Some( + x509_module.call_method1(pyo3::intern!(py, "OCSPNonce"), (nonce,))?, + )) } _ => Ok(None), } @@ -354,7 +356,7 @@ impl OCSPResponse { .response .get() .single_response()?; - let x509_module = py.import("cryptography.x509")?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_single_extensions, @@ -380,7 +382,10 @@ impl OCSPResponse { encoding: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let der = py - .import("cryptography.hazmat.primitives.serialization")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? .getattr(pyo3::intern!(py, "Encoding"))? .getattr(pyo3::intern!(py, "DER"))?; if !encoding.is(der) { @@ -522,7 +527,7 @@ impl SingleResponse<'_> { CertStatus::Revoked(_) => "REVOKED", CertStatus::Unknown(_) => "UNKNOWN", }; - py.import("cryptography.x509.ocsp")? + py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))? .getattr(pyo3::intern!(py, "OCSPCertStatus"))? .getattr(attr) } @@ -531,11 +536,11 @@ impl SingleResponse<'_> { &self, py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { - let hashes = py.import("cryptography.hazmat.primitives.hashes")?; + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; match ocsp::OIDS_TO_HASH.get(&self.cert_id.hash_algorithm.oid) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => { - let exceptions = py.import("cryptography.exceptions")?; + let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; Err(CryptographyError::from(pyo3::PyErr::from_value( exceptions .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? @@ -616,7 +621,7 @@ fn create_ocsp_response( let borrowed_cert; let py_certs: Option>>; let response_bytes = if response_status == SUCCESSFUL_RESPONSE { - let ocsp_mod = py.import("cryptography.x509.ocsp")?; + let ocsp_mod = py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))?; let py_single_resp = builder.getattr(pyo3::intern!(py, "_response"))?; py_cert = py_single_resp @@ -648,7 +653,10 @@ fn create_ocsp_response( .is_none() { let value = py - .import("cryptography.hazmat.backends.openssl.decode_asn1")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.backends.openssl.decode_asn1" + ))? .getattr(pyo3::intern!(py, "_CRL_ENTRY_REASON_ENUM_TO_CODE"))? .get_item(py_single_resp.getattr(pyo3::intern!(py, "_revocation_reason"))?)? .extract::()?; @@ -695,7 +703,7 @@ fn create_ocsp_response( .getattr(pyo3::intern!(py, "HASH"))?) { let sha1 = py - .import("cryptography.hazmat.primitives.hashes")? + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? .getattr(pyo3::intern!(py, "SHA1"))? .call0()?; ResponderId::ByKey(ocsp::hash_data( @@ -739,8 +747,8 @@ fn create_ocsp_response( let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; if !responder_cert - .call_method0("public_key")? - .eq(private_key.call_method0("public_key")?)? + .call_method0(pyo3::intern!(py, "public_key"))? + .eq(private_key.call_method0(pyo3::intern!(py, "public_key"))?)? { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( diff --git a/src/rust/src/x509/sct.rs b/src/rust/src/x509/sct.rs index 35ae088c0b85..a13785bf3fb1 100644 --- a/src/rust/src/x509/sct.rs +++ b/src/rust/src/x509/sct.rs @@ -164,9 +164,12 @@ impl Sct { #[getter] fn version<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - py.import("cryptography.x509.certificate_transparency")? - .getattr(pyo3::intern!(py, "Version"))? - .getattr(pyo3::intern!(py, "v1")) + py.import(pyo3::intern!( + py, + "cryptography.x509.certificate_transparency" + ))? + .getattr(pyo3::intern!(py, "Version"))? + .getattr(pyo3::intern!(py, "v1")) } #[getter] @@ -177,10 +180,13 @@ impl Sct { #[getter] fn timestamp<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let datetime_class = py - .import("datetime")? + .import(pyo3::intern!(py, "datetime"))? .getattr(pyo3::intern!(py, "datetime"))?; datetime_class - .call_method1("utcfromtimestamp", (self.timestamp / 1000,))? + .call_method1( + pyo3::intern!(py, "utcfromtimestamp"), + (self.timestamp / 1000,), + )? .call_method( "replace", (), @@ -191,7 +197,10 @@ impl Sct { #[getter] fn entry_type<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let et_class = py - .import("cryptography.x509.certificate_transparency")? + .import(pyo3::intern!( + py, + "cryptography.x509.certificate_transparency" + ))? .getattr(pyo3::intern!(py, "LogEntryType"))?; let attr_name = match self.entry_type { LogEntryType::Certificate => "X509_CERTIFICATE", @@ -205,14 +214,17 @@ impl Sct { &self, py: pyo3::Python<'p>, ) -> pyo3::PyResult<&'p pyo3::PyAny> { - let hashes_mod = py.import("cryptography.hazmat.primitives.hashes")?; + let hashes_mod = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; hashes_mod.call_method0(self.hash_algorithm.to_attr()) } #[getter] fn signature_algorithm<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let sa_class = py - .import("cryptography.x509.certificate_transparency")? + .import(pyo3::intern!( + py, + "cryptography.x509.certificate_transparency" + ))? .getattr(pyo3::intern!(py, "SignatureAlgorithm"))?; sa_class.getattr(self.signature_algorithm.to_attr()) } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index fb46c5c8fb1d..4be023bb2331 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -39,23 +39,38 @@ enum HashType { fn identify_key_type(py: pyo3::Python<'_>, private_key: &pyo3::PyAny) -> pyo3::PyResult { let rsa_private_key: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.rsa")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.rsa" + ))? .getattr(pyo3::intern!(py, "RSAPrivateKey"))? .extract()?; let dsa_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.dsa")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dsa" + ))? .getattr(pyo3::intern!(py, "DSAPrivateKey"))? .extract()?; let ec_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ec")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))? .getattr(pyo3::intern!(py, "EllipticCurvePrivateKey"))? .extract()?; let ed25519_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ed25519")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ed25519" + ))? .getattr(pyo3::intern!(py, "Ed25519PrivateKey"))? .extract()?; let ed448_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ed448")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ed448" + ))? .getattr(pyo3::intern!(py, "Ed448PrivateKey"))? .extract()?; @@ -85,7 +100,7 @@ fn identify_hash_type( } let hash_algorithm_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.hashes")? + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? .getattr(pyo3::intern!(py, "HashAlgorithm"))? .extract()?; if !hash_algorithm.is_instance(hash_algorithm_type)? { @@ -107,13 +122,14 @@ fn identify_hash_type( "sha3-384" => Ok(HashType::Sha3_384), "sha3-512" => Ok(HashType::Sha3_512), name => Err(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")?.call_method1( - "UnsupportedAlgorithm", - (format!( - "Hash algorithm {:?} not supported for signatures", - name - ),), - )?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + "UnsupportedAlgorithm", + (format!( + "Hash algorithm {:?} not supported for signatures", + name + ),), + )?, )), } } @@ -225,10 +241,11 @@ pub(crate) fn compute_signature_algorithm<'p>( KeyType::Dsa, HashType::Sha3_224 | HashType::Sha3_256 | HashType::Sha3_384 | HashType::Sha3_512, ) => Err(pyo3::PyErr::from_value( - py.import("cryptography.exceptions")?.call_method1( - "UnsupportedAlgorithm", - ("SHA3 hashes are not supported with DSA keys",), - )?, + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + "UnsupportedAlgorithm", + ("SHA3 hashes are not supported with DSA keys",), + )?, )), (_, HashType::None) => Err(pyo3::exceptions::PyTypeError::new_err( "Algorithm must be a registered hash algorithm, not None.", @@ -245,22 +262,32 @@ pub(crate) fn sign_data<'p>( let key_type = identify_key_type(py, private_key)?; let signature = match key_type { - KeyType::Ed25519 | KeyType::Ed448 => private_key.call_method1("sign", (data,))?, + KeyType::Ed25519 | KeyType::Ed448 => { + private_key.call_method1(pyo3::intern!(py, "sign"), (data,))? + } KeyType::Ec => { - let ec_mod = py.import("cryptography.hazmat.primitives.asymmetric.ec")?; + let ec_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))?; let ecdsa = ec_mod .getattr(pyo3::intern!(py, "ECDSA"))? .call1((hash_algorithm,))?; - private_key.call_method1("sign", (data, ecdsa))? + private_key.call_method1(pyo3::intern!(py, "sign"), (data, ecdsa))? } KeyType::Rsa => { - let padding_mod = py.import("cryptography.hazmat.primitives.asymmetric.padding")?; + let padding_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; let pkcs1v15 = padding_mod .getattr(pyo3::intern!(py, "PKCS1v15"))? .call0()?; - private_key.call_method1("sign", (data, pkcs1v15, hash_algorithm))? + private_key.call_method1(pyo3::intern!(py, "sign"), (data, pkcs1v15, hash_algorithm))? + } + KeyType::Dsa => { + private_key.call_method1(pyo3::intern!(py, "sign"), (data, hash_algorithm))? } - KeyType::Dsa => private_key.call_method1("sign", (data, hash_algorithm))?, }; signature.extract() } @@ -296,7 +323,7 @@ pub(crate) fn verify_signature_with_oid<'p>( )); } let sig_hash_name = py_hash_name_from_hash_type(sig_hash_type); - let hashes = py.import("cryptography.hazmat.primitives.hashes")?; + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; let signature_hash = match sig_hash_name { Some(data) => hashes.getattr(data)?.call0()?, None => py.None().into_ref(py), @@ -304,25 +331,35 @@ pub(crate) fn verify_signature_with_oid<'p>( match key_type { KeyType::Ed25519 | KeyType::Ed448 => { - issuer_public_key.call_method1("verify", (signature, data))? + issuer_public_key.call_method1(pyo3::intern!(py, "verify"), (signature, data))? } KeyType::Ec => { - let ec_mod = py.import("cryptography.hazmat.primitives.asymmetric.ec")?; + let ec_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))?; let ecdsa = ec_mod .getattr(pyo3::intern!(py, "ECDSA"))? .call1((signature_hash,))?; - issuer_public_key.call_method1("verify", (signature, data, ecdsa))? + issuer_public_key.call_method1(pyo3::intern!(py, "verify"), (signature, data, ecdsa))? } KeyType::Rsa => { - let padding_mod = py.import("cryptography.hazmat.primitives.asymmetric.padding")?; + let padding_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; let pkcs1v15 = padding_mod .getattr(pyo3::intern!(py, "PKCS1v15"))? .call0()?; - issuer_public_key.call_method1("verify", (signature, data, pkcs1v15, signature_hash))? - } - KeyType::Dsa => { - issuer_public_key.call_method1("verify", (signature, data, signature_hash))? + issuer_public_key.call_method1( + pyo3::intern!(py, "verify"), + (signature, data, pkcs1v15, signature_hash), + )? } + KeyType::Dsa => issuer_public_key.call_method1( + pyo3::intern!(py, "verify"), + (signature, data, signature_hash), + )?, }; Ok(()) } @@ -332,23 +369,38 @@ pub(crate) fn identify_public_key_type( public_key: &pyo3::PyAny, ) -> pyo3::PyResult { let rsa_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.rsa")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.rsa" + ))? .getattr(pyo3::intern!(py, "RSAPublicKey"))? .extract()?; let dsa_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.dsa")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dsa" + ))? .getattr(pyo3::intern!(py, "DSAPublicKey"))? .extract()?; let ec_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ec")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))? .getattr(pyo3::intern!(py, "EllipticCurvePublicKey"))? .extract()?; let ed25519_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ed25519")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ed25519" + ))? .getattr(pyo3::intern!(py, "Ed25519PublicKey"))? .extract()?; let ed448_key_type: &pyo3::types::PyType = py - .import("cryptography.hazmat.primitives.asymmetric.ed448")? + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ed448" + ))? .getattr(pyo3::intern!(py, "Ed448PublicKey"))? .extract()?; From a38b2bcfac0d61b995b5034e6b5f112b2cec428b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 12 Apr 2023 08:20:24 -0400 Subject: [PATCH 608/827] Remove unused consts (#8713) --- src/cryptography/hazmat/primitives/asymmetric/ed25519.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index 772e5de82362..f26e54d24ec5 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -10,9 +10,6 @@ from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization -_ED25519_KEY_SIZE = 32 -_ED25519_SIG_SIZE = 64 - class Ed25519PublicKey(metaclass=abc.ABCMeta): @classmethod From ce2951a1bed0e628720920e01b73ad3ff741f4ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 23:10:54 +0000 Subject: [PATCH 609/827] Bump rich from 13.3.3 to 13.3.4 (#8717) Bumps [rich](https://github.com/Textualize/rich) from 13.3.3 to 13.3.4. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.3...v13.3.4) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ddb738150e4f..95d4c8e7f39f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -131,7 +131,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.3.3 +rich==13.3.4 # via twine ruff==0.0.261 # via cryptography (pyproject.toml) From 35beedf25a073bf84434be6b816c8e93cb4ecd65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 23:11:11 +0000 Subject: [PATCH 610/827] Bump packaging from 23.0 to 23.1 (#8716) Bumps [packaging](https://github.com/pypa/packaging) from 23.0 to 23.1. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/23.0...23.1) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 95d4c8e7f39f..9668353db5a3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -73,7 +73,7 @@ mypy-extensions==1.0.0 # mypy nox==2022.11.21 # via cryptography (pyproject.toml) -packaging==23.0 +packaging==23.1 # via # black # build From 500fb88199175b196a89730d124a58f58666313c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 23:11:25 +0000 Subject: [PATCH 611/827] Bump actions/checkout from 3.5.0 to 3.5.1 (#8715) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.0...v3.5.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 4 ++-- .github/workflows/boring-open-version-bump.yml | 2 +- .github/workflows/ci.yml | 18 +++++++++--------- .github/workflows/wheel-builder.yml | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 325d4e81eb1a..fcc0acf06769 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,12 +20,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false path: "cryptography-pr" - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: repository: "pyca/cryptography" diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 5e96a3e3ba8a..927b826bdec9 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 - id: check-sha-boring run: | SHA=$(git ls-remote https://boringssl.googlesource.com/boringssl refs/heads/master | cut -f1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29a80d797a96..7eb2e8d22a27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "dfb8e185134df90fd3f21fb6ec625e7c295fdcea"}} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -158,7 +158,7 @@ jobs: sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release if: matrix.IMAGE.IMAGE == 'alpine:aarch64' - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -210,7 +210,7 @@ jobs: name: "${{ matrix.PYTHON }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -259,7 +259,7 @@ jobs: name: "Rust Coverage" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -369,7 +369,7 @@ jobs: RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -433,7 +433,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests"} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -506,7 +506,7 @@ jobs: name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false @@ -549,7 +549,7 @@ jobs: name: "linkcheck" timeout-minutes: 10 steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 with: persist-credentials: false fetch-depth: 0 @@ -582,7 +582,7 @@ jobs: needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 timeout-minutes: 3 with: persist-credentials: false diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 62af5f7d8322..9bd56612b73a 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest name: sdists steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} From 870bb7006c7c0b9c4c8c7e94f03fe992c85606d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 00:03:39 +0000 Subject: [PATCH 612/827] Bump actions/checkout from 3.5.0 to 3.5.1 in /.github/actions/wycheproof (#8714) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.0...v3.5.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/wycheproof/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/wycheproof/action.yml b/.github/actions/wycheproof/action.yml index a7f265e12f29..14ec46fdb57c 100644 --- a/.github/actions/wycheproof/action.yml +++ b/.github/actions/wycheproof/action.yml @@ -5,7 +5,7 @@ runs: using: "composite" steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v3.5.1 with: repository: "google/wycheproof" path: "wycheproof" From f0c37fb9c2e659ca213c98b1c7693c89daef85a6 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 00:19:02 +0000 Subject: [PATCH 613/827] Bump BoringSSL and/or OpenSSL in CI (#8718) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7eb2e8d22a27..3c86cc4388ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 12, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "7b9b9baa95449d49019f7ce45b94963f8763005f"}} - # Latest commit on the OpenSSL master branch, as of Apr 12, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "dfb8e185134df90fd3f21fb6ec625e7c295fdcea"}} + # Latest commit on the BoringSSL master branch, as of Apr 13, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "abfd5ebc87ddca0fab9fca067c9d7edbc355eae8"}} + # Latest commit on the OpenSSL master branch, as of Apr 13, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "40f4884990a1717755df366e2aa06d01a1affd63"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.1 From ed89e1219e7198e05c682e5a7db71fc70fa344a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 13:05:51 +0000 Subject: [PATCH 614/827] Bump actions/checkout from 3.5.1 to 3.5.2 (#8719) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.1 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.1...v3.5.2) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 4 ++-- .github/workflows/boring-open-version-bump.yml | 2 +- .github/workflows/ci.yml | 18 +++++++++--------- .github/workflows/wheel-builder.yml | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index fcc0acf06769..2353be18d900 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,12 +20,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false path: "cryptography-pr" - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: repository: "pyca/cryptography" diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index 927b826bdec9..c2625a51b801 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'pyca' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 - id: check-sha-boring run: | SHA=$(git ls-remote https://boringssl.googlesource.com/boringssl refs/heads/master | cut -f1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c86cc4388ac..c4e779915284 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "40f4884990a1717755df366e2aa06d01a1affd63"}} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -158,7 +158,7 @@ jobs: sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release if: matrix.IMAGE.IMAGE == 'alpine:aarch64' - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -210,7 +210,7 @@ jobs: name: "${{ matrix.PYTHON }} with Rust ${{ matrix.RUST }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -259,7 +259,7 @@ jobs: name: "Rust Coverage" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -369,7 +369,7 @@ jobs: RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -433,7 +433,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests"} timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -506,7 +506,7 @@ jobs: name: "Downstream tests for ${{ matrix.DOWNSTREAM }}" timeout-minutes: 15 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false @@ -549,7 +549,7 @@ jobs: name: "linkcheck" timeout-minutes: 10 steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 with: persist-credentials: false fetch-depth: 0 @@ -582,7 +582,7 @@ jobs: needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] if: ${{ always() }} steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 timeout-minutes: 3 with: persist-credentials: false diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 9bd56612b73a..c5446fcee0bb 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest name: sdists steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 with: # The tag to build or the tag received by the tag event ref: ${{ github.event.inputs.version || github.ref }} From 06fbca955fa0e370be863b157d55dd28e01b6fda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 13:16:37 +0000 Subject: [PATCH 615/827] Bump actions/checkout from 3.5.1 to 3.5.2 in /.github/actions/wycheproof (#8720) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.1 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.1...v3.5.2) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/wycheproof/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/wycheproof/action.yml b/.github/actions/wycheproof/action.yml index 14ec46fdb57c..6ededc54b15d 100644 --- a/.github/actions/wycheproof/action.yml +++ b/.github/actions/wycheproof/action.yml @@ -5,7 +5,7 @@ runs: using: "composite" steps: - - uses: actions/checkout@v3.5.1 + - uses: actions/checkout@v3.5.2 with: repository: "google/wycheproof" path: "wycheproof" From 77f94f031d207ea4338c013f278fff1463802cf6 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:24:28 +0800 Subject: [PATCH 616/827] Bump BoringSSL and/or OpenSSL in CI (#8721) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4e779915284..573966225335 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 13, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "abfd5ebc87ddca0fab9fca067c9d7edbc355eae8"}} - # Latest commit on the OpenSSL master branch, as of Apr 13, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "40f4884990a1717755df366e2aa06d01a1affd63"}} + # Latest commit on the BoringSSL master branch, as of Apr 14, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "298e6c2b9c97ca17ee8cf65d24819ec19420013c"}} + # Latest commit on the OpenSSL master branch, as of Apr 14, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "efbff4de3e259cee71a4e1bbd86b30ebd86bbdae"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 017c70454439caaafe2cb4f4b10b0c561f14f8c3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 14 Apr 2023 19:29:11 +0800 Subject: [PATCH 617/827] re-add a binding for an upcoming pyopenssl release (#8724) --- src/_cffi_src/openssl/ssl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 1b59e97ff083..c836be4f9f6d 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -254,6 +254,7 @@ unsigned int); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); int SSL_CTX_add_client_CA(SSL_CTX *, X509 *); void SSL_CTX_set_client_CA_list(SSL_CTX *, Cryptography_STACK_OF_X509_NAME *); From 746ce97a84e3bf519e80985c6729d9e1a38403e7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 14 Apr 2023 07:30:49 -0400 Subject: [PATCH 618/827] Compare benchmarks against the target branch, not main (#8726) * Compare benchmarks against the target branch, not main * Update benchmark.yml --- .github/workflows/benchmark.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 2353be18d900..abc595c97d93 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -2,6 +2,7 @@ name: Benchmark on: pull_request: paths: + - '.github/workflows/benchmark.yml' - 'src/**' - 'tests/**' @@ -30,7 +31,7 @@ jobs: with: repository: "pyca/cryptography" path: "cryptography-main" - ref: "main" + ref: "${{ github.base_ref }}" - name: Setup python id: setup-python From 7f8d0dcdf44d95663f1f83fe182b3e092e52f6ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:09:43 +0000 Subject: [PATCH 619/827] Bump pyo3 from 0.18.2 to 0.18.3 in /src/rust (#8734) Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.18.2 to 0.18.3. - [Release notes](https://github.com/pyo3/pyo3/releases) - [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md) - [Commits](https://github.com/pyo3/pyo3/compare/v0.18.2...v0.18.3) --- updated-dependencies: - dependency-name: pyo3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2cf3919ebc5a..c16a7fcecbdc 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb848f80438f926a9ebddf0a539ed6065434fd7aae03a89312a9821f81b8501" +checksum = "e3b1ac5b3731ba34fdaa9785f8d74d17448cd18f30cf19e0c7e7b1fdb5272109" dependencies = [ "cfg-if", "indoc", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98a42e7f42e917ce6664c832d5eee481ad514c98250c49e0b03b20593e2c7ed0" +checksum = "9cb946f5ac61bb61a5014924910d936ebd2b23b705f7a4a3c40b05c720b079a3" dependencies = [ "once_cell", "target-lexicon", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0707f0ab26826fe4ccd59b69106e9df5e12d097457c7b8f9c0fd1d2743eec4d" +checksum = "fd4d7c5337821916ea2a1d21d1092e8443cf34879e53a0ac653fbb98f44ff65c" dependencies = [ "libc", "pyo3-build-config", @@ -302,9 +302,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978d18e61465ecd389e1f235ff5a467146dc4e3c3968b90d274fe73a5dd4a438" +checksum = "a9d39c55dab3fc5a4b25bbd1ac10a2da452c4aca13bb450f22818a002e29648d" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e0e1128f85ce3fca66e435e08aa2089a2689c1c48ce97803e13f63124058462" +checksum = "97daff08a4c48320587b5224cc98d609e3c27b6d437315bd40b605c98eeb5918" dependencies = [ "proc-macro2", "quote", From 9f1130623ec1197b27b58ef0cb40a1319f4ea5e0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 14 Apr 2023 21:44:42 +0800 Subject: [PATCH 620/827] port 40.0.2 changelog (#8729) --- CHANGELOG.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9387ea6a9c0e..75cd3a49df57 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,14 @@ Changelog proprietary Microsoft certificate extension. * Implemented support for equality checks on all asymmetric public key types. +.. _v40-0-2: + +40.0.2 - 2023-04-14 +~~~~~~~~~~~~~~~~~~~ + +* Fixed compilation when using LibreSSL 3.7.2. +* Added some functions to support an upcoming ``pyOpenSSL`` release. + .. _v40-0-1: 40.0.1 - 2023-03-24 From 71efa27c1745d83fce801b02a01e8817ef4f6a89 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 14 Apr 2023 21:45:52 +0800 Subject: [PATCH 621/827] separate linkcheck job from ci.yml (#8730) --- .github/workflows/ci.yml | 33 ----------------------- .github/workflows/linkcheck.yml | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/linkcheck.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 573966225335..878431a99dbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -543,39 +543,6 @@ jobs: shell: python - run: ./.github/downstream.d/${{ matrix.DOWNSTREAM }}.sh run - docs-linkcheck: - if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'linkcheck')) - runs-on: ubuntu-latest - name: "linkcheck" - timeout-minutes: 10 - steps: - - uses: actions/checkout@v3.5.2 - with: - persist-credentials: false - fetch-depth: 0 - - name: set mtimes for rust dirs - uses: ./.github/actions/mtime-fix - - name: Setup python - id: setup-python - uses: actions/setup-python@v4.5.0 - with: - python-version: 3.11 - - name: Cache rust and pip - uses: ./.github/actions/cache - timeout-minutes: 2 - with: - # This creates the same key as the docs job (as long as they have the same - # python version) - key: 3.11-${{ steps.setup-python.outputs.python-version }} - - run: python -m pip install -c ci-constraints-requirements.txt nox - - name: Build nox environment - run: | - nox -v --install-only -s docs-linkcheck - env: - CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - - name: linkcheck - run: nox --no-install -s docs-linkcheck -- --color=yes - all-green: # https://github.community/t/is-it-possible-to-require-all-github-actions-tasks-to-pass-without-enumerating-them/117957/4?u=graingert runs-on: ubuntu-latest diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml new file mode 100644 index 000000000000..02457ec7bf18 --- /dev/null +++ b/.github/workflows/linkcheck.yml @@ -0,0 +1,46 @@ +name: linkcheck +on: + pull_request: {} + push: + branches: + - main + +permissions: + contents: read + +env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + +jobs: + docs-linkcheck: + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'linkcheck')) + runs-on: ubuntu-latest + name: "linkcheck" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3.5.2 + with: + persist-credentials: false + fetch-depth: 0 + - name: set mtimes for rust dirs + uses: ./.github/actions/mtime-fix + - name: Setup python + id: setup-python + uses: actions/setup-python@v4.5.0 + with: + python-version: 3.11 + - name: Cache rust and pip + uses: ./.github/actions/cache + timeout-minutes: 2 + with: + # This creates the same key as the docs job (as long as they have the same + # python version) + key: 3.11-${{ steps.setup-python.outputs.python-version }} + - run: python -m pip install -c ci-constraints-requirements.txt nox + - name: Build nox environment + run: | + nox -v --install-only -s docs-linkcheck + env: + CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} + - name: linkcheck + run: nox --no-install -s docs-linkcheck -- --color=yes \ No newline at end of file From c22b1d6fbe4c04ee1851208b782c0784cae3b648 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 14 Apr 2023 21:46:21 +0800 Subject: [PATCH 622/827] call it base instead of main (#8731) --- .github/workflows/benchmark.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index abc595c97d93..09745aa48ca8 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 3 with: repository: "pyca/cryptography" - path: "cryptography-main" + path: "cryptography-base" ref: "${{ github.base_ref }}" - name: Setup python @@ -39,19 +39,19 @@ jobs: with: python-version: "3.11" - - name: Create virtualenv (main) + - name: Create virtualenv (base) run: | - python -m venv .venv-main - .venv-main/bin/pip install -v -c ./cryptography-main/ci-constraints-requirements.txt "./cryptography-main[test]" ./cryptography-main/vectors/ + python -m venv .venv-base + .venv-base/bin/pip install -v -c ./cryptography-base/ci-constraints-requirements.txt "./cryptography-base[test]" ./cryptography-base/vectors/ - name: Create virtualenv (PR) run: | python -m venv .venv-pr .venv-pr/bin/pip install -v -c ./cryptography-pr/ci-constraints-requirements.txt "./cryptography-pr[test]" ./cryptography-pr/vectors/ - - name: Run benchmarks (main) - run: .venv-main/bin/pytest --benchmark-enable --benchmark-only ./cryptography-pr/tests/bench/ --benchmark-json=bench-main.json + - name: Run benchmarks (base) + run: .venv-base/bin/pytest --benchmark-enable --benchmark-only ./cryptography-pr/tests/bench/ --benchmark-json=bench-base.json - name: Run benchmarks (PR) run: .venv-pr/bin/pytest --benchmark-enable --benchmark-only ./cryptography-pr/tests/bench/ --benchmark-json=bench-pr.json - name: Compare results - run: python ./cryptography-pr/.github/compare_benchmarks.py bench-main.json bench-pr.json | tee -a $GITHUB_STEP_SUMMARY + run: python ./cryptography-pr/.github/compare_benchmarks.py bench-base.json bench-pr.json | tee -a $GITHUB_STEP_SUMMARY From f2dbe6fb2afc23090ec443dfa9af2ff8d42a0a2f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 14 Apr 2023 21:46:37 +0800 Subject: [PATCH 623/827] update cargo.toml's openssl-sys (#8732) the .lock is correct since it got updated by dependabot when it bumped to 0.9.85 for openssl, but the PR bumping this closed. The lock supersedes this, but this should be right! --- src/rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 1e188960257d..3175cd12ba27 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,7 +14,7 @@ asn1 = { version = "0.14.0", default-features = false } pem = "1.1" ouroboros = "0.15" openssl = "0.10.50" -openssl-sys = "0.9.84" +openssl-sys = "0.9.85" foreign-types-shared = "0.1" [build-dependencies] From 3b62a90c448aeed395a41639b41f32b42c6f05b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:56:45 +0000 Subject: [PATCH 624/827] Bump dawidd6/action-download-artifact from 2.26.1 to 2.27.0 (#8735) Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2.26.1 to 2.27.0. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/7132ab516fba5f602fafae6fdd4822afa10db76f...246dbf436b23d7c49e21a7ab8204ca9ecd1fe615) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/pypi-publish.yml | 2 +- .github/workflows/wheel-builder.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 878431a99dbd..cf3941e422cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -394,7 +394,7 @@ jobs: timeout-minutes: 2 uses: ./.github/actions/wycheproof - - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f + - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: repo: pyca/infra workflow: build-macos-openssl.yml @@ -453,7 +453,7 @@ jobs: key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - run: python -m pip install -c ci-constraints-requirements.txt "nox" coverage[toml] - - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f + - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: repo: pyca/infra workflow: build-windows-openssl.yml diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 172bb131a9b9..e873b579b58f 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -25,7 +25,7 @@ jobs: permissions: id-token: "write" steps: - - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f + - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: path: dist/ run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.id }} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index c5446fcee0bb..83fe53d3aa4f 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -194,7 +194,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') - - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f + - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: repo: pyca/infra workflow: build-macos-openssl.yml @@ -273,7 +273,7 @@ jobs: toolchain: stable target: ${{ matrix.WINDOWS.RUST_TRIPLE }} - - uses: dawidd6/action-download-artifact@7132ab516fba5f602fafae6fdd4822afa10db76f + - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: repo: pyca/infra workflow: build-windows-openssl.yml From dcff16cded0ed5ce5ef956fae7fbf6eb41e9b1e9 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 15 Apr 2023 00:18:02 +0000 Subject: [PATCH 625/827] Bump BoringSSL and/or OpenSSL in CI (#8736) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf3941e422cc..706d50bb3315 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 14, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "298e6c2b9c97ca17ee8cf65d24819ec19420013c"}} - # Latest commit on the OpenSSL master branch, as of Apr 14, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "efbff4de3e259cee71a4e1bbd86b30ebd86bbdae"}} + # Latest commit on the BoringSSL master branch, as of Apr 15, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d3acd45456450f7e8091f0f56084bc2da93e48fe"}} + # Latest commit on the OpenSSL master branch, as of Apr 15, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "7eab7680ee61c64b2ae7acd9dd199ab6734f3d1f"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 0da9abfbe79a7a171e58c905b6621dc614d5e8ac Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 15 Apr 2023 08:49:31 +0800 Subject: [PATCH 626/827] we also need X509_STORE_up_ref for pyopenssl (#8737) --- src/_cffi_src/openssl/x509_vfy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py index 0337afa3497d..f1ea8ee6af82 100644 --- a/src/_cffi_src/openssl/x509_vfy.py +++ b/src/_cffi_src/openssl/x509_vfy.py @@ -143,6 +143,7 @@ /* Included due to external consumer, see https://github.com/pyca/pyopenssl/issues/1031 */ int X509_STORE_set_purpose(X509_STORE *, int); +int X509_STORE_up_ref(X509_STORE *); void X509_STORE_free(X509_STORE *); /* X509_STORE_CTX */ From 45bddbfb192656e8e6819d060d2f060a24fffd54 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 15 Apr 2023 12:05:11 +0800 Subject: [PATCH 627/827] add support for aes256-gcm@openssh.com decryption for SSH keys (#8738) * add support for aes256-gcm@openssh.com decryption for SSH keys * review feedback * skip when bcrypt isn't present --- CHANGELOG.rst | 2 + docs/development/test-vectors.rst | 4 + .../hazmat/primitives/serialization/ssh.py | 108 ++++++++++++++---- tests/hazmat/primitives/test_ssh.py | 45 +++++++- .../asymmetric/OpenSSH/ed25519-aesgcm-psw.key | 8 ++ .../OpenSSH/ed25519-aesgcm-psw.key.pub | 1 + 6 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key.pub diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 75cd3a49df57..5a550584ef8e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,8 @@ Changelog * Added support for the :class:`~cryptography.x509.MSCertificateTemplate` proprietary Microsoft certificate extension. * Implemented support for equality checks on all asymmetric public key types. +* Added support for ``aes256-gcm@openssh.com`` encrypted keys in + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key`. .. _v40-0-2: diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index b3a1c301da58..c042eb9bf331 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -803,6 +803,10 @@ Custom PKCS7 Test Vectors Custom OpenSSH Test Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ``ed25519-aesgcm-psw.key`` and ``ed25519-aesgcm-psw.key.pub`` generated by + exporting an Ed25519 key from ``1password 8`` with the password "password". + This key is encrypted using the ``aes256-gcm@openssh.com`` algorithm. + Generated by ``asymmetric/OpenSSH/gen.sh`` using command-line tools from OpenSSH_7.6p1 package. diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 90261845143a..7725c83543e8 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -11,6 +11,7 @@ import typing import warnings from base64 import encodebytes as _base64_encode +from dataclasses import dataclass from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm @@ -23,7 +24,12 @@ rsa, ) from cryptography.hazmat.primitives.asymmetric import utils as asym_utils -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.ciphers import ( + AEADDecryptionContext, + Cipher, + algorithms, + modes, +) from cryptography.hazmat.primitives.serialization import ( Encoding, KeySerializationEncryption, @@ -78,18 +84,51 @@ def _bcrypt_kdf( # padding for max blocksize _PADDING = memoryview(bytearray(range(1, 1 + 16))) + +@dataclass +class _SSHCipher: + alg: typing.Type[algorithms.AES] + key_len: int + mode: typing.Union[ + typing.Type[modes.CTR], + typing.Type[modes.CBC], + typing.Type[modes.GCM], + ] + block_len: int + iv_len: int + tag_len: typing.Optional[int] + is_aead: bool + + # ciphers that are actually used in key wrapping -_SSH_CIPHERS: typing.Dict[ - bytes, - typing.Tuple[ - typing.Type[algorithms.AES], - int, - typing.Union[typing.Type[modes.CTR], typing.Type[modes.CBC]], - int, - ], -] = { - b"aes256-ctr": (algorithms.AES, 32, modes.CTR, 16), - b"aes256-cbc": (algorithms.AES, 32, modes.CBC, 16), +_SSH_CIPHERS: typing.Dict[bytes, _SSHCipher] = { + b"aes256-ctr": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.CTR, + block_len=16, + iv_len=16, + tag_len=None, + is_aead=False, + ), + b"aes256-cbc": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.CBC, + block_len=16, + iv_len=16, + tag_len=None, + is_aead=False, + ), + b"aes256-gcm@openssh.com": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.GCM, + block_len=16, + iv_len=12, + tag_len=16, + is_aead=True, + ), } # map local curve name to key type @@ -156,14 +195,19 @@ def _init_cipher( password: typing.Optional[bytes], salt: bytes, rounds: int, -) -> Cipher[typing.Union[modes.CBC, modes.CTR]]: +) -> Cipher[typing.Union[modes.CBC, modes.CTR, modes.GCM]]: """Generate key + iv and return cipher.""" if not password: raise ValueError("Key is password-protected.") - algo, key_len, mode, iv_len = _SSH_CIPHERS[ciphername] - seed = _bcrypt_kdf(password, salt, key_len + iv_len, rounds, True) - return Cipher(algo(seed[:key_len]), mode(seed[key_len:])) + ciph = _SSH_CIPHERS[ciphername] + seed = _bcrypt_kdf( + password, salt, ciph.key_len + ciph.iv_len, rounds, True + ) + return Cipher( + ciph.alg(seed[: ciph.key_len]), + ciph.mode(seed[ciph.key_len :]), + ) def _get_u32(data: memoryview) -> typing.Tuple[int, memoryview]: @@ -604,10 +648,6 @@ def load_ssh_private_key( pubfields, pubdata = kformat.get_public(pubdata) _check_empty(pubdata) - # load secret data - edata, data = _get_sshstr(data) - _check_empty(data) - if (ciphername, kdfname) != (_NONE, _NONE): ciphername_bytes = ciphername.tobytes() if ciphername_bytes not in _SSH_CIPHERS: @@ -616,14 +656,36 @@ def load_ssh_private_key( ) if kdfname != _BCRYPT: raise UnsupportedAlgorithm(f"Unsupported KDF: {kdfname!r}") - blklen = _SSH_CIPHERS[ciphername_bytes][3] + blklen = _SSH_CIPHERS[ciphername_bytes].block_len + tag_len = _SSH_CIPHERS[ciphername_bytes].tag_len + # load secret data + edata, data = _get_sshstr(data) + # see https://bugzilla.mindrot.org/show_bug.cgi?id=3553 for + # information about how OpenSSH handles AEAD tags + if _SSH_CIPHERS[ciphername_bytes].is_aead: + tag = bytes(data) + if len(tag) != tag_len: + raise ValueError("Corrupt data: invalid tag length for cipher") + else: + _check_empty(data) _check_block_size(edata, blklen) salt, kbuf = _get_sshstr(kdfoptions) rounds, kbuf = _get_u32(kbuf) _check_empty(kbuf) ciph = _init_cipher(ciphername_bytes, password, salt.tobytes(), rounds) - edata = memoryview(ciph.decryptor().update(edata)) + dec = ciph.decryptor() + edata = memoryview(dec.update(edata)) + if _SSH_CIPHERS[ciphername_bytes].is_aead: + assert isinstance(dec, AEADDecryptionContext) + _check_empty(dec.finalize_with_tag(tag)) + else: + # _check_block_size requires data to be a full block so there + # should be no output from finalize + _check_empty(dec.finalize()) else: + # load secret data + edata, data = _get_sshstr(data) + _check_empty(data) blklen = 8 _check_block_size(edata, blklen) ck1, edata = _get_u32(edata) @@ -676,7 +738,7 @@ def _serialize_ssh_private_key( f_kdfoptions = _FragList() if password: ciphername = _DEFAULT_CIPHER - blklen = _SSH_CIPHERS[ciphername][3] + blklen = _SSH_CIPHERS[ciphername].block_len kdfname = _BCRYPT rounds = _DEFAULT_ROUNDS if ( diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index c9f995b1f0c6..e5c58062d075 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -10,7 +10,7 @@ import pytest from cryptography import utils -from cryptography.exceptions import InvalidSignature +from cryptography.exceptions import InvalidSignature, InvalidTag from cryptography.hazmat.primitives.asymmetric import ( dsa, ec, @@ -153,6 +153,7 @@ def run_partial_pubkey(self, pubdata, backend): ("ecdsa-psw.key",), ("ed25519-nopsw.key",), ("ed25519-psw.key",), + ("ed25519-aesgcm-psw.key",), ], ) def test_load_ssh_private_key(self, key_file, backend): @@ -243,6 +244,48 @@ def test_load_ssh_private_key(self, key_file, backend): maxline = max(map(len, priv_data2.split(b"\n"))) assert maxline < 80 + @pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires Ed25519 support", + ) + @pytest.mark.supported( + only_if=lambda backend: ssh._bcrypt_supported, + skip_message="Requires that bcrypt exists", + ) + def test_load_ssh_private_key_invalid_tag(self, backend): + priv_data = bytearray( + load_vectors_from_file( + os.path.join( + "asymmetric", "OpenSSH", "ed25519-aesgcm-psw.key" + ), + lambda f: f.read(), + mode="rb", + ) + ) + # mutate one byte to break the tag + priv_data[-38] = 82 + with pytest.raises(InvalidTag): + load_ssh_private_key(priv_data, b"password") + + @pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires Ed25519 support", + ) + @pytest.mark.supported( + only_if=lambda backend: ssh._bcrypt_supported, + skip_message="Requires that bcrypt exists", + ) + def test_load_ssh_private_key_tag_incorrect_length(self, backend): + priv_data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "ed25519-aesgcm-psw.key"), + lambda f: f.read(), + mode="rb", + ) + # clip out a byte + broken_data = priv_data[:-37] + priv_data[-38:] + with pytest.raises(ValueError): + load_ssh_private_key(broken_data, b"password") + @pytest.mark.supported( only_if=lambda backend: ssh._bcrypt_supported, skip_message="Requires that bcrypt exists", diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key b/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key new file mode 100644 index 000000000000..673cf2d79101 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAAFmFlczI1Ni1nY21Ab3BlbnNzaC5jb20AAAAGYmNyeXB0AA +AAGAAAABBxwbaftabtGFPlzbCIuqOIAAAAIAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAA +ICuPdFT6OORNyXh9rMfOx3LUCm9yANYovOfNlGd2hg01AAAAkBl0VICPNwd88NHm9w10X0 +bn0WTOJMzyQBw8cNZvswPvczViEFmW0pZwDmeVrBBTLmktn4b3D7IfCMJIbfAq+N+rRZ0p +xhPi6toZopq1wP4dE44DYQ1dr2K4evLv5pRCLJUkmNny/7jFEOggVx8N5o8pOSuf0tNhYd +SCn7oNc1syjS2w0Zjb2ZTiX4L9d60tSLDwLOolS1Xc0nPUMnzC5hM= +-----END OPENSSH PRIVATE KEY----- diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key.pub new file mode 100644 index 000000000000..ed7c311aee03 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/ed25519-aesgcm-psw.key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuPdFT6OORNyXh9rMfOx3LUCm9yANYovOfNlGd2hg01 From a9d1bcfe5fce9f6e257231521c96298b952ad72a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Apr 2023 11:02:05 -0400 Subject: [PATCH 628/827] Bump pytest from 7.3.0 to 7.3.1 (#8739) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.3.0 to 7.3.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.3.0...7.3.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 9668353db5a3..4f00c537256f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -105,7 +105,7 @@ pygments==2.15.0 # sphinx pyproject-hooks==1.0.0 # via build -pytest==7.3.0 +pytest==7.3.1 # via # cryptography (pyproject.toml) # pytest-benchmark From 9c09a67204223578896026035ce877d7ea2ffdf4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 16 Apr 2023 19:34:00 +0800 Subject: [PATCH 629/827] drop libressl 3.5.x support (#8741) OpenBSD 7.1 is no longer supported so neither is LibreSSL 3.5.x --- .github/workflows/ci.yml | 1 - CHANGELOG.rst | 1 + src/_cffi_src/openssl/crypto.py | 8 -------- src/_cffi_src/openssl/cryptography.py | 3 --- src/cryptography/hazmat/bindings/openssl/_conditional.py | 7 ------- tests/hazmat/backends/test_openssl_memleak.py | 3 +-- 6 files changed, 2 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 706d50bb3315..92dd1db1b763 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,6 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.5.4"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5a550584ef8e..fcc6f28cbc47 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,7 @@ Changelog * **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been removed. Users on older version of OpenSSL will need to upgrade. * **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. +* **BACKWARDS INCOMPATIBLE:** Dropped support for LibreSSL < 3.6. * Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. * Added support for the :class:`~cryptography.x509.OCSPAcceptableResponses` OCSP extension. diff --git a/src/_cffi_src/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py index f36a0fa17616..b81b5de1da27 100644 --- a/src/_cffi_src/openssl/crypto.py +++ b/src/_cffi_src/openssl/crypto.py @@ -10,7 +10,6 @@ TYPES = """ static const long Cryptography_HAS_MEM_FUNCTIONS; -static const long Cryptography_HAS_OPENSSL_CLEANUP; static const int OPENSSL_VERSION; static const int OPENSSL_CFLAGS; @@ -42,13 +41,6 @@ """ CUSTOMIZATIONS = """ -#if CRYPTOGRAPHY_LIBRESSL_LESS_THAN_360 -static const long Cryptography_HAS_OPENSSL_CLEANUP = 0; -void (*OPENSSL_cleanup)(void) = NULL; -#else -static const long Cryptography_HAS_OPENSSL_CLEANUP = 1; -#endif - #if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_IS_BORINGSSL static const long Cryptography_HAS_MEM_FUNCTIONS = 0; int (*Cryptography_CRYPTO_set_mem_functions)( diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py index 05d3e0e50165..f5fcb04405b5 100644 --- a/src/_cffi_src/openssl/cryptography.py +++ b/src/_cffi_src/openssl/cryptography.py @@ -43,13 +43,10 @@ #endif #if CRYPTOGRAPHY_IS_LIBRESSL -#define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_360 \ - (LIBRESSL_VERSION_NUMBER < 0x3060000f) #define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 \ (LIBRESSL_VERSION_NUMBER < 0x3070000f) #else -#define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_360 (0) #define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 (0) #endif diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 95d5297d5711..3130edd490ff 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -124,12 +124,6 @@ def cryptography_has_custom_ext() -> typing.List[str]: ] -def cryptography_has_openssl_cleanup() -> typing.List[str]: - return [ - "OPENSSL_cleanup", - ] - - def cryptography_has_tlsv13_functions() -> typing.List[str]: return [ "SSL_VERIFY_POST_HANDSHAKE", @@ -299,7 +293,6 @@ def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: "Cryptography_HAS_PSK": cryptography_has_psk, "Cryptography_HAS_PSK_TLSv1_3": cryptography_has_psk_tlsv13, "Cryptography_HAS_CUSTOM_EXT": cryptography_has_custom_ext, - "Cryptography_HAS_OPENSSL_CLEANUP": cryptography_has_openssl_cleanup, "Cryptography_HAS_TLSv1_3_FUNCTIONS": cryptography_has_tlsv13_functions, "Cryptography_HAS_RAW_KEY": cryptography_has_raw_key, "Cryptography_HAS_EVP_DIGESTFINAL_XOF": ( diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index 755f1827d278..05e8f9480356 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -122,8 +122,7 @@ def free(ptr, path, line): _openssl.lib.OSSL_PROVIDER_unload(backend._binding._legacy_provider) _openssl.lib.OSSL_PROVIDER_unload(backend._binding._default_provider) - if _openssl.lib.Cryptography_HAS_OPENSSL_CLEANUP: - _openssl.lib.OPENSSL_cleanup() + _openssl.lib.OPENSSL_cleanup() # Swap back to the original functions so that if OpenSSL tries to free # something from its atexit handle it won't be going through a Python From 3e40017b5fff43b2bc3be774eca47c0643e97649 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 17 Apr 2023 05:45:25 +0800 Subject: [PATCH 630/827] begin separation of x509 crate from cryptography crate (#8740) * begin separation of x509 crate from cryptography crate this will not be a published crate for now and the separation is incomplete. * no more rawcertificate, no more re-exporting * rename RawCsr * rename rawcrl * port ocsprequest and rename * more raw renaming * switch to a workspace, rename * remove unneeded imports * add license headers, remove more unneeded imports * coverage * this should actually be possible iwth just --all * merge all the coverage files * path fix * one last guess * coverage * remove extra definition --- .github/workflows/ci.yml | 6 +- src/rust/Cargo.lock | 8 + src/rust/Cargo.toml | 4 + src/rust/cryptography-x509/Cargo.toml | 11 + src/rust/cryptography-x509/src/certificate.rs | 41 +++ src/rust/cryptography-x509/src/common.rs | 142 +++++++++++ src/rust/cryptography-x509/src/crl.rs | 69 +++++ src/rust/cryptography-x509/src/csr.rs | 70 +++++ src/rust/cryptography-x509/src/extensions.rs | 175 +++++++++++++ src/rust/cryptography-x509/src/lib.rs | 14 + src/rust/cryptography-x509/src/name.rs | 88 +++++++ src/rust/cryptography-x509/src/ocsp_req.rs | 46 ++++ src/rust/cryptography-x509/src/oid.rs | 86 +++++++ src/rust/src/asn1.rs | 2 +- src/rust/src/pkcs7.rs | 51 ++-- src/rust/src/x509/certificate.rs | 234 +++-------------- src/rust/src/x509/common.rs | 240 +----------------- src/rust/src/x509/crl.rs | 193 +++++--------- src/rust/src/x509/csr.rs | 105 +++----- src/rust/src/x509/extensions.rs | 80 +++--- src/rust/src/x509/mod.rs | 5 +- src/rust/src/x509/ocsp.rs | 116 ++++----- src/rust/src/x509/ocsp_req.rs | 66 ++--- src/rust/src/x509/ocsp_resp.rs | 57 +++-- src/rust/src/x509/oid.rs | 101 -------- src/rust/src/x509/sign.rs | 51 ++-- 26 files changed, 1096 insertions(+), 965 deletions(-) create mode 100644 src/rust/cryptography-x509/Cargo.toml create mode 100644 src/rust/cryptography-x509/src/certificate.rs create mode 100644 src/rust/cryptography-x509/src/common.rs create mode 100644 src/rust/cryptography-x509/src/crl.rs create mode 100644 src/rust/cryptography-x509/src/csr.rs create mode 100644 src/rust/cryptography-x509/src/extensions.rs create mode 100644 src/rust/cryptography-x509/src/lib.rs create mode 100644 src/rust/cryptography-x509/src/name.rs create mode 100644 src/rust/cryptography-x509/src/ocsp_req.rs create mode 100644 src/rust/cryptography-x509/src/oid.rs delete mode 100644 src/rust/src/x509/oid.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92dd1db1b763..5ee7a8595905 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -323,7 +323,7 @@ jobs: - name: Rust Tests run: | cd src/rust - cargo test --no-default-features + cargo test --no-default-features --all env: RUSTFLAGS: "-Cinstrument-coverage" LLVM_PROFILE_FILE: "rust-cov/cov-%m-%p.profraw" @@ -332,7 +332,7 @@ jobs: set -xe cd src/rust/ cargo profdata -- merge -sparse ../../rust-cov/*.profraw -o pytest-rust-cov.profdata - cargo profdata -- merge -sparse rust-cov/*.profraw -o cargo-test-rust-cov.profdata + cargo profdata -- merge -sparse rust-cov/*.profraw cryptography-x509/rust-cov/*.profraw -o cargo-test-rust-cov.profdata COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") cargo cov -- export \ @@ -342,7 +342,7 @@ jobs: --ignore-filename-regex='/rustc/' \ --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > ../../${COV_UUID}-1.lcov cargo cov -- export \ - $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]") \ + $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --all --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]") \ -instr-profile=cargo-test-rust-cov.profdata \ --ignore-filename-regex='/.cargo/registry' \ --ignore-filename-regex='/rustc/' \ diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c16a7fcecbdc..1fc04cecd0dc 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -70,6 +70,7 @@ version = "0.1.0" dependencies = [ "asn1", "cc", + "cryptography-x509", "foreign-types-shared", "once_cell", "openssl", @@ -79,6 +80,13 @@ dependencies = [ "pyo3", ] +[[package]] +name = "cryptography-x509" +version = "0.1.0" +dependencies = [ + "asn1", +] + [[package]] name = "foreign-types" version = "0.3.2" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 3175cd12ba27..e96b1fc2b505 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -11,6 +11,7 @@ rust-version = "1.56.0" once_cell = "1" pyo3 = { version = "0.18" } asn1 = { version = "0.14.0", default-features = false } +cryptography-x509 = { path = "cryptography-x509" } pem = "1.1" ouroboros = "0.15" openssl = "0.10.50" @@ -31,3 +32,6 @@ crate-type = ["cdylib"] [profile.release] lto = "thin" overflow-checks = true + +[workspace] +members = ["cryptography-x509"] diff --git a/src/rust/cryptography-x509/Cargo.toml b/src/rust/cryptography-x509/Cargo.toml new file mode 100644 index 000000000000..b062ddbbfb57 --- /dev/null +++ b/src/rust/cryptography-x509/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "cryptography-x509" +version = "0.1.0" +authors = ["The cryptography developers "] +edition = "2021" +publish = false +# This specifies the MSRV +rust-version = "1.56.0" + +[dependencies] +asn1 = { version = "0.14.0", default-features = false } diff --git a/src/rust/cryptography-x509/src/certificate.rs b/src/rust/cryptography-x509/src/certificate.rs new file mode 100644 index 000000000000..bb9a666f5f78 --- /dev/null +++ b/src/rust/cryptography-x509/src/certificate.rs @@ -0,0 +1,41 @@ +// 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. + +use crate::common; +use crate::extensions; +use crate::name; + +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] +pub struct Certificate<'a> { + pub tbs_cert: TbsCertificate<'a>, + pub signature_alg: common::AlgorithmIdentifier<'a>, + pub signature: asn1::BitString<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] +pub struct TbsCertificate<'a> { + #[explicit(0)] + #[default(0)] + pub version: u8, + pub serial: asn1::BigInt<'a>, + pub signature_alg: common::AlgorithmIdentifier<'a>, + + pub issuer: name::Name<'a>, + pub validity: Validity, + pub subject: name::Name<'a>, + + pub spki: common::SubjectPublicKeyInfo<'a>, + #[implicit(1)] + pub issuer_unique_id: Option>, + #[implicit(2)] + pub subject_unique_id: Option>, + #[explicit(3)] + pub extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] +pub struct Validity { + pub not_before: common::Time, + pub not_after: common::Time, +} diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs new file mode 100644 index 000000000000..13fcb3368243 --- /dev/null +++ b/src/rust/cryptography-x509/src/common.rs @@ -0,0 +1,142 @@ +// 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. + +use std::marker::PhantomData; + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] +pub struct AlgorithmIdentifier<'a> { + pub oid: asn1::ObjectIdentifier, + pub params: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] +pub struct SubjectPublicKeyInfo<'a> { + _algorithm: AlgorithmIdentifier<'a>, + pub subject_public_key: asn1::BitString<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)] +pub struct AttributeTypeValue<'a> { + pub type_id: asn1::ObjectIdentifier, + pub value: RawTlv<'a>, +} + +// Like `asn1::Tlv` but doesn't store `full_data` so it can be constructed from +// an un-encoded tag and value. +#[derive(Hash, PartialEq, Eq, Clone)] +pub struct RawTlv<'a> { + tag: asn1::Tag, + value: &'a [u8], +} + +impl<'a> RawTlv<'a> { + pub fn new(tag: asn1::Tag, value: &'a [u8]) -> Self { + RawTlv { tag, value } + } + + pub fn tag(&self) -> asn1::Tag { + self.tag + } + pub fn data(&self) -> &'a [u8] { + self.value + } +} +impl<'a> asn1::Asn1Readable<'a> for RawTlv<'a> { + fn parse(parser: &mut asn1::Parser<'a>) -> asn1::ParseResult { + let tlv = parser.read_element::>()?; + Ok(RawTlv::new(tlv.tag(), tlv.data())) + } + + fn can_parse(_tag: asn1::Tag) -> bool { + true + } +} +impl<'a> asn1::Asn1Writable for RawTlv<'a> { + fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult { + w.write_tlv(self.tag, move |dest| dest.push_slice(self.value)) + } +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] +pub enum Time { + UtcTime(asn1::UtcTime), + GeneralizedTime(asn1::GeneralizedTime), +} + +impl Time { + pub fn as_datetime(&self) -> &asn1::DateTime { + match self { + Time::UtcTime(data) => data.as_datetime(), + Time::GeneralizedTime(data) => data.as_datetime(), + } + } +} + +#[derive(Hash, PartialEq, Clone)] +pub enum Asn1ReadableOrWritable<'a, T, U> { + Read(T, PhantomData<&'a ()>), + Write(U, PhantomData<&'a ()>), +} + +impl<'a, T, U> Asn1ReadableOrWritable<'a, T, U> { + pub fn new_read(v: T) -> Self { + Asn1ReadableOrWritable::Read(v, PhantomData) + } + + pub fn new_write(v: U) -> Self { + Asn1ReadableOrWritable::Write(v, PhantomData) + } + + pub fn unwrap_read(&self) -> &T { + match self { + Asn1ReadableOrWritable::Read(v, _) => v, + Asn1ReadableOrWritable::Write(_, _) => panic!("unwrap_read called on a Write value"), + } + } +} + +impl<'a, T: asn1::SimpleAsn1Readable<'a>, U> asn1::SimpleAsn1Readable<'a> + for Asn1ReadableOrWritable<'a, T, U> +{ + const TAG: asn1::Tag = T::TAG; + fn parse_data(data: &'a [u8]) -> asn1::ParseResult { + Ok(Self::new_read(T::parse_data(data)?)) + } +} + +impl<'a, T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleAsn1Writable + for Asn1ReadableOrWritable<'a, T, U> +{ + const TAG: asn1::Tag = U::TAG; + fn write_data(&self, w: &mut asn1::WriteBuf) -> asn1::WriteResult { + match self { + Asn1ReadableOrWritable::Read(v, _) => T::write_data(v, w), + Asn1ReadableOrWritable::Write(v, _) => U::write_data(v, w), + } + } +} + +#[cfg(test)] +mod tests { + use super::{Asn1ReadableOrWritable, RawTlv}; + use asn1::Asn1Readable; + + #[test] + #[should_panic] + fn test_asn1_readable_or_writable_unwrap_read() { + Asn1ReadableOrWritable::::new_write(17).unwrap_read(); + } + + #[test] + fn test_asn1_readable_or_writable_write_read_data() { + let v = Asn1ReadableOrWritable::::new_read(17); + assert_eq!(&asn1::write_single(&v).unwrap(), b"\x02\x01\x11"); + } + + #[test] + fn test_raw_tlv_can_parse() { + let t = asn1::Tag::from_bytes(&[0]).unwrap().0; + assert!(RawTlv::can_parse(t)); + } +} diff --git a/src/rust/cryptography-x509/src/crl.rs b/src/rust/cryptography-x509/src/crl.rs new file mode 100644 index 000000000000..3a47e0a37727 --- /dev/null +++ b/src/rust/cryptography-x509/src/crl.rs @@ -0,0 +1,69 @@ +// 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. + +use crate::{common, extensions, name}; + +pub type ReasonFlags<'a> = + Option, asn1::OwnedBitString>>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] +pub struct CertificateRevocationList<'a> { + pub tbs_cert_list: TBSCertList<'a>, + pub signature_algorithm: common::AlgorithmIdentifier<'a>, + pub signature_value: asn1::BitString<'a>, +} + +pub type RevokedCertificates<'a> = Option< + common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, RevokedCertificate<'a>>, + asn1::SequenceOfWriter<'a, RevokedCertificate<'a>, Vec>>, + >, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] +pub struct TBSCertList<'a> { + pub version: Option, + pub signature: common::AlgorithmIdentifier<'a>, + pub issuer: name::Name<'a>, + pub this_update: common::Time, + pub next_update: Option, + pub revoked_certificates: RevokedCertificates<'a>, + #[explicit(0)] + pub crl_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] +pub struct RevokedCertificate<'a> { + pub user_certificate: asn1::BigUint<'a>, + pub revocation_date: common::Time, + pub crl_entry_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct IssuingDistributionPoint<'a> { + #[explicit(0)] + pub distribution_point: Option>, + + #[implicit(1)] + #[default(false)] + pub only_contains_user_certs: bool, + + #[implicit(2)] + #[default(false)] + pub only_contains_ca_certs: bool, + + #[implicit(3)] + pub only_some_reasons: ReasonFlags<'a>, + + #[implicit(4)] + #[default(false)] + pub indirect_crl: bool, + + #[implicit(5)] + #[default(false)] + pub only_contains_attribute_certs: bool, +} + +pub type CRLReason = asn1::Enumerated; diff --git a/src/rust/cryptography-x509/src/csr.rs b/src/rust/cryptography-x509/src/csr.rs new file mode 100644 index 000000000000..c23d22d0fd11 --- /dev/null +++ b/src/rust/cryptography-x509/src/csr.rs @@ -0,0 +1,70 @@ +// 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. + +use crate::common; +use crate::extensions; +use crate::name; +use crate::oid; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct Csr<'a> { + pub csr_info: CertificationRequestInfo<'a>, + pub signature_alg: common::AlgorithmIdentifier<'a>, + pub signature: asn1::BitString<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct CertificationRequestInfo<'a> { + pub version: u8, + pub subject: name::Name<'a>, + pub spki: common::SubjectPublicKeyInfo<'a>, + #[implicit(0, required)] + pub attributes: Attributes<'a>, +} + +impl CertificationRequestInfo<'_> { + pub fn get_extension_attribute( + &self, + ) -> Result>, asn1::ParseError> { + for attribute in self.attributes.unwrap_read().clone() { + if attribute.type_id == oid::EXTENSION_REQUEST + || attribute.type_id == oid::MS_EXTENSION_REQUEST + { + check_attribute_length(attribute.values.unwrap_read().clone())?; + let val = attribute.values.unwrap_read().clone().next().unwrap(); + let exts = asn1::parse_single(val.full_data())?; + return Ok(Some(exts)); + } + } + Ok(None) + } +} + +pub fn check_attribute_length<'a>( + values: asn1::SetOf<'a, asn1::Tlv<'a>>, +) -> Result<(), asn1::ParseError> { + if values.count() > 1 { + // TODO: We should raise a more specific error here + // Only single-valued attributes are supported + Err(asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue)) + } else { + Ok(()) + } +} + +pub type Attributes<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SetOf<'a, Attribute<'a>>, + asn1::SetOfWriter<'a, Attribute<'a>, Vec>>, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct Attribute<'a> { + pub type_id: asn1::ObjectIdentifier, + pub values: common::Asn1ReadableOrWritable< + 'a, + asn1::SetOf<'a, asn1::Tlv<'a>>, + asn1::SetOfWriter<'a, common::RawTlv<'a>, [common::RawTlv<'a>; 1]>, + >, +} diff --git a/src/rust/cryptography-x509/src/extensions.rs b/src/rust/cryptography-x509/src/extensions.rs new file mode 100644 index 000000000000..11c6e54a4d34 --- /dev/null +++ b/src/rust/cryptography-x509/src/extensions.rs @@ -0,0 +1,175 @@ +// 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. + +use crate::common; +use crate::crl; +use crate::name; + +pub type Extensions<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, Extension<'a>>, + asn1::SequenceOfWriter<'a, Extension<'a>, Vec>>, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)] +pub struct Extension<'a> { + pub extn_id: asn1::ObjectIdentifier, + #[default(false)] + pub critical: bool, + pub extn_value: &'a [u8], +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct PolicyConstraints { + #[implicit(0)] + pub require_explicit_policy: Option, + #[implicit(1)] + pub inhibit_policy_mapping: Option, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct AccessDescription<'a> { + pub access_method: asn1::ObjectIdentifier, + pub access_location: name::GeneralName<'a>, +} + +pub type SequenceOfAccessDescriptions<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, AccessDescription<'a>>, + asn1::SequenceOfWriter<'a, AccessDescription<'a>, Vec>>, +>; + +// Needed due to clippy type complexity warning. +type SequenceOfPolicyQualifiers<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, PolicyQualifierInfo<'a>>, + asn1::SequenceOfWriter<'a, PolicyQualifierInfo<'a>, Vec>>, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct PolicyInformation<'a> { + pub policy_identifier: asn1::ObjectIdentifier, + pub policy_qualifiers: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct PolicyQualifierInfo<'a> { + pub policy_qualifier_id: asn1::ObjectIdentifier, + pub qualifier: Qualifier<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum Qualifier<'a> { + CpsUri(asn1::IA5String<'a>), + UserNotice(UserNotice<'a>), +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct UserNotice<'a> { + pub notice_ref: Option>, + pub explicit_text: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct NoticeReference<'a> { + pub organization: DisplayText<'a>, + pub notice_numbers: common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, asn1::BigUint<'a>>, + asn1::SequenceOfWriter<'a, asn1::BigUint<'a>, Vec>>, + >, +} + +// DisplayText also allows BMPString, which we currently do not support. +#[allow(clippy::enum_variant_names)] +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum DisplayText<'a> { + IA5String(asn1::IA5String<'a>), + Utf8String(asn1::Utf8String<'a>), + VisibleString(asn1::VisibleString<'a>), + BmpString(asn1::BMPString<'a>), +} + +// Needed due to clippy type complexity warning. +pub type SequenceOfSubtrees<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, GeneralSubtree<'a>>, + asn1::SequenceOfWriter<'a, GeneralSubtree<'a>, Vec>>, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct NameConstraints<'a> { + #[implicit(0)] + pub permitted_subtrees: Option>, + + #[implicit(1)] + pub excluded_subtrees: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct GeneralSubtree<'a> { + pub base: name::GeneralName<'a>, + + #[implicit(0)] + #[default(0u64)] + pub minimum: u64, + + #[implicit(1)] + pub maximum: Option, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct MSCertificateTemplate { + pub template_id: asn1::ObjectIdentifier, + pub major_version: Option, + pub minor_version: Option, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct DistributionPoint<'a> { + #[explicit(0)] + pub distribution_point: Option>, + + #[implicit(1)] + pub reasons: crl::ReasonFlags<'a>, + + #[implicit(2)] + pub crl_issuer: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum DistributionPointName<'a> { + #[implicit(0)] + FullName(name::SequenceOfGeneralName<'a>), + + #[implicit(1)] + NameRelativeToCRLIssuer( + common::Asn1ReadableOrWritable< + 'a, + asn1::SetOf<'a, common::AttributeTypeValue<'a>>, + asn1::SetOfWriter< + 'a, + common::AttributeTypeValue<'a>, + Vec>, + >, + >, + ), +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct AuthorityKeyIdentifier<'a> { + #[implicit(0)] + pub key_identifier: Option<&'a [u8]>, + #[implicit(1)] + pub authority_cert_issuer: Option>, + #[implicit(2)] + pub authority_cert_serial_number: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct BasicConstraints { + #[default(false)] + pub ca: bool, + pub path_length: Option, +} diff --git a/src/rust/cryptography-x509/src/lib.rs b/src/rust/cryptography-x509/src/lib.rs new file mode 100644 index 000000000000..3f8878772dd1 --- /dev/null +++ b/src/rust/cryptography-x509/src/lib.rs @@ -0,0 +1,14 @@ +// 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. + +#![forbid(unsafe_code)] + +pub mod certificate; +pub mod common; +pub mod crl; +pub mod csr; +pub mod extensions; +pub mod name; +pub mod ocsp_req; +pub mod oid; diff --git a/src/rust/cryptography-x509/src/name.rs b/src/rust/cryptography-x509/src/name.rs new file mode 100644 index 000000000000..f53e342cbf33 --- /dev/null +++ b/src/rust/cryptography-x509/src/name.rs @@ -0,0 +1,88 @@ +// 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. + +use crate::common; + +pub type Name<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, asn1::SetOf<'a, common::AttributeTypeValue<'a>>>, + asn1::SequenceOfWriter< + 'a, + asn1::SetOfWriter<'a, common::AttributeTypeValue<'a>, Vec>>, + Vec< + asn1::SetOfWriter< + 'a, + common::AttributeTypeValue<'a>, + Vec>, + >, + >, + >, +>; + +/// An IA5String ASN.1 element whose contents is not validated as meeting the +/// requirements (ASCII characters only), and instead is only known to be +/// valid UTF-8. +pub struct UnvalidatedIA5String<'a>(pub &'a str); + +impl<'a> asn1::SimpleAsn1Readable<'a> for UnvalidatedIA5String<'a> { + const TAG: asn1::Tag = asn1::IA5String::TAG; + fn parse_data(data: &'a [u8]) -> asn1::ParseResult { + Ok(UnvalidatedIA5String(std::str::from_utf8(data).map_err( + |_| asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue), + )?)) + } +} + +impl<'a> asn1::SimpleAsn1Writable for UnvalidatedIA5String<'a> { + const TAG: asn1::Tag = asn1::IA5String::TAG; + fn write_data(&self, dest: &mut asn1::WriteBuf) -> asn1::WriteResult { + dest.push_slice(self.0.as_bytes()) + } +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] +pub struct OtherName<'a> { + pub type_id: asn1::ObjectIdentifier, + #[explicit(0, required)] + pub value: asn1::Tlv<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum GeneralName<'a> { + #[implicit(0)] + OtherName(OtherName<'a>), + + #[implicit(1)] + RFC822Name(UnvalidatedIA5String<'a>), + + #[implicit(2)] + DNSName(UnvalidatedIA5String<'a>), + + #[implicit(3)] + // unsupported + X400Address(asn1::Sequence<'a>), + + // Name is explicit per RFC 5280 Appendix A.1. + #[explicit(4)] + DirectoryName(Name<'a>), + + #[implicit(5)] + // unsupported + EDIPartyName(asn1::Sequence<'a>), + + #[implicit(6)] + UniformResourceIdentifier(UnvalidatedIA5String<'a>), + + #[implicit(7)] + IPAddress(&'a [u8]), + + #[implicit(8)] + RegisteredID(asn1::ObjectIdentifier), +} + +pub(crate) type SequenceOfGeneralName<'a> = common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, GeneralName<'a>>, + asn1::SequenceOfWriter<'a, GeneralName<'a>, Vec>>, +>; diff --git a/src/rust/cryptography-x509/src/ocsp_req.rs b/src/rust/cryptography-x509/src/ocsp_req.rs new file mode 100644 index 000000000000..1e096e71f1da --- /dev/null +++ b/src/rust/cryptography-x509/src/ocsp_req.rs @@ -0,0 +1,46 @@ +// 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. + +use crate::{common, extensions, name}; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct TBSRequest<'a> { + #[explicit(0)] + #[default(0)] + pub version: u8, + #[explicit(1)] + pub requestor_name: Option>, + pub request_list: common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, Request<'a>>, + asn1::SequenceOfWriter<'a, Request<'a>>, + >, + #[explicit(2)] + pub request_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct Request<'a> { + pub req_cert: CertID<'a>, + #[explicit(0)] + pub single_request_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct CertID<'a> { + pub hash_algorithm: common::AlgorithmIdentifier<'a>, + pub issuer_name_hash: &'a [u8], + pub issuer_key_hash: &'a [u8], + pub serial_number: asn1::BigInt<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct OCSPRequest<'a> { + pub tbs_request: TBSRequest<'a>, + // Parsing out the full structure, which includes the entirety of a + // certificate is more trouble than it's worth, since it's not in the + // Python API. + #[explicit(0)] + pub optional_signature: Option>, +} diff --git a/src/rust/cryptography-x509/src/oid.rs b/src/rust/cryptography-x509/src/oid.rs new file mode 100644 index 000000000000..b2d22ebddb1c --- /dev/null +++ b/src/rust/cryptography-x509/src/oid.rs @@ -0,0 +1,86 @@ +// 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. + +pub const EXTENSION_REQUEST: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 14); +pub const MS_EXTENSION_REQUEST: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 311, 2, 1, 14); +pub const MS_CERTIFICATE_TEMPLATE: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 311, 21, 7); +pub const PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 2); +pub const PRECERT_POISON_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 3); +pub const SIGNED_CERTIFICATE_TIMESTAMPS_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 5); +pub const AUTHORITY_INFORMATION_ACCESS_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 1); +pub const SUBJECT_INFORMATION_ACCESS_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 11); +pub const TLS_FEATURE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 24); +pub const CP_CPS_URI_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 2, 1); +pub const CP_USER_NOTICE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 2, 2); +pub const NONCE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 2); +pub const OCSP_NO_CHECK_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 5); +pub const SUBJECT_KEY_IDENTIFIER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 14); +pub const KEY_USAGE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 15); +pub const SUBJECT_ALTERNATIVE_NAME_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 17); +pub const ISSUER_ALTERNATIVE_NAME_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 18); +pub const BASIC_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 19); +pub const CRL_NUMBER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 20); +pub const CRL_REASON_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 21); +pub const INVALIDITY_DATE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 24); +pub const DELTA_CRL_INDICATOR_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 27); +pub const ISSUING_DISTRIBUTION_POINT_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 28); +pub const CERTIFICATE_ISSUER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 29); +pub const NAME_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 30); +pub const CRL_DISTRIBUTION_POINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 31); +pub const CERTIFICATE_POLICIES_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 32); +pub const AUTHORITY_KEY_IDENTIFIER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 35); +pub const POLICY_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 36); +pub const EXTENDED_KEY_USAGE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 37); +pub const FRESHEST_CRL_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 46); +pub const INHIBIT_ANY_POLICY_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 54); +pub const ACCEPTABLE_RESPONSES_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 4); + +// Signing methods +pub const ECDSA_WITH_SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 10045, 4, 3, 1); +pub const ECDSA_WITH_SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 10045, 4, 3, 2); +pub const ECDSA_WITH_SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 10045, 4, 3, 3); +pub const ECDSA_WITH_SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 10045, 4, 3, 4); +pub const ECDSA_WITH_SHA3_224_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 9); +pub const ECDSA_WITH_SHA3_256_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 10); +pub const ECDSA_WITH_SHA3_384_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 11); +pub const ECDSA_WITH_SHA3_512_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 12); + +pub const RSA_WITH_SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 14); +pub const RSA_WITH_SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 11); +pub const RSA_WITH_SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 12); +pub const RSA_WITH_SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 13); +pub const RSA_WITH_SHA3_224_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 13); +pub const RSA_WITH_SHA3_256_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 14); +pub const RSA_WITH_SHA3_384_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 15); +pub const RSA_WITH_SHA3_512_OID: asn1::ObjectIdentifier = + asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 16); + +pub const DSA_WITH_SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 1); +pub const DSA_WITH_SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 2); +pub const DSA_WITH_SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 3); +pub const DSA_WITH_SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 4); + +pub const ED25519_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 101, 112); +pub const ED448_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 101, 113); + +// Hashes +pub const SHA1_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 14, 3, 2, 26); +pub const SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 4); +pub const SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 1); +pub const SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2); +pub const SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 3); diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 53981ddac6e8..cad48a73f174 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -3,7 +3,7 @@ // for complete details. use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509::Name; +use cryptography_x509::name::Name; use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index bb516143425f..2fdb610e3e82 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -6,6 +6,8 @@ use crate::asn1::encode_der_data; use crate::buf::CffiBuf; use crate::error::CryptographyResult; use crate::x509; +use cryptography_x509::csr::{Attribute, Attributes}; +use cryptography_x509::{common, name, oid}; use once_cell::sync::Lazy; use std::borrow::Cow; @@ -26,10 +28,10 @@ const AES_128_CBC_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3 static OIDS_TO_MIC_NAME: Lazy> = Lazy::new(|| { let mut h = HashMap::new(); - h.insert(&x509::oid::SHA224_OID, "sha-224"); - h.insert(&x509::oid::SHA256_OID, "sha-256"); - h.insert(&x509::oid::SHA384_OID, "sha-384"); - h.insert(&x509::oid::SHA512_OID, "sha-512"); + h.insert(&oid::SHA224_OID, "sha-224"); + h.insert(&oid::SHA256_OID, "sha-256"); + h.insert(&oid::SHA384_OID, "sha-384"); + h.insert(&oid::SHA512_OID, "sha-512"); h }); @@ -52,10 +54,11 @@ enum Content<'a> { #[derive(asn1::Asn1Write)] struct SignedData<'a> { version: u8, - digest_algorithms: asn1::SetOfWriter<'a, x509::AlgorithmIdentifier<'a>>, + digest_algorithms: asn1::SetOfWriter<'a, common::AlgorithmIdentifier<'a>>, content_info: ContentInfo<'a>, #[implicit(0)] - certificates: Option>>, + certificates: + Option>>, // We don't ever supply any of these, so for now, don't fill out the fields. #[implicit(1)] @@ -68,27 +71,27 @@ struct SignedData<'a> { struct SignerInfo<'a> { version: u8, issuer_and_serial_number: IssuerAndSerialNumber<'a>, - digest_algorithm: x509::AlgorithmIdentifier<'a>, + digest_algorithm: common::AlgorithmIdentifier<'a>, #[implicit(0)] - authenticated_attributes: Option>, + authenticated_attributes: Option>, - digest_encryption_algorithm: x509::AlgorithmIdentifier<'a>, + digest_encryption_algorithm: common::AlgorithmIdentifier<'a>, encrypted_digest: &'a [u8], #[implicit(1)] - unauthenticated_attributes: Option>, + unauthenticated_attributes: Option>, } #[derive(asn1::Asn1Write)] struct IssuerAndSerialNumber<'a> { - issuer: x509::Name<'a>, + issuer: name::Name<'a>, serial_number: asn1::BigInt<'a>, } #[pyo3::prelude::pyfunction] fn serialize_certificates<'p>( py: pyo3::Python<'p>, - py_certs: Vec>, + py_certs: Vec>, encoding: &'p pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { if py_certs.is_empty() { @@ -163,12 +166,12 @@ fn sign_and_serialize<'p>( ]))?; let py_signers: Vec<( - pyo3::PyRef<'p, x509::Certificate>, + pyo3::PyRef<'p, x509::certificate::Certificate>, &pyo3::PyAny, &pyo3::PyAny, )> = builder.getattr(pyo3::intern!(py, "_signers"))?.extract()?; - let py_certs: Vec> = builder + let py_certs: Vec> = builder .getattr(pyo3::intern!(py, "_additional_certs"))? .extract()?; @@ -189,15 +192,15 @@ fn sign_and_serialize<'p>( } else { let mut authenticated_attrs = vec![]; - authenticated_attrs.push(x509::csr::Attribute { + authenticated_attrs.push(Attribute { type_id: PKCS7_CONTENT_TYPE_OID, - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ asn1::parse_single(&content_type_bytes).unwrap(), ])), }); - authenticated_attrs.push(x509::csr::Attribute { + authenticated_attrs.push(Attribute { type_id: PKCS7_SIGNING_TIME_OID, - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ asn1::parse_single(&signing_time_bytes).unwrap(), ])), }); @@ -206,17 +209,17 @@ fn sign_and_serialize<'p>( asn1::write_single(&x509::ocsp::hash_data(py, py_hash_alg, &data_with_header)?)?; // Gross hack: copy to PyBytes to extend the lifetime to 'p let digest_bytes = pyo3::types::PyBytes::new(py, &digest); - authenticated_attrs.push(x509::csr::Attribute { + authenticated_attrs.push(Attribute { type_id: PKCS7_MESSAGE_DIGEST_OID, - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ asn1::parse_single(digest_bytes.as_bytes()).unwrap(), ])), }); if !options.contains(pkcs7_options.getattr(pyo3::intern!(py, "NoCapabilities"))?)? { - authenticated_attrs.push(x509::csr::Attribute { + authenticated_attrs.push(Attribute { type_id: PKCS7_SMIME_CAP_OID, - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ asn1::parse_single(&smime_cap_bytes).unwrap(), ])), }); @@ -226,14 +229,14 @@ fn sign_and_serialize<'p>( asn1::write_single(&asn1::SetOfWriter::new(authenticated_attrs.as_slice()))?; ( - Some(x509::Asn1ReadableOrWritable::new_write( + Some(common::Asn1ReadableOrWritable::new_write( asn1::SetOfWriter::new(authenticated_attrs), )), x509::sign::sign_data(py, py_private_key, py_hash_alg, &signed_data)?, ) }; - let digest_alg = x509::AlgorithmIdentifier { + let digest_alg = common::AlgorithmIdentifier { oid: x509::ocsp::HASH_NAME_TO_OIDS[py_hash_alg .getattr(pyo3::intern!(py, "name"))? .extract::<&str>()?] diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 6ccde6542cb3..a20e3fe5ff1a 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -7,79 +7,49 @@ use crate::asn1::{ }; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{crl, extensions, oid, sct, sign, Asn1ReadableOrWritable}; +use crate::x509::{extensions, sct, sign}; +use cryptography_x509::common::Asn1ReadableOrWritable; +use cryptography_x509::extensions::{ + AuthorityKeyIdentifier, BasicConstraints, DisplayText, DistributionPoint, + DistributionPointName, MSCertificateTemplate, NameConstraints, PolicyConstraints, + PolicyInformation, PolicyQualifierInfo, Qualifier, SequenceOfAccessDescriptions, + SequenceOfSubtrees, UserNotice, +}; +use cryptography_x509::extensions::{Extension, Extensions}; +use cryptography_x509::{common, name, oid}; use pyo3::{IntoPy, ToPyObject}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] -pub(crate) struct RawCertificate<'a> { - pub(crate) tbs_cert: TbsCertificate<'a>, - signature_alg: x509::AlgorithmIdentifier<'a>, - signature: asn1::BitString<'a>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] -pub(crate) struct TbsCertificate<'a> { - #[explicit(0)] - #[default(0)] - version: u8, - pub(crate) serial: asn1::BigInt<'a>, - signature_alg: x509::AlgorithmIdentifier<'a>, - - pub(crate) issuer: x509::Name<'a>, - validity: Validity, - pub(crate) subject: x509::Name<'a>, - - pub(crate) spki: SubjectPublicKeyInfo<'a>, - #[implicit(1)] - issuer_unique_id: Option>, - #[implicit(2)] - subject_unique_id: Option>, - #[explicit(3)] - extensions: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] -pub(crate) struct Validity { - not_before: x509::Time, - not_after: x509::Time, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] -pub(crate) struct SubjectPublicKeyInfo<'a> { - _algorithm: x509::AlgorithmIdentifier<'a>, - pub(crate) subject_public_key: asn1::BitString<'a>, -} - #[ouroboros::self_referencing] -pub(crate) struct OwnedRawCertificate { +pub(crate) struct OwnedCertificate { data: pyo3::Py, #[borrows(data)] #[covariant] - value: RawCertificate<'this>, + value: cryptography_x509::certificate::Certificate<'this>, } -impl OwnedRawCertificate { +impl OwnedCertificate { // Re-expose ::new with `pub(crate)` visibility. pub(crate) fn new_public( data: pyo3::Py, value_ref_builder: impl for<'this> FnOnce( &'this pyo3::Py, - ) -> RawCertificate<'this>, - ) -> OwnedRawCertificate { - OwnedRawCertificate::new(data, value_ref_builder) + ) + -> cryptography_x509::certificate::Certificate<'this>, + ) -> OwnedCertificate { + OwnedCertificate::new(data, value_ref_builder) } - pub(crate) fn borrow_value_public(&self) -> &RawCertificate<'_> { + pub(crate) fn borrow_value_public(&self) -> &cryptography_x509::certificate::Certificate<'_> { self.borrow_value() } } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] pub(crate) struct Certificate { - pub(crate) raw: OwnedRawCertificate, + pub(crate) raw: OwnedCertificate, pub(crate) cached_extensions: Option, } @@ -209,7 +179,7 @@ impl Certificate { Some(extensions) => { let readable_extensions = extensions.unwrap_read().clone(); let ext_count = readable_extensions.len(); - let filtered_extensions: Vec> = readable_extensions + let filtered_extensions: Vec> = readable_extensions .filter(|x| x.extn_id != oid::PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID) .collect(); if filtered_extensions.len() == ext_count { @@ -219,7 +189,7 @@ impl Certificate { ), )); } - let filtered_extensions: x509::Extensions<'_> = Asn1ReadableOrWritable::new_write( + let filtered_extensions: Extensions<'_> = Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(filtered_extensions), ); tbs_precert.extensions = Some(filtered_extensions); @@ -409,7 +379,7 @@ fn load_der_x509_certificate( py: pyo3::Python<'_>, data: pyo3::Py, ) -> CryptographyResult { - let raw = OwnedRawCertificate::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; + let raw = OwnedCertificate::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; // Parse cert version immediately so we can raise error on parse if it is invalid. cert_version(py, raw.borrow_value().tbs_cert.version)?; // determine if the serial is negative and raise a warning if it is. We want to drop support @@ -437,57 +407,6 @@ fn warn_if_negative_serial(py: pyo3::Python<'_>, bytes: &'_ [u8]) -> pyo3::PyRes Ok(()) } -// Needed due to clippy type complexity warning. -type SequenceOfPolicyQualifiers<'a> = x509::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, PolicyQualifierInfo<'a>>, - asn1::SequenceOfWriter<'a, PolicyQualifierInfo<'a>, Vec>>, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct PolicyInformation<'a> { - pub policy_identifier: asn1::ObjectIdentifier, - pub policy_qualifiers: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct PolicyQualifierInfo<'a> { - pub policy_qualifier_id: asn1::ObjectIdentifier, - pub qualifier: Qualifier<'a>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) enum Qualifier<'a> { - CpsUri(asn1::IA5String<'a>), - UserNotice(UserNotice<'a>), -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct UserNotice<'a> { - pub notice_ref: Option>, - pub explicit_text: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct NoticeReference<'a> { - pub organization: DisplayText<'a>, - pub notice_numbers: x509::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, asn1::BigUint<'a>>, - asn1::SequenceOfWriter<'a, asn1::BigUint<'a>, Vec>>, - >, -} - -// DisplayText also allows BMPString, which we currently do not support. -#[allow(clippy::enum_variant_names)] -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) enum DisplayText<'a> { - IA5String(asn1::IA5String<'a>), - Utf8String(asn1::Utf8String<'a>), - VisibleString(asn1::VisibleString<'a>), - BmpString(asn1::BMPString<'a>), -} - fn parse_display_text( py: pyo3::Python<'_>, text: DisplayText<'_>, @@ -592,41 +511,6 @@ fn parse_cp(py: pyo3::Python<'_>, ext_data: &[u8]) -> Result = x509::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, GeneralSubtree<'a>>, - asn1::SequenceOfWriter<'a, GeneralSubtree<'a>, Vec>>, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct NameConstraints<'a> { - #[implicit(0)] - pub permitted_subtrees: Option>, - - #[implicit(1)] - pub excluded_subtrees: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct GeneralSubtree<'a> { - pub base: x509::GeneralName<'a>, - - #[implicit(0)] - #[default(0u64)] - pub minimum: u64, - - #[implicit(1)] - pub maximum: Option, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct MSCertificateTemplate { - pub template_id: asn1::ObjectIdentifier, - pub major_version: Option, - pub minor_version: Option, -} - fn parse_general_subtrees( py: pyo3::Python<'_>, subtrees: SequenceOfSubtrees<'_>, @@ -638,43 +522,6 @@ fn parse_general_subtrees( Ok(gns.to_object(py)) } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct DistributionPoint<'a> { - #[explicit(0)] - pub distribution_point: Option>, - - #[implicit(1)] - pub reasons: crl::ReasonFlags<'a>, - - #[implicit(2)] - pub crl_issuer: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) enum DistributionPointName<'a> { - #[implicit(0)] - FullName(x509::common::SequenceOfGeneralName<'a>), - - #[implicit(1)] - NameRelativeToCRLIssuer( - x509::Asn1ReadableOrWritable< - 'a, - asn1::SetOf<'a, x509::AttributeTypeValue<'a>>, - asn1::SetOfWriter<'a, x509::AttributeTypeValue<'a>, Vec>>, - >, - ), -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct AuthorityKeyIdentifier<'a> { - #[implicit(0)] - pub key_identifier: Option<&'a [u8]>, - #[implicit(1)] - pub authority_cert_issuer: Option>, - #[implicit(2)] - pub authority_cert_serial_number: Option>, -} - pub(crate) fn parse_distribution_point_name( py: pyo3::Python<'_>, dp: DistributionPointName<'_>, @@ -767,21 +614,6 @@ pub(crate) fn encode_distribution_point_reasons( Ok(asn1::OwnedBitString::new(bits, unused_bits).unwrap()) } -#[derive(asn1::Asn1Read, asn1::Asn1Write, pyo3::prelude::FromPyObject)] -pub(crate) struct BasicConstraints { - #[default(false)] - pub ca: bool, - pub path_length: Option, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct PolicyConstraints { - #[implicit(0)] - pub require_explicit_policy: Option, - #[implicit(1)] - pub inhibit_policy_mapping: Option, -} - pub(crate) fn parse_authority_key_identifier<'p>( py: pyo3::Python<'p>, ext_data: &[u8], @@ -807,7 +639,7 @@ pub(crate) fn parse_access_descriptions( ) -> Result { let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let ads = pyo3::types::PyList::empty(py); - let parsed = asn1::parse_single::>(ext_data)?; + let parsed = asn1::parse_single::>(ext_data)?; for access in parsed.unwrap_read().clone() { let py_oid = oid_to_py_oid(py, &access.access_method)?.to_object(py); let gn = x509::parse_general_name(py, access.access_location)?; @@ -829,7 +661,7 @@ pub fn parse_cert_ext<'p>( match oid { oid::SUBJECT_ALTERNATIVE_NAME_OID => { let gn_seq = - asn1::parse_single::>>(ext_data)?; + asn1::parse_single::>>(ext_data)?; let sans = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module @@ -839,7 +671,7 @@ pub fn parse_cert_ext<'p>( } oid::ISSUER_ALTERNATIVE_NAME_OID => { let gn_seq = - asn1::parse_single::>>(ext_data)?; + asn1::parse_single::>>(ext_data)?; let ians = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module @@ -1016,16 +848,18 @@ pub fn parse_cert_ext<'p>( pub(crate) fn time_from_py( py: pyo3::Python<'_>, val: &pyo3::PyAny, -) -> CryptographyResult { +) -> CryptographyResult { let dt = x509::py_to_datetime(py, val)?; time_from_datetime(dt) } -pub(crate) fn time_from_datetime(dt: asn1::DateTime) -> CryptographyResult { +pub(crate) fn time_from_datetime(dt: asn1::DateTime) -> CryptographyResult { if dt.year() >= 2050 { - Ok(x509::Time::GeneralizedTime(asn1::GeneralizedTime::new(dt)?)) + Ok(common::Time::GeneralizedTime(asn1::GeneralizedTime::new( + dt, + )?)) } else { - Ok(x509::Time::UtcTime(asn1::UtcTime::new(dt).unwrap())) + Ok(common::Time::UtcTime(asn1::UtcTime::new(dt).unwrap())) } } @@ -1065,7 +899,7 @@ fn create_x509_certificate( let py_not_before = builder.getattr(pyo3::intern!(py, "_not_valid_before"))?; let py_not_after = builder.getattr(pyo3::intern!(py, "_not_valid_after"))?; - let tbs_cert = TbsCertificate { + let tbs_cert = cryptography_x509::certificate::TbsCertificate { version: builder .getattr(pyo3::intern!(py, "_version"))? .getattr(pyo3::intern!(py, "value"))? @@ -1073,7 +907,7 @@ fn create_x509_certificate( serial: asn1::BigInt::new(py_uint_to_big_endian_bytes(py, py_serial)?).unwrap(), signature_alg: sigalg.clone(), issuer: x509::common::encode_name(py, py_issuer_name)?, - validity: Validity { + validity: cryptography_x509::certificate::Validity { not_before: time_from_py(py, py_not_before)?, not_after: time_from_py(py, py_not_after)?, }, @@ -1090,7 +924,7 @@ fn create_x509_certificate( let tbs_bytes = asn1::write_single(&tbs_cert)?; let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; - let data = asn1::write_single(&RawCertificate { + let data = asn1::write_single(&cryptography_x509::certificate::Certificate { tbs_cert, signature_alg: sigalg, signature: asn1::BitString::new(signature, 0).unwrap(), diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 3d4aec39cc71..4d977a921172 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -5,10 +5,14 @@ use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; +use cryptography_x509::common::{Asn1ReadableOrWritable, AttributeTypeValue, RawTlv}; +use cryptography_x509::extensions::{ + AccessDescription, Extension, Extensions, SequenceOfAccessDescriptions, +}; +use cryptography_x509::name::{GeneralName, Name, OtherName, UnvalidatedIA5String}; use pyo3::types::IntoPyDict; use pyo3::ToPyObject; use std::collections::HashSet; -use std::marker::PhantomData; /// Parse all sections in a PEM file and return the first matching section. /// If no matching sections are found, return an error. @@ -26,58 +30,6 @@ pub(crate) fn find_in_pem( }) } -pub(crate) type Name<'a> = Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, asn1::SetOf<'a, AttributeTypeValue<'a>>>, - asn1::SequenceOfWriter< - 'a, - asn1::SetOfWriter<'a, AttributeTypeValue<'a>, Vec>>, - Vec, Vec>>>, - >, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)] -pub(crate) struct AttributeTypeValue<'a> { - pub(crate) type_id: asn1::ObjectIdentifier, - pub(crate) value: RawTlv<'a>, -} - -// Like `asn1::Tlv` but doesn't store `full_data` so it can be constructed from -// an un-encoded tag and value. -#[derive(Hash, PartialEq, Eq, Clone)] -pub(crate) struct RawTlv<'a> { - tag: asn1::Tag, - value: &'a [u8], -} - -impl<'a> RawTlv<'a> { - pub(crate) fn new(tag: asn1::Tag, value: &'a [u8]) -> Self { - RawTlv { tag, value } - } - - pub(crate) fn tag(&self) -> asn1::Tag { - self.tag - } - pub(crate) fn data(&self) -> &'a [u8] { - self.value - } -} -impl<'a> asn1::Asn1Readable<'a> for RawTlv<'a> { - fn parse(parser: &mut asn1::Parser<'a>) -> asn1::ParseResult { - let tlv = parser.read_element::>()?; - Ok(RawTlv::new(tlv.tag(), tlv.data())) - } - - fn can_parse(_tag: asn1::Tag) -> bool { - true - } -} -impl<'a> asn1::Asn1Writable for RawTlv<'a> { - fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult { - w.write_tlv(self.tag, move |dest| dest.push_slice(self.value)) - } -} - pub(crate) fn encode_name<'p>( py: pyo3::Python<'p>, py_name: &'p pyo3::PyAny, @@ -145,73 +97,6 @@ fn encode_name_bytes<'p>( Ok(pyo3::types::PyBytes::new(py, &result)) } -/// An IA5String ASN.1 element whose contents is not validated as meeting the -/// requirements (ASCII characters only), and instead is only known to be -/// valid UTF-8. -pub(crate) struct UnvalidatedIA5String<'a>(pub(crate) &'a str); - -impl<'a> asn1::SimpleAsn1Readable<'a> for UnvalidatedIA5String<'a> { - const TAG: asn1::Tag = asn1::IA5String::TAG; - fn parse_data(data: &'a [u8]) -> asn1::ParseResult { - Ok(UnvalidatedIA5String(std::str::from_utf8(data).map_err( - |_| asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue), - )?)) - } -} - -impl<'a> asn1::SimpleAsn1Writable for UnvalidatedIA5String<'a> { - const TAG: asn1::Tag = asn1::IA5String::TAG; - fn write_data(&self, dest: &mut asn1::WriteBuf) -> asn1::WriteResult { - dest.push_slice(self.0.as_bytes()) - } -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] -pub(crate) struct OtherName<'a> { - pub(crate) type_id: asn1::ObjectIdentifier, - #[explicit(0, required)] - pub(crate) value: asn1::Tlv<'a>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) enum GeneralName<'a> { - #[implicit(0)] - OtherName(OtherName<'a>), - - #[implicit(1)] - RFC822Name(UnvalidatedIA5String<'a>), - - #[implicit(2)] - DNSName(UnvalidatedIA5String<'a>), - - #[implicit(3)] - // unsupported - X400Address(asn1::Sequence<'a>), - - // Name is explicit per RFC 5280 Appendix A.1. - #[explicit(4)] - DirectoryName(Name<'a>), - - #[implicit(5)] - // unsupported - EDIPartyName(asn1::Sequence<'a>), - - #[implicit(6)] - UniformResourceIdentifier(UnvalidatedIA5String<'a>), - - #[implicit(7)] - IPAddress(&'a [u8]), - - #[implicit(8)] - RegisteredID(asn1::ObjectIdentifier), -} - -pub(crate) type SequenceOfGeneralName<'a> = Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, GeneralName<'a>>, - asn1::SequenceOfWriter<'a, GeneralName<'a>, Vec>>, ->; - pub(crate) fn encode_general_names<'a>( py: pyo3::Python<'a>, py_gns: &'a pyo3::PyAny, @@ -271,18 +156,6 @@ pub(crate) fn encode_general_name<'a>( } } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct AccessDescription<'a> { - pub(crate) access_method: asn1::ObjectIdentifier, - pub(crate) access_location: GeneralName<'a>, -} - -pub(crate) type SequenceOfAccessDescriptions<'a> = Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, AccessDescription<'a>>, - asn1::SequenceOfWriter<'a, AccessDescription<'a>, Vec>>, ->; - pub(crate) fn encode_access_descriptions<'a>( py: pyo3::Python<'a>, py_ads: &'a pyo3::PyAny, @@ -303,41 +176,6 @@ pub(crate) fn encode_access_descriptions<'a>( )) } -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] -pub(crate) enum Time { - UtcTime(asn1::UtcTime), - GeneralizedTime(asn1::GeneralizedTime), -} - -impl Time { - pub(crate) fn as_datetime(&self) -> &asn1::DateTime { - match self { - Time::UtcTime(data) => data.as_datetime(), - Time::GeneralizedTime(data) => data.as_datetime(), - } - } -} - -pub(crate) type Extensions<'a> = Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, Extension<'a>>, - asn1::SequenceOfWriter<'a, Extension<'a>, Vec>>, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] -pub(crate) struct AlgorithmIdentifier<'a> { - pub(crate) oid: asn1::ObjectIdentifier, - pub(crate) params: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)] -pub(crate) struct Extension<'a> { - pub(crate) extn_id: asn1::ObjectIdentifier, - #[default(false)] - pub(crate) critical: bool, - pub(crate) extn_value: &'a [u8], -} - pub(crate) fn parse_name<'p>( py: pyo3::Python<'p>, name: &Name<'_>, @@ -723,77 +561,9 @@ pub(crate) fn datetime_now(py: pyo3::Python<'_>) -> pyo3::PyResult { - Read(T, PhantomData<&'a ()>), - Write(U, PhantomData<&'a ()>), -} - -impl<'a, T, U> Asn1ReadableOrWritable<'a, T, U> { - pub(crate) fn new_read(v: T) -> Self { - Asn1ReadableOrWritable::Read(v, PhantomData) - } - - pub(crate) fn new_write(v: U) -> Self { - Asn1ReadableOrWritable::Write(v, PhantomData) - } - - pub(crate) fn unwrap_read(&self) -> &T { - match self { - Asn1ReadableOrWritable::Read(v, _) => v, - Asn1ReadableOrWritable::Write(_, _) => panic!("unwrap_read called on a Write value"), - } - } -} - -impl<'a, T: asn1::SimpleAsn1Readable<'a>, U> asn1::SimpleAsn1Readable<'a> - for Asn1ReadableOrWritable<'a, T, U> -{ - const TAG: asn1::Tag = T::TAG; - fn parse_data(data: &'a [u8]) -> asn1::ParseResult { - Ok(Self::new_read(T::parse_data(data)?)) - } -} - -impl<'a, T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleAsn1Writable - for Asn1ReadableOrWritable<'a, T, U> -{ - const TAG: asn1::Tag = U::TAG; - fn write_data(&self, w: &mut asn1::WriteBuf) -> asn1::WriteResult { - match self { - Asn1ReadableOrWritable::Read(v, _) => T::write_data(v, w), - Asn1ReadableOrWritable::Write(v, _) => U::write_data(v, w), - } - } -} - pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { module.add_wrapped(pyo3::wrap_pyfunction!(encode_extension_value))?; module.add_wrapped(pyo3::wrap_pyfunction!(encode_name_bytes))?; Ok(()) } - -#[cfg(test)] -mod tests { - use super::{Asn1ReadableOrWritable, RawTlv}; - use asn1::Asn1Readable; - - #[test] - #[should_panic] - fn test_asn1_readable_or_writable_unwrap_read() { - Asn1ReadableOrWritable::::new_write(17).unwrap_read(); - } - - #[test] - fn test_asn1_readable_or_writable_write_read_data() { - let v = Asn1ReadableOrWritable::::new_read(17); - assert_eq!(&asn1::write_single(&v).unwrap(), b"\x02\x01\x11"); - } - - #[test] - fn test_raw_tlv_can_parse() { - let t = asn1::Tag::from_bytes(&[0]).unwrap().0; - assert!(RawTlv::can_parse(t)); - } -} diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index f5ab1b0c02da..ea04bb984766 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -7,7 +7,8 @@ use crate::asn1::{ }; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{certificate, extensions, oid, sign}; +use crate::x509::{certificate, extensions, sign}; +use cryptography_x509::{common, crl, name, oid}; use pyo3::{IntoPy, ToPyObject}; use std::sync::Arc; @@ -16,13 +17,13 @@ fn load_der_x509_crl( py: pyo3::Python<'_>, data: pyo3::Py, ) -> Result { - let raw = OwnedRawCertificateRevocationList::try_new( + let owned = OwnedCertificateRevocationList::try_new( data, |data| asn1::parse_single(data.as_bytes(py)), |_| Ok(pyo3::once_cell::GILOnceCell::new()), )?; - let version = raw.borrow_value().tbs_cert_list.version.unwrap_or(1); + let version = owned.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; return Err(CryptographyError::from(pyo3::PyErr::from_value( @@ -33,7 +34,7 @@ fn load_der_x509_crl( } Ok(CertificateRevocationList { - raw: Arc::new(raw), + owned: Arc::new(owned), cached_extensions: None, }) } @@ -55,41 +56,41 @@ fn load_pem_x509_crl( } #[ouroboros::self_referencing] -struct OwnedRawCertificateRevocationList { +struct OwnedCertificateRevocationList { data: pyo3::Py, #[borrows(data)] #[covariant] - value: RawCertificateRevocationList<'this>, + value: crl::CertificateRevocationList<'this>, #[borrows(data)] #[not_covariant] - revoked_certs: pyo3::once_cell::GILOnceCell>>, + revoked_certs: pyo3::once_cell::GILOnceCell>>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CertificateRevocationList { - raw: Arc, + owned: Arc, cached_extensions: Option, } impl CertificateRevocationList { fn public_bytes_der(&self) -> CryptographyResult> { - Ok(asn1::write_single(self.raw.borrow_value())?) + Ok(asn1::write_single(self.owned.borrow_value())?) } fn revoked_cert(&self, py: pyo3::Python<'_>, idx: usize) -> pyo3::PyResult { - let raw = try_map_arc_data_crl(&self.raw, |_crl, revoked_certs| { + let owned = try_map_arc_data_crl(&self.owned, |_crl, revoked_certs| { let revoked_certs = revoked_certs.get(py).unwrap(); Ok::<_, pyo3::PyErr>(revoked_certs[idx].clone()) })?; Ok(RevokedCertificate { - raw, + owned, cached_extensions: None, }) } fn len(&self) -> usize { - self.raw + self.owned .borrow_value() .tbs_cert_list .revoked_certificates @@ -106,8 +107,12 @@ impl CertificateRevocationList { op: pyo3::basic::CompareOp, ) -> pyo3::PyResult { match op { - pyo3::basic::CompareOp::Eq => Ok(self.raw.borrow_value() == other.raw.borrow_value()), - pyo3::basic::CompareOp::Ne => Ok(self.raw.borrow_value() != other.raw.borrow_value()), + pyo3::basic::CompareOp::Eq => { + Ok(self.owned.borrow_value() == other.owned.borrow_value()) + } + pyo3::basic::CompareOp::Ne => { + Ok(self.owned.borrow_value() != other.owned.borrow_value()) + } _ => Err(pyo3::exceptions::PyTypeError::new_err( "CRLs cannot be ordered", )), @@ -120,7 +125,7 @@ impl CertificateRevocationList { fn __iter__(&self) -> CRLIterator { CRLIterator { - contents: OwnedCRLIteratorData::try_new(Arc::clone(&self.raw), |v| { + contents: OwnedCRLIteratorData::try_new(Arc::clone(&self.owned), |v| { Ok::<_, ()>( v.borrow_value() .tbs_cert_list @@ -138,7 +143,7 @@ impl CertificateRevocationList { py: pyo3::Python<'_>, idx: &pyo3::PyAny, ) -> pyo3::PyResult { - self.raw.with(|val| { + self.owned.with(|val| { val.revoked_certs.get_or_init(py, || { match &val.value.tbs_cert_list.revoked_certificates { Some(c) => c.unwrap_read().clone().collect(), @@ -186,7 +191,7 @@ impl CertificateRevocationList { #[getter] fn signature_algorithm_oid<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - oid_to_py_oid(py, &self.raw.borrow_value().signature_algorithm.oid) + oid_to_py_oid(py, &self.owned.borrow_value().signature_algorithm.oid) } #[getter] @@ -206,7 +211,7 @@ impl CertificateRevocationList { "UnsupportedAlgorithm", (format!( "Signature algorithm OID:{} not recognized", - self.raw.borrow_value().signature_algorithm.oid + self.owned.borrow_value().signature_algorithm.oid ),), )?)), } @@ -214,7 +219,7 @@ impl CertificateRevocationList { #[getter] fn signature(&self) -> &[u8] { - self.raw.borrow_value().signature_value.as_bytes() + self.owned.borrow_value().signature_value.as_bytes() } #[getter] @@ -222,7 +227,7 @@ impl CertificateRevocationList { &self, py: pyo3::Python<'p>, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let b = asn1::write_single(&self.raw.borrow_value().tbs_cert_list)?; + let b = asn1::write_single(&self.owned.borrow_value().tbs_cert_list)?; Ok(pyo3::types::PyBytes::new(py, &b)) } @@ -231,7 +236,7 @@ impl CertificateRevocationList { py: pyo3::Python<'p>, encoding: &'p pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let result = asn1::write_single(self.raw.borrow_value())?; + let result = asn1::write_single(self.owned.borrow_value())?; encode_der_data(py, "X509 CRL".to_string(), result, encoding) } @@ -240,13 +245,13 @@ impl CertificateRevocationList { fn issuer<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { Ok(x509::parse_name( py, - &self.raw.borrow_value().tbs_cert_list.issuer, + &self.owned.borrow_value().tbs_cert_list.issuer, )?) } #[getter] fn next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - match &self.raw.borrow_value().tbs_cert_list.next_update { + match &self.owned.borrow_value().tbs_cert_list.next_update { Some(t) => x509::datetime_to_py(py, t.as_datetime()), None => Ok(py.None().into_ref(py)), } @@ -256,7 +261,7 @@ impl CertificateRevocationList { fn last_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { x509::datetime_to_py( py, - self.raw + self.owned .borrow_value() .tbs_cert_list .this_update @@ -270,7 +275,7 @@ impl CertificateRevocationList { x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.raw.borrow_value().tbs_cert_list.crl_extensions, + &self.owned.borrow_value().tbs_cert_list.crl_extensions, |oid, ext_data| match *oid { oid::CRL_NUMBER_OID => { let bignum = asn1::parse_single::>(ext_data)?; @@ -291,7 +296,7 @@ impl CertificateRevocationList { )) } oid::ISSUER_ALTERNATIVE_NAME_OID => { - let gn_seq = asn1::parse_single::>>( + let gn_seq = asn1::parse_single::>>( ext_data, )?; let ians = x509::parse_general_names(py, &gn_seq)?; @@ -313,7 +318,7 @@ impl CertificateRevocationList { certificate::parse_authority_key_identifier(py, ext_data)?, )), oid::ISSUING_DISTRIBUTION_POINT_OID => { - let idp = asn1::parse_single::>(ext_data)?; + let idp = asn1::parse_single::>(ext_data)?; let (full_name, relative_name) = match idp.distribution_point { Some(data) => certificate::parse_distribution_point_name(py, data)?, None => (py.None(), py.None()), @@ -359,7 +364,7 @@ impl CertificateRevocationList { serial: &pyo3::types::PyLong, ) -> pyo3::PyResult> { let serial_bytes = py_uint_to_big_endian_bytes(py, serial)?; - let owned = OwnedRawRevokedCertificate::try_new(Arc::clone(&self.raw), |v| { + let owned = OwnedRevokedCertificate::try_new(Arc::clone(&self.owned), |v| { let certs = match &v.borrow_value().tbs_cert_list.revoked_certificates { Some(certs) => certs.unwrap_read().clone(), None => return Err(()), @@ -375,7 +380,7 @@ impl CertificateRevocationList { }); match owned { Ok(o) => Ok(Some(RevokedCertificate { - raw: o, + owned: o, cached_extensions: None, })), Err(()) => Ok(None), @@ -387,8 +392,8 @@ impl CertificateRevocationList { py: pyo3::Python<'p>, public_key: &'p pyo3::PyAny, ) -> CryptographyResult { - if slf.raw.borrow_value().tbs_cert_list.signature - != slf.raw.borrow_value().signature_algorithm + if slf.owned.borrow_value().tbs_cert_list.signature + != slf.owned.borrow_value().signature_algorithm { return Ok(false); }; @@ -400,9 +405,9 @@ impl CertificateRevocationList { Ok(sign::verify_signature_with_oid( py, public_key, - &slf.raw.borrow_value().signature_algorithm.oid, - slf.raw.borrow_value().signature_value.as_bytes(), - &asn1::write_single(&slf.raw.borrow_value().tbs_cert_list)?, + &slf.owned.borrow_value().signature_algorithm.oid, + slf.owned.borrow_value().signature_value.as_bytes(), + &asn1::write_single(&slf.owned.borrow_value().tbs_cert_list)?, ) .is_ok()) } @@ -410,10 +415,10 @@ impl CertificateRevocationList { #[ouroboros::self_referencing] struct OwnedCRLIteratorData { - data: Arc, + data: Arc, #[borrows(data)] #[covariant] - value: Option>>, + value: Option>>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] @@ -424,13 +429,13 @@ struct CRLIterator { // Open-coded implementation of the API discussed in // https://github.com/joshua-maros/ouroboros/issues/38 fn try_map_arc_data_crl( - crl: &Arc, + crl: &Arc, f: impl for<'this> FnOnce( - &'this OwnedRawCertificateRevocationList, - &pyo3::once_cell::GILOnceCell>>, - ) -> Result, E>, -) -> Result { - OwnedRawRevokedCertificate::try_new(Arc::clone(crl), |inner_crl| { + &'this OwnedCertificateRevocationList, + &pyo3::once_cell::GILOnceCell>>, + ) -> Result, E>, +) -> Result { + OwnedRevokedCertificate::try_new(Arc::clone(crl), |inner_crl| { crl.with(|value| { f(inner_crl, unsafe { std::mem::transmute(value.revoked_certs) @@ -441,11 +446,11 @@ fn try_map_arc_data_crl( fn try_map_arc_data_mut_crl_iterator( it: &mut OwnedCRLIteratorData, f: impl for<'this> FnOnce( - &'this OwnedRawCertificateRevocationList, - &mut Option>>, - ) -> Result, E>, -) -> Result { - OwnedRawRevokedCertificate::try_new(Arc::clone(it.borrow_data()), |inner_it| { + &'this OwnedCertificateRevocationList, + &mut Option>>, + ) -> Result, E>, +) -> Result { + OwnedRevokedCertificate::try_new(Arc::clone(it.borrow_data()), |inner_it| { it.with_value_mut(|value| f(inner_it, unsafe { std::mem::transmute(value) })) }) } @@ -470,57 +475,23 @@ impl CRLIterator { }) .ok()?; Some(RevokedCertificate { - raw: revoked, + owned: revoked, cached_extensions: None, }) } } -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] -struct RawCertificateRevocationList<'a> { - tbs_cert_list: TBSCertList<'a>, - signature_algorithm: x509::AlgorithmIdentifier<'a>, - signature_value: asn1::BitString<'a>, -} - -type RevokedCertificates<'a> = Option< - x509::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, RawRevokedCertificate<'a>>, - asn1::SequenceOfWriter<'a, RawRevokedCertificate<'a>, Vec>>, - >, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)] -struct TBSCertList<'a> { - version: Option, - signature: x509::AlgorithmIdentifier<'a>, - issuer: x509::Name<'a>, - this_update: x509::Time, - next_update: Option, - revoked_certificates: RevokedCertificates<'a>, - #[explicit(0)] - crl_extensions: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] -struct RawRevokedCertificate<'a> { - user_certificate: asn1::BigUint<'a>, - revocation_date: x509::Time, - crl_entry_extensions: Option>, -} - #[ouroboros::self_referencing] -struct OwnedRawRevokedCertificate { - data: Arc, +struct OwnedRevokedCertificate { + data: Arc, #[borrows(data)] #[covariant] - value: RawRevokedCertificate<'this>, + value: crl::RevokedCertificate<'this>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct RevokedCertificate { - raw: OwnedRawRevokedCertificate, + owned: OwnedRevokedCertificate, cached_extensions: Option, } @@ -528,12 +499,12 @@ struct RevokedCertificate { impl RevokedCertificate { #[getter] fn serial_number<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - big_byte_slice_to_py_int(py, self.raw.borrow_value().user_certificate.as_bytes()) + big_byte_slice_to_py_int(py, self.owned.borrow_value().user_certificate.as_bytes()) } #[getter] fn revocation_date<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - x509::datetime_to_py(py, self.raw.borrow_value().revocation_date.as_datetime()) + x509::datetime_to_py(py, self.owned.borrow_value().revocation_date.as_datetime()) } #[getter] @@ -541,45 +512,15 @@ impl RevokedCertificate { x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.raw.borrow_value().crl_entry_extensions, + &self.owned.borrow_value().crl_entry_extensions, |oid, ext_data| parse_crl_entry_ext(py, oid.clone(), ext_data), ) } } -pub(crate) type ReasonFlags<'a> = - Option, asn1::OwnedBitString>>; - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct IssuingDistributionPoint<'a> { - #[explicit(0)] - pub distribution_point: Option>, - - #[implicit(1)] - #[default(false)] - pub only_contains_user_certs: bool, - - #[implicit(2)] - #[default(false)] - pub only_contains_ca_certs: bool, - - #[implicit(3)] - pub only_some_reasons: ReasonFlags<'a>, - - #[implicit(4)] - #[default(false)] - pub indirect_crl: bool, - - #[implicit(5)] - #[default(false)] - pub only_contains_attribute_certs: bool, -} - -pub(crate) type CRLReason = asn1::Enumerated; - pub(crate) fn parse_crl_reason_flags<'p>( py: pyo3::Python<'p>, - reason: &CRLReason, + reason: &crl::CRLReason, ) -> CryptographyResult<&'p pyo3::PyAny> { let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let flag_name = match reason.value() { @@ -615,7 +556,7 @@ pub fn parse_crl_entry_ext<'p>( let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; match oid { oid::CRL_REASON_OID => { - let flags = parse_crl_reason_flags(py, &asn1::parse_single::(data)?)?; + let flags = parse_crl_reason_flags(py, &asn1::parse_single::(data)?)?; Ok(Some( x509_module .getattr(pyo3::intern!(py, "CRLReason"))? @@ -623,7 +564,7 @@ pub fn parse_crl_entry_ext<'p>( )) } oid::CERTIFICATE_ISSUER_OID => { - let gn_seq = asn1::parse_single::>>(data)?; + let gn_seq = asn1::parse_single::>>(data)?; let gns = x509::parse_general_names(py, &gn_seq)?; Ok(Some( x509_module @@ -663,7 +604,7 @@ fn create_x509_crl( .getattr(pyo3::intern!(py, "serial_number"))? .extract()?; let py_revocation_date = py_revoked_cert.getattr(pyo3::intern!(py, "revocation_date"))?; - revoked_certs.push(RawRevokedCertificate { + revoked_certs.push(crl::RevokedCertificate { user_certificate: asn1::BigUint::new(py_uint_to_big_endian_bytes(py, serial_number)?) .unwrap(), revocation_date: x509::certificate::time_from_py(py, py_revocation_date)?, @@ -678,7 +619,7 @@ fn create_x509_crl( let py_issuer_name = builder.getattr(pyo3::intern!(py, "_issuer_name"))?; let py_this_update = builder.getattr(pyo3::intern!(py, "_last_update"))?; let py_next_update = builder.getattr(pyo3::intern!(py, "_next_update"))?; - let tbs_cert_list = TBSCertList { + let tbs_cert_list = crl::TBSCertList { version: Some(1), signature: sigalg.clone(), issuer: x509::common::encode_name(py, py_issuer_name)?, @@ -687,7 +628,7 @@ fn create_x509_crl( revoked_certificates: if revoked_certs.is_empty() { None } else { - Some(x509::Asn1ReadableOrWritable::new_write( + Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(revoked_certs), )) }, @@ -700,7 +641,7 @@ fn create_x509_crl( let tbs_bytes = asn1::write_single(&tbs_cert_list)?; let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; - let data = asn1::write_single(&RawCertificateRevocationList { + let data = asn1::write_single(&crl::CertificateRevocationList { tbs_cert_list, signature_algorithm: sigalg, signature_value: asn1::BitString::new(signature, 0).unwrap(), diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 2122018e069c..6de3667ae4fd 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -5,83 +5,25 @@ use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{certificate, oid, sign}; +use crate::x509::{certificate, sign}; use asn1::SimpleAsn1Readable; +use cryptography_x509::csr::{check_attribute_length, Attribute, CertificationRequestInfo, Csr}; +use cryptography_x509::{common, oid}; use pyo3::IntoPy; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct RawCsr<'a> { - csr_info: CertificationRequestInfo<'a>, - signature_alg: x509::AlgorithmIdentifier<'a>, - signature: asn1::BitString<'a>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct CertificationRequestInfo<'a> { - version: u8, - subject: x509::Name<'a>, - spki: certificate::SubjectPublicKeyInfo<'a>, - #[implicit(0, required)] - attributes: Attributes<'a>, -} - -pub(crate) type Attributes<'a> = x509::Asn1ReadableOrWritable< - 'a, - asn1::SetOf<'a, Attribute<'a>>, - asn1::SetOfWriter<'a, Attribute<'a>, Vec>>, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct Attribute<'a> { - pub(crate) type_id: asn1::ObjectIdentifier, - pub(crate) values: x509::Asn1ReadableOrWritable< - 'a, - asn1::SetOf<'a, asn1::Tlv<'a>>, - asn1::SetOfWriter<'a, x509::common::RawTlv<'a>, [x509::common::RawTlv<'a>; 1]>, - >, -} - -fn check_attribute_length<'a>( - values: asn1::SetOf<'a, asn1::Tlv<'a>>, -) -> Result<(), CryptographyError> { - if values.count() > 1 { - Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err("Only single-valued attributes are supported"), - )) - } else { - Ok(()) - } -} - -impl CertificationRequestInfo<'_> { - fn get_extension_attribute(&self) -> Result>, CryptographyError> { - for attribute in self.attributes.unwrap_read().clone() { - if attribute.type_id == oid::EXTENSION_REQUEST - || attribute.type_id == oid::MS_EXTENSION_REQUEST - { - check_attribute_length(attribute.values.unwrap_read().clone())?; - let val = attribute.values.unwrap_read().clone().next().unwrap(); - let exts = asn1::parse_single(val.full_data())?; - return Ok(Some(exts)); - } - } - Ok(None) - } -} - #[ouroboros::self_referencing] -struct OwnedRawCsr { +struct OwnedCsr { data: pyo3::Py, #[borrows(data)] #[covariant] - value: RawCsr<'this>, + value: Csr<'this>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CertificateSigningRequest { - raw: OwnedRawCsr, + raw: OwnedCsr, cached_extensions: Option, } @@ -212,7 +154,11 @@ impl CertificateSigningRequest { .clone() { if rust_oid == attribute.type_id { - check_attribute_length(attribute.values.unwrap_read().clone())?; + check_attribute_length(attribute.values.unwrap_read().clone()).map_err(|_| { + pyo3::exceptions::PyValueError::new_err( + "Only single-valued attributes are supported", + ) + })?; let val = attribute.values.unwrap_read().clone().next().unwrap(); // We allow utf8string, printablestring, and ia5string at this time if val.tag() == asn1::Utf8String::TAG @@ -248,7 +194,11 @@ impl CertificateSigningRequest { .unwrap_read() .clone() { - check_attribute_length(attribute.values.unwrap_read().clone())?; + check_attribute_length(attribute.values.unwrap_read().clone()).map_err(|_| { + pyo3::exceptions::PyValueError::new_err( + "Only single-valued attributes are supported", + ) + })?; let oid = oid_to_py_oid(py, &attribute.type_id)?; let val = attribute.values.unwrap_read().clone().next().unwrap(); let serialized = pyo3::types::PyBytes::new(py, val.data()); @@ -268,7 +218,16 @@ impl CertificateSigningRequest { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { - let exts = self.raw.borrow_value().csr_info.get_extension_attribute()?; + let exts = self + .raw + .borrow_value() + .csr_info + .get_extension_attribute() + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err( + "Only single-valued attributes are supported", + ) + })?; x509::parse_and_cache_extensions(py, &mut self.cached_extensions, &exts, |oid, ext_data| { certificate::parse_cert_ext(py, oid.clone(), ext_data) @@ -314,7 +273,7 @@ fn load_der_x509_csr( py: pyo3::Python<'_>, data: pyo3::Py, ) -> CryptographyResult { - let raw = OwnedRawCsr::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; + let raw = OwnedCsr::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; let version = raw.borrow_value().csr_info.version; if version != 0 { @@ -369,7 +328,7 @@ fn create_x509_csr( ext_bytes = asn1::write_single(&exts)?; attrs.push(Attribute { type_id: (oid::EXTENSION_REQUEST).clone(), - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ asn1::parse_single(&ext_bytes)?, ])), }) @@ -393,8 +352,8 @@ fn create_x509_csr( attrs.push(Attribute { type_id: oid, - values: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ - x509::common::RawTlv::new(tag, value), + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + common::RawTlv::new(tag, value), ])), }) } @@ -405,12 +364,12 @@ fn create_x509_csr( version: 0, subject: x509::common::encode_name(py, py_subject_name)?, spki: asn1::parse_single(spki_bytes)?, - attributes: x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(attrs)), + attributes: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(attrs)), }; let tbs_bytes = asn1::write_single(&csr_info)?; let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; - let data = asn1::write_single(&RawCsr { + let data = asn1::write_single(&Csr { csr_info, signature_alg: sigalg, signature: asn1::BitString::new(signature, 0).unwrap(), diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 84009b0c7c48..08e112cbbcf5 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -5,25 +5,26 @@ use crate::asn1::{py_oid_to_oid, py_uint_to_big_endian_bytes}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{certificate, crl, oid, sct}; +use crate::x509::{certificate, sct}; +use cryptography_x509::{common, crl, extensions, oid}; fn encode_general_subtrees<'a>( py: pyo3::Python<'a>, subtrees: &'a pyo3::PyAny, -) -> Result>, CryptographyError> { +) -> Result>, CryptographyError> { if subtrees.is_none() { Ok(None) } else { let mut subtree_seq = vec![]; for name in subtrees.iter()? { let gn = x509::common::encode_general_name(py, name?)?; - subtree_seq.push(certificate::GeneralSubtree { + subtree_seq.push(extensions::GeneralSubtree { base: gn, minimum: 0, maximum: None, }); } - Ok(Some(x509::Asn1ReadableOrWritable::new_write( + Ok(Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(subtree_seq), ))) } @@ -32,7 +33,7 @@ fn encode_general_subtrees<'a>( pub(crate) fn encode_authority_key_identifier<'a>( py: pyo3::Python<'a>, py_aki: &'a pyo3::PyAny, -) -> pyo3::PyResult> { +) -> pyo3::PyResult> { #[derive(pyo3::prelude::FromPyObject)] struct PyAuthorityKeyIdentifier<'a> { key_identifier: Option<&'a [u8]>, @@ -42,7 +43,7 @@ pub(crate) fn encode_authority_key_identifier<'a>( let aki = py_aki.extract::>()?; let authority_cert_issuer = if let Some(authority_cert_issuer) = aki.authority_cert_issuer { let gns = x509::common::encode_general_names(py, authority_cert_issuer)?; - Some(x509::Asn1ReadableOrWritable::new_write( + Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(gns), )) } else { @@ -55,7 +56,7 @@ pub(crate) fn encode_authority_key_identifier<'a>( } else { None }; - Ok(certificate::AuthorityKeyIdentifier { + Ok(extensions::AuthorityKeyIdentifier { authority_cert_issuer, authority_cert_serial_number, key_identifier: aki.key_identifier, @@ -65,7 +66,7 @@ pub(crate) fn encode_authority_key_identifier<'a>( pub(crate) fn encode_distribution_points<'p>( py: pyo3::Python<'p>, py_dps: &'p pyo3::PyAny, -) -> pyo3::PyResult>> { +) -> pyo3::PyResult>> { #[derive(pyo3::prelude::FromPyObject)] struct PyDistributionPoint<'a> { crl_issuer: Option<&'a pyo3::PyAny>, @@ -80,7 +81,7 @@ pub(crate) fn encode_distribution_points<'p>( let crl_issuer = if let Some(py_crl_issuer) = py_dp.crl_issuer { let gns = x509::common::encode_general_names(py, py_crl_issuer)?; - Some(x509::Asn1ReadableOrWritable::new_write( + Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(gns), )) } else { @@ -88,27 +89,27 @@ pub(crate) fn encode_distribution_points<'p>( }; let distribution_point = if let Some(py_full_name) = py_dp.full_name { let gns = x509::common::encode_general_names(py, py_full_name)?; - Some(certificate::DistributionPointName::FullName( - x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), + Some(extensions::DistributionPointName::FullName( + common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), )) } else if let Some(py_relative_name) = py_dp.relative_name { let mut name_entries = vec![]; for py_name_entry in py_relative_name.iter()? { name_entries.push(x509::common::encode_name_entry(py, py_name_entry?)?); } - Some(certificate::DistributionPointName::NameRelativeToCRLIssuer( - x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), + Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( + common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), )) } else { None }; let reasons = if let Some(py_reasons) = py_dp.reasons { let reasons = certificate::encode_distribution_point_reasons(py, py_reasons)?; - Some(x509::Asn1ReadableOrWritable::new_write(reasons)) + Some(common::Asn1ReadableOrWritable::new_write(reasons)) } else { None }; - dps.push(certificate::DistributionPoint { + dps.push(extensions::DistributionPoint { crl_issuer, distribution_point, reasons, @@ -124,7 +125,16 @@ pub(crate) fn encode_extension( ) -> CryptographyResult>> { match oid { &oid::BASIC_CONSTRAINTS_OID => { - let bc = ext.extract::()?; + #[derive(pyo3::prelude::FromPyObject)] + struct PyBasicConstraints { + ca: bool, + path_length: Option, + } + let pybc = ext.extract::()?; + let bc = extensions::BasicConstraints { + ca: pybc.ca, + path_length: pybc.path_length, + }; Ok(Some(asn1::write_single(&bc)?)) } &oid::SUBJECT_KEY_IDENTIFIER_OID => { @@ -232,9 +242,9 @@ pub(crate) fn encode_extension( .into()) } }; - certificate::PolicyQualifierInfo { + extensions::PolicyQualifierInfo { policy_qualifier_id: (oid::CP_CPS_URI_OID).clone(), - qualifier: certificate::Qualifier::CpsUri(cps_uri), + qualifier: extensions::Qualifier::CpsUri(cps_uri), } } else { let py_notice = @@ -250,15 +260,15 @@ pub(crate) fn encode_extension( notice_numbers.push(asn1::BigUint::new(bytes).unwrap()); } - Some(certificate::NoticeReference { - organization: certificate::DisplayText::Utf8String( + Some(extensions::NoticeReference { + organization: extensions::DisplayText::Utf8String( asn1::Utf8String::new( py_notice .getattr(pyo3::intern!(py, "organization"))? .extract()?, ), ), - notice_numbers: x509::Asn1ReadableOrWritable::new_write( + notice_numbers: common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(notice_numbers), ), }) @@ -268,17 +278,17 @@ pub(crate) fn encode_extension( let py_explicit_text = py_qualifier.getattr(pyo3::intern!(py, "explicit_text"))?; let explicit_text = if py_explicit_text.is_true()? { - Some(certificate::DisplayText::Utf8String(asn1::Utf8String::new( + Some(extensions::DisplayText::Utf8String(asn1::Utf8String::new( py_explicit_text.extract()?, ))) } else { None }; - certificate::PolicyQualifierInfo { + extensions::PolicyQualifierInfo { policy_qualifier_id: (oid::CP_USER_NOTICE_OID).clone(), - qualifier: certificate::Qualifier::UserNotice( - certificate::UserNotice { + qualifier: extensions::Qualifier::UserNotice( + extensions::UserNotice { notice_ref, explicit_text, }, @@ -287,7 +297,7 @@ pub(crate) fn encode_extension( }; qualifiers.push(qualifier); } - Some(x509::Asn1ReadableOrWritable::new_write( + Some(common::Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(qualifiers), )) } else { @@ -295,7 +305,7 @@ pub(crate) fn encode_extension( }; let py_policy_id = py_policy_info.getattr(pyo3::intern!(py, "policy_identifier"))?; - policy_informations.push(certificate::PolicyInformation { + policy_informations.push(extensions::PolicyInformation { policy_identifier: py_oid_to_oid(py_policy_id)?, policy_qualifiers: qualifiers, }); @@ -305,7 +315,7 @@ pub(crate) fn encode_extension( ))?)) } &oid::POLICY_CONSTRAINTS_OID => { - let pc = certificate::PolicyConstraints { + let pc = extensions::PolicyConstraints { require_explicit_policy: ext .getattr(pyo3::intern!(py, "require_explicit_policy"))? .extract()?, @@ -318,7 +328,7 @@ pub(crate) fn encode_extension( &oid::NAME_CONSTRAINTS_OID => { let permitted = ext.getattr(pyo3::intern!(py, "permitted_subtrees"))?; let excluded = ext.getattr(pyo3::intern!(py, "excluded_subtrees"))?; - let nc = certificate::NameConstraints { + let nc = extensions::NameConstraints { permitted_subtrees: encode_general_subtrees(ext.py(), permitted)?, excluded_subtrees: encode_general_subtrees(ext.py(), excluded)?, }; @@ -412,23 +422,23 @@ pub(crate) fn encode_extension( { let py_reasons = ext.getattr(pyo3::intern!(py, "only_some_reasons"))?; let reasons = certificate::encode_distribution_point_reasons(ext.py(), py_reasons)?; - Some(x509::Asn1ReadableOrWritable::new_write(reasons)) + Some(common::Asn1ReadableOrWritable::new_write(reasons)) } else { None }; let distribution_point = if ext.getattr(pyo3::intern!(py, "full_name"))?.is_true()? { let py_full_name = ext.getattr(pyo3::intern!(py, "full_name"))?; let gns = x509::common::encode_general_names(ext.py(), py_full_name)?; - Some(certificate::DistributionPointName::FullName( - x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), + Some(extensions::DistributionPointName::FullName( + common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), )) } else if ext.getattr(pyo3::intern!(py, "relative_name"))?.is_true()? { let mut name_entries = vec![]; for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? { name_entries.push(x509::common::encode_name_entry(ext.py(), py_name_entry?)?); } - Some(certificate::DistributionPointName::NameRelativeToCRLIssuer( - x509::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), + Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( + common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), )) } else { None @@ -458,7 +468,7 @@ pub(crate) fn encode_extension( } &oid::MS_CERTIFICATE_TEMPLATE => { let py_template_id = ext.getattr(pyo3::intern!(py, "template_id"))?; - let mstpl = certificate::MSCertificateTemplate { + let mstpl = extensions::MSCertificateTemplate { template_id: py_oid_to_oid(py_template_id)?, major_version: ext.getattr(pyo3::intern!(py, "major_version"))?.extract()?, minor_version: ext.getattr(pyo3::intern!(py, "minor_version"))?.extract()?, diff --git a/src/rust/src/x509/mod.rs b/src/rust/src/x509/mod.rs index 2ad15c6e6dbc..c43bf9023e71 100644 --- a/src/rust/src/x509/mod.rs +++ b/src/rust/src/x509/mod.rs @@ -10,13 +10,10 @@ pub(crate) mod extensions; pub(crate) mod ocsp; pub(crate) mod ocsp_req; pub(crate) mod ocsp_resp; -pub(crate) mod oid; pub(crate) mod sct; pub(crate) mod sign; -pub(crate) use certificate::Certificate; pub(crate) use common::{ datetime_to_py, find_in_pem, parse_and_cache_extensions, parse_general_name, - parse_general_names, parse_name, parse_rdn, py_to_datetime, AlgorithmIdentifier, - Asn1ReadableOrWritable, AttributeTypeValue, Extensions, GeneralName, Name, Time, + parse_general_names, parse_name, parse_rdn, py_to_datetime, }; diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index e3568ca9df8b..b362ef326d8d 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -4,7 +4,9 @@ use crate::error::CryptographyResult; use crate::x509; -use crate::x509::oid; +use crate::x509::certificate::Certificate; +use cryptography_x509::ocsp_req::CertID; +use cryptography_x509::{common, oid}; use once_cell::sync::Lazy; use std::collections::HashMap; @@ -28,69 +30,59 @@ pub(crate) static HASH_NAME_TO_OIDS: Lazy h }); -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -pub(crate) struct CertID<'a> { - pub(crate) hash_algorithm: x509::AlgorithmIdentifier<'a>, - pub(crate) issuer_name_hash: &'a [u8], - pub(crate) issuer_key_hash: &'a [u8], - pub(crate) serial_number: asn1::BigInt<'a>, -} - -impl CertID<'_> { - pub(crate) fn new<'p>( - py: pyo3::Python<'p>, - cert: &'p x509::Certificate, - issuer: &'p x509::Certificate, - hash_algorithm: &'p pyo3::PyAny, - ) -> CryptographyResult> { - let issuer_der = asn1::write_single(&cert.raw.borrow_value_public().tbs_cert.issuer)?; - let issuer_name_hash = hash_data(py, hash_algorithm, &issuer_der)?; - let issuer_key_hash = hash_data( - py, - hash_algorithm, - issuer - .raw - .borrow_value_public() - .tbs_cert - .spki - .subject_public_key - .as_bytes(), - )?; +pub(crate) fn certid_new<'p>( + py: pyo3::Python<'p>, + cert: &'p Certificate, + issuer: &'p Certificate, + hash_algorithm: &'p pyo3::PyAny, +) -> CryptographyResult> { + let issuer_der = asn1::write_single(&cert.raw.borrow_value_public().tbs_cert.issuer)?; + let issuer_name_hash = hash_data(py, hash_algorithm, &issuer_der)?; + let issuer_key_hash = hash_data( + py, + hash_algorithm, + issuer + .raw + .borrow_value_public() + .tbs_cert + .spki + .subject_public_key + .as_bytes(), + )?; - Ok(CertID { - hash_algorithm: x509::AlgorithmIdentifier { - oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - params: Some(*x509::sign::NULL_TLV), - }, - issuer_name_hash, - issuer_key_hash, - serial_number: cert.raw.borrow_value_public().tbs_cert.serial, - }) - } + Ok(CertID { + hash_algorithm: common::AlgorithmIdentifier { + oid: HASH_NAME_TO_OIDS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), + params: Some(*x509::sign::NULL_TLV), + }, + issuer_name_hash, + issuer_key_hash, + serial_number: cert.raw.borrow_value_public().tbs_cert.serial, + }) +} - pub(crate) fn new_from_hash<'p>( - py: pyo3::Python<'p>, - issuer_name_hash: &'p [u8], - issuer_key_hash: &'p [u8], - serial_number: asn1::BigInt<'p>, - hash_algorithm: &'p pyo3::PyAny, - ) -> CryptographyResult> { - Ok(CertID { - hash_algorithm: x509::AlgorithmIdentifier { - oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - params: Some(*x509::sign::NULL_TLV), - }, - issuer_name_hash, - issuer_key_hash, - serial_number, - }) - } +pub(crate) fn certid_new_from_hash<'p>( + py: pyo3::Python<'p>, + issuer_name_hash: &'p [u8], + issuer_key_hash: &'p [u8], + serial_number: asn1::BigInt<'p>, + hash_algorithm: &'p pyo3::PyAny, +) -> CryptographyResult> { + Ok(CertID { + hash_algorithm: common::AlgorithmIdentifier { + oid: HASH_NAME_TO_OIDS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), + params: Some(*x509::sign::NULL_TLV), + }, + issuer_name_hash, + issuer_key_hash, + serial_number, + }) } pub(crate) fn hash_data<'p>( diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index afd939d478f4..856c60c93d9a 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -5,15 +5,16 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, py_uint_to_big_endian_bytes}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{extensions, ocsp, oid}; +use crate::x509::{extensions, ocsp}; +use cryptography_x509::{common, ocsp_req, oid}; use pyo3::IntoPy; #[ouroboros::self_referencing] -struct OwnedRawOCSPRequest { +struct OwnedOCSPRequest { data: pyo3::Py, #[borrows(data)] #[covariant] - value: RawOCSPRequest<'this>, + value: ocsp_req::OCSPRequest<'this>, } #[pyo3::prelude::pyfunction] @@ -21,7 +22,7 @@ fn load_der_ocsp_request( py: pyo3::Python<'_>, data: pyo3::Py, ) -> CryptographyResult { - let raw = OwnedRawOCSPRequest::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; + let raw = OwnedOCSPRequest::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; if raw .borrow_value() @@ -46,13 +47,13 @@ fn load_der_ocsp_request( #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPRequest { - raw: OwnedRawOCSPRequest, + raw: OwnedOCSPRequest, cached_extensions: Option, } impl OCSPRequest { - fn cert_id(&self) -> ocsp::CertID<'_> { + fn cert_id(&self) -> ocsp_req::CertID<'_> { self.raw .borrow_value() .tbs_request @@ -174,39 +175,6 @@ impl OCSPRequest { } } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct RawOCSPRequest<'a> { - tbs_request: TBSRequest<'a>, - // Parsing out the full structure, which includes the entirety of a - // certificate is more trouble than it's worth, since it's not in the - // Python API. - #[explicit(0)] - optional_signature: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct TBSRequest<'a> { - #[explicit(0)] - #[default(0)] - version: u8, - #[explicit(1)] - requestor_name: Option>, - request_list: x509::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, Request<'a>>, - asn1::SequenceOfWriter<'a, Request<'a>>, - >, - #[explicit(2)] - request_extensions: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct Request<'a> { - req_cert: ocsp::CertID<'a>, - #[explicit(0)] - single_request_extensions: Option>, -} - #[pyo3::prelude::pyfunction] fn create_ocsp_request( py: pyo3::Python<'_>, @@ -216,20 +184,20 @@ fn create_ocsp_request( // Declare outside the if-block so the lifetimes are right. let (py_cert, py_issuer, py_hash): ( - pyo3::PyRef<'_, x509::Certificate>, - pyo3::PyRef<'_, x509::Certificate>, + pyo3::PyRef<'_, x509::certificate::Certificate>, + pyo3::PyRef<'_, x509::certificate::Certificate>, &pyo3::PyAny, ); let req_cert = if !builder_request.is_none() { let tuple = builder_request.extract::<( - pyo3::PyRef<'_, x509::Certificate>, - pyo3::PyRef<'_, x509::Certificate>, + pyo3::PyRef<'_, x509::certificate::Certificate>, + pyo3::PyRef<'_, x509::certificate::Certificate>, &pyo3::PyAny, )>()?; py_cert = tuple.0; py_issuer = tuple.1; py_hash = tuple.2; - ocsp::CertID::new(py, &py_cert, &py_issuer, py_hash)? + ocsp::certid_new(py, &py_cert, &py_issuer, py_hash)? } else { let (issuer_name_hash, issuer_key_hash, py_serial, py_hash): ( &[u8], @@ -240,7 +208,7 @@ fn create_ocsp_request( .getattr(pyo3::intern!(py, "_request_hash"))? .extract()?; let serial_number = asn1::BigInt::new(py_uint_to_big_endian_bytes(py, py_serial)?).unwrap(); - ocsp::CertID::new_from_hash( + ocsp::certid_new_from_hash( py, issuer_name_hash, issuer_key_hash, @@ -254,15 +222,15 @@ fn create_ocsp_request( builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, )?; - let reqs = [Request { + let reqs = [ocsp_req::Request { req_cert, single_request_extensions: None, }]; - let ocsp_req = RawOCSPRequest { - tbs_request: TBSRequest { + let ocsp_req = ocsp_req::OCSPRequest { + tbs_request: ocsp_req::TBSRequest { version: 0, requestor_name: None, - request_list: x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( + request_list: common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( &reqs, )), request_extensions: extensions, diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 0b2cab5f0b07..ffbf9c88af46 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -5,7 +5,10 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; -use crate::x509::{certificate, crl, extensions, ocsp, oid, py_to_datetime, sct}; +use crate::x509::{certificate, crl, extensions, ocsp, py_to_datetime, sct}; +use cryptography_x509::crl::CRLReason; +use cryptography_x509::extensions::Extensions; +use cryptography_x509::{common, name, ocsp_req, oid}; use pyo3::IntoPy; use std::sync::Arc; @@ -233,7 +236,7 @@ impl OCSPResponse { }); py_certs.append(pyo3::PyCell::new( py, - x509::Certificate { + x509::certificate::Certificate { raw: raw_cert, cached_extensions: None, }, @@ -407,9 +410,9 @@ fn map_arc_data_ocsp_response( f: impl for<'this> FnOnce( &'this [u8], &RawOCSPResponse<'this>, - ) -> certificate::RawCertificate<'this>, -) -> certificate::OwnedRawCertificate { - certificate::OwnedRawCertificate::new_public(it.borrow_data().clone_ref(py), |inner_it| { + ) -> cryptography_x509::certificate::Certificate<'this>, +) -> certificate::OwnedCertificate { + certificate::OwnedCertificate::new_public(it.borrow_data().clone_ref(py), |inner_it| { it.with(|value| { f(inner_it.as_bytes(py), unsafe { std::mem::transmute(value.value) @@ -443,13 +446,13 @@ struct ResponseBytes<'a> { } type OCSPCerts<'a> = Option< - x509::Asn1ReadableOrWritable< + common::Asn1ReadableOrWritable< 'a, - asn1::SequenceOf<'a, certificate::RawCertificate<'a>>, + asn1::SequenceOf<'a, cryptography_x509::certificate::Certificate<'a>>, asn1::SequenceOfWriter< 'a, - certificate::RawCertificate<'a>, - Vec>, + cryptography_x509::certificate::Certificate<'a>, + Vec>, >, >, >; @@ -457,7 +460,7 @@ type OCSPCerts<'a> = Option< #[derive(asn1::Asn1Read, asn1::Asn1Write)] struct BasicOCSPResponse<'a> { tbs_response_data: ResponseData<'a>, - signature_algorithm: x509::AlgorithmIdentifier<'a>, + signature_algorithm: common::AlgorithmIdentifier<'a>, signature: asn1::BitString<'a>, #[explicit(0)] certs: OCSPCerts<'a>, @@ -488,32 +491,32 @@ struct ResponseData<'a> { version: u8, responder_id: ResponderId<'a>, produced_at: asn1::GeneralizedTime, - responses: x509::Asn1ReadableOrWritable< + responses: common::Asn1ReadableOrWritable< 'a, asn1::SequenceOf<'a, SingleResponse<'a>>, asn1::SequenceOfWriter<'a, SingleResponse<'a>, Vec>>, >, #[explicit(1)] - response_extensions: Option>, + response_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] enum ResponderId<'a> { #[explicit(1)] - ByName(x509::Name<'a>), + ByName(name::Name<'a>), #[explicit(2)] ByKey(&'a [u8]), } #[derive(asn1::Asn1Read, asn1::Asn1Write)] struct SingleResponse<'a> { - cert_id: ocsp::CertID<'a>, + cert_id: ocsp_req::CertID<'a>, cert_status: CertStatus, this_update: asn1::GeneralizedTime, #[explicit(0)] next_update: Option, #[explicit(1)] - single_extensions: Option>, + single_extensions: Option>, } impl SingleResponse<'_> { @@ -601,7 +604,7 @@ enum CertStatus { struct RevokedInfo { revocation_time: asn1::GeneralizedTime, #[explicit(0)] - revocation_reason: Option, + revocation_reason: Option, } #[pyo3::prelude::pyfunction] @@ -616,10 +619,10 @@ fn create_ocsp_response( .getattr(pyo3::intern!(py, "value"))? .extract::()?; - let py_cert: pyo3::PyRef<'_, x509::Certificate>; - let py_issuer: pyo3::PyRef<'_, x509::Certificate>; + let py_cert: pyo3::PyRef<'_, x509::certificate::Certificate>; + let py_issuer: pyo3::PyRef<'_, x509::certificate::Certificate>; let borrowed_cert; - let py_certs: Option>>; + let py_certs: Option>>; let response_bytes = if response_status == SUCCESSFUL_RESPONSE { let ocsp_mod = py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))?; @@ -631,10 +634,12 @@ fn create_ocsp_response( .getattr(pyo3::intern!(py, "_issuer"))? .extract()?; let py_cert_hash_algorithm = py_single_resp.getattr(pyo3::intern!(py, "_algorithm"))?; - let (responder_cert, responder_encoding): (&pyo3::PyCell, &pyo3::PyAny) = - builder - .getattr(pyo3::intern!(py, "_responder_id"))? - .extract()?; + let (responder_cert, responder_encoding): ( + &pyo3::PyCell, + &pyo3::PyAny, + ) = builder + .getattr(pyo3::intern!(py, "_responder_id"))? + .extract()?; let py_cert_status = py_single_resp.getattr(pyo3::intern!(py, "_cert_status"))?; let cert_status = if py_cert_status.is(ocsp_mod @@ -690,7 +695,7 @@ fn create_ocsp_response( let this_update = asn1::GeneralizedTime::new(py_to_datetime(py, py_this_update)?)?; let responses = vec![SingleResponse { - cert_id: ocsp::CertID::new(py, &py_cert, &py_issuer, py_cert_hash_algorithm)?, + cert_id: ocsp::certid_new(py, &py_cert, &py_issuer, py_cert_hash_algorithm)?, cert_status, next_update, this_update, @@ -732,7 +737,7 @@ fn create_ocsp_response( version: 0, produced_at: asn1::GeneralizedTime::new(x509::common::datetime_now(py)?)?, responder_id, - responses: x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( + responses: common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( responses, )), response_extensions: x509::common::encode_extensions( @@ -759,7 +764,7 @@ fn create_ocsp_response( py_certs = builder.getattr(pyo3::intern!(py, "_certs"))?.extract()?; let certs = py_certs.as_ref().map(|py_certs| { - x509::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( + common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( py_certs .iter() .map(|c| c.raw.borrow_value_public().clone()) diff --git a/src/rust/src/x509/oid.rs b/src/rust/src/x509/oid.rs deleted file mode 100644 index b2e3a36acd3e..000000000000 --- a/src/rust/src/x509/oid.rs +++ /dev/null @@ -1,101 +0,0 @@ -// 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. - -pub(crate) const EXTENSION_REQUEST: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 113549, 1, 9, 14); -pub(crate) const MS_EXTENSION_REQUEST: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 4, 1, 311, 2, 1, 14); -pub(crate) const MS_CERTIFICATE_TEMPLATE: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 4, 1, 311, 21, 7); -pub(crate) const PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 2); -pub(crate) const PRECERT_POISON_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 3); -pub(crate) const SIGNED_CERTIFICATE_TIMESTAMPS_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 4, 1, 11129, 2, 4, 5); -pub(crate) const AUTHORITY_INFORMATION_ACCESS_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 1); -pub(crate) const SUBJECT_INFORMATION_ACCESS_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 11); -pub(crate) const TLS_FEATURE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 1, 24); -pub(crate) const CP_CPS_URI_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 2, 1); -pub(crate) const CP_USER_NOTICE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 2, 2); -pub(crate) const NONCE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 2); -pub(crate) const OCSP_NO_CHECK_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 5); -pub(crate) const SUBJECT_KEY_IDENTIFIER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 14); -pub(crate) const KEY_USAGE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 15); -pub(crate) const SUBJECT_ALTERNATIVE_NAME_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 17); -pub(crate) const ISSUER_ALTERNATIVE_NAME_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 18); -pub(crate) const BASIC_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 19); -pub(crate) const CRL_NUMBER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 20); -pub(crate) const CRL_REASON_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 21); -pub(crate) const INVALIDITY_DATE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 24); -pub(crate) const DELTA_CRL_INDICATOR_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 27); -pub(crate) const ISSUING_DISTRIBUTION_POINT_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 28); -pub(crate) const CERTIFICATE_ISSUER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 29); -pub(crate) const NAME_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 30); -pub(crate) const CRL_DISTRIBUTION_POINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 31); -pub(crate) const CERTIFICATE_POLICIES_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 32); -pub(crate) const AUTHORITY_KEY_IDENTIFIER_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 35); -pub(crate) const POLICY_CONSTRAINTS_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 36); -pub(crate) const EXTENDED_KEY_USAGE_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 37); -pub(crate) const FRESHEST_CRL_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 46); -pub(crate) const INHIBIT_ANY_POLICY_OID: asn1::ObjectIdentifier = asn1::oid!(2, 5, 29, 54); -pub(crate) const ACCEPTABLE_RESPONSES_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 3, 6, 1, 5, 5, 7, 48, 1, 4); - -// Signing methods -pub(crate) const ECDSA_WITH_SHA224_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 10045, 4, 3, 1); -pub(crate) const ECDSA_WITH_SHA256_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 10045, 4, 3, 2); -pub(crate) const ECDSA_WITH_SHA384_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 10045, 4, 3, 3); -pub(crate) const ECDSA_WITH_SHA512_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 10045, 4, 3, 4); -pub(crate) const ECDSA_WITH_SHA3_224_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 9); -pub(crate) const ECDSA_WITH_SHA3_256_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 10); -pub(crate) const ECDSA_WITH_SHA3_384_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 11); -pub(crate) const ECDSA_WITH_SHA3_512_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 12); - -pub(crate) const RSA_WITH_SHA224_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 113549, 1, 1, 14); -pub(crate) const RSA_WITH_SHA256_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 113549, 1, 1, 11); -pub(crate) const RSA_WITH_SHA384_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 113549, 1, 1, 12); -pub(crate) const RSA_WITH_SHA512_OID: asn1::ObjectIdentifier = - asn1::oid!(1, 2, 840, 113549, 1, 1, 13); -pub(crate) const RSA_WITH_SHA3_224_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 13); -pub(crate) const RSA_WITH_SHA3_256_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 14); -pub(crate) const RSA_WITH_SHA3_384_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 15); -pub(crate) const RSA_WITH_SHA3_512_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 16); - -pub(crate) const DSA_WITH_SHA224_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 1); -pub(crate) const DSA_WITH_SHA256_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 2); -pub(crate) const DSA_WITH_SHA384_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 3); -pub(crate) const DSA_WITH_SHA512_OID: asn1::ObjectIdentifier = - asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 4); - -pub(crate) const ED25519_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 101, 112); -pub(crate) const ED448_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 101, 113); - -// Hashes -pub(crate) const SHA1_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 14, 3, 2, 26); -pub(crate) const SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 4); -pub(crate) const SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 1); -pub(crate) const SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2); -pub(crate) const SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 3); diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 4be023bb2331..12579b35e4c0 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -3,8 +3,7 @@ // for complete details. use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; -use crate::x509::oid; +use cryptography_x509::{common, oid}; use once_cell::sync::Lazy; @@ -138,16 +137,16 @@ pub(crate) fn compute_signature_algorithm<'p>( py: pyo3::Python<'p>, private_key: &'p pyo3::PyAny, hash_algorithm: &'p pyo3::PyAny, -) -> pyo3::PyResult> { +) -> pyo3::PyResult> { let key_type = identify_key_type(py, private_key)?; let hash_type = identify_hash_type(py, hash_algorithm)?; match (key_type, hash_type) { - (KeyType::Ed25519, HashType::None) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ed25519, HashType::None) => Ok(common::AlgorithmIdentifier { oid: (oid::ED25519_OID).clone(), params: None, }), - (KeyType::Ed448, HashType::None) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ed448, HashType::None) => Ok(common::AlgorithmIdentifier { oid: (oid::ED448_OID).clone(), params: None, }), @@ -155,85 +154,85 @@ pub(crate) fn compute_signature_algorithm<'p>( "Algorithm must be None when signing via ed25519 or ed448", )), - (KeyType::Ec, HashType::Sha224) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA224_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha256) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA256_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha384) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA384_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha512) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA512_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha3_224) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA3_224_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha3_256) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA3_256_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha3_384) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA3_384_OID).clone(), params: None, }), - (KeyType::Ec, HashType::Sha3_512) => Ok(x509::AlgorithmIdentifier { + (KeyType::Ec, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { oid: (oid::ECDSA_WITH_SHA3_512_OID).clone(), params: None, }), - (KeyType::Rsa, HashType::Sha224) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA224_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha256) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA256_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha384) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA384_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha512) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA512_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha3_224) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA3_224_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha3_256) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA3_256_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha3_384) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA3_384_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Rsa, HashType::Sha3_512) => Ok(x509::AlgorithmIdentifier { + (KeyType::Rsa, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { oid: (oid::RSA_WITH_SHA3_512_OID).clone(), params: Some(*NULL_TLV), }), - (KeyType::Dsa, HashType::Sha224) => Ok(x509::AlgorithmIdentifier { + (KeyType::Dsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: (oid::DSA_WITH_SHA224_OID).clone(), params: None, }), - (KeyType::Dsa, HashType::Sha256) => Ok(x509::AlgorithmIdentifier { + (KeyType::Dsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: (oid::DSA_WITH_SHA256_OID).clone(), params: None, }), - (KeyType::Dsa, HashType::Sha384) => Ok(x509::AlgorithmIdentifier { + (KeyType::Dsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: (oid::DSA_WITH_SHA384_OID).clone(), params: None, }), - (KeyType::Dsa, HashType::Sha512) => Ok(x509::AlgorithmIdentifier { + (KeyType::Dsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: (oid::DSA_WITH_SHA512_OID).clone(), params: None, }), @@ -456,7 +455,7 @@ fn identify_key_hash_type_for_oid( #[cfg(test)] mod tests { use super::{identify_key_hash_type_for_oid, py_hash_name_from_hash_type, HashType, KeyType}; - use crate::x509::oid; + use cryptography_x509::oid; #[test] fn test_identify_key_hash_type_for_oid() { From b358a7d805058795518f34fc44276ab388849005 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 17 Apr 2023 07:39:55 +0800 Subject: [PATCH 631/827] port OCSP responses to the new crate (#8742) --- src/rust/cryptography-x509/src/lib.rs | 1 + src/rust/cryptography-x509/src/ocsp_resp.rs | 87 +++++ src/rust/src/x509/ocsp_resp.rs | 363 ++++++++------------ 3 files changed, 239 insertions(+), 212 deletions(-) create mode 100644 src/rust/cryptography-x509/src/ocsp_resp.rs diff --git a/src/rust/cryptography-x509/src/lib.rs b/src/rust/cryptography-x509/src/lib.rs index 3f8878772dd1..897e0f6c0229 100644 --- a/src/rust/cryptography-x509/src/lib.rs +++ b/src/rust/cryptography-x509/src/lib.rs @@ -11,4 +11,5 @@ pub mod csr; pub mod extensions; pub mod name; pub mod ocsp_req; +pub mod ocsp_resp; pub mod oid; diff --git a/src/rust/cryptography-x509/src/ocsp_resp.rs b/src/rust/cryptography-x509/src/ocsp_resp.rs new file mode 100644 index 000000000000..f7620f6aa601 --- /dev/null +++ b/src/rust/cryptography-x509/src/ocsp_resp.rs @@ -0,0 +1,87 @@ +// 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. + +use crate::{certificate, common, crl, extensions, name, ocsp_req}; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct OCSPResponse<'a> { + pub response_status: asn1::Enumerated, + #[explicit(0)] + pub response_bytes: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct ResponseBytes<'a> { + pub response_type: asn1::ObjectIdentifier, + pub response: asn1::OctetStringEncoded>, +} + +pub type OCSPCerts<'a> = Option< + common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, certificate::Certificate<'a>>, + asn1::SequenceOfWriter<'a, certificate::Certificate<'a>, Vec>>, + >, +>; + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct BasicOCSPResponse<'a> { + pub tbs_response_data: ResponseData<'a>, + pub signature_algorithm: common::AlgorithmIdentifier<'a>, + pub signature: asn1::BitString<'a>, + #[explicit(0)] + pub certs: OCSPCerts<'a>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct ResponseData<'a> { + #[explicit(0)] + #[default(0)] + pub version: u8, + pub responder_id: ResponderId<'a>, + pub produced_at: asn1::GeneralizedTime, + pub responses: common::Asn1ReadableOrWritable< + 'a, + asn1::SequenceOf<'a, SingleResponse<'a>>, + asn1::SequenceOfWriter<'a, SingleResponse<'a>, Vec>>, + >, + #[explicit(1)] + pub response_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum ResponderId<'a> { + #[explicit(1)] + ByName(name::Name<'a>), + #[explicit(2)] + ByKey(&'a [u8]), +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct SingleResponse<'a> { + pub cert_id: ocsp_req::CertID<'a>, + pub cert_status: CertStatus, + pub this_update: asn1::GeneralizedTime, + #[explicit(0)] + pub next_update: Option, + #[explicit(1)] + pub single_extensions: Option>, +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub enum CertStatus { + #[implicit(0)] + Good(()), + #[implicit(1)] + Revoked(RevokedInfo), + #[implicit(2)] + Unknown(()), +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct RevokedInfo { + pub revocation_time: asn1::GeneralizedTime, + #[explicit(0)] + pub revocation_reason: Option, +} diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index ffbf9c88af46..3344867ba186 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -6,9 +6,8 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, py_to_datetime, sct}; -use cryptography_x509::crl::CRLReason; -use cryptography_x509::extensions::Extensions; -use cryptography_x509::{common, name, ocsp_req, oid}; +use cryptography_x509::ocsp_resp::SingleResponse; +use cryptography_x509::{common, ocsp_resp, oid}; use pyo3::IntoPy; use std::sync::Arc; @@ -19,7 +18,7 @@ fn load_der_ocsp_response( py: pyo3::Python<'_>, data: pyo3::Py, ) -> Result { - let raw = OwnedRawOCSPResponse::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; + let raw = OwnedOCSPResponse::try_new(data, |data| asn1::parse_single(data.as_bytes(py)))?; let response = raw.borrow_value(); match response.response_status.value() { @@ -60,23 +59,23 @@ fn load_der_ocsp_response( } #[ouroboros::self_referencing] -struct OwnedRawOCSPResponse { +struct OwnedOCSPResponse { data: pyo3::Py, #[borrows(data)] #[covariant] - value: RawOCSPResponse<'this>, + value: ocsp_resp::OCSPResponse<'this>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] struct OCSPResponse { - raw: Arc, + raw: Arc, cached_extensions: Option, cached_single_extensions: Option, } impl OCSPResponse { - fn requires_successful_response(&self) -> pyo3::PyResult<&BasicOCSPResponse<'_>> { + fn requires_successful_response(&self) -> pyo3::PyResult<&ocsp_resp::BasicOCSPResponse<'_>> { match self.raw.borrow_value().response_bytes.as_ref() { Some(b) => Ok(b.response.get()), None => Err(pyo3::exceptions::PyValueError::new_err( @@ -144,8 +143,8 @@ impl OCSPResponse { fn responder_name<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; match resp.tbs_response_data.responder_id { - ResponderId::ByName(ref name) => Ok(x509::parse_name(py, name)?), - ResponderId::ByKey(_) => Ok(py.None().into_ref(py)), + ocsp_resp::ResponderId::ByName(ref name) => Ok(x509::parse_name(py, name)?), + ocsp_resp::ResponderId::ByKey(_) => Ok(py.None().into_ref(py)), } } @@ -153,8 +152,10 @@ impl OCSPResponse { fn responder_key_hash<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; match resp.tbs_response_data.responder_id { - ResponderId::ByKey(key_hash) => Ok(pyo3::types::PyBytes::new(py, key_hash).as_ref()), - ResponderId::ByName(_) => Ok(py.None().into_ref(py)), + ocsp_resp::ResponderId::ByKey(key_hash) => { + Ok(pyo3::types::PyBytes::new(py, key_hash).as_ref()) + } + ocsp_resp::ResponderId::ByName(_) => Ok(py.None().into_ref(py)), } } @@ -248,21 +249,21 @@ impl OCSPResponse { #[getter] fn serial_number<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_serial_number(py) + let single_resp = single_response(resp)?; + singleresp_py_serial_number(&single_resp, py) } #[getter] fn issuer_key_hash(&self) -> Result<&[u8], CryptographyError> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; + let single_resp = single_response(resp)?; Ok(single_resp.cert_id.issuer_key_hash) } #[getter] fn issuer_name_hash(&self) -> Result<&[u8], CryptographyError> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; + let single_resp = single_response(resp)?; Ok(single_resp.cert_id.issuer_name_hash) } @@ -272,42 +273,43 @@ impl OCSPResponse { py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_hash_algorithm(py) + let single_resp = single_response(resp)?; + singleresp_py_hash_algorithm(&single_resp, py) } #[getter] fn certificate_status<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - resp.single_response()?.py_certificate_status(py) + let single_resp = single_response(resp)?; + singleresp_py_certificate_status(&single_resp, py) } #[getter] fn revocation_time<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_revocation_time(py) + let single_resp = single_response(resp)?; + singleresp_py_revocation_time(&single_resp, py) } #[getter] fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_revocation_reason(py) + let single_resp = single_response(resp)?; + singleresp_py_revocation_reason(&single_resp, py) } #[getter] fn this_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_this_update(py) + let single_resp = single_response(resp)?; + singleresp_py_this_update(&single_resp, py) } #[getter] fn next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - let single_resp = resp.single_response()?; - single_resp.py_next_update(py) + let single_resp = single_response(resp)?; + singleresp_py_next_update(&single_resp, py) } #[getter] @@ -350,15 +352,15 @@ impl OCSPResponse { #[getter] fn single_extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { self.requires_successful_response()?; - let single_resp = self - .raw - .borrow_value() - .response_bytes - .as_ref() - .unwrap() - .response - .get() - .single_response()?; + let single_resp = single_response( + self.raw + .borrow_value() + .response_bytes + .as_ref() + .unwrap() + .response + .get(), + )?; let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, @@ -406,10 +408,10 @@ impl OCSPResponse { // https://github.com/joshua-maros/ouroboros/issues/38 fn map_arc_data_ocsp_response( py: pyo3::Python<'_>, - it: &OwnedRawOCSPResponse, + it: &OwnedOCSPResponse, f: impl for<'this> FnOnce( &'this [u8], - &RawOCSPResponse<'this>, + &ocsp_resp::OCSPResponse<'this>, ) -> cryptography_x509::certificate::Certificate<'this>, ) -> certificate::OwnedCertificate { certificate::OwnedCertificate::new_public(it.borrow_data().clone_ref(py), |inner_it| { @@ -423,190 +425,121 @@ fn map_arc_data_ocsp_response( fn try_map_arc_data_mut_ocsp_response_iterator( it: &mut OwnedOCSPResponseIteratorData, f: impl for<'this> FnOnce( - &'this OwnedRawOCSPResponse, - &mut asn1::SequenceOf<'this, SingleResponse<'this>>, - ) -> Result, E>, + &'this OwnedOCSPResponse, + &mut asn1::SequenceOf<'this, ocsp_resp::SingleResponse<'this>>, + ) -> Result, E>, ) -> Result { OwnedSingleResponse::try_new(Arc::clone(it.borrow_data()), |inner_it| { it.with_value_mut(|value| f(inner_it, unsafe { std::mem::transmute(value) })) }) } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct RawOCSPResponse<'a> { - response_status: asn1::Enumerated, - #[explicit(0)] - response_bytes: Option>, -} +fn single_response<'a>( + resp: &ocsp_resp::BasicOCSPResponse<'a>, +) -> Result, CryptographyError> { + let responses = resp.tbs_response_data.responses.unwrap_read(); + let num_responses = responses.len(); + + if num_responses != 1 { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "OCSP response contains {} SINGLERESP structures. Use .response_iter to iterate through them", + num_responses + )) + )); + } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct ResponseBytes<'a> { - response_type: asn1::ObjectIdentifier, - response: asn1::OctetStringEncoded>, + Ok(responses.clone().next().unwrap()) } -type OCSPCerts<'a> = Option< - common::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, cryptography_x509::certificate::Certificate<'a>>, - asn1::SequenceOfWriter< - 'a, - cryptography_x509::certificate::Certificate<'a>, - Vec>, - >, - >, ->; - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct BasicOCSPResponse<'a> { - tbs_response_data: ResponseData<'a>, - signature_algorithm: common::AlgorithmIdentifier<'a>, - signature: asn1::BitString<'a>, - #[explicit(0)] - certs: OCSPCerts<'a>, +fn singleresp_py_serial_number<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> pyo3::PyResult<&'p pyo3::PyAny> { + big_byte_slice_to_py_int(py, resp.cert_id.serial_number.as_bytes()) } -impl BasicOCSPResponse<'_> { - fn single_response(&self) -> Result, CryptographyError> { - let responses = self.tbs_response_data.responses.unwrap_read(); - let num_responses = responses.len(); +fn singleresp_py_certificate_status<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> pyo3::PyResult<&'p pyo3::PyAny> { + let attr = match resp.cert_status { + ocsp_resp::CertStatus::Good(_) => "GOOD", + ocsp_resp::CertStatus::Revoked(_) => "REVOKED", + ocsp_resp::CertStatus::Unknown(_) => "UNKNOWN", + }; + py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))? + .getattr(pyo3::intern!(py, "OCSPCertStatus"))? + .getattr(attr) +} - if num_responses != 1 { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err(format!( - "OCSP response contains {} SINGLERESP structures. Use .response_iter to iterate through them", - num_responses - )) - )); +fn singleresp_py_hash_algorithm<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> Result<&'p pyo3::PyAny, CryptographyError> { + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; + match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid) { + Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), + None => { + let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; + Err(CryptographyError::from(pyo3::PyErr::from_value( + exceptions + .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? + .call1((format!( + "Signature algorithm OID: {} not recognized", + resp.cert_id.hash_algorithm.oid + ),))?, + ))) } - - Ok(responses.clone().next().unwrap()) } } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct ResponseData<'a> { - #[explicit(0)] - #[default(0)] - version: u8, - responder_id: ResponderId<'a>, - produced_at: asn1::GeneralizedTime, - responses: common::Asn1ReadableOrWritable< - 'a, - asn1::SequenceOf<'a, SingleResponse<'a>>, - asn1::SequenceOfWriter<'a, SingleResponse<'a>, Vec>>, - >, - #[explicit(1)] - response_extensions: Option>, -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -enum ResponderId<'a> { - #[explicit(1)] - ByName(name::Name<'a>), - #[explicit(2)] - ByKey(&'a [u8]), +fn singleresp_py_this_update<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> pyo3::PyResult<&'p pyo3::PyAny> { + x509::datetime_to_py(py, resp.this_update.as_datetime()) } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct SingleResponse<'a> { - cert_id: ocsp_req::CertID<'a>, - cert_status: CertStatus, - this_update: asn1::GeneralizedTime, - #[explicit(0)] - next_update: Option, - #[explicit(1)] - single_extensions: Option>, -} - -impl SingleResponse<'_> { - fn py_serial_number<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - big_byte_slice_to_py_int(py, self.cert_id.serial_number.as_bytes()) - } - - fn py_certificate_status<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - let attr = match self.cert_status { - CertStatus::Good(_) => "GOOD", - CertStatus::Revoked(_) => "REVOKED", - CertStatus::Unknown(_) => "UNKNOWN", - }; - py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))? - .getattr(pyo3::intern!(py, "OCSPCertStatus"))? - .getattr(attr) - } - - fn py_hash_algorithm<'p>( - &self, - py: pyo3::Python<'p>, - ) -> Result<&'p pyo3::PyAny, CryptographyError> { - let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match ocsp::OIDS_TO_HASH.get(&self.cert_id.hash_algorithm.oid) { - Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), - None => { - let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; - Err(CryptographyError::from(pyo3::PyErr::from_value( - exceptions - .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? - .call1((format!( - "Signature algorithm OID: {} not recognized", - self.cert_id.hash_algorithm.oid - ),))?, - ))) - } - } - } - - fn py_this_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - x509::datetime_to_py(py, self.this_update.as_datetime()) +fn singleresp_py_next_update<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> pyo3::PyResult<&'p pyo3::PyAny> { + match &resp.next_update { + Some(v) => x509::datetime_to_py(py, v.as_datetime()), + None => Ok(py.None().into_ref(py)), } +} - fn py_next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - match &self.next_update { - Some(v) => x509::datetime_to_py(py, v.as_datetime()), +fn singleresp_py_revocation_reason<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> CryptographyResult<&'p pyo3::PyAny> { + match &resp.cert_status { + ocsp_resp::CertStatus::Revoked(revoked_info) => match revoked_info.revocation_reason { + Some(ref v) => crl::parse_crl_reason_flags(py, v), None => Ok(py.None().into_ref(py)), + }, + ocsp_resp::CertStatus::Good(_) | ocsp_resp::CertStatus::Unknown(_) => { + Ok(py.None().into_ref(py)) } } +} - fn py_revocation_reason<'p>( - &self, - py: pyo3::Python<'p>, - ) -> CryptographyResult<&'p pyo3::PyAny> { - match &self.cert_status { - CertStatus::Revoked(revoked_info) => match revoked_info.revocation_reason { - Some(ref v) => crl::parse_crl_reason_flags(py, v), - None => Ok(py.None().into_ref(py)), - }, - CertStatus::Good(_) | CertStatus::Unknown(_) => Ok(py.None().into_ref(py)), +fn singleresp_py_revocation_time<'p>( + resp: &ocsp_resp::SingleResponse<'_>, + py: pyo3::Python<'p>, +) -> pyo3::PyResult<&'p pyo3::PyAny> { + match &resp.cert_status { + ocsp_resp::CertStatus::Revoked(revoked_info) => { + x509::datetime_to_py(py, revoked_info.revocation_time.as_datetime()) } - } - - fn py_revocation_time<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - match &self.cert_status { - CertStatus::Revoked(revoked_info) => { - x509::datetime_to_py(py, revoked_info.revocation_time.as_datetime()) - } - CertStatus::Good(_) | CertStatus::Unknown(_) => Ok(py.None().into_ref(py)), + ocsp_resp::CertStatus::Good(_) | ocsp_resp::CertStatus::Unknown(_) => { + Ok(py.None().into_ref(py)) } } } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -enum CertStatus { - #[implicit(0)] - Good(()), - #[implicit(1)] - Revoked(RevokedInfo), - #[implicit(2)] - Unknown(()), -} - -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct RevokedInfo { - revocation_time: asn1::GeneralizedTime, - #[explicit(0)] - revocation_reason: Option, -} - #[pyo3::prelude::pyfunction] fn create_ocsp_response( py: pyo3::Python<'_>, @@ -646,12 +579,12 @@ fn create_ocsp_response( .getattr(pyo3::intern!(py, "OCSPCertStatus"))? .getattr(pyo3::intern!(py, "GOOD"))?) { - CertStatus::Good(()) + ocsp_resp::CertStatus::Good(()) } else if py_cert_status.is(ocsp_mod .getattr(pyo3::intern!(py, "OCSPCertStatus"))? .getattr(pyo3::intern!(py, "UNKNOWN"))?) { - CertStatus::Unknown(()) + ocsp_resp::CertStatus::Unknown(()) } else { let revocation_reason = if !py_single_resp .getattr(pyo3::intern!(py, "_revocation_reason"))? @@ -674,7 +607,7 @@ fn create_ocsp_response( py_single_resp.getattr(pyo3::intern!(py, "_revocation_time"))?; let revocation_time = asn1::GeneralizedTime::new(py_to_datetime(py, py_revocation_time)?)?; - CertStatus::Revoked(RevokedInfo { + ocsp_resp::CertStatus::Revoked(ocsp_resp::RevokedInfo { revocation_time, revocation_reason, }) @@ -711,7 +644,7 @@ fn create_ocsp_response( .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? .getattr(pyo3::intern!(py, "SHA1"))? .call0()?; - ResponderId::ByKey(ocsp::hash_data( + ocsp_resp::ResponderId::ByKey(ocsp::hash_data( py, sha1, borrowed_cert @@ -723,7 +656,7 @@ fn create_ocsp_response( .as_bytes(), )?) } else { - ResponderId::ByName( + ocsp_resp::ResponderId::ByName( borrowed_cert .raw .borrow_value_public() @@ -733,7 +666,7 @@ fn create_ocsp_response( ) }; - let tbs_response_data = ResponseData { + let tbs_response_data = ocsp_resp::ResponseData { version: 0, produced_at: asn1::GeneralizedTime::new(x509::common::datetime_now(py)?)?, responder_id, @@ -772,13 +705,13 @@ fn create_ocsp_response( )) }); - let basic_resp = BasicOCSPResponse { + let basic_resp = ocsp_resp::BasicOCSPResponse { tbs_response_data, signature: asn1::BitString::new(signature, 0).unwrap(), signature_algorithm: sigalg, certs, }; - Some(ResponseBytes { + Some(ocsp_resp::ResponseBytes { response_type: (BASIC_RESPONSE_OID).clone(), response: asn1::OctetStringEncoded::new(basic_resp), }) @@ -786,7 +719,7 @@ fn create_ocsp_response( None }; - let resp = RawOCSPResponse { + let resp = ocsp_resp::OCSPResponse { response_status: asn1::Enumerated::new(response_status), response_bytes, }; @@ -803,7 +736,7 @@ pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult< #[ouroboros::self_referencing] struct OwnedOCSPResponseIteratorData { - data: Arc, + data: Arc, #[borrows(data)] #[covariant] value: asn1::SequenceOf<'this, SingleResponse<'this>>, @@ -835,10 +768,10 @@ impl OCSPResponseIterator { #[ouroboros::self_referencing] struct OwnedSingleResponse { - data: Arc, + data: Arc, #[borrows(data)] #[covariant] - value: SingleResponse<'this>, + value: ocsp_resp::SingleResponse<'this>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.ocsp")] @@ -856,7 +789,7 @@ impl OCSPSingleResponse { impl OCSPSingleResponse { #[getter] fn serial_number<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - self.single_response().py_serial_number(py) + singleresp_py_serial_number(self.single_response(), py) } #[getter] @@ -876,31 +809,37 @@ impl OCSPSingleResponse { &self, py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { - self.single_response().py_hash_algorithm(py) + let single_resp = self.single_response(); + singleresp_py_hash_algorithm(single_resp, py) } #[getter] fn certificate_status<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - self.single_response().py_certificate_status(py) + let single_resp = self.single_response(); + singleresp_py_certificate_status(single_resp, py) } #[getter] fn revocation_time<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - self.single_response().py_revocation_time(py) + let single_resp = self.single_response(); + singleresp_py_revocation_time(single_resp, py) } #[getter] fn revocation_reason<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { - self.single_response().py_revocation_reason(py) + let single_resp = self.single_response(); + singleresp_py_revocation_reason(single_resp, py) } #[getter] fn this_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - self.single_response().py_this_update(py) + let single_resp = self.single_response(); + singleresp_py_this_update(single_resp, py) } #[getter] fn next_update<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - self.single_response().py_next_update(py) + let single_resp = self.single_response(); + singleresp_py_next_update(single_resp, py) } } From 8f7313f67320f7699903c7eb9d512f7b7632f111 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:17:10 +0000 Subject: [PATCH 632/827] Bump BoringSSL and/or OpenSSL in CI (#8744) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ee7a8595905..7c50e3d801c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 15, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d3acd45456450f7e8091f0f56084bc2da93e48fe"}} - # Latest commit on the OpenSSL master branch, as of Apr 15, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "7eab7680ee61c64b2ae7acd9dd199ab6734f3d1f"}} + # Latest commit on the OpenSSL master branch, as of Apr 17, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "8835940db58229fc467cdea1eebf3f064352a086"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 15c05ca10096db4ecb7a853bbc971896c0a8f4f3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 16 Apr 2023 20:37:51 -0400 Subject: [PATCH 633/827] Intern more strings (#8743) --- src/rust/src/x509/ocsp_resp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 3344867ba186..717be9565b7a 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -464,9 +464,9 @@ fn singleresp_py_certificate_status<'p>( py: pyo3::Python<'p>, ) -> pyo3::PyResult<&'p pyo3::PyAny> { let attr = match resp.cert_status { - ocsp_resp::CertStatus::Good(_) => "GOOD", - ocsp_resp::CertStatus::Revoked(_) => "REVOKED", - ocsp_resp::CertStatus::Unknown(_) => "UNKNOWN", + ocsp_resp::CertStatus::Good(_) => pyo3::intern!(py, "GOOD"), + ocsp_resp::CertStatus::Revoked(_) => pyo3::intern!(py, "REVOKED"), + ocsp_resp::CertStatus::Unknown(_) => pyo3::intern!(py, "UNKNOWN"), }; py.import(pyo3::intern!(py, "cryptography.x509.ocsp"))? .getattr(pyo3::intern!(py, "OCSPCertStatus"))? From ee1a3076157f9c7586d4f533594daeea3a10c8ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 09:27:47 -0400 Subject: [PATCH 634/827] Bump attrs from 22.2.0 to 23.1.0 (#8746) Bumps [attrs](https://github.com/python-attrs/attrs) from 22.2.0 to 23.1.0. - [Release notes](https://github.com/python-attrs/attrs/releases) - [Changelog](https://github.com/python-attrs/attrs/blob/main/CHANGELOG.md) - [Commits](https://github.com/python-attrs/attrs/compare/22.2.0...23.1.0) --- updated-dependencies: - dependency-name: attrs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4f00c537256f..4a8d9d262c38 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -9,7 +9,7 @@ alabaster==0.7.13 # via sphinx argcomplete==2.1.2 # via nox -attrs==22.2.0 +attrs==23.1.0 # via # pytest babel==2.12.1 From 2373401d1a6f2c2658150d0f932d952bb04d7d2e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 17 Apr 2023 16:18:59 -0400 Subject: [PATCH 635/827] Simplify Rust build script (#8745) Rather than spawn a python and pass the script on stdin, just use `-c` --- src/rust/build.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/rust/build.rs b/src/rust/build.rs index d315ec62d869..7b63b95d5d24 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -1,7 +1,6 @@ use std::env; -use std::io::Write; use std::path::Path; -use std::process::{Command, Stdio}; +use std::process::Command; #[allow(clippy::unusual_byte_groupings)] fn main() { @@ -91,18 +90,9 @@ fn run_python_script(interpreter: impl AsRef, script: &str) -> Result Err(format!( From 2f917b0e9b17828d7f5c9203f6d52416d4bca475 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 20:30:01 -0400 Subject: [PATCH 636/827] Bump BoringSSL and/or OpenSSL in CI (#8748) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c50e3d801c7..b9bf5d294002 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 15, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d3acd45456450f7e8091f0f56084bc2da93e48fe"}} - # Latest commit on the OpenSSL master branch, as of Apr 17, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "8835940db58229fc467cdea1eebf3f064352a086"}} + # Latest commit on the BoringSSL master branch, as of Apr 18, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c466222febf86ef8e12c7926d5544354c905fce5"}} + # Latest commit on the OpenSSL master branch, as of Apr 18, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "dcfeb617477dd957f69e713cbc61fd4dca0f2db4"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 3f00e4d8c618b363bc8421aae586c897602f5af5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 17 Apr 2023 23:01:25 -0400 Subject: [PATCH 637/827] Switch to an allow-list (#8747) Right now the rust subdirectory gets processed for packages, which never exist. This can break some development workflows. --- pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8024179a9738..8cf73cc44922 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,10 +60,7 @@ package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] -exclude = [ - "_cffi_src", - "_cffi_src.*", -] +include = ["cryptography*"] [tool.setuptools.dynamic] version = {attr = "cryptography.__version__"} From f584cfe8662616a625344fcc4358c53048738cc7 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 00:16:24 +0000 Subject: [PATCH 638/827] Bump BoringSSL and/or OpenSSL in CI (#8750) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9bf5d294002..8b736add6cd8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 18, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c466222febf86ef8e12c7926d5544354c905fce5"}} - # Latest commit on the OpenSSL master branch, as of Apr 18, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "dcfeb617477dd957f69e713cbc61fd4dca0f2db4"}} + # Latest commit on the BoringSSL master branch, as of Apr 19, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6776d5cd8fcdf6c5e05bae2d655076dbeaa56103"}} + # Latest commit on the OpenSSL master branch, as of Apr 19, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "04e0abc8bb1c24534d16cc930b611ac1d03bc9bf"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 1d8375fcaa86ae65b499869d3936936dc9970e9e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 18 Apr 2023 22:54:40 -0400 Subject: [PATCH 639/827] Don't build boringssl rust bindings (#8751) rust-openssl isn't actually using them --- .github/workflows/build_openssl.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build_openssl.sh b/.github/workflows/build_openssl.sh index 704e29b41931..42357abae9fc 100755 --- a/.github/workflows/build_openssl.sh +++ b/.github/workflows/build_openssl.sh @@ -74,8 +74,7 @@ elif [[ "${TYPE}" == "boringssl" ]]; then git checkout "${VERSION}" mkdir build pushd build - # Find the default rust target based on what rustc is built for - cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="$(rustc -V --verbose | grep 'host: ' | sed 's/host: //')" -DCMAKE_INSTALL_PREFIX="${OSSL_PATH}" + cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX="${OSSL_PATH}" make -j"$(nproc)" make install # delete binaries we don't need From 3e02d4d57387a6ab12db2300abbd7522ef830ac4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 13:12:14 +0000 Subject: [PATCH 640/827] Bump filelock from 3.11.0 to 3.12.0 (#8753) Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.11.0...3.12.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4a8d9d262c38..71b4b9c0f180 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -43,7 +43,7 @@ exceptiongroup==1.1.1 # via pytest execnet==1.9.0 # via pytest-xdist -filelock==3.11.0 +filelock==3.12.0 # via virtualenv idna==3.4 # via requests From 278fc87a0b77444fab1b1eb9a36dc48b0d95f0df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 13:14:11 +0000 Subject: [PATCH 641/827] Bump pygments from 2.15.0 to 2.15.1 (#8754) Bumps [pygments](https://github.com/pygments/pygments) from 2.15.0 to 2.15.1. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](https://github.com/pygments/pygments/compare/2.15.0...2.15.1) --- updated-dependencies: - dependency-name: pygments dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 71b4b9c0f180..60b04b364b84 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -98,7 +98,7 @@ pyenchant==3.2.2 # via # cryptography (pyproject.toml) # sphinxcontrib-spelling -pygments==2.15.0 +pygments==2.15.1 # via # readme-renderer # rich From fe6f5d4d6db20e37429d62eba98de3d23c40cf84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 21:50:14 +0000 Subject: [PATCH 642/827] Bump virtualenv from 20.21.0 to 20.21.1 (#8756) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.21.0 to 20.21.1. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.21.0...20.21.1) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 60b04b364b84..74e323871056 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -180,7 +180,7 @@ urllib3==1.26.15 # via # requests # twine -virtualenv==20.21.0 +virtualenv==20.21.1 # via nox webencodings==0.5.1 # via bleach From de67d0c7201c6e107a7f69f36f80fda2f21e9e00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 21:53:33 +0000 Subject: [PATCH 643/827] Bump ruff from 0.0.261 to 0.0.262 (#8757) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.261 to 0.0.262. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.261...v0.0.262) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 74e323871056..e960c623765d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -133,7 +133,7 @@ rfc3986==2.0.0 # via twine rich==13.3.4 # via twine -ruff==0.0.261 +ruff==0.0.262 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From ec5d5d77f3eb6f49dbd4d6c8b210d2c46481076b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 20 Apr 2023 17:14:25 -0600 Subject: [PATCH 644/827] Fix CI (#8766) * Bump BoringSSL and/or OpenSSL in CI * Bump openssl from 0.10.50 to 0.10.51 in /src/rust Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.50 to 0.10.51. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.50...openssl-v0.10.51) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Pin pyasn1 on twisted --------- Signed-off-by: dependabot[bot] Co-authored-by: pyca-boringbot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/downstream.d/twisted.sh | 2 +- .github/workflows/ci.yml | 8 ++++---- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/downstream.d/twisted.sh b/.github/downstream.d/twisted.sh index 9fc195ba7552..f8f294970507 100755 --- a/.github/downstream.d/twisted.sh +++ b/.github/downstream.d/twisted.sh @@ -5,7 +5,7 @@ case "${1}" in git clone --depth=1 https://github.com/twisted/twisted cd twisted git rev-parse HEAD - pip install ".[all_non_platform]" + pip install ".[all_non_platform]" "pyasn1!=0.5.0" ;; run) cd twisted diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b736add6cd8..d236722b194d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 19, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "6776d5cd8fcdf6c5e05bae2d655076dbeaa56103"}} - # Latest commit on the OpenSSL master branch, as of Apr 19, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "04e0abc8bb1c24534d16cc930b611ac1d03bc9bf"}} + # Latest commit on the BoringSSL master branch, as of Apr 20, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "bcecc7d834fc44ad257b2f23f88e1cf597ab2736"}} + # Latest commit on the OpenSSL master branch, as of Apr 20, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c8093347f736c7991350d26048b680d0e64974a0"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 1fc04cecd0dc..38656b24ca9f 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -141,9 +141,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.50" +version = "0.10.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" +checksum = "97ea2d98598bf9ada7ea6ee8a30fb74f9156b63bbe495d64ec2b87c269d2dda3" dependencies = [ "bitflags", "cfg-if", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.85" +version = "0.9.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" +checksum = "992bac49bdbab4423199c654a5515bd2a6c6a23bf03f2dd3bdb7e5ae6259bc69" dependencies = [ "cc", "libc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index e96b1fc2b505..588d742bdeb7 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -14,7 +14,7 @@ asn1 = { version = "0.14.0", default-features = false } cryptography-x509 = { path = "cryptography-x509" } pem = "1.1" ouroboros = "0.15" -openssl = "0.10.50" +openssl = "0.10.51" openssl-sys = "0.9.85" foreign-types-shared = "0.1" From 3534a9c3a24aff0f18d5f1c359760dc237526710 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:37:22 -0600 Subject: [PATCH 645/827] Bump libc from 0.2.141 to 0.2.142 in /src/rust (#8765) Bumps [libc](https://github.com/rust-lang/libc) from 0.2.141 to 0.2.142. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.141...0.2.142) --- updated-dependencies: - dependency-name: libc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 38656b24ca9f..7fdd8b92be21 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -110,9 +110,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "lock_api" From f26dcee04d7c58cb452c2625d97bb7b005f837bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 23:50:30 +0000 Subject: [PATCH 646/827] Bump actions/setup-python from 4.5.0 to 4.6.0 (#8759) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/linkcheck.yml | 2 +- .github/workflows/wheel-builder.yml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 09745aa48ca8..f121370e67df 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -35,7 +35,7 @@ jobs: - name: Setup python id: setup-python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: "3.11" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d236722b194d..84e46c70b0e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} - name: Clone wycheproof @@ -222,7 +222,7 @@ jobs: with: key: ${{ matrix.RUST }} - name: Setup python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON }} - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff @@ -297,7 +297,7 @@ jobs: ~/.cargo/bin/rust-size ~/.cargo/bin/rust-strip - name: Setup python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON }} - run: cargo install cargo-binutils @@ -382,7 +382,7 @@ jobs: key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.PYTHON.VERSION }} - name: Setup python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 @@ -441,7 +441,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} @@ -516,7 +516,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 - name: Setup python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON }} - run: ./.github/downstream.d/${{ matrix.DOWNSTREAM }}.sh install @@ -558,7 +558,7 @@ jobs: jobs: ${{ toJSON(needs) }} - name: Setup python if: ${{ always() }} - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: '3.11' - run: pip install -c ci-constraints-requirements.txt coverage[toml] diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 02457ec7bf18..8adca7075078 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -26,7 +26,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: 3.11 - name: Cache rust and pip diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 83fe53d3aa4f..9306ce7415e7 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -190,7 +190,7 @@ jobs: PYTHON_DOWNLOAD_URL: ${{ matrix.PYTHON.DOWNLOAD_URL }} if: contains(matrix.PYTHON.VERSION, 'pypy') == false - name: Setup pypy - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') @@ -264,7 +264,7 @@ jobs: name: cryptography-sdist - name: Setup python - uses: actions/setup-python@v4.5.0 + uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} From 7af92f2ffb3f3191c1ea3f61fa5c3d3666e5443a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 20 Apr 2023 18:17:26 -0600 Subject: [PATCH 647/827] modify cache keys to incorporate rust version (#8762) * modify cache keys to incorporate rust version * Update .github/actions/cache/action.yml Co-authored-by: Alex Gaynor --------- Co-authored-by: Alex Gaynor --- .github/actions/cache/action.yml | 6 +++++- .github/workflows/ci.yml | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 67e6cd437030..3e8c300d03e1 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -19,6 +19,10 @@ runs: using: "composite" steps: + - name: Get rust version + id: rust-version + run: echo "version=$(rustc --version | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT + shell: bash - name: Get pip cache dir id: pip-cache run: | @@ -39,7 +43,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock') }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84e46c70b0e7..8037e9a3bfcc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -219,8 +219,6 @@ jobs: - name: Cache rust and pip uses: ./.github/actions/cache timeout-minutes: 2 - with: - key: ${{ matrix.RUST }} - name: Setup python uses: actions/setup-python@v4.6.0 with: @@ -275,7 +273,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 with: - key: ${{ steps.rust-toolchain.outputs.cachekey }}-coverage + key: coverage additional-paths: | ~/.cargo/bin/cargo-cov ~/.cargo/bin/cargo-nm From 48f4bde6690020880a0b2dfa714d8a5ab6d46f19 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:17:46 -0600 Subject: [PATCH 648/827] Bump BoringSSL and/or OpenSSL in CI (#8767) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8037e9a3bfcc..6617011f4ffe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 20, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "bcecc7d834fc44ad257b2f23f88e1cf597ab2736"}} - # Latest commit on the OpenSSL master branch, as of Apr 20, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c8093347f736c7991350d26048b680d0e64974a0"}} + # Latest commit on the OpenSSL master branch, as of Apr 21, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "a901b31e99442f087051ae7efdcbc9ad6e6a5b33"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 15c622eae0819c1f4cc092b7276fb495cc354c9a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 08:53:01 -0600 Subject: [PATCH 649/827] Don't try to compute coverage for anything in ~/.cargo (#8771) This way it'll exclude ~/.cargo/git as well --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6617011f4ffe..62ef4f959d53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -336,13 +336,13 @@ jobs: cargo cov -- export \ ../../.nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ -instr-profile=pytest-rust-cov.profdata \ - --ignore-filename-regex='/.cargo/registry' \ + --ignore-filename-regex='/.cargo/' \ --ignore-filename-regex='/rustc/' \ --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > ../../${COV_UUID}-1.lcov cargo cov -- export \ $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --all --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]") \ -instr-profile=cargo-test-rust-cov.profdata \ - --ignore-filename-regex='/.cargo/registry' \ + --ignore-filename-regex='/.cargo/' \ --ignore-filename-regex='/rustc/' \ --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > ../../${COV_UUID}-2.lcov From 34edbb2e17f4c633caa54615668738bc03c081f5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 11:16:35 -0600 Subject: [PATCH 650/827] Update FAQ (#8773) Add a Q on the scope of our issue tracker, and remove a legacy Q. --- docs/faq.rst | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index 1bbf5eb4b7a9..ac7f4152c731 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -1,6 +1,22 @@ Frequently asked questions ========================== +What issues can you help with in your issue tracker? +---------------------------------------------------- + +The primary purpose of our issue tracker is to enable us to identify and +resolve bugs and feature requests in ``cryptography``, so any time a user +files a bug, we start by asking: Is this a ``cryptography`` bug, or is it a +bug somewhere else? + +That said, we do our best to help users to debug issues that are in their code +or environments. Please note, however, that there's a limit to our ability to +assist users in resolving problems that are specific to their environments, +particularly when we have no way to reproduce the issue. + +Lastly, we're not able to provide support for general Python or Python +packaging issues. + .. _faq-howto-handle-deprecation-warning: I cannot suppress the deprecation warning that ``cryptography`` emits on import @@ -102,15 +118,6 @@ If you have no other libraries using OpenSSL in your process, or they do not appear to be at fault, it's possible that this is a bug in ``cryptography``. Please file an `issue`_ with instructions on how to reproduce it. -error: ``-Werror=sign-conversion``: No option ``-Wsign-conversion`` during installation ---------------------------------------------------------------------------------------- - -The compiler you are using is too old and not supported by ``cryptography``. -Please upgrade to a more recent version. If you are running OpenBSD 6.1 or -earlier the default compiler is extremely old. Use ``pkg_add`` to install a -newer ``gcc`` and then install ``cryptography`` using -``CC=/path/to/newer/gcc pip install cryptography``. - Installing cryptography with OpenSSL 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0 fails ---------------------------------------------------------------------------- @@ -154,7 +161,7 @@ Why can't I import my PEM file? ------------------------------- PEM is a format (defined by several RFCs, but originally :rfc:`1421`) for -encoding keys, certificates and others cryptographic data into a regular form. +encoding keys, certificates, and others cryptographic data into a regular form. The data is encoded as base64 and wrapped with a header and footer. If you are having trouble importing PEM files, make sure your file fits From 923fe070bad8880d55dee26cc10fd521f30e1e40 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 11:40:19 -0600 Subject: [PATCH 651/827] Added a benchmark for hashing (#8774) --- tests/bench/test_hashes.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/bench/test_hashes.py diff --git a/tests/bench/test_hashes.py b/tests/bench/test_hashes.py new file mode 100644 index 000000000000..49ca5be30d6b --- /dev/null +++ b/tests/bench/test_hashes.py @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives import hashes + + +def test_sha256(benchmark): + def bench(): + h = hashes.Hash(hashes.SHA256()) + h.update(b"I love hashing. So much. The best.") + return h.finalize() + + benchmark(bench) From 8397cd2a05692a4f54cf6335befe36ea19e5e11b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 14:06:41 -0600 Subject: [PATCH 652/827] Convert hashes to Rust (#8775) --- .../hazmat/backends/openssl/backend.py | 6 - .../hazmat/backends/openssl/hashes.py | 88 ---------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../hazmat/bindings/_rust/openssl/hashes.pyi | 17 ++ src/cryptography/hazmat/primitives/hashes.py | 76 ++++----- src/rust/src/backend/hashes.rs | 154 ++++++++++++++++++ src/rust/src/backend/mod.rs | 3 + tests/hazmat/primitives/utils.py | 1 - 8 files changed, 205 insertions(+), 142 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/hashes.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi create mode 100644 src/rust/src/backend/hashes.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 71215e6b4c24..6176d16d97fd 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -30,7 +30,6 @@ _EllipticCurvePrivateKey, _EllipticCurvePublicKey, ) -from cryptography.hazmat.backends.openssl.hashes import _HashContext from cryptography.hazmat.backends.openssl.hmac import _HMACContext from cryptography.hazmat.backends.openssl.poly1305 import ( _POLY1305_KEY_SIZE, @@ -274,11 +273,6 @@ def hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool: return self.hash_supported(algorithm) - def create_hash_ctx( - self, algorithm: hashes.HashAlgorithm - ) -> hashes.HashContext: - return _HashContext(self, algorithm) - def cipher_supported(self, cipher: CipherAlgorithm, mode: Mode) -> bool: if self._fips_enabled: # FIPS mode requires AES. TripleDES is disallowed/deprecated in diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py deleted file mode 100644 index 370407aac58d..000000000000 --- a/src/cryptography/hazmat/backends/openssl/hashes.py +++ /dev/null @@ -1,88 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import hashes - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -class _HashContext(hashes.HashContext): - def __init__( - self, backend: Backend, algorithm: hashes.HashAlgorithm, ctx=None - ) -> None: - self._algorithm = algorithm - - self._backend = backend - - if ctx is None: - ctx = self._backend._lib.EVP_MD_CTX_new() - ctx = self._backend._ffi.gc( - ctx, self._backend._lib.EVP_MD_CTX_free - ) - evp_md = self._backend._evp_md_from_algorithm(algorithm) - if evp_md == self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "{} is not a supported hash on this backend.".format( - algorithm.name - ), - _Reasons.UNSUPPORTED_HASH, - ) - res = self._backend._lib.EVP_DigestInit_ex( - ctx, evp_md, self._backend._ffi.NULL - ) - self._backend.openssl_assert(res != 0) - - self._ctx = ctx - - @property - def algorithm(self) -> hashes.HashAlgorithm: - return self._algorithm - - def copy(self) -> _HashContext: - copied_ctx = self._backend._lib.EVP_MD_CTX_new() - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx) - self._backend.openssl_assert(res != 0) - return _HashContext(self._backend, self.algorithm, ctx=copied_ctx) - - def update(self, data: bytes) -> None: - data_ptr = self._backend._ffi.from_buffer(data) - res = self._backend._lib.EVP_DigestUpdate( - self._ctx, data_ptr, len(data) - ) - self._backend.openssl_assert(res != 0) - - def finalize(self) -> bytes: - if isinstance(self.algorithm, hashes.ExtendableOutputFunction): - # extendable output functions use a different finalize - return self._finalize_xof() - else: - buf = self._backend._ffi.new( - "unsigned char[]", self._backend._lib.EVP_MAX_MD_SIZE - ) - outlen = self._backend._ffi.new("unsigned int *") - res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen) - self._backend.openssl_assert(res != 0) - self._backend.openssl_assert( - outlen[0] == self.algorithm.digest_size - ) - return self._backend._ffi.buffer(buf)[: outlen[0]] - - def _finalize_xof(self) -> bytes: - buf = self._backend._ffi.new( - "unsigned char[]", self.algorithm.digest_size - ) - res = self._backend._lib.EVP_DigestFinalXOF( - self._ctx, buf, self.algorithm.digest_size - ) - self._backend.openssl_assert(res != 0) - return self._backend._ffi.buffer(buf)[: self.algorithm.digest_size] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index aceb859c63c7..07fa9d7b9320 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -7,6 +7,7 @@ import typing from cryptography.hazmat.bindings._rust.openssl import ( ed448, ed25519, + hashes, x448, x25519, ) @@ -14,6 +15,7 @@ from cryptography.hazmat.bindings._rust.openssl import ( __all__ = [ "openssl_version", "raise_openssl_error", + "hashes", "ed448", "ed25519", "x448", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi new file mode 100644 index 000000000000..ca5f42a00615 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi @@ -0,0 +1,17 @@ +# 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. + +import typing + +from cryptography.hazmat.primitives import hashes + +class Hash(hashes.HashContext): + def __init__( + self, algorithm: hashes.HashAlgorithm, backend: typing.Any = None + ) -> None: ... + @property + def algorithm(self) -> hashes.HashAlgorithm: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def copy(self) -> Hash: ... diff --git a/src/cryptography/hazmat/primitives/hashes.py b/src/cryptography/hazmat/primitives/hashes.py index c4b7d1060ada..b6a7ff140e68 100644 --- a/src/cryptography/hazmat/primitives/hashes.py +++ b/src/cryptography/hazmat/primitives/hashes.py @@ -7,8 +7,31 @@ import abc import typing -from cryptography import utils -from cryptography.exceptions import AlreadyFinalized +from cryptography.hazmat.bindings._rust import openssl as rust_openssl + +__all__ = [ + "HashAlgorithm", + "HashContext", + "Hash", + "ExtendableOutputFunction", + "SHA1", + "SHA512_224", + "SHA512_256", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA3_224", + "SHA3_256", + "SHA3_384", + "SHA3_512", + "SHAKE128", + "SHAKE256", + "MD5", + "BLAKE2b", + "BLAKE2s", + "SM3", +] class HashAlgorithm(metaclass=abc.ABCMeta): @@ -62,57 +85,16 @@ def copy(self) -> HashContext: """ +Hash = rust_openssl.hashes.Hash +HashContext.register(Hash) + + class ExtendableOutputFunction(metaclass=abc.ABCMeta): """ An interface for extendable output functions. """ -class Hash(HashContext): - _ctx: typing.Optional[HashContext] - - def __init__( - self, - algorithm: HashAlgorithm, - backend: typing.Any = None, - ctx: typing.Optional[HashContext] = None, - ) -> None: - if not isinstance(algorithm, HashAlgorithm): - raise TypeError("Expected instance of hashes.HashAlgorithm.") - self._algorithm = algorithm - - if ctx is None: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - self._ctx = ossl.create_hash_ctx(self.algorithm) - else: - self._ctx = ctx - - @property - def algorithm(self) -> HashAlgorithm: - return self._algorithm - - def update(self, data: bytes) -> None: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - utils._check_byteslike("data", data) - self._ctx.update(data) - - def copy(self) -> Hash: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - return Hash(self.algorithm, ctx=self._ctx.copy()) - - def finalize(self) -> bytes: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - digest = self._ctx.finalize() - self._ctx = None - return digest - - class SHA1(HashAlgorithm): name = "sha1" digest_size = 20 diff --git a/src/rust/src/backend/hashes.rs b/src/rust/src/backend/hashes.rs new file mode 100644 index 000000000000..807890365265 --- /dev/null +++ b/src/rust/src/backend/hashes.rs @@ -0,0 +1,154 @@ +// 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. + +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; +use std::borrow::Cow; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.hashes")] +struct Hash { + #[pyo3(get)] + algorithm: pyo3::Py, + ctx: Option, +} + +impl Hash { + fn get_ctx(&self, py: pyo3::Python<'_>) -> CryptographyResult<&openssl::hash::Hasher> { + if let Some(ctx) = self.ctx.as_ref() { + return Ok(ctx); + }; + Err(CryptographyError::from(pyo3::PyErr::from_value( + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + pyo3::intern!(py, "AlreadyFinalized"), + ("Context was already finalized.",), + )?, + ))) + } + + fn get_mut_ctx( + &mut self, + py: pyo3::Python<'_>, + ) -> CryptographyResult<&mut openssl::hash::Hasher> { + if let Some(ctx) = self.ctx.as_mut() { + return Ok(ctx); + } + Err(CryptographyError::from(pyo3::PyErr::from_value( + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + pyo3::intern!(py, "AlreadyFinalized"), + ("Context was already finalized.",), + )?, + ))) + } +} + +#[pyo3::pymethods] +impl Hash { + #[new] + #[pyo3(signature = (algorithm, backend=None))] + fn new( + py: pyo3::Python<'_>, + algorithm: &pyo3::PyAny, + backend: Option<&pyo3::PyAny>, + ) -> CryptographyResult { + let _ = backend; + let hash_algorithm_class = py + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? + .getattr(pyo3::intern!(py, "HashAlgorithm"))?; + if !algorithm.is_instance(hash_algorithm_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "Expected instance of hashes.HashAlgorithm.", + ), + )); + } + + let name = algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?; + let openssl_name = if name == "blake2b" || name == "blake2s" { + let digest_size = algorithm + .getattr(pyo3::intern!(py, "digest_size"))? + .extract::()?; + Cow::Owned(format!("{}{}", name, digest_size * 8)) + } else { + Cow::Borrowed(name) + }; + + let md = match openssl::hash::MessageDigest::from_name(&openssl_name) { + Some(md) => md, + None => { + let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; + let reason = exceptions_module + .getattr(pyo3::intern!(py, "_Reasons"))? + .getattr(pyo3::intern!(py, "UNSUPPORTED_HASH"))?; + return Err(CryptographyError::from(pyo3::PyErr::from_value( + exceptions_module.call_method1( + pyo3::intern!(py, "UnsupportedAlgorithm"), + ( + format!("{} is not a supported hash on this backend", name), + reason, + ), + )?, + ))); + } + }; + let ctx = openssl::hash::Hasher::new(md)?; + + Ok(Hash { + algorithm: algorithm.into(), + ctx: Some(ctx), + }) + } + + fn update(&mut self, py: pyo3::Python<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> { + self.get_mut_ctx(py)?.update(data.as_bytes())?; + Ok(()) + } + + fn finalize<'p>( + &mut self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + #[cfg(not(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL)))] + { + let xof_class = py + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? + .getattr(pyo3::intern!(py, "ExtendableOutputFunction"))?; + let algorithm = self.algorithm.clone_ref(py); + let algorithm = algorithm.as_ref(py); + if algorithm.is_instance(xof_class)? { + let ctx = self.get_mut_ctx(py)?; + let digest_size = algorithm + .getattr(pyo3::intern!(py, "digest_size"))? + .extract::()?; + let result = pyo3::types::PyBytes::new_with(py, digest_size, |b| { + ctx.finish_xof(b).unwrap(); + Ok(()) + })?; + self.ctx = None; + return Ok(result); + } + } + + let data = self.get_mut_ctx(py)?.finish()?; + self.ctx = None; + Ok(pyo3::types::PyBytes::new(py, &data)) + } + + fn copy(&self, py: pyo3::Python<'_>) -> CryptographyResult { + Ok(Hash { + algorithm: self.algorithm.clone_ref(py), + ctx: Some(self.get_ctx(py)?.clone()), + }) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "hashes")?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index d2d8cd478548..c4095a03d5f9 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -6,6 +6,7 @@ pub(crate) mod ed25519; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] pub(crate) mod ed448; +pub(crate) mod hashes; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] @@ -24,5 +25,7 @@ pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult< #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] module.add_submodule(x448::create_module(module.py())?)?; + module.add_submodule(hashes::create_module(module.py())?)?; + Ok(()) } diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 282744e80eaa..637c1eaa67f2 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -209,7 +209,6 @@ def base_hash_test(backend, algorithm, digest_size): assert m.algorithm.digest_size == digest_size m_copy = m.copy() assert m != m_copy - assert m._ctx != m_copy._ctx m.update(b"abc") copy = m.copy() From 1bc46c7298bb4e309afb765552a7e155e9d02b90 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 15:24:11 -0600 Subject: [PATCH 653/827] Added a benchmark for hmac (#8776) --- tests/bench/test_hmac.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/bench/test_hmac.py diff --git a/tests/bench/test_hmac.py b/tests/bench/test_hmac.py new file mode 100644 index 000000000000..b5b1e33bd8b9 --- /dev/null +++ b/tests/bench/test_hmac.py @@ -0,0 +1,14 @@ +# 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. + +from cryptography.hazmat.primitives import hashes, hmac + + +def test_hmac_sha256(benchmark): + def bench(): + h = hmac.HMAC(b"my extremely secure key", hashes.SHA256()) + h.update(b"I love hashing. So much. The best.") + return h.finalize() + + benchmark(bench) From 49dee344a1ae64c91398f6586a92f9b05a0c1961 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 21 Apr 2023 17:04:45 -0500 Subject: [PATCH 654/827] update MAC docs (#8777) * Update hmac.rst * Update poly1305.rst --- docs/hazmat/primitives/mac/hmac.rst | 2 +- docs/hazmat/primitives/mac/poly1305.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/hazmat/primitives/mac/hmac.rst b/docs/hazmat/primitives/mac/hmac.rst index c94b7902dfa6..bce8538d1bfd 100644 --- a/docs/hazmat/primitives/mac/hmac.rst +++ b/docs/hazmat/primitives/mac/hmac.rst @@ -54,7 +54,7 @@ of a message. ... cryptography.exceptions.InvalidSignature: Signature did not match digest. - :param key: Secret key as ``bytes``. + :param key: The secret key. :type key: :term:`bytes-like` :param algorithm: An :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` diff --git a/docs/hazmat/primitives/mac/poly1305.rst b/docs/hazmat/primitives/mac/poly1305.rst index 7504a076e81b..e3240f5baccf 100644 --- a/docs/hazmat/primitives/mac/poly1305.rst +++ b/docs/hazmat/primitives/mac/poly1305.rst @@ -48,7 +48,7 @@ messages allows an attacker to forge tags. Poly1305 is described in ... cryptography.exceptions.InvalidSignature: Value did not match computed tag. - :param key: Secret key as ``bytes``. + :param key: The secret key. :type key: :term:`bytes-like` :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the version of OpenSSL ``cryptography`` is compiled against does not From c7cbfeccac42e434a5c67578054b9b5df50659bb Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 16:29:54 -0600 Subject: [PATCH 655/827] Remove now unused bindings (#8778) --- src/_cffi_src/openssl/evp.py | 12 ------------ src/_cffi_src/openssl/nid.py | 1 - 2 files changed, 13 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index aa92f1ddb968..b22c2ac0f9fa 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -58,10 +58,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *); int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int); -int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *); -int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *); -int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t); -int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *); int EVP_DigestFinalXOF(EVP_MD_CTX *, unsigned char *, size_t); const EVP_MD *EVP_get_digestbyname(const char *); @@ -91,13 +87,9 @@ ENGINE *, EVP_PKEY *); int EVP_DigestSignUpdate(EVP_MD_CTX *, const void *, size_t); int EVP_DigestSignFinal(EVP_MD_CTX *, unsigned char *, size_t *); -int EVP_DigestVerifyInit(EVP_MD_CTX *, EVP_PKEY_CTX **, const EVP_MD *, - ENGINE *, EVP_PKEY *); - EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *); -EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int, ENGINE *); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *); int EVP_PKEY_sign_init(EVP_PKEY_CTX *); int EVP_PKEY_sign(EVP_PKEY_CTX *, unsigned char *, size_t *, @@ -117,8 +109,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *); -int EVP_PKEY_keygen_init(EVP_PKEY_CTX *); -int EVP_PKEY_keygen(EVP_PKEY_CTX *, EVP_PKEY **); int EVP_PKEY_derive_init(EVP_PKEY_CTX *); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *, EVP_PKEY *); int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *, EVP_PKEY *, int); @@ -131,8 +121,6 @@ int EVP_DigestSign(EVP_MD_CTX *, unsigned char *, size_t *, const unsigned char *, size_t); -int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t, - const unsigned char *, size_t); int EVP_PKEY_bits(const EVP_PKEY *); diff --git a/src/_cffi_src/openssl/nid.py b/src/_cffi_src/openssl/nid.py index 8933c95d82f0..7f6cb62303af 100644 --- a/src/_cffi_src/openssl/nid.py +++ b/src/_cffi_src/openssl/nid.py @@ -16,7 +16,6 @@ static const int NID_undef; static const int NID_aes_256_cbc; static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -static const int NID_X448; static const int NID_ED25519; static const int NID_ED448; static const int NID_poly1305; From 5d843986ce5e40a59f6578f2937d57aae30d3dd0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 21 Apr 2023 17:41:36 -0600 Subject: [PATCH 656/827] Do sigstore signatures when uploading to pypi (#8779) * Do sigstore signatures when uploading to pypi * Update .github/workflows/pypi-publish.yml Co-authored-by: Paul Kehrer --------- Co-authored-by: Paul Kehrer --- .github/workflows/pypi-publish.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index e873b579b58f..eed42830ecc7 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -29,7 +29,7 @@ jobs: with: path: dist/ run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.id }} - - run: pip install twine requests + - run: pip install twine requests sigstore - run: | echo "OIDC_AUDIENCE=pypi" >> $GITHUB_ENV @@ -67,3 +67,10 @@ jobs: shell: python - run: twine upload --skip-existing $(find dist/ -type f -name 'cryptography*') + + # Do not perform sigstore signatures for things for TestPyPI. This is + # because there's nothing that would prevent a malicious PyPI from + # serving a signed TestPyPI asset in place of a release intended for + # PyPI. + - run: sigstore sign $(find dist/ -type f -name 'cryptography*') + if: env.TWINE_REPOSITORY == 'pypi' From 30525e82c77b91963c4f2e8931d2b0257689d364 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 22 Apr 2023 00:16:16 +0000 Subject: [PATCH 657/827] Bump BoringSSL and/or OpenSSL in CI (#8780) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62ef4f959d53..bb9e0ca5195e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 20, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "bcecc7d834fc44ad257b2f23f88e1cf597ab2736"}} - # Latest commit on the OpenSSL master branch, as of Apr 21, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "a901b31e99442f087051ae7efdcbc9ad6e6a5b33"}} + # Latest commit on the BoringSSL master branch, as of Apr 22, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b0b1f9dfc583c96d5f91b7f8cdb7efabcf22793b"}} + # Latest commit on the OpenSSL master branch, as of Apr 22, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c04e78f0c69201226430fed14c291c281da47f2d"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 40a3c07703d11a951b74d1b2bdd36a3a03763e80 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 11:29:11 -0600 Subject: [PATCH 658/827] Simplify CI config, and require less duplication (#8782) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb9e0ca5195e..d872dfaaaf6d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -330,7 +330,7 @@ jobs: set -xe cd src/rust/ cargo profdata -- merge -sparse ../../rust-cov/*.profraw -o pytest-rust-cov.profdata - cargo profdata -- merge -sparse rust-cov/*.profraw cryptography-x509/rust-cov/*.profraw -o cargo-test-rust-cov.profdata + cargo profdata -- merge -sparse $(find . -iname "*.profraw") -o cargo-test-rust-cov.profdata COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") cargo cov -- export \ From e107518f1e534aae8562281624cef8a8ee7aad61 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 11:56:38 -0600 Subject: [PATCH 659/827] Attempt to consolidate rust cov invocations (#8783) --- .github/workflows/ci.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d872dfaaaf6d..2ae0092ef535 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -329,24 +329,18 @@ jobs: run: | set -xe cd src/rust/ - cargo profdata -- merge -sparse ../../rust-cov/*.profraw -o pytest-rust-cov.profdata - cargo profdata -- merge -sparse $(find . -iname "*.profraw") -o cargo-test-rust-cov.profdata + cargo profdata -- merge -sparse $(find ../.. -iname "*.profraw") -o rust-cov.profdata COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") cargo cov -- export \ ../../.nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ - -instr-profile=pytest-rust-cov.profdata \ + $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --all --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]" | awk '{print "-object " $0}') \ + -instr-profile=rust-cov.profdata \ --ignore-filename-regex='/.cargo/' \ --ignore-filename-regex='/rustc/' \ - --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > ../../${COV_UUID}-1.lcov - cargo cov -- export \ - $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --all --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]") \ - -instr-profile=cargo-test-rust-cov.profdata \ - --ignore-filename-regex='/.cargo/' \ - --ignore-filename-regex='/rustc/' \ - --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > ../../${COV_UUID}-2.lcov + --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > "../../${COV_UUID}.lcov" - sed -E -i 's/SF:(.*)\/src\/rust\/(.*)/SF:src\/rust\/\2/g' ../../*.lcov + sed -E -i 's/SF:(.*)\/src\/rust\/(.*)/SF:src\/rust\/\2/g' "../../${COV_UUID}.lcov" - uses: ./.github/actions/upload-coverage macos: From 8d616959f964a0aec6382ef4816990bef6e84619 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 12:20:57 -0600 Subject: [PATCH 660/827] Convert HMAC to Rust (#8781) --- .../hazmat/backends/openssl/backend.py | 6 - .../hazmat/backends/openssl/hmac.py | 86 -------------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../hazmat/bindings/_rust/openssl/hmac.pyi | 21 ++++ src/cryptography/hazmat/primitives/hmac.py | 66 +---------- src/rust/Cargo.lock | 11 ++ src/rust/Cargo.toml | 3 +- src/rust/cryptography-openssl/Cargo.toml | 14 +++ src/rust/cryptography-openssl/src/hmac.rs | 93 +++++++++++++++ src/rust/cryptography-openssl/src/lib.rs | 36 ++++++ src/rust/src/backend/hashes.rs | 112 +++++++++--------- src/rust/src/backend/hmac.rs | 104 ++++++++++++++++ src/rust/src/backend/mod.rs | 2 + tests/hazmat/primitives/test_hmac.py | 5 + tests/hazmat/primitives/utils.py | 1 - 15 files changed, 353 insertions(+), 209 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/hmac.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi create mode 100644 src/rust/cryptography-openssl/Cargo.toml create mode 100644 src/rust/cryptography-openssl/src/hmac.rs create mode 100644 src/rust/cryptography-openssl/src/lib.rs create mode 100644 src/rust/src/backend/hmac.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 6176d16d97fd..04b25f471a76 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -30,7 +30,6 @@ _EllipticCurvePrivateKey, _EllipticCurvePublicKey, ) -from cryptography.hazmat.backends.openssl.hmac import _HMACContext from cryptography.hazmat.backends.openssl.poly1305 import ( _POLY1305_KEY_SIZE, _Poly1305Context, @@ -223,11 +222,6 @@ def openssl_version_text(self) -> str: def openssl_version_number(self) -> int: return self._lib.OpenSSL_version_num() - def create_hmac_ctx( - self, key: bytes, algorithm: hashes.HashAlgorithm - ) -> _HMACContext: - return _HMACContext(self, key, algorithm) - def _evp_md_from_algorithm(self, algorithm: hashes.HashAlgorithm): if algorithm.name == "blake2b" or algorithm.name == "blake2s": alg = "{}{}".format( diff --git a/src/cryptography/hazmat/backends/openssl/hmac.py b/src/cryptography/hazmat/backends/openssl/hmac.py deleted file mode 100644 index 669f380705e1..000000000000 --- a/src/cryptography/hazmat/backends/openssl/hmac.py +++ /dev/null @@ -1,86 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import ( - InvalidSignature, - UnsupportedAlgorithm, - _Reasons, -) -from cryptography.hazmat.primitives import constant_time, hashes - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -class _HMACContext(hashes.HashContext): - def __init__( - self, - backend: Backend, - key: bytes, - algorithm: hashes.HashAlgorithm, - ctx=None, - ): - self._algorithm = algorithm - self._backend = backend - - if ctx is None: - ctx = self._backend._lib.HMAC_CTX_new() - self._backend.openssl_assert(ctx != self._backend._ffi.NULL) - ctx = self._backend._ffi.gc(ctx, self._backend._lib.HMAC_CTX_free) - evp_md = self._backend._evp_md_from_algorithm(algorithm) - if evp_md == self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "{} is not a supported hash on this backend".format( - algorithm.name - ), - _Reasons.UNSUPPORTED_HASH, - ) - key_ptr = self._backend._ffi.from_buffer(key) - res = self._backend._lib.HMAC_Init_ex( - ctx, key_ptr, len(key), evp_md, self._backend._ffi.NULL - ) - self._backend.openssl_assert(res != 0) - - self._ctx = ctx - self._key = key - - @property - def algorithm(self) -> hashes.HashAlgorithm: - return self._algorithm - - def copy(self) -> _HMACContext: - copied_ctx = self._backend._lib.HMAC_CTX_new() - self._backend.openssl_assert(copied_ctx != self._backend._ffi.NULL) - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.HMAC_CTX_free - ) - res = self._backend._lib.HMAC_CTX_copy(copied_ctx, self._ctx) - self._backend.openssl_assert(res != 0) - return _HMACContext( - self._backend, self._key, self.algorithm, ctx=copied_ctx - ) - - def update(self, data: bytes) -> None: - data_ptr = self._backend._ffi.from_buffer(data) - res = self._backend._lib.HMAC_Update(self._ctx, data_ptr, len(data)) - self._backend.openssl_assert(res != 0) - - def finalize(self) -> bytes: - buf = self._backend._ffi.new( - "unsigned char[]", self._backend._lib.EVP_MAX_MD_SIZE - ) - outlen = self._backend._ffi.new("unsigned int *") - res = self._backend._lib.HMAC_Final(self._ctx, buf, outlen) - self._backend.openssl_assert(res != 0) - self._backend.openssl_assert(outlen[0] == self.algorithm.digest_size) - return self._backend._ffi.buffer(buf)[: outlen[0]] - - def verify(self, signature: bytes) -> None: - digest = self.finalize() - if not constant_time.bytes_eq(digest, signature): - raise InvalidSignature("Signature did not match digest.") diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 07fa9d7b9320..3e8d894cdb51 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -8,6 +8,7 @@ from cryptography.hazmat.bindings._rust.openssl import ( ed448, ed25519, hashes, + hmac, x448, x25519, ) @@ -16,6 +17,7 @@ __all__ = [ "openssl_version", "raise_openssl_error", "hashes", + "hmac", "ed448", "ed25519", "x448", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi new file mode 100644 index 000000000000..e38d9b54d01b --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi @@ -0,0 +1,21 @@ +# 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. + +import typing + +from cryptography.hazmat.primitives import hashes + +class HMAC(hashes.HashContext): + def __init__( + self, + key: bytes, + algorithm: hashes.HashAlgorithm, + backend: typing.Any = None, + ) -> None: ... + @property + def algorithm(self) -> hashes.HashAlgorithm: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def verify(self, signature: bytes) -> None: ... + def copy(self) -> HMAC: ... diff --git a/src/cryptography/hazmat/primitives/hmac.py b/src/cryptography/hazmat/primitives/hmac.py index 6627f57499ec..a9442d59ab47 100644 --- a/src/cryptography/hazmat/primitives/hmac.py +++ b/src/cryptography/hazmat/primitives/hmac.py @@ -4,68 +4,10 @@ from __future__ import annotations -import typing - -from cryptography import utils -from cryptography.exceptions import AlreadyFinalized -from cryptography.hazmat.backends.openssl.hmac import _HMACContext +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import hashes +__all__ = ["HMAC"] -class HMAC(hashes.HashContext): - _ctx: typing.Optional[_HMACContext] - - def __init__( - self, - key: bytes, - algorithm: hashes.HashAlgorithm, - backend: typing.Any = None, - ctx=None, - ): - if not isinstance(algorithm, hashes.HashAlgorithm): - raise TypeError("Expected instance of hashes.HashAlgorithm.") - self._algorithm = algorithm - - self._key = key - if ctx is None: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - self._ctx = ossl.create_hmac_ctx(key, self.algorithm) - else: - self._ctx = ctx - - @property - def algorithm(self) -> hashes.HashAlgorithm: - return self._algorithm - - def update(self, data: bytes) -> None: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - utils._check_byteslike("data", data) - self._ctx.update(data) - - def copy(self) -> HMAC: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - return HMAC( - self._key, - self.algorithm, - ctx=self._ctx.copy(), - ) - - def finalize(self) -> bytes: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - digest = self._ctx.finalize() - self._ctx = None - return digest - - def verify(self, signature: bytes) -> None: - utils._check_bytes("signature", signature) - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - ctx, self._ctx = self._ctx, None - ctx.verify(signature) +HMAC = rust_openssl.hmac.HMAC +hashes.HashContext.register(HMAC) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 7fdd8b92be21..c7bc163a11a6 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -64,12 +64,23 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cryptography-openssl" +version = "0.1.0" +dependencies = [ + "foreign-types", + "foreign-types-shared", + "openssl", + "openssl-sys", +] + [[package]] name = "cryptography-rust" version = "0.1.0" dependencies = [ "asn1", "cc", + "cryptography-openssl", "cryptography-x509", "foreign-types-shared", "once_cell", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 588d742bdeb7..e97f800b7108 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -12,6 +12,7 @@ once_cell = "1" pyo3 = { version = "0.18" } asn1 = { version = "0.14.0", default-features = false } cryptography-x509 = { path = "cryptography-x509" } +cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" openssl = "0.10.51" @@ -34,4 +35,4 @@ lto = "thin" overflow-checks = true [workspace] -members = ["cryptography-x509"] +members = ["cryptography-openssl", "cryptography-x509"] diff --git a/src/rust/cryptography-openssl/Cargo.toml b/src/rust/cryptography-openssl/Cargo.toml new file mode 100644 index 000000000000..31927129e234 --- /dev/null +++ b/src/rust/cryptography-openssl/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cryptography-openssl" +version = "0.1.0" +authors = ["The cryptography developers "] +edition = "2021" +publish = false +# This specifies the MSRV +rust-version = "1.56.0" + +[dependencies] +openssl = "0.10.51" +ffi = { package = "openssl-sys", version = "0.9.85" } +foreign-types = "0.3" +foreign-types-shared = "0.1" diff --git a/src/rust/cryptography-openssl/src/hmac.rs b/src/rust/cryptography-openssl/src/hmac.rs new file mode 100644 index 000000000000..b30de478688d --- /dev/null +++ b/src/rust/cryptography-openssl/src/hmac.rs @@ -0,0 +1,93 @@ +// 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. + +use crate::{cvt, cvt_p, OpenSSLResult}; +use foreign_types_shared::{ForeignType, ForeignTypeRef}; +use std::ptr; + +foreign_types::foreign_type! { + type CType = ffi::HMAC_CTX; + fn drop = ffi::HMAC_CTX_free; + + pub struct Hmac; + pub struct HmacRef; +} + +unsafe impl Sync for Hmac {} +unsafe impl Send for Hmac {} + +impl Hmac { + pub fn new(key: &[u8], md: openssl::hash::MessageDigest) -> OpenSSLResult { + unsafe { + let h = Hmac::from_ptr(cvt_p(ffi::HMAC_CTX_new())?); + cvt(ffi::HMAC_Init_ex( + h.as_ptr(), + key.as_ptr().cast(), + key.len() + .try_into() + .expect("Key too long for OpenSSL's length type"), + md.as_ptr(), + ptr::null_mut(), + ))?; + Ok(h) + } + } +} + +impl HmacRef { + pub fn update(&mut self, data: &[u8]) -> OpenSSLResult<()> { + unsafe { + cvt(ffi::HMAC_Update(self.as_ptr(), data.as_ptr(), data.len()))?; + } + Ok(()) + } + + pub fn finish(&mut self) -> OpenSSLResult { + let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; + let mut len = ffi::EVP_MAX_MD_SIZE as std::os::raw::c_uint; + unsafe { + cvt(ffi::HMAC_Final(self.as_ptr(), buf.as_mut_ptr(), &mut len))?; + } + Ok(DigestBytes { + buf, + len: len.try_into().unwrap(), + }) + } + + pub fn copy(&self) -> OpenSSLResult { + unsafe { + let h = Hmac::from_ptr(cvt_p(ffi::HMAC_CTX_new())?); + cvt(ffi::HMAC_CTX_copy(h.as_ptr(), self.as_ptr()))?; + Ok(h) + } + } +} + +pub struct DigestBytes { + buf: [u8; ffi::EVP_MAX_MD_SIZE as usize], + len: usize, +} + +impl std::ops::Deref for DigestBytes { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + &self.buf[..self.len] + } +} + +#[cfg(test)] +mod tests { + use super::DigestBytes; + + #[test] + fn test_digest_bytes() { + let d = DigestBytes { + buf: [19; ffi::EVP_MAX_MD_SIZE as usize], + len: 12, + }; + assert_eq!(&*d, b"\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13"); + } +} diff --git a/src/rust/cryptography-openssl/src/lib.rs b/src/rust/cryptography-openssl/src/lib.rs new file mode 100644 index 000000000000..fcc2ff1a585b --- /dev/null +++ b/src/rust/cryptography-openssl/src/lib.rs @@ -0,0 +1,36 @@ +// 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. + +pub mod hmac; + +pub type OpenSSLResult = Result; + +#[inline] +fn cvt(r: std::os::raw::c_int) -> Result { + if r <= 0 { + Err(openssl::error::ErrorStack::get()) + } else { + Ok(r) + } +} + +#[inline] +fn cvt_p(r: *mut T) -> Result<*mut T, openssl::error::ErrorStack> { + if r.is_null() { + Err(openssl::error::ErrorStack::get()) + } else { + Ok(r) + } +} + +#[cfg(test)] +mod tests { + use std::ptr; + + #[test] + fn test_cvt() { + assert!(crate::cvt(-1).is_err()); + assert!(crate::cvt_p(ptr::null_mut::<()>()).is_err()); + } +} diff --git a/src/rust/src/backend/hashes.rs b/src/rust/src/backend/hashes.rs index 807890365265..14af3906aa8f 100644 --- a/src/rust/src/backend/hashes.rs +++ b/src/rust/src/backend/hashes.rs @@ -13,18 +13,24 @@ struct Hash { ctx: Option, } +pub(crate) fn already_finalized_error( + py: pyo3::Python<'_>, +) -> CryptographyResult { + Ok(CryptographyError::from(pyo3::PyErr::from_value( + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + pyo3::intern!(py, "AlreadyFinalized"), + ("Context was already finalized.",), + )?, + ))) +} + impl Hash { fn get_ctx(&self, py: pyo3::Python<'_>) -> CryptographyResult<&openssl::hash::Hasher> { if let Some(ctx) = self.ctx.as_ref() { return Ok(ctx); }; - Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - pyo3::intern!(py, "AlreadyFinalized"), - ("Context was already finalized.",), - )?, - ))) + Err(already_finalized_error(py)?) } fn get_mut_ctx( @@ -34,13 +40,52 @@ impl Hash { if let Some(ctx) = self.ctx.as_mut() { return Ok(ctx); } - Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - pyo3::intern!(py, "AlreadyFinalized"), - ("Context was already finalized.",), + Err(already_finalized_error(py)?) + } +} + +pub(crate) fn message_digest_from_algorithm( + py: pyo3::Python<'_>, + algorithm: &pyo3::PyAny, +) -> CryptographyResult { + let hash_algorithm_class = py + .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? + .getattr(pyo3::intern!(py, "HashAlgorithm"))?; + if !algorithm.is_instance(hash_algorithm_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err("Expected instance of hashes.HashAlgorithm."), + )); + } + + let name = algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?; + let openssl_name = if name == "blake2b" || name == "blake2s" { + let digest_size = algorithm + .getattr(pyo3::intern!(py, "digest_size"))? + .extract::()?; + Cow::Owned(format!("{}{}", name, digest_size * 8)) + } else { + Cow::Borrowed(name) + }; + + match openssl::hash::MessageDigest::from_name(&openssl_name) { + Some(md) => Ok(md), + None => { + let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; + let reason = exceptions_module + .getattr(pyo3::intern!(py, "_Reasons"))? + .getattr(pyo3::intern!(py, "UNSUPPORTED_HASH"))?; + Err(CryptographyError::from(pyo3::PyErr::from_value( + exceptions_module.call_method1( + pyo3::intern!(py, "UnsupportedAlgorithm"), + ( + format!("{} is not a supported hash on this backend", name), + reason, + ), )?, - ))) + ))) + } } } @@ -54,47 +99,8 @@ impl Hash { backend: Option<&pyo3::PyAny>, ) -> CryptographyResult { let _ = backend; - let hash_algorithm_class = py - .import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))? - .getattr(pyo3::intern!(py, "HashAlgorithm"))?; - if !algorithm.is_instance(hash_algorithm_class)? { - return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "Expected instance of hashes.HashAlgorithm.", - ), - )); - } - let name = algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?; - let openssl_name = if name == "blake2b" || name == "blake2s" { - let digest_size = algorithm - .getattr(pyo3::intern!(py, "digest_size"))? - .extract::()?; - Cow::Owned(format!("{}{}", name, digest_size * 8)) - } else { - Cow::Borrowed(name) - }; - - let md = match openssl::hash::MessageDigest::from_name(&openssl_name) { - Some(md) => md, - None => { - let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; - let reason = exceptions_module - .getattr(pyo3::intern!(py, "_Reasons"))? - .getattr(pyo3::intern!(py, "UNSUPPORTED_HASH"))?; - return Err(CryptographyError::from(pyo3::PyErr::from_value( - exceptions_module.call_method1( - pyo3::intern!(py, "UnsupportedAlgorithm"), - ( - format!("{} is not a supported hash on this backend", name), - reason, - ), - )?, - ))); - } - }; + let md = message_digest_from_algorithm(py, algorithm)?; let ctx = openssl::hash::Hasher::new(md)?; Ok(Hash { diff --git a/src/rust/src/backend/hmac.rs b/src/rust/src/backend/hmac.rs new file mode 100644 index 000000000000..f483f48efd71 --- /dev/null +++ b/src/rust/src/backend/hmac.rs @@ -0,0 +1,104 @@ +// 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. + +use crate::backend::hashes::{already_finalized_error, message_digest_from_algorithm}; +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; + +#[pyo3::prelude::pyclass( + module = "cryptography.hazmat.bindings._rust.openssl.hmac", + name = "HMAC" +)] +struct Hmac { + #[pyo3(get)] + algorithm: pyo3::Py, + ctx: Option, +} + +impl Hmac { + fn get_ctx( + &self, + py: pyo3::Python<'_>, + ) -> CryptographyResult<&cryptography_openssl::hmac::Hmac> { + if let Some(ctx) = self.ctx.as_ref() { + return Ok(ctx); + }; + Err(already_finalized_error(py)?) + } + + fn get_mut_ctx( + &mut self, + py: pyo3::Python<'_>, + ) -> CryptographyResult<&mut cryptography_openssl::hmac::Hmac> { + if let Some(ctx) = self.ctx.as_mut() { + return Ok(ctx); + } + Err(already_finalized_error(py)?) + } +} + +#[pyo3::pymethods] +impl Hmac { + #[new] + #[pyo3(signature = (key, algorithm, backend=None))] + fn new( + py: pyo3::Python<'_>, + key: CffiBuf<'_>, + algorithm: &pyo3::PyAny, + backend: Option<&pyo3::PyAny>, + ) -> CryptographyResult { + let _ = backend; + + let md = message_digest_from_algorithm(py, algorithm)?; + let ctx = cryptography_openssl::hmac::Hmac::new(key.as_bytes(), md)?; + + Ok(Hmac { + ctx: Some(ctx), + algorithm: algorithm.into(), + }) + } + + fn update(&mut self, py: pyo3::Python<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> { + self.get_mut_ctx(py)?.update(data.as_bytes())?; + Ok(()) + } + + fn finalize<'p>( + &mut self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let data = self.get_mut_ctx(py)?.finish()?; + self.ctx = None; + Ok(pyo3::types::PyBytes::new(py, &data)) + } + + fn verify(&mut self, py: pyo3::Python<'_>, signature: &[u8]) -> CryptographyResult<()> { + let actual = self.finalize(py)?.as_bytes(); + if actual.len() != signature.len() || !openssl::memcmp::eq(actual, signature) { + return Err(CryptographyError::from(pyo3::PyErr::from_value( + py.import(pyo3::intern!(py, "cryptography.exceptions"))? + .call_method1( + pyo3::intern!(py, "InvalidSignature"), + ("Signature did not match digest.",), + )?, + ))); + } + + Ok(()) + } + + fn copy(&self, py: pyo3::Python<'_>) -> CryptographyResult { + Ok(Hmac { + ctx: Some(self.get_ctx(py)?.copy()?), + algorithm: self.algorithm.clone_ref(py), + }) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "hmac")?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index c4095a03d5f9..b48f2089a991 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -7,6 +7,7 @@ pub(crate) mod ed25519; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] pub(crate) mod ed448; pub(crate) mod hashes; +pub(crate) mod hmac; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] @@ -26,6 +27,7 @@ pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult< module.add_submodule(x448::create_module(module.py())?)?; module.add_submodule(hashes::create_module(module.py())?)?; + module.add_submodule(hmac::create_module(module.py())?)?; Ok(()) } diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 818ff2a7d829..78bb26254d9b 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -88,3 +88,8 @@ def test_buffer_protocol(self, backend): assert h.finalize() == binascii.unhexlify( b"a1bf7169c56a501c6585190ff4f07cad6e492a3ee187c0372614fb444b9fc3f0" ) + + def test_algorithm(self): + alg = hashes.SHA256() + h = hmac.HMAC(b"123456", alg) + assert h.algorithm is alg diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 637c1eaa67f2..056b31ee55c8 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -229,7 +229,6 @@ def base_hmac_test(backend, algorithm): h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) h_copy = h.copy() assert h != h_copy - assert h._ctx != h_copy._ctx def generate_hmac_test(param_loader, path, file_names, algorithm): From 2ca57be0c4845d40992cbe7d13435df552e631f0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 13:32:59 -0600 Subject: [PATCH 661/827] Use pyo3's facilities for exceptions (#8785) --- src/cryptography/exceptions.py | 17 ++-------- .../hazmat/bindings/_rust/exceptions.pyi | 17 ++++++++++ src/rust/src/backend/hashes.rs | 22 ++++--------- src/rust/src/exceptions.rs | 33 +++++++++++++++++++ src/rust/src/lib.rs | 2 ++ src/rust/src/x509/certificate.rs | 18 ++++------ src/rust/src/x509/crl.rs | 14 +++----- src/rust/src/x509/csr.rs | 18 ++++------ src/rust/src/x509/ocsp_req.rs | 19 ++++------- src/rust/src/x509/ocsp_resp.rs | 26 ++++++--------- src/rust/src/x509/sign.rs | 23 ++++--------- tests/utils.py | 2 +- 12 files changed, 105 insertions(+), 106 deletions(-) create mode 100644 src/cryptography/hazmat/bindings/_rust/exceptions.pyi create mode 100644 src/rust/src/exceptions.rs diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py index 59c7ebaff43c..47fdd18eeeb2 100644 --- a/src/cryptography/exceptions.py +++ b/src/cryptography/exceptions.py @@ -6,25 +6,12 @@ import typing -from cryptography import utils +from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions if typing.TYPE_CHECKING: from cryptography.hazmat.bindings._rust import openssl as rust_openssl - -class _Reasons(utils.Enum): - BACKEND_MISSING_INTERFACE = 0 - UNSUPPORTED_HASH = 1 - UNSUPPORTED_CIPHER = 2 - UNSUPPORTED_PADDING = 3 - UNSUPPORTED_MGF = 4 - UNSUPPORTED_PUBLIC_KEY_ALGORITHM = 5 - UNSUPPORTED_ELLIPTIC_CURVE = 6 - UNSUPPORTED_SERIALIZATION = 7 - UNSUPPORTED_X509 = 8 - UNSUPPORTED_EXCHANGE_ALGORITHM = 9 - UNSUPPORTED_DIFFIE_HELLMAN = 10 - UNSUPPORTED_MAC = 11 +_Reasons = rust_exceptions._Reasons class UnsupportedAlgorithm(Exception): diff --git a/src/cryptography/hazmat/bindings/_rust/exceptions.pyi b/src/cryptography/hazmat/bindings/_rust/exceptions.pyi new file mode 100644 index 000000000000..09f46b1e817f --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/exceptions.pyi @@ -0,0 +1,17 @@ +# 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. + +class _Reasons: + BACKEND_MISSING_INTERFACE: _Reasons + UNSUPPORTED_HASH: _Reasons + UNSUPPORTED_CIPHER: _Reasons + UNSUPPORTED_PADDING: _Reasons + UNSUPPORTED_MGF: _Reasons + UNSUPPORTED_PUBLIC_KEY_ALGORITHM: _Reasons + UNSUPPORTED_ELLIPTIC_CURVE: _Reasons + UNSUPPORTED_SERIALIZATION: _Reasons + UNSUPPORTED_X509: _Reasons + UNSUPPORTED_EXCHANGE_ALGORITHM: _Reasons + UNSUPPORTED_DIFFIE_HELLMAN: _Reasons + UNSUPPORTED_MAC: _Reasons diff --git a/src/rust/src/backend/hashes.rs b/src/rust/src/backend/hashes.rs index 14af3906aa8f..6543094ee24a 100644 --- a/src/rust/src/backend/hashes.rs +++ b/src/rust/src/backend/hashes.rs @@ -4,6 +4,7 @@ use crate::buf::CffiBuf; use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; use std::borrow::Cow; #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.hashes")] @@ -71,21 +72,12 @@ pub(crate) fn message_digest_from_algorithm( match openssl::hash::MessageDigest::from_name(&openssl_name) { Some(md) => Ok(md), - None => { - let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; - let reason = exceptions_module - .getattr(pyo3::intern!(py, "_Reasons"))? - .getattr(pyo3::intern!(py, "UNSUPPORTED_HASH"))?; - Err(CryptographyError::from(pyo3::PyErr::from_value( - exceptions_module.call_method1( - pyo3::intern!(py, "UnsupportedAlgorithm"), - ( - format!("{} is not a supported hash on this backend", name), - reason, - ), - )?, - ))) - } + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(( + format!("{} is not a supported hash on this backend", name), + exceptions::Reasons::UNSUPPORTED_HASH, + )), + )), } } diff --git a/src/rust/src/exceptions.rs b/src/rust/src/exceptions.rs new file mode 100644 index 000000000000..be59a6351bfa --- /dev/null +++ b/src/rust/src/exceptions.rs @@ -0,0 +1,33 @@ +// 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. + +#[pyo3::prelude::pyclass( + module = "cryptography.hazmat.bindings._rust.exceptions", + name = "_Reasons" +)] +#[allow(non_camel_case_types)] +pub(crate) enum Reasons { + BACKEND_MISSING_INTERFACE, + UNSUPPORTED_HASH, + UNSUPPORTED_CIPHER, + UNSUPPORTED_PADDING, + UNSUPPORTED_MGF, + UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + UNSUPPORTED_ELLIPTIC_CURVE, + UNSUPPORTED_SERIALIZATION, + UNSUPPORTED_X509, + UNSUPPORTED_EXCHANGE_ALGORITHM, + UNSUPPORTED_DIFFIE_HELLMAN, + UNSUPPORTED_MAC, +} + +pyo3::import_exception!(cryptography.exceptions, UnsupportedAlgorithm); + +pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let submod = pyo3::prelude::PyModule::new(py, "exceptions")?; + + submod.add_class::()?; + + Ok(submod) +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 74989350bad7..f39762c88a09 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -13,6 +13,7 @@ mod asn1; mod backend; mod buf; mod error; +mod exceptions; pub(crate) mod oid; mod pkcs7; mod pool; @@ -156,6 +157,7 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> m.add_submodule(asn1::create_submodule(py)?)?; m.add_submodule(pkcs7::create_submodule(py)?)?; + m.add_submodule(exceptions::create_submodule(py)?)?; let x509_mod = pyo3::prelude::PyModule::new(py, "x509")?; crate::x509::certificate::add_to_module(x509_mod)?; diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index a20e3fe5ff1a..889878972d1d 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -6,8 +6,8 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, }; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; use crate::x509::{extensions, sct, sign}; +use crate::{exceptions, x509}; use cryptography_x509::common::Asn1ReadableOrWritable; use cryptography_x509::extensions::{ AuthorityKeyIdentifier, BasicConstraints, DisplayText, DistributionPoint, @@ -244,16 +244,12 @@ impl Certificate { let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - "UnsupportedAlgorithm", - (format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid - ),), - )?, - ))), + Err(_) => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + self.raw.borrow_value().signature_alg.oid + )), + )), } } diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index ea04bb984766..dcf09c731385 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -6,8 +6,8 @@ use crate::asn1::{ big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes, }; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; use crate::x509::{certificate, extensions, sign}; +use crate::{exceptions, x509}; use cryptography_x509::{common, crl, name, oid}; use pyo3::{IntoPy, ToPyObject}; use std::sync::Arc; @@ -201,19 +201,15 @@ impl CertificateRevocationList { ) -> pyo3::PyResult<&'p pyo3::PyAny> { let oid = self.signature_algorithm_oid(py)?; let oid_module = py.import(pyo3::intern!(py, "cryptography.hazmat._oid"))?; - let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; match oid_module .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))? .get_item(oid) { Ok(v) => Ok(v), - Err(_) => Err(pyo3::PyErr::from_value(exceptions_module.call_method1( - "UnsupportedAlgorithm", - (format!( - "Signature algorithm OID:{} not recognized", - self.owned.borrow_value().signature_algorithm.oid - ),), - )?)), + Err(_) => Err(exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + self.owned.borrow_value().signature_algorithm.oid + ))), } } diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 6de3667ae4fd..f376b9fed31a 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -4,8 +4,8 @@ use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; use crate::x509::{certificate, sign}; +use crate::{exceptions, x509}; use asn1::SimpleAsn1Readable; use cryptography_x509::csr::{check_attribute_length, Attribute, CertificationRequestInfo, Csr}; use cryptography_x509::{common, oid}; @@ -102,16 +102,12 @@ impl CertificateSigningRequest { let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); match hash_alg { Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - "UnsupportedAlgorithm", - (format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid - ),), - )?, - ))), + Err(_) => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + self.raw.borrow_value().signature_alg.oid + )), + )), } } diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 856c60c93d9a..701868e89395 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -4,8 +4,8 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, py_uint_to_big_endian_bytes}; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; use crate::x509::{extensions, ocsp}; +use crate::{exceptions, x509}; use cryptography_x509::{common, ocsp_req, oid}; use pyo3::IntoPy; @@ -88,17 +88,12 @@ impl OCSPRequest { let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), - None => { - let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; - Err(CryptographyError::from(pyo3::PyErr::from_value( - exceptions - .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? - .call1((format!( - "Signature algorithm OID: {} not recognized", - cert_id.hash_algorithm.oid - ),))?, - ))) - } + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + cert_id.hash_algorithm.oid + )), + )), } } diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 717be9565b7a..103b610ec51f 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -4,8 +4,8 @@ use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid}; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; use crate::x509::{certificate, crl, extensions, ocsp, py_to_datetime, sct}; +use crate::{exceptions, x509}; use cryptography_x509::ocsp_resp::SingleResponse; use cryptography_x509::{common, ocsp_resp, oid}; use pyo3::IntoPy; @@ -187,10 +187,9 @@ impl OCSPResponse { "Signature algorithm OID: {} not recognized", self.requires_successful_response()?.signature_algorithm.oid ); - Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1(pyo3::intern!(py, "UnsupportedAlgorithm"), (exc_messsage,))?, - ))) + Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(exc_messsage), + )) } } } @@ -480,17 +479,12 @@ fn singleresp_py_hash_algorithm<'p>( let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), - None => { - let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?; - Err(CryptographyError::from(pyo3::PyErr::from_value( - exceptions - .getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))? - .call1((format!( - "Signature algorithm OID: {} not recognized", - resp.cert_id.hash_algorithm.oid - ),))?, - ))) - } + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + resp.cert_id.hash_algorithm.oid + )), + )), } } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 12579b35e4c0..187dc54db986 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -3,6 +3,7 @@ // for complete details. use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; use cryptography_x509::{common, oid}; use once_cell::sync::Lazy; @@ -120,16 +121,10 @@ fn identify_hash_type( "sha3-256" => Ok(HashType::Sha3_256), "sha3-384" => Ok(HashType::Sha3_384), "sha3-512" => Ok(HashType::Sha3_512), - name => Err(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - "UnsupportedAlgorithm", - (format!( - "Hash algorithm {:?} not supported for signatures", - name - ),), - )?, - )), + name => Err(exceptions::UnsupportedAlgorithm::new_err(format!( + "Hash algorithm {:?} not supported for signatures", + name + ))), } } @@ -239,12 +234,8 @@ pub(crate) fn compute_signature_algorithm<'p>( ( KeyType::Dsa, HashType::Sha3_224 | HashType::Sha3_256 | HashType::Sha3_384 | HashType::Sha3_512, - ) => Err(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - "UnsupportedAlgorithm", - ("SHA3 hashes are not supported with DSA keys",), - )?, + ) => Err(exceptions::UnsupportedAlgorithm::new_err( + "SHA3 hashes are not supported with DSA keys", )), (_, HashType::None) => Err(pyo3::exceptions::PyTypeError::new_err( "Algorithm must be a registered hash algorithm, not None.", diff --git a/tests/utils.py b/tests/utils.py index c87df65c1507..bad0f87da164 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -33,7 +33,7 @@ def raises_unsupported_algorithm(reason): with pytest.raises(UnsupportedAlgorithm) as exc_info: yield exc_info - assert exc_info.value._reason is reason + assert exc_info.value._reason == reason T = typing.TypeVar("T") From 82ad1bd4eff6f62179afcd255d292bfae70a0e5e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 13:59:13 -0600 Subject: [PATCH 662/827] Finish adopting pyo3's exceptio facilities (#8786) --- src/rust/src/backend/ed25519.rs | 15 +++++--------- src/rust/src/backend/ed448.rs | 15 +++++--------- src/rust/src/backend/hashes.rs | 35 ++++++++++++-------------------- src/rust/src/backend/hmac.rs | 33 +++++++++++------------------- src/rust/src/error.rs | 21 ++++++------------- src/rust/src/exceptions.rs | 7 +++++++ src/rust/src/x509/certificate.rs | 11 +++++----- src/rust/src/x509/common.rs | 26 ++++++++++-------------- src/rust/src/x509/crl.rs | 12 +++++------ src/rust/src/x509/csr.rs | 23 +++++++++------------ 10 files changed, 81 insertions(+), 117 deletions(-) diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index 09ed9ac10eff..003a5e913275 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -5,6 +5,7 @@ use crate::backend::utils; use crate::buf::CffiBuf; use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; use foreign_types_shared::ForeignTypeRef; #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed25519")] @@ -117,20 +118,14 @@ impl Ed25519PrivateKey { #[pyo3::prelude::pymethods] impl Ed25519PublicKey { - fn verify( - &self, - py: pyo3::Python<'_>, - signature: &[u8], - data: &[u8], - ) -> CryptographyResult<()> { + fn verify(&self, signature: &[u8], data: &[u8]) -> CryptographyResult<()> { let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)? .verify_oneshot(signature, data)?; if !valid { - return Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1(pyo3::intern!(py, "InvalidSignature"), ())?, - ))); + return Err(CryptographyError::from( + exceptions::InvalidSignature::new_err(()), + )); } Ok(()) diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index db17a7062bfe..72fd6fd588a7 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -5,6 +5,7 @@ use crate::backend::utils; use crate::buf::CffiBuf; use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; use foreign_types_shared::ForeignTypeRef; #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.ed448")] @@ -115,20 +116,14 @@ impl Ed448PrivateKey { #[pyo3::prelude::pymethods] impl Ed448PublicKey { - fn verify( - &self, - py: pyo3::Python<'_>, - signature: &[u8], - data: &[u8], - ) -> CryptographyResult<()> { + fn verify(&self, signature: &[u8], data: &[u8]) -> CryptographyResult<()> { let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)? .verify_oneshot(signature, data)?; if !valid { - return Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1(pyo3::intern!(py, "InvalidSignature"), ())?, - ))); + return Err(CryptographyError::from( + exceptions::InvalidSignature::new_err(()), + )); } Ok(()) diff --git a/src/rust/src/backend/hashes.rs b/src/rust/src/backend/hashes.rs index 6543094ee24a..d9157d6e8a18 100644 --- a/src/rust/src/backend/hashes.rs +++ b/src/rust/src/backend/hashes.rs @@ -14,34 +14,25 @@ struct Hash { ctx: Option, } -pub(crate) fn already_finalized_error( - py: pyo3::Python<'_>, -) -> CryptographyResult { - Ok(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - pyo3::intern!(py, "AlreadyFinalized"), - ("Context was already finalized.",), - )?, - ))) +pub(crate) fn already_finalized_error() -> CryptographyError { + CryptographyError::from(exceptions::AlreadyFinalized::new_err( + "Context was already finalized.", + )) } impl Hash { - fn get_ctx(&self, py: pyo3::Python<'_>) -> CryptographyResult<&openssl::hash::Hasher> { + fn get_ctx(&self) -> CryptographyResult<&openssl::hash::Hasher> { if let Some(ctx) = self.ctx.as_ref() { return Ok(ctx); }; - Err(already_finalized_error(py)?) + Err(already_finalized_error()) } - fn get_mut_ctx( - &mut self, - py: pyo3::Python<'_>, - ) -> CryptographyResult<&mut openssl::hash::Hasher> { + fn get_mut_ctx(&mut self) -> CryptographyResult<&mut openssl::hash::Hasher> { if let Some(ctx) = self.ctx.as_mut() { return Ok(ctx); } - Err(already_finalized_error(py)?) + Err(already_finalized_error()) } } @@ -101,8 +92,8 @@ impl Hash { }) } - fn update(&mut self, py: pyo3::Python<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> { - self.get_mut_ctx(py)?.update(data.as_bytes())?; + fn update(&mut self, data: CffiBuf<'_>) -> CryptographyResult<()> { + self.get_mut_ctx()?.update(data.as_bytes())?; Ok(()) } @@ -118,7 +109,7 @@ impl Hash { let algorithm = self.algorithm.clone_ref(py); let algorithm = algorithm.as_ref(py); if algorithm.is_instance(xof_class)? { - let ctx = self.get_mut_ctx(py)?; + let ctx = self.get_mut_ctx()?; let digest_size = algorithm .getattr(pyo3::intern!(py, "digest_size"))? .extract::()?; @@ -131,7 +122,7 @@ impl Hash { } } - let data = self.get_mut_ctx(py)?.finish()?; + let data = self.get_mut_ctx()?.finish()?; self.ctx = None; Ok(pyo3::types::PyBytes::new(py, &data)) } @@ -139,7 +130,7 @@ impl Hash { fn copy(&self, py: pyo3::Python<'_>) -> CryptographyResult { Ok(Hash { algorithm: self.algorithm.clone_ref(py), - ctx: Some(self.get_ctx(py)?.clone()), + ctx: Some(self.get_ctx()?.clone()), }) } } diff --git a/src/rust/src/backend/hmac.rs b/src/rust/src/backend/hmac.rs index f483f48efd71..d37b97277fdd 100644 --- a/src/rust/src/backend/hmac.rs +++ b/src/rust/src/backend/hmac.rs @@ -5,6 +5,7 @@ use crate::backend::hashes::{already_finalized_error, message_digest_from_algorithm}; use crate::buf::CffiBuf; use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; #[pyo3::prelude::pyclass( module = "cryptography.hazmat.bindings._rust.openssl.hmac", @@ -17,24 +18,18 @@ struct Hmac { } impl Hmac { - fn get_ctx( - &self, - py: pyo3::Python<'_>, - ) -> CryptographyResult<&cryptography_openssl::hmac::Hmac> { + fn get_ctx(&self) -> CryptographyResult<&cryptography_openssl::hmac::Hmac> { if let Some(ctx) = self.ctx.as_ref() { return Ok(ctx); }; - Err(already_finalized_error(py)?) + Err(already_finalized_error()) } - fn get_mut_ctx( - &mut self, - py: pyo3::Python<'_>, - ) -> CryptographyResult<&mut cryptography_openssl::hmac::Hmac> { + fn get_mut_ctx(&mut self) -> CryptographyResult<&mut cryptography_openssl::hmac::Hmac> { if let Some(ctx) = self.ctx.as_mut() { return Ok(ctx); } - Err(already_finalized_error(py)?) + Err(already_finalized_error()) } } @@ -59,8 +54,8 @@ impl Hmac { }) } - fn update(&mut self, py: pyo3::Python<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> { - self.get_mut_ctx(py)?.update(data.as_bytes())?; + fn update(&mut self, data: CffiBuf<'_>) -> CryptographyResult<()> { + self.get_mut_ctx()?.update(data.as_bytes())?; Ok(()) } @@ -68,7 +63,7 @@ impl Hmac { &mut self, py: pyo3::Python<'p>, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - let data = self.get_mut_ctx(py)?.finish()?; + let data = self.get_mut_ctx()?.finish()?; self.ctx = None; Ok(pyo3::types::PyBytes::new(py, &data)) } @@ -76,13 +71,9 @@ impl Hmac { fn verify(&mut self, py: pyo3::Python<'_>, signature: &[u8]) -> CryptographyResult<()> { let actual = self.finalize(py)?.as_bytes(); if actual.len() != signature.len() || !openssl::memcmp::eq(actual, signature) { - return Err(CryptographyError::from(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.exceptions"))? - .call_method1( - pyo3::intern!(py, "InvalidSignature"), - ("Signature did not match digest.",), - )?, - ))); + return Err(CryptographyError::from( + exceptions::InvalidSignature::new_err(("Signature did not match digest.",)), + )); } Ok(()) @@ -90,7 +81,7 @@ impl Hmac { fn copy(&self, py: pyo3::Python<'_>) -> CryptographyResult { Ok(Hmac { - ctx: Some(self.get_ctx(py)?.copy()?), + ctx: Some(self.get_ctx()?.copy()?), algorithm: self.algorithm.clone_ref(py), }) } diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index e484993cced7..689ae613e8bb 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -2,7 +2,8 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::OpenSSLError; +use crate::{exceptions, OpenSSLError}; +use pyo3::ToPyObject; pub enum CryptographyError { Asn1Parse(asn1::ParseError), @@ -63,12 +64,6 @@ impl From for pyo3::PyErr { } CryptographyError::Py(py_error) => py_error, CryptographyError::OpenSSL(error_stack) => pyo3::Python::with_gil(|py| { - let internal_error = py - .import(pyo3::intern!(py, "cryptography.exceptions")) - .expect("Failed to import cryptography module") - .getattr(pyo3::intern!(py, "InternalError")) - .expect("Failed to get InternalError attribute"); - let errors = pyo3::types::PyList::empty(py); for e in error_stack.errors() { errors @@ -78,20 +73,16 @@ impl From for pyo3::PyErr { ) .expect("Failed to append to list"); } - pyo3::PyErr::from_value( - internal_error - .call1(( - "Unknown OpenSSL error. This error is commonly encountered + exceptions::InternalError::new_err(( + "Unknown OpenSSL error. This error is commonly encountered when another library is not cleaning up the OpenSSL error stack. If you are using cryptography with another library that uses OpenSSL try disabling it before reporting a bug. Otherwise please file an issue at https://github.com/pyca/cryptography/issues with information on how to reproduce this.", - errors, - )) - .expect("Failed to create InternalError"), - ) + errors.to_object(py), + )) }), } } diff --git a/src/rust/src/exceptions.rs b/src/rust/src/exceptions.rs index be59a6351bfa..ec1e18c7ff9c 100644 --- a/src/rust/src/exceptions.rs +++ b/src/rust/src/exceptions.rs @@ -22,7 +22,14 @@ pub(crate) enum Reasons { UNSUPPORTED_MAC, } +pyo3::import_exception!(cryptography.exceptions, AlreadyFinalized); +pyo3::import_exception!(cryptography.exceptions, InternalError); +pyo3::import_exception!(cryptography.exceptions, InvalidSignature); pyo3::import_exception!(cryptography.exceptions, UnsupportedAlgorithm); +pyo3::import_exception!(cryptography.x509, AttributeNotFound); +pyo3::import_exception!(cryptography.x509, DuplicateExtension); +pyo3::import_exception!(cryptography.x509, UnsupportedGeneralNameType); +pyo3::import_exception!(cryptography.x509, InvalidVersion); pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let submod = pyo3::prelude::PyModule::new(py, "exceptions")?; diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 889878972d1d..b8d281014ff6 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -327,11 +327,12 @@ fn cert_version(py: pyo3::Python<'_>, version: u8) -> Result<&pyo3::PyAny, Crypt 2 => Ok(x509_module .getattr(pyo3::intern!(py, "Version"))? .get_item(pyo3::intern!(py, "v3"))?), - _ => Err(CryptographyError::from(pyo3::PyErr::from_value( - x509_module - .getattr(pyo3::intern!(py, "InvalidVersion"))? - .call1((format!("{} is not a valid X509 version", version), version))?, - ))), + _ => Err(CryptographyError::from( + exceptions::InvalidVersion::new_err(( + format!("{} is not a valid X509 version", version), + version, + )), + )), } } diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 4d977a921172..e81d52a0020c 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -4,14 +4,14 @@ use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; -use crate::x509; +use crate::{exceptions, x509}; use cryptography_x509::common::{Asn1ReadableOrWritable, AttributeTypeValue, RawTlv}; use cryptography_x509::extensions::{ AccessDescription, Extension, Extensions, SequenceOfAccessDescriptions, }; use cryptography_x509::name::{GeneralName, Name, OtherName, UnvalidatedIA5String}; use pyo3::types::IntoPyDict; -use pyo3::ToPyObject; +use pyo3::{IntoPy, ToPyObject}; use std::collections::HashSet; /// Parse all sections in a PEM file and return the first matching section. @@ -308,12 +308,11 @@ pub(crate) fn parse_general_name( .to_object(py) } _ => { - return Err(CryptographyError::from(pyo3::PyErr::from_value( - x509_module.call_method1( - "UnsupportedGeneralNameType", - ("x400Address/EDIPartyName are not supported types",), - )?, - ))) + return Err(CryptographyError::from( + exceptions::UnsupportedGeneralNameType::new_err( + "x400Address/EDIPartyName are not supported types", + ), + )) } }; Ok(py_gn) @@ -411,13 +410,10 @@ pub(crate) fn parse_and_cache_extensions< let oid_obj = oid_to_py_oid(py, &raw_ext.extn_id)?; if seen_oids.contains(&raw_ext.extn_id) { - return Err(pyo3::PyErr::from_value(x509_module.call_method1( - "DuplicateExtension", - ( - format!("Duplicate {} extension found", raw_ext.extn_id), - oid_obj, - ), - )?)); + return Err(exceptions::DuplicateExtension::new_err(( + format!("Duplicate {} extension found", raw_ext.extn_id), + oid_obj.into_py(py), + ))); } let extn_value = match parse_ext(&raw_ext.extn_id, raw_ext.extn_value)? { diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index dcf09c731385..079122f2c392 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -25,12 +25,12 @@ fn load_der_x509_crl( let version = owned.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { - let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; - return Err(CryptographyError::from(pyo3::PyErr::from_value( - x509_module - .getattr(pyo3::intern!(py, "InvalidVersion"))? - .call1((format!("{} is not a valid CRL version", version), version))?, - ))); + return Err(CryptographyError::from( + exceptions::InvalidVersion::new_err(( + format!("{} is not a valid CRL version", version), + version, + )), + )); } Ok(CertificateRevocationList { diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index f376b9fed31a..2d734681910a 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -170,13 +170,10 @@ impl CertificateSigningRequest { ))); } } - Err(pyo3::PyErr::from_value( - py.import(pyo3::intern!(py, "cryptography.x509"))? - .call_method1( - "AttributeNotFound", - (format!("No {} attribute was found", oid), oid), - )?, - )) + Err(exceptions::AttributeNotFound::new_err(( + format!("No {} attribute was found", oid), + oid.into_py(py), + ))) } #[getter] @@ -273,12 +270,12 @@ fn load_der_x509_csr( let version = raw.borrow_value().csr_info.version; if version != 0 { - let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; - return Err(CryptographyError::from(pyo3::PyErr::from_value( - x509_module - .getattr(pyo3::intern!(py, "InvalidVersion"))? - .call1((format!("{} is not a valid CSR version", version), version))?, - ))); + return Err(CryptographyError::from( + exceptions::InvalidVersion::new_err(( + format!("{} is not a valid CSR version", version), + version, + )), + )); } Ok(CertificateSigningRequest { From 2530fa1999468185a368f5a4ea3cf21b486b3518 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 03:31:57 +0000 Subject: [PATCH 663/827] Bump nox from 2022.11.21 to 2023.4.22 (#8790) Bumps [nox](https://github.com/wntrblm/nox) from 2022.11.21 to 2023.4.22. - [Release notes](https://github.com/wntrblm/nox/releases) - [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md) - [Commits](https://github.com/wntrblm/nox/compare/2022.11.21...2023.04.22) --- updated-dependencies: - dependency-name: nox dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e960c623765d..50b8353b2d59 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -71,7 +71,7 @@ mypy-extensions==1.0.0 # via # black # mypy -nox==2022.11.21 +nox==2023.4.22 # via cryptography (pyproject.toml) packaging==23.1 # via From e3ae04d9c580623307a6dcc906aed4d327c7bbdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 03:42:09 +0000 Subject: [PATCH 664/827] Bump argcomplete from 2.1.2 to 3.0.6 (#8784) Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 2.1.2 to 3.0.6. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v2.1.2...v3.0.6) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 50b8353b2d59..8562db7ff388 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -7,7 +7,7 @@ alabaster==0.7.13 # via sphinx -argcomplete==2.1.2 +argcomplete==3.0.6 # via nox attrs==23.1.0 # via From 9e7aa16b656e5eb9955493b60106ebf8a86fc348 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 03:52:50 +0000 Subject: [PATCH 665/827] Bump virtualenv from 20.21.1 to 20.22.0 (#8760) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.21.1 to 20.22.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.21.1...20.22.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 8562db7ff388..e48ac8e5ce70 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -180,7 +180,7 @@ urllib3==1.26.15 # via # requests # twine -virtualenv==20.21.1 +virtualenv==20.22.0 # via nox webencodings==0.5.1 # via bleach From a7caf592648f0021f1c53a4a7858717364dca73d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 22 Apr 2023 22:13:58 -0600 Subject: [PATCH 666/827] Remove attrs from ci-constraints-requirements.txt (#8791) It's now unused in pytest: https://github.com/pytest-dev/pytest/commit/310b67b2271cb05f575054c1cdd2ece2412c89a2 --- ci-constraints-requirements.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e48ac8e5ce70..2e53429ed18e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -9,9 +9,6 @@ alabaster==0.7.13 # via sphinx argcomplete==3.0.6 # via nox -attrs==23.1.0 - # via - # pytest babel==2.12.1 # via sphinx black==23.3.0 From e9183cae405b5f2c99b8b715ed18bacb91fb273c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 23 Apr 2023 09:36:10 -0600 Subject: [PATCH 667/827] Re-pin importlib-metadata (#8792) --- ci-constraints-requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2e53429ed18e..97e8c71d6025 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -46,6 +46,10 @@ idna==3.4 # via requests imagesize==1.4.1 # via sphinx +importlib-metadata==6.6.0 + # via + # keyring + # twine iniconfig==2.0.0 # via pytest jaraco-classes==3.2.3 From 3b4a5e27916371e1708f7baedb4e19cf9bb2cc8d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 23 Apr 2023 11:10:24 -0600 Subject: [PATCH 668/827] Bump syn (#8793) dependabot is not currently updating it because of: https://github.com/dependabot/dependabot-core/issues/2064 --- src/rust/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c7bc163a11a6..79d5fd721e44 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -31,7 +31,7 @@ checksum = "ee4d9abdcc064cc9568bff2599089bb497a7de2c4b59608de35e3380b496617a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.15", ] [[package]] @@ -173,7 +173,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.15", ] [[package]] @@ -385,9 +385,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.12" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", From ca7bcf492c5d1b792e0fffe4ef07a3f0154318b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 19:17:32 +0000 Subject: [PATCH 669/827] Bump asn1 from 0.14.0 to 0.15.0 in /src/rust (#8796) Bumps [asn1](https://github.com/alex/rust-asn1) from 0.14.0 to 0.15.0. - [Release notes](https://github.com/alex/rust-asn1/releases) - [Commits](https://github.com/alex/rust-asn1/compare/0.14.0...0.15.0) --- updated-dependencies: - dependency-name: asn1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- src/rust/cryptography-x509/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 79d5fd721e44..eb9290607fe9 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -16,18 +16,18 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "asn1" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48a34f02cde9e43d380b3c72f3deb14b9ef8bf262bd3c92426437b21e74a509a" +checksum = "fa66f5a3e8407b8d3dd8fefc2a62a1aba9539a1d8f856024643c2ae0a8e541ed" dependencies = [ "asn1_derive", ] [[package]] name = "asn1_derive" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4d9abdcc064cc9568bff2599089bb497a7de2c4b59608de35e3380b496617a" +checksum = "a6365c8b2b1a059ca234d1b69ba501cfa98f1cfd342b95c75611895f1cb0fb81" dependencies = [ "proc-macro2", "quote", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index e97f800b7108..b928e55d2221 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" pyo3 = { version = "0.18" } -asn1 = { version = "0.14.0", default-features = false } +asn1 = { version = "0.15.0", default-features = false } cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" diff --git a/src/rust/cryptography-x509/Cargo.toml b/src/rust/cryptography-x509/Cargo.toml index b062ddbbfb57..398473471733 100644 --- a/src/rust/cryptography-x509/Cargo.toml +++ b/src/rust/cryptography-x509/Cargo.toml @@ -8,4 +8,4 @@ publish = false rust-version = "1.56.0" [dependencies] -asn1 = { version = "0.14.0", default-features = false } +asn1 = { version = "0.15.0", default-features = false } From 5f3871e4dfb9bc8f4da9f2317d656538223ad400 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 23 Apr 2023 14:51:35 -0500 Subject: [PATCH 670/827] add two RSA PSS certificate vectors that have invalid encodings (#8797) * add two RSA PSS certificate vectors that have invalid encodings The signatures on these vectors are not valid. * spelling --- docs/development/test-vectors.rst | 5 +++++ docs/spelling_wordlist.txt | 1 + .../x509/custom/rsa_pss_cert_invalid_mgf.der | Bin 0 -> 891 bytes .../x509/custom/rsa_pss_cert_no_sig_params.der | Bin 0 -> 842 bytes 4 files changed, 6 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/rsa_pss_cert_invalid_mgf.der create mode 100644 vectors/cryptography_vectors/x509/custom/rsa_pss_cert_no_sig_params.der diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index c042eb9bf331..e86f27afde75 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -478,6 +478,11 @@ Custom X.509 Vectors are longer than 2 characters. * ``rsa_pss_cert.pem`` - A self-signed certificate with an RSA PSS signature with ``asymmetric/PKCS8/rsa_pss_2048.pem`` as its key. +* ``rsa_pss_cert_invalid_mgf.der`` - A self-signed certificate with an invalid + RSA PSS signature that has a non-MGF1 OID for its mask generation function in the + signature algorithm. +* ``rsa_pss_cert_no_sig_params.der`` - A self-signed certificate with an invalid + RSA PSS signature algorithm that is missing signature parameters for PSS. * ``long-form-name-attribute.pem`` - A certificate with ``subject`` and ``issuer`` names containing attributes whose value's tag is encoded in long-form. * ``mismatch_inner_outer_sig_algorithm.der`` - A leaf certificate derived from diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index d581d3d4c490..62a62fb96e34 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -77,6 +77,7 @@ Koblitz Lange logins metadata +MGF Monterey Mozilla multi diff --git a/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_invalid_mgf.der b/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_invalid_mgf.der new file mode 100644 index 0000000000000000000000000000000000000000..3141976caed07ba59251fe06bae85d819fd89fee GIT binary patch literal 891 zcmXqLVlFpmVlr63%*4pVBx2w2|Jioo@6~q`k{@nZ{;zfWnm;oPoY*+E+C196^D;7W z8JI5MH{fOCOlb39Ol4+aVq|4lC}SXnP{DyFyNHE}iQ%4sl%a%y7#nja3o{RYa#3YL zNq%}!VnIfwUS__5oH(zMk%5V^fsui+p`k^TIIpp>fr%kd49vx=w~0}~fE!^u7jqLM zKZ8LNBNtN>BO}B1h?jY-8fLQ`Ls!oERbY3<<7r?01KTaGTz}SAiq|CV)%>iRHZ9{+ z>=D)2gXcre2``$#8n@ungvRSf=6HwC+q7{XS3vrf`BG^u-WpFQPHA#Dq15=rgoRO)m_v2m(SJYJvnu6X-Tipx+^;Knyceqa3A&HpLle9Z{!!Pb$qRBV)_ZrWb zta}+fCWrp$Dn7DzcPc29Eqzenyvn-b(ofYBS5`_W6*svbcK%+YT3m0iXTm!Fo#K~# zPCtB?!Xa0~!qE4E>2RGfJNT literal 0 HcmV?d00001 diff --git a/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_no_sig_params.der b/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_no_sig_params.der new file mode 100644 index 0000000000000000000000000000000000000000..33df2ec52f188624d18bd4b77e9aeb6d81461454 GIT binary patch literal 842 zcmXqLVsfr%kd49vx=w~0}~fE!^u7jqLM zKZ8LNBNtN>BO}B1h?jY-8fLQ`Ls!oERbY3<<7r?01KTaGTz}SAiq|CV)%>iRHZ9{+ z>=D)2gXcre2``$#8n@ungvRSf=6HwC+q7{XS3vrf`BG^u-WpFQPHA#Dq15=rgoRO)m_v2m(SJYJvnu6X-Tipx+^;Knyceqa3Al|}tN6&?-Kn5Zw)8=P z^D66#OFvalTv;ihRNUl#*!g>nYH_{6o(b#xcZy%~IsNcm3Wr<`3q#)vrq}hhT2WcY z(@ME`)EIUoE1k2ED%MoC&ks)C`SQG#d@T#oX0t@Gv*+*gR;YSA@q}>Tg@s0sJH*a5 y)c!SJee0g&2bNVUwEy@$)4s_#i>t^?G-Rju&0o`-d?y6HvN@gCwp05aqcH$9U_z7t literal 0 HcmV?d00001 From 9425d2376b3601e625556d7d3f07e8ba1cd2800a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 23 Apr 2023 15:22:50 -0500 Subject: [PATCH 671/827] add one more RSA PSS invalid test vector (#8798) --- docs/development/test-vectors.rst | 2 ++ .../custom/rsa_pss_cert_unsupported_mgf_hash.der | Bin 0 -> 891 bytes 2 files changed, 2 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/rsa_pss_cert_unsupported_mgf_hash.der diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index e86f27afde75..1916c57c4098 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -483,6 +483,8 @@ Custom X.509 Vectors signature algorithm. * ``rsa_pss_cert_no_sig_params.der`` - A self-signed certificate with an invalid RSA PSS signature algorithm that is missing signature parameters for PSS. +* ``rsa_pss_cert_unsupported_mgf_hash.der`` - A self-signed certificate with an + unsupported MGF1 hash algorithm in the signature algorithm. * ``long-form-name-attribute.pem`` - A certificate with ``subject`` and ``issuer`` names containing attributes whose value's tag is encoded in long-form. * ``mismatch_inner_outer_sig_algorithm.der`` - A leaf certificate derived from diff --git a/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_unsupported_mgf_hash.der b/vectors/cryptography_vectors/x509/custom/rsa_pss_cert_unsupported_mgf_hash.der new file mode 100644 index 0000000000000000000000000000000000000000..d6276d09886695d703095a9102a18fe52db41bec GIT binary patch literal 891 zcmXqLVlFpmVlr63%*4pVBx2w2|Jioo@6~q`k{@nZ{;zfWnm;oPoY*+E+C196^D;7W z8JI5MH{fOCOlb39Ol4+aVq|4lC}SXnP{DyFyNHE}iQ%4sl%a%y7#nja3o{RYa#3YL zNq%}!VnIfwUS__5oH(zMk%5V^fsui+p`k^TIIpp>fr%kd49vx=w~0}~fE!^u7jqLM zKZ8LNBNtN>BO}B1h?jY-8fLQ`Ls!oERbY3<<7r?01KTaGTz}SAiq|CV)%>iRHZ9{+ z>=D)2gXcre2``$#8n@ungvRSf=6HwC+q7{XS3vrf`BG^u-WpFQPHA#Dq15=rgoRO)m_v2m(SJYJvnu6X-Tipx+^;Knyceqa3AoSz>zch>|D@3}u7PPEwiagy*P?GE1Xi@TR- z@=g7{#xo}CUPh0}p+CBckL=x@3JPUQ9~3yRvaY!FQ}x7^l@dzDP40)Czt^Z1*Bk7a zu+D#{_$8my58tJ5$knhg^u1tuU2m%um32I=l#54=VMnskIUA{BO=bK1;N)E{mON|$ zfo17WR3jd?{63j9;c#@soF{Kz9=oj3p_|K4cxHBov2kdV=;MV2#)S-$`5~7t&s)jY zvLJ0XOB6eM{yuMos<#tQ2nSwRX!N*4>}*5rU-Q+s?n!=NS+zp@kKZ%xn~bx#ip)eq Zc6#6ZHNDAqLf|W#(|K(>weK++0{~X}ONRge literal 0 HcmV?d00001 From a7abb5b2f684eb019e837bd8ec50a1adccfc841f Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 23 Apr 2023 15:41:31 -0600 Subject: [PATCH 672/827] Rewrite how we cached RevokedCertificates (#8799) This removes the use of non_covariant, which is a blocker for considering self_cell. --- src/rust/src/x509/crl.rs | 70 +++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 079122f2c392..db4fd0394afd 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -17,11 +17,9 @@ fn load_der_x509_crl( py: pyo3::Python<'_>, data: pyo3::Py, ) -> Result { - let owned = OwnedCertificateRevocationList::try_new( - data, - |data| asn1::parse_single(data.as_bytes(py)), - |_| Ok(pyo3::once_cell::GILOnceCell::new()), - )?; + let owned = OwnedCertificateRevocationList::try_new(data, |data| { + asn1::parse_single(data.as_bytes(py)) + })?; let version = owned.borrow_value().tbs_cert_list.version.unwrap_or(1); if version != 1 { @@ -35,6 +33,7 @@ fn load_der_x509_crl( Ok(CertificateRevocationList { owned: Arc::new(owned), + revoked_certs: pyo3::once_cell::GILOnceCell::new(), cached_extensions: None, }) } @@ -61,15 +60,13 @@ struct OwnedCertificateRevocationList { #[borrows(data)] #[covariant] value: crl::CertificateRevocationList<'this>, - #[borrows(data)] - #[not_covariant] - revoked_certs: pyo3::once_cell::GILOnceCell>>, } #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct CertificateRevocationList { owned: Arc, + revoked_certs: pyo3::once_cell::GILOnceCell>, cached_extensions: Option, } @@ -78,15 +75,11 @@ impl CertificateRevocationList { Ok(asn1::write_single(self.owned.borrow_value())?) } - fn revoked_cert(&self, py: pyo3::Python<'_>, idx: usize) -> pyo3::PyResult { - let owned = try_map_arc_data_crl(&self.owned, |_crl, revoked_certs| { - let revoked_certs = revoked_certs.get(py).unwrap(); - Ok::<_, pyo3::PyErr>(revoked_certs[idx].clone()) - })?; - Ok(RevokedCertificate { - owned, + fn revoked_cert(&self, py: pyo3::Python<'_>, idx: usize) -> RevokedCertificate { + RevokedCertificate { + owned: self.revoked_certs.get(py).unwrap()[idx].clone(), cached_extensions: None, - }) + } } fn len(&self) -> usize { @@ -143,13 +136,13 @@ impl CertificateRevocationList { py: pyo3::Python<'_>, idx: &pyo3::PyAny, ) -> pyo3::PyResult { - self.owned.with(|val| { - val.revoked_certs.get_or_init(py, || { - match &val.value.tbs_cert_list.revoked_certificates { - Some(c) => c.unwrap_read().clone().collect(), - None => vec![], - } - }); + self.revoked_certs.get_or_init(py, || { + let mut revoked_certs = vec![]; + let mut it = self.__iter__(); + while let Some(c) = it.__next__() { + revoked_certs.push(c.owned); + } + revoked_certs }); if idx.is_instance_of::()? { @@ -158,7 +151,7 @@ impl CertificateRevocationList { .indices(self.len().try_into().unwrap())?; let result = pyo3::types::PyList::empty(py); for i in (indices.start..indices.stop).step_by(indices.step.try_into().unwrap()) { - let revoked_cert = pyo3::PyCell::new(py, self.revoked_cert(py, i as usize)?)?; + let revoked_cert = pyo3::PyCell::new(py, self.revoked_cert(py, i as usize))?; result.append(revoked_cert)?; } Ok(result.to_object(py)) @@ -170,7 +163,7 @@ impl CertificateRevocationList { if idx >= (self.len() as isize) || idx < 0 { return Err(pyo3::exceptions::PyIndexError::new_err(())); } - Ok(pyo3::PyCell::new(py, self.revoked_cert(py, idx as usize)?)?.to_object(py)) + Ok(pyo3::PyCell::new(py, self.revoked_cert(py, idx as usize))?.to_object(py)) } } @@ -424,21 +417,6 @@ struct CRLIterator { // Open-coded implementation of the API discussed in // https://github.com/joshua-maros/ouroboros/issues/38 -fn try_map_arc_data_crl( - crl: &Arc, - f: impl for<'this> FnOnce( - &'this OwnedCertificateRevocationList, - &pyo3::once_cell::GILOnceCell>>, - ) -> Result, E>, -) -> Result { - OwnedRevokedCertificate::try_new(Arc::clone(crl), |inner_crl| { - crl.with(|value| { - f(inner_crl, unsafe { - std::mem::transmute(value.revoked_certs) - }) - }) - }) -} fn try_map_arc_data_mut_crl_iterator( it: &mut OwnedCRLIteratorData, f: impl for<'this> FnOnce( @@ -485,6 +463,18 @@ struct OwnedRevokedCertificate { value: crl::RevokedCertificate<'this>, } +impl Clone for OwnedRevokedCertificate { + fn clone(&self) -> OwnedRevokedCertificate { + // This is safe because `Arc::clone` ensures the data is alive, but + // Rust doesn't understand the lifetime relationship it produces. + // Open-coded implementation of the API discussed in + // https://github.com/joshua-maros/ouroboros/issues/38 + OwnedRevokedCertificate::new(Arc::clone(self.borrow_data()), |_| unsafe { + std::mem::transmute(self.borrow_value().clone()) + }) + } +} + #[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.x509")] struct RevokedCertificate { owned: OwnedRevokedCertificate, From 085c373fb6e610f0939223c62f32f9eb643f7ab2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 23 Apr 2023 16:27:01 -0600 Subject: [PATCH 673/827] Remove HMAC bindings (#8801) --- src/_cffi_src/build_openssl.py | 1 - src/_cffi_src/openssl/hmac.py | 26 -------------------------- 2 files changed, 27 deletions(-) delete mode 100644 src/_cffi_src/openssl/hmac.py diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index 3ff1332e2772..e199329db606 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -36,7 +36,6 @@ "err", "evp", "fips", - "hmac", "nid", "objects", "opensslv", diff --git a/src/_cffi_src/openssl/hmac.py b/src/_cffi_src/openssl/hmac.py deleted file mode 100644 index 8fbc2b411608..000000000000 --- a/src/_cffi_src/openssl/hmac.py +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -from __future__ import annotations - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef ... HMAC_CTX; -""" - -FUNCTIONS = """ -int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *); -int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t); -int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *); -int HMAC_CTX_copy(HMAC_CTX *, HMAC_CTX *); - -HMAC_CTX *HMAC_CTX_new(void); -void HMAC_CTX_free(HMAC_CTX *ctx); -""" - -CUSTOMIZATIONS = """ -""" From cad9499ea01cbbd7196569b660f147d52e2e6e87 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 07:15:54 -0600 Subject: [PATCH 674/827] De-duplicate SPKI struct (#8803) --- src/rust/src/asn1.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index cad48a73f174..d412bb8b77f5 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -3,6 +3,7 @@ // for complete details. use crate::error::{CryptographyError, CryptographyResult}; +use cryptography_x509::common::SubjectPublicKeyInfo; use cryptography_x509::name::Name; use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; @@ -23,29 +24,17 @@ pub(crate) fn oid_to_py_oid<'p>( Ok(pyo3::Py::new(py, crate::oid::ObjectIdentifier { oid: oid.clone() })?.into_ref(py)) } -#[derive(asn1::Asn1Read)] -struct AlgorithmIdentifier<'a> { - _oid: asn1::ObjectIdentifier, - _params: Option>, -} - -#[derive(asn1::Asn1Read)] -struct Spki<'a> { - _algorithm: AlgorithmIdentifier<'a>, - data: asn1::BitString<'a>, -} - #[pyo3::prelude::pyfunction] fn parse_spki_for_data( py: pyo3::Python<'_>, data: &[u8], ) -> Result { - let spki = asn1::parse_single::>(data)?; - if spki.data.padding_bits() != 0 { + let spki = asn1::parse_single::>(data)?; + if spki.subject_public_key.padding_bits() != 0 { return Err(pyo3::exceptions::PyValueError::new_err("Invalid public key encoding").into()); } - Ok(pyo3::types::PyBytes::new(py, spki.data.as_bytes()).to_object(py)) + Ok(pyo3::types::PyBytes::new(py, spki.subject_public_key.as_bytes()).to_object(py)) } #[derive(asn1::Asn1Read, asn1::Asn1Write)] From 342fa03ffde73c967bf6af731f18a6de44e6c8c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 13:17:16 +0000 Subject: [PATCH 675/827] Bump argcomplete from 3.0.6 to 3.0.8 (#8805) Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.0.6 to 3.0.8. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.0.6...v3.0.8) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 97e8c71d6025..3f7b5f352a24 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -7,7 +7,7 @@ alabaster==0.7.13 # via sphinx -argcomplete==3.0.6 +argcomplete==3.0.8 # via nox babel==2.12.1 # via sphinx From eb995fed64dd733db6340fd729de8b927452689a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 07:23:15 -0600 Subject: [PATCH 676/827] modernize intersphinx_mapping configuration (#8806) --- docs/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0d8f866362a3..e67b03b6597e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -183,8 +183,7 @@ ), ] -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"https://docs.python.org/3": None} +intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} epub_theme = "epub" From 8edeed4392302cd5302465e8472786935842ae28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 13:36:57 +0000 Subject: [PATCH 677/827] Bump sphinx from 6.1.3 to 6.2.0 (#8804) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 6.1.3 to 6.2.0. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v6.1.3...v6.2.0) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3f7b5f352a24..c57e536353f7 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -140,7 +140,7 @@ six==1.16.0 # via bleach snowballstemmer==2.2.0 # via sphinx -sphinx==6.1.3 +sphinx==6.2.0 # via # cryptography (pyproject.toml) # sphinx-rtd-theme From 963d6c456bfa7b0beeead2d3016fab77abf42c61 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 08:30:29 -0600 Subject: [PATCH 678/827] Remove duplicative test certificate structure (#8807) --- src/rust/src/asn1.rs | 60 +++++++++++--------------------------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index d412bb8b77f5..01b4aff19015 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -3,7 +3,9 @@ // for complete details. use crate::error::{CryptographyError, CryptographyResult}; -use cryptography_x509::common::SubjectPublicKeyInfo; +use asn1::SimpleAsn1Readable; +use cryptography_x509::certificate::Certificate; +use cryptography_x509::common::{SubjectPublicKeyInfo, Time}; use cryptography_x509::name::Name; use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; @@ -152,39 +154,6 @@ struct TestCertificate { subject_value_tags: Vec, } -#[derive(asn1::Asn1Read)] -struct Asn1Certificate<'a> { - tbs_cert: TbsCertificate<'a>, - _signature_alg: asn1::Sequence<'a>, - _signature: asn1::BitString<'a>, -} - -#[derive(asn1::Asn1Read)] -struct TbsCertificate<'a> { - #[explicit(0)] - _version: Option, - _serial: asn1::BigUint<'a>, - _signature_alg: asn1::Sequence<'a>, - - issuer: Name<'a>, - validity: Validity<'a>, - subject: Name<'a>, - - _spki: asn1::Sequence<'a>, - #[implicit(1)] - _issuer_unique_id: Option>, - #[implicit(2)] - _subject_unique_id: Option>, - #[explicit(3)] - _extensions: Option>, -} - -#[derive(asn1::Asn1Read)] -struct Validity<'a> { - not_before: asn1::Tlv<'a>, - not_after: asn1::Tlv<'a>, -} - fn parse_name_value_tags(rdns: &mut Name<'_>) -> Vec { let mut tags = vec![]; for rdn in rdns.unwrap_read().clone() { @@ -196,21 +165,22 @@ fn parse_name_value_tags(rdns: &mut Name<'_>) -> Vec { tags } +fn time_tag(t: &Time) -> u8 { + match t { + Time::UtcTime(_) => asn1::UtcTime::TAG.as_u8().unwrap(), + Time::GeneralizedTime(_) => asn1::GeneralizedTime::TAG.as_u8().unwrap(), + } +} + #[pyo3::prelude::pyfunction] fn test_parse_certificate(data: &[u8]) -> Result { - let mut asn1_cert = asn1::parse_single::>(data)?; + let mut cert = asn1::parse_single::>(data)?; Ok(TestCertificate { - not_before_tag: asn1_cert - .tbs_cert - .validity - .not_before - .tag() - .as_u8() - .unwrap(), - not_after_tag: asn1_cert.tbs_cert.validity.not_after.tag().as_u8().unwrap(), - issuer_value_tags: parse_name_value_tags(&mut asn1_cert.tbs_cert.issuer), - subject_value_tags: parse_name_value_tags(&mut asn1_cert.tbs_cert.subject), + not_before_tag: time_tag(&cert.tbs_cert.validity.not_before), + not_after_tag: time_tag(&cert.tbs_cert.validity.not_after), + issuer_value_tags: parse_name_value_tags(&mut cert.tbs_cert.issuer), + subject_value_tags: parse_name_value_tags(&mut cert.tbs_cert.subject), }) } From 33fb461ad9275edd5c5a028b18acaf14a93e6102 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 09:14:43 -0600 Subject: [PATCH 679/827] Refactor build so cffi compilation is in its own crate (#8809) --- src/rust/Cargo.lock | 10 ++ src/rust/Cargo.toml | 3 +- src/rust/build.rs | 123 +------------------------ src/rust/cryptography-cffi/Cargo.toml | 15 +++ src/rust/cryptography-cffi/build.rs | 126 ++++++++++++++++++++++++++ src/rust/cryptography-cffi/src/lib.rs | 31 +++++++ src/rust/src/lib.rs | 25 +---- 7 files changed, 189 insertions(+), 144 deletions(-) create mode 100644 src/rust/cryptography-cffi/Cargo.toml create mode 100644 src/rust/cryptography-cffi/build.rs create mode 100644 src/rust/cryptography-cffi/src/lib.rs diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index eb9290607fe9..e00d244cd4bb 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -64,6 +64,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cryptography-cffi" +version = "0.1.0" +dependencies = [ + "cc", + "openssl-sys", + "pyo3", +] + [[package]] name = "cryptography-openssl" version = "0.1.0" @@ -80,6 +89,7 @@ version = "0.1.0" dependencies = [ "asn1", "cc", + "cryptography-cffi", "cryptography-openssl", "cryptography-x509", "foreign-types-shared", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index b928e55d2221..dae85cef1d25 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -11,6 +11,7 @@ rust-version = "1.56.0" once_cell = "1" pyo3 = { version = "0.18" } asn1 = { version = "0.15.0", default-features = false } +cryptography-cffi = { path = "cryptography-cffi" } cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" @@ -35,4 +36,4 @@ lto = "thin" overflow-checks = true [workspace] -members = ["cryptography-openssl", "cryptography-x509"] +members = ["cryptography-cffi", "cryptography-openssl", "cryptography-x509"] diff --git a/src/rust/build.rs b/src/rust/build.rs index 7b63b95d5d24..574560394d88 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -1,77 +1,11 @@ +// 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. + use std::env; -use std::path::Path; -use std::process::Command; #[allow(clippy::unusual_byte_groupings)] fn main() { - let target = env::var("TARGET").unwrap(); - let openssl_static = env::var("OPENSSL_STATIC") - .map(|x| x == "1") - .unwrap_or(false); - if target.contains("apple") && openssl_static { - // On (older) OSX we need to link against the clang runtime, - // which is hidden in some non-default path. - // - // More details at https://github.com/alexcrichton/curl-rust/issues/279. - if let Some(path) = macos_link_search_path() { - println!("cargo:rustc-link-lib=clang_rt.osx"); - println!("cargo:rustc-link-search={}", path); - } - } - - 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_else(|_| "python3".to_string()); - println!("cargo:rerun-if-changed=../_cffi_src/"); - let output = Command::new(&python) - .env("OUT_DIR", &out_dir) - .arg("../_cffi_src/build_openssl.py") - .output() - .expect("failed to execute build_openssl.py"); - if !output.status.success() { - panic!( - "failed to run build_openssl.py, stdout: \n{}\nstderr: \n{}\n", - String::from_utf8(output.stdout).unwrap(), - String::from_utf8(output.stderr).unwrap() - ); - } - - let python_impl = run_python_script( - &python, - "import platform; print(platform.python_implementation(), end='')", - ) - .unwrap(); - println!("cargo:rustc-cfg=python_implementation=\"{}\"", python_impl); - let python_include = run_python_script( - &python, - "import sysconfig; print(sysconfig.get_path('include'), end='')", - ) - .unwrap(); - let openssl_include = - std::env::var_os("DEP_OPENSSL_INCLUDE").expect("unable to find openssl include path"); - let openssl_c = Path::new(&out_dir).join("_openssl.c"); - - let mut build = cc::Build::new(); - build - .file(openssl_c) - .include(python_include) - .include(openssl_include) - .flag_if_supported("-Wconversion") - .flag_if_supported("-Wno-error=sign-conversion") - .flag_if_supported("-Wno-unused-parameter"); - - // Enable abi3 mode if we're not using PyPy. - if python_impl != "PyPy" { - // cp37 (Python 3.7 to help our grep when we some day drop 3.7 support) - build.define("Py_LIMITED_API", "0x030700f0"); - } - - if cfg!(windows) { - build.define("WIN32_LEAN_AND_MEAN", None); - } - - build.compile("_openssl.a"); - if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { let version = u64::from_str_radix(&version, 16).unwrap(); @@ -84,52 +18,3 @@ fn main() { println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_BORINGSSL"); } } - -/// Run a python script using the specified interpreter binary. -fn run_python_script(interpreter: impl AsRef, script: &str) -> Result { - let interpreter = interpreter.as_ref(); - let out = Command::new(interpreter) - .env("PYTHONIOENCODING", "utf-8") - .arg("-c") - .arg(script) - .output(); - - match out { - Err(err) => Err(format!( - "failed to run the Python interpreter at {}: {}", - interpreter.display(), - err - )), - Ok(ok) if !ok.status.success() => Err(format!( - "Python script failed: {}", - String::from_utf8(ok.stderr).expect("failed to parse Python script stderr as utf-8") - )), - Ok(ok) => Ok( - String::from_utf8(ok.stdout).expect("failed to parse Python script stdout as utf-8") - ), - } -} - -fn macos_link_search_path() -> Option { - let output = Command::new("clang") - .arg("--print-search-dirs") - .output() - .ok()?; - if !output.status.success() { - println!( - "failed to run 'clang --print-search-dirs', continuing without a link search path" - ); - return None; - } - - let stdout = String::from_utf8_lossy(&output.stdout); - for line in stdout.lines() { - if line.contains("libraries: =") { - let path = line.split('=').nth(1)?; - return Some(format!("{}/lib/darwin", path)); - } - } - - println!("failed to determine link search path, continuing without it"); - None -} diff --git a/src/rust/cryptography-cffi/Cargo.toml b/src/rust/cryptography-cffi/Cargo.toml new file mode 100644 index 000000000000..0c5655b170cc --- /dev/null +++ b/src/rust/cryptography-cffi/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cryptography-cffi" +version = "0.1.0" +authors = ["The cryptography developers "] +edition = "2021" +publish = false +# This specifies the MSRV +rust-version = "1.56.0" + +[dependencies] +pyo3 = { version = "0.18" } +openssl-sys = "0.9.85" + +[build-dependencies] +cc = "1.0.72" diff --git a/src/rust/cryptography-cffi/build.rs b/src/rust/cryptography-cffi/build.rs new file mode 100644 index 000000000000..9a93b50bc438 --- /dev/null +++ b/src/rust/cryptography-cffi/build.rs @@ -0,0 +1,126 @@ +// 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. + +use std::env; +use std::path::Path; +use std::process::Command; + +fn main() { + let target = env::var("TARGET").unwrap(); + let openssl_static = env::var("OPENSSL_STATIC") + .map(|x| x == "1") + .unwrap_or(false); + if target.contains("apple") && openssl_static { + // On (older) OSX we need to link against the clang runtime, + // which is hidden in some non-default path. + // + // More details at https://github.com/alexcrichton/curl-rust/issues/279. + if let Some(path) = macos_link_search_path() { + println!("cargo:rustc-link-lib=clang_rt.osx"); + println!("cargo:rustc-link-search={}", path); + } + } + + 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_else(|_| "python3".to_string()); + println!("cargo:rerun-if-changed=../../_cffi_src/"); + let output = Command::new(&python) + .env("OUT_DIR", &out_dir) + .arg("../../_cffi_src/build_openssl.py") + .output() + .expect("failed to execute build_openssl.py"); + if !output.status.success() { + panic!( + "failed to run build_openssl.py, stdout: \n{}\nstderr: \n{}\n", + String::from_utf8(output.stdout).unwrap(), + String::from_utf8(output.stderr).unwrap() + ); + } + + let python_impl = run_python_script( + &python, + "import platform; print(platform.python_implementation(), end='')", + ) + .unwrap(); + println!("cargo:rustc-cfg=python_implementation=\"{}\"", python_impl); + let python_include = run_python_script( + &python, + "import sysconfig; print(sysconfig.get_path('include'), end='')", + ) + .unwrap(); + let openssl_include = + std::env::var_os("DEP_OPENSSL_INCLUDE").expect("unable to find openssl include path"); + let openssl_c = Path::new(&out_dir).join("_openssl.c"); + + let mut build = cc::Build::new(); + build + .file(openssl_c) + .include(python_include) + .include(openssl_include) + .flag_if_supported("-Wconversion") + .flag_if_supported("-Wno-error=sign-conversion") + .flag_if_supported("-Wno-unused-parameter"); + + // Enable abi3 mode if we're not using PyPy. + if python_impl != "PyPy" { + // cp37 (Python 3.7 to help our grep when we some day drop 3.7 support) + build.define("Py_LIMITED_API", "0x030700f0"); + } + + if cfg!(windows) { + build.define("WIN32_LEAN_AND_MEAN", None); + } + + build.compile("_openssl.a"); +} + +/// Run a python script using the specified interpreter binary. +fn run_python_script(interpreter: impl AsRef, script: &str) -> Result { + let interpreter = interpreter.as_ref(); + let out = Command::new(interpreter) + .env("PYTHONIOENCODING", "utf-8") + .arg("-c") + .arg(script) + .output(); + + match out { + Err(err) => Err(format!( + "failed to run the Python interpreter at {}: {}", + interpreter.display(), + err + )), + Ok(ok) if !ok.status.success() => Err(format!( + "Python script failed: {}", + String::from_utf8(ok.stderr).expect("failed to parse Python script stderr as utf-8") + )), + Ok(ok) => Ok( + String::from_utf8(ok.stdout).expect("failed to parse Python script stdout as utf-8") + ), + } +} + +fn macos_link_search_path() -> Option { + let output = Command::new("clang") + .arg("--print-search-dirs") + .output() + .ok()?; + if !output.status.success() { + println!( + "failed to run 'clang --print-search-dirs', continuing without a link search path" + ); + return None; + } + + let stdout = String::from_utf8_lossy(&output.stdout); + for line in stdout.lines() { + if line.contains("libraries: =") { + let path = line.split('=').nth(1)?; + return Some(format!("{}/lib/darwin", path)); + } + } + + println!("failed to determine link search path, continuing without it"); + None +} diff --git a/src/rust/cryptography-cffi/src/lib.rs b/src/rust/cryptography-cffi/src/lib.rs new file mode 100644 index 000000000000..e263d53d8769 --- /dev/null +++ b/src/rust/cryptography-cffi/src/lib.rs @@ -0,0 +1,31 @@ +// 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. + +#[cfg(not(python_implementation = "PyPy"))] +use pyo3::FromPyPointer; + +#[cfg(python_implementation = "PyPy")] +extern "C" { + fn Cryptography_make_openssl_module() -> std::os::raw::c_int; +} +#[cfg(not(python_implementation = "PyPy"))] +extern "C" { + fn PyInit__openssl() -> *mut pyo3::ffi::PyObject; +} + +pub fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::types::PyModule> { + #[cfg(python_implementation = "PyPy")] + let openssl_mod = unsafe { + let res = Cryptography_make_openssl_module(); + assert_eq!(res, 0); + pyo3::types::PyModule::import(py, "_openssl")? + }; + #[cfg(not(python_implementation = "PyPy"))] + let openssl_mod = unsafe { + let ptr = PyInit__openssl(); + pyo3::types::PyModule::from_owned_ptr(py, ptr) + }; + + Ok(openssl_mod) +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index f39762c88a09..3d04f93c9b72 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -19,18 +19,6 @@ mod pkcs7; mod pool; mod x509; -#[cfg(not(python_implementation = "PyPy"))] -use pyo3::FromPyPointer; - -#[cfg(python_implementation = "PyPy")] -extern "C" { - fn Cryptography_make_openssl_module() -> std::os::raw::c_int; -} -#[cfg(not(python_implementation = "PyPy"))] -extern "C" { - fn PyInit__openssl() -> *mut pyo3::ffi::PyObject; -} - /// Returns the value of the input with the most-significant-bit copied to all /// of the bits. fn duplicate_msb_to_all(a: u8) -> u8 { @@ -172,18 +160,7 @@ 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)?; - #[cfg(python_implementation = "PyPy")] - let openssl_mod = unsafe { - let res = Cryptography_make_openssl_module(); - assert_eq!(res, 0); - pyo3::types::PyModule::import(py, "_openssl")? - }; - #[cfg(not(python_implementation = "PyPy"))] - let openssl_mod = unsafe { - let ptr = PyInit__openssl(); - pyo3::types::PyModule::from_owned_ptr(py, ptr) - }; - m.add_submodule(openssl_mod)?; + m.add_submodule(cryptography_cffi::create_module(py)?)?; let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?; openssl_mod.add_function(pyo3::wrap_pyfunction!(openssl_version, m)?)?; From 9b0133c4dcb0282124745e211d497ed025a91045 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 09:18:51 -0600 Subject: [PATCH 680/827] Remove clippy ignore that's no longer required (#8808) --- src/rust/src/backend/ed25519.rs | 4 ++-- src/rust/src/backend/ed448.rs | 4 ++-- src/rust/src/backend/x25519.rs | 4 ++-- src/rust/src/backend/x448.rs | 4 ++-- src/rust/src/lib.rs | 5 ----- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index 003a5e913275..f10d12db23f9 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -106,7 +106,7 @@ impl Ed25519PrivateKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_private_bytes( py, - &*slf, + slf, &slf.borrow().pkey, encoding, format, @@ -145,7 +145,7 @@ impl Ed25519PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, true) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) } fn __richcmp__( diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index 72fd6fd588a7..44e0240a1fa5 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -104,7 +104,7 @@ impl Ed448PrivateKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_private_bytes( py, - &*slf, + slf, &slf.borrow().pkey, encoding, format, @@ -143,7 +143,7 @@ impl Ed448PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, true) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) } fn __richcmp__( diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 409f28c87a18..0a62182b1be8 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -108,7 +108,7 @@ impl X25519PrivateKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_private_bytes( py, - &*slf, + slf, &slf.borrow().pkey, encoding, format, @@ -134,7 +134,7 @@ impl X25519PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, false) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false) } fn __richcmp__( diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index acfc9f2a0945..0eb44b8fe8fc 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -107,7 +107,7 @@ impl X448PrivateKey { ) -> CryptographyResult<&'p pyo3::types::PyBytes> { utils::pkey_private_bytes( py, - &*slf, + slf, &slf.borrow().pkey, encoding, format, @@ -133,7 +133,7 @@ impl X448PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, &*slf, &slf.borrow().pkey, encoding, format, false) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false) } fn __richcmp__( diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 3d04f93c9b72..95df2fa3c852 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -3,11 +3,6 @@ // for complete details. #![deny(rust_2018_idioms)] -// Temporarily allow `clippy::borrow_deref_ref` until we can upgrade to the -// latest pyo3: https://github.com/PyO3/pyo3/pull/2503 -// -// `unknown_lints` is required until GHA upgrades their rustc. -#![allow(unknown_lints, clippy::borrow_deref_ref)] mod asn1; mod backend; From a62a62ac76dde25c568542717ad92058f2ea145a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 24 Apr 2023 09:32:30 -0600 Subject: [PATCH 681/827] move more structs into cryptography-x509 (#8810) --- src/rust/cryptography-x509/src/common.rs | 6 ++ src/rust/cryptography-x509/src/lib.rs | 1 + src/rust/cryptography-x509/src/pkcs7.rs | 60 +++++++++++++++++ src/rust/src/asn1.rs | 8 +-- src/rust/src/pkcs7.rs | 86 +++++------------------- 5 files changed, 83 insertions(+), 78 deletions(-) create mode 100644 src/rust/cryptography-x509/src/pkcs7.rs diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 13fcb3368243..edae5d4a40bd 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -117,6 +117,12 @@ impl<'a, T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleA } } +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct DssSignature<'a> { + pub r: asn1::BigUint<'a>, + pub s: asn1::BigUint<'a>, +} + #[cfg(test)] mod tests { use super::{Asn1ReadableOrWritable, RawTlv}; diff --git a/src/rust/cryptography-x509/src/lib.rs b/src/rust/cryptography-x509/src/lib.rs index 897e0f6c0229..548e073b13e5 100644 --- a/src/rust/cryptography-x509/src/lib.rs +++ b/src/rust/cryptography-x509/src/lib.rs @@ -13,3 +13,4 @@ pub mod name; pub mod ocsp_req; pub mod ocsp_resp; pub mod oid; +pub mod pkcs7; diff --git a/src/rust/cryptography-x509/src/pkcs7.rs b/src/rust/cryptography-x509/src/pkcs7.rs new file mode 100644 index 000000000000..c5b7a9e3f650 --- /dev/null +++ b/src/rust/cryptography-x509/src/pkcs7.rs @@ -0,0 +1,60 @@ +// 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. + +use crate::{certificate, common, csr, name}; + +pub const PKCS7_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 1); +pub const PKCS7_SIGNED_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 2); + +#[derive(asn1::Asn1Write)] +pub struct ContentInfo<'a> { + pub _content_type: asn1::DefinedByMarker, + + #[defined_by(_content_type)] + pub content: Content<'a>, +} + +#[derive(asn1::Asn1DefinedByWrite)] +pub enum Content<'a> { + #[defined_by(PKCS7_SIGNED_DATA_OID)] + SignedData(asn1::Explicit<'a, Box>, 0>), + #[defined_by(PKCS7_DATA_OID)] + Data(Option>), +} + +#[derive(asn1::Asn1Write)] +pub struct SignedData<'a> { + pub version: u8, + pub digest_algorithms: asn1::SetOfWriter<'a, common::AlgorithmIdentifier<'a>>, + pub content_info: ContentInfo<'a>, + #[implicit(0)] + pub certificates: Option>>, + + // We don't ever supply any of these, so for now, don't fill out the fields. + #[implicit(1)] + pub crls: Option>>, + + pub signer_infos: asn1::SetOfWriter<'a, SignerInfo<'a>>, +} + +#[derive(asn1::Asn1Write)] +pub struct SignerInfo<'a> { + pub version: u8, + pub issuer_and_serial_number: IssuerAndSerialNumber<'a>, + pub digest_algorithm: common::AlgorithmIdentifier<'a>, + #[implicit(0)] + pub authenticated_attributes: Option>, + + pub digest_encryption_algorithm: common::AlgorithmIdentifier<'a>, + pub encrypted_digest: &'a [u8], + + #[implicit(1)] + pub unauthenticated_attributes: Option>, +} + +#[derive(asn1::Asn1Write)] +pub struct IssuerAndSerialNumber<'a> { + pub issuer: name::Name<'a>, + pub serial_number: asn1::BigInt<'a>, +} diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 01b4aff19015..96e44e93ae93 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -5,7 +5,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use asn1::SimpleAsn1Readable; use cryptography_x509::certificate::Certificate; -use cryptography_x509::common::{SubjectPublicKeyInfo, Time}; +use cryptography_x509::common::{DssSignature, SubjectPublicKeyInfo, Time}; use cryptography_x509::name::Name; use pyo3::basic::CompareOp; use pyo3::types::IntoPyDict; @@ -39,12 +39,6 @@ fn parse_spki_for_data( Ok(pyo3::types::PyBytes::new(py, spki.subject_public_key.as_bytes()).to_object(py)) } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct DssSignature<'a> { - r: asn1::BigUint<'a>, - s: asn1::BigUint<'a>, -} - pub(crate) fn big_byte_slice_to_py_int<'p>( py: pyo3::Python<'p>, v: &'_ [u8], diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 2fdb610e3e82..236976bf4046 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -6,17 +6,14 @@ use crate::asn1::encode_der_data; use crate::buf::CffiBuf; use crate::error::CryptographyResult; use crate::x509; -use cryptography_x509::csr::{Attribute, Attributes}; -use cryptography_x509::{common, name, oid}; +use cryptography_x509::csr::Attribute; +use cryptography_x509::{common, oid, pkcs7}; use once_cell::sync::Lazy; use std::borrow::Cow; use std::collections::HashMap; use std::ops::Deref; -const PKCS7_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 1); -const PKCS7_SIGNED_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 2); - const PKCS7_CONTENT_TYPE_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 3); const PKCS7_MESSAGE_DIGEST_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 4); const PKCS7_SIGNING_TIME_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 5); @@ -35,59 +32,6 @@ static OIDS_TO_MIC_NAME: Lazy> = Lazy::ne h }); -#[derive(asn1::Asn1Write)] -struct ContentInfo<'a> { - _content_type: asn1::DefinedByMarker, - - #[defined_by(_content_type)] - content: Content<'a>, -} - -#[derive(asn1::Asn1DefinedByWrite)] -enum Content<'a> { - #[defined_by(PKCS7_SIGNED_DATA_OID)] - SignedData(asn1::Explicit<'a, Box>, 0>), - #[defined_by(PKCS7_DATA_OID)] - Data(Option>), -} - -#[derive(asn1::Asn1Write)] -struct SignedData<'a> { - version: u8, - digest_algorithms: asn1::SetOfWriter<'a, common::AlgorithmIdentifier<'a>>, - content_info: ContentInfo<'a>, - #[implicit(0)] - certificates: - Option>>, - - // We don't ever supply any of these, so for now, don't fill out the fields. - #[implicit(1)] - crls: Option>>, - - signer_infos: asn1::SetOfWriter<'a, SignerInfo<'a>>, -} - -#[derive(asn1::Asn1Write)] -struct SignerInfo<'a> { - version: u8, - issuer_and_serial_number: IssuerAndSerialNumber<'a>, - digest_algorithm: common::AlgorithmIdentifier<'a>, - #[implicit(0)] - authenticated_attributes: Option>, - - digest_encryption_algorithm: common::AlgorithmIdentifier<'a>, - encrypted_digest: &'a [u8], - - #[implicit(1)] - unauthenticated_attributes: Option>, -} - -#[derive(asn1::Asn1Write)] -struct IssuerAndSerialNumber<'a> { - issuer: name::Name<'a>, - serial_number: asn1::BigInt<'a>, -} - #[pyo3::prelude::pyfunction] fn serialize_certificates<'p>( py: pyo3::Python<'p>, @@ -106,21 +50,21 @@ fn serialize_certificates<'p>( .map(|c| c.raw.borrow_value_public()) .collect::>(); - let signed_data = SignedData { + let signed_data = pkcs7::SignedData { version: 1, digest_algorithms: asn1::SetOfWriter::new(&[]), - content_info: ContentInfo { + content_info: pkcs7::ContentInfo { _content_type: asn1::DefinedByMarker::marker(), - content: Content::Data(Some(asn1::Explicit::new(b""))), + content: pkcs7::Content::Data(Some(asn1::Explicit::new(b""))), }, certificates: Some(asn1::SetOfWriter::new(&raw_certs)), crls: None, signer_infos: asn1::SetOfWriter::new(&[]), }; - let content_info = ContentInfo { + let content_info = pkcs7::ContentInfo { _content_type: asn1::DefinedByMarker::marker(), - content: Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), + content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), }; let content_info_bytes = asn1::write_single(&content_info)?; @@ -153,7 +97,7 @@ fn sign_and_serialize<'p>( smime_canonicalize(raw_data.as_bytes(), text_mode) }; - let content_type_bytes = asn1::write_single(&PKCS7_DATA_OID)?; + let content_type_bytes = asn1::write_single(&pkcs7::PKCS7_DATA_OID)?; let now = x509::common::datetime_now(py)?; let signing_time_bytes = asn1::write_single(&x509::certificate::time_from_datetime(now)?)?; let smime_cap_bytes = asn1::write_single(&asn1::SequenceOfWriter::new([ @@ -249,9 +193,9 @@ fn sign_and_serialize<'p>( } certs.push(cert.raw.borrow_value_public()); - signer_infos.push(SignerInfo { + signer_infos.push(pkcs7::SignerInfo { version: 1, - issuer_and_serial_number: IssuerAndSerialNumber { + issuer_and_serial_number: pkcs7::IssuerAndSerialNumber { issuer: cert.raw.borrow_value_public().tbs_cert.issuer.clone(), serial_number: cert.raw.borrow_value_public().tbs_cert.serial, }, @@ -276,12 +220,12 @@ fn sign_and_serialize<'p>( Some(asn1::parse_single(&data_tlv_bytes).unwrap()) }; - let signed_data = SignedData { + let signed_data = pkcs7::SignedData { version: 1, digest_algorithms: asn1::SetOfWriter::new(&digest_algs), - content_info: ContentInfo { + content_info: pkcs7::ContentInfo { _content_type: asn1::DefinedByMarker::marker(), - content: Content::Data(content.map(asn1::Explicit::new)), + content: pkcs7::Content::Data(content.map(asn1::Explicit::new)), }, certificates: if options.contains(pkcs7_options.getattr(pyo3::intern!(py, "NoCerts"))?)? { None @@ -292,9 +236,9 @@ fn sign_and_serialize<'p>( signer_infos: asn1::SetOfWriter::new(&signer_infos), }; - let content_info = ContentInfo { + let content_info = pkcs7::ContentInfo { _content_type: asn1::DefinedByMarker::marker(), - content: Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), + content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))), }; let ci_bytes = asn1::write_single(&content_info)?; From 4ecb62c5006894fa2d925795916ceec810588248 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 12:23:34 -0600 Subject: [PATCH 682/827] Refactor encode_extensions so that the largest extensions aren't inline (#8813) --- src/rust/src/x509/extensions.rs | 435 +++++++++++++++++--------------- 1 file changed, 228 insertions(+), 207 deletions(-) diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index 08e112cbbcf5..e12c320a0c47 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -118,6 +118,226 @@ pub(crate) fn encode_distribution_points<'p>( Ok(dps) } +fn encode_basic_constraints(ext: &pyo3::PyAny) -> CryptographyResult> { + #[derive(pyo3::prelude::FromPyObject)] + struct PyBasicConstraints { + ca: bool, + path_length: Option, + } + let pybc = ext.extract::()?; + let bc = extensions::BasicConstraints { + ca: pybc.ca, + path_length: pybc.path_length, + }; + Ok(asn1::write_single(&bc)?) +} + +fn encode_key_usage(py: pyo3::Python<'_>, ext: &pyo3::PyAny) -> CryptographyResult> { + let mut bs = [0, 0]; + certificate::set_bit( + &mut bs, + 0, + ext.getattr(pyo3::intern!(py, "digital_signature"))? + .is_true()?, + ); + certificate::set_bit( + &mut bs, + 1, + ext.getattr(pyo3::intern!(py, "content_commitment"))? + .is_true()?, + ); + certificate::set_bit( + &mut bs, + 2, + ext.getattr(pyo3::intern!(py, "key_encipherment"))? + .is_true()?, + ); + certificate::set_bit( + &mut bs, + 3, + ext.getattr(pyo3::intern!(py, "data_encipherment"))? + .is_true()?, + ); + certificate::set_bit( + &mut bs, + 4, + ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()?, + ); + certificate::set_bit( + &mut bs, + 5, + ext.getattr(pyo3::intern!(py, "key_cert_sign"))?.is_true()?, + ); + certificate::set_bit( + &mut bs, + 6, + ext.getattr(pyo3::intern!(py, "crl_sign"))?.is_true()?, + ); + if ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()? { + certificate::set_bit( + &mut bs, + 7, + ext.getattr(pyo3::intern!(py, "encipher_only"))?.is_true()?, + ); + certificate::set_bit( + &mut bs, + 8, + ext.getattr(pyo3::intern!(py, "decipher_only"))?.is_true()?, + ); + } + let (bits, unused_bits) = if bs[1] == 0 { + if bs[0] == 0 { + (&[][..], 0) + } else { + (&bs[..1], bs[0].trailing_zeros() as u8) + } + } else { + (&bs[..], bs[1].trailing_zeros() as u8) + }; + let v = asn1::BitString::new(bits, unused_bits).unwrap(); + Ok(asn1::write_single(&v)?) +} + +fn encode_certificate_policies( + py: pyo3::Python<'_>, + ext: &pyo3::PyAny, +) -> CryptographyResult> { + let mut policy_informations = vec![]; + for py_policy_info in ext.iter()? { + let py_policy_info = py_policy_info?; + let py_policy_qualifiers = + py_policy_info.getattr(pyo3::intern!(py, "policy_qualifiers"))?; + let qualifiers = if py_policy_qualifiers.is_true()? { + let mut qualifiers = vec![]; + for py_qualifier in py_policy_qualifiers.iter()? { + let py_qualifier = py_qualifier?; + let qualifier = if py_qualifier.is_instance_of::()? { + let cps_uri = match asn1::IA5String::new(py_qualifier.extract()?) { + Some(s) => s, + None => { + return Err(pyo3::exceptions::PyValueError::new_err( + "Qualifier must be an ASCII-string.", + ) + .into()) + } + }; + extensions::PolicyQualifierInfo { + policy_qualifier_id: (oid::CP_CPS_URI_OID).clone(), + qualifier: extensions::Qualifier::CpsUri(cps_uri), + } + } else { + let py_notice = py_qualifier.getattr(pyo3::intern!(py, "notice_reference"))?; + let notice_ref = if py_notice.is_true()? { + let mut notice_numbers = vec![]; + for py_num in py_notice + .getattr(pyo3::intern!(py, "notice_numbers"))? + .iter()? + { + let bytes = py_uint_to_big_endian_bytes(ext.py(), py_num?.downcast()?)?; + notice_numbers.push(asn1::BigUint::new(bytes).unwrap()); + } + + Some(extensions::NoticeReference { + organization: extensions::DisplayText::Utf8String( + asn1::Utf8String::new( + py_notice + .getattr(pyo3::intern!(py, "organization"))? + .extract()?, + ), + ), + notice_numbers: common::Asn1ReadableOrWritable::new_write( + asn1::SequenceOfWriter::new(notice_numbers), + ), + }) + } else { + None + }; + let py_explicit_text = + py_qualifier.getattr(pyo3::intern!(py, "explicit_text"))?; + let explicit_text = if py_explicit_text.is_true()? { + Some(extensions::DisplayText::Utf8String(asn1::Utf8String::new( + py_explicit_text.extract()?, + ))) + } else { + None + }; + + extensions::PolicyQualifierInfo { + policy_qualifier_id: (oid::CP_USER_NOTICE_OID).clone(), + qualifier: extensions::Qualifier::UserNotice(extensions::UserNotice { + notice_ref, + explicit_text, + }), + } + }; + qualifiers.push(qualifier); + } + Some(common::Asn1ReadableOrWritable::new_write( + asn1::SequenceOfWriter::new(qualifiers), + )) + } else { + None + }; + let py_policy_id = py_policy_info.getattr(pyo3::intern!(py, "policy_identifier"))?; + policy_informations.push(extensions::PolicyInformation { + policy_identifier: py_oid_to_oid(py_policy_id)?, + policy_qualifiers: qualifiers, + }); + } + Ok(asn1::write_single(&asn1::SequenceOfWriter::new( + policy_informations, + ))?) +} + +fn encode_issuing_distribution_point( + py: pyo3::Python<'_>, + ext: &pyo3::PyAny, +) -> CryptographyResult> { + let only_some_reasons = if ext + .getattr(pyo3::intern!(py, "only_some_reasons"))? + .is_true()? + { + let py_reasons = ext.getattr(pyo3::intern!(py, "only_some_reasons"))?; + let reasons = certificate::encode_distribution_point_reasons(ext.py(), py_reasons)?; + Some(common::Asn1ReadableOrWritable::new_write(reasons)) + } else { + None + }; + let distribution_point = if ext.getattr(pyo3::intern!(py, "full_name"))?.is_true()? { + let py_full_name = ext.getattr(pyo3::intern!(py, "full_name"))?; + let gns = x509::common::encode_general_names(ext.py(), py_full_name)?; + Some(extensions::DistributionPointName::FullName( + common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), + )) + } else if ext.getattr(pyo3::intern!(py, "relative_name"))?.is_true()? { + let mut name_entries = vec![]; + for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? { + name_entries.push(x509::common::encode_name_entry(ext.py(), py_name_entry?)?); + } + Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( + common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), + )) + } else { + None + }; + + let idp = crl::IssuingDistributionPoint { + distribution_point, + indirect_crl: ext.getattr(pyo3::intern!(py, "indirect_crl"))?.extract()?, + only_contains_attribute_certs: ext + .getattr(pyo3::intern!(py, "only_contains_attribute_certs"))? + .extract()?, + only_contains_ca_certs: ext + .getattr(pyo3::intern!(py, "only_contains_ca_certs"))? + .extract()?, + only_contains_user_certs: ext + .getattr(pyo3::intern!(py, "only_contains_user_certs"))? + .extract()?, + only_some_reasons, + }; + Ok(asn1::write_single(&idp)?) +} + pub(crate) fn encode_extension( py: pyo3::Python<'_>, oid: &asn1::ObjectIdentifier, @@ -125,17 +345,8 @@ pub(crate) fn encode_extension( ) -> CryptographyResult>> { match oid { &oid::BASIC_CONSTRAINTS_OID => { - #[derive(pyo3::prelude::FromPyObject)] - struct PyBasicConstraints { - ca: bool, - path_length: Option, - } - let pybc = ext.extract::()?; - let bc = extensions::BasicConstraints { - ca: pybc.ca, - path_length: pybc.path_length, - }; - Ok(Some(asn1::write_single(&bc)?)) + let der = encode_basic_constraints(ext)?; + Ok(Some(der)) } &oid::SUBJECT_KEY_IDENTIFIER_OID => { let digest = ext @@ -144,69 +355,8 @@ pub(crate) fn encode_extension( Ok(Some(asn1::write_single(&digest)?)) } &oid::KEY_USAGE_OID => { - let mut bs = [0, 0]; - certificate::set_bit( - &mut bs, - 0, - ext.getattr(pyo3::intern!(py, "digital_signature"))? - .is_true()?, - ); - certificate::set_bit( - &mut bs, - 1, - ext.getattr(pyo3::intern!(py, "content_commitment"))? - .is_true()?, - ); - certificate::set_bit( - &mut bs, - 2, - ext.getattr(pyo3::intern!(py, "key_encipherment"))? - .is_true()?, - ); - certificate::set_bit( - &mut bs, - 3, - ext.getattr(pyo3::intern!(py, "data_encipherment"))? - .is_true()?, - ); - certificate::set_bit( - &mut bs, - 4, - ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()?, - ); - certificate::set_bit( - &mut bs, - 5, - ext.getattr(pyo3::intern!(py, "key_cert_sign"))?.is_true()?, - ); - certificate::set_bit( - &mut bs, - 6, - ext.getattr(pyo3::intern!(py, "crl_sign"))?.is_true()?, - ); - if ext.getattr(pyo3::intern!(py, "key_agreement"))?.is_true()? { - certificate::set_bit( - &mut bs, - 7, - ext.getattr(pyo3::intern!(py, "encipher_only"))?.is_true()?, - ); - certificate::set_bit( - &mut bs, - 8, - ext.getattr(pyo3::intern!(py, "decipher_only"))?.is_true()?, - ); - } - let (bits, unused_bits) = if bs[1] == 0 { - if bs[0] == 0 { - (&[][..], 0) - } else { - (&bs[..1], bs[0].trailing_zeros() as u8) - } - } else { - (&bs[..], bs[1].trailing_zeros() as u8) - }; - let v = asn1::BitString::new(bits, unused_bits).unwrap(); - Ok(Some(asn1::write_single(&v)?)) + let der = encode_key_usage(py, ext)?; + Ok(Some(der)) } &oid::AUTHORITY_INFORMATION_ACCESS_OID | &oid::SUBJECT_INFORMATION_ACCESS_OID => { let ads = x509::common::encode_access_descriptions(ext.py(), ext)?; @@ -223,96 +373,8 @@ pub(crate) fn encode_extension( ))?)) } &oid::CERTIFICATE_POLICIES_OID => { - let mut policy_informations = vec![]; - for py_policy_info in ext.iter()? { - let py_policy_info = py_policy_info?; - let py_policy_qualifiers = - py_policy_info.getattr(pyo3::intern!(py, "policy_qualifiers"))?; - let qualifiers = if py_policy_qualifiers.is_true()? { - let mut qualifiers = vec![]; - for py_qualifier in py_policy_qualifiers.iter()? { - let py_qualifier = py_qualifier?; - let qualifier = if py_qualifier.is_instance_of::()? { - let cps_uri = match asn1::IA5String::new(py_qualifier.extract()?) { - Some(s) => s, - None => { - return Err(pyo3::exceptions::PyValueError::new_err( - "Qualifier must be an ASCII-string.", - ) - .into()) - } - }; - extensions::PolicyQualifierInfo { - policy_qualifier_id: (oid::CP_CPS_URI_OID).clone(), - qualifier: extensions::Qualifier::CpsUri(cps_uri), - } - } else { - let py_notice = - py_qualifier.getattr(pyo3::intern!(py, "notice_reference"))?; - let notice_ref = if py_notice.is_true()? { - let mut notice_numbers = vec![]; - for py_num in py_notice - .getattr(pyo3::intern!(py, "notice_numbers"))? - .iter()? - { - let bytes = - py_uint_to_big_endian_bytes(ext.py(), py_num?.downcast()?)?; - notice_numbers.push(asn1::BigUint::new(bytes).unwrap()); - } - - Some(extensions::NoticeReference { - organization: extensions::DisplayText::Utf8String( - asn1::Utf8String::new( - py_notice - .getattr(pyo3::intern!(py, "organization"))? - .extract()?, - ), - ), - notice_numbers: common::Asn1ReadableOrWritable::new_write( - asn1::SequenceOfWriter::new(notice_numbers), - ), - }) - } else { - None - }; - let py_explicit_text = - py_qualifier.getattr(pyo3::intern!(py, "explicit_text"))?; - let explicit_text = if py_explicit_text.is_true()? { - Some(extensions::DisplayText::Utf8String(asn1::Utf8String::new( - py_explicit_text.extract()?, - ))) - } else { - None - }; - - extensions::PolicyQualifierInfo { - policy_qualifier_id: (oid::CP_USER_NOTICE_OID).clone(), - qualifier: extensions::Qualifier::UserNotice( - extensions::UserNotice { - notice_ref, - explicit_text, - }, - ), - } - }; - qualifiers.push(qualifier); - } - Some(common::Asn1ReadableOrWritable::new_write( - asn1::SequenceOfWriter::new(qualifiers), - )) - } else { - None - }; - let py_policy_id = - py_policy_info.getattr(pyo3::intern!(py, "policy_identifier"))?; - policy_informations.push(extensions::PolicyInformation { - policy_identifier: py_oid_to_oid(py_policy_id)?, - policy_qualifiers: qualifiers, - }); - } - Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new( - policy_informations, - ))?)) + let der = encode_certificate_policies(py, ext)?; + Ok(Some(der)) } &oid::POLICY_CONSTRAINTS_OID => { let pc = extensions::PolicyConstraints { @@ -416,49 +478,8 @@ pub(crate) fn encode_extension( )?)) } &oid::ISSUING_DISTRIBUTION_POINT_OID => { - let only_some_reasons = if ext - .getattr(pyo3::intern!(py, "only_some_reasons"))? - .is_true()? - { - let py_reasons = ext.getattr(pyo3::intern!(py, "only_some_reasons"))?; - let reasons = certificate::encode_distribution_point_reasons(ext.py(), py_reasons)?; - Some(common::Asn1ReadableOrWritable::new_write(reasons)) - } else { - None - }; - let distribution_point = if ext.getattr(pyo3::intern!(py, "full_name"))?.is_true()? { - let py_full_name = ext.getattr(pyo3::intern!(py, "full_name"))?; - let gns = x509::common::encode_general_names(ext.py(), py_full_name)?; - Some(extensions::DistributionPointName::FullName( - common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new(gns)), - )) - } else if ext.getattr(pyo3::intern!(py, "relative_name"))?.is_true()? { - let mut name_entries = vec![]; - for py_name_entry in ext.getattr(pyo3::intern!(py, "relative_name"))?.iter()? { - name_entries.push(x509::common::encode_name_entry(ext.py(), py_name_entry?)?); - } - Some(extensions::DistributionPointName::NameRelativeToCRLIssuer( - common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(name_entries)), - )) - } else { - None - }; - - let idp = crl::IssuingDistributionPoint { - distribution_point, - indirect_crl: ext.getattr(pyo3::intern!(py, "indirect_crl"))?.extract()?, - only_contains_attribute_certs: ext - .getattr(pyo3::intern!(py, "only_contains_attribute_certs"))? - .extract()?, - only_contains_ca_certs: ext - .getattr(pyo3::intern!(py, "only_contains_ca_certs"))? - .extract()?, - only_contains_user_certs: ext - .getattr(pyo3::intern!(py, "only_contains_user_certs"))? - .extract()?, - only_some_reasons, - }; - Ok(Some(asn1::write_single(&idp)?)) + let der = encode_issuing_distribution_point(py, ext)?; + Ok(Some(der)) } &oid::NONCE_OID => { let nonce = ext From 9bea7fe5f01853746bbb0b1911430652e89bfe34 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 13:24:37 -0600 Subject: [PATCH 683/827] Factor out a few more extension encodings (#8814) --- src/rust/src/x509/common.rs | 10 +--- src/rust/src/x509/extensions.rs | 99 +++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index e81d52a0020c..571963e36b63 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -6,9 +6,7 @@ use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::{exceptions, x509}; use cryptography_x509::common::{Asn1ReadableOrWritable, AttributeTypeValue, RawTlv}; -use cryptography_x509::extensions::{ - AccessDescription, Extension, Extensions, SequenceOfAccessDescriptions, -}; +use cryptography_x509::extensions::{AccessDescription, Extension, Extensions}; use cryptography_x509::name::{GeneralName, Name, OtherName, UnvalidatedIA5String}; use pyo3::types::IntoPyDict; use pyo3::{IntoPy, ToPyObject}; @@ -159,7 +157,7 @@ pub(crate) fn encode_general_name<'a>( pub(crate) fn encode_access_descriptions<'a>( py: pyo3::Python<'a>, py_ads: &'a pyo3::PyAny, -) -> Result, CryptographyError> { +) -> CryptographyResult> { let mut ads = vec![]; for py_ad in py_ads.iter()? { let py_ad = py_ad?; @@ -171,9 +169,7 @@ pub(crate) fn encode_access_descriptions<'a>( access_location, }); } - Ok(Asn1ReadableOrWritable::new_write( - asn1::SequenceOfWriter::new(ads), - )) + Ok(asn1::write_single(&asn1::SequenceOfWriter::new(ads))?) } pub(crate) fn parse_name<'p>( diff --git a/src/rust/src/x509/extensions.rs b/src/rust/src/x509/extensions.rs index e12c320a0c47..98d1bd63b910 100644 --- a/src/rust/src/x509/extensions.rs +++ b/src/rust/src/x509/extensions.rs @@ -33,7 +33,7 @@ fn encode_general_subtrees<'a>( pub(crate) fn encode_authority_key_identifier<'a>( py: pyo3::Python<'a>, py_aki: &'a pyo3::PyAny, -) -> pyo3::PyResult> { +) -> CryptographyResult> { #[derive(pyo3::prelude::FromPyObject)] struct PyAuthorityKeyIdentifier<'a> { key_identifier: Option<&'a [u8]>, @@ -56,17 +56,17 @@ pub(crate) fn encode_authority_key_identifier<'a>( } else { None }; - Ok(extensions::AuthorityKeyIdentifier { + Ok(asn1::write_single(&extensions::AuthorityKeyIdentifier { authority_cert_issuer, authority_cert_serial_number, key_identifier: aki.key_identifier, - }) + })?) } pub(crate) fn encode_distribution_points<'p>( py: pyo3::Python<'p>, py_dps: &'p pyo3::PyAny, -) -> pyo3::PyResult>> { +) -> CryptographyResult> { #[derive(pyo3::prelude::FromPyObject)] struct PyDistributionPoint<'a> { crl_issuer: Option<&'a pyo3::PyAny>, @@ -115,7 +115,7 @@ pub(crate) fn encode_distribution_points<'p>( reasons, }); } - Ok(dps) + Ok(asn1::write_single(&asn1::SequenceOfWriter::new(dps))?) } fn encode_basic_constraints(ext: &pyo3::PyAny) -> CryptographyResult> { @@ -338,6 +338,45 @@ fn encode_issuing_distribution_point( Ok(asn1::write_single(&idp)?) } +fn encode_oid_sequence(ext: &pyo3::PyAny) -> CryptographyResult> { + let mut oids = vec![]; + for el in ext.iter()? { + let oid = py_oid_to_oid(el?)?; + oids.push(oid); + } + Ok(asn1::write_single(&asn1::SequenceOfWriter::new(oids))?) +} + +fn encode_tls_features(py: pyo3::Python<'_>, ext: &pyo3::PyAny) -> CryptographyResult> { + // Ideally we'd skip building up a vec and just write directly into the + // writer. This isn't possible at the moment because the callback to write + // an asn1::Sequence can't return an error, and we need to handle errors + // from Python. + let mut els = vec![]; + for el in ext.iter()? { + els.push(el?.getattr(pyo3::intern!(py, "value"))?.extract::()?); + } + + Ok(asn1::write_single(&asn1::SequenceOfWriter::new(els))?) +} + +fn encode_scts(ext: &pyo3::PyAny) -> CryptographyResult> { + let mut length = 0; + for sct in ext.iter()? { + let sct = sct?.downcast::>()?; + length += sct.borrow().sct_data.len() + 2; + } + + let mut result = vec![]; + result.extend_from_slice(&(length as u16).to_be_bytes()); + for sct in ext.iter()? { + let sct = sct?.downcast::>()?; + result.extend_from_slice(&(sct.borrow().sct_data.len() as u16).to_be_bytes()); + result.extend_from_slice(&sct.borrow().sct_data); + } + Ok(asn1::write_single(&result.as_slice())?) +} + pub(crate) fn encode_extension( py: pyo3::Python<'_>, oid: &asn1::ObjectIdentifier, @@ -359,18 +398,12 @@ pub(crate) fn encode_extension( Ok(Some(der)) } &oid::AUTHORITY_INFORMATION_ACCESS_OID | &oid::SUBJECT_INFORMATION_ACCESS_OID => { - let ads = x509::common::encode_access_descriptions(ext.py(), ext)?; - Ok(Some(asn1::write_single(&ads)?)) + let der = x509::common::encode_access_descriptions(ext.py(), ext)?; + Ok(Some(der)) } &oid::EXTENDED_KEY_USAGE_OID | &oid::ACCEPTABLE_RESPONSES_OID => { - let mut oids = vec![]; - for el in ext.iter()? { - let oid = py_oid_to_oid(el?)?; - oids.push(oid); - } - Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new( - oids, - ))?)) + let der = encode_oid_sequence(ext)?; + Ok(Some(der)) } &oid::CERTIFICATE_POLICIES_OID => { let der = encode_certificate_policies(py, ext)?; @@ -410,43 +443,23 @@ pub(crate) fn encode_extension( Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?)) } &oid::AUTHORITY_KEY_IDENTIFIER_OID => { - let aki = encode_authority_key_identifier(ext.py(), ext)?; - Ok(Some(asn1::write_single(&aki)?)) + let der = encode_authority_key_identifier(ext.py(), ext)?; + Ok(Some(der)) } &oid::FRESHEST_CRL_OID | &oid::CRL_DISTRIBUTION_POINTS_OID => { - let dps = encode_distribution_points(ext.py(), ext)?; - Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(dps))?)) + let der = encode_distribution_points(ext.py(), ext)?; + Ok(Some(der)) } &oid::OCSP_NO_CHECK_OID => Ok(Some(asn1::write_single(&())?)), &oid::TLS_FEATURE_OID => { - // Ideally we'd skip building up a vec and just write directly into the - // writer. This isn't possible at the moment because the callback to write - // an asn1::Sequence can't return an error, and we need to handle errors - // from Python. - let mut els = vec![]; - for el in ext.iter()? { - els.push(el?.getattr(pyo3::intern!(py, "value"))?.extract::()?); - } - - Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(els))?)) + let der = encode_tls_features(py, ext)?; + Ok(Some(der)) } &oid::PRECERT_POISON_OID => Ok(Some(asn1::write_single(&())?)), &oid::PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID | &oid::SIGNED_CERTIFICATE_TIMESTAMPS_OID => { - let mut length = 0; - for sct in ext.iter()? { - let sct = sct?.downcast::>()?; - length += sct.borrow().sct_data.len() + 2; - } - - let mut result = vec![]; - result.extend_from_slice(&(length as u16).to_be_bytes()); - for sct in ext.iter()? { - let sct = sct?.downcast::>()?; - result.extend_from_slice(&(sct.borrow().sct_data.len() as u16).to_be_bytes()); - result.extend_from_slice(&sct.borrow().sct_data); - } - Ok(Some(asn1::write_single(&result.as_slice())?)) + let der = encode_scts(ext)?; + Ok(Some(der)) } &oid::CRL_REASON_OID => { let value = ext From 6bb5578f352a290f3222ece8533e713f5e786193 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 23:22:45 +0000 Subject: [PATCH 684/827] Bump openssl-sys from 0.9.86 to 0.9.87 in /src/rust (#8817) Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.86 to 0.9.87. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.86...openssl-sys-v0.9.87) --- updated-dependencies: - dependency-name: openssl-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- src/rust/cryptography-cffi/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index e00d244cd4bb..88d95551d302 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.86" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992bac49bdbab4423199c654a5515bd2a6c6a23bf03f2dd3bdb7e5ae6259bc69" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index dae85cef1d25..abbff3324a8a 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -17,7 +17,7 @@ cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" openssl = "0.10.51" -openssl-sys = "0.9.85" +openssl-sys = "0.9.87" foreign-types-shared = "0.1" [build-dependencies] diff --git a/src/rust/cryptography-cffi/Cargo.toml b/src/rust/cryptography-cffi/Cargo.toml index 0c5655b170cc..f9ae6bc2ed43 100644 --- a/src/rust/cryptography-cffi/Cargo.toml +++ b/src/rust/cryptography-cffi/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56.0" [dependencies] pyo3 = { version = "0.18" } -openssl-sys = "0.9.85" +openssl-sys = "0.9.87" [build-dependencies] cc = "1.0.72" From 001345861e422fd3df51362502f66469651ab1e3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 17:28:28 -0600 Subject: [PATCH 685/827] Switch to using python -m build in wheel-builder (#8816) --- .github/workflows/wheel-builder.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 9306ce7415e7..90e29c960d92 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -35,11 +35,11 @@ jobs: - run: python -m venv .venv - name: Install Python dependencies - run: .venv/bin/pip install -U pip wheel cffi setuptools-rust + run: .venv/bin/pip install -U pip build - name: Make sdist (cryptography) - run: .venv/bin/python setup.py sdist + run: .venv/bin/python -m build --sdist - name: Make sdist and wheel (vectors) - run: cd vectors/ && ../.venv/bin/python setup.py sdist bdist_wheel + run: cd vectors/ && ../.venv/bin/python -m build - uses: actions/upload-artifact@v3.1.2 with: name: "cryptography-sdist" From c315920795d98b29d79cf7de728d383c984580f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 23:37:48 +0000 Subject: [PATCH 686/827] Bump target-lexicon from 0.12.6 to 0.12.7 in /src/rust (#8818) Bumps [target-lexicon](https://github.com/bytecodealliance/target-lexicon) from 0.12.6 to 0.12.7. - [Release notes](https://github.com/bytecodealliance/target-lexicon/releases) - [Commits](https://github.com/bytecodealliance/target-lexicon/compare/v0.12.6...v0.12.7) --- updated-dependencies: - dependency-name: target-lexicon dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 88d95551d302..bcf5884f0e34 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -406,9 +406,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.6" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "unicode-ident" From 9108d82a284a2996aa1fcbc2f318bf657c53049c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 23:49:00 +0000 Subject: [PATCH 687/827] Bump openssl from 0.10.51 to 0.10.52 in /src/rust (#8819) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.51 to 0.10.52. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.51...openssl-v0.10.52) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- src/rust/cryptography-openssl/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index bcf5884f0e34..e63a2e1ef0bf 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -162,9 +162,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.51" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ea2d98598bf9ada7ea6ee8a30fb74f9156b63bbe495d64ec2b87c269d2dda3" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index abbff3324a8a..bb8f74a849b0 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -16,7 +16,7 @@ cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" -openssl = "0.10.51" +openssl = "0.10.52" openssl-sys = "0.9.87" foreign-types-shared = "0.1" diff --git a/src/rust/cryptography-openssl/Cargo.toml b/src/rust/cryptography-openssl/Cargo.toml index 31927129e234..bd153edc40d5 100644 --- a/src/rust/cryptography-openssl/Cargo.toml +++ b/src/rust/cryptography-openssl/Cargo.toml @@ -8,7 +8,7 @@ publish = false rust-version = "1.56.0" [dependencies] -openssl = "0.10.51" +openssl = "0.10.52" ffi = { package = "openssl-sys", version = "0.9.85" } foreign-types = "0.3" foreign-types-shared = "0.1" From 392835b8a42d1555a04aa02408b3cdbd045f75d8 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 02:08:49 +0000 Subject: [PATCH 688/827] Bump BoringSSL and/or OpenSSL in CI (#8821) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ae0092ef535..f37af412e70e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 22, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b0b1f9dfc583c96d5f91b7f8cdb7efabcf22793b"}} - # Latest commit on the OpenSSL master branch, as of Apr 22, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c04e78f0c69201226430fed14c291c281da47f2d"}} + # Latest commit on the BoringSSL master branch, as of Apr 25, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "de2d610a341f5a4b8c222425890537cb84c91400"}} + # Latest commit on the OpenSSL master branch, as of Apr 25, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "24a322544373f7acda05e19f64a6c3120d459d5b"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 9d70b87ff5371078ba53c01e27673fa9f0298f21 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 20:10:54 -0600 Subject: [PATCH 689/827] Don't use setup.py in doc tests (#8820) --- ci-constraints-requirements.txt | 6 ++++-- noxfile.py | 2 +- pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index c57e536353f7..2a38918e676d 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -1,7 +1,7 @@ # 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 --resolver=backtracking --strip-extras --unsafe-package=cffi --unsafe-package=pycparser --unsafe-package=setuptools pyproject.toml +# 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 @@ -16,7 +16,9 @@ black==23.3.0 bleach==6.0.0 # via readme-renderer build==0.10.0 - # via check-manifest + # via + # check-manifest + # cryptography (pyproject.toml) certifi==2022.12.7 # via requests charset-normalizer==3.1.0 diff --git a/noxfile.py b/noxfile.py index b60d6a602e63..8f1b94a500fb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -106,7 +106,7 @@ def docs(session: nox.Session) -> None: # This is in the docs job because `twine check` verifies that the README # is valid reStructuredText. - session.run("python", "setup.py", "sdist") + session.run("python", "-m", "build", "--sdist") session.run("twine", "check", "dist/*") diff --git a/pyproject.toml b/pyproject.toml index 8cf73cc44922..c66e0a38da40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ test = [ test-randomorder = ["pytest-randomly"] docs = ["sphinx >=5.3.0", "sphinx-rtd-theme >=1.1.1"] docstest = ["pyenchant >=1.6.11", "twine >=1.12.0", "sphinxcontrib-spelling >=4.0.1"] -sdist = ["setuptools_rust >=0.11.4"] +sdist = ["build"] pep8test = ["black", "ruff", "mypy", "check-manifest"] [tool.black] From b5c25a91dac63fba15335eb8c72c444b70ffeeac Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 21:22:11 -0600 Subject: [PATCH 690/827] Migrate DH to Rust (#8768) --- .../hazmat/backends/openssl/backend.py | 176 +------ .../hazmat/backends/openssl/dh.py | 331 ------------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../hazmat/bindings/_rust/openssl/dh.pyi | 22 + .../hazmat/primitives/asymmetric/dh.py | 11 +- src/rust/src/backend/dh.rs | 443 ++++++++++++++++++ src/rust/src/backend/mod.rs | 4 +- src/rust/src/backend/utils.rs | 49 +- tests/hazmat/backends/test_openssl.py | 33 +- tests/hazmat/primitives/test_dh.py | 5 +- tests/hazmat/primitives/test_ed25519.py | 11 +- tests/hazmat/primitives/test_ed448.py | 11 +- tests/hazmat/primitives/test_serialization.py | 8 + tests/hazmat/primitives/test_x25519.py | 11 +- tests/hazmat/primitives/test_x448.py | 11 +- 15 files changed, 585 insertions(+), 543 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/dh.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/dh.pyi create mode 100644 src/rust/src/backend/dh.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 04b25f471a76..c8e1b81a218c 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -15,12 +15,6 @@ from cryptography.hazmat.backends.openssl import aead from cryptography.hazmat.backends.openssl.ciphers import _CipherContext from cryptography.hazmat.backends.openssl.cmac import _CMACContext -from cryptography.hazmat.backends.openssl.dh import ( - _dh_params_dup, - _DHParameters, - _DHPrivateKey, - _DHPublicKey, -) from cryptography.hazmat.backends.openssl.dsa import ( _DSAParameters, _DSAPrivateKey, @@ -609,10 +603,9 @@ def _evp_pkey_to_private_key( ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) elif key_type in self._dh_types: - dh_cdata = self._lib.EVP_PKEY_get1_DH(evp_pkey) - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - return _DHPrivateKey(self, dh_cdata, evp_pkey) + return rust_openssl.dh.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL return rust_openssl.ed25519.private_key_from_ptr( @@ -674,10 +667,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) elif key_type in self._dh_types: - dh_cdata = self._lib.EVP_PKEY_get1_DH(evp_pkey) - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - return _DHPublicKey(self, dh_cdata, evp_pkey) + return rust_openssl.dh.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL return rust_openssl.ed25519.public_key_from_ptr( @@ -925,16 +917,7 @@ def load_pem_public_key(self, data: bytes) -> PublicKeyTypes: self._handle_key_loading_error() def load_pem_parameters(self, data: bytes) -> dh.DHParameters: - mem_bio = self._bytes_to_bio(data) - # only DH is supported currently - dh_cdata = self._lib.PEM_read_bio_DHparams( - mem_bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL - ) - if dh_cdata != self._ffi.NULL: - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - return _DHParameters(self, dh_cdata) - else: - self._handle_key_loading_error() + return rust_openssl.dh.from_pem_parameters(data) def load_der_private_key( self, @@ -1000,22 +983,7 @@ def load_der_public_key(self, data: bytes) -> PublicKeyTypes: self._handle_key_loading_error() def load_der_parameters(self, data: bytes) -> dh.DHParameters: - mem_bio = self._bytes_to_bio(data) - dh_cdata = self._lib.d2i_DHparams_bio(mem_bio.bio, self._ffi.NULL) - if dh_cdata != self._ffi.NULL: - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - return _DHParameters(self, dh_cdata) - elif self._lib.Cryptography_HAS_EVP_PKEY_DHX: - # We check to see if the is dhx. - self._consume_errors() - res = self._lib.BIO_reset(mem_bio.bio) - self.openssl_assert(res == 1) - dh_cdata = self._lib.d2i_DHxparams_bio(mem_bio.bio, self._ffi.NULL) - if dh_cdata != self._ffi.NULL: - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - return _DHParameters(self, dh_cdata) - - self._handle_key_loading_error() + return rust_openssl.dh.from_der_parameters(data) def _cert2ossl(self, cert: x509.Certificate) -> typing.Any: data = cert.public_bytes(serialization.Encoding.DER) @@ -1611,48 +1579,12 @@ def dh_supported(self) -> bool: def generate_dh_parameters( self, generator: int, key_size: int ) -> dh.DHParameters: - if key_size < dh._MIN_MODULUS_SIZE: - raise ValueError( - "DH key_size must be at least {} bits".format( - dh._MIN_MODULUS_SIZE - ) - ) - - if generator not in (2, 5): - raise ValueError("DH generator must be 2 or 5") - - dh_param_cdata = self._lib.DH_new() - self.openssl_assert(dh_param_cdata != self._ffi.NULL) - dh_param_cdata = self._ffi.gc(dh_param_cdata, self._lib.DH_free) - - res = self._lib.DH_generate_parameters_ex( - dh_param_cdata, key_size, generator, self._ffi.NULL - ) - if res != 1: - errors = self._consume_errors() - raise ValueError("Unable to generate DH parameters", errors) - - return _DHParameters(self, dh_param_cdata) - - def _dh_cdata_to_evp_pkey(self, dh_cdata): - evp_pkey = self._create_evp_pkey_gc() - res = self._lib.EVP_PKEY_set1_DH(evp_pkey, dh_cdata) - self.openssl_assert(res == 1) - return evp_pkey + return rust_openssl.dh.generate_parameters(generator, key_size) def generate_dh_private_key( self, parameters: dh.DHParameters ) -> dh.DHPrivateKey: - dh_key_cdata = _dh_params_dup( - parameters._dh_cdata, self # type: ignore[attr-defined] - ) - - res = self._lib.DH_generate_key(dh_key_cdata) - self.openssl_assert(res == 1) - - evp_pkey = self._dh_cdata_to_evp_pkey(dh_key_cdata) - - return _DHPrivateKey(self, dh_key_cdata, evp_pkey) + return parameters.generate_private_key() def generate_dh_private_key_and_parameters( self, generator: int, key_size: int @@ -1664,99 +1596,17 @@ def generate_dh_private_key_and_parameters( def load_dh_private_numbers( self, numbers: dh.DHPrivateNumbers ) -> dh.DHPrivateKey: - parameter_numbers = numbers.public_numbers.parameter_numbers - - dh_cdata = self._lib.DH_new() - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - - p = self._int_to_bn(parameter_numbers.p) - g = self._int_to_bn(parameter_numbers.g) - - if parameter_numbers.q is not None: - q = self._int_to_bn(parameter_numbers.q) - else: - q = self._ffi.NULL - - pub_key = self._int_to_bn(numbers.public_numbers.y) - priv_key = self._int_to_bn(numbers.x) - - res = self._lib.DH_set0_pqg(dh_cdata, p, q, g) - self.openssl_assert(res == 1) - - res = self._lib.DH_set0_key(dh_cdata, pub_key, priv_key) - self.openssl_assert(res == 1) - - codes = self._ffi.new("int[]", 1) - res = self._lib.DH_check(dh_cdata, codes) - self.openssl_assert(res == 1) - - # DH_check will return DH_NOT_SUITABLE_GENERATOR if p % 24 does not - # equal 11 when the generator is 2 (a quadratic nonresidue). - # We want to ignore that error because p % 24 == 23 is also fine. - # Specifically, g is then a quadratic residue. Within the context of - # Diffie-Hellman this means it can only generate half the possible - # values. That sounds bad, but quadratic nonresidues leak a bit of - # the key to the attacker in exchange for having the full key space - # available. See: https://crypto.stackexchange.com/questions/12961 - if codes[0] != 0 and not ( - parameter_numbers.g == 2 - and codes[0] ^ self._lib.DH_NOT_SUITABLE_GENERATOR == 0 - ): - raise ValueError("DH private numbers did not pass safety checks.") - - evp_pkey = self._dh_cdata_to_evp_pkey(dh_cdata) - - return _DHPrivateKey(self, dh_cdata, evp_pkey) + return rust_openssl.dh.from_private_numbers(numbers) def load_dh_public_numbers( self, numbers: dh.DHPublicNumbers ) -> dh.DHPublicKey: - dh_cdata = self._lib.DH_new() - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - - parameter_numbers = numbers.parameter_numbers - - p = self._int_to_bn(parameter_numbers.p) - g = self._int_to_bn(parameter_numbers.g) - - if parameter_numbers.q is not None: - q = self._int_to_bn(parameter_numbers.q) - else: - q = self._ffi.NULL - - pub_key = self._int_to_bn(numbers.y) - - res = self._lib.DH_set0_pqg(dh_cdata, p, q, g) - self.openssl_assert(res == 1) - - res = self._lib.DH_set0_key(dh_cdata, pub_key, self._ffi.NULL) - self.openssl_assert(res == 1) - - evp_pkey = self._dh_cdata_to_evp_pkey(dh_cdata) - - return _DHPublicKey(self, dh_cdata, evp_pkey) + return rust_openssl.dh.from_public_numbers(numbers) def load_dh_parameter_numbers( self, numbers: dh.DHParameterNumbers ) -> dh.DHParameters: - dh_cdata = self._lib.DH_new() - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - - p = self._int_to_bn(numbers.p) - g = self._int_to_bn(numbers.g) - - if numbers.q is not None: - q = self._int_to_bn(numbers.q) - else: - q = self._ffi.NULL - - res = self._lib.DH_set0_pqg(dh_cdata, p, q, g) - self.openssl_assert(res == 1) - - return _DHParameters(self, dh_cdata) + return rust_openssl.dh.from_parameter_numbers(numbers) def dh_parameters_supported( self, p: int, g: int, q: typing.Optional[int] = None diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py deleted file mode 100644 index 42a92bcc1cd6..000000000000 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ /dev/null @@ -1,331 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import dh - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -def _dh_params_dup(dh_cdata, backend: Backend): - lib = backend._lib - ffi = backend._ffi - - param_cdata = lib.DHparams_dup(dh_cdata) - backend.openssl_assert(param_cdata != ffi.NULL) - param_cdata = ffi.gc(param_cdata, lib.DH_free) - if lib.CRYPTOGRAPHY_IS_LIBRESSL: - # In libressl DHparams_dup don't copy q - q = ffi.new("BIGNUM **") - lib.DH_get0_pqg(dh_cdata, ffi.NULL, q, ffi.NULL) - q_dup = lib.BN_dup(q[0]) - res = lib.DH_set0_pqg(param_cdata, ffi.NULL, q_dup, ffi.NULL) - backend.openssl_assert(res == 1) - - return param_cdata - - -def _dh_cdata_to_parameters(dh_cdata, backend: Backend) -> _DHParameters: - param_cdata = _dh_params_dup(dh_cdata, backend) - return _DHParameters(backend, param_cdata) - - -class _DHParameters(dh.DHParameters): - def __init__(self, backend: Backend, dh_cdata): - self._backend = backend - self._dh_cdata = dh_cdata - - def parameter_numbers(self) -> dh.DHParameterNumbers: - p = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg(self._dh_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - q_val: typing.Optional[int] - if q[0] == self._backend._ffi.NULL: - q_val = None - else: - q_val = self._backend._bn_to_int(q[0]) - return dh.DHParameterNumbers( - p=self._backend._bn_to_int(p[0]), - g=self._backend._bn_to_int(g[0]), - q=q_val, - ) - - def generate_private_key(self) -> dh.DHPrivateKey: - return self._backend.generate_dh_private_key(self) - - def parameter_bytes( - self, - encoding: serialization.Encoding, - format: serialization.ParameterFormat, - ) -> bytes: - if encoding is serialization.Encoding.OpenSSH: - raise TypeError("OpenSSH encoding is not supported") - - if format is not serialization.ParameterFormat.PKCS3: - raise ValueError("Only PKCS3 serialization is supported") - - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg( - self._dh_cdata, self._backend._ffi.NULL, q, self._backend._ffi.NULL - ) - if ( - q[0] != self._backend._ffi.NULL - and not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX - ): - raise UnsupportedAlgorithm( - "DH X9.42 serialization is not supported", - _Reasons.UNSUPPORTED_SERIALIZATION, - ) - - if encoding is serialization.Encoding.PEM: - if q[0] != self._backend._ffi.NULL: - write_bio = self._backend._lib.PEM_write_bio_DHxparams - else: - write_bio = self._backend._lib.PEM_write_bio_DHparams - elif encoding is serialization.Encoding.DER: - if q[0] != self._backend._ffi.NULL: - write_bio = self._backend._lib.i2d_DHxparams_bio - else: - write_bio = self._backend._lib.i2d_DHparams_bio - else: - raise TypeError("encoding must be an item from the Encoding enum") - - bio = self._backend._create_mem_bio_gc() - res = write_bio(bio, self._dh_cdata) - self._backend.openssl_assert(res == 1) - return self._backend._read_mem_bio(bio) - - -def _get_dh_num_bits(backend, dh_cdata) -> int: - p = backend._ffi.new("BIGNUM **") - backend._lib.DH_get0_pqg(dh_cdata, p, backend._ffi.NULL, backend._ffi.NULL) - backend.openssl_assert(p[0] != backend._ffi.NULL) - return backend._lib.BN_num_bits(p[0]) - - -class _DHPrivateKey(dh.DHPrivateKey): - def __init__(self, backend: Backend, dh_cdata, evp_pkey): - self._backend = backend - self._dh_cdata = dh_cdata - self._evp_pkey = evp_pkey - self._key_size_bytes = self._backend._lib.DH_size(dh_cdata) - - @property - def key_size(self) -> int: - return _get_dh_num_bits(self._backend, self._dh_cdata) - - def private_numbers(self) -> dh.DHPrivateNumbers: - p = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg(self._dh_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - if q[0] == self._backend._ffi.NULL: - q_val = None - else: - q_val = self._backend._bn_to_int(q[0]) - pub_key = self._backend._ffi.new("BIGNUM **") - priv_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_key(self._dh_cdata, pub_key, priv_key) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(priv_key[0] != self._backend._ffi.NULL) - return dh.DHPrivateNumbers( - public_numbers=dh.DHPublicNumbers( - parameter_numbers=dh.DHParameterNumbers( - p=self._backend._bn_to_int(p[0]), - g=self._backend._bn_to_int(g[0]), - q=q_val, - ), - y=self._backend._bn_to_int(pub_key[0]), - ), - x=self._backend._bn_to_int(priv_key[0]), - ) - - def exchange(self, peer_public_key: dh.DHPublicKey) -> bytes: - if not isinstance(peer_public_key, _DHPublicKey): - raise TypeError("peer_public_key must be a DHPublicKey") - - ctx = self._backend._lib.EVP_PKEY_CTX_new( - self._evp_pkey, self._backend._ffi.NULL - ) - self._backend.openssl_assert(ctx != self._backend._ffi.NULL) - ctx = self._backend._ffi.gc(ctx, self._backend._lib.EVP_PKEY_CTX_free) - res = self._backend._lib.EVP_PKEY_derive_init(ctx) - self._backend.openssl_assert(res == 1) - res = self._backend._lib.EVP_PKEY_derive_set_peer( - ctx, peer_public_key._evp_pkey - ) - # Invalid kex errors here in OpenSSL 3.0 because checks were moved - # to EVP_PKEY_derive_set_peer - self._exchange_assert(res == 1) - keylen = self._backend._ffi.new("size_t *") - res = self._backend._lib.EVP_PKEY_derive( - ctx, self._backend._ffi.NULL, keylen - ) - # Invalid kex errors here in OpenSSL < 3 - self._exchange_assert(res == 1) - self._backend.openssl_assert(keylen[0] > 0) - buf = self._backend._ffi.new("unsigned char[]", keylen[0]) - res = self._backend._lib.EVP_PKEY_derive(ctx, buf, keylen) - self._backend.openssl_assert(res == 1) - - key = self._backend._ffi.buffer(buf, keylen[0])[:] - pad = self._key_size_bytes - len(key) - - if pad > 0: - key = (b"\x00" * pad) + key - - return key - - def _exchange_assert(self, ok: bool) -> None: - if not ok: - errors = self._backend._consume_errors() - raise ValueError( - "Error computing shared key.", - errors, - ) - - def public_key(self) -> dh.DHPublicKey: - dh_cdata = _dh_params_dup(self._dh_cdata, self._backend) - pub_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_key( - self._dh_cdata, pub_key, self._backend._ffi.NULL - ) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - pub_key_dup = self._backend._lib.BN_dup(pub_key[0]) - self._backend.openssl_assert(pub_key_dup != self._backend._ffi.NULL) - - res = self._backend._lib.DH_set0_key( - dh_cdata, pub_key_dup, self._backend._ffi.NULL - ) - self._backend.openssl_assert(res == 1) - evp_pkey = self._backend._dh_cdata_to_evp_pkey(dh_cdata) - return _DHPublicKey(self._backend, dh_cdata, evp_pkey) - - def parameters(self) -> dh.DHParameters: - return _dh_cdata_to_parameters(self._dh_cdata, self._backend) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - if format is not serialization.PrivateFormat.PKCS8: - raise ValueError( - "DH private keys support only PKCS8 serialization" - ) - if not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX: - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg( - self._dh_cdata, - self._backend._ffi.NULL, - q, - self._backend._ffi.NULL, - ) - if q[0] != self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "DH X9.42 serialization is not supported", - _Reasons.UNSUPPORTED_SERIALIZATION, - ) - - return self._backend._private_key_bytes( - encoding, - format, - encryption_algorithm, - self, - self._evp_pkey, - self._dh_cdata, - ) - - -class _DHPublicKey(dh.DHPublicKey): - def __init__(self, backend: Backend, dh_cdata, evp_pkey): - self._backend = backend - self._dh_cdata = dh_cdata - self._evp_pkey = evp_pkey - self._key_size_bits = _get_dh_num_bits(self._backend, self._dh_cdata) - - @property - def key_size(self) -> int: - return self._key_size_bits - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _DHPublicKey): - return NotImplemented - - res = self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) - if res < 0: - # DH public keys have two types (DH, DHX) that OpenSSL - # considers different types but we do not. Mismatched types - # push an error on the stack, so we need to consume it. - self._backend._consume_errors() - return res == 1 - - def public_numbers(self) -> dh.DHPublicNumbers: - p = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg(self._dh_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - if q[0] == self._backend._ffi.NULL: - q_val = None - else: - q_val = self._backend._bn_to_int(q[0]) - pub_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_key( - self._dh_cdata, pub_key, self._backend._ffi.NULL - ) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - return dh.DHPublicNumbers( - parameter_numbers=dh.DHParameterNumbers( - p=self._backend._bn_to_int(p[0]), - g=self._backend._bn_to_int(g[0]), - q=q_val, - ), - y=self._backend._bn_to_int(pub_key[0]), - ) - - def parameters(self) -> dh.DHParameters: - return _dh_cdata_to_parameters(self._dh_cdata, self._backend) - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if format is not serialization.PublicFormat.SubjectPublicKeyInfo: - raise ValueError( - "DH public keys support only " - "SubjectPublicKeyInfo serialization" - ) - - if not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX: - q = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DH_get0_pqg( - self._dh_cdata, - self._backend._ffi.NULL, - q, - self._backend._ffi.NULL, - ) - if q[0] != self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "DH X9.42 serialization is not supported", - _Reasons.UNSUPPORTED_SERIALIZATION, - ) - - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 3e8d894cdb51..bfa641259854 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -5,6 +5,7 @@ import typing from cryptography.hazmat.bindings._rust.openssl import ( + dh, ed448, ed25519, hashes, @@ -16,6 +17,7 @@ from cryptography.hazmat.bindings._rust.openssl import ( __all__ = [ "openssl_version", "raise_openssl_error", + "dh", "hashes", "hmac", "ed448", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/dh.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/dh.pyi new file mode 100644 index 000000000000..bfd005d99fec --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/dh.pyi @@ -0,0 +1,22 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import dh + +MIN_MODULUS_SIZE: int + +class DHPrivateKey: ... +class DHPublicKey: ... +class DHParameters: ... + +def generate_parameters(generator: int, key_size: int) -> dh.DHParameters: ... +def private_key_from_ptr(ptr: int) -> dh.DHPrivateKey: ... +def public_key_from_ptr(ptr: int) -> dh.DHPublicKey: ... +def from_pem_parameters(data: bytes) -> dh.DHParameters: ... +def from_der_parameters(data: bytes) -> dh.DHParameters: ... +def from_private_numbers(numbers: dh.DHPrivateNumbers) -> dh.DHPrivateKey: ... +def from_public_numbers(numbers: dh.DHPublicNumbers) -> dh.DHPublicKey: ... +def from_parameter_numbers( + numbers: dh.DHParameterNumbers, +) -> dh.DHParameters: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index 02feb5f2ed4c..751bcc402e94 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -7,10 +7,9 @@ import abc import typing +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization -_MIN_MODULUS_SIZE = 512 - def generate_parameters( generator: int, key_size: int, backend: typing.Any = None @@ -30,9 +29,10 @@ def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: if g < 2: raise ValueError("DH generator must be 2 or greater") - if p.bit_length() < _MIN_MODULUS_SIZE: + if p.bit_length() < rust_openssl.dh.MIN_MODULUS_SIZE: raise ValueError( - f"p (modulus) must be at least {_MIN_MODULUS_SIZE}-bit" + f"p (modulus) must be at least " + f"{rust_openssl.dh.MIN_MODULUS_SIZE}-bit" ) self._p = p @@ -168,6 +168,7 @@ def parameter_numbers(self) -> DHParameterNumbers: DHParametersWithSerialization = DHParameters +DHParameters.register(rust_openssl.dh.DHParameters) class DHPublicKey(metaclass=abc.ABCMeta): @@ -208,6 +209,7 @@ def __eq__(self, other: object) -> bool: DHPublicKeyWithSerialization = DHPublicKey +DHPublicKey.register(rust_openssl.dh.DHPublicKey) class DHPrivateKey(metaclass=abc.ABCMeta): @@ -256,3 +258,4 @@ def private_bytes( DHPrivateKeyWithSerialization = DHPrivateKey +DHPrivateKey.register(rust_openssl.dh.DHPrivateKey) diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs new file mode 100644 index 000000000000..33e94f1c204d --- /dev/null +++ b/src/rust/src/backend/dh.rs @@ -0,0 +1,443 @@ +// 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. + +use crate::asn1::encode_der_data; +use crate::backend::utils; +use crate::error::{CryptographyError, CryptographyResult}; +use crate::x509; +use foreign_types_shared::ForeignTypeRef; + +const MIN_MODULUS_SIZE: u32 = 512; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.dh")] +struct DHPrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.dh")] +struct DHPublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.dh")] +struct DHParameters { + dh: openssl::dh::Dh, +} + +#[pyo3::prelude::pyfunction] +fn generate_parameters(generator: u32, key_size: u32) -> CryptographyResult { + if key_size < MIN_MODULUS_SIZE { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "DH key_size must be at least {} bits", + MIN_MODULUS_SIZE + )), + )); + } + if generator != 2 && generator != 5 { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("DH generator must be 2 or 5"), + )); + } + + let dh = openssl::dh::Dh::generate_params(key_size, generator) + .map_err(|_| pyo3::exceptions::PyValueError::new_err("Unable to generate DH parameters"))?; + Ok(DHParameters { dh }) +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> DHPrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + DHPrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> DHPublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + DHPublicKey { + pkey: pkey.to_owned(), + } +} + +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +struct ASN1DHParams<'a> { + p: asn1::BigUint<'a>, + g: asn1::BigUint<'a>, + q: Option>, +} + +#[pyo3::prelude::pyfunction] +fn from_der_parameters(data: &[u8]) -> CryptographyResult { + let asn1_params = asn1::parse_single::>(data)?; + + let p = openssl::bn::BigNum::from_slice(asn1_params.p.as_bytes())?; + let q = asn1_params + .q + .map(|q| openssl::bn::BigNum::from_slice(q.as_bytes())) + .transpose()?; + let g = openssl::bn::BigNum::from_slice(asn1_params.g.as_bytes())?; + + Ok(DHParameters { + dh: openssl::dh::Dh::from_pqg(p, q, g)?, + }) +} + +#[pyo3::prelude::pyfunction] +fn from_pem_parameters(data: &[u8]) -> CryptographyResult { + let parsed = x509::find_in_pem( + data, + |p| p.tag == "DH PARAMETERS" || p.tag == "X9.42 DH PARAMETERS", + "Valid PEM but no BEGIN DH PARAMETERS/END DH PARAMETERS delimiters. Are you sure this is a DH parameters?", + )?; + + from_der_parameters(&parsed.contents) +} + +fn dh_parameters_from_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult> { + let p = utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "p"))?)?; + let q = numbers + .getattr(pyo3::intern!(py, "q"))? + .extract::>()? + .map(|v| utils::py_int_to_bn(py, v)) + .transpose()?; + let g = utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "g"))?)?; + + let dh = openssl::dh::Dh::from_pqg(p, q, g)?; + if !dh.check_key()? { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "DH private numbers did not pass safety checks.", + ), + )); + } + + Ok(dh) +} + +#[pyo3::prelude::pyfunction] +fn from_private_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let public_numbers = numbers.getattr(pyo3::intern!(py, "public_numbers"))?; + let parameter_numbers = public_numbers.getattr(pyo3::intern!(py, "parameter_numbers"))?; + + let dh = dh_parameters_from_numbers(py, parameter_numbers)?; + + let pub_key = utils::py_int_to_bn(py, public_numbers.getattr(pyo3::intern!(py, "y"))?)?; + let priv_key = utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "x"))?)?; + + let pkey = openssl::pkey::PKey::from_dh(dh.set_key(pub_key, priv_key)?)?; + Ok(DHPrivateKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_public_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let parameter_numbers = numbers.getattr(pyo3::intern!(py, "parameter_numbers"))?; + let dh = dh_parameters_from_numbers(py, parameter_numbers)?; + + let pub_key = utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "y"))?)?; + + let pkey = openssl::pkey::PKey::from_dh(dh.set_public_key(pub_key)?)?; + + Ok(DHPublicKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_parameter_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let dh = dh_parameters_from_numbers(py, numbers)?; + Ok(DHParameters { dh }) +} + +fn clone_dh( + dh: &openssl::dh::Dh, +) -> CryptographyResult> { + let p = dh.prime_p().to_owned()?; + let q = dh.prime_q().map(|q| q.to_owned()).transpose()?; + let g = dh.generator().to_owned()?; + Ok(openssl::dh::Dh::from_pqg(p, q, g)?) +} + +#[pyo3::prelude::pymethods] +impl DHPrivateKey { + #[getter] + fn key_size(&self) -> i32 { + self.pkey.dh().unwrap().prime_p().num_bits() + } + + fn exchange<'p>( + &self, + py: pyo3::Python<'p>, + public_key: &DHPublicKey, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut deriver = openssl::derive::Deriver::new(&self.pkey)?; + deriver + .set_peer(&public_key.pkey) + .map_err(|_| pyo3::exceptions::PyValueError::new_err("Error computing shared key."))?; + + Ok(pyo3::types::PyBytes::new_with(py, deriver.len()?, |b| { + let n = deriver.derive(b).unwrap(); + + let pad = b.len() - n; + if pad > 0 { + b.copy_within(0..n, pad); + for c in b.iter_mut().take(pad) { + *c = 0; + } + } + Ok(()) + })?) + } + + fn private_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let dh = self.pkey.dh().unwrap(); + + let py_p = utils::bn_to_py_int(py, dh.prime_p())?; + let py_q = dh + .prime_q() + .map(|q| utils::bn_to_py_int(py, q)) + .transpose()?; + let py_g = utils::bn_to_py_int(py, dh.generator())?; + + let py_pub_key = utils::bn_to_py_int(py, dh.public_key())?; + let py_private_key = utils::bn_to_py_int(py, dh.private_key())?; + + let dh_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dh" + ))?; + + let parameter_numbers = + dh_mod.call_method1(pyo3::intern!(py, "DHParameterNumbers"), (py_p, py_g, py_q))?; + let public_numbers = dh_mod.call_method1( + pyo3::intern!(py, "DHPublicNumbers"), + (py_pub_key, parameter_numbers), + )?; + + Ok(dh_mod.call_method1( + pyo3::intern!(py, "DHPrivateNumbers"), + (py_private_key, public_numbers), + )?) + } + + fn public_key(&self) -> CryptographyResult { + let orig_dh = self.pkey.dh().unwrap(); + let dh = clone_dh(&orig_dh)?; + + let pkey = + openssl::pkey::PKey::from_dh(dh.set_public_key(orig_dh.public_key().to_owned()?)?)?; + + Ok(DHPublicKey { pkey }) + } + + fn parameters(&self) -> CryptographyResult { + Ok(DHParameters { + dh: clone_dh(&self.pkey.dh().unwrap())?, + }) + } + + fn private_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let private_format_class = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? + .getattr(pyo3::intern!(py, "PrivateFormat"))?; + if !format.is(private_format_class.getattr(pyo3::intern!(py, "PKCS8"))?) { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "DH private keys support only PKCS8 serialization", + ), + )); + } + + utils::pkey_private_bytes( + py, + slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + true, + ) + } +} + +#[pyo3::prelude::pymethods] +impl DHPublicKey { + #[getter] + fn key_size(&self) -> i32 { + self.pkey.dh().unwrap().prime_p().num_bits() + } + + fn public_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let public_format_class = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? + .getattr(pyo3::intern!(py, "PublicFormat"))?; + if !format.is(public_format_class.getattr(pyo3::intern!(py, "SubjectPublicKeyInfo"))?) { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "DH public keys support only SubjectPublicKeyInfo serialization", + ), + )); + } + + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) + } + + fn parameters(&self) -> CryptographyResult { + Ok(DHParameters { + dh: clone_dh(&self.pkey.dh().unwrap())?, + }) + } + + fn public_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let dh = self.pkey.dh().unwrap(); + + let py_p = utils::bn_to_py_int(py, dh.prime_p())?; + let py_q = dh + .prime_q() + .map(|q| utils::bn_to_py_int(py, q)) + .transpose()?; + let py_g = utils::bn_to_py_int(py, dh.generator())?; + + let py_pub_key = utils::bn_to_py_int(py, dh.public_key())?; + + let dh_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dh" + ))?; + + let parameter_numbers = + dh_mod.call_method1(pyo3::intern!(py, "DHParameterNumbers"), (py_p, py_g, py_q))?; + + Ok(dh_mod.call_method1( + pyo3::intern!(py, "DHPublicNumbers"), + (py_pub_key, parameter_numbers), + )?) + } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, DHPublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } +} + +#[pyo3::prelude::pymethods] +impl DHParameters { + fn generate_private_key(&self) -> CryptographyResult { + let dh = clone_dh(&self.dh)?.generate_key()?; + Ok(DHPrivateKey { + pkey: openssl::pkey::PKey::from_dh(dh)?, + }) + } + + fn parameter_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let py_p = utils::bn_to_py_int(py, self.dh.prime_p())?; + let py_q = self + .dh + .prime_q() + .map(|q| utils::bn_to_py_int(py, q)) + .transpose()?; + let py_g = utils::bn_to_py_int(py, self.dh.generator())?; + + Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dh" + ))? + .call_method1(pyo3::intern!(py, "DHParameterNumbers"), (py_p, py_g, py_q))?) + } + + fn parameter_bytes<'p>( + &self, + py: pyo3::Python<'p>, + encoding: &'p pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let parameter_format_class = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.serialization" + ))? + .getattr(pyo3::intern!(py, "ParameterFormat"))?; + if !format.is(parameter_format_class.getattr(pyo3::intern!(py, "PKCS3"))?) { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err("Only PKCS3 serialization is supported"), + )); + } + + let p_bytes = utils::bn_to_big_endian_bytes(self.dh.prime_p())?; + let q_bytes = self + .dh + .prime_q() + .map(utils::bn_to_big_endian_bytes) + .transpose()?; + let g_bytes = utils::bn_to_big_endian_bytes(self.dh.generator())?; + let asn1dh_params = ASN1DHParams { + p: asn1::BigUint::new(&p_bytes).unwrap(), + q: q_bytes.as_ref().map(|q| asn1::BigUint::new(q).unwrap()), + g: asn1::BigUint::new(&g_bytes).unwrap(), + }; + let data = asn1::write_single(&asn1dh_params)?; + let tag = if q_bytes.is_none() { + "DH PARAMETERS" + } else { + "X9.42 DH PARAMETERS" + }; + encode_der_data(py, tag.to_string(), data, encoding) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "dh")?; + m.add_wrapped(pyo3::wrap_pyfunction!(generate_parameters))?; + m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_der_parameters))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_pem_parameters))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_private_numbers))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_public_numbers))?; + m.add_wrapped(pyo3::wrap_pyfunction!(from_parameter_numbers))?; + + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + + m.add("MIN_MODULUS_SIZE", MIN_MODULUS_SIZE)?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index b48f2089a991..a38d39287ee2 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -2,13 +2,13 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +pub(crate) mod dh; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod ed25519; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] pub(crate) mod ed448; pub(crate) mod hashes; pub(crate) mod hmac; -#[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod x25519; @@ -16,6 +16,8 @@ pub(crate) mod x25519; pub(crate) mod x448; pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { + module.add_submodule(dh::create_module(module.py())?)?; + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(ed25519::create_module(module.py())?)?; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] diff --git a/src/rust/src/backend/utils.rs b/src/rust/src/backend/utils.rs index 25b7a5b9f87e..072a80f5f73d 100644 --- a/src/rust/src/backend/utils.rs +++ b/src/rust/src/backend/utils.rs @@ -4,6 +4,39 @@ use crate::error::{CryptographyError, CryptographyResult}; +pub(crate) fn py_int_to_bn( + py: pyo3::Python<'_>, + v: &pyo3::PyAny, +) -> CryptographyResult { + let n = v + .call_method0(pyo3::intern!(py, "bit_length"))? + .extract::()? + / 8 + + 1; + let bytes: &[u8] = v + .call_method1(pyo3::intern!(py, "to_bytes"), (n, pyo3::intern!(py, "big")))? + .extract()?; + + Ok(openssl::bn::BigNum::from_slice(bytes)?) +} + +pub(crate) fn bn_to_py_int<'p>( + py: pyo3::Python<'p>, + b: &openssl::bn::BigNumRef, +) -> CryptographyResult<&'p pyo3::PyAny> { + assert!(!b.is_negative()); + + let int_type = py.get_type::(); + Ok(int_type.call_method1( + pyo3::intern!(py, "from_bytes"), + (b.to_vec(), pyo3::intern!(py, "big")), + )?) +} + +pub(crate) fn bn_to_big_endian_bytes(b: &openssl::bn::BigNumRef) -> CryptographyResult> { + Ok(b.to_vec_padded(b.num_bits() / 8 + 1)?) +} + pub(crate) fn pkey_private_bytes<'p>( py: pyo3::Python<'p>, key_obj: &pyo3::PyAny, @@ -23,6 +56,9 @@ pub(crate) fn pkey_private_bytes<'p>( let private_format_class: &pyo3::types::PyType = serialization_mod .getattr(pyo3::intern!(py, "PrivateFormat"))? .extract()?; + let key_serialization_encryption_class: &pyo3::types::PyType = serialization_mod + .getattr(pyo3::intern!(py, "KeySerializationEncryption"))? + .extract()?; let no_encryption_class: &pyo3::types::PyType = serialization_mod .getattr(pyo3::intern!(py, "NoEncryption"))? .extract()?; @@ -44,7 +80,15 @@ pub(crate) fn pkey_private_bytes<'p>( ), )); } + if !encryption_algorithm.is_instance(key_serialization_encryption_class)? { + return Err(CryptographyError::from( + pyo3::exceptions::PyTypeError::new_err( + "Encryption algorithm must be a KeySerializationEncryption instance", + ), + )); + } + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) { @@ -68,9 +112,7 @@ pub(crate) fn pkey_private_bytes<'p>( .extract::<&[u8]>()? } else { return Err(CryptographyError::from( - pyo3::exceptions::PyTypeError::new_err( - "Encryption algorithm must be a KeySerializationEncryption instance", - ), + pyo3::exceptions::PyValueError::new_err("Unsupported encryption type"), )); }; @@ -170,6 +212,7 @@ pub(crate) fn pkey_public_bytes<'p>( )); } + #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) { diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 27a0b95286ce..c8fa1efa21f5 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -13,7 +13,7 @@ from cryptography.hazmat.backends.openssl.backend import backend from cryptography.hazmat.backends.openssl.ec import _sn_to_elliptic_curve from cryptography.hazmat.primitives import hashes, serialization -from cryptography.hazmat.primitives.asymmetric import dh, padding +from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.algorithms import AES from cryptography.hazmat.primitives.ciphers.modes import CBC @@ -27,7 +27,6 @@ ) from ...hazmat.primitives.test_rsa import rsa_key_512, rsa_key_2048 from ...utils import ( - load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm, ) @@ -373,36 +372,6 @@ def test_password_length_limit(self, rsa_key_2048): skip_message="Requires DH support", ) class TestOpenSSLDHSerialization: - @pytest.mark.parametrize( - "vector", - load_vectors_from_file( - os.path.join("asymmetric", "DH", "RFC5114.txt"), load_nist_vectors - ), - ) - def test_dh_serialization_with_q_unsupported(self, backend, vector): - parameters = dh.DHParameterNumbers( - int(vector["p"], 16), int(vector["g"], 16), int(vector["q"], 16) - ) - public = dh.DHPublicNumbers(int(vector["ystatcavs"], 16), parameters) - private = dh.DHPrivateNumbers(int(vector["xstatcavs"], 16), public) - private_key = private.private_key(backend) - public_key = private_key.public_key() - with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION): - private_key.private_bytes( - serialization.Encoding.PEM, - serialization.PrivateFormat.PKCS8, - serialization.NoEncryption(), - ) - with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION): - public_key.public_bytes( - serialization.Encoding.PEM, - serialization.PublicFormat.SubjectPublicKeyInfo, - ) - with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION): - parameters.parameters(backend).parameter_bytes( - serialization.Encoding.PEM, serialization.ParameterFormat.PKCS3 - ) - @pytest.mark.parametrize( ("key_path", "loader_func"), [ diff --git a/tests/hazmat/primitives/test_dh.py b/tests/hazmat/primitives/test_dh.py index d47739ac07e8..098d6e142b24 100644 --- a/tests/hazmat/primitives/test_dh.py +++ b/tests/hazmat/primitives/test_dh.py @@ -148,7 +148,7 @@ def test_unsupported_generator_generate_dh(self, backend): with pytest.raises(ValueError): dh.generate_parameters(7, 512, backend) - def test_large_key_generate_dh(self): + def test_large_key_generate_dh(self, backend): with pytest.raises(ValueError): dh.generate_parameters(2, 1 << 30) @@ -486,6 +486,9 @@ def test_public_key_equality(self, backend): assert key1 != key3 assert key1 != object() + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] + @pytest.mark.supported( only_if=lambda backend: backend.dh_supported(), diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 7f847078c345..4b47e0a1657f 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -15,6 +15,7 @@ Ed25519PublicKey, ) +from ...doubles import DummyKeySerializationEncryption from ...utils import load_vectors_from_file, raises_unsupported_algorithm @@ -156,18 +157,24 @@ def test_invalid_length_from_private_bytes(self, backend): def test_invalid_private_bytes(self, backend): key = Ed25519PrivateKey.generate() - with pytest.raises(ValueError): + with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.Raw, None, # type: ignore[arg-type] ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.Raw, + serialization.PrivateFormat.Raw, + DummyKeySerializationEncryption(), + ) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.PKCS8, - None, # type: ignore[arg-type] + DummyKeySerializationEncryption(), ) with pytest.raises(ValueError): diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index e88d3dce2ccc..650cdda7997c 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -15,6 +15,7 @@ Ed448PublicKey, ) +from ...doubles import DummyKeySerializationEncryption from ...utils import ( load_nist_vectors, load_vectors_from_file, @@ -192,18 +193,24 @@ def test_invalid_length_from_private_bytes(self, backend): def test_invalid_private_bytes(self, backend): key = Ed448PrivateKey.generate() - with pytest.raises(ValueError): + with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.Raw, None, # type: ignore[arg-type] ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.Raw, + serialization.PrivateFormat.Raw, + DummyKeySerializationEncryption(), + ) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.PKCS8, - None, # type: ignore[arg-type] + DummyKeySerializationEncryption(), ) with pytest.raises(ValueError): diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 59a141d3395a..58693a4912d2 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -395,6 +395,10 @@ def test_load_ec_public_key(self, backend): assert key.curve.name == "secp256r1" assert key.curve.key_size == 256 + @pytest.mark.supported( + only_if=lambda backend: backend.dh_supported(), + skip_message="DH not supported", + ) def test_wrong_parameters_format(self, backend): param_data = b"---- NOT A KEY ----\n" @@ -734,6 +738,10 @@ def test_wrong_public_format(self, backend): with pytest.raises(ValueError): load_pem_public_key(key_data, backend) + @pytest.mark.supported( + only_if=lambda backend: backend.dh_supported(), + skip_message="DH not supported", + ) def test_wrong_parameters_format(self, backend): param_data = b"---- NOT A KEY ----\n" diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index 21cc55edfc03..ae4f382bc487 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -15,6 +15,7 @@ X25519PublicKey, ) +from ...doubles import DummyKeySerializationEncryption from ...utils import ( load_nist_vectors, load_vectors_from_file, @@ -195,18 +196,24 @@ def test_invalid_length_from_private_bytes(self, backend): def test_invalid_private_bytes(self, backend): key = X25519PrivateKey.generate() - with pytest.raises(ValueError): + with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.Raw, None, # type: ignore[arg-type] ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.Raw, + serialization.PrivateFormat.Raw, + DummyKeySerializationEncryption(), + ) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.PKCS8, - None, # type: ignore[arg-type] + DummyKeySerializationEncryption(), ) with pytest.raises(ValueError): diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index c9d92112b698..e2f840fa82fb 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -15,6 +15,7 @@ X448PublicKey, ) +from ...doubles import DummyKeySerializationEncryption from ...utils import ( load_nist_vectors, load_vectors_from_file, @@ -200,18 +201,24 @@ def test_invalid_length_from_private_bytes(self, backend): def test_invalid_private_bytes(self, backend): key = X448PrivateKey.generate() - with pytest.raises(ValueError): + with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.Raw, None, # type: ignore[arg-type] ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.Raw, + serialization.PrivateFormat.Raw, + DummyKeySerializationEncryption(), + ) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.Raw, serialization.PrivateFormat.PKCS8, - None, # type: ignore[arg-type] + DummyKeySerializationEncryption(), ) with pytest.raises(ValueError): From bb16b2a7d74978c4d02cfb43823a413b1ec79410 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 21:36:01 -0600 Subject: [PATCH 691/827] Convert KDFs to Rust (#8787) --- .../hazmat/backends/openssl/backend.py | 60 ------------------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../hazmat/bindings/_rust/openssl/kdf.pyi | 22 +++++++ .../hazmat/primitives/kdf/pbkdf2.py | 10 ++-- .../hazmat/primitives/kdf/scrypt.py | 12 +++- src/rust/src/backend/kdf.rs | 60 +++++++++++++++++++ src/rust/src/backend/mod.rs | 2 + 7 files changed, 99 insertions(+), 69 deletions(-) create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi create mode 100644 src/rust/src/backend/kdf.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index c8e1b81a218c..9360fee7ab31 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -85,7 +85,6 @@ XTS, Mode, ) -from cryptography.hazmat.primitives.kdf import scrypt from cryptography.hazmat.primitives.serialization import ssh from cryptography.hazmat.primitives.serialization.pkcs12 import ( PBES, @@ -365,30 +364,6 @@ def create_symmetric_decryption_ctx( def pbkdf2_hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool: return self.hmac_supported(algorithm) - def derive_pbkdf2_hmac( - self, - algorithm: hashes.HashAlgorithm, - length: int, - salt: bytes, - iterations: int, - key_material: bytes, - ) -> bytes: - buf = self._ffi.new("unsigned char[]", length) - evp_md = self._evp_md_non_null_from_algorithm(algorithm) - key_material_ptr = self._ffi.from_buffer(key_material) - res = self._lib.PKCS5_PBKDF2_HMAC( - key_material_ptr, - len(key_material), - salt, - len(salt), - iterations, - evp_md, - length, - buf, - ) - self.openssl_assert(res == 1) - return self._ffi.buffer(buf)[:] - def _consume_errors(self) -> typing.List[rust_openssl.OpenSSLError]: return rust_openssl.capture_error_stack() @@ -1703,41 +1678,6 @@ def ed448_load_private_bytes(self, data: bytes) -> ed448.Ed448PrivateKey: def ed448_generate_key(self) -> ed448.Ed448PrivateKey: return rust_openssl.ed448.generate_key() - def derive_scrypt( - self, - key_material: bytes, - salt: bytes, - length: int, - n: int, - r: int, - p: int, - ) -> bytes: - buf = self._ffi.new("unsigned char[]", length) - key_material_ptr = self._ffi.from_buffer(key_material) - res = self._lib.EVP_PBE_scrypt( - key_material_ptr, - len(key_material), - salt, - len(salt), - n, - r, - p, - scrypt._MEM_LIMIT, - buf, - length, - ) - if res != 1: - errors = self._consume_errors() - # memory required formula explained here: - # https://blog.filippo.io/the-scrypt-parameters/ - min_memory = 128 * n * r // (1024**2) - raise MemoryError( - "Not enough memory to derive key. These parameters require" - " {} MB of memory.".format(min_memory), - errors, - ) - return self._ffi.buffer(buf)[:] - def aead_cipher_supported(self, cipher) -> bool: cipher_name = aead._aead_cipher_name(cipher) if self._fips_enabled and cipher_name not in self._fips_aead: diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index bfa641259854..3b43036ce15d 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -10,6 +10,7 @@ from cryptography.hazmat.bindings._rust.openssl import ( ed25519, hashes, hmac, + kdf, x448, x25519, ) @@ -20,6 +21,7 @@ __all__ = [ "dh", "hashes", "hmac", + "kdf", "ed448", "ed25519", "x448", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi new file mode 100644 index 000000000000..034a8fed2e78 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi @@ -0,0 +1,22 @@ +# 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. + +from cryptography.hazmat.primitives.hashes import HashAlgorithm + +def derive_pbkdf2_hmac( + key_material: bytes, + algorithm: HashAlgorithm, + salt: bytes, + iterations: int, + length: int, +) -> bytes: ... +def derive_scrypt( + key_material: bytes, + salt: bytes, + n: int, + r: int, + p: int, + max_mem: int, + length: int, +) -> bytes: ... diff --git a/src/cryptography/hazmat/primitives/kdf/pbkdf2.py b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py index 2caa50e80a19..623e1ca7f9eb 100644 --- a/src/cryptography/hazmat/primitives/kdf/pbkdf2.py +++ b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py @@ -13,6 +13,7 @@ UnsupportedAlgorithm, _Reasons, ) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import constant_time, hashes from cryptography.hazmat.primitives.kdf import KeyDerivationFunction @@ -49,15 +50,12 @@ def derive(self, key_material: bytes) -> bytes: raise AlreadyFinalized("PBKDF2 instances can only be used once.") self._used = True - utils._check_byteslike("key_material", key_material) - from cryptography.hazmat.backends.openssl.backend import backend - - return backend.derive_pbkdf2_hmac( + return rust_openssl.kdf.derive_pbkdf2_hmac( + key_material, self._algorithm, - self._length, self._salt, self._iterations, - key_material, + self._length, ) def verify(self, key_material: bytes, expected_key: bytes) -> None: diff --git a/src/cryptography/hazmat/primitives/kdf/scrypt.py b/src/cryptography/hazmat/primitives/kdf/scrypt.py index 6443832aa382..05a4f675b6ab 100644 --- a/src/cryptography/hazmat/primitives/kdf/scrypt.py +++ b/src/cryptography/hazmat/primitives/kdf/scrypt.py @@ -13,6 +13,7 @@ InvalidKey, UnsupportedAlgorithm, ) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import constant_time from cryptography.hazmat.primitives.kdf import KeyDerivationFunction @@ -62,10 +63,15 @@ def derive(self, key_material: bytes) -> bytes: self._used = True utils._check_byteslike("key_material", key_material) - from cryptography.hazmat.backends.openssl.backend import backend - return backend.derive_scrypt( - key_material, self._salt, self._length, self._n, self._r, self._p + return rust_openssl.kdf.derive_scrypt( + key_material, + self._salt, + self._n, + self._r, + self._p, + _MEM_LIMIT, + self._length, ) def verify(self, key_material: bytes, expected_key: bytes) -> None: diff --git a/src/rust/src/backend/kdf.rs b/src/rust/src/backend/kdf.rs new file mode 100644 index 000000000000..5bd5606c9f1b --- /dev/null +++ b/src/rust/src/backend/kdf.rs @@ -0,0 +1,60 @@ +// 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. + +use crate::backend::hashes; +use crate::buf::CffiBuf; +use crate::error::CryptographyResult; + +#[pyo3::prelude::pyfunction] +fn derive_pbkdf2_hmac<'p>( + py: pyo3::Python<'p>, + key_material: CffiBuf<'_>, + algorithm: &pyo3::PyAny, + salt: &[u8], + iterations: usize, + length: usize, +) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let md = hashes::message_digest_from_algorithm(py, algorithm)?; + + Ok(pyo3::types::PyBytes::new_with(py, length, |b| { + openssl::pkcs5::pbkdf2_hmac(key_material.as_bytes(), salt, iterations, md, b).unwrap(); + Ok(()) + })?) +} + +#[cfg(not(CRYPTOGRAPHY_IS_LIBRESSL))] +#[pyo3::prelude::pyfunction] +#[allow(clippy::too_many_arguments)] +fn derive_scrypt<'p>( + py: pyo3::Python<'p>, + key_material: CffiBuf<'_>, + salt: &[u8], + n: u64, + r: u64, + p: u64, + max_mem: u64, + length: usize, +) -> CryptographyResult<&'p pyo3::types::PyBytes> { + Ok(pyo3::types::PyBytes::new_with(py, length, |b| { + openssl::pkcs5::scrypt(key_material.as_bytes(), salt, n, r, p, max_mem, b).map_err(|_| { + // memory required formula explained here: + // https://blog.filippo.io/the-scrypt-parameters/ + let min_memory = 128 * n * r / (1024 * 1024); + pyo3::exceptions::PyMemoryError::new_err(format!( + "Not enough memory to derive key. These parameters require {}MB of memory.", + min_memory + )) + }) + })?) +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "kdf")?; + + m.add_wrapped(pyo3::wrap_pyfunction!(derive_pbkdf2_hmac))?; + #[cfg(not(CRYPTOGRAPHY_IS_LIBRESSL))] + m.add_wrapped(pyo3::wrap_pyfunction!(derive_scrypt))?; + + Ok(m) +} diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index a38d39287ee2..e52b149e38ef 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -9,6 +9,7 @@ pub(crate) mod ed25519; pub(crate) mod ed448; pub(crate) mod hashes; pub(crate) mod hmac; +pub(crate) mod kdf; pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod x25519; @@ -30,6 +31,7 @@ pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult< module.add_submodule(hashes::create_module(module.py())?)?; module.add_submodule(hmac::create_module(module.py())?)?; + module.add_submodule(kdf::create_module(module.py())?)?; Ok(()) } From 6bd393ea837ee062acdc1d66eca6c12c91fc76e6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 24 Apr 2023 21:51:05 -0600 Subject: [PATCH 692/827] Move is_fips logic to Rust (#8822) --- .../hazmat/backends/openssl/backend.py | 19 ++--------- .../bindings/_rust/openssl/__init__.pyi | 1 + src/rust/cryptography-openssl/build.rs | 24 ++++++++++++++ src/rust/cryptography-openssl/src/fips.rs | 32 +++++++++++++++++++ src/rust/cryptography-openssl/src/lib.rs | 1 + src/rust/src/lib.rs | 6 ++++ 6 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 src/rust/cryptography-openssl/build.rs create mode 100644 src/rust/cryptography-openssl/src/fips.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 9360fee7ab31..28f75cb94f88 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -156,7 +156,7 @@ def __init__(self) -> None: self._binding = binding.Binding() self._ffi = self._binding.ffi self._lib = self._binding.lib - self._fips_enabled = self._is_fips_enabled() + self._fips_enabled = rust_openssl.is_fips_enabled() self._cipher_registry: typing.Dict[ typing.Tuple[typing.Type[CipherAlgorithm], typing.Type[Mode]], @@ -181,25 +181,12 @@ def openssl_assert( ) -> None: return binding._openssl_assert(self._lib, ok, errors=errors) - def _is_fips_enabled(self) -> bool: - if self._lib.Cryptography_HAS_300_FIPS: - mode = self._lib.EVP_default_properties_is_fips_enabled( - self._ffi.NULL - ) - else: - mode = self._lib.FIPS_mode() - - if mode == 0: - # OpenSSL without FIPS pushes an error on the error stack - self._lib.ERR_clear_error() - return bool(mode) - def _enable_fips(self) -> None: # This function enables FIPS mode for OpenSSL 3.0.0 on installs that # have the FIPS provider installed properly. self._binding._enable_fips() - assert self._is_fips_enabled() - self._fips_enabled = self._is_fips_enabled() + assert rust_openssl.is_fips_enabled() + self._fips_enabled = rust_openssl.is_fips_enabled() def openssl_version_text(self) -> str: """ diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 3b43036ce15d..6712fff2755b 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -31,6 +31,7 @@ __all__ = [ def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... def capture_error_stack() -> typing.List[OpenSSLError]: ... +def is_fips_enabled() -> bool: ... class OpenSSLError: @property diff --git a/src/rust/cryptography-openssl/build.rs b/src/rust/cryptography-openssl/build.rs new file mode 100644 index 000000000000..a0b4566a753c --- /dev/null +++ b/src/rust/cryptography-openssl/build.rs @@ -0,0 +1,24 @@ +// 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. + +use std::env; + +#[allow(clippy::unusual_byte_groupings)] +fn main() { + if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") { + let version = u64::from_str_radix(&version, 16).unwrap(); + + if version >= 0x3_00_00_00_0 { + println!("cargo:rustc-cfg=CRYPTOGRAPHY_OPENSSL_300_OR_GREATER"); + } + } + + if env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER").is_ok() { + println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_LIBRESSL"); + } + + if env::var("DEP_OPENSSL_BORINGSSL").is_ok() { + println!("cargo:rustc-cfg=CRYPTOGRAPHY_IS_BORINGSSL"); + } +} diff --git a/src/rust/cryptography-openssl/src/fips.rs b/src/rust/cryptography-openssl/src/fips.rs new file mode 100644 index 000000000000..29c4c789d838 --- /dev/null +++ b/src/rust/cryptography-openssl/src/fips.rs @@ -0,0 +1,32 @@ +// 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. + +#[cfg(all( + CRYPTOGRAPHY_OPENSSL_300_OR_GREATER, + not(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL)) +))] +use std::ptr; + +pub fn is_enabled() -> bool { + #[cfg(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL))] + { + return false; + } + + #[cfg(all( + CRYPTOGRAPHY_OPENSSL_300_OR_GREATER, + not(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL)) + ))] + unsafe { + ffi::EVP_default_properties_is_fips_enabled(ptr::null_mut()) == 1 + } + + #[cfg(all( + not(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER), + not(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL)) + ))] + { + return openssl::fips::enabled(); + } +} diff --git a/src/rust/cryptography-openssl/src/lib.rs b/src/rust/cryptography-openssl/src/lib.rs index fcc2ff1a585b..0a2b48149e0f 100644 --- a/src/rust/cryptography-openssl/src/lib.rs +++ b/src/rust/cryptography-openssl/src/lib.rs @@ -2,6 +2,7 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +pub mod fips; pub mod hmac; pub type OpenSSLResult = Result; diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 95df2fa3c852..4d88e2813b50 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -131,6 +131,11 @@ fn capture_error_stack(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::types::PyL Ok(errs) } +#[pyo3::prelude::pyfunction] +fn is_fips_enabled() -> bool { + cryptography_openssl::fips::is_enabled() +} + #[pyo3::prelude::pymodule] fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { m.add_function(pyo3::wrap_pyfunction!(check_pkcs7_padding, m)?)?; @@ -161,6 +166,7 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> openssl_mod.add_function(pyo3::wrap_pyfunction!(openssl_version, m)?)?; openssl_mod.add_function(pyo3::wrap_pyfunction!(raise_openssl_error, m)?)?; openssl_mod.add_function(pyo3::wrap_pyfunction!(capture_error_stack, m)?)?; + openssl_mod.add_function(pyo3::wrap_pyfunction!(is_fips_enabled, m)?)?; openssl_mod.add_class::()?; crate::backend::add_to_module(openssl_mod)?; m.add_submodule(openssl_mod)?; From cebbe78b1fa2a52c51f2abb8885447e8475d4400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:11:05 +0000 Subject: [PATCH 693/827] Bump ruff from 0.0.262 to 0.0.263 (#8824) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.262 to 0.0.263. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.262...v0.0.263) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2a38918e676d..843ed02a6d5e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -136,7 +136,7 @@ rfc3986==2.0.0 # via twine rich==13.3.4 # via twine -ruff==0.0.262 +ruff==0.0.263 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From e03d583dcb29c653074c160169c890ce01400511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:12:11 +0000 Subject: [PATCH 694/827] Bump sphinx from 6.2.0 to 6.2.1 (#8825) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v6.2.0...v6.2.1) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 843ed02a6d5e..264417db4518 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -142,7 +142,7 @@ six==1.16.0 # via bleach snowballstemmer==2.2.0 # via sphinx -sphinx==6.2.0 +sphinx==6.2.1 # via # cryptography (pyproject.toml) # sphinx-rtd-theme From bb91e8b44950e909c6cfa56b9339ccbcc6c66bfe Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 25 Apr 2023 07:23:57 -0600 Subject: [PATCH 695/827] See if we can always enable abi3 (#8823) Previously it wasn't because pypy doesn't support abi3, but maybe the pyo3 feature works. --- setup.py | 6 ------ src/rust/Cargo.toml | 2 +- src/rust/cryptography-cffi/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index b05dc2f129c3..4fe0c027c17c 100644 --- a/setup.py +++ b/setup.py @@ -54,12 +54,6 @@ "cryptography.hazmat.bindings._rust", "src/rust/Cargo.toml", py_limited_api=True, - # Enable abi3 mode if we're not using PyPy. - features=( - [] - if platform.python_implementation() == "PyPy" - else ["pyo3/abi3-py37"] - ), rust_version=">=1.56.0", ) ], diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index bb8f74a849b0..614bd9967e0a 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" -pyo3 = { version = "0.18" } +pyo3 = { version = "0.18", features = ["abi3-py37"] } asn1 = { version = "0.15.0", default-features = false } cryptography-cffi = { path = "cryptography-cffi" } cryptography-x509 = { path = "cryptography-x509" } diff --git a/src/rust/cryptography-cffi/Cargo.toml b/src/rust/cryptography-cffi/Cargo.toml index f9ae6bc2ed43..652e621e10a0 100644 --- a/src/rust/cryptography-cffi/Cargo.toml +++ b/src/rust/cryptography-cffi/Cargo.toml @@ -8,7 +8,7 @@ publish = false rust-version = "1.56.0" [dependencies] -pyo3 = { version = "0.18" } +pyo3 = { version = "0.18", features = ["abi3-py37"] } openssl-sys = "0.9.87" [build-dependencies] From 62ac9c2d474f157bc91f7dc9dee9551380e41bde Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 25 Apr 2023 12:58:06 -0600 Subject: [PATCH 696/827] Stop invoking setup.py in wheel builder (#8826) --- .github/workflows/wheel-builder.yml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 90e29c960d92..f6040de26c84 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -105,16 +105,15 @@ jobs: - run: /opt/python/${{ matrix.PYTHON.VERSION }}/bin/python -m venv .venv - name: Install Python dependencies run: .venv/bin/pip install -U pip wheel cffi setuptools-rust - - run: tar zxvf cryptography*.tar.gz && rm cryptography*.tar.gz && mkdir tmpwheelhouse + - run: mkdir tmpwheelhouse - name: Build the wheel run: | if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then - PY_LIMITED_API="--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }}" + PY_LIMITED_API="--config-settings=--build-option=--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} --no-build-isolation" fi - cd cryptography* OPENSSL_DIR="/opt/pyca/cryptography/openssl" \ OPENSSL_STATIC=1 \ - ../.venv/bin/python setup.py bdist_wheel $PY_LIMITED_API && mv dist/cryptography*.whl ../tmpwheelhouse + .venv/bin/python -m pip wheel -v $PY_LIMITED_API cryptograph*.tar.gz -w dist/ && mv dist/cryptography*.whl tmpwheelhouse env: RUSTUP_HOME: /root/.rustup - run: auditwheel repair --plat ${{ matrix.MANYLINUX.NAME }} tmpwheelhouse/cryptograph*.whl -w wheelhouse/ @@ -211,18 +210,21 @@ jobs: - run: ${{ matrix.PYTHON.BIN_PATH }} -m venv venv - run: venv/bin/pip install -U pip wheel cffi setuptools-rust - - run: tar zxvf cryptography*.tar.gz && mkdir wheelhouse + - run: mkdir wheelhouse - name: Build the wheel run: | - cd cryptography* - OPENSSL_DIR="$(readlink -f ../../openssl-macos-universal2/)" \ + if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then + PY_LIMITED_API="--config-settings=--build-option=--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} --no-build-isolation" + fi + + OPENSSL_DIR="$(readlink -f ../openssl-macos-universal2/)" \ OPENSSL_STATIC=1 \ - ../venv/bin/python setup.py bdist_wheel --py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} && mv dist/cryptography*.whl ../wheelhouse + venv/bin/python -m pip wheel -v $PY_LIMITED_API cryptograph*.tar.gz -w dist/ && mv dist/cryptography*.whl 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: venv/bin/pip install -f wheelhouse/ --no-index cryptography - name: Show the wheel's minimum macOS SDK and architectures run: | find venv/lib/*/site-packages/cryptography/hazmat/bindings -name '*.so' -exec vtool -show {} \; @@ -290,9 +292,14 @@ jobs: - run: python -m pip install -U pip wheel - run: python -m pip install cffi setuptools-rust - - run: tar zxvf cryptography*.tar.gz && mkdir wheelhouse + - run: mkdir wheelhouse + - run: | + if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then + PY_LIMITED_API="--config-settings=--build-option=--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} --no-build-isolation" + fi + + python -m pip wheel -v cryptography*.tar.gz $PY_LIMITED_API -w dist/ && mv dist/cryptography*.whl wheelhouse/ shell: bash - - run: cd cryptography* && python setup.py bdist_wheel --py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} && mv dist/cryptography*.whl ../wheelhouse - run: pip install -f wheelhouse --no-index cryptography - name: Print the OpenSSL we built and linked against run: | From ea46011d713e7c539ac2e883eff20501eceb7725 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 25 Apr 2023 17:40:15 -0600 Subject: [PATCH 697/827] update macos wheel builder to use latest 3.11.x (#8827) --- .github/workflows/wheel-builder.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index f6040de26c84..c3e145a99a9f 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -146,7 +146,7 @@ jobs: - VERSION: '3.11' ABI_VERSION: 'cp37' # Despite the name, this is built for the macOS 11 SDK on arm64 and 10.9+ on intel - DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.2/python-3.11.2-macos11.pkg' + DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.3/python-3.11.3-macos11.pkg' BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' DEPLOYMENT_TARGET: '10.12' # This archflags is default, but let's be explicit @@ -157,7 +157,7 @@ jobs: _PYTHON_HOST_PLATFORM: 'macosx-10.9-universal2' - VERSION: '3.11' ABI_VERSION: 'cp37' - DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.2/python-3.11.2-macos11.pkg' + DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.3/python-3.11.3-macos11.pkg' BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' DEPLOYMENT_TARGET: '10.12' # We continue to build a non-universal2 for a bit to see metrics on From 3cb5ca7d4a16b9b15b462cbdb86b638f24c0e945 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 00:15:36 +0000 Subject: [PATCH 698/827] Bump BoringSSL and/or OpenSSL in CI (#8829) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f37af412e70e..8835b2144d24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 25, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "de2d610a341f5a4b8c222425890537cb84c91400"}} - # Latest commit on the OpenSSL master branch, as of Apr 25, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "24a322544373f7acda05e19f64a6c3120d459d5b"}} + # Latest commit on the BoringSSL master branch, as of Apr 26, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d5f3a9e82fc6735eff5733f51b892d776f4a84eb"}} + # Latest commit on the OpenSSL master branch, as of Apr 26, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "fc374a087e7fc5a5bd243ea42ce9879e8432b20e"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From cd23d7ab13ff66e339dd357d0cdbb9b2ddb63bdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 08:15:42 -0500 Subject: [PATCH 699/827] Bump platformdirs from 3.2.0 to 3.3.0 (#8831) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.2.0...3.3.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 264417db4518..12c6805fc382 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -87,7 +87,7 @@ pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine -platformdirs==3.2.0 +platformdirs==3.3.0 # via # black # virtualenv From d78ecb8dc1095ae9101d32671183d7a9bed13acd Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 26 Apr 2023 09:17:14 -0400 Subject: [PATCH 700/827] Remove a bunch of unused bindings (#8830) Also replace one DH function with a simpler implementation --- src/_cffi_src/openssl/dh.py | 21 --------------- src/_cffi_src/openssl/evp.py | 11 -------- src/_cffi_src/openssl/pem.py | 5 ---- .../hazmat/backends/openssl/backend.py | 26 +++++-------------- .../hazmat/bindings/openssl/_conditional.py | 9 ------- 5 files changed, 7 insertions(+), 65 deletions(-) diff --git a/src/_cffi_src/openssl/dh.py b/src/_cffi_src/openssl/dh.py index 1a75b6d22879..b4a42e7f6058 100644 --- a/src/_cffi_src/openssl/dh.py +++ b/src/_cffi_src/openssl/dh.py @@ -15,29 +15,8 @@ """ FUNCTIONS = """ -DH *DH_new(void); void DH_free(DH *); -int DH_size(const DH *); -int DH_generate_key(DH *); -DH *DHparams_dup(DH *); - -void DH_get0_pqg(const DH *, const BIGNUM **, const BIGNUM **, - const BIGNUM **); -int DH_set0_pqg(DH *, BIGNUM *, BIGNUM *, BIGNUM *); -void DH_get0_key(const DH *, const BIGNUM **, const BIGNUM **); -int DH_set0_key(DH *, BIGNUM *, BIGNUM *); - -int DH_check(const DH *, int *); -int DH_generate_parameters_ex(DH *, int, int, BN_GENCB *); -DH *d2i_DHparams_bio(BIO *, DH **); -int i2d_DHparams_bio(BIO *, DH *); -DH *d2i_DHxparams_bio(BIO *, DH **); -int i2d_DHxparams_bio(BIO *, DH *); """ CUSTOMIZATIONS = """ -#if !(defined(EVP_PKEY_DHX) && EVP_PKEY_DHX != -1) -DH *(*d2i_DHxparams_bio)(BIO *bp, DH **x) = NULL; -int (*i2d_DHxparams_bio)(BIO *bp, DH *x) = NULL; -#endif """ diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index b22c2ac0f9fa..f1c367010398 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -67,7 +67,6 @@ int EVP_PKEY_size(EVP_PKEY *); RSA *EVP_PKEY_get1_RSA(EVP_PKEY *); DSA *EVP_PKEY_get1_DSA(EVP_PKEY *); -DH *EVP_PKEY_get1_DH(EVP_PKEY *); int EVP_PKEY_encrypt(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t); @@ -131,15 +130,8 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *); -int PKCS5_PBKDF2_HMAC(const char *, int, const unsigned char *, int, int, - const EVP_MD *, int, unsigned char *); - int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *, const EVP_MD *); -int EVP_PBE_scrypt(const char *, size_t, const unsigned char *, size_t, - uint64_t, uint64_t, uint64_t, uint64_t, unsigned char *, - size_t); - EVP_PKEY *EVP_PKEY_new_raw_private_key(int, ENGINE *, const unsigned char *, size_t); EVP_PKEY *EVP_PKEY_new_raw_public_key(int, ENGINE *, const unsigned char *, @@ -161,9 +153,6 @@ #if CRYPTOGRAPHY_IS_LIBRESSL || defined(OPENSSL_NO_SCRYPT) static const long Cryptography_HAS_SCRYPT = 0; -int (*EVP_PBE_scrypt)(const char *, size_t, const unsigned char *, size_t, - uint64_t, uint64_t, uint64_t, uint64_t, unsigned char *, - size_t) = NULL; #else static const long Cryptography_HAS_SCRYPT = 1; #endif diff --git a/src/_cffi_src/openssl/pem.py b/src/_cffi_src/openssl/pem.py index aac77ac71111..07f267199ad8 100644 --- a/src/_cffi_src/openssl/pem.py +++ b/src/_cffi_src/openssl/pem.py @@ -63,12 +63,7 @@ int PEM_write_bio_ECPrivateKey(BIO *, EC_KEY *, const EVP_CIPHER *, unsigned char *, int, pem_password_cb *, void *); -int PEM_write_bio_DHparams(BIO *, DH *); -int PEM_write_bio_DHxparams(BIO *, DH *); """ CUSTOMIZATIONS = """ -#if !defined(EVP_PKEY_DHX) || EVP_PKEY_DHX == -1 -int (*PEM_write_bio_DHxparams)(BIO *, DH *) = NULL; -#endif """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 28f75cb94f88..62b4659c87bf 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1573,26 +1573,14 @@ def load_dh_parameter_numbers( def dh_parameters_supported( self, p: int, g: int, q: typing.Optional[int] = None ) -> bool: - dh_cdata = self._lib.DH_new() - self.openssl_assert(dh_cdata != self._ffi.NULL) - dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) - - p = self._int_to_bn(p) - g = self._int_to_bn(g) - - if q is not None: - q = self._int_to_bn(q) + try: + rust_openssl.dh.from_parameter_numbers( + dh.DHParameterNumbers(p=p, g=g, q=q) + ) + except ValueError: + return False else: - q = self._ffi.NULL - - res = self._lib.DH_set0_pqg(dh_cdata, p, q, g) - self.openssl_assert(res == 1) - - codes = self._ffi.new("int[]", 1) - res = self._lib.DH_check(dh_cdata, codes) - self.openssl_assert(res == 1) - - return codes[0] == 0 + return True def dh_x942_serialization_supported(self) -> bool: return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1 diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 3130edd490ff..c09c9531280b 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -30,17 +30,9 @@ def cryptography_has_tls_st() -> typing.List[str]: ] -def cryptography_has_scrypt() -> typing.List[str]: - return [ - "EVP_PBE_scrypt", - ] - - def cryptography_has_evp_pkey_dhx() -> typing.List[str]: return [ "EVP_PKEY_DHX", - "d2i_DHxparams_bio", - "i2d_DHxparams_bio", ] @@ -279,7 +271,6 @@ def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: "Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb, "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st, "Cryptography_HAS_TLS_ST": cryptography_has_tls_st, - "Cryptography_HAS_SCRYPT": cryptography_has_scrypt, "Cryptography_HAS_EVP_PKEY_DHX": cryptography_has_evp_pkey_dhx, "Cryptography_HAS_MEM_FUNCTIONS": cryptography_has_mem_functions, "Cryptography_HAS_X509_STORE_CTX_GET_ISSUER": ( From 9d06775cb1db57ea4389dfeb95e9657d926cb81b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 26 Apr 2023 09:21:39 -0400 Subject: [PATCH 701/827] Automate the version bump (#8828) --- docs/doing-a-release.rst | 5 ++-- pyproject.toml | 7 +++--- release.py | 47 +++++++++++++++++++++++++++++++++-- src/cryptography/__about__.py | 1 + 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index c1571226e990..48e253ea4960 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -40,8 +40,7 @@ Bumping the version number The next step in doing a release is bumping the version number in the software. -* Update the version number in ``src/cryptography/__about__.py``. -* Update the version number in ``vectors/cryptography_vectors/__about__.py``. +* Run ``python release.py bump-version {new_version}`` * Set the release date in the :doc:`/changelog`. * Do a commit indicating this. * Send a pull request with this. @@ -54,7 +53,7 @@ The commit that merged the version number bump is now the official release commit for this release. You will need to have ``gpg`` installed and a ``gpg`` key in order to do a release. Once this has happened: -* Run ``python release.py {version}``. +* Run ``python release.py release {version}``. The release should now be available on PyPI and a tag should be available in the repository. diff --git a/pyproject.toml b/pyproject.toml index c66e0a38da40..782e6da4f5bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,9 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography" +version = "41.0.0.dev1" + + authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] @@ -45,7 +48,6 @@ dependencies = [ # Must be kept in sync with `build-system.requires` "cffi >=1.12", ] -dynamic = ["version"] [project.urls] homepage = "https://github.com/pyca/cryptography" @@ -62,9 +64,6 @@ package-dir = {"" = "src"} where = ["src"] include = ["cryptography*"] -[tool.setuptools.dynamic] -version = {attr = "cryptography.__version__"} - [project.optional-dependencies] ssh = ["bcrypt >=3.1.5"] diff --git a/release.py b/release.py index 339eb0610a8c..9f41a82ec2e1 100644 --- a/release.py +++ b/release.py @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import pathlib +import re import subprocess import click @@ -12,7 +14,12 @@ def run(*args: str) -> None: subprocess.check_call(list(args)) -@click.command() +@click.group() +def cli(): + pass + + +@cli.command() @click.argument("version") def release(version: str) -> None: """ @@ -23,5 +30,41 @@ def release(version: str) -> None: run("git", "push", "--tags") +def replace_version( + p: pathlib.Path, variable_name: str, new_version: str +) -> None: + with p.open() as f: + content = f.read() + + pattern = rf"^{variable_name}\s*=\s*.*$" + match = re.search(pattern, content, re.MULTILINE) + assert match is not None + + start, end = match.span() + new_content = ( + content[:start] + f'{variable_name} = "{new_version}"' + content[end:] + ) + + # Write back to file + with p.open("w") as f: + f.write(new_content) + + +@cli.command() +@click.argument("new_version") +def bump_version(new_version: str) -> None: + base_dir = pathlib.Path(__file__).parent + + replace_version(base_dir / "pyproject.toml", "version", new_version) + replace_version( + base_dir / "src/cryptography/__about__.py", "__version__", new_version + ) + replace_version( + base_dir / "vectors/cryptography_vectors/__about__.py", + "__version__", + new_version, + ) + + if __name__ == "__main__": - release() + cli() diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 9ab3785b18f7..5a31e0ff9a59 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -12,5 +12,6 @@ __version__ = "41.0.0.dev1" + __author__ = "The Python Cryptographic Authority and individual contributors" __copyright__ = f"Copyright 2013-2023 {__author__}" From 0131d543bd6b8b9b2b724fa177d51f2bd48f57db Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 00:18:10 +0000 Subject: [PATCH 702/827] Bump BoringSSL and/or OpenSSL in CI (#8832) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8835b2144d24..d1e4ee9b2de5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 26, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "d5f3a9e82fc6735eff5733f51b892d776f4a84eb"}} - # Latest commit on the OpenSSL master branch, as of Apr 26, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "fc374a087e7fc5a5bd243ea42ce9879e8432b20e"}} + # Latest commit on the BoringSSL master branch, as of Apr 27, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "a02b7435ca52b81c7cce656d577c8423b1cc4bb3"}} + # Latest commit on the OpenSSL master branch, as of Apr 27, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c48cc764ed57e49456d5b90a7d885e8af196df78"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 95019ef296a82de04b12811a3112afdc7bea9b73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:39:41 +0200 Subject: [PATCH 703/827] Bump requests from 2.28.2 to 2.29.0 (#8836) Bumps [requests](https://github.com/psf/requests) from 2.28.2 to 2.29.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.28.2...v2.29.0) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 12c6805fc382..72953297476f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -125,7 +125,7 @@ pytest-xdist==3.2.1 # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine -requests==2.28.2 +requests==2.29.0 # via # requests-toolbelt # sphinx From 4956f31e2da3fb573e0a7e2b8324df6a55f53b82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:40:54 +0200 Subject: [PATCH 704/827] Bump platformdirs from 3.3.0 to 3.4.0 (#8834) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.3.0...3.4.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 72953297476f..f27c88508aec 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -87,7 +87,7 @@ pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine -platformdirs==3.3.0 +platformdirs==3.4.0 # via # black # virtualenv From a06e52e7d8499857c390629117ba5ff9c6eb9950 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 23:06:58 -0400 Subject: [PATCH 705/827] Bump BoringSSL and/or OpenSSL in CI (#8837) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1e4ee9b2de5..b03206523e4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of Apr 27, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "a02b7435ca52b81c7cce656d577c8423b1cc4bb3"}} - # Latest commit on the OpenSSL master branch, as of Apr 27, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "c48cc764ed57e49456d5b90a7d885e8af196df78"}} + # Latest commit on the OpenSSL master branch, as of Apr 28, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "57582450318e955632d8fb09f42bd90f2ed5d3b4"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From ad4c9031078657dded5bc6e32f110b1f4b993e11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:17:08 +0000 Subject: [PATCH 706/827] Bump virtualenv from 20.22.0 to 20.23.0 (#8838) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.22.0 to 20.23.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.22.0...20.23.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f27c88508aec..7aaf9827353e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -183,7 +183,7 @@ urllib3==1.26.15 # via # requests # twine -virtualenv==20.22.0 +virtualenv==20.23.0 # via nox webencodings==0.5.1 # via bleach From f0bb028b9d86074255f5d4e1305cec45aea1f550 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:17:18 +0000 Subject: [PATCH 707/827] Bump coverage from 7.2.3 to 7.2.4 (#8840) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.3 to 7.2.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.3...7.2.4) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7aaf9827353e..4839099fb4ad 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -29,7 +29,7 @@ click==8.1.3 # via black colorlog==6.7.0 # via nox -coverage==7.2.3 +coverage==7.2.4 # via pytest-cov distlib==0.3.6 # via virtualenv From 752d912298275a7405c9aea9b03d518e0dfb40ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:17:29 +0000 Subject: [PATCH 708/827] Bump platformdirs from 3.4.0 to 3.5.0 (#8839) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.4.0...3.5.0) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4839099fb4ad..16ad28848334 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -87,7 +87,7 @@ pathspec==0.11.1 # via black pkginfo==1.9.6 # via twine -platformdirs==3.4.0 +platformdirs==3.5.0 # via # black # virtualenv From d34d05c2104fc6913f4c58fa2fd52b8ffec0604c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:34:19 +0000 Subject: [PATCH 709/827] Bump rich from 13.3.4 to 13.3.5 (#8841) Bumps [rich](https://github.com/Textualize/rich) from 13.3.4 to 13.3.5. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.4...v13.3.5) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 16ad28848334..4a0b58c320de 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -134,7 +134,7 @@ requests-toolbelt==0.10.1 # via twine rfc3986==2.0.0 # via twine -rich==13.3.4 +rich==13.3.5 # via twine ruff==0.0.263 # via cryptography (pyproject.toml) From a703aaa14576ddd9d07fa0af6abd76b331f54625 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 20:47:19 -0400 Subject: [PATCH 710/827] Bump BoringSSL and/or OpenSSL in CI (#8843) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b03206523e4d..20229b2b1be3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 27, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "a02b7435ca52b81c7cce656d577c8423b1cc4bb3"}} - # Latest commit on the OpenSSL master branch, as of Apr 28, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "57582450318e955632d8fb09f42bd90f2ed5d3b4"}} + # Latest commit on the BoringSSL master branch, as of Apr 29, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "9939e14cffc66f9b9f3374fb52c97bd8bfb0bfbe"}} + # Latest commit on the OpenSSL master branch, as of Apr 29, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "b5a635dc2113e1bc807ea358a670146c813df989"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From ac939ffb493667d00cb5d3f8233234df45f8770c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 29 Apr 2023 15:19:52 +0200 Subject: [PATCH 711/827] move ASN1DHParams to cryptography_x509::common (#8844) --- src/rust/cryptography-x509/src/common.rs | 7 +++++++ src/rust/src/backend/dh.rs | 12 +++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index edae5d4a40bd..122b37b6a7e6 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -123,6 +123,13 @@ pub struct DssSignature<'a> { pub s: asn1::BigUint<'a>, } +#[derive(asn1::Asn1Read, asn1::Asn1Write)] +pub struct DHParams<'a> { + pub p: asn1::BigUint<'a>, + pub g: asn1::BigUint<'a>, + pub q: Option>, +} + #[cfg(test)] mod tests { use super::{Asn1ReadableOrWritable, RawTlv}; diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index 33e94f1c204d..2daff9dcb656 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -6,6 +6,7 @@ use crate::asn1::encode_der_data; use crate::backend::utils; use crate::error::{CryptographyError, CryptographyResult}; use crate::x509; +use cryptography_x509::common; use foreign_types_shared::ForeignTypeRef; const MIN_MODULUS_SIZE: u32 = 512; @@ -62,16 +63,9 @@ fn public_key_from_ptr(ptr: usize) -> DHPublicKey { } } -#[derive(asn1::Asn1Read, asn1::Asn1Write)] -struct ASN1DHParams<'a> { - p: asn1::BigUint<'a>, - g: asn1::BigUint<'a>, - q: Option>, -} - #[pyo3::prelude::pyfunction] fn from_der_parameters(data: &[u8]) -> CryptographyResult { - let asn1_params = asn1::parse_single::>(data)?; + let asn1_params = asn1::parse_single::>(data)?; let p = openssl::bn::BigNum::from_slice(asn1_params.p.as_bytes())?; let q = asn1_params @@ -407,7 +401,7 @@ impl DHParameters { .map(utils::bn_to_big_endian_bytes) .transpose()?; let g_bytes = utils::bn_to_big_endian_bytes(self.dh.generator())?; - let asn1dh_params = ASN1DHParams { + let asn1dh_params = common::DHParams { p: asn1::BigUint::new(&p_bytes).unwrap(), q: q_bytes.as_ref().map(|q| asn1::BigUint::new(q).unwrap()), g: asn1::BigUint::new(&g_bytes).unwrap(), From 828bcf36d624c2de3ed30da9445741c8369d2b7f Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 30 Apr 2023 02:11:30 -0400 Subject: [PATCH 712/827] Remove pointless newlines that snuck in (#8845) --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 782e6da4f5bd..9c01f84e3b5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,8 +12,6 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography" version = "41.0.0.dev1" - - authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] From be18c839856a9b2af4381fef70694d581b1262fb Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 30 Apr 2023 12:14:28 -0400 Subject: [PATCH 713/827] Switch from check-manifest to check-sdist (#8846) The latter will work with non-setuptools build backends. --- ci-constraints-requirements.txt | 9 +++++---- noxfile.py | 2 +- pyproject.toml | 11 ++++++++++- src/_cffi_src/build_openssl.py | 2 +- src/_cffi_src/utils.py | 13 +++++++------ 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 4a0b58c320de..3bae95b92635 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -17,13 +17,13 @@ bleach==6.0.0 # via readme-renderer build==0.10.0 # via - # check-manifest + # check-sdist # cryptography (pyproject.toml) certifi==2022.12.7 # via requests charset-normalizer==3.1.0 # via requests -check-manifest==0.49 +check-sdist==0.1.2 # via cryptography (pyproject.toml) click==8.1.3 # via black @@ -84,7 +84,9 @@ packaging==23.1 # pytest # sphinx pathspec==0.11.1 - # via black + # via + # black + # check-sdist pkginfo==1.9.6 # via twine platformdirs==3.5.0 @@ -193,4 +195,3 @@ zipp==3.15.0 # The following packages are considered to be unsafe in a requirements file: # cffi # pycparser -# setuptools diff --git a/noxfile.py b/noxfile.py index 8f1b94a500fb..8c9cc218b56b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -125,7 +125,7 @@ def flake(session: nox.Session) -> None: session.run("ruff", ".") session.run("black", "--check", ".") - session.run("check-manifest") + session.run("check-sdist") session.run( "mypy", "src/cryptography/", diff --git a/pyproject.toml b/pyproject.toml index 9c01f84e3b5a..6f786bdb7e9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,7 @@ test-randomorder = ["pytest-randomly"] docs = ["sphinx >=5.3.0", "sphinx-rtd-theme >=1.1.1"] docstest = ["pyenchant >=1.6.11", "twine >=1.12.0", "sphinxcontrib-spelling >=4.0.1"] sdist = ["build"] -pep8test = ["black", "ruff", "mypy", "check-manifest"] +pep8test = ["black", "ruff", "mypy", "check-sdist"] [tool.black] line-length = 79 @@ -143,3 +143,12 @@ line-length = 79 [tool.ruff.isort] known-first-party = ["cryptography", "cryptography_vectors", "tests"] + +[tool.check-sdist] +git-only = [ + "vectors/*", + "release.py", + "ci-constraints-requirements.txt", + ".gitattributes", + ".gitignore", +] \ No newline at end of file diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index e199329db606..019789441431 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -54,7 +54,7 @@ ) if __name__ == "__main__": - out_dir = os.getenv("OUT_DIR") + out_dir = os.environ["OUT_DIR"] module_name, source, source_extension, kwds = ffi._assigned_source c_file = os.path.join(out_dir, module_name + source_extension) if platform.python_implementation() == "PyPy": diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index 9eb782686eae..b5fba37091d9 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -7,6 +7,7 @@ import os import platform import sys +import typing from cffi import FFI @@ -18,9 +19,9 @@ def build_ffi_for_binding( - module_name, - module_prefix, - modules, + module_name: str, + module_prefix: str, + modules: typing.List[str], ): """ Modules listed in ``modules`` should have the following attributes: @@ -54,9 +55,9 @@ def build_ffi_for_binding( def build_ffi( - module_name, - cdef_source, - verify_source, + module_name: str, + cdef_source: str, + verify_source: str, ): ffi = FFI() # Always add the CRYPTOGRAPHY_PACKAGE_VERSION to the shared object From e71d269a9a4f5e3859298ba9b9db686f334f2f5a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 30 Apr 2023 16:45:19 -0400 Subject: [PATCH 714/827] Remove manual fix for twisted in CI (#8847) --- .github/downstream.d/twisted.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/downstream.d/twisted.sh b/.github/downstream.d/twisted.sh index f8f294970507..9fc195ba7552 100755 --- a/.github/downstream.d/twisted.sh +++ b/.github/downstream.d/twisted.sh @@ -5,7 +5,7 @@ case "${1}" in git clone --depth=1 https://github.com/twisted/twisted cd twisted git rev-parse HEAD - pip install ".[all_non_platform]" "pyasn1!=0.5.0" + pip install ".[all_non_platform]" ;; run) cd twisted From 11a01d4392fd4dd82fbafd4d11d8178c39bf043b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 02:41:41 +0000 Subject: [PATCH 715/827] Bump coverage from 7.2.4 to 7.2.5 (#8848) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.4 to 7.2.5. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.4...7.2.5) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3bae95b92635..bec914a8c939 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -29,7 +29,7 @@ click==8.1.3 # via black colorlog==6.7.0 # via nox -coverage==7.2.4 +coverage==7.2.5 # via pytest-cov distlib==0.3.6 # via virtualenv From 12e0f0bcc64d31a830c0c158dfe71dbf4df70564 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 11:34:59 +0000 Subject: [PATCH 716/827] Bump requests-toolbelt from 0.10.1 to 1.0.0 (#8851) Bumps [requests-toolbelt](https://github.com/requests/toolbelt) from 0.10.1 to 1.0.0. - [Release notes](https://github.com/requests/toolbelt/releases) - [Changelog](https://github.com/requests/toolbelt/blob/master/HISTORY.rst) - [Commits](https://github.com/requests/toolbelt/compare/0.10.1...1.0.0) --- updated-dependencies: - dependency-name: requests-toolbelt dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index bec914a8c939..f1eb0318d594 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -132,7 +132,7 @@ requests==2.29.0 # requests-toolbelt # sphinx # twine -requests-toolbelt==0.10.1 +requests-toolbelt==1.0.0 # via twine rfc3986==2.0.0 # via twine From ac2060b57174f0791f639aa9bf3f382217239b68 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 00:20:32 +0000 Subject: [PATCH 717/827] Bump BoringSSL and/or OpenSSL in CI (#8852) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20229b2b1be3..0b9658163e06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of Apr 29, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "9939e14cffc66f9b9f3374fb52c97bd8bfb0bfbe"}} - # Latest commit on the OpenSSL master branch, as of Apr 29, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "b5a635dc2113e1bc807ea358a670146c813df989"}} + # Latest commit on the BoringSSL master branch, as of May 02, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "86ada1ea2f51ff41baa2919337e5d721bd27f764"}} + # Latest commit on the OpenSSL master branch, as of May 02, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1009940c14716ac03d5f161bdb4ae626ec6fe729"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 07dc182728f2dc25dc31ff3c1053f5b118ba6ca1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 13:12:55 +0000 Subject: [PATCH 718/827] Bump peter-evans/create-pull-request from 5.0.0 to 5.0.1 (#8856) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/5b4a9f6a9e2af26e5f02351490b90d01eb8ec1e5...284f54f989303d2699d373481a0cfa13ad5a6666) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/boring-open-version-bump.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/boring-open-version-bump.yml b/.github/workflows/boring-open-version-bump.yml index c2625a51b801..0c0036e11cac 100644 --- a/.github/workflows/boring-open-version-bump.yml +++ b/.github/workflows/boring-open-version-bump.yml @@ -58,7 +58,7 @@ jobs: private_key: ${{ secrets.BORINGBOT_PRIVATE_KEY }} if: steps.check-sha-boring.outputs.COMMIT_SHA || steps.check-sha-openssl.outputs.COMMIT_SHA - name: Create Pull Request - uses: peter-evans/create-pull-request@5b4a9f6a9e2af26e5f02351490b90d01eb8ec1e5 + uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666 with: commit-message: "Bump BoringSSL and/or OpenSSL in CI" title: "Bump BoringSSL and/or OpenSSL in CI" From 0c0c3fabf2a2bd66e38d6551e7ea277a1bed69ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 13:28:10 +0000 Subject: [PATCH 719/827] Bump ruff from 0.0.263 to 0.0.264 (#8857) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.263 to 0.0.264. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.263...v0.0.264) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f1eb0318d594..3ea980358c40 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -138,7 +138,7 @@ rfc3986==2.0.0 # via twine rich==13.3.5 # via twine -ruff==0.0.263 +ruff==0.0.264 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From f0f9c9cf6f4f63e295cd86dcd19f7557e8486370 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 2 May 2023 10:09:19 -0400 Subject: [PATCH 720/827] Switch the vectors pacakge to use modern pyproject.toml (#8853) --- .github/workflows/wheel-builder.yml | 2 +- docs/doing-a-release.rst | 5 ++--- release.py | 5 +++++ vectors/pyproject.toml | 22 ++++++++++++++++++++++ vectors/setup.cfg | 18 ------------------ vectors/setup.py | 9 --------- 6 files changed, 30 insertions(+), 31 deletions(-) create mode 100644 vectors/pyproject.toml delete mode 100644 vectors/setup.cfg delete mode 100644 vectors/setup.py diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index c3e145a99a9f..b64828ab61dc 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -17,7 +17,7 @@ on: - .github/workflows/wheel-builder.yml - setup.py - pyproject.toml - - src/cryptography/__about__.py + - vectors/pyproject.toml env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index 48e253ea4960..c7e82ffb4df2 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -86,9 +86,8 @@ Post-release tasks * Close the `milestone`_ for the previous release on GitHub. * For major version releases, send a pull request to pyOpenSSL increasing the maximum ``cryptography`` version pin and perform a pyOpenSSL release. -* Update the version number to the next major (e.g. ``0.5.dev1``) in - ``src/cryptography/__about__.py`` and - ``vectors/cryptography_vectors/__about__.py``. +* Update the version number to the next major (e.g. ``0.5.dev1``) with + ``python release.py bump-version {new_version}``. * Add new :doc:`/changelog` entry with next version and note that it is under active development * Send a pull request with these items diff --git a/release.py b/release.py index 9f41a82ec2e1..b4844a12a5e5 100644 --- a/release.py +++ b/release.py @@ -59,6 +59,11 @@ def bump_version(new_version: str) -> None: replace_version( base_dir / "src/cryptography/__about__.py", "__version__", new_version ) + replace_version( + base_dir / "vectors/pyproject.toml", + "version", + new_version, + ) replace_version( base_dir / "vectors/cryptography_vectors/__about__.py", "__version__", diff --git a/vectors/pyproject.toml b/vectors/pyproject.toml new file mode 100644 index 000000000000..f3da68b11abe --- /dev/null +++ b/vectors/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "cryptography_vectors" +version = "41.0.0.dev1" +authors = [ + {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} +] +description = "Test vectors for the cryptography package." +license = {text = "Apache-2.0 OR BSD-3-Clause"} + +[project.urls] +homepage = "https://github.com/pyca/cryptography" + +[tool.setuptools] +zip-safe = false +include-package-data = true + +[tool.distutils.bdist_wheel] +universal = true diff --git a/vectors/setup.cfg b/vectors/setup.cfg deleted file mode 100644 index 99faeffba83b..000000000000 --- a/vectors/setup.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[metadata] -name = cryptography_vectors -version = attr: cryptography_vectors.__version__ -description = Test vectors for the cryptography package. -license = BSD or Apache License, Version 2.0 -url = https://github.com/pyca/cryptography -author = The Python Cryptographic Authority and individual contributors -author_email = cryptography-dev@python.org - - -[options] -zip_safe = False -include_package_data = True -packages = find: - - -[bdist_wheel] -universal = 1 diff --git a/vectors/setup.py b/vectors/setup.py deleted file mode 100644 index 88d88a75d8b0..000000000000 --- a/vectors/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python - -# 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. - -from setuptools import setup - -setup() From d484a8b1052fc1db920da36129a1de9ac0f9ff09 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 00:20:13 +0000 Subject: [PATCH 721/827] Bump BoringSSL and/or OpenSSL in CI (#8861) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b9658163e06..30acdf8bc338 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 02, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "86ada1ea2f51ff41baa2919337e5d721bd27f764"}} - # Latest commit on the OpenSSL master branch, as of May 02, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1009940c14716ac03d5f161bdb4ae626ec6fe729"}} + # Latest commit on the BoringSSL master branch, as of May 03, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "4c8bcf0da2951cacd8ed8eaa7fd2df4b22fca23b"}} + # Latest commit on the OpenSSL master branch, as of May 03, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "56547da9d3fa24f54b439497d322b12beb004c80"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 8d772f51907af4b00857c3a89ad9e73a2f48ccb4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 13:07:10 +0000 Subject: [PATCH 722/827] Bump pkg-config from 0.3.26 to 0.3.27 in /src/rust (#8862) Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.26 to 0.3.27. - [Release notes](https://github.com/rust-lang/pkg-config-rs/releases) - [Changelog](https://github.com/rust-lang/pkg-config-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/pkg-config-rs/compare/0.3.26...0.3.27) --- updated-dependencies: - dependency-name: pkg-config dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index e63a2e1ef0bf..b2f1b99d7dad 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -255,9 +255,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "proc-macro-error" From bbea31b68d12a3f4cc43b4f6ca9f6fa5ea751d25 Mon Sep 17 00:00:00 2001 From: Harmin Parra Rueda Date: Wed, 3 May 2023 23:34:54 +0200 Subject: [PATCH 723/827] Fix for #8854 (#8855) * Fix for #8854 Fix for issue #8854 * Fix for issue #8854 Fix for issue #8854 * versionadded --------- Co-authored-by: Paul Kehrer --- docs/x509/reference.rst | 6 ++++++ src/cryptography/hazmat/_oid.py | 1 + 2 files changed, 7 insertions(+) diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 2f7040ebfa12..71a6eb1799b5 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -3034,6 +3034,12 @@ instances. The following common OIDs are available as constants. Corresponds to the dotted string ``"2.5.4.12"``. + .. attribute:: INITIALS + + .. versionadded:: 41.0.0 + + Corresponds to the dotted string ``"2.5.4.43"``. + .. attribute:: GENERATION_QUALIFIER Corresponds to the dotted string ``"2.5.4.44"``. diff --git a/src/cryptography/hazmat/_oid.py b/src/cryptography/hazmat/_oid.py index 908f6206db3f..01d4b3406062 100644 --- a/src/cryptography/hazmat/_oid.py +++ b/src/cryptography/hazmat/_oid.py @@ -66,6 +66,7 @@ class NameOID: SURNAME = ObjectIdentifier("2.5.4.4") GIVEN_NAME = ObjectIdentifier("2.5.4.42") TITLE = ObjectIdentifier("2.5.4.12") + INITIALS = ObjectIdentifier("2.5.4.43") GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44") X500_UNIQUE_IDENTIFIER = ObjectIdentifier("2.5.4.45") DN_QUALIFIER = ObjectIdentifier("2.5.4.46") From e72f353cb14be5f6524ea81d7cd300d599df49c5 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 00:16:08 +0000 Subject: [PATCH 724/827] Bump BoringSSL and/or OpenSSL in CI (#8863) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30acdf8bc338..cf907fd1a2f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 03, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "4c8bcf0da2951cacd8ed8eaa7fd2df4b22fca23b"}} - # Latest commit on the OpenSSL master branch, as of May 03, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "56547da9d3fa24f54b439497d322b12beb004c80"}} + # Latest commit on the BoringSSL master branch, as of May 04, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "85e6453cc3b940b2151681f55e698b625be0d723"}} + # Latest commit on the OpenSSL master branch, as of May 04, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "010333be5362a07508888124c83efac35b28760f"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 032845a0d68f670eeb848e8c4f1abf257c6c2106 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 20:56:45 -0400 Subject: [PATCH 725/827] Bump BoringSSL and/or OpenSSL in CI (#8866) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf907fd1a2f8..c27b0c72daaa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 04, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "85e6453cc3b940b2151681f55e698b625be0d723"}} - # Latest commit on the OpenSSL master branch, as of May 04, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "010333be5362a07508888124c83efac35b28760f"}} + # Latest commit on the BoringSSL master branch, as of May 05, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5e988c40553f6afe38971d4a32f5c4b7b48ac972"}} + # Latest commit on the OpenSSL master branch, as of May 05, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "42a6a25ba4ddb40333e92e6e2fc57625d9567090"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From faa09a42ce42dd9943680000b519ccdf253fb8b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 13:09:25 +0000 Subject: [PATCH 726/827] Bump requests from 2.29.0 to 2.30.0 (#8868) Bumps [requests](https://github.com/psf/requests) from 2.29.0 to 2.30.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.29.0...v2.30.0) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 3ea980358c40..7a758256295b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -127,7 +127,7 @@ pytest-xdist==3.2.1 # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine -requests==2.29.0 +requests==2.30.0 # via # requests-toolbelt # sphinx From 947cf632e1502c1f0aa6bd032238f1bef80657ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 13:27:54 +0000 Subject: [PATCH 727/827] Bump urllib3 from 1.26.15 to 2.0.2 (#8869) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.15 to 2.0.2. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.15...2.0.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 7a758256295b..5f6b56b99e90 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -181,7 +181,7 @@ twine==4.0.2 # via cryptography (pyproject.toml) typing-extensions==4.5.0 # via mypy -urllib3==1.26.15 +urllib3==2.0.2 # via # requests # twine From b0dc9b0a09744a52137157b5e7920d88c36bbb5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 16:40:30 +0000 Subject: [PATCH 728/827] Bump asn1 from 0.15.0 to 0.15.1 in /src/rust (#8871) Bumps [asn1](https://github.com/alex/rust-asn1) from 0.15.0 to 0.15.1. - [Commits](https://github.com/alex/rust-asn1/compare/0.15.0...0.15.1) --- updated-dependencies: - dependency-name: asn1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- src/rust/cryptography-x509/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b2f1b99d7dad..cb554bb9763e 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -16,18 +16,18 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "asn1" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa66f5a3e8407b8d3dd8fefc2a62a1aba9539a1d8f856024643c2ae0a8e541ed" +checksum = "de3ffc84e382cf516922078c67853a781fdb4363cf364594df8eab5ef5485553" dependencies = [ "asn1_derive", ] [[package]] name = "asn1_derive" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6365c8b2b1a059ca234d1b69ba501cfa98f1cfd342b95c75611895f1cb0fb81" +checksum = "7124c4d563619518d0ad454032967d5645627033d4b6e4e17bb7ac0237241c81" dependencies = [ "proc-macro2", "quote", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 614bd9967e0a..52e179a4c42e 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" pyo3 = { version = "0.18", features = ["abi3-py37"] } -asn1 = { version = "0.15.0", default-features = false } +asn1 = { version = "0.15.1", default-features = false } cryptography-cffi = { path = "cryptography-cffi" } cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } diff --git a/src/rust/cryptography-x509/Cargo.toml b/src/rust/cryptography-x509/Cargo.toml index 398473471733..8c4d20537435 100644 --- a/src/rust/cryptography-x509/Cargo.toml +++ b/src/rust/cryptography-x509/Cargo.toml @@ -8,4 +8,4 @@ publish = false rust-version = "1.56.0" [dependencies] -asn1 = { version = "0.15.0", default-features = false } +asn1 = { version = "0.15.1", default-features = false } From 8ae2b3fc2d4abd840c0fd7722e5bd01436db8027 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 5 May 2023 13:37:10 -0400 Subject: [PATCH 729/827] Switch AlgorithmIdentifier to use rust-asn1's native defined by support (#8870) --- src/rust/cryptography-x509/src/common.rs | 24 ++++- src/rust/src/pkcs7.rs | 16 +-- src/rust/src/x509/certificate.rs | 6 +- src/rust/src/x509/crl.rs | 6 +- src/rust/src/x509/csr.rs | 6 +- src/rust/src/x509/ocsp.rs | 26 +++-- src/rust/src/x509/ocsp_req.rs | 4 +- src/rust/src/x509/ocsp_resp.rs | 10 +- src/rust/src/x509/sign.rs | 124 +++++++++++++++-------- 9 files changed, 144 insertions(+), 78 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 122b37b6a7e6..7835c3a5a3f3 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -2,12 +2,32 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::oid; +use asn1::Asn1DefinedByWritable; use std::marker::PhantomData; #[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] pub struct AlgorithmIdentifier<'a> { - pub oid: asn1::ObjectIdentifier, - pub params: Option>, + pub oid: asn1::DefinedByMarker, + #[defined_by(oid)] + pub params: AlgorithmParameters<'a>, +} + +impl AlgorithmIdentifier<'_> { + pub fn oid(&self) -> &asn1::ObjectIdentifier { + self.params.item() + } +} + +#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Hash, Clone)] +pub enum AlgorithmParameters<'a> { + #[defined_by(oid::ED25519_OID)] + Ed25519, + #[defined_by(oid::ED448_OID)] + Ed448, + + #[default] + Other(asn1::ObjectIdentifier, Option>), } #[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 236976bf4046..589be56738d5 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -8,7 +8,6 @@ use crate::error::CryptographyResult; use crate::x509; use cryptography_x509::csr::Attribute; use cryptography_x509::{common, oid, pkcs7}; - use once_cell::sync::Lazy; use std::borrow::Cow; use std::collections::HashMap; @@ -181,11 +180,14 @@ fn sign_and_serialize<'p>( }; let digest_alg = common::AlgorithmIdentifier { - oid: x509::ocsp::HASH_NAME_TO_OIDS[py_hash_alg - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - params: Some(*x509::sign::NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + x509::ocsp::HASH_NAME_TO_OIDS[py_hash_alg + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), + Some(*x509::sign::NULL_TLV), + ), }; // Technically O(n^2), but no one will have that many signers. if !digest_algs.contains(&digest_alg) { @@ -252,7 +254,7 @@ fn sign_and_serialize<'p>( if encoding.is(encoding_class.getattr(pyo3::intern!(py, "SMIME"))?) { let mic_algs = digest_algs .iter() - .map(|d| OIDS_TO_MIC_NAME[&d.oid]) + .map(|d| OIDS_TO_MIC_NAME[&d.oid()]) .collect::>() .join(","); let smime_encode = py diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index b8d281014ff6..949c4e10f1ce 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -247,7 +247,7 @@ impl Certificate { Err(_) => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid + self.raw.borrow_value().signature_alg.oid(), )), )), } @@ -255,7 +255,7 @@ impl Certificate { #[getter] fn signature_algorithm_oid<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - oid_to_py_oid(py, &self.raw.borrow_value().signature_alg.oid) + oid_to_py_oid(py, self.raw.borrow_value().signature_alg.oid()) } #[getter] @@ -311,7 +311,7 @@ impl Certificate { sign::verify_signature_with_oid( py, issuer.public_key(py)?, - &self.raw.borrow_value().signature_alg.oid, + self.raw.borrow_value().signature_alg.oid(), self.raw.borrow_value().signature.as_bytes(), &asn1::write_single(&self.raw.borrow_value().tbs_cert)?, ) diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index db4fd0394afd..b6529ebf3cb3 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -184,7 +184,7 @@ impl CertificateRevocationList { #[getter] fn signature_algorithm_oid<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - oid_to_py_oid(py, &self.owned.borrow_value().signature_algorithm.oid) + oid_to_py_oid(py, self.owned.borrow_value().signature_algorithm.oid()) } #[getter] @@ -201,7 +201,7 @@ impl CertificateRevocationList { Ok(v) => Ok(v), Err(_) => Err(exceptions::UnsupportedAlgorithm::new_err(format!( "Signature algorithm OID: {} not recognized", - self.owned.borrow_value().signature_algorithm.oid + self.owned.borrow_value().signature_algorithm.oid(), ))), } } @@ -394,7 +394,7 @@ impl CertificateRevocationList { Ok(sign::verify_signature_with_oid( py, public_key, - &slf.owned.borrow_value().signature_algorithm.oid, + slf.owned.borrow_value().signature_algorithm.oid(), slf.owned.borrow_value().signature_value.as_bytes(), &asn1::write_single(&slf.owned.borrow_value().tbs_cert_list)?, ) diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 2d734681910a..c4a69ebb53f0 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -105,7 +105,7 @@ impl CertificateSigningRequest { Err(_) => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid + self.raw.borrow_value().signature_alg.oid() )), )), } @@ -113,7 +113,7 @@ impl CertificateSigningRequest { #[getter] fn signature_algorithm_oid<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { - oid_to_py_oid(py, &self.raw.borrow_value().signature_alg.oid) + oid_to_py_oid(py, self.raw.borrow_value().signature_alg.oid()) } fn public_bytes<'p>( @@ -235,7 +235,7 @@ impl CertificateSigningRequest { Ok(sign::verify_signature_with_oid( py, slf.public_key(py)?, - &slf.raw.borrow_value().signature_alg.oid, + slf.raw.borrow_value().signature_alg.oid(), slf.raw.borrow_value().signature.as_bytes(), &asn1::write_single(&slf.raw.borrow_value().csr_info)?, ) diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index b362ef326d8d..0ea5555c12f1 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -52,11 +52,14 @@ pub(crate) fn certid_new<'p>( Ok(CertID { hash_algorithm: common::AlgorithmIdentifier { - oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - params: Some(*x509::sign::NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + HASH_NAME_TO_OIDS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), + Some(*x509::sign::NULL_TLV), + ), }, issuer_name_hash, issuer_key_hash, @@ -73,11 +76,14 @@ pub(crate) fn certid_new_from_hash<'p>( ) -> CryptographyResult> { Ok(CertID { hash_algorithm: common::AlgorithmIdentifier { - oid: HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - params: Some(*x509::sign::NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + HASH_NAME_TO_OIDS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), + Some(*x509::sign::NULL_TLV), + ), }, issuer_name_hash, issuer_key_hash, diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 701868e89395..b8faedb09dc2 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -86,12 +86,12 @@ impl OCSPRequest { let cert_id = self.cert_id(); let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid) { + match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid()) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( "Signature algorithm OID: {} not recognized", - cert_id.hash_algorithm.oid + cert_id.hash_algorithm.oid() )), )), } diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 103b610ec51f..15cf99d9fe55 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -168,7 +168,7 @@ impl OCSPResponse { #[getter] fn signature_algorithm_oid<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<&'p pyo3::PyAny> { let resp = self.requires_successful_response()?; - oid_to_py_oid(py, &resp.signature_algorithm.oid) + oid_to_py_oid(py, resp.signature_algorithm.oid()) } #[getter] @@ -185,7 +185,9 @@ impl OCSPResponse { Err(_) => { let exc_messsage = format!( "Signature algorithm OID: {} not recognized", - self.requires_successful_response()?.signature_algorithm.oid + self.requires_successful_response()? + .signature_algorithm + .oid() ); Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(exc_messsage), @@ -477,12 +479,12 @@ fn singleresp_py_hash_algorithm<'p>( py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid) { + match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid()) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( "Signature algorithm OID: {} not recognized", - resp.cert_id.hash_algorithm.oid + resp.cert_id.hash_algorithm.oid() )), )), } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 187dc54db986..c4c01c9737fc 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -138,98 +138,134 @@ pub(crate) fn compute_signature_algorithm<'p>( match (key_type, hash_type) { (KeyType::Ed25519, HashType::None) => Ok(common::AlgorithmIdentifier { - oid: (oid::ED25519_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Ed25519, }), (KeyType::Ed448, HashType::None) => Ok(common::AlgorithmIdentifier { - oid: (oid::ED448_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Ed448, }), (KeyType::Ed25519 | KeyType::Ed448, _) => Err(pyo3::exceptions::PyValueError::new_err( "Algorithm must be None when signing via ed25519 or ed448", )), (KeyType::Ec, HashType::Sha224) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA224_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA224_OID).clone(), None), }), (KeyType::Ec, HashType::Sha256) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA256_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA256_OID).clone(), None), }), (KeyType::Ec, HashType::Sha384) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA384_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA384_OID).clone(), None), }), (KeyType::Ec, HashType::Sha512) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA512_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA512_OID).clone(), None), }), (KeyType::Ec, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA3_224_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::ECDSA_WITH_SHA3_224_OID).clone(), + None, + ), }), (KeyType::Ec, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA3_256_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::ECDSA_WITH_SHA3_256_OID).clone(), + None, + ), }), (KeyType::Ec, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA3_384_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::ECDSA_WITH_SHA3_384_OID).clone(), + None, + ), }), (KeyType::Ec, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { - oid: (oid::ECDSA_WITH_SHA3_512_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::ECDSA_WITH_SHA3_512_OID).clone(), + None, + ), }), (KeyType::Rsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA224_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA224_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA256_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA256_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA384_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA384_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA512_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA512_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA3_224_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA3_224_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA3_256_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA3_256_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA3_384_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA3_384_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Rsa, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { - oid: (oid::RSA_WITH_SHA3_512_OID).clone(), - params: Some(*NULL_TLV), + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other( + (oid::RSA_WITH_SHA3_512_OID).clone(), + Some(*NULL_TLV), + ), }), (KeyType::Dsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { - oid: (oid::DSA_WITH_SHA224_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA224_OID).clone(), None), }), (KeyType::Dsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { - oid: (oid::DSA_WITH_SHA256_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA256_OID).clone(), None), }), (KeyType::Dsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { - oid: (oid::DSA_WITH_SHA384_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA384_OID).clone(), None), }), (KeyType::Dsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { - oid: (oid::DSA_WITH_SHA512_OID).clone(), - params: None, + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA512_OID).clone(), None), }), ( KeyType::Dsa, From 141bcc588098773690c04917da654f1d475c4939 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 5 May 2023 15:57:50 -0400 Subject: [PATCH 730/827] Use defined_by for RSA signature AlgorithmIdentifiers (#8874) I had hoped the parameters would just be Null (no Option<>), but a review of the RFC (3447, 4055) indicates that both should be allowed, though the WebPKI enforces greater constraints. --- src/rust/cryptography-x509/src/common.rs | 18 +++++++++++ src/rust/src/x509/sign.rs | 40 +++++------------------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 7835c3a5a3f3..2a878db23cbf 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -26,6 +26,24 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::ED448_OID)] Ed448, + #[defined_by(oid::RSA_WITH_SHA224_OID)] + RsaWithSha224(Option), + #[defined_by(oid::RSA_WITH_SHA256_OID)] + RsaWithSha256(Option), + #[defined_by(oid::RSA_WITH_SHA384_OID)] + RsaWithSha384(Option), + #[defined_by(oid::RSA_WITH_SHA512_OID)] + RsaWithSha512(Option), + + #[defined_by(oid::RSA_WITH_SHA3_224_OID)] + RsaWithSha3_224(Option), + #[defined_by(oid::RSA_WITH_SHA3_256_OID)] + RsaWithSha3_256(Option), + #[defined_by(oid::RSA_WITH_SHA3_384_OID)] + RsaWithSha3_384(Option), + #[defined_by(oid::RSA_WITH_SHA3_512_OID)] + RsaWithSha3_512(Option), + #[default] Other(asn1::ObjectIdentifier, Option>), } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index c4c01c9737fc..07668621feab 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -196,59 +196,35 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Rsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA224_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha224(Some(())), }), (KeyType::Rsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA256_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha256(Some(())), }), (KeyType::Rsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA384_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha384(Some(())), }), (KeyType::Rsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA512_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha512(Some(())), }), (KeyType::Rsa, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA3_224_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha3_224(Some(())), }), (KeyType::Rsa, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA3_256_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha3_256(Some(())), }), (KeyType::Rsa, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA3_384_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha3_384(Some(())), }), (KeyType::Rsa, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::RSA_WITH_SHA3_512_OID).clone(), - Some(*NULL_TLV), - ), + params: common::AlgorithmParameters::RsaWithSha3_512(Some(())), }), (KeyType::Dsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { From 10688d1ba27e0899812f2eb12be0d8a2a352ba85 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 5 May 2023 16:19:29 -0400 Subject: [PATCH 731/827] Use defined_by for (EC)DSA signature AlgorithmIdentifiers (#8875) Also fix a test that had an incorrect parameters for an OID. The test had deliberately been constructed to be invalid, but in a _different_ respect. --- src/rust/cryptography-x509/src/common.rs | 27 +++++++++++++ src/rust/src/x509/sign.rs | 36 ++++++------------ .../mismatch_inner_outer_sig_algorithm.der | Bin 1473 -> 1471 bytes 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 2a878db23cbf..4dd83d926e61 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -26,6 +26,24 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::ED448_OID)] Ed448, + #[defined_by(oid::ECDSA_WITH_SHA224_OID)] + EcDsaWithSha224, + #[defined_by(oid::ECDSA_WITH_SHA256_OID)] + EcDsaWithSha256, + #[defined_by(oid::ECDSA_WITH_SHA384_OID)] + EcDsaWithSha384, + #[defined_by(oid::ECDSA_WITH_SHA512_OID)] + EcDsaWithSha512, + + #[defined_by(oid::ECDSA_WITH_SHA3_224_OID)] + EcDsaWithSha3_224, + #[defined_by(oid::ECDSA_WITH_SHA3_256_OID)] + EcDsaWithSha3_256, + #[defined_by(oid::ECDSA_WITH_SHA3_384_OID)] + EcDsaWithSha3_384, + #[defined_by(oid::ECDSA_WITH_SHA3_512_OID)] + EcDsaWithSha3_512, + #[defined_by(oid::RSA_WITH_SHA224_OID)] RsaWithSha224(Option), #[defined_by(oid::RSA_WITH_SHA256_OID)] @@ -44,6 +62,15 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::RSA_WITH_SHA3_512_OID)] RsaWithSha3_512(Option), + #[defined_by(oid::DSA_WITH_SHA224_OID)] + DsaWithSha224, + #[defined_by(oid::DSA_WITH_SHA256_OID)] + DsaWithSha256, + #[defined_by(oid::DSA_WITH_SHA384_OID)] + DsaWithSha384, + #[defined_by(oid::DSA_WITH_SHA512_OID)] + DsaWithSha512, + #[default] Other(asn1::ObjectIdentifier, Option>), } diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 07668621feab..d30a270643c2 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -151,47 +151,35 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Ec, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA224_OID).clone(), None), + params: common::AlgorithmParameters::EcDsaWithSha224, }), (KeyType::Ec, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA256_OID).clone(), None), + params: common::AlgorithmParameters::EcDsaWithSha256, }), (KeyType::Ec, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA384_OID).clone(), None), + params: common::AlgorithmParameters::EcDsaWithSha384, }), (KeyType::Ec, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::ECDSA_WITH_SHA512_OID).clone(), None), + params: common::AlgorithmParameters::EcDsaWithSha512, }), (KeyType::Ec, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::ECDSA_WITH_SHA3_224_OID).clone(), - None, - ), + params: common::AlgorithmParameters::EcDsaWithSha3_224, }), (KeyType::Ec, HashType::Sha3_256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::ECDSA_WITH_SHA3_256_OID).clone(), - None, - ), + params: common::AlgorithmParameters::EcDsaWithSha3_256, }), (KeyType::Ec, HashType::Sha3_384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::ECDSA_WITH_SHA3_384_OID).clone(), - None, - ), + params: common::AlgorithmParameters::EcDsaWithSha3_384, }), (KeyType::Ec, HashType::Sha3_512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - (oid::ECDSA_WITH_SHA3_512_OID).clone(), - None, - ), + params: common::AlgorithmParameters::EcDsaWithSha3_512, }), (KeyType::Rsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { @@ -229,19 +217,19 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Dsa, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA224_OID).clone(), None), + params: common::AlgorithmParameters::DsaWithSha224, }), (KeyType::Dsa, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA256_OID).clone(), None), + params: common::AlgorithmParameters::DsaWithSha256, }), (KeyType::Dsa, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA384_OID).clone(), None), + params: common::AlgorithmParameters::DsaWithSha384, }), (KeyType::Dsa, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other((oid::DSA_WITH_SHA512_OID).clone(), None), + params: common::AlgorithmParameters::DsaWithSha512, }), ( KeyType::Dsa, diff --git a/vectors/cryptography_vectors/x509/custom/mismatch_inner_outer_sig_algorithm.der b/vectors/cryptography_vectors/x509/custom/mismatch_inner_outer_sig_algorithm.der index ff4e7fb557e59043edc751aedd92dc1fe5438a0f..bf7a473f31d7eb53881321d1fd9aaa6097d31c4e 100644 GIT binary patch delta 39 vcmX@ey`Njopow+2K@-d31t*7 From 4da2e580a9cb6544cdaf32787677f16513bb6f6d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 5 May 2023 17:25:04 -0400 Subject: [PATCH 732/827] Use defined_by for hash AlgorithmIdentifiers (#8876) --- src/rust/cryptography-x509/src/common.rs | 11 ++++ src/rust/src/pkcs7.rs | 14 ++--- src/rust/src/x509/ocsp.rs | 79 +++++++++++++++--------- src/rust/src/x509/sign.rs | 9 --- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 4dd83d926e61..f44308a8579e 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -21,6 +21,17 @@ impl AlgorithmIdentifier<'_> { #[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Hash, Clone)] pub enum AlgorithmParameters<'a> { + #[defined_by(oid::SHA1_OID)] + Sha1(asn1::Null), + #[defined_by(oid::SHA224_OID)] + Sha224(asn1::Null), + #[defined_by(oid::SHA256_OID)] + Sha256(asn1::Null), + #[defined_by(oid::SHA384_OID)] + Sha384(asn1::Null), + #[defined_by(oid::SHA512_OID)] + Sha512(asn1::Null), + #[defined_by(oid::ED25519_OID)] Ed25519, #[defined_by(oid::ED448_OID)] diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 589be56738d5..6bc90173fade 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -179,16 +179,10 @@ fn sign_and_serialize<'p>( ) }; - let digest_alg = common::AlgorithmIdentifier { - oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - x509::ocsp::HASH_NAME_TO_OIDS[py_hash_alg - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - Some(*x509::sign::NULL_TLV), - ), - }; + let digest_alg = x509::ocsp::HASH_NAME_TO_ALGORITHM_IDENTIFIERS[py_hash_alg + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(); // Technically O(n^2), but no one will have that many signers. if !digest_algs.contains(&digest_alg) { digest_algs.push(digest_alg.clone()); diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index 0ea5555c12f1..53a0f2c4ed8b 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -19,16 +19,47 @@ pub(crate) static OIDS_TO_HASH: Lazy> = L h.insert(&oid::SHA512_OID, "SHA512"); h }); -pub(crate) static HASH_NAME_TO_OIDS: Lazy> = - Lazy::new(|| { - let mut h = HashMap::new(); - h.insert("sha1", &oid::SHA1_OID); - h.insert("sha224", &oid::SHA224_OID); - h.insert("sha256", &oid::SHA256_OID); - h.insert("sha384", &oid::SHA384_OID); - h.insert("sha512", &oid::SHA512_OID); - h - }); +pub(crate) static HASH_NAME_TO_ALGORITHM_IDENTIFIERS: Lazy< + HashMap<&str, common::AlgorithmIdentifier<'_>>, +> = Lazy::new(|| { + let mut h = HashMap::new(); + h.insert( + "sha1", + common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Sha1(()), + }, + ); + h.insert( + "sha224", + common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Sha224(()), + }, + ); + h.insert( + "sha256", + common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Sha256(()), + }, + ); + h.insert( + "sha384", + common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Sha384(()), + }, + ); + h.insert( + "sha512", + common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: common::AlgorithmParameters::Sha512(()), + }, + ); + h +}); pub(crate) fn certid_new<'p>( py: pyo3::Python<'p>, @@ -51,16 +82,10 @@ pub(crate) fn certid_new<'p>( )?; Ok(CertID { - hash_algorithm: common::AlgorithmIdentifier { - oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - Some(*x509::sign::NULL_TLV), - ), - }, + hash_algorithm: x509::ocsp::HASH_NAME_TO_ALGORITHM_IDENTIFIERS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), issuer_name_hash, issuer_key_hash, serial_number: cert.raw.borrow_value_public().tbs_cert.serial, @@ -75,16 +100,10 @@ pub(crate) fn certid_new_from_hash<'p>( hash_algorithm: &'p pyo3::PyAny, ) -> CryptographyResult> { Ok(CertID { - hash_algorithm: common::AlgorithmIdentifier { - oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Other( - HASH_NAME_TO_OIDS[hash_algorithm - .getattr(pyo3::intern!(py, "name"))? - .extract::<&str>()?] - .clone(), - Some(*x509::sign::NULL_TLV), - ), - }, + hash_algorithm: x509::ocsp::HASH_NAME_TO_ALGORITHM_IDENTIFIERS[hash_algorithm + .getattr(pyo3::intern!(py, "name"))? + .extract::<&str>()?] + .clone(), issuer_name_hash, issuer_key_hash, serial_number, diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index d30a270643c2..c2dc3e651755 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -6,15 +6,6 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::exceptions; use cryptography_x509::{common, oid}; -use once_cell::sync::Lazy; - -static NULL_DER: Lazy> = Lazy::new(|| { - // TODO: kind of verbose way to say "\x05\x00". - asn1::write_single(&()).unwrap() -}); -pub(crate) static NULL_TLV: Lazy> = - Lazy::new(|| asn1::parse_single(&NULL_DER).unwrap()); - #[derive(Debug, PartialEq)] pub(crate) enum KeyType { Rsa, From 0e5e0030abebc6656629fea6bb9ac10ff8cb8295 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 19:33:15 -0500 Subject: [PATCH 733/827] Bump BoringSSL and/or OpenSSL in CI (#8877) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c27b0c72daaa..9a97b41f1d49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 05, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5e988c40553f6afe38971d4a32f5c4b7b48ac972"}} - # Latest commit on the OpenSSL master branch, as of May 05, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "42a6a25ba4ddb40333e92e6e2fc57625d9567090"}} + # Latest commit on the BoringSSL master branch, as of May 06, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b1c6f45f1fe6d808555d04a41bb44b322e4f4c1d"}} + # Latest commit on the OpenSSL master branch, as of May 06, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "6aeb42eca97227c8235af0986d1525ee4a916504"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 1f67bb4266ff192fb04602e0d9b8bed1a9dac9e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 13:42:53 +0000 Subject: [PATCH 734/827] Bump ruff from 0.0.264 to 0.0.265 (#8879) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.264 to 0.0.265. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.264...v0.0.265) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5f6b56b99e90..38ba5288477f 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -138,7 +138,7 @@ rfc3986==2.0.0 # via twine rich==13.3.5 # via twine -ruff==0.0.264 +ruff==0.0.265 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From 4a3c4407e42f13c6d08ad6863c10962f3f52b230 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 6 May 2023 08:51:03 -0500 Subject: [PATCH 735/827] Check for sigalg by type rather than OID (#8878) --- src/rust/src/x509/certificate.rs | 2 +- src/rust/src/x509/crl.rs | 2 +- src/rust/src/x509/csr.rs | 2 +- src/rust/src/x509/sign.rs | 179 +++++++++++++++++++++---------- 4 files changed, 128 insertions(+), 57 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 949c4e10f1ce..58dcf2d5d3f2 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -311,7 +311,7 @@ impl Certificate { sign::verify_signature_with_oid( py, issuer.public_key(py)?, - self.raw.borrow_value().signature_alg.oid(), + &self.raw.borrow_value().signature_alg, self.raw.borrow_value().signature.as_bytes(), &asn1::write_single(&self.raw.borrow_value().tbs_cert)?, ) diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index b6529ebf3cb3..e2c4b9c09b9e 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -394,7 +394,7 @@ impl CertificateRevocationList { Ok(sign::verify_signature_with_oid( py, public_key, - slf.owned.borrow_value().signature_algorithm.oid(), + &slf.owned.borrow_value().signature_algorithm, slf.owned.borrow_value().signature_value.as_bytes(), &asn1::write_single(&slf.owned.borrow_value().tbs_cert_list)?, ) diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index c4a69ebb53f0..35aee5c9e501 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -235,7 +235,7 @@ impl CertificateSigningRequest { Ok(sign::verify_signature_with_oid( py, slf.public_key(py)?, - slf.raw.borrow_value().signature_alg.oid(), + &slf.raw.borrow_value().signature_alg, slf.raw.borrow_value().signature.as_bytes(), &asn1::write_single(&slf.raw.borrow_value().csr_info)?, ) diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index c2dc3e651755..5c69ecedf4fe 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -4,7 +4,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::exceptions; -use cryptography_x509::{common, oid}; +use cryptography_x509::common; #[derive(Debug, PartialEq)] pub(crate) enum KeyType { @@ -290,12 +290,13 @@ fn py_hash_name_from_hash_type(hash_type: HashType) -> Option<&'static str> { pub(crate) fn verify_signature_with_oid<'p>( py: pyo3::Python<'p>, issuer_public_key: &'p pyo3::PyAny, - signature_oid: &asn1::ObjectIdentifier, + signature_algorithm: &common::AlgorithmIdentifier<'_>, signature: &[u8], data: &[u8], ) -> CryptographyResult<()> { let key_type = identify_public_key_type(py, issuer_public_key)?; - let (sig_key_type, sig_hash_type) = identify_key_hash_type_for_oid(signature_oid)?; + let (sig_key_type, sig_hash_type) = + identify_key_hash_type_for_algorithm_params(&signature_algorithm.params)?; if key_type != sig_key_type { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( @@ -402,32 +403,32 @@ pub(crate) fn identify_public_key_type( } } -fn identify_key_hash_type_for_oid( - oid: &asn1::ObjectIdentifier, +fn identify_key_hash_type_for_algorithm_params( + params: &common::AlgorithmParameters<'_>, ) -> pyo3::PyResult<(KeyType, HashType)> { - match *oid { - oid::RSA_WITH_SHA224_OID => Ok((KeyType::Rsa, HashType::Sha224)), - oid::RSA_WITH_SHA256_OID => Ok((KeyType::Rsa, HashType::Sha256)), - oid::RSA_WITH_SHA384_OID => Ok((KeyType::Rsa, HashType::Sha384)), - oid::RSA_WITH_SHA512_OID => Ok((KeyType::Rsa, HashType::Sha512)), - oid::RSA_WITH_SHA3_224_OID => Ok((KeyType::Rsa, HashType::Sha3_224)), - oid::RSA_WITH_SHA3_256_OID => Ok((KeyType::Rsa, HashType::Sha3_256)), - oid::RSA_WITH_SHA3_384_OID => Ok((KeyType::Rsa, HashType::Sha3_384)), - oid::RSA_WITH_SHA3_512_OID => Ok((KeyType::Rsa, HashType::Sha3_512)), - oid::ECDSA_WITH_SHA224_OID => Ok((KeyType::Ec, HashType::Sha224)), - oid::ECDSA_WITH_SHA256_OID => Ok((KeyType::Ec, HashType::Sha256)), - oid::ECDSA_WITH_SHA384_OID => Ok((KeyType::Ec, HashType::Sha384)), - oid::ECDSA_WITH_SHA512_OID => Ok((KeyType::Ec, HashType::Sha512)), - oid::ECDSA_WITH_SHA3_224_OID => Ok((KeyType::Ec, HashType::Sha3_224)), - oid::ECDSA_WITH_SHA3_256_OID => Ok((KeyType::Ec, HashType::Sha3_256)), - oid::ECDSA_WITH_SHA3_384_OID => Ok((KeyType::Ec, HashType::Sha3_384)), - oid::ECDSA_WITH_SHA3_512_OID => Ok((KeyType::Ec, HashType::Sha3_512)), - oid::ED25519_OID => Ok((KeyType::Ed25519, HashType::None)), - oid::ED448_OID => Ok((KeyType::Ed448, HashType::None)), - oid::DSA_WITH_SHA224_OID => Ok((KeyType::Dsa, HashType::Sha224)), - oid::DSA_WITH_SHA256_OID => Ok((KeyType::Dsa, HashType::Sha256)), - oid::DSA_WITH_SHA384_OID => Ok((KeyType::Dsa, HashType::Sha384)), - oid::DSA_WITH_SHA512_OID => Ok((KeyType::Dsa, HashType::Sha512)), + match params { + common::AlgorithmParameters::RsaWithSha224(..) => Ok((KeyType::Rsa, HashType::Sha224)), + common::AlgorithmParameters::RsaWithSha256(..) => Ok((KeyType::Rsa, HashType::Sha256)), + common::AlgorithmParameters::RsaWithSha384(..) => Ok((KeyType::Rsa, HashType::Sha384)), + common::AlgorithmParameters::RsaWithSha512(..) => Ok((KeyType::Rsa, HashType::Sha512)), + common::AlgorithmParameters::RsaWithSha3_224(..) => Ok((KeyType::Rsa, HashType::Sha3_224)), + common::AlgorithmParameters::RsaWithSha3_256(..) => Ok((KeyType::Rsa, HashType::Sha3_256)), + common::AlgorithmParameters::RsaWithSha3_384(..) => Ok((KeyType::Rsa, HashType::Sha3_384)), + common::AlgorithmParameters::RsaWithSha3_512(..) => Ok((KeyType::Rsa, HashType::Sha3_512)), + common::AlgorithmParameters::EcDsaWithSha224 => Ok((KeyType::Ec, HashType::Sha224)), + common::AlgorithmParameters::EcDsaWithSha256 => Ok((KeyType::Ec, HashType::Sha256)), + common::AlgorithmParameters::EcDsaWithSha384 => Ok((KeyType::Ec, HashType::Sha384)), + common::AlgorithmParameters::EcDsaWithSha512 => Ok((KeyType::Ec, HashType::Sha512)), + common::AlgorithmParameters::EcDsaWithSha3_224 => Ok((KeyType::Ec, HashType::Sha3_224)), + common::AlgorithmParameters::EcDsaWithSha3_256 => Ok((KeyType::Ec, HashType::Sha3_256)), + common::AlgorithmParameters::EcDsaWithSha3_384 => Ok((KeyType::Ec, HashType::Sha3_384)), + common::AlgorithmParameters::EcDsaWithSha3_512 => Ok((KeyType::Ec, HashType::Sha3_512)), + common::AlgorithmParameters::Ed25519 => Ok((KeyType::Ed25519, HashType::None)), + common::AlgorithmParameters::Ed448 => Ok((KeyType::Ed448, HashType::None)), + common::AlgorithmParameters::DsaWithSha224 => Ok((KeyType::Dsa, HashType::Sha224)), + common::AlgorithmParameters::DsaWithSha256 => Ok((KeyType::Dsa, HashType::Sha256)), + common::AlgorithmParameters::DsaWithSha384 => Ok((KeyType::Dsa, HashType::Sha384)), + common::AlgorithmParameters::DsaWithSha512 => Ok((KeyType::Dsa, HashType::Sha512)), _ => Err(pyo3::exceptions::PyValueError::new_err( "Unsupported signature algorithm", )), @@ -436,100 +437,170 @@ fn identify_key_hash_type_for_oid( #[cfg(test)] mod tests { - use super::{identify_key_hash_type_for_oid, py_hash_name_from_hash_type, HashType, KeyType}; - use cryptography_x509::oid; + use super::{ + identify_key_hash_type_for_algorithm_params, py_hash_name_from_hash_type, HashType, KeyType, + }; + use cryptography_x509::{common, oid}; #[test] - fn test_identify_key_hash_type_for_oid() { + fn test_identify_key_hash_type_for_algorithm_params() { assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA224_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha224(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha224) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA256_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha256(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha256) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA384_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha384(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha384) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA512_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha512(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha512) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_224_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha3_224(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha3_224) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_256_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha3_256(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha3_256) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_384_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha3_384(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha3_384) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::RSA_WITH_SHA3_512_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::RsaWithSha3_512(Some(())) + ) + .unwrap(), (KeyType::Rsa, HashType::Sha3_512) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA224_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha224 + ) + .unwrap(), (KeyType::Ec, HashType::Sha224) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA256_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha256 + ) + .unwrap(), (KeyType::Ec, HashType::Sha256) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA384_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha384 + ) + .unwrap(), (KeyType::Ec, HashType::Sha384) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA512_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha512 + ) + .unwrap(), (KeyType::Ec, HashType::Sha512) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_224_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha3_224 + ) + .unwrap(), (KeyType::Ec, HashType::Sha3_224) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_256_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha3_256 + ) + .unwrap(), (KeyType::Ec, HashType::Sha3_256) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_384_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha3_384 + ) + .unwrap(), (KeyType::Ec, HashType::Sha3_384) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ECDSA_WITH_SHA3_512_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::EcDsaWithSha3_512 + ) + .unwrap(), (KeyType::Ec, HashType::Sha3_512) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ED25519_OID).unwrap(), + identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Ed25519) + .unwrap(), (KeyType::Ed25519, HashType::None) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::ED448_OID).unwrap(), + identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Ed448) + .unwrap(), (KeyType::Ed448, HashType::None) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA224_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::DsaWithSha224 + ) + .unwrap(), (KeyType::Dsa, HashType::Sha224) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA256_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::DsaWithSha256 + ) + .unwrap(), (KeyType::Dsa, HashType::Sha256) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA384_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::DsaWithSha384 + ) + .unwrap(), (KeyType::Dsa, HashType::Sha384) ); assert_eq!( - identify_key_hash_type_for_oid(&oid::DSA_WITH_SHA512_OID).unwrap(), + identify_key_hash_type_for_algorithm_params( + &common::AlgorithmParameters::DsaWithSha512 + ) + .unwrap(), (KeyType::Dsa, HashType::Sha512) ); - assert!(identify_key_hash_type_for_oid(&oid::TLS_FEATURE_OID).is_err()); + assert!( + identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Other( + oid::TLS_FEATURE_OID, + None + )) + .is_err() + ); } #[test] From d60796a38fe7b08b84e62203e91945c87b6d1a8e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 7 May 2023 08:27:29 -0500 Subject: [PATCH 736/827] Use parameters instead of oids in another place (#8880) --- src/rust/cryptography-x509/src/common.rs | 2 +- src/rust/src/x509/ocsp.rs | 17 ++++++++++------- src/rust/src/x509/ocsp_req.rs | 2 +- src/rust/src/x509/ocsp_resp.rs | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index f44308a8579e..65e583f113a2 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -19,7 +19,7 @@ impl AlgorithmIdentifier<'_> { } } -#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Hash, Clone)] +#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Eq, Hash, Clone)] pub enum AlgorithmParameters<'a> { #[defined_by(oid::SHA1_OID)] Sha1(asn1::Null), diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index 53a0f2c4ed8b..afa0b026ed1e 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -5,20 +5,23 @@ use crate::error::CryptographyResult; use crate::x509; use crate::x509::certificate::Certificate; +use cryptography_x509::common; use cryptography_x509::ocsp_req::CertID; -use cryptography_x509::{common, oid}; use once_cell::sync::Lazy; use std::collections::HashMap; -pub(crate) static OIDS_TO_HASH: Lazy> = Lazy::new(|| { +pub(crate) static ALGORITHM_PARAMETERS_TO_HASH: Lazy< + HashMap, &str>, +> = Lazy::new(|| { let mut h = HashMap::new(); - h.insert(&oid::SHA1_OID, "SHA1"); - h.insert(&oid::SHA224_OID, "SHA224"); - h.insert(&oid::SHA256_OID, "SHA256"); - h.insert(&oid::SHA384_OID, "SHA384"); - h.insert(&oid::SHA512_OID, "SHA512"); + h.insert(common::AlgorithmParameters::Sha1(()), "SHA1"); + h.insert(common::AlgorithmParameters::Sha224(()), "SHA224"); + h.insert(common::AlgorithmParameters::Sha256(()), "SHA256"); + h.insert(common::AlgorithmParameters::Sha384(()), "SHA384"); + h.insert(common::AlgorithmParameters::Sha512(()), "SHA512"); h }); + pub(crate) static HASH_NAME_TO_ALGORITHM_IDENTIFIERS: Lazy< HashMap<&str, common::AlgorithmIdentifier<'_>>, > = Lazy::new(|| { diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index b8faedb09dc2..235ac6ee10c5 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -86,7 +86,7 @@ impl OCSPRequest { let cert_id = self.cert_id(); let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid()) { + match ocsp::ALGORITHM_PARAMETERS_TO_HASH.get(&cert_id.hash_algorithm.params) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 15cf99d9fe55..942822b48168 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -479,7 +479,7 @@ fn singleresp_py_hash_algorithm<'p>( py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid()) { + match ocsp::ALGORITHM_PARAMETERS_TO_HASH.get(&resp.cert_id.hash_algorithm.params) { Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), None => Err(CryptographyError::from( exceptions::UnsupportedAlgorithm::new_err(format!( From b284ff959183aeaa8f986700ef119d0f08dd6af0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 May 2023 14:12:35 +0000 Subject: [PATCH 737/827] Bump certifi from 2022.12.7 to 2023.5.7 (#8881) Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.12.7 to 2023.5.7. - [Commits](https://github.com/certifi/python-certifi/compare/2022.12.07...2023.05.07) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 38ba5288477f..12b2f942e703 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -19,7 +19,7 @@ build==0.10.0 # via # check-sdist # cryptography (pyproject.toml) -certifi==2022.12.7 +certifi==2023.5.7 # via requests charset-normalizer==3.1.0 # via requests From 47b5ea6a9a914585a52bebe3d1e6be328a551734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 May 2023 14:18:52 +0000 Subject: [PATCH 738/827] Bump libc from 0.2.142 to 0.2.143 in /src/rust (#8882) Bumps [libc](https://github.com/rust-lang/libc) from 0.2.142 to 0.2.143. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.142...0.2.143) --- updated-dependencies: - dependency-name: libc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index cb554bb9763e..c7e79503c469 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -131,9 +131,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" [[package]] name = "lock_api" From 8ab4d1a58e6128f8c32981ee3f667e89d09c758b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 7 May 2023 09:58:41 -0500 Subject: [PATCH 739/827] Try using the default LTO (#8883) --- src/rust/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 52e179a4c42e..d221cb17a9b9 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -32,7 +32,6 @@ name = "cryptography_rust" crate-type = ["cdylib"] [profile.release] -lto = "thin" overflow-checks = true [workspace] From 0f2b72bb12b698e5787241a54ea9132837a1ec9c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 7 May 2023 11:01:33 -0500 Subject: [PATCH 740/827] invalid visible string support (#8884) * invalid visible string support this allows utf8 in visiblestring, which is not valid DER. we raise a warning when this happens, but allow it since belgian eIDs, among others, have encoding errors. Belgium fixed this by 2021 (and possibly earlier), but their eID certificates have 10 year validity. * review comments * clippy --- docs/development/test-vectors.rst | 2 + src/cryptography/utils.py | 1 + src/rust/cryptography-x509/src/common.rs | 37 ++++++++++++++++++- src/rust/cryptography-x509/src/extensions.rs | 3 +- src/rust/src/x509/certificate.rs | 11 ++++++ tests/x509/test_x509.py | 19 ++++++++++ .../belgian-eid-invalid-visiblestring.pem | 37 +++++++++++++++++++ 7 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 vectors/cryptography_vectors/x509/belgian-eid-invalid-visiblestring.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 1916c57c4098..c84bdeff49fb 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -287,6 +287,8 @@ X.509 a subject DN with a bit string type. * ``cryptography-scts-tbs-precert.der`` - The "to-be-signed" pre-certificate bytes from ``cryptography-scts.pem``, with the SCT list extension removed. +* ``belgian-eid-invalid-visiblestring.pem`` - A certificate with UTF-8 + bytes in a ``VisibleString`` type. Custom X.509 Vectors ~~~~~~~~~~~~~~~~~~~~ diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 651e8509acf4..719168168440 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -23,6 +23,7 @@ class CryptographyDeprecationWarning(UserWarning): DeprecatedIn36 = CryptographyDeprecationWarning DeprecatedIn37 = CryptographyDeprecationWarning DeprecatedIn40 = CryptographyDeprecationWarning +DeprecatedIn41 = CryptographyDeprecationWarning def _check_bytes(name: str, value: bytes) -> None: diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 65e583f113a2..9668ae237703 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -206,11 +206,46 @@ pub struct DHParams<'a> { pub q: Option>, } +/// A VisibleString ASN.1 element whose contents is not validated as meeting the +/// requirements (visible characters of IA5), and instead is only known to be +/// valid UTF-8. +pub struct UnvalidatedVisibleString<'a>(pub &'a str); + +impl<'a> UnvalidatedVisibleString<'a> { + pub fn as_str(&self) -> &'a str { + self.0 + } +} + +impl<'a> asn1::SimpleAsn1Readable<'a> for UnvalidatedVisibleString<'a> { + const TAG: asn1::Tag = asn1::VisibleString::TAG; + fn parse_data(data: &'a [u8]) -> asn1::ParseResult { + Ok(UnvalidatedVisibleString( + std::str::from_utf8(data) + .map_err(|_| asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue))?, + )) + } +} + +impl<'a> asn1::SimpleAsn1Writable for UnvalidatedVisibleString<'a> { + const TAG: asn1::Tag = asn1::VisibleString::TAG; + fn write_data(&self, _: &mut asn1::WriteBuf) -> asn1::WriteResult { + unimplemented!(); + } +} + #[cfg(test)] mod tests { - use super::{Asn1ReadableOrWritable, RawTlv}; + use super::{Asn1ReadableOrWritable, RawTlv, UnvalidatedVisibleString}; use asn1::Asn1Readable; + #[test] + #[should_panic] + fn test_unvalidated_visible_string_write() { + let v = UnvalidatedVisibleString("foo"); + asn1::write_single(&v).unwrap(); + } + #[test] #[should_panic] fn test_asn1_readable_or_writable_unwrap_read() { diff --git a/src/rust/cryptography-x509/src/extensions.rs b/src/rust/cryptography-x509/src/extensions.rs index 11c6e54a4d34..0728633d4adb 100644 --- a/src/rust/cryptography-x509/src/extensions.rs +++ b/src/rust/cryptography-x509/src/extensions.rs @@ -87,7 +87,8 @@ pub struct NoticeReference<'a> { pub enum DisplayText<'a> { IA5String(asn1::IA5String<'a>), Utf8String(asn1::Utf8String<'a>), - VisibleString(asn1::VisibleString<'a>), + // Not validated due to certificates with UTF-8 in VisibleString. See PR #8884 + VisibleString(common::UnvalidatedVisibleString<'a>), BmpString(asn1::BMPString<'a>), } diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 58dcf2d5d3f2..98f1a073fef7 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -412,6 +412,17 @@ fn parse_display_text( DisplayText::IA5String(o) => Ok(pyo3::types::PyString::new(py, o.as_str()).to_object(py)), DisplayText::Utf8String(o) => Ok(pyo3::types::PyString::new(py, o.as_str()).to_object(py)), DisplayText::VisibleString(o) => { + if asn1::VisibleString::new(o.as_str()).is_none() { + let cryptography_warning = py + .import(pyo3::intern!(py, "cryptography.utils"))? + .getattr(pyo3::intern!(py, "DeprecatedIn41"))?; + pyo3::PyErr::warn( + py, + cryptography_warning, + "Invalid ASN.1 (UTF-8 characters in a VisibleString) in the explicit text and/or notice reference of the certificate policies extension. In a future version of cryptography, an exception will be raised.", + 1, + )?; + } Ok(pyo3::types::PyString::new(py, o.as_str()).to_object(py)) } DisplayText::BmpString(o) => { diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 4a3fb26c63ad..1de45192b550 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -1250,6 +1250,25 @@ def test_invalid_version_cert(self, backend): assert exc.value.parsed_version == 7 + def test_invalid_visiblestring_in_explicit_text(self, backend): + cert = _load_cert( + os.path.join( + "x509", + "belgian-eid-invalid-visiblestring.pem", + ), + x509.load_pem_x509_certificate, + ) + with pytest.warns(utils.DeprecatedIn41): + cp = cert.extensions.get_extension_for_class( + x509.CertificatePolicies + ).value + assert isinstance(cp, x509.CertificatePolicies) + assert cp[0].policy_qualifiers[1].explicit_text == ( + "Gebruik onderworpen aan aansprakelijkheidsbeperkingen, zie CPS " + "- Usage soumis à des limitations de responsabilité, voir CPS - " + "Verwendung unterliegt Haftungsbeschränkungen, gemäss CPS" + ) + def test_eq(self, backend): cert = _load_cert( os.path.join("x509", "custom", "post2000utctime.pem"), diff --git a/vectors/cryptography_vectors/x509/belgian-eid-invalid-visiblestring.pem b/vectors/cryptography_vectors/x509/belgian-eid-invalid-visiblestring.pem new file mode 100644 index 000000000000..17650782f99f --- /dev/null +++ b/vectors/cryptography_vectors/x509/belgian-eid-invalid-visiblestring.pem @@ -0,0 +1,37 @@ +-----BEGIN CERTIFICATE----- +MIIGYzCCBEugAwIBAgIQEAAAAAAAdQQMgK5bRTyOHTANBgkqhkiG9w0BAQsFADAz +MQswCQYDVQQGEwJCRTETMBEGA1UEAxMKQ2l0aXplbiBDQTEPMA0GA1UEBRMGMjAx +NjIzMB4XDTE2MDgyOTA5NDcwMFoXDTI2MDgyNDIzNTk1OVowbzELMAkGA1UEBhMC +QkUxIjAgBgNVBAMTGUVsc2UgRGUgUHJvZnQgKFNpZ25hdHVyZSkxETAPBgNVBAQT +CERlIFByb2Z0MRMwEQYDVQQqEwpFbHNlIEZyYW5zMRQwEgYDVQQFEws2OTA3MDMz +ODg1MDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSMFzc0v5Fr5GM3 +1cvaF7obKH1mNUR5cAcNPdLbC8U8SzOIvArBIKToYJRQIxgy7S/XOPs7p/cnidQe +5yVNoIZlxWyB1nbbCR2c4rZJjzUz8bAXPKILjY7C+Q+Zxp6+8C6igDfd+n+eYuhU +u1kxPvGiZ+m+DuKTfjzhQAqG0kZteqwwlipJkt7FDsLxsgcxPBpMDm02sVL5pTme +rkY7mQpXZ5fpT2n2nzuNerxlfExeSdROAD/EZAxTAkuOgURWXmFBHPm0A9cipDYO +foyPcMO5/7JUPv7LWhRoMr+XrTBOVmkFxccJ8EXRtNxNVujwbjeUJp7Z+20ST1h/ +rDyNOKMCAwEAAaOCAjUwggIxMB8GA1UdIwQYMBaAFIIiihHTwEk9pIiqBydUoV6f +KmxqMHAGCCsGAQUFBwEBBGQwYjA2BggrBgEFBQcwAoYqaHR0cDovL2NlcnRzLmVp +ZC5iZWxnaXVtLmJlL2JlbGdpdW1yczQuY3J0MCgGCCsGAQUFBzABhhxodHRwOi8v +b2NzcC5laWQuYmVsZ2l1bS5iZS8yMIIBGAYDVR0gBIIBDzCCAQswggEHBgdgOAwB +AQIBMIH7MCwGCCsGAQUFBwIBFiBodHRwOi8vcmVwb3NpdG9yeS5laWQuYmVsZ2l1 +bS5iZTCBygYIKwYBBQUHAgIwgb0agbpHZWJydWlrIG9uZGVyd29ycGVuIGFhbiBh +YW5zcHJha2VsaWpraGVpZHNiZXBlcmtpbmdlbiwgemllIENQUyAtIFVzYWdlIHNv +dW1pcyDDoCBkZXMgbGltaXRhdGlvbnMgZGUgcmVzcG9uc2FiaWxpdMOpLCB2b2ly +IENQUyAtIFZlcndlbmR1bmcgdW50ZXJsaWVndCBIYWZ0dW5nc2Jlc2NocsOkbmt1 +bmdlbiwgZ2Vtw6RzcyBDUFMwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL2NybC5l +aWQuYmVsZ2l1bS5iZS9laWRjMjAxNjIzLmNybDAOBgNVHQ8BAf8EBAMCBkAwEQYJ +YIZIAYb4QgEBBAQDAgUgMCIGCCsGAQUFBwEDBBYwFDAIBgYEAI5GAQEwCAYGBACO +RgEEMA0GCSqGSIb3DQEBCwUAA4ICAQABNGZci7JGuvzXfk5MJCX/2Py3M9//R9iN +E/b8brMP6aCHJuDnEW7RcGAyleQQJYrTQnizWqoHRnkQ4BjQCZCpTEhERvCJz9KC +J0L9+9M3TNDGLMY14Tu/h8Uga6vThXoxI4VK2Y3gEP5qWV0tMdbu+dLSLZ+O2qkj +vtk8apYLn/2MGQ/srbu6HOLATvAKMtkF2za6zY0VL1Se9gHaHQdI9nnXKA3YD/7n +C4UrqozruMqGRNCpWhD/fRgdHotRaD4ZDuC7hUZH2b+ldFII4tsZiXcVhX6RN7KF +h5Ji/F2K9vqA0TbMWUEfiULSQfNc86LOd4riJ5VeVYtUl5kcrfVWMGBPQaq7c3OG +G2L2x4rkB8mvRTeQZCU5ENuEZX34jZuKnv7pabdntzowE5VQWjLgFGQ7UyTFbImZ +cR+H5djrrzO3Uvnu6a9v0ILGCLqES06pgH/apwtpHQPhvCWA8KBqf2aTgpZ8GsFI +qTraP819yyr+GOOp/NO8EvcOsyjgWwzDvtpoLty3/wMXC5DBNoUb3W/uMju5MJ3E +2dthCxnP7ES2PbdGTDK8Jtbgp5sJtfV6GCjgHDsIL5XGy6CagDghEG84TrYvKxTG +PlmUThXhFRVjwv2tbpgFC7z/RwARqcNYxZKFKAHXCx6hWgSQbuEN5j6JFQh3ZUL+ +R2V64/XeBQ== +-----END CERTIFICATE----- From e129a1ddbcb359393bb2e45e00d2cfcf64336e39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 May 2023 20:03:37 +0000 Subject: [PATCH 741/827] Bump asn1 from 0.15.1 to 0.15.2 in /src/rust (#8886) Bumps [asn1](https://github.com/alex/rust-asn1) from 0.15.1 to 0.15.2. - [Commits](https://github.com/alex/rust-asn1/compare/0.15.1...0.15.2) --- updated-dependencies: - dependency-name: asn1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 8 ++++---- src/rust/Cargo.toml | 2 +- src/rust/cryptography-x509/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index c7e79503c469..0c044d097de6 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -16,18 +16,18 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "asn1" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3ffc84e382cf516922078c67853a781fdb4363cf364594df8eab5ef5485553" +checksum = "28c19b9324de5b815b6487e0f8098312791b09de0dbf3d5c2db1fe2d95bab973" dependencies = [ "asn1_derive", ] [[package]] name = "asn1_derive" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7124c4d563619518d0ad454032967d5645627033d4b6e4e17bb7ac0237241c81" +checksum = "a045c3ccad89f244a86bd1e6cf1a7bf645296e7692698b056399b6efd4639407" dependencies = [ "proc-macro2", "quote", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index d221cb17a9b9..3efbf1334343 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.56.0" [dependencies] once_cell = "1" pyo3 = { version = "0.18", features = ["abi3-py37"] } -asn1 = { version = "0.15.1", default-features = false } +asn1 = { version = "0.15.2", default-features = false } cryptography-cffi = { path = "cryptography-cffi" } cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } diff --git a/src/rust/cryptography-x509/Cargo.toml b/src/rust/cryptography-x509/Cargo.toml index 8c4d20537435..017d51dd44a3 100644 --- a/src/rust/cryptography-x509/Cargo.toml +++ b/src/rust/cryptography-x509/Cargo.toml @@ -8,4 +8,4 @@ publish = false rust-version = "1.56.0" [dependencies] -asn1 = { version = "0.15.1", default-features = false } +asn1 = { version = "0.15.2", default-features = false } From 8834b590ede72c79532ccd34857a6904c48d3634 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 7 May 2023 15:20:26 -0500 Subject: [PATCH 742/827] Print more rust dirs for debugging in mtime-fix (#8887) --- .github/actions/mtime-fix/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/mtime-fix/action.yml b/.github/actions/mtime-fix/action.yml index 0690132db689..42779037ce87 100644 --- a/.github/actions/mtime-fix/action.yml +++ b/.github/actions/mtime-fix/action.yml @@ -11,7 +11,7 @@ runs: echo "The git available is probably too old so checkout didn't create a real git clone, skipping mtime fix" exit 0 fi - ls -Rla src/rust/src src/_cffi_src + ls -Rla src/rust src/_cffi_src echo "Verifying commits are monotonic because if they're not caching gets wrecked" COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5) SORTED_COMMIT_ORDER=$(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -5 | sort -rn) @@ -22,5 +22,5 @@ runs: echo "Setting mtimes for dirs" for f in $(git ls-tree -t -r --name-only HEAD src/rust src/_cffi_src); do touch -t $(git log --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S -1 HEAD -- "$f") "$f"; done echo "Done" - ls -Rla src/rust/src src/_cffi_src + ls -Rla src/rust src/_cffi_src shell: bash From b436fafa7cf43c96f66d50162ac495c99ade1f39 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 7 May 2023 15:26:45 -0500 Subject: [PATCH 743/827] add signature_algorithm_parameters to certificate (#8795) this allows easier verification of cert signatures, but more specifically allows PSS signature verification --- CHANGELOG.rst | 3 + docs/x509/reference.rst | 52 +++++++++ src/cryptography/x509/base.py | 10 ++ src/rust/cryptography-x509/src/common.rs | 57 +++++++++- src/rust/cryptography-x509/src/oid.rs | 13 +++ src/rust/src/x509/certificate.rs | 130 +++++++++++++++++++++-- tests/x509/test_x509.py | 92 ++++++++++++++-- 7 files changed, 338 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fcc6f28cbc47..d4fd576242b0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,9 @@ Changelog * Implemented support for equality checks on all asymmetric public key types. * Added support for ``aes256-gcm@openssh.com`` encrypted keys in :func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key`. +* Added support for obtaining X.509 certificate signature algorithm parameters + (including PSS) via + :meth:`~cryptography.x509.Certificate.signature_algorithm_parameters`. .. _v40-0-2: diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 71a6eb1799b5..647666c5c67e 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -146,6 +146,30 @@ X.509 Reference -----END CERTIFICATE----- """.strip() + rsa_pss_pem_cert = b""" + -----BEGIN CERTIFICATE----- + MIIDfTCCAjCgAwIBAgIUP4D/5rcT93vdYGPhsKf+hbes/JgwQgYJKoZIhvcNAQEK + MDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF + AKIEAgIA3jAaMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMjIwNDMwMjAz + MTE4WhcNMzMwNDEyMjAzMTE4WjAaMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8w + ggEgMAsGCSqGSIb3DQEBCgOCAQ8AMIIBCgKCAQEAt1jpboUoNppBVamc+nA+zEjl + jn/gPbRFCvyveRd8Yr0p8y1mlmjKXcQlXcHPVM4TopgFXqDykIHXxJxLV56ysb4K + UGe0nxpmhEso5ZGUgkDIIoH0NAQAsS8rS2ZzNJcLrLGrMY6DRgFsa+G6h2DvMwgl + nsX++a8FIm7Vu+OZnfWpDEuhJU4TRtHVviJSYkFMckyYBB48k1MU+0b4pezHconZ + mMEisBFFbwarNvowf2i/tRESe3myKXfiJsZZ2UzdE3FqycSgw1tx8qV/Z8myozUW + uihIdw8TGbbsJhEeVFxQEP/DVzC6HHDI3EVpr2jPYeIE60hhZwM7jUmQscLerQID + AQABo1MwUTAdBgNVHQ4EFgQUb1QD8QEIQn5DALIAujTDATssNcQwHwYDVR0jBBgw + FoAUb1QD8QEIQn5DALIAujTDATssNcQwDwYDVR0TAQH/BAUwAwEB/zBCBgkqhkiG + 9w0BAQowNaAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFl + AwQCAQUAogQCAgDeA4IBAQAvKBXlx07tdmtfhNTPn16dupBIS5344ZE4tfGSE5Ir + iA1X0bukKQ6V+6xJXGreaIw0wvwtIeI/R0JwcR114HBDqjt40vklyNSpGCJzgkfD + Q/d8JXN/MLyQrk+5F9JMy+HuZAgefAQAjugC6389Klpqx2Z1CgwmALhjIs48GnMp + Iz9vU2O6RDkMBlBRdmfkJVjhhPvJYpDDW1ic5O3pxtMoiC1tAHHMm4gzM1WCFeOh + cDNxABlvVNPTnqkOhKBmmwRaBwdvvksgeu2RyBNR0KEy44gWzYB9/Ter2t4Z8ASq + qCv8TuYr2QGaCnI2FVS5S9n6l4JNkFHqPMtuhrkr3gEz + -----END CERTIFICATE----- + """.strip() + Loading Certificates ~~~~~~~~~~~~~~~~~~~~ @@ -413,6 +437,34 @@ X.509 Certificate Object >>> cert.signature_algorithm_oid + .. attribute:: signature_algorithm_parameters + + .. versionadded:: 41.0.0 + + Returns the parameters of the signature algorithm used to sign the + certificate. For RSA signatures it will return either a + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15` or + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` object. + + For ECDSA signatures it will + return an :class:`~cryptography.hazmat.primitives.asymmetric.ec.ECDSA`. + + For EdDSA and DSA signatures it will return ``None``. + + These objects can be used to verify signatures on the certificate. + + :returns: None, + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`, + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS`, or + :class:`~cryptography.hazmat.primitives.asymmetric.ec.ECDSA` + + .. doctest:: + + >>> from cryptography.hazmat.primitives.asymmetric import padding + >>> pss_cert = x509.load_pem_x509_certificate(rsa_pss_pem_cert) + >>> isinstance(pss_cert.signature_algorithm_parameters, padding.PSS) + True + .. attribute:: extensions :type: :class:`Extensions` diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 63eaa6bd4013..64453eb70aa5 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -17,6 +17,7 @@ ec, ed448, ed25519, + padding, rsa, x448, x25519, @@ -232,6 +233,15 @@ def signature_algorithm_oid(self) -> ObjectIdentifier: Returns the ObjectIdentifier of the signature algorithm. """ + @property + @abc.abstractmethod + def signature_algorithm_parameters( + self, + ) -> typing.Union[None, padding.PSS, padding.PKCS1v15, ec.ECDSA]: + """ + Returns the signature algorithm parameters. + """ + @property @abc.abstractmethod def extensions(self) -> Extensions: diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 9668ae237703..d099716599ea 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -6,7 +6,7 @@ use crate::oid; use asn1::Asn1DefinedByWritable; use std::marker::PhantomData; -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone, Eq)] pub struct AlgorithmIdentifier<'a> { pub oid: asn1::DefinedByMarker, #[defined_by(oid)] @@ -55,6 +55,11 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::ECDSA_WITH_SHA3_512_OID)] EcDsaWithSha3_512, + #[defined_by(oid::RSA_WITH_SHA1_OID)] + RsaWithSha1(Option), + #[defined_by(oid::RSA_WITH_SHA1_ALT_OID)] + RsaWithSha1Alt(Option), + #[defined_by(oid::RSA_WITH_SHA224_OID)] RsaWithSha224(Option), #[defined_by(oid::RSA_WITH_SHA256_OID)] @@ -73,6 +78,12 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::RSA_WITH_SHA3_512_OID)] RsaWithSha3_512(Option), + // RsaPssParameters must be present in Certificate::tbs_cert::signature_alg::params + // and Certificate::signature_alg::params, but Certificate::tbs_cert::spki::algorithm::oid + // also uses RSASSA_PSS_OID and the params field is omitted since it has no meaning there. + #[defined_by(oid::RSASSA_PSS_OID)] + RsaPss(Option>>), + #[defined_by(oid::DSA_WITH_SHA224_OID)] DsaWithSha224, #[defined_by(oid::DSA_WITH_SHA256_OID)] @@ -205,6 +216,50 @@ pub struct DHParams<'a> { pub g: asn1::BigUint<'a>, pub q: Option>, } +// RSA-PSS ASN.1 default hash algorithm +pub const PSS_SHA1_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: AlgorithmParameters::Sha1(()), +}; + +// This is defined as an AlgorithmIdentifier in RFC 4055, +// but the mask generation algorithm **must** contain an AlgorithmIdentifier +// in its params, so we define it this way. +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq)] +pub struct MaskGenAlgorithm<'a> { + pub oid: asn1::ObjectIdentifier, + pub params: AlgorithmIdentifier<'a>, +} + +// RSA-PSS ASN.1 default mask gen algorithm +pub const PSS_SHA1_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm { + oid: oid::MGF1_OID, + params: PSS_SHA1_HASH_ALG, +}; + +// From RFC 4055 section 3.1: +// RSASSA-PSS-params ::= SEQUENCE { +// hashAlgorithm [0] HashAlgorithm DEFAULT +// sha1Identifier, +// maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT +// mgf1SHA1Identifier, +// saltLength [2] INTEGER DEFAULT 20, +// trailerField [3] INTEGER DEFAULT 1 } +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq)] +pub struct RsaPssParameters<'a> { + #[explicit(0)] + #[default(PSS_SHA1_HASH_ALG)] + pub hash_algorithm: AlgorithmIdentifier<'a>, + #[explicit(1)] + #[default(PSS_SHA1_MASK_GEN_ALG)] + pub mask_gen_algorithm: MaskGenAlgorithm<'a>, + #[explicit(2)] + #[default(20u16)] + pub salt_length: u16, + #[explicit(3)] + #[default(1u8)] + _trailer_field: u8, +} /// A VisibleString ASN.1 element whose contents is not validated as meeting the /// requirements (visible characters of IA5), and instead is only known to be diff --git a/src/rust/cryptography-x509/src/oid.rs b/src/rust/cryptography-x509/src/oid.rs index b2d22ebddb1c..ac80b9a31365 100644 --- a/src/rust/cryptography-x509/src/oid.rs +++ b/src/rust/cryptography-x509/src/oid.rs @@ -57,6 +57,8 @@ pub const ECDSA_WITH_SHA3_384_OID: asn1::ObjectIdentifier = pub const ECDSA_WITH_SHA3_512_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 3, 12); +pub const RSA_WITH_SHA1_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 5); +pub const RSA_WITH_SHA1_ALT_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 14, 3, 2, 29); pub const RSA_WITH_SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 14); pub const RSA_WITH_SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 11); pub const RSA_WITH_SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 12); @@ -84,3 +86,14 @@ pub const SHA224_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, pub const SHA256_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 1); pub const SHA384_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2); pub const SHA512_OID: asn1::ObjectIdentifier = asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 3); +pub const SHA3_224_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 224); +pub const SHA3_256_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 256); +pub const SHA3_384_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 384); +pub const SHA3_512_OID: asn1::ObjectIdentifier = + asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 512); + +pub const MGF1_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 8); +pub const RSASSA_PSS_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 1, 10); diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 98f1a073fef7..03d8ae883256 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -17,10 +17,28 @@ use cryptography_x509::extensions::{ }; use cryptography_x509::extensions::{Extension, Extensions}; use cryptography_x509::{common, name, oid}; +use once_cell::sync::Lazy; use pyo3::{IntoPy, ToPyObject}; use std::collections::hash_map::DefaultHasher; +use std::collections::HashMap; use std::hash::{Hash, Hasher}; +// This is similar to a hashmap in ocsp.rs but contains more hash algorithms +// that aren't allowable in OCSP +static HASH_OIDS_TO_HASH: Lazy> = Lazy::new(|| { + let mut h = HashMap::new(); + h.insert(&oid::SHA1_OID, "SHA1"); + h.insert(&oid::SHA224_OID, "SHA224"); + h.insert(&oid::SHA256_OID, "SHA256"); + h.insert(&oid::SHA384_OID, "SHA384"); + h.insert(&oid::SHA512_OID, "SHA512"); + h.insert(&oid::SHA3_224_OID, "SHA3_224"); + h.insert(&oid::SHA3_256_OID, "SHA3_256"); + h.insert(&oid::SHA3_384_OID, "SHA3_384"); + h.insert(&oid::SHA3_512_OID, "SHA3_512"); + h +}); + #[ouroboros::self_referencing] pub(crate) struct OwnedCertificate { data: pyo3::Py, @@ -241,15 +259,25 @@ impl Certificate { let sig_oids_to_hash = py .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; - let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); - match hash_alg { - Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from( - exceptions::UnsupportedAlgorithm::new_err(format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid(), - )), - )), + match &self.raw.borrow_value().signature_alg.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + hash_oid_py_hash(py, pss.hash_algorithm.oid().clone()) + } + _ => { + let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); + match hash_alg { + Ok(data) => Ok(data), + Err(_) => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + self.raw.borrow_value().signature_alg.oid() + )), + )), + } + } } } @@ -258,6 +286,74 @@ impl Certificate { oid_to_py_oid(py, self.raw.borrow_value().signature_alg.oid()) } + #[getter] + fn signature_algorithm_parameters<'p>( + &'p self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::PyAny> { + match &self.raw.borrow_value().signature_alg.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + if pss.mask_gen_algorithm.oid != oid::MGF1_OID { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "Unsupported mask generation OID: {}", + pss.mask_gen_algorithm.oid + )), + )); + } + let py_mask_gen_hash_alg = + hash_oid_py_hash(py, pss.mask_gen_algorithm.params.oid().clone())?; + let padding = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; + let py_mgf = padding + .getattr(pyo3::intern!(py, "MGF1"))? + .call1((py_mask_gen_hash_alg,))?; + Ok(padding + .getattr(pyo3::intern!(py, "PSS"))? + .call1((py_mgf, pss.salt_length))?) + } + common::AlgorithmParameters::RsaWithSha1(_) + | common::AlgorithmParameters::RsaWithSha1Alt(_) + | common::AlgorithmParameters::RsaWithSha224(_) + | common::AlgorithmParameters::RsaWithSha256(_) + | common::AlgorithmParameters::RsaWithSha384(_) + | common::AlgorithmParameters::RsaWithSha512(_) + | common::AlgorithmParameters::RsaWithSha3_224(_) + | common::AlgorithmParameters::RsaWithSha3_256(_) + | common::AlgorithmParameters::RsaWithSha3_384(_) + | common::AlgorithmParameters::RsaWithSha3_512(_) => { + let pkcs = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))? + .getattr(pyo3::intern!(py, "PKCS1v15"))? + .call0()?; + Ok(pkcs) + } + common::AlgorithmParameters::EcDsaWithSha224 + | common::AlgorithmParameters::EcDsaWithSha256 + | common::AlgorithmParameters::EcDsaWithSha384 + | common::AlgorithmParameters::EcDsaWithSha512 + | common::AlgorithmParameters::EcDsaWithSha3_224 + | common::AlgorithmParameters::EcDsaWithSha3_256 + | common::AlgorithmParameters::EcDsaWithSha3_384 + | common::AlgorithmParameters::EcDsaWithSha3_512 => Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))? + .getattr(pyo3::intern!(py, "ECDSA"))? + .call1((self.signature_hash_algorithm(py)?,))?), + _ => Ok(py.None().into_ref(py)), + } + } + #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; @@ -853,6 +949,22 @@ pub fn parse_cert_ext<'p>( } } +fn hash_oid_py_hash( + py: pyo3::Python<'_>, + oid: asn1::ObjectIdentifier, +) -> CryptographyResult<&pyo3::PyAny> { + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; + match HASH_OIDS_TO_HASH.get(&oid) { + Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + &oid + )), + )), + } +} + pub(crate) fn time_from_py( py: pyo3::Python<'_>, val: &pyo3::PyAny, diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 1de45192b550..a32dfca930cf 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -729,15 +729,15 @@ def test_get_revoked_certificate_doesnt_reorder( assert crl[2].serial_number == 3 +@pytest.mark.supported( + only_if=lambda backend: ( + not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL + and not backend._lib.CRYPTOGRAPHY_IS_BORINGSSL + and not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E + ), + skip_message="Does not support RSA PSS loading", +) class TestRSAPSSCertificate: - @pytest.mark.supported( - only_if=lambda backend: ( - not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL - and not backend._lib.CRYPTOGRAPHY_IS_BORINGSSL - and not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E - ), - skip_message="Does not support RSA PSS loading", - ) def test_load_cert_pub_key(self, backend): cert = _load_cert( os.path.join("x509", "custom", "rsa_pss_cert.pem"), @@ -751,7 +751,47 @@ def test_load_cert_pub_key(self, backend): assert isinstance(expected_pub_key, rsa.RSAPublicKey) pub_key = cert.public_key() assert isinstance(pub_key, rsa.RSAPublicKey) - assert pub_key.public_numbers() == expected_pub_key.public_numbers() + assert pub_key == expected_pub_key + pss = cert.signature_algorithm_parameters + assert isinstance(pss, padding.PSS) + assert isinstance(pss._mgf, padding.MGF1) + assert isinstance(pss._mgf._algorithm, hashes.SHA256) + assert pss._salt_length == 222 + assert isinstance(cert.signature_hash_algorithm, hashes.SHA256) + pub_key.verify( + cert.signature, + cert.tbs_certificate_bytes, + pss, + cert.signature_hash_algorithm, + ) + + def test_invalid_mgf(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "rsa_pss_cert_invalid_mgf.der"), + x509.load_der_x509_certificate, + ) + with pytest.raises(ValueError): + cert.signature_algorithm_parameters + + def test_unsupported_mgf_hash(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "rsa_pss_cert_unsupported_mgf_hash.der" + ), + x509.load_der_x509_certificate, + ) + with pytest.raises(UnsupportedAlgorithm): + cert.signature_algorithm_parameters + + def test_no_sig_params(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "rsa_pss_cert_no_sig_params.der"), + x509.load_der_x509_certificate, + ) + with pytest.raises(ValueError): + cert.signature_algorithm_parameters + with pytest.raises(ValueError): + cert.signature_hash_algorithm class TestRSACertificate: @@ -768,6 +808,28 @@ def test_load_pem_cert(self, backend): assert ( cert.signature_algorithm_oid == SignatureAlgorithmOID.RSA_WITH_SHA1 ) + assert isinstance( + cert.signature_algorithm_parameters, padding.PKCS1v15 + ) + + def test_check_pkcs1_signature_algorithm_parameters(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "ca", "rsa_ca.pem"), + x509.load_pem_x509_certificate, + ) + assert isinstance(cert, x509.Certificate) + assert isinstance( + cert.signature_algorithm_parameters, padding.PKCS1v15 + ) + pk = cert.public_key() + assert isinstance(pk, rsa.RSAPublicKey) + assert cert.signature_hash_algorithm is not None + pk.verify( + cert.signature, + cert.tbs_certificate_bytes, + cert.signature_algorithm_parameters, + cert.signature_hash_algorithm, + ) def test_load_legacy_pem_header(self, backend): cert = _load_cert( @@ -4599,6 +4661,7 @@ def test_load_dsa_cert(self, backend): assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) public_key = cert.public_key() assert isinstance(public_key, dsa.DSAPublicKey) + assert cert.signature_algorithm_parameters is None num = public_key.public_numbers() assert num.y == int( "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94" @@ -4847,6 +4910,15 @@ def test_load_ecdsa_cert(self, backend): 16, ) assert isinstance(num.curve, ec.SECP384R1) + assert isinstance(cert.signature_algorithm_parameters, ec.ECDSA) + assert isinstance( + cert.signature_algorithm_parameters.algorithm, hashes.SHA384 + ) + public_key.verify( + cert.signature, + cert.tbs_certificate_bytes, + cert.signature_algorithm_parameters, + ) def test_load_bitstring_dn(self, backend): cert = _load_cert( @@ -5590,6 +5662,7 @@ def test_load_pem_cert(self, backend): assert cert.serial_number == 9579446940964433301 assert cert.signature_hash_algorithm is None assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED25519 + assert cert.signature_algorithm_parameters is None def test_deepcopy(self, backend): cert = _load_cert( @@ -5635,6 +5708,7 @@ def test_load_pem_cert(self, backend): assert cert.serial_number == 448 assert cert.signature_hash_algorithm is None assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED448 + assert cert.signature_algorithm_parameters is None def test_verify_directly_issued_by_ed448(self, backend): issuer_private_key = ed448.Ed448PrivateKey.generate() From 8cd2765d13da03aec5bfea87d922c63e56277e03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 13:22:29 +0000 Subject: [PATCH 744/827] Bump libc from 0.2.143 to 0.2.144 in /src/rust (#8891) Bumps [libc](https://github.com/rust-lang/libc) from 0.2.143 to 0.2.144. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.143...0.2.144) --- updated-dependencies: - dependency-name: libc dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 0c044d097de6..d76c498485ba 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -131,9 +131,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "libc" -version = "0.2.143" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "lock_api" From 81916ba1b9ca55133adfc233980e3a80b60addff Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 23:03:06 -0400 Subject: [PATCH 745/827] Bump BoringSSL and/or OpenSSL in CI (#8893) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a97b41f1d49..e066969acb8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 06, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b1c6f45f1fe6d808555d04a41bb44b322e4f4c1d"}} - # Latest commit on the OpenSSL master branch, as of May 06, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "6aeb42eca97227c8235af0986d1525ee4a916504"}} + # Latest commit on the BoringSSL master branch, as of May 09, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "2aae3f58b42e75690f28853f712a2e204857b7f6"}} + # Latest commit on the OpenSSL master branch, as of May 09, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3868807d2fe5a72aa897ce5f7f7ba7e9cc3c09cb"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 6bb05529a49a0ce532b7e4bf65ac6246d4d57e91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 03:37:12 +0000 Subject: [PATCH 746/827] Bump quote from 1.0.26 to 1.0.27 in /src/rust (#8894) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.26 to 1.0.27. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.26...1.0.27) --- updated-dependencies: - dependency-name: quote dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index d76c498485ba..9fdd2313155b 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -354,9 +354,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] From 3b8cb2b7337a7dc3a004555fd4bfa032e35a34af Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 9 May 2023 02:29:16 -0400 Subject: [PATCH 747/827] Don't install coverage, it's not needed (#8895) --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e066969acb8d..b06ae9771f57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: # pypy3-3.8 and pypy3-3.9 -- both of them show up as 7.3.11. key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-${{ matrix.PYTHON.NOXSESSION }}-${{ env.OPENSSL_HASH }} - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - name: Create nox environment run: | nox -v --install-only @@ -182,7 +182,7 @@ jobs: - run: | echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' coverage + - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' - run: '/venv/bin/nox -v --install-only -s tests' env: RUSTUP_HOME: /root/.rustup @@ -229,7 +229,7 @@ jobs: - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - name: Create nox environment run: nox -v --install-only -s tests env: @@ -304,7 +304,7 @@ jobs: - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] cffi + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' cffi - name: Create nox environment run: nox -v --install-only -s tests env: @@ -379,7 +379,7 @@ jobs: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - name: Clone wycheproof timeout-minutes: 2 @@ -442,7 +442,7 @@ jobs: timeout-minutes: 2 with: key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }} - - run: python -m pip install -c ci-constraints-requirements.txt "nox" coverage[toml] + - run: python -m pip install -c ci-constraints-requirements.txt "nox" - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: From 1f883568e5ab88fa34a6d041195d368bff5dc702 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 00:17:59 +0000 Subject: [PATCH 748/827] Bump BoringSSL and/or OpenSSL in CI (#8897) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b06ae9771f57..41fac5d7beff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 09, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "2aae3f58b42e75690f28853f712a2e204857b7f6"}} - # Latest commit on the OpenSSL master branch, as of May 09, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3868807d2fe5a72aa897ce5f7f7ba7e9cc3c09cb"}} + # Latest commit on the OpenSSL master branch, as of May 10, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "8c63b14296f117b07781509ced529a8955d78fb9"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 9dfb1200948523046d6996f0cd81c7fec2060ab6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 9 May 2023 20:25:05 -0400 Subject: [PATCH 749/827] Added a missing rerun-if stanza (#8899) --- src/rust/cryptography-cffi/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust/cryptography-cffi/build.rs b/src/rust/cryptography-cffi/build.rs index 9a93b50bc438..4a40990b9da4 100644 --- a/src/rust/cryptography-cffi/build.rs +++ b/src/rust/cryptography-cffi/build.rs @@ -25,6 +25,7 @@ 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_else(|_| "python3".to_string()); + println!("cargo:rerun-if-env-changed=PYO3_PYTHON"); println!("cargo:rerun-if-changed=../../_cffi_src/"); let output = Command::new(&python) .env("OUT_DIR", &out_dir) From c6887af98236de1343def4544282812b60b3a383 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 10 May 2023 09:25:18 +0900 Subject: [PATCH 750/827] update cache key to reflect all rust files, not just cargo.lock (#8898) rust uses mtime to determine if files are fresh or not. However, if the mtime of a file in main is newer than the mtime of a commit in a PR then it will load the cache and there will be weird errors since it thinks the cache is new enough but in reality the code has changed. This change ties our cache keys to all our rust files, not just our cargo.lock, and should resolve this issue. --- .github/actions/cache/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 3e8c300d03e1..37b9cc81bd37 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -43,11 +43,11 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock') }}-${{ steps.rust-version.version }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ du -sh ~/.cargo/registry/cache/ du -sh src/rust/target/ shell: bash - if: ${{ steps.cache.outputs.cache-hit }} \ No newline at end of file + if: ${{ steps.cache.outputs.cache-hit }} From 1ff6208ec739b27ae2826d866f4d2bd3db77fd87 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Wed, 10 May 2023 07:14:49 -0400 Subject: [PATCH 751/827] certificate: add a `get_extension` helper (#8892) * certificate: add a `get_extension` helper Signed-off-by: William Woodruff * certificate: OID by ref Signed-off-by: William Woodruff * certificate: syntax Signed-off-by: William Woodruff * x509, src: `check_duplicate_extensions` Signed-off-by: William Woodruff * src: simplify Signed-off-by: William Woodruff * src: everyone loves newtypes Signed-off-by: William Woodruff * rust: refactor-o-rama Signed-off-by: William Woodruff * src: look upon my works Signed-off-by: William Woodruff * src: continue blasting the code Signed-off-by: William Woodruff * src/rust: actually commit my changes Signed-off-by: William Woodruff * src: clippage Signed-off-by: William Woodruff * relocate Signed-off-by: William Woodruff * src: dedupe Signed-off-by: William Woodruff * src: cleanup Signed-off-by: William Woodruff * clippage Signed-off-by: William Woodruff * src: dedupe Signed-off-by: William Woodruff * common: cleanup Signed-off-by: William Woodruff * src: unused impls Signed-off-by: William Woodruff * more deletion Signed-off-by: William Woodruff * clippage Signed-off-by: William Woodruff * extensions: add a `get_extension` test Signed-off-by: William Woodruff * extensions: unused derives Signed-off-by: William Woodruff * tests/x509: dup ext check for tbs_precertificate_bytes Signed-off-by: William Woodruff * certificate: remove `extensions()` Signed-off-by: William Woodruff * extensions: docs Signed-off-by: William Woodruff * extensions: newtype Signed-off-by: William Woodruff * rust: better error types, dedupe Signed-off-by: William Woodruff extensions: unwrap -> expect Signed-off-by: William Woodruff * Revert "rust: better error types, dedupe" This reverts commit 212b75ff2f69a3b3cfc9d6a55949f23877f8f618. --------- Signed-off-by: William Woodruff --- src/rust/cryptography-x509/src/certificate.rs | 9 +- src/rust/cryptography-x509/src/crl.rs | 10 ++- src/rust/cryptography-x509/src/csr.rs | 2 +- src/rust/cryptography-x509/src/extensions.rs | 83 ++++++++++++++++++- src/rust/cryptography-x509/src/ocsp_req.rs | 10 ++- src/rust/cryptography-x509/src/ocsp_resp.rs | 10 ++- src/rust/src/x509/certificate.rs | 28 ++++--- src/rust/src/x509/common.rs | 31 +++---- src/rust/src/x509/crl.rs | 10 ++- src/rust/src/x509/csr.rs | 11 ++- src/rust/src/x509/ocsp_req.rs | 6 +- src/rust/src/x509/ocsp_resp.rs | 29 ++++--- tests/x509/test_x509.py | 14 ++++ 13 files changed, 193 insertions(+), 60 deletions(-) diff --git a/src/rust/cryptography-x509/src/certificate.rs b/src/rust/cryptography-x509/src/certificate.rs index bb9a666f5f78..59960242b202 100644 --- a/src/rust/cryptography-x509/src/certificate.rs +++ b/src/rust/cryptography-x509/src/certificate.rs @@ -4,6 +4,7 @@ use crate::common; use crate::extensions; +use crate::extensions::Extensions; use crate::name; #[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] @@ -31,7 +32,13 @@ pub struct TbsCertificate<'a> { #[implicit(2)] pub subject_unique_id: Option>, #[explicit(3)] - pub extensions: Option>, + pub raw_extensions: Option>, +} + +impl<'a> TbsCertificate<'a> { + pub fn extensions(&'a self) -> Result>, asn1::ObjectIdentifier> { + Extensions::from_raw_extensions(self.raw_extensions.as_ref()) + } } #[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)] diff --git a/src/rust/cryptography-x509/src/crl.rs b/src/rust/cryptography-x509/src/crl.rs index 3a47e0a37727..c81a3c4a95fd 100644 --- a/src/rust/cryptography-x509/src/crl.rs +++ b/src/rust/cryptography-x509/src/crl.rs @@ -2,7 +2,11 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::{common, extensions, name}; +use crate::{ + common, + extensions::{self}, + name, +}; pub type ReasonFlags<'a> = Option, asn1::OwnedBitString>>; @@ -31,14 +35,14 @@ pub struct TBSCertList<'a> { pub next_update: Option, pub revoked_certificates: RevokedCertificates<'a>, #[explicit(0)] - pub crl_extensions: Option>, + pub raw_crl_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)] pub struct RevokedCertificate<'a> { pub user_certificate: asn1::BigUint<'a>, pub revocation_date: common::Time, - pub crl_entry_extensions: Option>, + pub raw_crl_entry_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] diff --git a/src/rust/cryptography-x509/src/csr.rs b/src/rust/cryptography-x509/src/csr.rs index c23d22d0fd11..d2cf9b5e2739 100644 --- a/src/rust/cryptography-x509/src/csr.rs +++ b/src/rust/cryptography-x509/src/csr.rs @@ -26,7 +26,7 @@ pub struct CertificationRequestInfo<'a> { impl CertificationRequestInfo<'_> { pub fn get_extension_attribute( &self, - ) -> Result>, asn1::ParseError> { + ) -> Result>, asn1::ParseError> { for attribute in self.attributes.unwrap_read().clone() { if attribute.type_id == oid::EXTENSION_REQUEST || attribute.type_id == oid::MS_EXTENSION_REQUEST diff --git a/src/rust/cryptography-x509/src/extensions.rs b/src/rust/cryptography-x509/src/extensions.rs index 0728633d4adb..b1138fec206e 100644 --- a/src/rust/cryptography-x509/src/extensions.rs +++ b/src/rust/cryptography-x509/src/extensions.rs @@ -2,16 +2,62 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use std::collections::HashSet; + use crate::common; use crate::crl; use crate::name; -pub type Extensions<'a> = common::Asn1ReadableOrWritable< +pub type RawExtensions<'a> = common::Asn1ReadableOrWritable< 'a, asn1::SequenceOf<'a, Extension<'a>>, asn1::SequenceOfWriter<'a, Extension<'a>, Vec>>, >; +/// An invariant-enforcing wrapper for `RawExtensions`. +/// +/// In particular, an `Extensions` cannot be constructed from a `RawExtensions` +/// that contains duplicated extensions (by OID). +pub struct Extensions<'a>(RawExtensions<'a>); + +impl<'a> Extensions<'a> { + /// Create an `Extensions` from the given `RawExtensions`. + /// + /// Returns an `Err` variant containing the first duplicated extension's + /// OID, if there are any duplicates. + pub fn from_raw_extensions( + raw: Option<&RawExtensions<'a>>, + ) -> Result, asn1::ObjectIdentifier> { + match raw { + Some(raw_exts) => { + let mut seen_oids = HashSet::new(); + + for ext in raw_exts.unwrap_read().clone() { + if !seen_oids.insert(ext.extn_id.clone()) { + return Err(ext.extn_id); + } + } + + Ok(Some(Self(raw_exts.clone()))) + } + None => Ok(None), + } + } + + /// Retrieves the extension identified by the given OID, + /// or None if the extension is not present (or no extensions are present). + pub fn get_extension(&self, oid: &asn1::ObjectIdentifier) -> Option { + let mut extensions = self.0.unwrap_read().clone(); + + extensions.find(|ext| &ext.extn_id == oid) + } + + /// Returns a reference to the underlying extensions. + pub fn as_raw(&self) -> &RawExtensions<'_> { + &self.0 + } +} + #[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)] pub struct Extension<'a> { pub extn_id: asn1::ObjectIdentifier, @@ -174,3 +220,38 @@ pub struct BasicConstraints { pub ca: bool, pub path_length: Option, } + +#[cfg(test)] +mod tests { + use asn1::SequenceOfWriter; + + use crate::oid::{AUTHORITY_KEY_IDENTIFIER_OID, BASIC_CONSTRAINTS_OID}; + + use super::{BasicConstraints, Extension, Extensions}; + + #[test] + fn test_get_extension() { + let extension_value = BasicConstraints { + ca: true, + path_length: Some(3), + }; + let extension = Extension { + extn_id: BASIC_CONSTRAINTS_OID, + critical: true, + extn_value: &asn1::write_single(&extension_value).unwrap(), + }; + let extensions = SequenceOfWriter::new(vec![extension]); + + let der = asn1::write_single(&extensions).unwrap(); + + let extensions: Extensions = + Extensions::from_raw_extensions(Some(&asn1::parse_single(&der).unwrap())) + .unwrap() + .unwrap(); + + assert!(&extensions.get_extension(&BASIC_CONSTRAINTS_OID).is_some()); + assert!(&extensions + .get_extension(&AUTHORITY_KEY_IDENTIFIER_OID) + .is_none()); + } +} diff --git a/src/rust/cryptography-x509/src/ocsp_req.rs b/src/rust/cryptography-x509/src/ocsp_req.rs index 1e096e71f1da..ba54d391f506 100644 --- a/src/rust/cryptography-x509/src/ocsp_req.rs +++ b/src/rust/cryptography-x509/src/ocsp_req.rs @@ -2,7 +2,11 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::{common, extensions, name}; +use crate::{ + common, + extensions::{self}, + name, +}; #[derive(asn1::Asn1Read, asn1::Asn1Write)] pub struct TBSRequest<'a> { @@ -17,14 +21,14 @@ pub struct TBSRequest<'a> { asn1::SequenceOfWriter<'a, Request<'a>>, >, #[explicit(2)] - pub request_extensions: Option>, + pub raw_request_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] pub struct Request<'a> { pub req_cert: CertID<'a>, #[explicit(0)] - pub single_request_extensions: Option>, + pub single_request_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] diff --git a/src/rust/cryptography-x509/src/ocsp_resp.rs b/src/rust/cryptography-x509/src/ocsp_resp.rs index f7620f6aa601..21f01e2c7375 100644 --- a/src/rust/cryptography-x509/src/ocsp_resp.rs +++ b/src/rust/cryptography-x509/src/ocsp_resp.rs @@ -2,7 +2,11 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. -use crate::{certificate, common, crl, extensions, name, ocsp_req}; +use crate::{ + certificate, common, crl, + extensions::{self}, + name, ocsp_req, +}; #[derive(asn1::Asn1Read, asn1::Asn1Write)] pub struct OCSPResponse<'a> { @@ -47,7 +51,7 @@ pub struct ResponseData<'a> { asn1::SequenceOfWriter<'a, SingleResponse<'a>, Vec>>, >, #[explicit(1)] - pub response_extensions: Option>, + pub raw_response_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] @@ -66,7 +70,7 @@ pub struct SingleResponse<'a> { #[explicit(0)] pub next_update: Option, #[explicit(1)] - pub single_extensions: Option>, + pub raw_single_extensions: Option>, } #[derive(asn1::Asn1Read, asn1::Asn1Write)] diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 03d8ae883256..3784b1c9a4b0 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -9,13 +9,13 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509::{extensions, sct, sign}; use crate::{exceptions, x509}; use cryptography_x509::common::Asn1ReadableOrWritable; +use cryptography_x509::extensions::Extension; use cryptography_x509::extensions::{ AuthorityKeyIdentifier, BasicConstraints, DisplayText, DistributionPoint, DistributionPointName, MSCertificateTemplate, NameConstraints, PolicyConstraints, - PolicyInformation, PolicyQualifierInfo, Qualifier, SequenceOfAccessDescriptions, + PolicyInformation, PolicyQualifierInfo, Qualifier, RawExtensions, SequenceOfAccessDescriptions, SequenceOfSubtrees, UserNotice, }; -use cryptography_x509::extensions::{Extension, Extensions}; use cryptography_x509::{common, name, oid}; use once_cell::sync::Lazy; use pyo3::{IntoPy, ToPyObject}; @@ -193,9 +193,9 @@ impl Certificate { let val = self.raw.borrow_value(); let mut tbs_precert = val.tbs_cert.clone(); // Remove the SCT list extension - match tbs_precert.extensions { - Some(extensions) => { - let readable_extensions = extensions.unwrap_read().clone(); + match val.tbs_cert.extensions() { + Ok(Some(extensions)) => { + let readable_extensions = extensions.as_raw().unwrap_read().clone(); let ext_count = readable_extensions.len(); let filtered_extensions: Vec> = readable_extensions .filter(|x| x.extn_id != oid::PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID) @@ -207,18 +207,26 @@ impl Certificate { ), )); } - let filtered_extensions: Extensions<'_> = Asn1ReadableOrWritable::new_write( + let filtered_extensions: RawExtensions<'_> = Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(filtered_extensions), ); - tbs_precert.extensions = Some(filtered_extensions); + tbs_precert.raw_extensions = Some(filtered_extensions); let result = asn1::write_single(&tbs_precert)?; Ok(pyo3::types::PyBytes::new(py, &result)) } - None => Err(CryptographyError::from( + Ok(None) => Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( "Could not find any extensions in TBS certificate", ), )), + Err(oid) => { + let oid_obj = oid_to_py_oid(py, &oid)?; + Err(exceptions::DuplicateExtension::new_err(( + format!("Duplicate {} extension found", oid), + oid_obj.into_py(py), + )) + .into()) + } } } @@ -360,7 +368,7 @@ impl Certificate { x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.raw.borrow_value().tbs_cert.extensions, + &self.raw.borrow_value().tbs_cert.raw_extensions, |oid, ext_data| match *oid { oid::PRECERT_POISON_OID => { asn1::parse_single::<()>(ext_data)?; @@ -1035,7 +1043,7 @@ fn create_x509_certificate( spki: asn1::parse_single(spki_bytes)?, issuer_unique_id: None, subject_unique_id: None, - extensions: x509::common::encode_extensions( + raw_extensions: x509::common::encode_extensions( py, builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 571963e36b63..94ae58d386c5 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -6,11 +6,10 @@ use crate::asn1::{oid_to_py_oid, py_oid_to_oid}; use crate::error::{CryptographyError, CryptographyResult}; use crate::{exceptions, x509}; use cryptography_x509::common::{Asn1ReadableOrWritable, AttributeTypeValue, RawTlv}; -use cryptography_x509::extensions::{AccessDescription, Extension, Extensions}; +use cryptography_x509::extensions::{AccessDescription, Extension, Extensions, RawExtensions}; use cryptography_x509::name::{GeneralName, Name, OtherName, UnvalidatedIA5String}; use pyo3::types::IntoPyDict; use pyo3::{IntoPy, ToPyObject}; -use std::collections::HashSet; /// Parse all sections in a PEM file and return the first matching section. /// If no matching sections are found, return an error. @@ -391,27 +390,30 @@ pub(crate) fn parse_and_cache_extensions< >( py: pyo3::Python<'p>, cached_extensions: &mut Option, - raw_exts: &Option>, + raw_extensions: &Option>, parse_ext: F, ) -> pyo3::PyResult { if let Some(cached) = cached_extensions { return Ok(cached.clone_ref(py)); } + let extensions = match Extensions::from_raw_extensions(raw_extensions.as_ref()) { + Ok(extensions) => extensions, + Err(oid) => { + let oid_obj = oid_to_py_oid(py, &oid)?; + return Err(exceptions::DuplicateExtension::new_err(( + format!("Duplicate {} extension found", oid), + oid_obj.into_py(py), + ))); + } + }; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let exts = pyo3::types::PyList::empty(py); - let mut seen_oids = HashSet::new(); - if let Some(raw_exts) = raw_exts { - for raw_ext in raw_exts.unwrap_read().clone() { + if let Some(extensions) = extensions { + for raw_ext in extensions.as_raw().unwrap_read().clone() { let oid_obj = oid_to_py_oid(py, &raw_ext.extn_id)?; - if seen_oids.contains(&raw_ext.extn_id) { - return Err(exceptions::DuplicateExtension::new_err(( - format!("Duplicate {} extension found", raw_ext.extn_id), - oid_obj.into_py(py), - ))); - } - let extn_value = match parse_ext(&raw_ext.extn_id, raw_ext.extn_value)? { Some(e) => e, None => x509_module.call_method1( @@ -424,7 +426,6 @@ pub(crate) fn parse_and_cache_extensions< (oid_obj, raw_ext.critical, extn_value), )?; exts.append(ext_obj)?; - seen_oids.insert(raw_ext.extn_id); } } let extensions = x509_module @@ -445,7 +446,7 @@ pub(crate) fn encode_extensions< py: pyo3::Python<'p>, py_exts: &'p pyo3::PyAny, encode_ext: F, -) -> pyo3::PyResult>> { +) -> pyo3::PyResult>> { let unrecognized_extension_type: &pyo3::types::PyType = py .import(pyo3::intern!(py, "cryptography.x509"))? .getattr(pyo3::intern!(py, "UnrecognizedExtension"))? diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index e2c4b9c09b9e..6bb08779a0a2 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -260,11 +260,13 @@ impl CertificateRevocationList { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { + let tbs_cert_list = &self.owned.borrow_value().tbs_cert_list; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.owned.borrow_value().tbs_cert_list.crl_extensions, + &tbs_cert_list.raw_crl_extensions, |oid, ext_data| match *oid { oid::CRL_NUMBER_OID => { let bignum = asn1::parse_single::>(ext_data)?; @@ -498,7 +500,7 @@ impl RevokedCertificate { x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.owned.borrow_value().crl_entry_extensions, + &self.owned.borrow_value().raw_crl_entry_extensions, |oid, ext_data| parse_crl_entry_ext(py, oid.clone(), ext_data), ) } @@ -594,7 +596,7 @@ fn create_x509_crl( user_certificate: asn1::BigUint::new(py_uint_to_big_endian_bytes(py, serial_number)?) .unwrap(), revocation_date: x509::certificate::time_from_py(py, py_revocation_date)?, - crl_entry_extensions: x509::common::encode_extensions( + raw_crl_entry_extensions: x509::common::encode_extensions( py, py_revoked_cert.getattr(pyo3::intern!(py, "extensions"))?, extensions::encode_extension, @@ -618,7 +620,7 @@ fn create_x509_crl( asn1::SequenceOfWriter::new(revoked_certs), )) }, - crl_extensions: x509::common::encode_extensions( + raw_crl_extensions: x509::common::encode_extensions( py, builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 35aee5c9e501..7ceed3511daa 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -211,7 +211,7 @@ impl CertificateSigningRequest { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { - let exts = self + let raw_exts = self .raw .borrow_value() .csr_info @@ -222,9 +222,12 @@ impl CertificateSigningRequest { ) })?; - x509::parse_and_cache_extensions(py, &mut self.cached_extensions, &exts, |oid, ext_data| { - certificate::parse_cert_ext(py, oid.clone(), ext_data) - }) + x509::parse_and_cache_extensions( + py, + &mut self.cached_extensions, + &raw_exts, + |oid, ext_data| certificate::parse_cert_ext(py, oid.clone(), ext_data), + ) } #[getter] diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index 235ac6ee10c5..bd5aecad0ec7 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -108,11 +108,13 @@ impl OCSPRequest { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { + let tbs_request = &self.raw.borrow_value().tbs_request; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self.raw.borrow_value().tbs_request.request_extensions, + &tbs_request.raw_request_extensions, |oid, value| { match *oid { oid::NONCE_OID => { @@ -228,7 +230,7 @@ fn create_ocsp_request( request_list: common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( &reqs, )), - request_extensions: extensions, + raw_request_extensions: extensions, }, optional_signature: None, }; diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 942822b48168..728eb92cef38 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -316,20 +316,22 @@ impl OCSPResponse { #[getter] fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult { self.requires_successful_response()?; + + let response_data = &self + .raw + .borrow_value() + .response_bytes + .as_ref() + .unwrap() + .response + .get() + .tbs_response_data; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_extensions, - &self - .raw - .borrow_value() - .response_bytes - .as_ref() - .unwrap() - .response - .get() - .tbs_response_data - .response_extensions, + &response_data.raw_response_extensions, |oid, ext_data| { match oid { &oid::NONCE_OID => { @@ -362,11 +364,12 @@ impl OCSPResponse { .response .get(), )?; + let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; x509::parse_and_cache_extensions( py, &mut self.cached_single_extensions, - &single_resp.single_extensions, + &single_resp.raw_single_extensions, |oid, ext_data| match oid { &oid::SIGNED_CERTIFICATE_TIMESTAMPS_OID => { let contents = asn1::parse_single::<&[u8]>(ext_data)?; @@ -628,7 +631,7 @@ fn create_ocsp_response( cert_status, next_update, this_update, - single_extensions: None, + raw_single_extensions: None, }]; borrowed_cert = responder_cert.borrow(); @@ -669,7 +672,7 @@ fn create_ocsp_response( responses: common::Asn1ReadableOrWritable::new_write(asn1::SequenceOfWriter::new( responses, )), - response_extensions: x509::common::encode_extensions( + raw_response_extensions: x509::common::encode_extensions( py, builder.getattr(pyo3::intern!(py, "_extensions"))?, extensions::encode_extension, diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index a32dfca930cf..b33e09ce518f 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -1000,6 +1000,20 @@ def test_tbs_certificate_bytes(self, backend): cert.signature_hash_algorithm, ) + def test_tbs_precertificate_bytes_duplicate_extensions_raises( + self, backend + ): + cert = _load_cert( + os.path.join("x509", "custom", "two_basic_constraints.pem"), + x509.load_pem_x509_certificate, + ) + + with pytest.raises( + x509.DuplicateExtension, + match="Duplicate 2.5.29.19 extension found", + ): + cert.tbs_precertificate_bytes + def test_tbs_precertificate_bytes_no_extensions_raises(self, backend): cert = _load_cert( os.path.join("x509", "v1_cert.pem"), From a8aaf19c3eb8d2ee7855d6b2c09ebe32f86aa7d5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 10 May 2023 15:20:23 -0400 Subject: [PATCH 752/827] Make Extensions contain an optional RawExtensions (#8900) This matter models how x.509 represents these things, and will make it easier to make Extensions an iterator in the future --- src/rust/cryptography-x509/src/certificate.rs | 2 +- src/rust/cryptography-x509/src/extensions.rs | 20 +++++++++---------- src/rust/src/x509/certificate.rs | 19 +++++++++++------- src/rust/src/x509/common.rs | 4 ++-- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/rust/cryptography-x509/src/certificate.rs b/src/rust/cryptography-x509/src/certificate.rs index 59960242b202..2a5616e93ef9 100644 --- a/src/rust/cryptography-x509/src/certificate.rs +++ b/src/rust/cryptography-x509/src/certificate.rs @@ -36,7 +36,7 @@ pub struct TbsCertificate<'a> { } impl<'a> TbsCertificate<'a> { - pub fn extensions(&'a self) -> Result>, asn1::ObjectIdentifier> { + pub fn extensions(&'a self) -> Result, asn1::ObjectIdentifier> { Extensions::from_raw_extensions(self.raw_extensions.as_ref()) } } diff --git a/src/rust/cryptography-x509/src/extensions.rs b/src/rust/cryptography-x509/src/extensions.rs index b1138fec206e..51c283af352c 100644 --- a/src/rust/cryptography-x509/src/extensions.rs +++ b/src/rust/cryptography-x509/src/extensions.rs @@ -18,7 +18,7 @@ pub type RawExtensions<'a> = common::Asn1ReadableOrWritable< /// /// In particular, an `Extensions` cannot be constructed from a `RawExtensions` /// that contains duplicated extensions (by OID). -pub struct Extensions<'a>(RawExtensions<'a>); +pub struct Extensions<'a>(Option>); impl<'a> Extensions<'a> { /// Create an `Extensions` from the given `RawExtensions`. @@ -27,7 +27,7 @@ impl<'a> Extensions<'a> { /// OID, if there are any duplicates. pub fn from_raw_extensions( raw: Option<&RawExtensions<'a>>, - ) -> Result, asn1::ObjectIdentifier> { + ) -> Result { match raw { Some(raw_exts) => { let mut seen_oids = HashSet::new(); @@ -38,22 +38,22 @@ impl<'a> Extensions<'a> { } } - Ok(Some(Self(raw_exts.clone()))) + Ok(Self(Some(raw_exts.clone()))) } - None => Ok(None), + None => Ok(Self(None)), } } /// Retrieves the extension identified by the given OID, /// or None if the extension is not present (or no extensions are present). pub fn get_extension(&self, oid: &asn1::ObjectIdentifier) -> Option { - let mut extensions = self.0.unwrap_read().clone(); - - extensions.find(|ext| &ext.extn_id == oid) + self.0 + .as_ref() + .and_then(|exts| exts.unwrap_read().clone().find(|ext| &ext.extn_id == oid)) } /// Returns a reference to the underlying extensions. - pub fn as_raw(&self) -> &RawExtensions<'_> { + pub fn as_raw(&self) -> &Option> { &self.0 } } @@ -245,9 +245,7 @@ mod tests { let der = asn1::write_single(&extensions).unwrap(); let extensions: Extensions = - Extensions::from_raw_extensions(Some(&asn1::parse_single(&der).unwrap())) - .unwrap() - .unwrap(); + Extensions::from_raw_extensions(Some(&asn1::parse_single(&der).unwrap())).unwrap(); assert!(&extensions.get_extension(&BASIC_CONSTRAINTS_OID).is_some()); assert!(&extensions diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 3784b1c9a4b0..dbe761fb9b19 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -194,8 +194,17 @@ impl Certificate { let mut tbs_precert = val.tbs_cert.clone(); // Remove the SCT list extension match val.tbs_cert.extensions() { - Ok(Some(extensions)) => { - let readable_extensions = extensions.as_raw().unwrap_read().clone(); + Ok(extensions) => { + let readable_extensions = match extensions.as_raw() { + Some(raw_exts) => raw_exts.unwrap_read().clone(), + None => { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Could not find any extensions in TBS certificate", + ), + )) + } + }; let ext_count = readable_extensions.len(); let filtered_extensions: Vec> = readable_extensions .filter(|x| x.extn_id != oid::PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS_OID) @@ -210,15 +219,11 @@ impl Certificate { let filtered_extensions: RawExtensions<'_> = Asn1ReadableOrWritable::new_write( asn1::SequenceOfWriter::new(filtered_extensions), ); + tbs_precert.raw_extensions = Some(filtered_extensions); let result = asn1::write_single(&tbs_precert)?; Ok(pyo3::types::PyBytes::new(py, &result)) } - Ok(None) => Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err( - "Could not find any extensions in TBS certificate", - ), - )), Err(oid) => { let oid_obj = oid_to_py_oid(py, &oid)?; Err(exceptions::DuplicateExtension::new_err(( diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 94ae58d386c5..3c42f0c5d31e 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -410,8 +410,8 @@ pub(crate) fn parse_and_cache_extensions< let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; let exts = pyo3::types::PyList::empty(py); - if let Some(extensions) = extensions { - for raw_ext in extensions.as_raw().unwrap_read().clone() { + if let Some(extensions) = extensions.as_raw() { + for raw_ext in extensions.unwrap_read().clone() { let oid_obj = oid_to_py_oid(py, &raw_ext.extn_id)?; let extn_value = match parse_ext(&raw_ext.extn_id, raw_ext.extn_value)? { From 998e86659ae750562ecc0bcf0eabd1828fd5c9ed Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 00:17:31 +0000 Subject: [PATCH 753/827] Bump BoringSSL and/or OpenSSL in CI (#8905) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41fac5d7beff..521295b9d9f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 09, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "2aae3f58b42e75690f28853f712a2e204857b7f6"}} - # Latest commit on the OpenSSL master branch, as of May 10, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "8c63b14296f117b07781509ced529a8955d78fb9"}} + # Latest commit on the BoringSSL master branch, as of May 11, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c6dd304d2c628277b710ab50ce9eed660696756d"}} + # Latest commit on the OpenSSL master branch, as of May 11, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "20d4dc8898edc12806ead2100ac09b907662aff6"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From cfee3c85a7d7e9c60f8041678c3070380ac3ca3d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 11 May 2023 08:29:39 +0800 Subject: [PATCH 754/827] add RSA PSS SHA1 hash algorithm + SHA1 MGF1 test vector (#8906) --- docs/development/test-vectors.rst | 2 ++ .../x509/ee-pss-sha1-cert.pem | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/ee-pss-sha1-cert.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index c84bdeff49fb..2a90eb30bedf 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -289,6 +289,8 @@ X.509 bytes from ``cryptography-scts.pem``, with the SCT list extension removed. * ``belgian-eid-invalid-visiblestring.pem`` - A certificate with UTF-8 bytes in a ``VisibleString`` type. +* ``ee-pss-sha1-cert.pem`` - An RSA PSS certificate using a SHA1 signature and + SHA1 for MGF1 from the OpenSSL test suite. Custom X.509 Vectors ~~~~~~~~~~~~~~~~~~~~ diff --git a/vectors/cryptography_vectors/x509/ee-pss-sha1-cert.pem b/vectors/cryptography_vectors/x509/ee-pss-sha1-cert.pem new file mode 100644 index 000000000000..b504aea5813a --- /dev/null +++ b/vectors/cryptography_vectors/x509/ee-pss-sha1-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIBAjANBgkqhkiG9w0BAQowADANMQswCQYDVQQDDAJDQTAg +Fw0xNzA0MjQyMTE5NDlaGA8yMTE3MDQyNTIxMTk0OVowEzERMA8GA1UEAwwIUFNT +LVNIQTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lYYYWu3tss +D9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT5Rcf/w3G +Q/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1lDz9mjsI2 +oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1U7OWaoIb +FYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5ep5LR2in +Kcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tniIQPYf55 +NB9KiR+3AgMBAAGjdzB1MB0GA1UdDgQWBBTnm+IqrYpsOst2UeWOB5gil+FzojAf +BgNVHSMEGDAWgBS0ETPx1+Je91OeICIQT4YGvx/JXjAJBgNVHRMEAjAAMBMGA1Ud +JQQMMAoGCCsGAQUFBwMBMBMGA1UdEQQMMAqCCFBTUy1TSEExMA0GCSqGSIb3DQEB +CjAAA4IBAQCC4qIOu7FVYMvRx13IrvzviF+RFRRfAD5NZSPFw5+riLMeRlA4Pdw/ +vCctNIpqjDaSFu8BRTUuyHPXSIvPo0Rl64TsfQNHP1Ut1/8XCecYCEBx/ROJHbM5 +YjoHMCAy+mR3f4BK1827Mp5U/wRJ6ljvE5EbALQ06ZEuIO6zqEAO6AROUCjWSyFd +z9fkEHS0XmploIywH4QXR7X+ueWOE3n76x+vziM4qoGsYxy0sxePfTWM1DscT1Kt +l5skZdZEKo6J8m8ImxfmtLutky2/tw5cdeWbovX3xfipabjPqpzO9Tf9aa4iblJa +AEQwRss+D6ixFO1rNKs1fjFva7A+9lrO +-----END CERTIFICATE----- From 1ef3cdb616c7a304e75c89ad458e49c1fbd5943f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 11 May 2023 09:09:56 +0800 Subject: [PATCH 755/827] support X.509 certificate PSS signing (#8888) * support X.509 certificate PSS signing no CSR, CRL, etc * handle PSS.(MAX_LENGTH, DIGEST_LENGTH), review feedback * name the kwarg * test improvements * skip if sha3 isn't supported --- CHANGELOG.rst | 3 + docs/x509/reference.rst | 18 +- .../hazmat/bindings/_rust/x509.pyi | 2 + src/cryptography/x509/base.py | 14 +- src/rust/cryptography-x509/src/common.rs | 18 +- src/rust/src/pkcs7.rs | 17 +- src/rust/src/x509/certificate.rs | 7 +- src/rust/src/x509/crl.rs | 16 +- src/rust/src/x509/csr.rs | 15 +- src/rust/src/x509/ocsp_resp.rs | 15 +- src/rust/src/x509/sign.rs | 145 ++++++++++++++-- tests/x509/test_x509.py | 163 ++++++++++++++++++ 12 files changed, 405 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d4fd576242b0..5073ce32b98e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,6 +23,9 @@ Changelog * Added support for obtaining X.509 certificate signature algorithm parameters (including PSS) via :meth:`~cryptography.x509.Certificate.signature_algorithm_parameters`. +* Support signing :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` + X.509 certificates via the new keyword-only argument ``rsa_padding`` on + :meth:`~cryptography.x509.CertificateBuilder.sign`. .. _v40-0-2: diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 647666c5c67e..e14c8ffc1093 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -872,7 +872,7 @@ X.509 Certificate Builder :param critical: Set to ``True`` if the extension must be understood and handled by whoever reads the certificate. - .. method:: sign(private_key, algorithm) + .. method:: sign(private_key, algorithm, *, rsa_padding=None) Sign the certificate using the CA's private key. @@ -891,6 +891,22 @@ X.509 Certificate Builder :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` otherwise. + :param rsa_padding: + + .. versionadded:: 41.0.0 + + This is a keyword-only argument. If ``private_key`` is an + ``RSAPrivateKey`` then this can be set to either + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15` or + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` to sign + with those respective paddings. If this is ``None`` then RSA + keys will default to ``PKCS1v15`` padding. All other key types **must** + not pass a value other than ``None``. + + :type rsa_padding: ``None``, + :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`, + or :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` + :returns: :class:`~cryptography.x509.Certificate` diff --git a/src/cryptography/hazmat/bindings/_rust/x509.pyi b/src/cryptography/hazmat/bindings/_rust/x509.pyi index 71c8d5c22c3e..24b2f5e3a78c 100644 --- a/src/cryptography/hazmat/bindings/_rust/x509.pyi +++ b/src/cryptography/hazmat/bindings/_rust/x509.pyi @@ -6,6 +6,7 @@ import typing from cryptography import x509 from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric.padding import PSS, PKCS1v15 from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes def load_pem_x509_certificate(data: bytes) -> x509.Certificate: ... @@ -23,6 +24,7 @@ def create_x509_certificate( builder: x509.CertificateBuilder, private_key: PrivateKeyTypes, hash_algorithm: typing.Optional[hashes.HashAlgorithm], + padding: typing.Optional[typing.Union[PKCS1v15, PSS]], ) -> x509.Certificate: ... def create_x509_csr( builder: x509.CertificateSigningRequestBuilder, diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 64453eb70aa5..576385e088d8 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -924,6 +924,10 @@ def sign( private_key: CertificateIssuerPrivateKeyTypes, algorithm: typing.Optional[_AllowedHashTypes], backend: typing.Any = None, + *, + rsa_padding: typing.Optional[ + typing.Union[padding.PSS, padding.PKCS1v15] + ] = None, ) -> Certificate: """ Signs the certificate using the CA's private key. @@ -946,7 +950,15 @@ def sign( if self._public_key is None: raise ValueError("A certificate must have a public key") - return rust_x509.create_x509_certificate(self, private_key, algorithm) + if rsa_padding is not None: + if not isinstance(rsa_padding, (padding.PSS, padding.PKCS1v15)): + raise TypeError("Padding must be PSS or PKCS1v15") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Padding is only supported for RSA keys") + + return rust_x509.create_x509_certificate( + self, private_key, algorithm, rsa_padding + ) class CertificateRevocationListBuilder: diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index d099716599ea..60856b7efd03 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -6,7 +6,7 @@ use crate::oid; use asn1::Asn1DefinedByWritable; use std::marker::PhantomData; -#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone, Eq)] +#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone, Eq, Debug)] pub struct AlgorithmIdentifier<'a> { pub oid: asn1::DefinedByMarker, #[defined_by(oid)] @@ -19,7 +19,7 @@ impl AlgorithmIdentifier<'_> { } } -#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Eq, Hash, Clone)] +#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Eq, Hash, Clone, Debug)] pub enum AlgorithmParameters<'a> { #[defined_by(oid::SHA1_OID)] Sha1(asn1::Null), @@ -31,6 +31,14 @@ pub enum AlgorithmParameters<'a> { Sha384(asn1::Null), #[defined_by(oid::SHA512_OID)] Sha512(asn1::Null), + #[defined_by(oid::SHA3_224_OID)] + Sha3_224(asn1::Null), + #[defined_by(oid::SHA3_256_OID)] + Sha3_256(asn1::Null), + #[defined_by(oid::SHA3_384_OID)] + Sha3_384(asn1::Null), + #[defined_by(oid::SHA3_512_OID)] + Sha3_512(asn1::Null), #[defined_by(oid::ED25519_OID)] Ed25519, @@ -225,7 +233,7 @@ pub const PSS_SHA1_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier { // This is defined as an AlgorithmIdentifier in RFC 4055, // but the mask generation algorithm **must** contain an AlgorithmIdentifier // in its params, so we define it this way. -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq)] +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug)] pub struct MaskGenAlgorithm<'a> { pub oid: asn1::ObjectIdentifier, pub params: AlgorithmIdentifier<'a>, @@ -245,7 +253,7 @@ pub const PSS_SHA1_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm { // mgf1SHA1Identifier, // saltLength [2] INTEGER DEFAULT 20, // trailerField [3] INTEGER DEFAULT 1 } -#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq)] +#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug)] pub struct RsaPssParameters<'a> { #[explicit(0)] #[default(PSS_SHA1_HASH_ALG)] @@ -258,7 +266,7 @@ pub struct RsaPssParameters<'a> { pub salt_length: u16, #[explicit(3)] #[default(1u8)] - _trailer_field: u8, + pub _trailer_field: u8, } /// A VisibleString ASN.1 element whose contents is not validated as meeting the diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 6bc90173fade..17a83fd16bb2 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -130,7 +130,13 @@ fn sign_and_serialize<'p>( { ( None, - x509::sign::sign_data(py, py_private_key, py_hash_alg, &data_with_header)?, + x509::sign::sign_data( + py, + py_private_key, + py_hash_alg, + py.None().into_ref(py), + &data_with_header, + )?, ) } else { let mut authenticated_attrs = vec![]; @@ -175,7 +181,13 @@ fn sign_and_serialize<'p>( Some(common::Asn1ReadableOrWritable::new_write( asn1::SetOfWriter::new(authenticated_attrs), )), - x509::sign::sign_data(py, py_private_key, py_hash_alg, &signed_data)?, + x509::sign::sign_data( + py, + py_private_key, + py_hash_alg, + py.None().into_ref(py), + &signed_data, + )?, ) }; @@ -201,6 +213,7 @@ fn sign_and_serialize<'p>( py, py_private_key, py_hash_alg, + py.None().into_ref(py), )?, encrypted_digest: signature, unauthenticated_attributes: None, diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index dbe761fb9b19..f77f141faadb 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -1002,8 +1002,10 @@ fn create_x509_certificate( builder: &pyo3::PyAny, private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, + rsa_padding: &pyo3::PyAny, ) -> CryptographyResult { - let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; + let sigalg = + x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm, rsa_padding)?; let serialization_mod = py.import(pyo3::intern!( py, "cryptography.hazmat.primitives.serialization" @@ -1056,7 +1058,8 @@ fn create_x509_certificate( }; let tbs_bytes = asn1::write_single(&tbs_cert)?; - let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; + let signature = + x509::sign::sign_data(py, private_key, hash_algorithm, rsa_padding, &tbs_bytes)?; let data = asn1::write_single(&cryptography_x509::certificate::Certificate { tbs_cert, signature_alg: sigalg, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 6bb08779a0a2..1331d3377cba 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -580,8 +580,12 @@ fn create_x509_crl( private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, ) -> CryptographyResult { - let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; - + let sigalg = x509::sign::compute_signature_algorithm( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + )?; let mut revoked_certs = vec![]; for py_revoked_cert in builder .getattr(pyo3::intern!(py, "_revoked_certificates"))? @@ -628,7 +632,13 @@ fn create_x509_crl( }; let tbs_bytes = asn1::write_single(&tbs_cert_list)?; - let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; + let signature = x509::sign::sign_data( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + &tbs_bytes, + )?; let data = asn1::write_single(&crl::CertificateRevocationList { tbs_cert_list, signature_algorithm: sigalg, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 7ceed3511daa..110acf3a1937 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -294,7 +294,12 @@ fn create_x509_csr( private_key: &pyo3::PyAny, hash_algorithm: &pyo3::PyAny, ) -> CryptographyResult { - let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; + let sigalg = x509::sign::compute_signature_algorithm( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + )?; let serialization_mod = py.import(pyo3::intern!( py, "cryptography.hazmat.primitives.serialization" @@ -364,7 +369,13 @@ fn create_x509_csr( }; let tbs_bytes = asn1::write_single(&csr_info)?; - let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; + let signature = x509::sign::sign_data( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + &tbs_bytes, + )?; let data = asn1::write_single(&Csr { csr_info, signature_alg: sigalg, diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 728eb92cef38..f2a86241e4fd 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -679,9 +679,20 @@ fn create_ocsp_response( )?, }; - let sigalg = x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm)?; + let sigalg = x509::sign::compute_signature_algorithm( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + )?; let tbs_bytes = asn1::write_single(&tbs_response_data)?; - let signature = x509::sign::sign_data(py, private_key, hash_algorithm, &tbs_bytes)?; + let signature = x509::sign::sign_data( + py, + private_key, + hash_algorithm, + py.None().into_ref(py), + &tbs_bytes, + )?; if !responder_cert .call_method0(pyo3::intern!(py, "public_key"))? diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 5c69ecedf4fe..c0b0ec5de3fe 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -4,7 +4,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::exceptions; -use cryptography_x509::common; +use cryptography_x509::{common, oid}; #[derive(Debug, PartialEq)] pub(crate) enum KeyType { @@ -119,14 +119,88 @@ fn identify_hash_type( } } +fn compute_pss_salt_length<'p>( + py: pyo3::Python<'p>, + private_key: &'p pyo3::PyAny, + hash_algorithm: &'p pyo3::PyAny, + rsa_padding: &'p pyo3::PyAny, +) -> pyo3::PyResult { + let padding_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; + let maxlen = padding_mod.getattr(pyo3::intern!(py, "_MaxLength"))?; + let digestlen = padding_mod.getattr(pyo3::intern!(py, "_DigestLength"))?; + let py_saltlen = rsa_padding.getattr(pyo3::intern!(py, "_salt_length"))?; + if py_saltlen.is_instance(maxlen)? { + padding_mod + .getattr(pyo3::intern!(py, "calculate_max_pss_salt_length"))? + .call1((private_key, hash_algorithm))? + .extract::() + } else if py_saltlen.is_instance(digestlen)? { + hash_algorithm + .getattr(pyo3::intern!(py, "digest_size"))? + .extract::() + } else if py_saltlen.is_instance(py.get_type::())? { + py_saltlen.extract::() + } else { + Err(pyo3::exceptions::PyTypeError::new_err( + "salt_length must be an int, MaxLength, or DigestLength.", + )) + } +} + pub(crate) fn compute_signature_algorithm<'p>( py: pyo3::Python<'p>, private_key: &'p pyo3::PyAny, hash_algorithm: &'p pyo3::PyAny, + rsa_padding: &'p pyo3::PyAny, ) -> pyo3::PyResult> { let key_type = identify_key_type(py, private_key)?; let hash_type = identify_hash_type(py, hash_algorithm)?; + let pss_type: &pyo3::types::PyType = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))? + .getattr(pyo3::intern!(py, "PSS"))? + .extract()?; + // If this is RSA-PSS we need to compute the signature algorithm from the + // parameters provided in rsa_padding. + if !rsa_padding.is_none() && rsa_padding.is_instance(pss_type)? { + let hash_alg_params = identify_alg_params_for_hash_type(hash_type)?; + let hash_algorithm_id = common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: hash_alg_params, + }; + let salt_length = compute_pss_salt_length(py, private_key, hash_algorithm, rsa_padding)?; + let py_mgf_alg = rsa_padding + .getattr(pyo3::intern!(py, "_mgf"))? + .getattr(pyo3::intern!(py, "_algorithm"))?; + let mgf_hash_type = identify_hash_type(py, py_mgf_alg)?; + let mgf_alg = common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params: identify_alg_params_for_hash_type(mgf_hash_type)?, + }; + let params = + common::AlgorithmParameters::RsaPss(Some(Box::new(common::RsaPssParameters { + hash_algorithm: hash_algorithm_id, + mask_gen_algorithm: common::MaskGenAlgorithm { + oid: oid::MGF1_OID, + params: mgf_alg, + }, + salt_length, + _trailer_field: 1, + }))); + + return Ok(common::AlgorithmIdentifier { + oid: asn1::DefinedByMarker::marker(), + params, + }); + } + // It's not an RSA PSS signature, so we compute the signature algorithm from + // the union of key type and hash type. match (key_type, hash_type) { (KeyType::Ed25519, HashType::None) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), @@ -238,6 +312,7 @@ pub(crate) fn sign_data<'p>( py: pyo3::Python<'p>, private_key: &'p pyo3::PyAny, hash_algorithm: &'p pyo3::PyAny, + rsa_padding: &'p pyo3::PyAny, data: &[u8], ) -> pyo3::PyResult<&'p [u8]> { let key_type = identify_key_type(py, private_key)?; @@ -257,14 +332,17 @@ pub(crate) fn sign_data<'p>( private_key.call_method1(pyo3::intern!(py, "sign"), (data, ecdsa))? } KeyType::Rsa => { - let padding_mod = py.import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))?; - let pkcs1v15 = padding_mod - .getattr(pyo3::intern!(py, "PKCS1v15"))? - .call0()?; - private_key.call_method1(pyo3::intern!(py, "sign"), (data, pkcs1v15, hash_algorithm))? + let mut padding = rsa_padding; + if padding.is_none() { + let padding_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; + padding = padding_mod + .getattr(pyo3::intern!(py, "PKCS1v15"))? + .call0()?; + } + private_key.call_method1(pyo3::intern!(py, "sign"), (data, padding, hash_algorithm))? } KeyType::Dsa => { private_key.call_method1(pyo3::intern!(py, "sign"), (data, hash_algorithm))? @@ -435,10 +513,29 @@ fn identify_key_hash_type_for_algorithm_params( } } +fn identify_alg_params_for_hash_type( + hash_type: HashType, +) -> pyo3::PyResult> { + match hash_type { + HashType::Sha224 => Ok(common::AlgorithmParameters::Sha224(())), + HashType::Sha256 => Ok(common::AlgorithmParameters::Sha256(())), + HashType::Sha384 => Ok(common::AlgorithmParameters::Sha384(())), + HashType::Sha512 => Ok(common::AlgorithmParameters::Sha512(())), + HashType::Sha3_224 => Ok(common::AlgorithmParameters::Sha3_224(())), + HashType::Sha3_256 => Ok(common::AlgorithmParameters::Sha3_256(())), + HashType::Sha3_384 => Ok(common::AlgorithmParameters::Sha3_384(())), + HashType::Sha3_512 => Ok(common::AlgorithmParameters::Sha3_512(())), + HashType::None => Err(pyo3::exceptions::PyTypeError::new_err( + "Algorithm must be a registered hash algorithm, not None.", + )), + } +} + #[cfg(test)] mod tests { use super::{ - identify_key_hash_type_for_algorithm_params, py_hash_name_from_hash_type, HashType, KeyType, + identify_alg_params_for_hash_type, identify_key_hash_type_for_algorithm_params, + py_hash_name_from_hash_type, HashType, KeyType, }; use cryptography_x509::{common, oid}; @@ -603,6 +700,34 @@ mod tests { ); } + #[test] + fn test_identify_alg_params_for_hash_type() { + for (hash, params) in [ + (HashType::Sha224, common::AlgorithmParameters::Sha224(())), + (HashType::Sha256, common::AlgorithmParameters::Sha256(())), + (HashType::Sha384, common::AlgorithmParameters::Sha384(())), + (HashType::Sha512, common::AlgorithmParameters::Sha512(())), + ( + HashType::Sha3_224, + common::AlgorithmParameters::Sha3_224(()), + ), + ( + HashType::Sha3_256, + common::AlgorithmParameters::Sha3_256(()), + ), + ( + HashType::Sha3_384, + common::AlgorithmParameters::Sha3_384(()), + ), + ( + HashType::Sha3_512, + common::AlgorithmParameters::Sha3_512(()), + ), + ] { + assert_eq!(identify_alg_params_for_hash_type(hash).unwrap(), params); + } + } + #[test] fn test_py_hash_name_from_hash_type() { for (hash, name) in [ diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index b33e09ce518f..19a854e24a98 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -765,6 +765,21 @@ def test_load_cert_pub_key(self, backend): cert.signature_hash_algorithm, ) + def test_load_pss_sha1_mgf1_sha1(self, backend): + cert = _load_cert( + os.path.join("x509", "ee-pss-sha1-cert.pem"), + x509.load_pem_x509_certificate, + ) + assert isinstance(cert, x509.Certificate) + pub_key = cert.public_key() + assert isinstance(pub_key, rsa.RSAPublicKey) + pss = cert.signature_algorithm_parameters + assert isinstance(pss, padding.PSS) + assert isinstance(pss._mgf, padding.MGF1) + assert isinstance(pss._mgf._algorithm, hashes.SHA1) + assert pss._salt_length == 20 + assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) + def test_invalid_mgf(self, backend): cert = _load_cert( os.path.join("x509", "custom", "rsa_pss_cert_invalid_mgf.der"), @@ -2404,6 +2419,154 @@ def test_extreme_times( # GENERALIZED TIME assert parsed.not_after_tag == 0x18 + @pytest.mark.parametrize( + ("alg", "mgf_alg"), + [ + (hashes.SHA512(), hashes.SHA256()), + (hashes.SHA3_512(), hashes.SHA3_256()), + ], + ) + def test_sign_pss( + self, rsa_key_2048: rsa.RSAPrivateKey, alg, mgf_alg, backend + ): + if not backend.signature_hash_supported(alg): + pytest.skip(f"{alg} signature not supported") + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(777) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + ) + pss = padding.PSS( + mgf=padding.MGF1(mgf_alg), salt_length=alg.digest_size + ) + cert = builder.sign(rsa_key_2048, alg, rsa_padding=pss) + pk = cert.public_key() + assert isinstance(pk, rsa.RSAPublicKey) + assert isinstance(cert.signature_hash_algorithm, type(alg)) + cert_params = cert.signature_algorithm_parameters + assert isinstance(cert_params, padding.PSS) + assert cert_params._salt_length == pss._salt_length + assert isinstance(cert_params._mgf, padding.MGF1) + assert isinstance(cert_params._mgf._algorithm, type(mgf_alg)) + pk.verify( + cert.signature, + cert.tbs_certificate_bytes, + cert_params, + alg, + ) + + @pytest.mark.parametrize( + ("padding_len", "computed_len"), + [ + (padding.PSS.MAX_LENGTH, 222), + (padding.PSS.DIGEST_LENGTH, 32), + ], + ) + def test_sign_pss_length_options( + self, + rsa_key_2048: rsa.RSAPrivateKey, + padding_len, + computed_len, + backend, + ): + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(777) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + ) + pss = padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), salt_length=padding_len + ) + cert = builder.sign(rsa_key_2048, hashes.SHA256(), rsa_padding=pss) + assert isinstance(cert.signature_algorithm_parameters, padding.PSS) + assert cert.signature_algorithm_parameters._salt_length == computed_len + + def test_sign_pss_auto_unsupported( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(777) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + ) + pss = padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.AUTO + ) + with pytest.raises(TypeError): + builder.sign(rsa_key_2048, hashes.SHA256(), rsa_padding=pss) + + def test_sign_invalid_padding( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(777) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + ) + with pytest.raises(TypeError): + builder.sign( + rsa_key_2048, + hashes.SHA256(), + rsa_padding=b"notapadding", # type: ignore[arg-type] + ) + eckey = ec.generate_private_key(ec.SECP256R1()) + with pytest.raises(TypeError): + builder.sign( + eckey, hashes.SHA256(), rsa_padding=padding.PKCS1v15() + ) + + def test_sign_pss_hash_none( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(777) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + ) + pss = padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=32) + with pytest.raises(TypeError): + builder.sign(rsa_key_2048, None, rsa_padding=pss) + def test_no_subject_name(self, rsa_key_2048: rsa.RSAPrivateKey, backend): subject_private_key = rsa_key_2048 builder = ( From 9a14c88898e5a002dc1633df81b87e3e33382979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 13:12:12 +0000 Subject: [PATCH 756/827] Bump mypy from 1.2.0 to 1.3.0 (#8910) Bumps [mypy](https://github.com/python/mypy) from 1.2.0 to 1.3.0. - [Commits](https://github.com/python/mypy/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 12b2f942e703..05a0fedd6cd3 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -68,7 +68,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.1.0 # via jaraco-classes -mypy==1.2.0 +mypy==1.3.0 # via cryptography (pyproject.toml) mypy-extensions==1.0.0 # via From 46eb804a3d27643c8923a1f331ef8b81095af9af Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 20:20:01 -0400 Subject: [PATCH 757/827] Bump BoringSSL and/or OpenSSL in CI (#8911) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 521295b9d9f4..5034759188d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 11, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c6dd304d2c628277b710ab50ce9eed660696756d"}} - # Latest commit on the OpenSSL master branch, as of May 11, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "20d4dc8898edc12806ead2100ac09b907662aff6"}} + # Latest commit on the BoringSSL master branch, as of May 12, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "e24491a09cbae08cccd1ad894455d547218d89c8"}} + # Latest commit on the OpenSSL master branch, as of May 12, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "13069d0144096ef8cecc82fb7fcd1a1eed93d7a8"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 0fd6cc2929e9a98c6d8d236f96ee81af40db638e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 13:13:57 +0000 Subject: [PATCH 758/827] Bump platformdirs from 3.5.0 to 3.5.1 (#8914) Bumps [platformdirs](https://github.com/platformdirs/platformdirs) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/3.5.0...3.5.1) --- updated-dependencies: - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 05a0fedd6cd3..ce17bc0fe6a4 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -89,7 +89,7 @@ pathspec==0.11.1 # check-sdist pkginfo==1.9.6 # via twine -platformdirs==3.5.0 +platformdirs==3.5.1 # via # black # virtualenv From cc4555394d594c2dc114f7ee5086caaa5e07f69e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 12 May 2023 15:38:54 -0400 Subject: [PATCH 759/827] Remove linkcheck skip (#8915) It now has a trusted issuer --- docs/conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index e67b03b6597e..4cbbde37b7ce 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -198,8 +198,6 @@ r"https://info.isl.ntt.co.jp/crypt/eng/camellia/", # Inconsistent small DH params they seem incapable of fixing r"https://www.secg.org/sec1-v2.pdf", - # Cert is issued from an untrusted root - r"https://e-trust.gosuslugi.ru", # Incomplete cert chain r"https://www.oscca.gov.cn", # Cloudflare returns 403s for all non-browser requests From 1dc587285c863d09a45129e68836181e70e15244 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 12 May 2023 15:40:15 -0400 Subject: [PATCH 760/827] Use pyo3's add_function instead of add_wrapped (#8913) Turns out the docs encourage this. --- src/rust/src/asn1.rs | 8 ++++---- src/rust/src/backend/dh.rs | 16 ++++++++-------- src/rust/src/backend/ed25519.rs | 10 +++++----- src/rust/src/backend/ed448.rs | 10 +++++----- src/rust/src/backend/kdf.rs | 4 ++-- src/rust/src/backend/x25519.rs | 10 +++++----- src/rust/src/backend/x448.rs | 10 +++++----- src/rust/src/pkcs7.rs | 4 ++-- src/rust/src/x509/certificate.rs | 8 ++++---- src/rust/src/x509/common.rs | 4 ++-- src/rust/src/x509/crl.rs | 6 +++--- src/rust/src/x509/csr.rs | 6 +++--- src/rust/src/x509/ocsp_req.rs | 4 ++-- src/rust/src/x509/ocsp_resp.rs | 4 ++-- 14 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/rust/src/asn1.rs b/src/rust/src/asn1.rs index 96e44e93ae93..bf17a5952f29 100644 --- a/src/rust/src/asn1.rs +++ b/src/rust/src/asn1.rs @@ -180,12 +180,12 @@ fn test_parse_certificate(data: &[u8]) -> Result) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let submod = pyo3::prelude::PyModule::new(py, "asn1")?; - submod.add_wrapped(pyo3::wrap_pyfunction!(parse_spki_for_data))?; + submod.add_function(pyo3::wrap_pyfunction!(parse_spki_for_data, submod)?)?; - submod.add_wrapped(pyo3::wrap_pyfunction!(decode_dss_signature))?; - submod.add_wrapped(pyo3::wrap_pyfunction!(encode_dss_signature))?; + submod.add_function(pyo3::wrap_pyfunction!(decode_dss_signature, submod)?)?; + submod.add_function(pyo3::wrap_pyfunction!(encode_dss_signature, submod)?)?; - submod.add_wrapped(pyo3::wrap_pyfunction!(test_parse_certificate))?; + submod.add_function(pyo3::wrap_pyfunction!(test_parse_certificate, submod)?)?; Ok(submod) } diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index 2daff9dcb656..b4dbaf5dded5 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -418,14 +418,14 @@ impl DHParameters { pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "dh")?; - m.add_wrapped(pyo3::wrap_pyfunction!(generate_parameters))?; - m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_der_parameters))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_pem_parameters))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_private_numbers))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_public_numbers))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_parameter_numbers))?; + m.add_function(pyo3::wrap_pyfunction!(generate_parameters, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_der_parameters, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_pem_parameters, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_numbers, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_numbers, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_parameter_numbers, m)?)?; m.add_class::()?; m.add_class::()?; diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index f10d12db23f9..8cad193c7a92 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -163,11 +163,11 @@ impl Ed25519PublicKey { pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "ed25519")?; - m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; - m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + m.add_function(pyo3::wrap_pyfunction!(generate_key, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_bytes, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_bytes, m)?)?; m.add_class::()?; m.add_class::()?; diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index 44e0240a1fa5..925a9fdb14f2 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -161,11 +161,11 @@ impl Ed448PublicKey { pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "ed448")?; - m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; - m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + m.add_function(pyo3::wrap_pyfunction!(generate_key, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_bytes, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_bytes, m)?)?; m.add_class::()?; m.add_class::()?; diff --git a/src/rust/src/backend/kdf.rs b/src/rust/src/backend/kdf.rs index 5bd5606c9f1b..de527f4671da 100644 --- a/src/rust/src/backend/kdf.rs +++ b/src/rust/src/backend/kdf.rs @@ -52,9 +52,9 @@ fn derive_scrypt<'p>( pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "kdf")?; - m.add_wrapped(pyo3::wrap_pyfunction!(derive_pbkdf2_hmac))?; + m.add_function(pyo3::wrap_pyfunction!(derive_pbkdf2_hmac, m)?)?; #[cfg(not(CRYPTOGRAPHY_IS_LIBRESSL))] - m.add_wrapped(pyo3::wrap_pyfunction!(derive_scrypt))?; + m.add_function(pyo3::wrap_pyfunction!(derive_scrypt, m)?)?; Ok(m) } diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index 0a62182b1be8..faf21ffddfe9 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -152,11 +152,11 @@ impl X25519PublicKey { pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "x25519")?; - m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; - m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + m.add_function(pyo3::wrap_pyfunction!(generate_key, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_bytes, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_bytes, m)?)?; m.add_class::()?; m.add_class::()?; diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index 0eb44b8fe8fc..456e7fa52ab8 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -151,11 +151,11 @@ impl X448PublicKey { pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let m = pyo3::prelude::PyModule::new(py, "x448")?; - m.add_wrapped(pyo3::wrap_pyfunction!(generate_key))?; - m.add_wrapped(pyo3::wrap_pyfunction!(private_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(public_key_from_ptr))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_private_bytes))?; - m.add_wrapped(pyo3::wrap_pyfunction!(from_public_bytes))?; + m.add_function(pyo3::wrap_pyfunction!(generate_key, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_bytes, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_bytes, m)?)?; m.add_class::()?; m.add_class::()?; diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 17a83fd16bb2..6a49acf98c7b 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -316,8 +316,8 @@ fn smime_canonicalize(data: &[u8], text_mode: bool) -> (Cow<'_, [u8]>, Cow<'_, [ pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { let submod = pyo3::prelude::PyModule::new(py, "pkcs7")?; - submod.add_wrapped(pyo3::wrap_pyfunction!(serialize_certificates))?; - submod.add_wrapped(pyo3::wrap_pyfunction!(sign_and_serialize))?; + submod.add_function(pyo3::wrap_pyfunction!(serialize_certificates, submod)?)?; + submod.add_function(pyo3::wrap_pyfunction!(sign_and_serialize, submod)?)?; Ok(submod) } diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index f77f141faadb..92ef6c9678bc 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -1077,10 +1077,10 @@ pub(crate) fn set_bit(vals: &mut [u8], n: usize, set: bool) { } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(load_der_x509_certificate))?; - module.add_wrapped(pyo3::wrap_pyfunction!(load_pem_x509_certificate))?; - module.add_wrapped(pyo3::wrap_pyfunction!(load_pem_x509_certificates))?; - module.add_wrapped(pyo3::wrap_pyfunction!(create_x509_certificate))?; + module.add_function(pyo3::wrap_pyfunction!(load_der_x509_certificate, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_certificate, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_certificates, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(create_x509_certificate, module)?)?; module.add_class::()?; diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index 3c42f0c5d31e..bc26dace3fa9 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -555,8 +555,8 @@ pub(crate) fn datetime_now(py: pyo3::Python<'_>) -> pyo3::PyResult pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(encode_extension_value))?; - module.add_wrapped(pyo3::wrap_pyfunction!(encode_name_bytes))?; + module.add_function(pyo3::wrap_pyfunction!(encode_extension_value, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(encode_name_bytes, module)?)?; Ok(()) } diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 1331d3377cba..9dc63aa8d6e8 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -648,9 +648,9 @@ fn create_x509_crl( } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(load_der_x509_crl))?; - module.add_wrapped(pyo3::wrap_pyfunction!(load_pem_x509_crl))?; - module.add_wrapped(pyo3::wrap_pyfunction!(create_x509_crl))?; + module.add_function(pyo3::wrap_pyfunction!(load_der_x509_crl, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_crl, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(create_x509_crl, module)?)?; module.add_class::()?; module.add_class::()?; diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 110acf3a1937..28ec67ed2075 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -385,9 +385,9 @@ fn create_x509_csr( } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(load_der_x509_csr))?; - module.add_wrapped(pyo3::wrap_pyfunction!(load_pem_x509_csr))?; - module.add_wrapped(pyo3::wrap_pyfunction!(create_x509_csr))?; + module.add_function(pyo3::wrap_pyfunction!(load_der_x509_csr, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_csr, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(create_x509_csr, module)?)?; module.add_class::()?; diff --git a/src/rust/src/x509/ocsp_req.rs b/src/rust/src/x509/ocsp_req.rs index bd5aecad0ec7..1571524edfeb 100644 --- a/src/rust/src/x509/ocsp_req.rs +++ b/src/rust/src/x509/ocsp_req.rs @@ -239,8 +239,8 @@ fn create_ocsp_request( } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(load_der_ocsp_request))?; - module.add_wrapped(pyo3::wrap_pyfunction!(create_ocsp_request))?; + module.add_function(pyo3::wrap_pyfunction!(load_der_ocsp_request, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(create_ocsp_request, module)?)?; Ok(()) } diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index f2a86241e4fd..721e0313a613 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -738,8 +738,8 @@ fn create_ocsp_response( } pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { - module.add_wrapped(pyo3::wrap_pyfunction!(load_der_ocsp_response))?; - module.add_wrapped(pyo3::wrap_pyfunction!(create_ocsp_response))?; + module.add_function(pyo3::wrap_pyfunction!(load_der_ocsp_response, module)?)?; + module.add_function(pyo3::wrap_pyfunction!(create_ocsp_response, module)?)?; Ok(()) } From 35ce702c9c2a5a0ceaaaf77bf8e9e7871511ce73 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 13 May 2023 00:18:10 +0000 Subject: [PATCH 761/827] Bump BoringSSL and/or OpenSSL in CI (#8917) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5034759188d8..3a3d8e587d95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 12, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "e24491a09cbae08cccd1ad894455d547218d89c8"}} - # Latest commit on the OpenSSL master branch, as of May 12, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "13069d0144096ef8cecc82fb7fcd1a1eed93d7a8"}} + # Latest commit on the BoringSSL master branch, as of May 13, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c215ce7e8230786e0d4ec463d95a9e44af513e6a"}} + # Latest commit on the OpenSSL master branch, as of May 13, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "2b5a546ce1960883febc51f5d2a71a8b7c1b3ab9"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 2eeb3396d3c40774f782ff2d68960f4871d812d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 May 2023 14:23:48 +0000 Subject: [PATCH 762/827] Bump ruff from 0.0.265 to 0.0.267 (#8919) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.265 to 0.0.267. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.265...v0.0.267) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index ce17bc0fe6a4..f6bea11e3112 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -138,7 +138,7 @@ rfc3986==2.0.0 # via twine rich==13.3.5 # via twine -ruff==0.0.265 +ruff==0.0.267 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From 05900ddc6e3860af3517b0e351bc841f46732f1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 May 2023 14:25:44 +0000 Subject: [PATCH 763/827] Bump pytest-xdist from 3.2.1 to 3.3.0 (#8920) Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.2.1 to 3.3.0. - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.2.1...v3.3.0) --- updated-dependencies: - dependency-name: pytest-xdist dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index f6bea11e3112..fff8548b798b 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -123,7 +123,7 @@ pytest-cov==4.0.0 # via cryptography (pyproject.toml) pytest-randomly==3.12.0 # via cryptography (pyproject.toml) -pytest-xdist==3.2.1 +pytest-xdist==3.3.0 # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine From 6cac7bcaf743d56215dd68a88f121c0811cfeb2b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 14 May 2023 08:07:26 +0800 Subject: [PATCH 764/827] refactor signature algorithm parameters into a separate function (#8921) * refactor signature algorithm parameters into a separate function this will be used in the verify_directly_issued_by PR * fix coverage with more refactoring --- src/rust/src/x509/certificate.rs | 188 +++++++++++++++++-------------- 1 file changed, 104 insertions(+), 84 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 92ef6c9678bc..4c0725023f6e 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -269,29 +269,7 @@ impl Certificate { &self, py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { - let sig_oids_to_hash = py - .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? - .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; - match &self.raw.borrow_value().signature_alg.params { - common::AlgorithmParameters::RsaPss(opt_pss) => { - let pss = opt_pss.as_ref().ok_or_else(|| { - pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") - })?; - hash_oid_py_hash(py, pss.hash_algorithm.oid().clone()) - } - _ => { - let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?); - match hash_alg { - Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from( - exceptions::UnsupportedAlgorithm::new_err(format!( - "Signature algorithm OID: {} not recognized", - self.raw.borrow_value().signature_alg.oid() - )), - )), - } - } - } + identify_signature_hash_algorithm(py, &self.raw.borrow_value().signature_alg) } #[getter] @@ -304,67 +282,7 @@ impl Certificate { &'p self, py: pyo3::Python<'p>, ) -> CryptographyResult<&'p pyo3::PyAny> { - match &self.raw.borrow_value().signature_alg.params { - common::AlgorithmParameters::RsaPss(opt_pss) => { - let pss = opt_pss.as_ref().ok_or_else(|| { - pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") - })?; - if pss.mask_gen_algorithm.oid != oid::MGF1_OID { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err(format!( - "Unsupported mask generation OID: {}", - pss.mask_gen_algorithm.oid - )), - )); - } - let py_mask_gen_hash_alg = - hash_oid_py_hash(py, pss.mask_gen_algorithm.params.oid().clone())?; - let padding = py.import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))?; - let py_mgf = padding - .getattr(pyo3::intern!(py, "MGF1"))? - .call1((py_mask_gen_hash_alg,))?; - Ok(padding - .getattr(pyo3::intern!(py, "PSS"))? - .call1((py_mgf, pss.salt_length))?) - } - common::AlgorithmParameters::RsaWithSha1(_) - | common::AlgorithmParameters::RsaWithSha1Alt(_) - | common::AlgorithmParameters::RsaWithSha224(_) - | common::AlgorithmParameters::RsaWithSha256(_) - | common::AlgorithmParameters::RsaWithSha384(_) - | common::AlgorithmParameters::RsaWithSha512(_) - | common::AlgorithmParameters::RsaWithSha3_224(_) - | common::AlgorithmParameters::RsaWithSha3_256(_) - | common::AlgorithmParameters::RsaWithSha3_384(_) - | common::AlgorithmParameters::RsaWithSha3_512(_) => { - let pkcs = py - .import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))? - .getattr(pyo3::intern!(py, "PKCS1v15"))? - .call0()?; - Ok(pkcs) - } - common::AlgorithmParameters::EcDsaWithSha224 - | common::AlgorithmParameters::EcDsaWithSha256 - | common::AlgorithmParameters::EcDsaWithSha384 - | common::AlgorithmParameters::EcDsaWithSha512 - | common::AlgorithmParameters::EcDsaWithSha3_224 - | common::AlgorithmParameters::EcDsaWithSha3_256 - | common::AlgorithmParameters::EcDsaWithSha3_384 - | common::AlgorithmParameters::EcDsaWithSha3_512 => Ok(py - .import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.ec" - ))? - .getattr(pyo3::intern!(py, "ECDSA"))? - .call1((self.signature_hash_algorithm(py)?,))?), - _ => Ok(py.None().into_ref(py)), - } + identify_signature_algorithm_parameters(py, &self.raw.borrow_value().signature_alg) } #[getter] @@ -1076,6 +994,108 @@ pub(crate) fn set_bit(vals: &mut [u8], n: usize, set: bool) { } } +pub(crate) fn identify_signature_hash_algorithm<'p>( + py: pyo3::Python<'p>, + signature_algorithm: &common::AlgorithmIdentifier<'_>, +) -> CryptographyResult<&'p pyo3::PyAny> { + let sig_oids_to_hash = py + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; + match &signature_algorithm.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + hash_oid_py_hash(py, pss.hash_algorithm.oid().clone()) + } + _ => { + let py_sig_alg_oid = oid_to_py_oid(py, signature_algorithm.oid())?; + let hash_alg = sig_oids_to_hash.get_item(py_sig_alg_oid); + match hash_alg { + Ok(data) => Ok(data), + Err(_) => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + signature_algorithm.oid() + )), + )), + } + } + } +} + +pub(crate) fn identify_signature_algorithm_parameters<'p>( + py: pyo3::Python<'p>, + signature_algorithm: &common::AlgorithmIdentifier<'_>, +) -> CryptographyResult<&'p pyo3::PyAny> { + match &signature_algorithm.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + if pss.mask_gen_algorithm.oid != oid::MGF1_OID { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "Unsupported mask generation OID: {}", + pss.mask_gen_algorithm.oid + )), + )); + } + let py_mask_gen_hash_alg = + hash_oid_py_hash(py, pss.mask_gen_algorithm.params.oid().clone())?; + let padding = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; + let py_mgf = padding + .getattr(pyo3::intern!(py, "MGF1"))? + .call1((py_mask_gen_hash_alg,))?; + Ok(padding + .getattr(pyo3::intern!(py, "PSS"))? + .call1((py_mgf, pss.salt_length))?) + } + common::AlgorithmParameters::RsaWithSha1(_) + | common::AlgorithmParameters::RsaWithSha1Alt(_) + | common::AlgorithmParameters::RsaWithSha224(_) + | common::AlgorithmParameters::RsaWithSha256(_) + | common::AlgorithmParameters::RsaWithSha384(_) + | common::AlgorithmParameters::RsaWithSha512(_) + | common::AlgorithmParameters::RsaWithSha3_224(_) + | common::AlgorithmParameters::RsaWithSha3_256(_) + | common::AlgorithmParameters::RsaWithSha3_384(_) + | common::AlgorithmParameters::RsaWithSha3_512(_) => { + let pkcs = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))? + .getattr(pyo3::intern!(py, "PKCS1v15"))? + .call0()?; + Ok(pkcs) + } + common::AlgorithmParameters::EcDsaWithSha224 + | common::AlgorithmParameters::EcDsaWithSha256 + | common::AlgorithmParameters::EcDsaWithSha384 + | common::AlgorithmParameters::EcDsaWithSha512 + | common::AlgorithmParameters::EcDsaWithSha3_224 + | common::AlgorithmParameters::EcDsaWithSha3_256 + | common::AlgorithmParameters::EcDsaWithSha3_384 + | common::AlgorithmParameters::EcDsaWithSha3_512 => { + let signature_hash_algorithm = + identify_signature_hash_algorithm(py, signature_algorithm)?; + + Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))? + .getattr(pyo3::intern!(py, "ECDSA"))? + .call1((signature_hash_algorithm,))?) + } + _ => Ok(py.None().into_ref(py)), + } +} + pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { module.add_function(pyo3::wrap_pyfunction!(load_der_x509_certificate, module)?)?; module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_certificate, module)?)?; From 2a1f42976206a39d0196786857b8d21a877ca42b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 14 May 2023 20:54:23 +0800 Subject: [PATCH 765/827] support PSS signatures in verify_directly_issued_by (#8908) --- src/rust/src/x509/certificate.rs | 2 +- src/rust/src/x509/crl.rs | 2 +- src/rust/src/x509/csr.rs | 5 +- src/rust/src/x509/sign.rs | 347 +++++++++---------------------- tests/x509/test_x509.py | 44 ++++ 5 files changed, 152 insertions(+), 248 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 4c0725023f6e..34e9ec0ec4b3 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -335,7 +335,7 @@ impl Certificate { ), )); }; - sign::verify_signature_with_oid( + sign::verify_signature_with_signature_algorithm( py, issuer.public_key(py)?, &self.raw.borrow_value().signature_alg, diff --git a/src/rust/src/x509/crl.rs b/src/rust/src/x509/crl.rs index 9dc63aa8d6e8..92301503563f 100644 --- a/src/rust/src/x509/crl.rs +++ b/src/rust/src/x509/crl.rs @@ -393,7 +393,7 @@ impl CertificateRevocationList { // being an invalid signature. sign::identify_public_key_type(py, public_key)?; - Ok(sign::verify_signature_with_oid( + Ok(sign::verify_signature_with_signature_algorithm( py, public_key, &slf.owned.borrow_value().signature_algorithm, diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs index 28ec67ed2075..2e7797f49baa 100644 --- a/src/rust/src/x509/csr.rs +++ b/src/rust/src/x509/csr.rs @@ -235,9 +235,10 @@ impl CertificateSigningRequest { slf: pyo3::PyRef<'_, Self>, py: pyo3::Python<'_>, ) -> CryptographyResult { - Ok(sign::verify_signature_with_oid( + let public_key = slf.public_key(py)?; + Ok(sign::verify_signature_with_signature_algorithm( py, - slf.public_key(py)?, + public_key, &slf.raw.borrow_value().signature_alg, slf.raw.borrow_value().signature.as_bytes(), &asn1::write_single(&slf.raw.borrow_value().csr_info)?, diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index c0b0ec5de3fe..0543004201e9 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -4,6 +4,7 @@ use crate::error::{CryptographyError, CryptographyResult}; use crate::exceptions; +use crate::x509::certificate; use cryptography_x509::{common, oid}; #[derive(Debug, PartialEq)] @@ -15,7 +16,6 @@ pub(crate) enum KeyType { Ed448, } -#[derive(Debug, PartialEq)] enum HashType { None, Sha224, @@ -351,21 +351,7 @@ pub(crate) fn sign_data<'p>( signature.extract() } -fn py_hash_name_from_hash_type(hash_type: HashType) -> Option<&'static str> { - match hash_type { - HashType::None => None, - HashType::Sha224 => Some("SHA224"), - HashType::Sha256 => Some("SHA256"), - HashType::Sha384 => Some("SHA384"), - HashType::Sha512 => Some("SHA512"), - HashType::Sha3_224 => Some("SHA3_224"), - HashType::Sha3_256 => Some("SHA3_256"), - HashType::Sha3_384 => Some("SHA3_384"), - HashType::Sha3_512 => Some("SHA3_512"), - } -} - -pub(crate) fn verify_signature_with_oid<'p>( +pub(crate) fn verify_signature_with_signature_algorithm<'p>( py: pyo3::Python<'p>, issuer_public_key: &'p pyo3::PyAny, signature_algorithm: &common::AlgorithmIdentifier<'_>, @@ -373,8 +359,7 @@ pub(crate) fn verify_signature_with_oid<'p>( data: &[u8], ) -> CryptographyResult<()> { let key_type = identify_public_key_type(py, issuer_public_key)?; - let (sig_key_type, sig_hash_type) = - identify_key_hash_type_for_algorithm_params(&signature_algorithm.params)?; + let sig_key_type = identify_key_type_for_algorithm_params(&signature_algorithm.params)?; if key_type != sig_key_type { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err( @@ -382,43 +367,30 @@ pub(crate) fn verify_signature_with_oid<'p>( ), )); } - let sig_hash_name = py_hash_name_from_hash_type(sig_hash_type); - let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - let signature_hash = match sig_hash_name { - Some(data) => hashes.getattr(data)?.call0()?, - None => py.None().into_ref(py), - }; - + let py_signature_algorithm_parameters = + certificate::identify_signature_algorithm_parameters(py, signature_algorithm)?; + let py_signature_hash_algorithm = + certificate::identify_signature_hash_algorithm(py, signature_algorithm)?; match key_type { KeyType::Ed25519 | KeyType::Ed448 => { issuer_public_key.call_method1(pyo3::intern!(py, "verify"), (signature, data))? } - KeyType::Ec => { - let ec_mod = py.import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.ec" - ))?; - let ecdsa = ec_mod - .getattr(pyo3::intern!(py, "ECDSA"))? - .call1((signature_hash,))?; - issuer_public_key.call_method1(pyo3::intern!(py, "verify"), (signature, data, ecdsa))? - } - KeyType::Rsa => { - let padding_mod = py.import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))?; - let pkcs1v15 = padding_mod - .getattr(pyo3::intern!(py, "PKCS1v15"))? - .call0()?; - issuer_public_key.call_method1( - pyo3::intern!(py, "verify"), - (signature, data, pkcs1v15, signature_hash), - )? - } + KeyType::Ec => issuer_public_key.call_method1( + pyo3::intern!(py, "verify"), + (signature, data, py_signature_algorithm_parameters), + )?, + KeyType::Rsa => issuer_public_key.call_method1( + pyo3::intern!(py, "verify"), + ( + signature, + data, + py_signature_algorithm_parameters, + py_signature_hash_algorithm, + ), + )?, KeyType::Dsa => issuer_public_key.call_method1( pyo3::intern!(py, "verify"), - (signature, data, signature_hash), + (signature, data, py_signature_hash_algorithm), )?, }; Ok(()) @@ -481,32 +453,33 @@ pub(crate) fn identify_public_key_type( } } -fn identify_key_hash_type_for_algorithm_params( +fn identify_key_type_for_algorithm_params( params: &common::AlgorithmParameters<'_>, -) -> pyo3::PyResult<(KeyType, HashType)> { +) -> pyo3::PyResult { match params { - common::AlgorithmParameters::RsaWithSha224(..) => Ok((KeyType::Rsa, HashType::Sha224)), - common::AlgorithmParameters::RsaWithSha256(..) => Ok((KeyType::Rsa, HashType::Sha256)), - common::AlgorithmParameters::RsaWithSha384(..) => Ok((KeyType::Rsa, HashType::Sha384)), - common::AlgorithmParameters::RsaWithSha512(..) => Ok((KeyType::Rsa, HashType::Sha512)), - common::AlgorithmParameters::RsaWithSha3_224(..) => Ok((KeyType::Rsa, HashType::Sha3_224)), - common::AlgorithmParameters::RsaWithSha3_256(..) => Ok((KeyType::Rsa, HashType::Sha3_256)), - common::AlgorithmParameters::RsaWithSha3_384(..) => Ok((KeyType::Rsa, HashType::Sha3_384)), - common::AlgorithmParameters::RsaWithSha3_512(..) => Ok((KeyType::Rsa, HashType::Sha3_512)), - common::AlgorithmParameters::EcDsaWithSha224 => Ok((KeyType::Ec, HashType::Sha224)), - common::AlgorithmParameters::EcDsaWithSha256 => Ok((KeyType::Ec, HashType::Sha256)), - common::AlgorithmParameters::EcDsaWithSha384 => Ok((KeyType::Ec, HashType::Sha384)), - common::AlgorithmParameters::EcDsaWithSha512 => Ok((KeyType::Ec, HashType::Sha512)), - common::AlgorithmParameters::EcDsaWithSha3_224 => Ok((KeyType::Ec, HashType::Sha3_224)), - common::AlgorithmParameters::EcDsaWithSha3_256 => Ok((KeyType::Ec, HashType::Sha3_256)), - common::AlgorithmParameters::EcDsaWithSha3_384 => Ok((KeyType::Ec, HashType::Sha3_384)), - common::AlgorithmParameters::EcDsaWithSha3_512 => Ok((KeyType::Ec, HashType::Sha3_512)), - common::AlgorithmParameters::Ed25519 => Ok((KeyType::Ed25519, HashType::None)), - common::AlgorithmParameters::Ed448 => Ok((KeyType::Ed448, HashType::None)), - common::AlgorithmParameters::DsaWithSha224 => Ok((KeyType::Dsa, HashType::Sha224)), - common::AlgorithmParameters::DsaWithSha256 => Ok((KeyType::Dsa, HashType::Sha256)), - common::AlgorithmParameters::DsaWithSha384 => Ok((KeyType::Dsa, HashType::Sha384)), - common::AlgorithmParameters::DsaWithSha512 => Ok((KeyType::Dsa, HashType::Sha512)), + common::AlgorithmParameters::RsaWithSha224(..) + | common::AlgorithmParameters::RsaWithSha256(..) + | common::AlgorithmParameters::RsaWithSha384(..) + | common::AlgorithmParameters::RsaWithSha512(..) + | common::AlgorithmParameters::RsaWithSha3_224(..) + | common::AlgorithmParameters::RsaWithSha3_256(..) + | common::AlgorithmParameters::RsaWithSha3_384(..) + | common::AlgorithmParameters::RsaWithSha3_512(..) + | common::AlgorithmParameters::RsaPss(..) => Ok(KeyType::Rsa), + common::AlgorithmParameters::EcDsaWithSha224 + | common::AlgorithmParameters::EcDsaWithSha256 + | common::AlgorithmParameters::EcDsaWithSha384 + | common::AlgorithmParameters::EcDsaWithSha512 + | common::AlgorithmParameters::EcDsaWithSha3_224 + | common::AlgorithmParameters::EcDsaWithSha3_256 + | common::AlgorithmParameters::EcDsaWithSha3_384 + | common::AlgorithmParameters::EcDsaWithSha3_512 => Ok(KeyType::Ec), + common::AlgorithmParameters::Ed25519 => Ok(KeyType::Ed25519), + common::AlgorithmParameters::Ed448 => Ok(KeyType::Ed448), + common::AlgorithmParameters::DsaWithSha224 + | common::AlgorithmParameters::DsaWithSha256 + | common::AlgorithmParameters::DsaWithSha384 + | common::AlgorithmParameters::DsaWithSha512 => Ok(KeyType::Dsa), _ => Err(pyo3::exceptions::PyValueError::new_err( "Unsupported signature algorithm", )), @@ -534,165 +507,68 @@ fn identify_alg_params_for_hash_type( #[cfg(test)] mod tests { use super::{ - identify_alg_params_for_hash_type, identify_key_hash_type_for_algorithm_params, - py_hash_name_from_hash_type, HashType, KeyType, + identify_alg_params_for_hash_type, identify_key_type_for_algorithm_params, HashType, + KeyType, }; use cryptography_x509::{common, oid}; #[test] - fn test_identify_key_hash_type_for_algorithm_params() { - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha224(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha224) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha256(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha256) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha384(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha384) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha512(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha512) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha3_224(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha3_224) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha3_256(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha3_256) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha3_384(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha3_384) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::RsaWithSha3_512(Some(())) - ) - .unwrap(), - (KeyType::Rsa, HashType::Sha3_512) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha224 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha224) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha256 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha256) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha384 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha384) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha512 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha512) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha3_224 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha3_224) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha3_256 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha3_256) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha3_384 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha3_384) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::EcDsaWithSha3_512 - ) - .unwrap(), - (KeyType::Ec, HashType::Sha3_512) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Ed25519) - .unwrap(), - (KeyType::Ed25519, HashType::None) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Ed448) - .unwrap(), - (KeyType::Ed448, HashType::None) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::DsaWithSha224 - ) - .unwrap(), - (KeyType::Dsa, HashType::Sha224) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::DsaWithSha256 - ) - .unwrap(), - (KeyType::Dsa, HashType::Sha256) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::DsaWithSha384 - ) - .unwrap(), - (KeyType::Dsa, HashType::Sha384) - ); - assert_eq!( - identify_key_hash_type_for_algorithm_params( - &common::AlgorithmParameters::DsaWithSha512 - ) - .unwrap(), - (KeyType::Dsa, HashType::Sha512) - ); + fn test_identify_key_type_for_algorithm_params() { + for (params, keytype) in [ + ( + &common::AlgorithmParameters::RsaWithSha224(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha256(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha384(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha512(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha3_224(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha3_256(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha3_384(Some(())), + KeyType::Rsa, + ), + ( + &common::AlgorithmParameters::RsaWithSha3_512(Some(())), + KeyType::Rsa, + ), + (&common::AlgorithmParameters::EcDsaWithSha224, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha256, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha384, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha512, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha3_224, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha3_256, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha3_384, KeyType::Ec), + (&common::AlgorithmParameters::EcDsaWithSha3_512, KeyType::Ec), + (&common::AlgorithmParameters::Ed25519, KeyType::Ed25519), + (&common::AlgorithmParameters::Ed448, KeyType::Ed448), + (&common::AlgorithmParameters::DsaWithSha224, KeyType::Dsa), + (&common::AlgorithmParameters::DsaWithSha256, KeyType::Dsa), + (&common::AlgorithmParameters::DsaWithSha384, KeyType::Dsa), + (&common::AlgorithmParameters::DsaWithSha512, KeyType::Dsa), + ] { + assert_eq!( + identify_key_type_for_algorithm_params(params).unwrap(), + keytype + ); + } assert!( - identify_key_hash_type_for_algorithm_params(&common::AlgorithmParameters::Other( + identify_key_type_for_algorithm_params(&common::AlgorithmParameters::Other( oid::TLS_FEATURE_OID, None )) @@ -727,21 +603,4 @@ mod tests { assert_eq!(identify_alg_params_for_hash_type(hash).unwrap(), params); } } - - #[test] - fn test_py_hash_name_from_hash_type() { - for (hash, name) in [ - (HashType::Sha224, "SHA224"), - (HashType::Sha256, "SHA256"), - (HashType::Sha384, "SHA384"), - (HashType::Sha512, "SHA512"), - (HashType::Sha3_224, "SHA3_224"), - (HashType::Sha3_256, "SHA3_256"), - (HashType::Sha3_384, "SHA3_384"), - (HashType::Sha3_512, "SHA3_512"), - ] { - let hash_str = py_hash_name_from_hash_type(hash).unwrap(); - assert_eq!(hash_str, name); - } - } } diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 19a854e24a98..5fd5265b7f4e 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -1558,6 +1558,50 @@ def test_parse_tls_feature_extension(self, backend): [x509.TLSFeatureType.status_request] ) + def test_verify_directly_issued_by_rsa_pss( + self, rsa_key_2048: rsa.RSAPrivateKey + ): + subject_private_key = RSA_KEY_2048_ALT.private_key( + unsafe_skip_rsa_key_validation=True + ) + + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(rsa_key_2048.public_key()) + .serial_number(1) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2030, 1, 1)) + ) + ca = builder.sign(rsa_key_2048, hashes.SHA256()) + builder = ( + x509.CertificateBuilder() + .subject_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "leaf")]) + ) + .issuer_name( + x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA CA")]) + ) + .public_key(subject_private_key.public_key()) + .serial_number(100) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2025, 1, 1)) + ) + cert = builder.sign( + rsa_key_2048, + hashes.SHA256(), + rsa_padding=padding.PSS( + padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.DIGEST_LENGTH, + ), + ) + cert.verify_directly_issued_by(ca) + def test_verify_directly_issued_by_rsa( self, rsa_key_2048: rsa.RSAPrivateKey ): From cff3c8fee74ba08cc0ce4b67bbb635f73270f8b3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 14 May 2023 16:36:57 -0400 Subject: [PATCH 766/827] There are wheels for basically all linux distros now (#8923) --- docs/installation.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 896baf8f6d1d..f35f270effea 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -79,11 +79,10 @@ Building cryptography on Linux .. note:: - If you are on RHEL/CentOS/Fedora/Debian/Ubuntu or another distribution - derived from the preceding list, then you should **upgrade pip** and - attempt to install ``cryptography`` again before following the instructions - to compile it below. These platforms will receive a binary wheel and - require no compiler if you have an updated ``pip``! + You should **upgrade pip** and attempt to install ``cryptography`` again + before following the instructions to compile it below. Most Linux + platforms will receive a binary wheel and require no compiler if you have + an updated ``pip``! ``cryptography`` ships ``manylinux`` wheels (as of 2.0) so all dependencies are included. For users on **pip 19.3** or above running on a ``manylinux2014`` From 4fc8e9aaa12f0b69fca0f36c544543aefb9c5d03 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 14 May 2023 16:37:20 -0400 Subject: [PATCH 767/827] Move code to sign.rs (#8922) --- src/rust/src/x509/certificate.rs | 140 +----------------------------- src/rust/src/x509/sign.rs | 143 ++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 142 deletions(-) diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 34e9ec0ec4b3..3446bbbbb604 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -17,28 +17,10 @@ use cryptography_x509::extensions::{ SequenceOfSubtrees, UserNotice, }; use cryptography_x509::{common, name, oid}; -use once_cell::sync::Lazy; use pyo3::{IntoPy, ToPyObject}; use std::collections::hash_map::DefaultHasher; -use std::collections::HashMap; use std::hash::{Hash, Hasher}; -// This is similar to a hashmap in ocsp.rs but contains more hash algorithms -// that aren't allowable in OCSP -static HASH_OIDS_TO_HASH: Lazy> = Lazy::new(|| { - let mut h = HashMap::new(); - h.insert(&oid::SHA1_OID, "SHA1"); - h.insert(&oid::SHA224_OID, "SHA224"); - h.insert(&oid::SHA256_OID, "SHA256"); - h.insert(&oid::SHA384_OID, "SHA384"); - h.insert(&oid::SHA512_OID, "SHA512"); - h.insert(&oid::SHA3_224_OID, "SHA3_224"); - h.insert(&oid::SHA3_256_OID, "SHA3_256"); - h.insert(&oid::SHA3_384_OID, "SHA3_384"); - h.insert(&oid::SHA3_512_OID, "SHA3_512"); - h -}); - #[ouroboros::self_referencing] pub(crate) struct OwnedCertificate { data: pyo3::Py, @@ -269,7 +251,7 @@ impl Certificate { &self, py: pyo3::Python<'p>, ) -> Result<&'p pyo3::PyAny, CryptographyError> { - identify_signature_hash_algorithm(py, &self.raw.borrow_value().signature_alg) + sign::identify_signature_hash_algorithm(py, &self.raw.borrow_value().signature_alg) } #[getter] @@ -282,7 +264,7 @@ impl Certificate { &'p self, py: pyo3::Python<'p>, ) -> CryptographyResult<&'p pyo3::PyAny> { - identify_signature_algorithm_parameters(py, &self.raw.borrow_value().signature_alg) + sign::identify_signature_algorithm_parameters(py, &self.raw.borrow_value().signature_alg) } #[getter] @@ -880,22 +862,6 @@ pub fn parse_cert_ext<'p>( } } -fn hash_oid_py_hash( - py: pyo3::Python<'_>, - oid: asn1::ObjectIdentifier, -) -> CryptographyResult<&pyo3::PyAny> { - let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; - match HASH_OIDS_TO_HASH.get(&oid) { - Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), - None => Err(CryptographyError::from( - exceptions::UnsupportedAlgorithm::new_err(format!( - "Signature algorithm OID: {} not recognized", - &oid - )), - )), - } -} - pub(crate) fn time_from_py( py: pyo3::Python<'_>, val: &pyo3::PyAny, @@ -994,108 +960,6 @@ pub(crate) fn set_bit(vals: &mut [u8], n: usize, set: bool) { } } -pub(crate) fn identify_signature_hash_algorithm<'p>( - py: pyo3::Python<'p>, - signature_algorithm: &common::AlgorithmIdentifier<'_>, -) -> CryptographyResult<&'p pyo3::PyAny> { - let sig_oids_to_hash = py - .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? - .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; - match &signature_algorithm.params { - common::AlgorithmParameters::RsaPss(opt_pss) => { - let pss = opt_pss.as_ref().ok_or_else(|| { - pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") - })?; - hash_oid_py_hash(py, pss.hash_algorithm.oid().clone()) - } - _ => { - let py_sig_alg_oid = oid_to_py_oid(py, signature_algorithm.oid())?; - let hash_alg = sig_oids_to_hash.get_item(py_sig_alg_oid); - match hash_alg { - Ok(data) => Ok(data), - Err(_) => Err(CryptographyError::from( - exceptions::UnsupportedAlgorithm::new_err(format!( - "Signature algorithm OID: {} not recognized", - signature_algorithm.oid() - )), - )), - } - } - } -} - -pub(crate) fn identify_signature_algorithm_parameters<'p>( - py: pyo3::Python<'p>, - signature_algorithm: &common::AlgorithmIdentifier<'_>, -) -> CryptographyResult<&'p pyo3::PyAny> { - match &signature_algorithm.params { - common::AlgorithmParameters::RsaPss(opt_pss) => { - let pss = opt_pss.as_ref().ok_or_else(|| { - pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") - })?; - if pss.mask_gen_algorithm.oid != oid::MGF1_OID { - return Err(CryptographyError::from( - pyo3::exceptions::PyValueError::new_err(format!( - "Unsupported mask generation OID: {}", - pss.mask_gen_algorithm.oid - )), - )); - } - let py_mask_gen_hash_alg = - hash_oid_py_hash(py, pss.mask_gen_algorithm.params.oid().clone())?; - let padding = py.import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))?; - let py_mgf = padding - .getattr(pyo3::intern!(py, "MGF1"))? - .call1((py_mask_gen_hash_alg,))?; - Ok(padding - .getattr(pyo3::intern!(py, "PSS"))? - .call1((py_mgf, pss.salt_length))?) - } - common::AlgorithmParameters::RsaWithSha1(_) - | common::AlgorithmParameters::RsaWithSha1Alt(_) - | common::AlgorithmParameters::RsaWithSha224(_) - | common::AlgorithmParameters::RsaWithSha256(_) - | common::AlgorithmParameters::RsaWithSha384(_) - | common::AlgorithmParameters::RsaWithSha512(_) - | common::AlgorithmParameters::RsaWithSha3_224(_) - | common::AlgorithmParameters::RsaWithSha3_256(_) - | common::AlgorithmParameters::RsaWithSha3_384(_) - | common::AlgorithmParameters::RsaWithSha3_512(_) => { - let pkcs = py - .import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.padding" - ))? - .getattr(pyo3::intern!(py, "PKCS1v15"))? - .call0()?; - Ok(pkcs) - } - common::AlgorithmParameters::EcDsaWithSha224 - | common::AlgorithmParameters::EcDsaWithSha256 - | common::AlgorithmParameters::EcDsaWithSha384 - | common::AlgorithmParameters::EcDsaWithSha512 - | common::AlgorithmParameters::EcDsaWithSha3_224 - | common::AlgorithmParameters::EcDsaWithSha3_256 - | common::AlgorithmParameters::EcDsaWithSha3_384 - | common::AlgorithmParameters::EcDsaWithSha3_512 => { - let signature_hash_algorithm = - identify_signature_hash_algorithm(py, signature_algorithm)?; - - Ok(py - .import(pyo3::intern!( - py, - "cryptography.hazmat.primitives.asymmetric.ec" - ))? - .getattr(pyo3::intern!(py, "ECDSA"))? - .call1((signature_hash_algorithm,))?) - } - _ => Ok(py.None().into_ref(py)), - } -} - pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { module.add_function(pyo3::wrap_pyfunction!(load_der_x509_certificate, module)?)?; module.add_function(pyo3::wrap_pyfunction!(load_pem_x509_certificate, module)?)?; diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 0543004201e9..16db5a587f90 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -2,10 +2,28 @@ // 2.0, and the BSD License. See the LICENSE file in the root of this repository // for complete details. +use crate::asn1::oid_to_py_oid; use crate::error::{CryptographyError, CryptographyResult}; use crate::exceptions; -use crate::x509::certificate; use cryptography_x509::{common, oid}; +use once_cell::sync::Lazy; +use std::collections::HashMap; + +// This is similar to a hashmap in ocsp.rs but contains more hash algorithms +// that aren't allowable in OCSP +static HASH_OIDS_TO_HASH: Lazy> = Lazy::new(|| { + let mut h = HashMap::new(); + h.insert(&oid::SHA1_OID, "SHA1"); + h.insert(&oid::SHA224_OID, "SHA224"); + h.insert(&oid::SHA256_OID, "SHA256"); + h.insert(&oid::SHA384_OID, "SHA384"); + h.insert(&oid::SHA512_OID, "SHA512"); + h.insert(&oid::SHA3_224_OID, "SHA3_224"); + h.insert(&oid::SHA3_256_OID, "SHA3_256"); + h.insert(&oid::SHA3_384_OID, "SHA3_384"); + h.insert(&oid::SHA3_512_OID, "SHA3_512"); + h +}); #[derive(Debug, PartialEq)] pub(crate) enum KeyType { @@ -368,9 +386,8 @@ pub(crate) fn verify_signature_with_signature_algorithm<'p>( )); } let py_signature_algorithm_parameters = - certificate::identify_signature_algorithm_parameters(py, signature_algorithm)?; - let py_signature_hash_algorithm = - certificate::identify_signature_hash_algorithm(py, signature_algorithm)?; + identify_signature_algorithm_parameters(py, signature_algorithm)?; + let py_signature_hash_algorithm = identify_signature_hash_algorithm(py, signature_algorithm)?; match key_type { KeyType::Ed25519 | KeyType::Ed448 => { issuer_public_key.call_method1(pyo3::intern!(py, "verify"), (signature, data))? @@ -504,6 +521,124 @@ fn identify_alg_params_for_hash_type( } } +fn hash_oid_py_hash( + py: pyo3::Python<'_>, + oid: asn1::ObjectIdentifier, +) -> CryptographyResult<&pyo3::PyAny> { + let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?; + match HASH_OIDS_TO_HASH.get(&oid) { + Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?), + None => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + &oid + )), + )), + } +} + +pub(crate) fn identify_signature_hash_algorithm<'p>( + py: pyo3::Python<'p>, + signature_algorithm: &common::AlgorithmIdentifier<'_>, +) -> CryptographyResult<&'p pyo3::PyAny> { + let sig_oids_to_hash = py + .import(pyo3::intern!(py, "cryptography.hazmat._oid"))? + .getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?; + match &signature_algorithm.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + hash_oid_py_hash(py, pss.hash_algorithm.oid().clone()) + } + _ => { + let py_sig_alg_oid = oid_to_py_oid(py, signature_algorithm.oid())?; + let hash_alg = sig_oids_to_hash.get_item(py_sig_alg_oid); + match hash_alg { + Ok(data) => Ok(data), + Err(_) => Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(format!( + "Signature algorithm OID: {} not recognized", + signature_algorithm.oid() + )), + )), + } + } + } +} + +pub(crate) fn identify_signature_algorithm_parameters<'p>( + py: pyo3::Python<'p>, + signature_algorithm: &common::AlgorithmIdentifier<'_>, +) -> CryptographyResult<&'p pyo3::PyAny> { + match &signature_algorithm.params { + common::AlgorithmParameters::RsaPss(opt_pss) => { + let pss = opt_pss.as_ref().ok_or_else(|| { + pyo3::exceptions::PyValueError::new_err("Invalid RSA PSS parameters") + })?; + if pss.mask_gen_algorithm.oid != oid::MGF1_OID { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err(format!( + "Unsupported mask generation OID: {}", + pss.mask_gen_algorithm.oid + )), + )); + } + let py_mask_gen_hash_alg = + hash_oid_py_hash(py, pss.mask_gen_algorithm.params.oid().clone())?; + let padding = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))?; + let py_mgf = padding + .getattr(pyo3::intern!(py, "MGF1"))? + .call1((py_mask_gen_hash_alg,))?; + Ok(padding + .getattr(pyo3::intern!(py, "PSS"))? + .call1((py_mgf, pss.salt_length))?) + } + common::AlgorithmParameters::RsaWithSha1(_) + | common::AlgorithmParameters::RsaWithSha1Alt(_) + | common::AlgorithmParameters::RsaWithSha224(_) + | common::AlgorithmParameters::RsaWithSha256(_) + | common::AlgorithmParameters::RsaWithSha384(_) + | common::AlgorithmParameters::RsaWithSha512(_) + | common::AlgorithmParameters::RsaWithSha3_224(_) + | common::AlgorithmParameters::RsaWithSha3_256(_) + | common::AlgorithmParameters::RsaWithSha3_384(_) + | common::AlgorithmParameters::RsaWithSha3_512(_) => { + let pkcs = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.padding" + ))? + .getattr(pyo3::intern!(py, "PKCS1v15"))? + .call0()?; + Ok(pkcs) + } + common::AlgorithmParameters::EcDsaWithSha224 + | common::AlgorithmParameters::EcDsaWithSha256 + | common::AlgorithmParameters::EcDsaWithSha384 + | common::AlgorithmParameters::EcDsaWithSha512 + | common::AlgorithmParameters::EcDsaWithSha3_224 + | common::AlgorithmParameters::EcDsaWithSha3_256 + | common::AlgorithmParameters::EcDsaWithSha3_384 + | common::AlgorithmParameters::EcDsaWithSha3_512 => { + let signature_hash_algorithm = + identify_signature_hash_algorithm(py, signature_algorithm)?; + + Ok(py + .import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.ec" + ))? + .getattr(pyo3::intern!(py, "ECDSA"))? + .call1((signature_hash_algorithm,))?) + } + _ => Ok(py.None().into_ref(py)), + } +} + #[cfg(test)] mod tests { use super::{ From 7a7aa67abcbf6a2c968d3479383d57ebc47a1f29 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sun, 14 May 2023 20:51:18 -0400 Subject: [PATCH 768/827] Bump BoringSSL and/or OpenSSL in CI (#8926) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a3d8e587d95..c11defdbb54a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,8 +41,8 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 13, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c215ce7e8230786e0d4ec463d95a9e44af513e6a"}} + # Latest commit on the BoringSSL master branch, as of May 15, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c1f5d795c2e5778254c94ca115fb89ff56624b73"}} # Latest commit on the OpenSSL master branch, as of May 13, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "2b5a546ce1960883febc51f5d2a71a8b7c1b3ab9"}} timeout-minutes: 15 From 24c582a1dc0bc07da4247b938cf293a04010c0a9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 14 May 2023 21:11:24 -0400 Subject: [PATCH 769/827] Pass --all to cargo test (#8925) --- noxfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 8c9cc218b56b..c70b1c333e63 100644 --- a/noxfile.py +++ b/noxfile.py @@ -143,4 +143,6 @@ def rust(session: nox.Session) -> None: with session.chdir("src/rust/"): session.run("cargo", "fmt", "--all", "--", "--check", external=True) session.run("cargo", "clippy", "--", "-D", "warnings", external=True) - session.run("cargo", "test", "--no-default-features", external=True) + session.run( + "cargo", "test", "--no-default-features", "--all", external=True + ) From d7996dc01fb23cc737678d67f322b1b62a034cd2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 14 May 2023 21:48:31 -0400 Subject: [PATCH 770/827] Run full nox rust env in coverage jobs (#8924) * Run full nox rust env in coverage jobs * Update ci.yml * Update ci.yml * fix 1.60 clippy warnings * warning name changed --- .github/workflows/ci.yml | 15 ++++---------- src/rust/cryptography-x509/src/lib.rs | 2 ++ src/rust/src/pkcs7.rs | 28 +++++++++++++-------------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c11defdbb54a..d50e8f1d0f9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -267,7 +267,7 @@ jobs: id: rust-toolchain with: toolchain: ${{ matrix.RUST }} - components: llvm-tools-preview + components: llvm-tools-preview,rustfmt,clippy - name: Cache rust and pip id: cargo-cache uses: ./.github/actions/cache @@ -304,27 +304,20 @@ jobs: - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' cffi + - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - name: Create nox environment - run: nox -v --install-only -s tests + run: nox -v --install-only -s tests rust env: CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} RUSTFLAGS: "-Cinstrument-coverage" LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - name: Tests - run: nox --no-install -s tests -- --color=yes --wycheproof-root=wycheproof + run: nox --no-install -s tests rust -- --color=yes --wycheproof-root=wycheproof env: COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} RUSTFLAGS: "-Cinstrument-coverage" LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - - name: Rust Tests - run: | - cd src/rust - cargo test --no-default-features --all - env: - RUSTFLAGS: "-Cinstrument-coverage" - LLVM_PROFILE_FILE: "rust-cov/cov-%m-%p.profraw" - name: Process coverage data run: | set -xe diff --git a/src/rust/cryptography-x509/src/lib.rs b/src/rust/cryptography-x509/src/lib.rs index 548e073b13e5..131c3fd156eb 100644 --- a/src/rust/cryptography-x509/src/lib.rs +++ b/src/rust/cryptography-x509/src/lib.rs @@ -3,6 +3,8 @@ // for complete details. #![forbid(unsafe_code)] +// These can be removed once our MSRV is >1.60 +#![allow(renamed_and_removed_lints, clippy::eval_order_dependence)] pub mod certificate; pub mod common; diff --git a/src/rust/src/pkcs7.rs b/src/rust/src/pkcs7.rs index 6a49acf98c7b..d2c500a72de7 100644 --- a/src/rust/src/pkcs7.rs +++ b/src/rust/src/pkcs7.rs @@ -139,20 +139,20 @@ fn sign_and_serialize<'p>( )?, ) } else { - let mut authenticated_attrs = vec![]; - - authenticated_attrs.push(Attribute { - type_id: PKCS7_CONTENT_TYPE_OID, - values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ - asn1::parse_single(&content_type_bytes).unwrap(), - ])), - }); - authenticated_attrs.push(Attribute { - type_id: PKCS7_SIGNING_TIME_OID, - values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ - asn1::parse_single(&signing_time_bytes).unwrap(), - ])), - }); + let mut authenticated_attrs = vec![ + Attribute { + type_id: PKCS7_CONTENT_TYPE_OID, + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + asn1::parse_single(&content_type_bytes).unwrap(), + ])), + }, + Attribute { + type_id: PKCS7_SIGNING_TIME_OID, + values: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new([ + asn1::parse_single(&signing_time_bytes).unwrap(), + ])), + }, + ]; let digest = asn1::write_single(&x509::ocsp::hash_data(py, py_hash_alg, &data_with_header)?)?; From d6586fdbeab4e15e111e55790d8ed789c97757ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 11:02:21 +0000 Subject: [PATCH 771/827] Bump proc-macro2 from 1.0.56 to 1.0.57 in /src/rust (#8928) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.56 to 1.0.57. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.56...1.0.57) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 9fdd2313155b..fd51294d9bba 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" dependencies = [ "unicode-ident", ] From e26a4207037f7e76dbb1913c52907c5342937ec8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 15 May 2023 07:42:16 -0400 Subject: [PATCH 772/827] Move slightly more of the rust coverage logic into noxfile.py (#8927) --- .github/workflows/ci.yml | 46 +++++++++++++++++++--------------------- noxfile.py | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d50e8f1d0f9c..291d5c6acb67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,22 +130,22 @@ jobs: fail-fast: false matrix: IMAGE: - - {IMAGE: "rhel8", RUNNER: "ubuntu-latest"} - - {IMAGE: "rhel8-fips", RUNNER: "ubuntu-latest", FIPS: true} - - {IMAGE: "buster", RUNNER: "ubuntu-latest"} - - {IMAGE: "bullseye", RUNNER: "ubuntu-latest"} - - {IMAGE: "bookworm", RUNNER: "ubuntu-latest"} - - {IMAGE: "sid", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-focal", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-jammy", RUNNER: "ubuntu-latest"} - - {IMAGE: "ubuntu-rolling", RUNNER: "ubuntu-latest"} - - {IMAGE: "fedora", RUNNER: "ubuntu-latest"} - - {IMAGE: "alpine", RUNNER: "ubuntu-latest"} - - {IMAGE: "centos-stream9", RUNNER: "ubuntu-latest"} - - {IMAGE: "centos-stream9-fips", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "rhel8", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "rhel8-fips", NOXSESSION: "tests", RUNNER: "ubuntu-latest", FIPS: true} + - {IMAGE: "buster", NOXSESSION: "tests-nocoverage", RUNNER: "ubuntu-latest"} + - {IMAGE: "bullseye", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "bookworm", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "sid", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-focal", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-jammy", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "ubuntu-rolling", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "fedora", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "alpine", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9", NOXSESSION: "tests", RUNNER: "ubuntu-latest"} + - {IMAGE: "centos-stream9-fips", NOXSESSION: "tests", RUNNER: "ubuntu-latest", FIPS: true} - - {IMAGE: "ubuntu-jammy:aarch64", RUNNER: [self-hosted, Linux, ARM64]} - - {IMAGE: "alpine:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "ubuntu-jammy:aarch64", NOXSESSION: "tests", RUNNER: [self-hosted, Linux, ARM64]} + - {IMAGE: "alpine:aarch64", NOXSESSION: "tests-nocoverage", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 steps: - name: Ridiculous alpine workaround for actions support on arm64 @@ -183,17 +183,19 @@ jobs: echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV if: matrix.IMAGE.FIPS - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' - - run: '/venv/bin/nox -v --install-only -s tests' + - run: '/venv/bin/nox -v --install-only' env: RUSTUP_HOME: /root/.rustup CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 - - run: '/venv/bin/nox --no-install -s tests -- --color=yes --wycheproof-root="wycheproof"' + NOXSESSION: ${{ matrix.IMAGE.NOXSESSION }} + - run: '/venv/bin/nox --no-install -- --color=yes --wycheproof-root="wycheproof"' env: COLUMNS: 80 # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 + NOXSESSION: ${{ matrix.IMAGE.NOXSESSION }} - uses: ./.github/actions/upload-coverage linux-rust: @@ -231,11 +233,11 @@ jobs: uses: ./.github/actions/wycheproof - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - name: Create nox environment - run: nox -v --install-only -s tests + run: nox -v --install-only -s tests-nocoverage env: CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - name: Tests - run: nox --no-install -s tests -- --color=yes --wycheproof-root=wycheproof + run: nox --no-install -s tests-nocoverage -- --color=yes --wycheproof-root=wycheproof env: COLUMNS: 80 - uses: ./.github/actions/upload-coverage @@ -309,15 +311,11 @@ jobs: run: nox -v --install-only -s tests rust env: CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - RUSTFLAGS: "-Cinstrument-coverage" - LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - name: Tests run: nox --no-install -s tests rust -- --color=yes --wycheproof-root=wycheproof env: COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - RUSTFLAGS: "-Cinstrument-coverage" - LLVM_PROFILE_FILE: "rust-cov/cov-%p.profraw" - name: Process coverage data run: | set -xe @@ -327,7 +325,7 @@ jobs: cargo cov -- export \ ../../.nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ - $(env RUSTFLAGS="-Cinstrument-coverage" cargo test --no-default-features --all --tests --no-run --message-format=json | jq -r "select(.profile.test == true) | .filenames[]" | awk '{print "-object " $0}') \ + $(cat ../../rust-tests.txt | awk '{print "-object " $0}') \ -instr-profile=rust-cov.profdata \ --ignore-filename-regex='/.cargo/' \ --ignore-filename-regex='/rustc/' \ diff --git a/noxfile.py b/noxfile.py index c70b1c333e63..93b10cd33f84 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,6 +4,8 @@ from __future__ import annotations +import json + import nox nox.options.reuse_existing_virtualenvs = True @@ -30,6 +32,15 @@ def tests(session: nox.Session) -> None: if session.name == "tests-randomorder": extras += ",test-randomorder" + if session.name != "tests-nocoverage": + session.env.update( + { + "RUSTFLAGS": "-Cinstrument-coverage " + + session.env.get("RUSTFLAGS", ""), + "LLVM_PROFILE_FILE": ".rust-cov/cov-%p.profraw", + } + ) + install(session, f".[{extras}]") install(session, "-e", "./vectors") @@ -138,11 +149,43 @@ def flake(session: nox.Session) -> None: @nox.session def rust(session: nox.Session) -> None: + session.env.update( + { + "RUSTFLAGS": "-Cinstrument-coverage " + + session.env.get("RUSTFLAGS", ""), + "LLVM_PROFILE_FILE": ".rust-cov/cov-%p.profraw", + } + ) + install(session, ".") with session.chdir("src/rust/"): session.run("cargo", "fmt", "--all", "--", "--check", external=True) session.run("cargo", "clippy", "--", "-D", "warnings", external=True) + + build_output = session.run( + "cargo", + "test", + "--no-default-features", + "--all", + "--no-run", + "-q", + "--message-format=json", + external=True, + silent=True, + ) session.run( "cargo", "test", "--no-default-features", "--all", external=True ) + + # It's None on install-only invocations + if build_output is not None: + assert isinstance(build_output, str) + rust_tests = [] + for line in build_output.splitlines(): + data = json.loads(line) + if data.get("profile", {}).get("test", False): + rust_tests.extend(data["filenames"]) + + with open("rust-tests.txt", "w") as f: + f.write("\n".join(rust_tests)) From 16fbebd345460fa173d851b226ecbf74abf9c3ec Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 08:33:17 +0800 Subject: [PATCH 773/827] Bump BoringSSL and/or OpenSSL in CI (#8932) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 291d5c6acb67..53fe7c385fb5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 15, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "c1f5d795c2e5778254c94ca115fb89ff56624b73"}} - # Latest commit on the OpenSSL master branch, as of May 13, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "2b5a546ce1960883febc51f5d2a71a8b7c1b3ab9"}} + # Latest commit on the BoringSSL master branch, as of May 16, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "dd9ee6068667ca58c8d6f1c1cea617fd69452ecf"}} + # Latest commit on the OpenSSL master branch, as of May 16, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "43d5dac9d00ac486823d949f85ee3ad650b62af8"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 4b8187f8bc8265ca5aba76994ca8963b845c0705 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 16 May 2023 08:38:15 +0800 Subject: [PATCH 774/827] don't use a set (#8931) * don't use a set We don't need one here and it creates ordering instability when iterating over an RDN * add a test --- src/rust/src/x509/common.rs | 4 ++-- tests/x509/test_x509.py | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs index bc26dace3fa9..8ceb518846d1 100644 --- a/src/rust/src/x509/common.rs +++ b/src/rust/src/x509/common.rs @@ -238,10 +238,10 @@ pub(crate) fn parse_rdn<'a>( rdn: &asn1::SetOf<'a, AttributeTypeValue<'a>>, ) -> Result { let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?; - let py_attrs = pyo3::types::PySet::empty(py)?; + let py_attrs = pyo3::types::PyList::empty(py); for attribute in rdn.clone() { let na = parse_name_attribute(py, attribute)?; - py_attrs.add(na)?; + py_attrs.append(na)?; } Ok(x509_module .call_method1(pyo3::intern!(py, "RelativeDistinguishedName"), (py_attrs,))? diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 5fd5265b7f4e..88be1a1763a2 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -2463,6 +2463,47 @@ def test_extreme_times( # GENERALIZED TIME assert parsed.not_after_tag == 0x18 + def test_rdns_preserve_iteration_order( + self, rsa_key_2048: rsa.RSAPrivateKey, backend + ): + """ + This test checks that RDN ordering is consistent when loading + data from a certificate. Since the underlying RDN is an ASN.1 + set these values get lexicographically ordered on encode and + the parsed value won't necessarily be in the same order as + the originally provided list. However, we want to make sure + that the order is always consistent since it confuses people + when it isn't. + """ + name = x509.Name( + [ + x509.RelativeDistinguishedName( + [ + x509.NameAttribute(NameOID.TITLE, "Test"), + x509.NameAttribute(NameOID.COMMON_NAME, "Multivalue"), + x509.NameAttribute(NameOID.SURNAME, "RDNs"), + ] + ), + ] + ) + + cert = ( + x509.CertificateBuilder() + .serial_number(1) + .issuer_name(name) + .subject_name(name) + .public_key(rsa_key_2048.public_key()) + .not_valid_before(datetime.datetime(2020, 1, 1)) + .not_valid_after(datetime.datetime(2038, 1, 1)) + .sign(rsa_key_2048, hashes.SHA256(), backend) + ) + loaded_cert = x509.load_pem_x509_certificate( + cert.public_bytes(encoding=serialization.Encoding.PEM) + ) + assert next(iter(loaded_cert.subject.rdns[0])) == x509.NameAttribute( + NameOID.SURNAME, "RDNs" + ) + @pytest.mark.parametrize( ("alg", "mgf_alg"), [ From 983b4617fe9668d03f6c58de56fadd1cbc296e64 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 15 May 2023 22:14:49 -0400 Subject: [PATCH 775/827] Cache slightly less in rust-coverage jobs (#8934) * Cache slightly less in rust-coverage jobs * Trigger CI to test cache --- .github/actions/cache/action.yml | 2 +- .github/workflows/ci.yml | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 37b9cc81bd37..47414c0f4f11 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -43,7 +43,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-4-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53fe7c385fb5..af52faacc78d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -278,24 +278,9 @@ jobs: key: coverage additional-paths: | ~/.cargo/bin/cargo-cov - ~/.cargo/bin/cargo-nm - ~/.cargo/bin/cargo-objcopy - ~/.cargo/bin/cargo-objdump ~/.cargo/bin/cargo-profdata - ~/.cargo/bin/cargo-readobj - ~/.cargo/bin/cargo-size - ~/.cargo/bin/cargo-strip - ~/.cargo/bin/rust-ar ~/.cargo/bin/rust-cov - ~/.cargo/bin/rust-ld - ~/.cargo/bin/rust-lld - ~/.cargo/bin/rust-nm - ~/.cargo/bin/rust-objcopy - ~/.cargo/bin/rust-objdump ~/.cargo/bin/rust-profdata - ~/.cargo/bin/rust-readobj - ~/.cargo/bin/rust-size - ~/.cargo/bin/rust-strip - name: Setup python uses: actions/setup-python@v4.6.0 with: From fb0606fd74d01efd319d9f98e0221bed1b45fa2a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 15 May 2023 22:46:54 -0400 Subject: [PATCH 776/827] Stop using cargo-binutils (#8935) Just find the copy of llvm-profdata/llvm-cov from rustc itself --- .github/actions/cache/action.yml | 2 +- .github/workflows/ci.yml | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 47414c0f4f11..4581770f93d5 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -43,7 +43,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-4-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-5-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af52faacc78d..cbd679da08c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -276,17 +276,10 @@ jobs: timeout-minutes: 2 with: key: coverage - additional-paths: | - ~/.cargo/bin/cargo-cov - ~/.cargo/bin/cargo-profdata - ~/.cargo/bin/rust-cov - ~/.cargo/bin/rust-profdata - name: Setup python uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON }} - - run: cargo install cargo-binutils - if: steps.cargo-cache.outputs.cache-hit != 'true' - name: Clone wycheproof timeout-minutes: 2 @@ -304,19 +297,18 @@ jobs: - name: Process coverage data run: | set -xe - cd src/rust/ - cargo profdata -- merge -sparse $(find ../.. -iname "*.profraw") -o rust-cov.profdata + "$(rustc --print target-libdir)/../bin/llvm-profdata" merge -sparse $(find . -iname "*.profraw") -o rust-cov.profdata COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") - cargo cov -- export \ - ../../.nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ - $(cat ../../rust-tests.txt | awk '{print "-object " $0}') \ + "$(rustc --print target-libdir)/../bin/llvm-cov" export \ + .nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ + $(cat rust-tests.txt | awk '{print "-object " $0}') \ -instr-profile=rust-cov.profdata \ --ignore-filename-regex='/.cargo/' \ --ignore-filename-regex='/rustc/' \ - --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > "../../${COV_UUID}.lcov" + --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > "${COV_UUID}.lcov" - sed -E -i 's/SF:(.*)\/src\/rust\/(.*)/SF:src\/rust\/\2/g' "../../${COV_UUID}.lcov" + sed -E -i 's/SF:(.*)\/src\/rust\/(.*)/SF:src\/rust\/\2/g' "${COV_UUID}.lcov" - uses: ./.github/actions/upload-coverage macos: From 1de2c14fb203808c647e1e8734e79c17ef7dc123 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 00:16:57 +0000 Subject: [PATCH 777/827] Bump BoringSSL and/or OpenSSL in CI (#8937) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbd679da08c0..273d5d8082fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,8 +41,8 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 16, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "dd9ee6068667ca58c8d6f1c1cea617fd69452ecf"}} + # Latest commit on the BoringSSL master branch, as of May 17, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "dd5219451c3ce26221762a15d867edf43b463bb2"}} # Latest commit on the OpenSSL master branch, as of May 16, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "43d5dac9d00ac486823d949f85ee3ad650b62af8"}} timeout-minutes: 15 From 5b7dd82561760a6d3545b0f6bc62d434c257e49e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 16 May 2023 20:39:18 -0400 Subject: [PATCH 778/827] Fix gitlab URLs for linkcheck (#8938) --- docs/development/test-vectors.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 2a90eb30bedf..67440fd4b18a 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -1016,13 +1016,13 @@ header format (substituting the correct information): .. _`Specification repository`: https://github.com/fernet/spec .. _`errata`: https://www.rfc-editor.org/errata_search.php?rfc=6238 .. _`OpenSSL example key`: https://github.com/openssl/openssl/blob/d02b48c63a58ea4367a0e905979f140b7d090f86/test/testrsa.pem -.. _`GnuTLS key parsing tests`: https://gitlab.com/gnutls/gnutls/commit/f16ef39ef0303b02d7fa590a37820440c466ce8d +.. _`GnuTLS key parsing tests`: https://gitlab.com/gnutls/gnutls/-/commit/f16ef39ef0303b02d7fa590a37820440c466ce8d .. _`enc-rsa-pkcs8.pem`: https://gitlab.com/gnutls/gnutls/blob/f8d943b38bf74eaaa11d396112daf43cb8aa82ae/tests/pkcs8-decode/encpkcs8.pem .. _`enc2-rsa-pkcs8.pem`: https://gitlab.com/gnutls/gnutls/blob/f8d943b38bf74eaaa11d396112daf43cb8aa82ae/tests/pkcs8-decode/enc2pkcs8.pem .. _`unenc-rsa-pkcs8.pem`: https://gitlab.com/gnutls/gnutls/blob/f8d943b38bf74eaaa11d396112daf43cb8aa82ae/tests/pkcs8-decode/unencpkcs8.pem .. _`pkcs12_s2k_pem.c`: https://gitlab.com/gnutls/gnutls/blob/f8d943b38bf74eaaa11d396112daf43cb8aa82ae/tests/pkcs12_s2k_pem.c .. _`Botan's ECC private keys`: https://github.com/randombit/botan/tree/4917f26a2b154e841cd27c1bcecdd41d2bdeb6ce/src/tests/data/ecc -.. _`GnuTLS example keys`: https://gitlab.com/gnutls/gnutls/commit/ad2061deafdd7db78fd405f9d143b0a7c579da7b +.. _`GnuTLS example keys`: https://gitlab.com/gnutls/gnutls/-/commit/ad2061deafdd7db78fd405f9d143b0a7c579da7b .. _`NESSIE IDEA vectors`: https://www.cosic.esat.kuleuven.be/nessie/testvectors/bc/idea/Idea-128-64.verified.test-vectors .. _`NESSIE`: https://en.wikipedia.org/wiki/NESSIE .. _`Ed25519 website`: https://ed25519.cr.yp.to/software.html From 736df2dc357ed36b0f602eb64ee278f9e3b7f041 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 17 May 2023 07:58:47 -0400 Subject: [PATCH 779/827] Move the remainder of the Rust coverage logic into the noxfile (#8936) --- .github/workflows/ci.yml | 21 +++------- .gitignore | 1 + noxfile.py | 88 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 273d5d8082fd..261ccdb7aa5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,7 @@ jobs: uses: actions/setup-python@v4.6.0 with: python-version: ${{ matrix.PYTHON.VERSION }} + - run: rustup component add llvm-tools-preview - name: Clone wycheproof timeout-minutes: 2 uses: ./.github/actions/wycheproof @@ -147,6 +148,8 @@ jobs: - {IMAGE: "ubuntu-jammy:aarch64", NOXSESSION: "tests", RUNNER: [self-hosted, Linux, ARM64]} - {IMAGE: "alpine:aarch64", NOXSESSION: "tests-nocoverage", RUNNER: [self-hosted, Linux, ARM64]} timeout-minutes: 15 + env: + RUSTUP_HOME: /root/.rustup steps: - name: Ridiculous alpine workaround for actions support on arm64 run: | @@ -185,7 +188,6 @@ jobs: - run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' - run: '/venv/bin/nox -v --install-only' env: - RUSTUP_HOME: /root/.rustup CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} # OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream OPENSSL_ENABLE_SHA1_SIGNATURES: 1 @@ -294,21 +296,6 @@ jobs: env: COLUMNS: 80 CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - - name: Process coverage data - run: | - set -xe - "$(rustc --print target-libdir)/../bin/llvm-profdata" merge -sparse $(find . -iname "*.profraw") -o rust-cov.profdata - COV_UUID=$(python3 -c "import uuid; print(uuid.uuid4())") - - "$(rustc --print target-libdir)/../bin/llvm-cov" export \ - .nox/tests/lib/python${{ matrix.PYTHON }}/site-packages/cryptography/hazmat/bindings/_rust.abi3.so \ - $(cat rust-tests.txt | awk '{print "-object " $0}') \ - -instr-profile=rust-cov.profdata \ - --ignore-filename-regex='/.cargo/' \ - --ignore-filename-regex='/rustc/' \ - --ignore-filename-regex='/.rustup/toolchains/' --format=lcov > "${COV_UUID}.lcov" - - sed -E -i 's/SF:(.*)\/src\/rust\/(.*)/SF:src\/rust\/\2/g' "${COV_UUID}.lcov" - uses: ./.github/actions/upload-coverage macos: @@ -346,6 +333,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 + - run: rustup component add llvm-tools-preview - run: python -m pip install -c ci-constraints-requirements.txt 'nox' @@ -405,6 +393,7 @@ jobs: with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} + - run: rustup component add llvm-tools-preview - name: Cache rust and pip uses: ./.github/actions/cache timeout-minutes: 2 diff --git a/.gitignore b/.gitignore index 7a00ba471236..035b15ccd025 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ htmlcov/ *.py[cdo] .hypothesis/ target/ +.rust-cov/ \ No newline at end of file diff --git a/noxfile.py b/noxfile.py index 93b10cd33f84..86a6a68b61a8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,7 +4,14 @@ from __future__ import annotations +import glob +import itertools import json +import pathlib +import re +import sys +import typing +import uuid import nox @@ -32,12 +39,15 @@ def tests(session: nox.Session) -> None: if session.name == "tests-randomorder": extras += ",test-randomorder" + prof_location = ( + pathlib.Path(".") / ".rust-cov" / str(uuid.uuid4()) + ).absolute() if session.name != "tests-nocoverage": session.env.update( { "RUSTFLAGS": "-Cinstrument-coverage " + session.env.get("RUSTFLAGS", ""), - "LLVM_PROFILE_FILE": ".rust-cov/cov-%p.profraw", + "LLVM_PROFILE_FILE": str(prof_location / "cov-%p.profraw"), } ) @@ -65,6 +75,13 @@ def tests(session: nox.Session) -> None: "tests/", ) + if session.name != "tests-nocoverage": + [rust_so] = glob.glob( + f"{session.virtualenv.location}/**/cryptography/hazmat/bindings/_rust.*", + recursive=True, + ) + process_rust_coverage(session, [rust_so], prof_location) + @nox.session def docs(session: nox.Session) -> None: @@ -149,11 +166,14 @@ def flake(session: nox.Session) -> None: @nox.session def rust(session: nox.Session) -> None: + prof_location = ( + pathlib.Path(".") / ".rust-cov" / str(uuid.uuid4()) + ).absolute() session.env.update( { "RUSTFLAGS": "-Cinstrument-coverage " + session.env.get("RUSTFLAGS", ""), - "LLVM_PROFILE_FILE": ".rust-cov/cov-%p.profraw", + "LLVM_PROFILE_FILE": str(prof_location / "cov-%p.profraw"), } ) @@ -187,5 +207,65 @@ def rust(session: nox.Session) -> None: if data.get("profile", {}).get("test", False): rust_tests.extend(data["filenames"]) - with open("rust-tests.txt", "w") as f: - f.write("\n".join(rust_tests)) + process_rust_coverage(session, rust_tests, prof_location) + + +LCOV_SOURCEFILE_RE = re.compile( + r"^SF:.*[\\/]src[\\/]rust[\\/](.*)$", flags=re.MULTILINE +) +BIN_EXT = ".exe" if sys.platform == "win32" else "" + + +def process_rust_coverage( + session: nox.Session, + rust_binaries: typing.List[str], + prof_raw_location: pathlib.Path, +) -> None: + # Hitting weird issues merging Windows and Linux Rust coverage, so just + # say the hell with it. + if sys.platform == "win32": + return + + target_libdir = session.run( + "rustc", "--print", "target-libdir", external=True, silent=True + ) + if target_libdir is not None: + target_bindir = pathlib.Path(target_libdir).parent / "bin" + + profraws = [ + str(prof_raw_location / p) + for p in prof_raw_location.glob("*.profraw") + ] + session.run( + str(target_bindir / ("llvm-profdata" + BIN_EXT)), + "merge", + "-sparse", + *profraws, + "-o", + "rust-cov.profdata", + external=True, + ) + + lcov_data = session.run( + str(target_bindir / ("llvm-cov" + BIN_EXT)), + "export", + rust_binaries[0], + *itertools.chain.from_iterable( + ["-object", b] for b in rust_binaries[1:] + ), + "-instr-profile=rust-cov.profdata", + "--ignore-filename-regex=[/\\].cargo[/\\]", + "--ignore-filename-regex=[/\\]rustc[/\\]", + "--ignore-filename-regex=[/\\].rustup[/\\]toolchains[/\\]", + "--ignore-filename-regex=[/\\]target[/\\]", + "--format=lcov", + silent=True, + external=True, + ) + assert isinstance(lcov_data, str) + lcov_data = LCOV_SOURCEFILE_RE.sub( + lambda m: "SF:src/rust/" + m.group(1).replace("\\", "/"), + lcov_data.replace("\r\n", "\n"), + ) + with open(f"{uuid.uuid4()}.lcov", "w") as f: + f.write(lcov_data) From c1ff39ff5cb0a179cd9a8fa44dd94482487e2fa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:05:45 +0000 Subject: [PATCH 780/827] Bump proc-macro2 from 1.0.57 to 1.0.58 in /src/rust (#8940) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.57 to 1.0.58. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.57...1.0.58) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index fd51294d9bba..957b228a0082 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ "unicode-ident", ] From c7146f9ed3830a9c3120722bc99dda81ce77037d Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 20:32:29 -0400 Subject: [PATCH 781/827] Bump BoringSSL and/or OpenSSL in CI (#8942) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 261ccdb7aa5e..721b13c70081 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 17, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "dd5219451c3ce26221762a15d867edf43b463bb2"}} - # Latest commit on the OpenSSL master branch, as of May 16, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "43d5dac9d00ac486823d949f85ee3ad650b62af8"}} + # Latest commit on the OpenSSL master branch, as of May 18, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "219db5e43c4f030a1c9c4a2f28249fd89b05ea0d"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From cbe719157ef89868413273da4bea379b75baf4be Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 20 May 2023 10:46:27 +0800 Subject: [PATCH 782/827] work around a centos9 fips bug in tests (#8947) filed as https://bugzilla.redhat.com/show_bug.cgi?id=2208724 --- tests/hazmat/bindings/test_openssl.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index c061c9bf11b0..2c54c6612131 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -21,13 +21,16 @@ def test_binding_loads(self): assert binding.lib assert binding.ffi - def test_ssl_ctx_options(self): + def test_ssl_ctx_options(self, backend): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) + # work around a bug in CentOS 9 stream FIPS + # https://bugzilla.redhat.com/show_bug.cgi?id=2208724 + backend._consume_errors() assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) current_options = b.lib.SSL_CTX_get_options(ctx) @@ -36,7 +39,7 @@ def test_ssl_ctx_options(self): assert resp == expected_options assert b.lib.SSL_CTX_get_options(ctx) == expected_options - def test_ssl_options(self): + def test_ssl_options(self, backend): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() # SSL_OP_ALL is 0 on BoringSSL @@ -46,6 +49,9 @@ def test_ssl_options(self): assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) + # work around a bug in CentOS 9 stream FIPS + # https://bugzilla.redhat.com/show_bug.cgi?id=2208724 + backend._consume_errors() ssl = b.ffi.gc(ssl, b.lib.SSL_free) current_options = b.lib.SSL_get_options(ssl) resp = b.lib.SSL_set_options(ssl, b.lib.SSL_OP_ALL) From 41156b1f7e8ec3fa22657b7cf036014327a503d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 22:57:50 -0400 Subject: [PATCH 783/827] Bump pytest-xdist from 3.3.0 to 3.3.1 (#8945) Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.3.0 to 3.3.1. - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: pytest-xdist dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index fff8548b798b..5783051ead7e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -123,7 +123,7 @@ pytest-cov==4.0.0 # via cryptography (pyproject.toml) pytest-randomly==3.12.0 # via cryptography (pyproject.toml) -pytest-xdist==3.3.0 +pytest-xdist==3.3.1 # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine From ceb527963949da2d77eaf846f419ae7a276f6b25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 May 2023 02:59:27 +0000 Subject: [PATCH 784/827] Bump ruff from 0.0.267 to 0.0.269 (#8944) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.267 to 0.0.269. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.267...v0.0.269) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5783051ead7e..be0d48cbd5a8 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -138,7 +138,7 @@ rfc3986==2.0.0 # via twine rich==13.3.5 # via twine -ruff==0.0.267 +ruff==0.0.269 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From eb09444b9317e392d75029d6d40128598836d98d Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 20 May 2023 03:09:41 +0000 Subject: [PATCH 785/827] Bump BoringSSL and/or OpenSSL in CI (#8943) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 721b13c70081..53bc416e84af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 17, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "dd5219451c3ce26221762a15d867edf43b463bb2"}} - # Latest commit on the OpenSSL master branch, as of May 18, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "219db5e43c4f030a1c9c4a2f28249fd89b05ea0d"}} + # Latest commit on the BoringSSL master branch, as of May 20, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "8abcb6fb41cbb29e93ed82048bb3d59bc8e6717f"}} + # Latest commit on the OpenSSL master branch, as of May 20, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "56a51b5a1ecd54eadc80bed4bfe5044a340787c1"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 4d03a47015888db37058e1717f155dc0ad1195e0 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 00:18:08 +0000 Subject: [PATCH 786/827] Bump BoringSSL and/or OpenSSL in CI (#8948) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53bc416e84af..e729388f0baf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 20, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "8abcb6fb41cbb29e93ed82048bb3d59bc8e6717f"}} - # Latest commit on the OpenSSL master branch, as of May 20, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "56a51b5a1ecd54eadc80bed4bfe5044a340787c1"}} + # Latest commit on the OpenSSL master branch, as of May 23, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "ab17dd8fa3db3e1be82dabfc9fde5dc6181e3f49"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 68f8545c6b8c82cebea30e4356e4c693821d41fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 00:27:53 +0000 Subject: [PATCH 787/827] Bump requests from 2.30.0 to 2.31.0 (#8949) Bumps [requests](https://github.com/psf/requests) from 2.30.0 to 2.31.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.30.0...v2.31.0) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index be0d48cbd5a8..e2107e05df8a 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -127,7 +127,7 @@ pytest-xdist==3.3.1 # via cryptography (pyproject.toml) readme-renderer==37.3 # via twine -requests==2.30.0 +requests==2.31.0 # via # requests-toolbelt # sphinx From 3bab5f80538a9d00c2282f1fa407764b610a483d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 23 May 2023 12:38:02 +0900 Subject: [PATCH 788/827] Revert "work around a centos9 fips bug in tests (#8947)" (#8950) This reverts commit cbe719157ef89868413273da4bea379b75baf4be. With the correct CentOS invocations we can properly set up FIPS in that environment so these errors don't occur. see: https://github.com/pyca/infra/pull/484 --- tests/hazmat/bindings/test_openssl.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 2c54c6612131..c061c9bf11b0 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -21,16 +21,13 @@ def test_binding_loads(self): assert binding.lib assert binding.ffi - def test_ssl_ctx_options(self, backend): + def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 ctx = b.lib.SSL_CTX_new(b.lib.TLS_method()) - # work around a bug in CentOS 9 stream FIPS - # https://bugzilla.redhat.com/show_bug.cgi?id=2208724 - backend._consume_errors() assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) current_options = b.lib.SSL_CTX_get_options(ctx) @@ -39,7 +36,7 @@ def test_ssl_ctx_options(self, backend): assert resp == expected_options assert b.lib.SSL_CTX_get_options(ctx) == expected_options - def test_ssl_options(self, backend): + def test_ssl_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() # SSL_OP_ALL is 0 on BoringSSL @@ -49,9 +46,6 @@ def test_ssl_options(self, backend): assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) - # work around a bug in CentOS 9 stream FIPS - # https://bugzilla.redhat.com/show_bug.cgi?id=2208724 - backend._consume_errors() ssl = b.ffi.gc(ssl, b.lib.SSL_free) current_options = b.lib.SSL_get_options(ssl) resp = b.lib.SSL_set_options(ssl, b.lib.SSL_OP_ALL) From f33cde87ec6cb0f1571560bf1b7790d22eb59c39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 09:52:49 -0400 Subject: [PATCH 789/827] Bump sphinx-rtd-theme from 1.2.0 to 1.2.1 (#8951) Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 1.2.0 to 1.2.1. - [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst) - [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/1.2.0...1.2.1) --- updated-dependencies: - dependency-name: sphinx-rtd-theme dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e2107e05df8a..1f763f1d4838 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -150,7 +150,7 @@ sphinx==6.2.1 # sphinx-rtd-theme # sphinxcontrib-jquery # sphinxcontrib-spelling -sphinx-rtd-theme==1.2.0 +sphinx-rtd-theme==1.2.1 # via cryptography (pyproject.toml) sphinxcontrib-applehelp==1.0.4 # via sphinx From 61708b5770799d2cdb33c986eb8b103bebfbf065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 13:58:04 +0000 Subject: [PATCH 790/827] Bump typing-extensions from 4.5.0 to 4.6.0 (#8952) Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.5.0 to 4.6.0. - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.5.0...4.6.0) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 1f763f1d4838..5f1ca526e945 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -179,7 +179,7 @@ tomli==2.0.1 # pytest twine==4.0.2 # via cryptography (pyproject.toml) -typing-extensions==4.5.0 +typing-extensions==4.6.0 # via mypy urllib3==2.0.2 # via From c4ec7aca54e6ecec930a0d348a246b2afa45d18c Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 20:39:58 -0400 Subject: [PATCH 791/827] Bump BoringSSL and/or OpenSSL in CI (#8954) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e729388f0baf..1a582aa85ef0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 20, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "8abcb6fb41cbb29e93ed82048bb3d59bc8e6717f"}} - # Latest commit on the OpenSSL master branch, as of May 23, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "ab17dd8fa3db3e1be82dabfc9fde5dc6181e3f49"}} + # Latest commit on the BoringSSL master branch, as of May 24, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "7e56051791944efa303930690a2089805385c983"}} + # Latest commit on the OpenSSL master branch, as of May 24, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "b501df3cefebcdaaeb7d6480b7a7b82d68927873"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 7ed71eb7818099b9d19d3898fccf8b1018504f69 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Wed, 24 May 2023 04:00:09 +0200 Subject: [PATCH 792/827] Add support for ChaCha20-Poly1305 with BoringSSL (#8946) * Add bindings for BoringSSL's EVP_AEAD API * Add support for ChaCha20-Poly1305 with BoringSSL Since BoringSSL supports this cipher through a different API than OpenSSL (EVP_AEAD vs EVP), this change splits the AEAD backend into two: the original OpenSSL backend (`_aead_openssl.py`) and the new BoringSSL backend (`_aead_boringssl.py`). The AEAD backend functions used by other modules (`aead._encrypt()`, `aead._decrypt()`, etc.) are now exposed through `aead/__init__.py` as wrappers. These wrappers select at runtime which backend to use. Currently only ChaCha20-Poly1305 + BoringSSL uses the BoringSSL backend. * EVP_AEAD: fixup cffi defs, add to _conditional Signed-off-by: William Woodruff evp_aead: fix initialization on BoringSSL Signed-off-by: William Woodruff _conditional: fatfingering Signed-off-by: William Woodruff backends/openssl: make an AEAD helper private Signed-off-by: William Woodruff openssl: collapse aead module Signed-off-by: William Woodruff openssl/aead: experimenting Signed-off-by: William Woodruff openssl/aead: use Cryptography_HAS_EVP_AEAD Signed-off-by: William Woodruff openssl/aead: group things Signed-off-by: William Woodruff Revert "openssl: collapse aead module" This reverts commit 558b8d57f469b6abf51e70e68f5cf330b7ae6414. aead: tweak feature test Signed-off-by: William Woodruff evp_aead: stupidness Signed-off-by: William Woodruff Revert "aead: tweak feature test" This reverts commit aa2eea648fed3e7460cfa358bf89c646e56f310d. Revert "Revert "openssl: collapse aead module"" This reverts commit 44a68c48b52dc0d243d23016999e7fafd580e48b. Revert "Revert "Revert "openssl: collapse aead module""" This reverts commit c35bb37f6c9b4a56f88d36402c8e13ab6396156b. Revert "Revert "aead: tweak feature test"" This reverts commit 78c0dc5ed298c0fde236b8137cb2b0795e905edc. openssl/aead: try to migrate more incrementally Signed-off-by: William Woodruff aead: lintage Signed-off-by: William Woodruff openssl/aead: more incremental rewriting Signed-off-by: William Woodruff openssl/aead: rename _OpenSSL -> _EVPCIPHER Signed-off-by: William Woodruff openssl/aead: collapse module Signed-off-by: William Woodruff * _conditional: undo accidental change Signed-off-by: William Woodruff * openssl/aead: remove _EVPAEAD Signed-off-by: William Woodruff * openssl/aead: remove _EVPCIPHER Signed-off-by: William Woodruff --------- Signed-off-by: William Woodruff Co-authored-by: William Woodruff --- src/_cffi_src/build_openssl.py | 1 + src/_cffi_src/openssl/evp_aead.py | 88 ++++++ .../hazmat/backends/openssl/aead.py | 281 ++++++++++++++++-- .../hazmat/backends/openssl/backend.py | 13 +- .../hazmat/bindings/openssl/_conditional.py | 12 + 5 files changed, 350 insertions(+), 45 deletions(-) create mode 100644 src/_cffi_src/openssl/evp_aead.py diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index 019789441431..6c4fd90e143b 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -35,6 +35,7 @@ "engine", "err", "evp", + "evp_aead", "fips", "nid", "objects", diff --git a/src/_cffi_src/openssl/evp_aead.py b/src/_cffi_src/openssl/evp_aead.py new file mode 100644 index 000000000000..a748bcd7a6a8 --- /dev/null +++ b/src/_cffi_src/openssl/evp_aead.py @@ -0,0 +1,88 @@ +# 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. + +from __future__ import annotations + +INCLUDES = """ +#if CRYPTOGRAPHY_IS_BORINGSSL +#include +#endif +""" + +TYPES = """ +typedef ... EVP_AEAD; +typedef ... EVP_AEAD_CTX; +static const size_t EVP_AEAD_DEFAULT_TAG_LENGTH; + +static const long Cryptography_HAS_EVP_AEAD; +""" + +FUNCTIONS = """ +const EVP_AEAD *EVP_aead_chacha20_poly1305(void); +void EVP_AEAD_CTX_free(EVP_AEAD_CTX *); +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *, uint8_t *, size_t *, size_t, + const uint8_t *, size_t, const uint8_t *, size_t, + const uint8_t *, size_t); +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *, uint8_t *, size_t *, size_t, + const uint8_t *, size_t, const uint8_t *, size_t, + const uint8_t *, size_t); +size_t EVP_AEAD_max_overhead(const EVP_AEAD *); +/* The function EVP_AEAD_CTX_NEW() has different signatures in BoringSSL and + LibreSSL, so we cannot declare it here. We define a wrapper for it instead. +*/ +EVP_AEAD_CTX *Cryptography_EVP_AEAD_CTX_new(const EVP_AEAD *, + const uint8_t *, size_t, + size_t); +""" + +CUSTOMIZATIONS = """ +#if CRYPTOGRAPHY_IS_BORINGSSL || CRYPTOGRAPHY_IS_LIBRESSL +static const long Cryptography_HAS_EVP_AEAD = 1; +#else +static const long Cryptography_HAS_EVP_AEAD = 0; +#endif + +#if CRYPTOGRAPHY_IS_BORINGSSL +EVP_AEAD_CTX *Cryptography_EVP_AEAD_CTX_new(const EVP_AEAD *aead, + const uint8_t *key, + size_t key_len, size_t tag_len) { + return EVP_AEAD_CTX_new(aead, key, key_len, tag_len); +} +#elif CRYPTOGRAPHY_IS_LIBRESSL +EVP_AEAD_CTX *Cryptography_EVP_AEAD_CTX_new(const EVP_AEAD *aead, + const uint8_t *key, + size_t key_len, size_t tag_len) { + EVP_AEAD_CTX *ctx = EVP_AEAD_CTX_new(); + if (ctx == NULL) { + return NULL; + } + + /* This mimics BoringSSL's behavior: any error here is pushed onto + the stack. + */ + int result = EVP_AEAD_CTX_init(ctx, aead, key, key_len, tag_len, NULL); + if (result != 1) { + return NULL; + } + + return ctx; +} +#else +typedef void EVP_AEAD; +typedef void EVP_AEAD_CTX; +static const size_t EVP_AEAD_DEFAULT_TAG_LENGTH = 0; +const EVP_AEAD *(*EVP_aead_chacha20_poly1305)(void) = NULL; +void (*EVP_AEAD_CTX_free)(EVP_AEAD_CTX *) = NULL; +int (*EVP_AEAD_CTX_seal)(const EVP_AEAD_CTX *, uint8_t *, size_t *, size_t, + const uint8_t *, size_t, const uint8_t *, size_t, + const uint8_t *, size_t) = NULL; +int (*EVP_AEAD_CTX_open)(const EVP_AEAD_CTX *, uint8_t *, size_t *, size_t, + const uint8_t *, size_t, const uint8_t *, size_t, + const uint8_t *, size_t) = NULL; +size_t (*EVP_AEAD_max_overhead)(const EVP_AEAD *) = NULL; +EVP_AEAD_CTX *(*Cryptography_EVP_AEAD_CTX_new)(const EVP_AEAD *, + const uint8_t *, size_t, + size_t) = NULL; +#endif +""" diff --git a/src/cryptography/hazmat/backends/openssl/aead.py b/src/cryptography/hazmat/backends/openssl/aead.py index 7361f227914d..b36f535f3f8f 100644 --- a/src/cryptography/hazmat/backends/openssl/aead.py +++ b/src/cryptography/hazmat/backends/openssl/aead.py @@ -22,11 +22,211 @@ AESCCM, AESGCM, AESOCB3, AESSIV, ChaCha20Poly1305 ] + +def _is_evp_aead_supported_cipher( + backend: Backend, cipher: _AEADTypes +) -> bool: + """ + Checks whether the given cipher is supported through + EVP_AEAD rather than the normal OpenSSL EVP_CIPHER API. + """ + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + + return backend._lib.Cryptography_HAS_EVP_AEAD and isinstance( + cipher, ChaCha20Poly1305 + ) + + +def _aead_cipher_supported(backend: Backend, cipher: _AEADTypes) -> bool: + if _is_evp_aead_supported_cipher(backend, cipher): + return True + else: + cipher_name = _evp_cipher_cipher_name(cipher) + if backend._fips_enabled and cipher_name not in backend._fips_aead: + return False + # SIV isn't loaded through get_cipherbyname but instead a new fetch API + # only available in 3.0+. But if we know we're on 3.0+ then we know + # it's supported. + if cipher_name.endswith(b"-siv"): + return backend._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER == 1 + else: + return ( + backend._lib.EVP_get_cipherbyname(cipher_name) + != backend._ffi.NULL + ) + + +def _aead_create_ctx( + backend: Backend, + cipher: _AEADTypes, + key: bytes, +): + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_create_ctx(backend, cipher, key) + else: + return _evp_cipher_create_ctx(backend, cipher, key) + + +def _encrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_encrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + else: + return _evp_cipher_encrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + + +def _decrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_decrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + else: + return _evp_cipher_decrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + + +def _evp_aead_create_ctx( + backend: Backend, + cipher: _AEADTypes, + key: bytes, + tag_len: typing.Optional[int] = None, +): + aead_cipher = _evp_aead_get_cipher(backend, cipher) + assert aead_cipher is not None + key_ptr = backend._ffi.from_buffer(key) + tag_len = ( + backend._lib.EVP_AEAD_DEFAULT_TAG_LENGTH + if tag_len is None + else tag_len + ) + ctx = backend._lib.Cryptography_EVP_AEAD_CTX_new( + aead_cipher, key_ptr, len(key), tag_len + ) + backend.openssl_assert(ctx != backend._ffi.NULL) + ctx = backend._ffi.gc(ctx, backend._lib.EVP_AEAD_CTX_free) + return ctx + + +def _evp_aead_get_cipher(backend: Backend, cipher: _AEADTypes): + from cryptography.hazmat.primitives.ciphers.aead import ( + ChaCha20Poly1305, + ) + + # Currently only ChaCha20-Poly1305 is supported using this API + assert isinstance(cipher, ChaCha20Poly1305) + return backend._lib.EVP_aead_chacha20_poly1305() + + +def _evp_aead_encrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any, +) -> bytes: + assert ctx is not None + + aead_cipher = _evp_aead_get_cipher(backend, cipher) + assert aead_cipher is not None + + out_len = backend._ffi.new("size_t *") + # max_out_len should be in_len plus the result of + # EVP_AEAD_max_overhead. + max_out_len = len(data) + backend._lib.EVP_AEAD_max_overhead(aead_cipher) + out_buf = backend._ffi.new("uint8_t[]", max_out_len) + data_ptr = backend._ffi.from_buffer(data) + nonce_ptr = backend._ffi.from_buffer(nonce) + aad = b"".join(associated_data) + aad_ptr = backend._ffi.from_buffer(aad) + + res = backend._lib.EVP_AEAD_CTX_seal( + ctx, + out_buf, + out_len, + max_out_len, + nonce_ptr, + len(nonce), + data_ptr, + len(data), + aad_ptr, + len(aad), + ) + backend.openssl_assert(res == 1) + encrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] + return encrypted_data + + +def _evp_aead_decrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any, +) -> bytes: + if len(data) < tag_length: + raise InvalidTag + + assert ctx is not None + + out_len = backend._ffi.new("size_t *") + # max_out_len should at least in_len + max_out_len = len(data) + out_buf = backend._ffi.new("uint8_t[]", max_out_len) + data_ptr = backend._ffi.from_buffer(data) + nonce_ptr = backend._ffi.from_buffer(nonce) + aad = b"".join(associated_data) + aad_ptr = backend._ffi.from_buffer(aad) + + res = backend._lib.EVP_AEAD_CTX_open( + ctx, + out_buf, + out_len, + max_out_len, + nonce_ptr, + len(nonce), + data_ptr, + len(data), + aad_ptr, + len(aad), + ) + + if res == 0: + backend._consume_errors() + raise InvalidTag + + decrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] + return decrypted_data + + _ENCRYPT = 1 _DECRYPT = 0 -def _aead_cipher_name(cipher: _AEADTypes) -> bytes: +def _evp_cipher_cipher_name(cipher: _AEADTypes) -> bytes: from cryptography.hazmat.primitives.ciphers.aead import ( AESCCM, AESGCM, @@ -64,7 +264,7 @@ def _evp_cipher(cipher_name: bytes, backend: Backend): return evp_cipher -def _aead_create_ctx( +def _evp_cipher_create_ctx( backend: Backend, cipher: _AEADTypes, key: bytes, @@ -72,7 +272,7 @@ def _aead_create_ctx( ctx = backend._lib.EVP_CIPHER_CTX_new() backend.openssl_assert(ctx != backend._ffi.NULL) ctx = backend._ffi.gc(ctx, backend._lib.EVP_CIPHER_CTX_free) - cipher_name = _aead_cipher_name(cipher) + cipher_name = _evp_cipher_cipher_name(cipher) evp_cipher = _evp_cipher(cipher_name, backend) key_ptr = backend._ffi.from_buffer(key) res = backend._lib.EVP_CipherInit_ex( @@ -87,7 +287,7 @@ def _aead_create_ctx( return ctx -def _aead_setup( +def _evp_cipher_aead_setup( backend: Backend, cipher_name: bytes, key: bytes, @@ -118,10 +318,13 @@ def _aead_setup( backend.openssl_assert(res != 0) if operation == _DECRYPT: assert tag is not None - _set_tag(backend, ctx, tag) + _evp_cipher_set_tag(backend, ctx, tag) elif cipher_name.endswith(b"-ccm"): res = backend._lib.EVP_CIPHER_CTX_ctrl( - ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, tag_len, backend._ffi.NULL + ctx, + backend._lib.EVP_CTRL_AEAD_SET_TAG, + tag_len, + backend._ffi.NULL, ) backend.openssl_assert(res != 0) @@ -139,7 +342,7 @@ def _aead_setup( return ctx -def _set_tag(backend, ctx, tag: bytes) -> None: +def _evp_cipher_set_tag(backend, ctx, tag: bytes) -> None: tag_ptr = backend._ffi.from_buffer(tag) res = backend._lib.EVP_CIPHER_CTX_ctrl( ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag_ptr @@ -147,7 +350,9 @@ def _set_tag(backend, ctx, tag: bytes) -> None: backend.openssl_assert(res != 0) -def _set_nonce_operation(backend, ctx, nonce: bytes, operation: int) -> None: +def _evp_cipher_set_nonce_operation( + backend, ctx, nonce: bytes, operation: int +) -> None: nonce_ptr = backend._ffi.from_buffer(nonce) res = backend._lib.EVP_CipherInit_ex( ctx, @@ -160,7 +365,7 @@ def _set_nonce_operation(backend, ctx, nonce: bytes, operation: int) -> None: backend.openssl_assert(res != 0) -def _set_length(backend: Backend, ctx, data_len: int) -> None: +def _evp_cipher_set_length(backend: Backend, ctx, data_len: int) -> None: intptr = backend._ffi.new("int *") res = backend._lib.EVP_CipherUpdate( ctx, backend._ffi.NULL, intptr, backend._ffi.NULL, data_len @@ -168,7 +373,9 @@ def _set_length(backend: Backend, ctx, data_len: int) -> None: backend.openssl_assert(res != 0) -def _process_aad(backend: Backend, ctx, associated_data: bytes) -> None: +def _evp_cipher_process_aad( + backend: Backend, ctx, associated_data: bytes +) -> None: outlen = backend._ffi.new("int *") a_data_ptr = backend._ffi.from_buffer(associated_data) res = backend._lib.EVP_CipherUpdate( @@ -177,7 +384,7 @@ def _process_aad(backend: Backend, ctx, associated_data: bytes) -> None: backend.openssl_assert(res != 0) -def _process_data(backend: Backend, ctx, data: bytes) -> bytes: +def _evp_cipher_process_data(backend: Backend, ctx, data: bytes) -> bytes: outlen = backend._ffi.new("int *") buf = backend._ffi.new("unsigned char[]", len(data)) data_ptr = backend._ffi.from_buffer(data) @@ -189,7 +396,7 @@ def _process_data(backend: Backend, ctx, data: bytes) -> bytes: return backend._ffi.buffer(buf, outlen[0])[:] -def _encrypt( +def _evp_cipher_encrypt( backend: Backend, cipher: _AEADTypes, nonce: bytes, @@ -201,8 +408,8 @@ def _encrypt( from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESSIV if ctx is None: - cipher_name = _aead_cipher_name(cipher) - ctx = _aead_setup( + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( backend, cipher_name, cipher._key, @@ -212,16 +419,17 @@ def _encrypt( _ENCRYPT, ) else: - _set_nonce_operation(backend, ctx, nonce, _ENCRYPT) + _evp_cipher_set_nonce_operation(backend, ctx, nonce, _ENCRYPT) - # CCM requires us to pass the length of the data before processing anything + # CCM requires us to pass the length of the data before processing + # anything. # However calling this with any other AEAD results in an error if isinstance(cipher, AESCCM): - _set_length(backend, ctx, len(data)) + _evp_cipher_set_length(backend, ctx, len(data)) for ad in associated_data: - _process_aad(backend, ctx, ad) - processed_data = _process_data(backend, ctx, data) + _evp_cipher_process_aad(backend, ctx, ad) + processed_data = _evp_cipher_process_data(backend, ctx, data) outlen = backend._ffi.new("int *") # All AEADs we support besides OCB are streaming so they return nothing # in finalization. OCB can return up to (16 byte block - 1) bytes so @@ -238,8 +446,8 @@ def _encrypt( tag = backend._ffi.buffer(tag_buf)[:] if isinstance(cipher, AESSIV): - # RFC 5297 defines the output as IV || C, where the tag we generate is - # the "IV" and C is the ciphertext. This is the opposite of our + # RFC 5297 defines the output as IV || C, where the tag we generate + # is the "IV" and C is the ciphertext. This is the opposite of our # other AEADs, which are Ciphertext || Tag backend.openssl_assert(len(tag) == 16) return tag + processed_data @@ -247,7 +455,7 @@ def _encrypt( return processed_data + tag -def _decrypt( +def _evp_cipher_decrypt( backend: Backend, cipher: _AEADTypes, nonce: bytes, @@ -262,8 +470,8 @@ def _decrypt( raise InvalidTag if isinstance(cipher, AESSIV): - # RFC 5297 defines the output as IV || C, where the tag we generate is - # the "IV" and C is the ciphertext. This is the opposite of our + # RFC 5297 defines the output as IV || C, where the tag we generate + # is the "IV" and C is the ciphertext. This is the opposite of our # other AEADs, which are Ciphertext || Tag tag = data[:tag_length] data = data[tag_length:] @@ -271,21 +479,28 @@ def _decrypt( tag = data[-tag_length:] data = data[:-tag_length] if ctx is None: - cipher_name = _aead_cipher_name(cipher) - ctx = _aead_setup( - backend, cipher_name, cipher._key, nonce, tag, tag_length, _DECRYPT + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( + backend, + cipher_name, + cipher._key, + nonce, + tag, + tag_length, + _DECRYPT, ) else: - _set_nonce_operation(backend, ctx, nonce, _DECRYPT) - _set_tag(backend, ctx, tag) + _evp_cipher_set_nonce_operation(backend, ctx, nonce, _DECRYPT) + _evp_cipher_set_tag(backend, ctx, tag) - # CCM requires us to pass the length of the data before processing anything + # CCM requires us to pass the length of the data before processing + # anything. # However calling this with any other AEAD results in an error if isinstance(cipher, AESCCM): - _set_length(backend, ctx, len(data)) + _evp_cipher_set_length(backend, ctx, len(data)) for ad in associated_data: - _process_aad(backend, ctx, ad) + _evp_cipher_process_aad(backend, ctx, ad) # CCM has a different error path if the tag doesn't match. Errors are # raised in Update and Final is irrelevant. if isinstance(cipher, AESCCM): @@ -299,7 +514,7 @@ def _decrypt( processed_data = backend._ffi.buffer(buf, outlen[0])[:] else: - processed_data = _process_data(backend, ctx, data) + processed_data = _evp_cipher_process_data(backend, ctx, data) outlen = backend._ffi.new("int *") # OCB can return up to 15 bytes (16 byte block - 1) in finalization buf = backend._ffi.new("unsigned char[]", 16) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 62b4659c87bf..00834f8cc04d 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1654,18 +1654,7 @@ def ed448_generate_key(self) -> ed448.Ed448PrivateKey: return rust_openssl.ed448.generate_key() def aead_cipher_supported(self, cipher) -> bool: - cipher_name = aead._aead_cipher_name(cipher) - if self._fips_enabled and cipher_name not in self._fips_aead: - return False - # SIV isn't loaded through get_cipherbyname but instead a new fetch API - # only available in 3.0+. But if we know we're on 3.0+ then we know - # it's supported. - if cipher_name.endswith(b"-siv"): - return self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER == 1 - else: - return ( - self._lib.EVP_get_cipherbyname(cipher_name) != self._ffi.NULL - ) + return aead._aead_cipher_supported(self, cipher) def _zero_data(self, data, length: int) -> None: # We clear things this way because at the moment we're not diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index c09c9531280b..5e8ecd04182c 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -262,6 +262,17 @@ def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: return ["EVP_PKEY_derive_set_peer_ex"] +def cryptography_has_evp_aead() -> typing.List[str]: + return [ + "EVP_aead_chacha20_poly1305", + "EVP_AEAD_CTX_free", + "EVP_AEAD_CTX_seal", + "EVP_AEAD_CTX_open", + "EVP_AEAD_max_overhead", + "Cryptography_EVP_AEAD_CTX_new", + ] + + # This is a mapping of # {condition: function-returning-names-dependent-on-that-condition} so we can # loop over them and delete unsupported names at runtime. It will be removed @@ -314,4 +325,5 @@ def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: "Cryptography_HAS_EVP_PKEY_SET_PEER_EX": ( cryptography_has_evp_pkey_set_peer_ex ), + "Cryptography_HAS_EVP_AEAD": (cryptography_has_evp_aead), } From 0a28f48998cbcf3f3e594ebab01182e235c046dc Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 23 May 2023 22:13:54 -0400 Subject: [PATCH 793/827] CHANGELOG: record ChaCha20Poly1305 changes (#8955) Signed-off-by: William Woodruff --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5073ce32b98e..1811f801cbf5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -26,6 +26,9 @@ Changelog * Support signing :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` X.509 certificates via the new keyword-only argument ``rsa_padding`` on :meth:`~cryptography.x509.CertificateBuilder.sign`. +* Added support for + :class:`~cryptography.hazmat.primitives.ciphers.aead.ChaCha20Poly1305` + on BoringSSL. .. _v40-0-2: From 69d7676135745cb8f9f6f8502d68177d30e42dcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 13:14:36 +0000 Subject: [PATCH 794/827] Bump typing-extensions from 4.6.0 to 4.6.1 (#8957) Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.6.0 to 4.6.1. - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.6.0...4.6.1) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 5f1ca526e945..84928b1e3f4e 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -179,7 +179,7 @@ tomli==2.0.1 # pytest twine==4.0.2 # via cryptography (pyproject.toml) -typing-extensions==4.6.0 +typing-extensions==4.6.1 # via mypy urllib3==2.0.2 # via From bc2b14ca5542a6f631ae018481145826e90a5259 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 13:26:38 +0000 Subject: [PATCH 795/827] Bump coverage from 7.2.5 to 7.2.6 (#8958) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.5 to 7.2.6. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.5...7.2.6) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 84928b1e3f4e..d3a30cf238ce 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -29,7 +29,7 @@ click==8.1.3 # via black colorlog==6.7.0 # via nox -coverage==7.2.5 +coverage==7.2.6 # via pytest-cov distlib==0.3.6 # via virtualenv From 9e3b2af68fbb2ab3db3d735c62f173ecca6cb572 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:40:34 +0000 Subject: [PATCH 796/827] Bump unicode-ident from 1.0.8 to 1.0.9 in /src/rust (#8960) Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.8 to 1.0.9. - [Release notes](https://github.com/dtolnay/unicode-ident/releases) - [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.8...1.0.9) --- updated-dependencies: - dependency-name: unicode-ident dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 957b228a0082..757bf69e3ea3 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -412,9 +412,9 @@ checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unindent" From 3ebe5701abd2e3670c71b81613774180db10e92d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:44:09 +0000 Subject: [PATCH 797/827] Bump actions/setup-python from 4.6.0 to 4.6.1 (#8961) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4.6.0...v4.6.1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/linkcheck.yml | 2 +- .github/workflows/wheel-builder.yml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index f121370e67df..1643a283b934 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -35,7 +35,7 @@ jobs: - name: Setup python id: setup-python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: "3.11" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a582aa85ef0..2e664a12cd62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} - run: rustup component add llvm-tools-preview @@ -224,7 +224,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 - name: Setup python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON }} - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff @@ -279,7 +279,7 @@ jobs: with: key: coverage - name: Setup python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON }} @@ -329,7 +329,7 @@ jobs: key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.PYTHON.VERSION }} - name: Setup python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: 'x64' # we force this right now so that it will install the universal2 on arm64 @@ -389,7 +389,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} @@ -465,7 +465,7 @@ jobs: uses: ./.github/actions/cache timeout-minutes: 2 - name: Setup python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON }} - run: ./.github/downstream.d/${{ matrix.DOWNSTREAM }}.sh install @@ -507,7 +507,7 @@ jobs: jobs: ${{ toJSON(needs) }} - name: Setup python if: ${{ always() }} - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: '3.11' - run: pip install -c ci-constraints-requirements.txt coverage[toml] diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 8adca7075078..9a11f2a9fc70 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -26,7 +26,7 @@ jobs: uses: ./.github/actions/mtime-fix - name: Setup python id: setup-python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: 3.11 - name: Cache rust and pip diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index b64828ab61dc..677319b3fa5a 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -189,7 +189,7 @@ jobs: PYTHON_DOWNLOAD_URL: ${{ matrix.PYTHON.DOWNLOAD_URL }} if: contains(matrix.PYTHON.VERSION, 'pypy') == false - name: Setup pypy - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} if: contains(matrix.PYTHON.VERSION, 'pypy') @@ -266,7 +266,7 @@ jobs: name: cryptography-sdist - name: Setup python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} architecture: ${{ matrix.WINDOWS.ARCH }} From b4e355926096c0dea91e3e255694d2dceed931cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:45:05 +0000 Subject: [PATCH 798/827] Bump ruff from 0.0.269 to 0.0.270 (#8962) Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.269 to 0.0.270. - [Release notes](https://github.com/charliermarsh/ruff/releases) - [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md) - [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.269...v0.0.270) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index d3a30cf238ce..e5cc4624d828 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -138,7 +138,7 @@ rfc3986==2.0.0 # via twine rich==13.3.5 # via twine -ruff==0.0.269 +ruff==0.0.270 # via cryptography (pyproject.toml) six==1.16.0 # via bleach From b426e6bc0c7a6b44e541fb2d86f37680780a0c9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:48:27 +0000 Subject: [PATCH 799/827] Bump pytest-cov from 4.0.0 to 4.1.0 (#8963) Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.0.0 to 4.1.0. - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.0.0...v4.1.0) --- updated-dependencies: - dependency-name: pytest-cov dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index e5cc4624d828..676df1435f04 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -119,7 +119,7 @@ pytest==7.3.1 # pytest-xdist pytest-benchmark==4.0.0 # via cryptography (pyproject.toml) -pytest-cov==4.0.0 +pytest-cov==4.1.0 # via cryptography (pyproject.toml) pytest-randomly==3.12.0 # via cryptography (pyproject.toml) From a30aa509b61b62926f779cd35d467dc48308c11b Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 00:18:07 +0000 Subject: [PATCH 800/827] Bump BoringSSL and/or OpenSSL in CI (#8965) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e664a12cd62..8a7f9bff5d8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,10 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 24, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "7e56051791944efa303930690a2089805385c983"}} - # Latest commit on the OpenSSL master branch, as of May 24, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "b501df3cefebcdaaeb7d6480b7a7b82d68927873"}} + # Latest commit on the BoringSSL master branch, as of May 25, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5fcd47d137f9b556edc7a392035dc2d2f43282ca"}} + # Latest commit on the OpenSSL master branch, as of May 25, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "674b61ebd982d6a6564ac1f90d8cde22371564bc"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From e34373bfebb18c8e00034c3c7881871c314d68de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 22:14:16 +0000 Subject: [PATCH 801/827] Bump quote from 1.0.27 to 1.0.28 in /src/rust (#8967) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.27 to 1.0.28. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.27...1.0.28) --- updated-dependencies: - dependency-name: quote dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 757bf69e3ea3..65040081c844 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -354,9 +354,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] From 13991ac2f4cc871ce93c842543ddd8be0574acc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 22:19:50 +0000 Subject: [PATCH 802/827] Bump typing-extensions from 4.6.1 to 4.6.2 (#8969) Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.6.1 to 4.6.2. - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.6.1...4.6.2) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 676df1435f04..2c91aecac0da 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -179,7 +179,7 @@ tomli==2.0.1 # pytest twine==4.0.2 # via cryptography (pyproject.toml) -typing-extensions==4.6.1 +typing-extensions==4.6.2 # via mypy urllib3==2.0.2 # via From 3a46372a9425d958b07aba969f437d4c3d21c04c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 22:32:35 +0000 Subject: [PATCH 803/827] Bump proc-macro2 from 1.0.58 to 1.0.59 in /src/rust (#8968) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.58...1.0.59) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 65040081c844..1d1c76d6bca8 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] From c9fd1d04a1dc3757852e81a1bae61f2f45662e65 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 00:24:14 -0400 Subject: [PATCH 804/827] Bump BoringSSL and/or OpenSSL in CI (#8970) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a7f9bff5d8e..b34dc312238f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 25, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5fcd47d137f9b556edc7a392035dc2d2f43282ca"}} - # Latest commit on the OpenSSL master branch, as of May 25, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "674b61ebd982d6a6564ac1f90d8cde22371564bc"}} + # Latest commit on the OpenSSL master branch, as of May 26, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "0bf7e94c10f1b00510b8a36cdcbedc02a66468be"}} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 From 965e04996f79f76e00148c0193f868e258f42ae5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 26 May 2023 14:09:53 -0400 Subject: [PATCH 805/827] Consolidate CI jobs (#8964) --- .github/actions/cache/action.yml | 6 +- .github/workflows/ci.yml | 114 ++++--------------------------- 2 files changed, 20 insertions(+), 100 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 4581770f93d5..6d254d398299 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -34,6 +34,10 @@ runs: echo "dir=$(python -m pip cache dir)" >> $GITHUB_OUTPUT fi shell: bash + - name: Normalize key + id: normalized-key + run: echo "key=$(echo "${{ inputs.key }}" | tr -d ',')" >> $GITHUB_OUTPUT + shell: bash - uses: actions/cache@v3.3.1 id: cache with: @@ -43,7 +47,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-5-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ steps.normalized-key.outputs.key }}-5-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b34dc312238f..b2dd1ba58ea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,13 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5fcd47d137f9b556edc7a392035dc2d2f43282ca"}} # Latest commit on the OpenSSL master branch, as of May 26, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "0bf7e94c10f1b00510b8a36cdcbedc02a66468be"}} + # Builds with various Rust versions. Includes MSRV and potential + # future MSRV: + # 1.60 - pem 2.0.1 + - {VERSION: "3.11", NOXSESSION: "tests-nocoverage", RUST: "1.56.0"} + - {VERSION: "3.11", NOXSESSION: "rust,tests", RUST: "1.60.0"} + - {VERSION: "3.11", NOXSESSION: "rust,tests", RUST: "beta"} + - {VERSION: "3.11", NOXSESSION: "rust,tests", RUST: "nightly"} timeout-minutes: 15 steps: - uses: actions/checkout@v3.5.2 @@ -59,6 +66,13 @@ jobs: uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.PYTHON.VERSION }} + - name: Setup rust + uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff + with: + toolchain: ${{ matrix.PYTHON.RUST }} + components: rustfmt,clippy + if: matrix.PYTHON.RUST + - run: rustup component add llvm-tools-preview - name: Clone wycheproof timeout-minutes: 2 @@ -200,104 +214,6 @@ jobs: NOXSESSION: ${{ matrix.IMAGE.NOXSESSION }} - uses: ./.github/actions/upload-coverage - linux-rust: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - PYTHON: - - "3.11" - RUST: - # Cover MSRV. 1.60+ and beta/nightly are in the linux-rust-coverage section. - - 1.56.0 - name: "${{ matrix.PYTHON }} with Rust ${{ matrix.RUST }}" - timeout-minutes: 15 - steps: - - uses: actions/checkout@v3.5.2 - timeout-minutes: 3 - with: - persist-credentials: false - fetch-depth: 0 - - name: set mtimes for rust dirs - uses: ./.github/actions/mtime-fix - - name: Cache rust and pip - uses: ./.github/actions/cache - timeout-minutes: 2 - - name: Setup python - uses: actions/setup-python@v4.6.1 - with: - python-version: ${{ matrix.PYTHON }} - - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff - with: - toolchain: ${{ matrix.RUST }} - - name: Clone wycheproof - timeout-minutes: 2 - uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - - name: Create nox environment - run: nox -v --install-only -s tests-nocoverage - env: - CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - - name: Tests - run: nox --no-install -s tests-nocoverage -- --color=yes --wycheproof-root=wycheproof - env: - COLUMNS: 80 - - uses: ./.github/actions/upload-coverage - - linux-rust-coverage: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - PYTHON: - - "3.11" - RUST: - # Potential future MSRVs: - # 1.60 - pem 2.0.1 - - 1.60.0 - - beta - - nightly - name: "Rust Coverage" - timeout-minutes: 15 - steps: - - uses: actions/checkout@v3.5.2 - timeout-minutes: 3 - with: - persist-credentials: false - fetch-depth: 0 - - name: set mtimes for rust dirs - uses: ./.github/actions/mtime-fix - - uses: dtolnay/rust-toolchain@52e69531e6f69a396bc9d1226284493a5db969ff - id: rust-toolchain - with: - toolchain: ${{ matrix.RUST }} - components: llvm-tools-preview,rustfmt,clippy - - name: Cache rust and pip - id: cargo-cache - uses: ./.github/actions/cache - timeout-minutes: 2 - with: - key: coverage - - name: Setup python - uses: actions/setup-python@v4.6.1 - with: - python-version: ${{ matrix.PYTHON }} - - - name: Clone wycheproof - timeout-minutes: 2 - uses: ./.github/actions/wycheproof - - run: python -m pip install -c ci-constraints-requirements.txt 'nox' - - name: Create nox environment - run: nox -v --install-only -s tests rust - env: - CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - - name: Tests - run: nox --no-install -s tests rust -- --color=yes --wycheproof-root=wycheproof - env: - COLUMNS: 80 - CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }} - - uses: ./.github/actions/upload-coverage - macos: runs-on: ${{ matrix.RUNNER.OS }} strategy: @@ -494,7 +410,7 @@ jobs: all-green: # https://github.community/t/is-it-possible-to-require-all-github-actions-tasks-to-pass-without-enumerating-them/117957/4?u=graingert runs-on: ubuntu-latest - needs: [linux, distros, linux-rust, linux-rust-coverage, macos, windows, linux-downstream] + needs: [linux, distros, macos, windows, linux-downstream] if: ${{ always() }} steps: - uses: actions/checkout@v3.5.2 From b3030dd161e1e6ab6a194effa47774db9d2c12d9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 26 May 2023 14:14:47 -0400 Subject: [PATCH 806/827] Convert Poly1305 to Rust (#8788) --- .../hazmat/backends/openssl/backend.py | 11 -- .../hazmat/backends/openssl/poly1305.py | 69 ---------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../bindings/_rust/openssl/poly1305.pyi | 13 ++ .../hazmat/primitives/poly1305.py | 57 +------- src/rust/src/backend/hmac.rs | 2 +- src/rust/src/backend/mod.rs | 3 + src/rust/src/backend/poly1305.rs | 127 ++++++++++++++++++ 8 files changed, 149 insertions(+), 135 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/poly1305.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi create mode 100644 src/rust/src/backend/poly1305.rs diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 00834f8cc04d..f2e381a15d61 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -24,10 +24,6 @@ _EllipticCurvePrivateKey, _EllipticCurvePublicKey, ) -from cryptography.hazmat.backends.openssl.poly1305 import ( - _POLY1305_KEY_SIZE, - _Poly1305Context, -) from cryptography.hazmat.backends.openssl.rsa import ( _RSAPrivateKey, _RSAPublicKey, @@ -1938,13 +1934,6 @@ def poly1305_supported(self) -> bool: return False return self._lib.Cryptography_HAS_POLY1305 == 1 - def create_poly1305_ctx(self, key: bytes) -> _Poly1305Context: - utils._check_byteslike("key", key) - if len(key) != _POLY1305_KEY_SIZE: - raise ValueError("A poly1305 key is 32 bytes long") - - return _Poly1305Context(self, key) - def pkcs7_supported(self) -> bool: return not self._lib.CRYPTOGRAPHY_IS_BORINGSSL diff --git a/src/cryptography/hazmat/backends/openssl/poly1305.py b/src/cryptography/hazmat/backends/openssl/poly1305.py deleted file mode 100644 index bb0c3738b667..000000000000 --- a/src/cryptography/hazmat/backends/openssl/poly1305.py +++ /dev/null @@ -1,69 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.primitives import constant_time - -_POLY1305_TAG_SIZE = 16 -_POLY1305_KEY_SIZE = 32 - - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -class _Poly1305Context: - def __init__(self, backend: Backend, key: bytes) -> None: - self._backend = backend - - key_ptr = self._backend._ffi.from_buffer(key) - # This function copies the key into OpenSSL-owned memory so we don't - # need to retain it ourselves - evp_pkey = self._backend._lib.EVP_PKEY_new_raw_private_key( - self._backend._lib.NID_poly1305, - self._backend._ffi.NULL, - key_ptr, - len(key), - ) - self._backend.openssl_assert(evp_pkey != self._backend._ffi.NULL) - self._evp_pkey = self._backend._ffi.gc( - evp_pkey, self._backend._lib.EVP_PKEY_free - ) - ctx = self._backend._lib.EVP_MD_CTX_new() - self._backend.openssl_assert(ctx != self._backend._ffi.NULL) - self._ctx = self._backend._ffi.gc( - ctx, self._backend._lib.EVP_MD_CTX_free - ) - res = self._backend._lib.EVP_DigestSignInit( - self._ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._evp_pkey, - ) - self._backend.openssl_assert(res == 1) - - def update(self, data: bytes) -> None: - data_ptr = self._backend._ffi.from_buffer(data) - res = self._backend._lib.EVP_DigestSignUpdate( - self._ctx, data_ptr, len(data) - ) - self._backend.openssl_assert(res != 0) - - def finalize(self) -> bytes: - buf = self._backend._ffi.new("unsigned char[]", _POLY1305_TAG_SIZE) - outlen = self._backend._ffi.new("size_t *", _POLY1305_TAG_SIZE) - res = self._backend._lib.EVP_DigestSignFinal(self._ctx, buf, outlen) - self._backend.openssl_assert(res != 0) - self._backend.openssl_assert(outlen[0] == _POLY1305_TAG_SIZE) - return self._backend._ffi.buffer(buf)[: outlen[0]] - - def verify(self, tag: bytes) -> None: - mac = self.finalize() - if not constant_time.bytes_eq(mac, tag): - raise InvalidSignature("Value did not match computed tag.") diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 6712fff2755b..9ab4e6c98cd6 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -11,6 +11,7 @@ from cryptography.hazmat.bindings._rust.openssl import ( hashes, hmac, kdf, + poly1305, x448, x25519, ) @@ -24,6 +25,7 @@ __all__ = [ "kdf", "ed448", "ed25519", + "poly1305", "x448", "x25519", ] diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi new file mode 100644 index 000000000000..2e9b0a9e1254 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi @@ -0,0 +1,13 @@ +# 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. + +class Poly1305: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_tag(key: bytes, data: bytes) -> bytes: ... + @staticmethod + def verify_tag(key: bytes, data: bytes, tag: bytes) -> None: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def verify(self, tag: bytes) -> None: ... diff --git a/src/cryptography/hazmat/primitives/poly1305.py b/src/cryptography/hazmat/primitives/poly1305.py index 77df07f02e68..7f5a77a576fd 100644 --- a/src/cryptography/hazmat/primitives/poly1305.py +++ b/src/cryptography/hazmat/primitives/poly1305.py @@ -4,59 +4,8 @@ from __future__ import annotations -import typing +from cryptography.hazmat.bindings._rust import openssl as rust_openssl -from cryptography import utils -from cryptography.exceptions import ( - AlreadyFinalized, - UnsupportedAlgorithm, - _Reasons, -) -from cryptography.hazmat.backends.openssl.poly1305 import _Poly1305Context +__all__ = ["Poly1305"] - -class Poly1305: - _ctx: typing.Optional[_Poly1305Context] - - def __init__(self, key: bytes): - from cryptography.hazmat.backends.openssl.backend import backend - - if not backend.poly1305_supported(): - raise UnsupportedAlgorithm( - "poly1305 is not supported by this version of OpenSSL.", - _Reasons.UNSUPPORTED_MAC, - ) - self._ctx = backend.create_poly1305_ctx(key) - - def update(self, data: bytes) -> None: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - utils._check_byteslike("data", data) - self._ctx.update(data) - - def finalize(self) -> bytes: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - mac = self._ctx.finalize() - self._ctx = None - return mac - - def verify(self, tag: bytes) -> None: - utils._check_bytes("tag", tag) - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - ctx, self._ctx = self._ctx, None - ctx.verify(tag) - - @classmethod - def generate_tag(cls, key: bytes, data: bytes) -> bytes: - p = Poly1305(key) - p.update(data) - return p.finalize() - - @classmethod - def verify_tag(cls, key: bytes, data: bytes, tag: bytes) -> None: - p = Poly1305(key) - p.update(data) - p.verify(tag) +Poly1305 = rust_openssl.poly1305.Poly1305 diff --git a/src/rust/src/backend/hmac.rs b/src/rust/src/backend/hmac.rs index d37b97277fdd..13509b859024 100644 --- a/src/rust/src/backend/hmac.rs +++ b/src/rust/src/backend/hmac.rs @@ -72,7 +72,7 @@ impl Hmac { let actual = self.finalize(py)?.as_bytes(); if actual.len() != signature.len() || !openssl::memcmp::eq(actual, signature) { return Err(CryptographyError::from( - exceptions::InvalidSignature::new_err(("Signature did not match digest.",)), + exceptions::InvalidSignature::new_err("Signature did not match digest."), )); } diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index e52b149e38ef..970571193d15 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -10,6 +10,7 @@ pub(crate) mod ed448; pub(crate) mod hashes; pub(crate) mod hmac; pub(crate) mod kdf; +pub(crate) mod poly1305; pub(crate) mod utils; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod x25519; @@ -29,6 +30,8 @@ pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult< #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] module.add_submodule(x448::create_module(module.py())?)?; + module.add_submodule(poly1305::create_module(module.py())?)?; + module.add_submodule(hashes::create_module(module.py())?)?; module.add_submodule(hmac::create_module(module.py())?)?; module.add_submodule(kdf::create_module(module.py())?)?; diff --git a/src/rust/src/backend/poly1305.rs b/src/rust/src/backend/poly1305.rs new file mode 100644 index 000000000000..17d279a4023f --- /dev/null +++ b/src/rust/src/backend/poly1305.rs @@ -0,0 +1,127 @@ +// 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. + +use crate::backend::hashes::already_finalized_error; +use crate::buf::CffiBuf; +use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; + +#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.poly1305")] +struct Poly1305 { + signer: Option>, +} + +impl Poly1305 { + fn get_mut_signer(&mut self) -> CryptographyResult<&mut openssl::sign::Signer<'static>> { + if let Some(signer) = self.signer.as_mut() { + return Ok(signer); + }; + Err(already_finalized_error()) + } +} + +#[pyo3::pymethods] +impl Poly1305 { + #[new] + fn new(key: CffiBuf<'_>) -> CryptographyResult { + #[cfg(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL))] + { + return Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(( + "poly1305 is not supported by this version of OpenSSL.", + exceptions::Reasons::UNSUPPORTED_MAC, + )), + )); + } + + #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] + { + if cryptography_openssl::fips::is_enabled() { + return Err(CryptographyError::from( + exceptions::UnsupportedAlgorithm::new_err(( + "poly1305 is not supported by this version of OpenSSL.", + exceptions::Reasons::UNSUPPORTED_MAC, + )), + )); + } + + let pkey = openssl::pkey::PKey::private_key_from_raw_bytes( + key.as_bytes(), + openssl::pkey::Id::POLY1305, + ) + .map_err(|_| { + pyo3::exceptions::PyValueError::new_err("A poly1305 key is 32 bytes long") + })?; + + Ok(Poly1305 { + signer: Some( + openssl::sign::Signer::new_without_digest(&pkey).map_err(|_| { + pyo3::exceptions::PyValueError::new_err("A poly1305 key is 32 bytes long") + })?, + ), + }) + } + } + + #[staticmethod] + fn generate_tag<'p>( + py: pyo3::Python<'p>, + key: CffiBuf<'_>, + data: CffiBuf<'_>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let mut p = Poly1305::new(key)?; + p.update(data)?; + p.finalize(py) + } + + #[staticmethod] + fn verify_tag( + py: pyo3::Python<'_>, + key: CffiBuf<'_>, + data: CffiBuf<'_>, + tag: &[u8], + ) -> CryptographyResult<()> { + let mut p = Poly1305::new(key)?; + p.update(data)?; + p.verify(py, tag) + } + + fn update(&mut self, data: CffiBuf<'_>) -> CryptographyResult<()> { + self.get_mut_signer()?.update(data.as_bytes())?; + Ok(()) + } + + fn finalize<'p>( + &mut self, + py: pyo3::Python<'p>, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let signer = self.get_mut_signer()?; + let result = pyo3::types::PyBytes::new_with(py, signer.len()?, |b| { + let n = signer.sign(b).unwrap(); + assert_eq!(n, b.len()); + Ok(()) + })?; + self.signer = None; + Ok(result) + } + + fn verify(&mut self, py: pyo3::Python<'_>, signature: &[u8]) -> CryptographyResult<()> { + let actual = self.finalize(py)?.as_bytes(); + if actual.len() != signature.len() || !openssl::memcmp::eq(actual, signature) { + return Err(CryptographyError::from( + exceptions::InvalidSignature::new_err("Value did not match computed tag."), + )); + } + + Ok(()) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "poly1305")?; + + m.add_class::()?; + + Ok(m) +} From 9c0dfde80a65bb92d1e5b981e2ea29ce20f9c828 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 00:15:49 +0000 Subject: [PATCH 807/827] Bump BoringSSL and/or OpenSSL in CI (#8973) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2dd1ba58ea4..b1afc783626c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,8 +41,8 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} - # Latest commit on the BoringSSL master branch, as of May 25, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "5fcd47d137f9b556edc7a392035dc2d2f43282ca"}} + # Latest commit on the BoringSSL master branch, as of May 27, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b0a026f8541c551854efd617021bb276f1fe5c23"}} # Latest commit on the OpenSSL master branch, as of May 26, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "0bf7e94c10f1b00510b8a36cdcbedc02a66468be"}} # Builds with various Rust versions. Includes MSRV and potential From 288c302b5041c45dbdb1a567885f50cf953519a7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 27 May 2023 00:32:26 -0400 Subject: [PATCH 808/827] Remove unused bindings (#8972) --- src/_cffi_src/openssl/evp.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index f1c367010398..d5875f7d09b0 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -82,11 +82,6 @@ int EVP_VerifyFinal(EVP_MD_CTX *, const unsigned char *, unsigned int, EVP_PKEY *); -int EVP_DigestSignInit(EVP_MD_CTX *, EVP_PKEY_CTX **, const EVP_MD *, - ENGINE *, EVP_PKEY *); -int EVP_DigestSignUpdate(EVP_MD_CTX *, const void *, size_t); -int EVP_DigestSignFinal(EVP_MD_CTX *, unsigned char *, size_t *); - EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *); @@ -118,9 +113,6 @@ EVP_MD_CTX *EVP_MD_CTX_new(void); void EVP_MD_CTX_free(EVP_MD_CTX *); -int EVP_DigestSign(EVP_MD_CTX *, unsigned char *, size_t *, - const unsigned char *, size_t); - int EVP_PKEY_bits(const EVP_PKEY *); int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *); From 93c96b777acffd6b1fab17077397e5c5a73c4c71 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 27 May 2023 16:07:20 +0200 Subject: [PATCH 809/827] allow null params in AlgorithmIdentifiers with SHA hash function OIDs (#8974) RFC 4055 section 2.1 states "All implementations MUST accept both NULL and absent parameters as legal and equivalent encodings". It also makes some somewhat conflicting statements after that, but LibreSSL omits the null params for PSS, and OpenSSL parses this without issue so tolerance it is. --- docs/development/test-vectors.rst | 3 ++ src/rust/cryptography-x509/src/common.rs | 20 ++++----- src/rust/src/x509/ocsp.rs | 20 ++++----- src/rust/src/x509/sign.rs | 44 ++++++++++++------- tests/x509/test_x509.py | 17 +++++++ .../x509/custom/rsa_pss_sha256_no_null.pem | 20 +++++++++ 6 files changed, 88 insertions(+), 36 deletions(-) create mode 100644 vectors/cryptography_vectors/x509/custom/rsa_pss_sha256_no_null.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 67440fd4b18a..56bc9361c555 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -496,6 +496,9 @@ Custom X.509 Vectors OID to not match the outer signature algorithm OID. * ``ms-certificate-template.pem`` - A certificate with a ``msCertificateTemplate`` extension. +* ``rsa_pss_sha256_no_null.pem`` - A certificate with an RSA PSS signature + with no encoded ``NULL`` for the PSS hash algorithm parameters. This certificate + was generated by LibreSSL. Custom X.509 Request Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 60856b7efd03..466d4b5bd179 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -22,23 +22,23 @@ impl AlgorithmIdentifier<'_> { #[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite, PartialEq, Eq, Hash, Clone, Debug)] pub enum AlgorithmParameters<'a> { #[defined_by(oid::SHA1_OID)] - Sha1(asn1::Null), + Sha1(Option), #[defined_by(oid::SHA224_OID)] - Sha224(asn1::Null), + Sha224(Option), #[defined_by(oid::SHA256_OID)] - Sha256(asn1::Null), + Sha256(Option), #[defined_by(oid::SHA384_OID)] - Sha384(asn1::Null), + Sha384(Option), #[defined_by(oid::SHA512_OID)] - Sha512(asn1::Null), + Sha512(Option), #[defined_by(oid::SHA3_224_OID)] - Sha3_224(asn1::Null), + Sha3_224(Option), #[defined_by(oid::SHA3_256_OID)] - Sha3_256(asn1::Null), + Sha3_256(Option), #[defined_by(oid::SHA3_384_OID)] - Sha3_384(asn1::Null), + Sha3_384(Option), #[defined_by(oid::SHA3_512_OID)] - Sha3_512(asn1::Null), + Sha3_512(Option), #[defined_by(oid::ED25519_OID)] Ed25519, @@ -227,7 +227,7 @@ pub struct DHParams<'a> { // RSA-PSS ASN.1 default hash algorithm pub const PSS_SHA1_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: AlgorithmParameters::Sha1(()), + params: AlgorithmParameters::Sha1(Some(())), }; // This is defined as an AlgorithmIdentifier in RFC 4055, diff --git a/src/rust/src/x509/ocsp.rs b/src/rust/src/x509/ocsp.rs index afa0b026ed1e..05ea096078bb 100644 --- a/src/rust/src/x509/ocsp.rs +++ b/src/rust/src/x509/ocsp.rs @@ -14,11 +14,11 @@ pub(crate) static ALGORITHM_PARAMETERS_TO_HASH: Lazy< HashMap, &str>, > = Lazy::new(|| { let mut h = HashMap::new(); - h.insert(common::AlgorithmParameters::Sha1(()), "SHA1"); - h.insert(common::AlgorithmParameters::Sha224(()), "SHA224"); - h.insert(common::AlgorithmParameters::Sha256(()), "SHA256"); - h.insert(common::AlgorithmParameters::Sha384(()), "SHA384"); - h.insert(common::AlgorithmParameters::Sha512(()), "SHA512"); + h.insert(common::AlgorithmParameters::Sha1(Some(())), "SHA1"); + h.insert(common::AlgorithmParameters::Sha224(Some(())), "SHA224"); + h.insert(common::AlgorithmParameters::Sha256(Some(())), "SHA256"); + h.insert(common::AlgorithmParameters::Sha384(Some(())), "SHA384"); + h.insert(common::AlgorithmParameters::Sha512(Some(())), "SHA512"); h }); @@ -30,35 +30,35 @@ pub(crate) static HASH_NAME_TO_ALGORITHM_IDENTIFIERS: Lazy< "sha1", common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Sha1(()), + params: common::AlgorithmParameters::Sha1(Some(())), }, ); h.insert( "sha224", common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Sha224(()), + params: common::AlgorithmParameters::Sha224(Some(())), }, ); h.insert( "sha256", common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Sha256(()), + params: common::AlgorithmParameters::Sha256(Some(())), }, ); h.insert( "sha384", common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Sha384(()), + params: common::AlgorithmParameters::Sha384(Some(())), }, ); h.insert( "sha512", common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::Sha512(()), + params: common::AlgorithmParameters::Sha512(Some(())), }, ); h diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index 16db5a587f90..b3a799b8cb01 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -507,14 +507,14 @@ fn identify_alg_params_for_hash_type( hash_type: HashType, ) -> pyo3::PyResult> { match hash_type { - HashType::Sha224 => Ok(common::AlgorithmParameters::Sha224(())), - HashType::Sha256 => Ok(common::AlgorithmParameters::Sha256(())), - HashType::Sha384 => Ok(common::AlgorithmParameters::Sha384(())), - HashType::Sha512 => Ok(common::AlgorithmParameters::Sha512(())), - HashType::Sha3_224 => Ok(common::AlgorithmParameters::Sha3_224(())), - HashType::Sha3_256 => Ok(common::AlgorithmParameters::Sha3_256(())), - HashType::Sha3_384 => Ok(common::AlgorithmParameters::Sha3_384(())), - HashType::Sha3_512 => Ok(common::AlgorithmParameters::Sha3_512(())), + HashType::Sha224 => Ok(common::AlgorithmParameters::Sha224(Some(()))), + HashType::Sha256 => Ok(common::AlgorithmParameters::Sha256(Some(()))), + HashType::Sha384 => Ok(common::AlgorithmParameters::Sha384(Some(()))), + HashType::Sha512 => Ok(common::AlgorithmParameters::Sha512(Some(()))), + HashType::Sha3_224 => Ok(common::AlgorithmParameters::Sha3_224(Some(()))), + HashType::Sha3_256 => Ok(common::AlgorithmParameters::Sha3_256(Some(()))), + HashType::Sha3_384 => Ok(common::AlgorithmParameters::Sha3_384(Some(()))), + HashType::Sha3_512 => Ok(common::AlgorithmParameters::Sha3_512(Some(()))), HashType::None => Err(pyo3::exceptions::PyTypeError::new_err( "Algorithm must be a registered hash algorithm, not None.", )), @@ -714,25 +714,37 @@ mod tests { #[test] fn test_identify_alg_params_for_hash_type() { for (hash, params) in [ - (HashType::Sha224, common::AlgorithmParameters::Sha224(())), - (HashType::Sha256, common::AlgorithmParameters::Sha256(())), - (HashType::Sha384, common::AlgorithmParameters::Sha384(())), - (HashType::Sha512, common::AlgorithmParameters::Sha512(())), + ( + HashType::Sha224, + common::AlgorithmParameters::Sha224(Some(())), + ), + ( + HashType::Sha256, + common::AlgorithmParameters::Sha256(Some(())), + ), + ( + HashType::Sha384, + common::AlgorithmParameters::Sha384(Some(())), + ), + ( + HashType::Sha512, + common::AlgorithmParameters::Sha512(Some(())), + ), ( HashType::Sha3_224, - common::AlgorithmParameters::Sha3_224(()), + common::AlgorithmParameters::Sha3_224(Some(())), ), ( HashType::Sha3_256, - common::AlgorithmParameters::Sha3_256(()), + common::AlgorithmParameters::Sha3_256(Some(())), ), ( HashType::Sha3_384, - common::AlgorithmParameters::Sha3_384(()), + common::AlgorithmParameters::Sha3_384(Some(())), ), ( HashType::Sha3_512, - common::AlgorithmParameters::Sha3_512(()), + common::AlgorithmParameters::Sha3_512(Some(())), ), ] { assert_eq!(identify_alg_params_for_hash_type(hash).unwrap(), params); diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 88be1a1763a2..662cb9af2b8e 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -765,6 +765,23 @@ def test_load_cert_pub_key(self, backend): cert.signature_hash_algorithm, ) + def test_load_pss_cert_no_null(self, backend): + """ + This test verifies that PSS certs where the hash algorithm + identifiers have no trailing null still load properly. LibreSSL + generates certs like this. + """ + cert = _load_cert( + os.path.join("x509", "custom", "rsa_pss_sha256_no_null.pem"), + x509.load_pem_x509_certificate, + ) + assert isinstance(cert, x509.Certificate) + pss = cert.signature_algorithm_parameters + assert isinstance(pss, padding.PSS) + assert isinstance(pss._mgf, padding.MGF1) + assert isinstance(pss._mgf._algorithm, hashes.SHA256) + assert isinstance(cert.signature_hash_algorithm, hashes.SHA256) + def test_load_pss_sha1_mgf1_sha1(self, backend): cert = _load_cert( os.path.join("x509", "ee-pss-sha1-cert.pem"), diff --git a/vectors/cryptography_vectors/x509/custom/rsa_pss_sha256_no_null.pem b/vectors/cryptography_vectors/x509/custom/rsa_pss_sha256_no_null.pem new file mode 100644 index 000000000000..3780fe0d56e4 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/rsa_pss_sha256_no_null.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAbgCCQDEHaWKEwyb7zA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQC +AaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIDASMRAwDgYDVQQDDAd0 +ZXN0aW5nMB4XDTIzMDUyNzA2NDExOVoXDTMzMDUyNDA2NDExOVowEjEQMA4GA1UE +AwwHdGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM2INK8b +04HqQ1ZYt94tDO0lFPOeCswGhKJQ9SRzTNpNB1XaJvrzz999gimmedUwgwVXHRdt +9WS/QXuyKzyeHcQFN8IPVylIMNGS9IEVa9NGNXzLVMIJYzDlwrEhQm6O4fUW8VtE +U85BXEw0yTEgeQxfuR688kjp/1bjkYsvLE/ID9EMgnXXmzunuqYxG+nmonfIYTgR +NpmXJJgp096sJHKaRkDaC7eApl6776kueFRRSiAIHY10wHqgOL0pBwIMSd/F/EKv +G0weUBLqjzus7G/+LdC6UoGWgV4EybvYlisH4SnLbNdvFilLWaNbgbD2R07hVaHs +8010rCq5RT766dcCAwEAATA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa +MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIAOCAQEAdKmJnR+UZaMi9RSI +ZBTN5SRv0nTJCwX/citYo8MMcsJ+DOLxR4tC9haYhRD9mIjks1NXcEKN+LqW9hDF +C5ptas03HeEY1NByS3wFSDRHggNFxpwmvX4hGp/8fjaf8EOb1rzh0TsJEgcv4h4Z +KeeSYvCtk5pMe+2lDgLfSegM22RFgXBj/wcI5JDxkGJ4M56++IM55HdXTY1cy7KY +woTtP8G6xzmKdVC+E8XGjBAbyzyommMpAI6aUnjW6oa4fD4ev1X17+/CQb1VyAYs +7nz4uBV1FTNAiUzjrf95KV5p2ir6YcOdspwuRbUJwGP+/1nXeN1pksnh56Fe3J5b +8Zw4cw== +-----END CERTIFICATE----- + From f639144ba7d49547422f3d91c9b3bfe6537d5334 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 28 May 2023 03:23:12 -0400 Subject: [PATCH 810/827] Remove a few more unused bindings (#8977) --- src/_cffi_src/openssl/bignum.py | 2 -- src/_cffi_src/openssl/ec.py | 1 - src/_cffi_src/openssl/pem.py | 1 - src/_cffi_src/openssl/pkcs7.py | 2 -- src/_cffi_src/openssl/ssl.py | 4 ---- src/_cffi_src/openssl/x509name.py | 1 - 6 files changed, 11 deletions(-) diff --git a/src/_cffi_src/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py index 9ea729001433..999e10cd031b 100644 --- a/src/_cffi_src/openssl/bignum.py +++ b/src/_cffi_src/openssl/bignum.py @@ -61,8 +61,6 @@ int BN_num_bytes(const BIGNUM *); -int BN_mod(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); - /* The following 3 prime methods are exposed for Tribler. */ int BN_generate_prime_ex(BIGNUM *, int, int, const BIGNUM *, const BIGNUM *, BN_GENCB *); diff --git a/src/_cffi_src/openssl/ec.py b/src/_cffi_src/openssl/ec.py index e745b3efcd14..0e3604d1d29a 100644 --- a/src/_cffi_src/openssl/ec.py +++ b/src/_cffi_src/openssl/ec.py @@ -35,7 +35,6 @@ size_t EC_get_builtin_curves(EC_builtin_curve *, size_t); -EC_KEY *EC_KEY_new(void); void EC_KEY_free(EC_KEY *); EC_KEY *EC_KEY_new_by_curve_name(int); diff --git a/src/_cffi_src/openssl/pem.py b/src/_cffi_src/openssl/pem.py index 07f267199ad8..950bd3780c9c 100644 --- a/src/_cffi_src/openssl/pem.py +++ b/src/_cffi_src/openssl/pem.py @@ -42,7 +42,6 @@ int PEM_write_bio_X509_CRL(BIO *, X509_CRL *); PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *); -int PEM_write_bio_PKCS7(BIO *, PKCS7 *); DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *); diff --git a/src/_cffi_src/openssl/pkcs7.py b/src/_cffi_src/openssl/pkcs7.py index 60741bbac19d..ef75157a80da 100644 --- a/src/_cffi_src/openssl/pkcs7.py +++ b/src/_cffi_src/openssl/pkcs7.py @@ -48,8 +48,6 @@ FUNCTIONS = """ void PKCS7_free(PKCS7 *); -PKCS7 *PKCS7_sign(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *, - BIO *, int); int SMIME_write_PKCS7(BIO *, PKCS7 *, BIO *, int); int PEM_write_bio_PKCS7_stream(BIO *, PKCS7 *, BIO *, int); PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *, X509 *, EVP_PKEY *, diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index c836be4f9f6d..dfab7f651341 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -12,7 +12,6 @@ static const long Cryptography_HAS_SSL_ST; static const long Cryptography_HAS_TLS_ST; static const long Cryptography_HAS_TLSv1_3_FUNCTIONS; -static const long Cryptography_HAS_DTLS; static const long Cryptography_HAS_SIGALGS; static const long Cryptography_HAS_PSK; static const long Cryptography_HAS_PSK_TLSv1_3; @@ -336,8 +335,6 @@ const char *SSL_get_version(const SSL *); int SSL_version(const SSL *); -void *SSL_get_ex_data(const SSL *, int); - void SSL_set_tlsext_host_name(SSL *, char *); void SSL_CTX_set_tlsext_servername_callback( SSL_CTX *, @@ -498,7 +495,6 @@ static const long Cryptography_HAS_DTLS_GET_DATA_MTU = 1; #endif -static const long Cryptography_HAS_DTLS = 1; /* Wrap DTLSv1_get_timeout to avoid cffi to handle a 'struct timeval'. */ long Cryptography_DTLSv1_get_timeout(SSL *ssl, time_t *ptv_sec, long *ptv_usec) { diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py index 876af17f2d5e..5e0349e4846a 100644 --- a/src/_cffi_src/openssl/x509name.py +++ b/src/_cffi_src/openssl/x509name.py @@ -39,7 +39,6 @@ ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *); ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *); -int X509_NAME_add_entry(X509_NAME *, X509_NAME_ENTRY *, int, int); int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, const unsigned char *, int, int, int); From 5efbc110905230f771d5bde918c059cd3d029e22 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 29 May 2023 02:04:28 -0400 Subject: [PATCH 811/827] Bump syn (#8979) Dependabot doesn't currently update it because of https://github.com/dependabot/dependabot-core/issues/2064 --- src/rust/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 1d1c76d6bca8..9f4f5b36f8ec 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -31,7 +31,7 @@ checksum = "a045c3ccad89f244a86bd1e6cf1a7bf645296e7692698b056399b6efd4639407" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -183,7 +183,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", From 3e24e44527a69884ca0c3247e1b5e9c8bbf590c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 13:07:44 +0000 Subject: [PATCH 812/827] Bump once_cell from 1.17.1 to 1.17.2 in /src/rust (#8982) Bumps [once_cell](https://github.com/matklad/once_cell) from 1.17.1 to 1.17.2. - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.17.1...v1.17.2) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 9f4f5b36f8ec..b66d30259a2c 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "openssl" From 88e8c288975709228005e70301644034463d9823 Mon Sep 17 00:00:00 2001 From: "pyca-boringbot[bot]" <106132319+pyca-boringbot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 00:23:34 +0000 Subject: [PATCH 813/827] Bump BoringSSL and/or OpenSSL in CI (#8983) Co-authored-by: pyca-boringbot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1afc783626c..899b5515c39c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 27, 2023. - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b0a026f8541c551854efd617021bb276f1fe5c23"}} - # Latest commit on the OpenSSL master branch, as of May 26, 2023. - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "0bf7e94c10f1b00510b8a36cdcbedc02a66468be"}} + # Latest commit on the OpenSSL master branch, as of May 30, 2023. + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "36424806d699233b9a90a3a97fff3011828e2548"}} # Builds with various Rust versions. Includes MSRV and potential # future MSRV: # 1.60 - pem 2.0.1 From 730a5ce11a91f40c1bb0f881ab22bc52d6cecef6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 02:01:47 +0000 Subject: [PATCH 814/827] Bump openssl-sys from 0.9.87 to 0.9.88 in /src/rust (#8984) Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.87 to 0.9.88. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.87...openssl-sys-v0.9.88) --- updated-dependencies: - dependency-name: openssl-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- src/rust/cryptography-cffi/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b66d30259a2c..49806893962c 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 3efbf1334343..30c1b44ccfef 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -17,7 +17,7 @@ cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" openssl = "0.10.52" -openssl-sys = "0.9.87" +openssl-sys = "0.9.88" foreign-types-shared = "0.1" [build-dependencies] diff --git a/src/rust/cryptography-cffi/Cargo.toml b/src/rust/cryptography-cffi/Cargo.toml index 652e621e10a0..65051c2a4627 100644 --- a/src/rust/cryptography-cffi/Cargo.toml +++ b/src/rust/cryptography-cffi/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56.0" [dependencies] pyo3 = { version = "0.18", features = ["abi3-py37"] } -openssl-sys = "0.9.87" +openssl-sys = "0.9.88" [build-dependencies] cc = "1.0.72" From 0918c7236c94c29272e0790ba0227cfa9401943b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 02:10:26 +0000 Subject: [PATCH 815/827] Bump coverage from 7.2.6 to 7.2.7 (#8985) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.6 to 7.2.7. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.6...7.2.7) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ci-constraints-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-constraints-requirements.txt b/ci-constraints-requirements.txt index 2c91aecac0da..009faa5e0bdc 100644 --- a/ci-constraints-requirements.txt +++ b/ci-constraints-requirements.txt @@ -29,7 +29,7 @@ click==8.1.3 # via black colorlog==6.7.0 # via nox -coverage==7.2.6 +coverage==7.2.7 # via pytest-cov distlib==0.3.6 # via virtualenv From 851d8ccb340bfc93c827b9e80af939a216b34925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 02:14:28 +0000 Subject: [PATCH 816/827] Bump openssl from 0.10.52 to 0.10.53 in /src/rust (#8986) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.52 to 0.10.53. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.52...openssl-v0.10.53) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- src/rust/cryptography-openssl/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 49806893962c..47d972ff46ff 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -162,9 +162,9 @@ checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" dependencies = [ "bitflags", "cfg-if", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 30c1b44ccfef..2ca1d79d6802 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -16,7 +16,7 @@ cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" -openssl = "0.10.52" +openssl = "0.10.53" openssl-sys = "0.9.88" foreign-types-shared = "0.1" diff --git a/src/rust/cryptography-openssl/Cargo.toml b/src/rust/cryptography-openssl/Cargo.toml index bd153edc40d5..587a85909565 100644 --- a/src/rust/cryptography-openssl/Cargo.toml +++ b/src/rust/cryptography-openssl/Cargo.toml @@ -8,7 +8,7 @@ publish = false rust-version = "1.56.0" [dependencies] -openssl = "0.10.52" +openssl = "0.10.53" ffi = { package = "openssl-sys", version = "0.9.85" } foreign-types = "0.3" foreign-types-shared = "0.1" From f302d28b81607aab28d22b653da78d564824f267 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 29 May 2023 22:17:09 -0400 Subject: [PATCH 817/827] Update CI for new LibreSSL releases (#8975) --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 899b5515c39c..4f79786f3470 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,8 +37,9 @@ jobs: - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.2"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.3"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.3"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.8.0"}} - {VERSION: "3.11", NOXSESSION: "tests-randomorder"} - {VERSION: "3.12-dev", NOXSESSION: "tests"} # Latest commit on the BoringSSL master branch, as of May 27, 2023. From 91e41898e6d1d2a9a6e980c39e2f8baa2fa8a1f8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 29 May 2023 22:32:12 -0400 Subject: [PATCH 818/827] Port DSA to Rust (#8978) --- src/_cffi_src/openssl/bignum.py | 2 - src/_cffi_src/openssl/dsa.py | 3 - src/_cffi_src/openssl/evp.py | 1 - .../hazmat/backends/openssl/backend.py | 117 +----- .../hazmat/backends/openssl/dsa.py | 246 ------------- .../bindings/_rust/openssl/__init__.pyi | 2 + .../hazmat/bindings/_rust/openssl/dsa.pyi | 20 ++ .../hazmat/primitives/asymmetric/dsa.py | 4 + src/rust/src/backend/dh.rs | 3 +- src/rust/src/backend/dsa.rs | 333 ++++++++++++++++++ src/rust/src/backend/ed25519.rs | 3 +- src/rust/src/backend/ed448.rs | 3 +- src/rust/src/backend/mod.rs | 2 + src/rust/src/backend/utils.rs | 40 ++- src/rust/src/backend/x25519.rs | 3 +- src/rust/src/backend/x448.rs | 3 +- src/rust/src/error.rs | 7 +- tests/hazmat/primitives/test_dsa.py | 6 + tests/hazmat/primitives/test_x25519.py | 7 + tests/x509/test_x509_crlbuilder.py | 4 + 20 files changed, 445 insertions(+), 364 deletions(-) delete mode 100644 src/cryptography/hazmat/backends/openssl/dsa.py create mode 100644 src/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi create mode 100644 src/rust/src/backend/dsa.rs diff --git a/src/_cffi_src/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py index 999e10cd031b..044403325582 100644 --- a/src/_cffi_src/openssl/bignum.py +++ b/src/_cffi_src/openssl/bignum.py @@ -39,8 +39,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *, const BIGNUM *, BN_CTX *); void BN_MONT_CTX_free(BN_MONT_CTX *); -BIGNUM *BN_dup(const BIGNUM *); - int BN_set_word(BIGNUM *, BN_ULONG); char *BN_bn2hex(const BIGNUM *); diff --git a/src/_cffi_src/openssl/dsa.py b/src/_cffi_src/openssl/dsa.py index 04478a0e577b..d91076393582 100644 --- a/src/_cffi_src/openssl/dsa.py +++ b/src/_cffi_src/openssl/dsa.py @@ -23,10 +23,7 @@ int DSA_verify(int, const unsigned char *, int, const unsigned char *, int, DSA *); -void DSA_get0_pqg(const DSA *, const BIGNUM **, const BIGNUM **, - const BIGNUM **); int DSA_set0_pqg(DSA *, BIGNUM *, BIGNUM *, BIGNUM *); -void DSA_get0_key(const DSA *, const BIGNUM **, const BIGNUM **); int DSA_set0_key(DSA *, BIGNUM *, BIGNUM *); int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int, int *, unsigned long *, BN_GENCB *); diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index d5875f7d09b0..ce54fd9fe931 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -66,7 +66,6 @@ int EVP_PKEY_type(int); int EVP_PKEY_size(EVP_PKEY *); RSA *EVP_PKEY_get1_RSA(EVP_PKEY *); -DSA *EVP_PKEY_get1_DSA(EVP_PKEY *); int EVP_PKEY_encrypt(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t); diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index f2e381a15d61..02d51094cfe5 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -15,11 +15,6 @@ from cryptography.hazmat.backends.openssl import aead from cryptography.hazmat.backends.openssl.ciphers import _CipherContext from cryptography.hazmat.backends.openssl.cmac import _CMACContext -from cryptography.hazmat.backends.openssl.dsa import ( - _DSAParameters, - _DSAPrivateKey, - _DSAPublicKey, -) from cryptography.hazmat.backends.openssl.ec import ( _EllipticCurvePrivateKey, _EllipticCurvePublicKey, @@ -551,10 +546,9 @@ def _evp_pkey_to_private_key( unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, ) elif key_type == self._lib.EVP_PKEY_DSA: - dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) - self.openssl_assert(dsa_cdata != self._ffi.NULL) - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - return _DSAPrivateKey(self, dsa_cdata, evp_pkey) + return rust_openssl.dsa.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == self._lib.EVP_PKEY_EC: ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) self.openssl_assert(ec_cdata != self._ffi.NULL) @@ -613,10 +607,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: self.openssl_assert(res == 1) return self.load_der_public_key(self._read_mem_bio(bio)) elif key_type == self._lib.EVP_PKEY_DSA: - dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) - self.openssl_assert(dsa_cdata != self._ffi.NULL) - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - return _DSAPublicKey(self, dsa_cdata, evp_pkey) + return rust_openssl.dsa.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) elif key_type == self._lib.EVP_PKEY_EC: ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) if ec_cdata == self._ffi.NULL: @@ -696,36 +689,12 @@ def generate_dsa_parameters(self, key_size: int) -> dsa.DSAParameters: "Key size must be 1024, 2048, 3072, or 4096 bits." ) - ctx = self._lib.DSA_new() - self.openssl_assert(ctx != self._ffi.NULL) - ctx = self._ffi.gc(ctx, self._lib.DSA_free) - - res = self._lib.DSA_generate_parameters_ex( - ctx, - key_size, - self._ffi.NULL, - 0, - self._ffi.NULL, - self._ffi.NULL, - self._ffi.NULL, - ) - - self.openssl_assert(res == 1) - - return _DSAParameters(self, ctx) + return rust_openssl.dsa.generate_parameters(key_size) def generate_dsa_private_key( self, parameters: dsa.DSAParameters ) -> dsa.DSAPrivateKey: - ctx = self._lib.DSAparams_dup( - parameters._dsa_cdata # type: ignore[attr-defined] - ) - self.openssl_assert(ctx != self._ffi.NULL) - ctx = self._ffi.gc(ctx, self._lib.DSA_free) - self._lib.DSA_generate_key(ctx) - evp_pkey = self._dsa_cdata_to_evp_pkey(ctx) - - return _DSAPrivateKey(self, ctx, evp_pkey) + return parameters.generate_private_key() def generate_dsa_private_key_and_parameters( self, key_size: int @@ -733,78 +702,28 @@ def generate_dsa_private_key_and_parameters( parameters = self.generate_dsa_parameters(key_size) return self.generate_dsa_private_key(parameters) - def _dsa_cdata_set_values( - self, dsa_cdata, p, q, g, pub_key, priv_key - ) -> None: - res = self._lib.DSA_set0_pqg(dsa_cdata, p, q, g) - self.openssl_assert(res == 1) - res = self._lib.DSA_set0_key(dsa_cdata, pub_key, priv_key) - self.openssl_assert(res == 1) - def load_dsa_private_numbers( self, numbers: dsa.DSAPrivateNumbers ) -> dsa.DSAPrivateKey: dsa._check_dsa_private_numbers(numbers) - parameter_numbers = numbers.public_numbers.parameter_numbers - - dsa_cdata = self._lib.DSA_new() - self.openssl_assert(dsa_cdata != self._ffi.NULL) - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - p = self._int_to_bn(parameter_numbers.p) - q = self._int_to_bn(parameter_numbers.q) - g = self._int_to_bn(parameter_numbers.g) - pub_key = self._int_to_bn(numbers.public_numbers.y) - priv_key = self._int_to_bn(numbers.x) - self._dsa_cdata_set_values(dsa_cdata, p, q, g, pub_key, priv_key) - - evp_pkey = self._dsa_cdata_to_evp_pkey(dsa_cdata) - - return _DSAPrivateKey(self, dsa_cdata, evp_pkey) + return rust_openssl.dsa.from_private_numbers(numbers) def load_dsa_public_numbers( self, numbers: dsa.DSAPublicNumbers ) -> dsa.DSAPublicKey: dsa._check_dsa_parameters(numbers.parameter_numbers) - dsa_cdata = self._lib.DSA_new() - self.openssl_assert(dsa_cdata != self._ffi.NULL) - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - p = self._int_to_bn(numbers.parameter_numbers.p) - q = self._int_to_bn(numbers.parameter_numbers.q) - g = self._int_to_bn(numbers.parameter_numbers.g) - pub_key = self._int_to_bn(numbers.y) - priv_key = self._ffi.NULL - self._dsa_cdata_set_values(dsa_cdata, p, q, g, pub_key, priv_key) - - evp_pkey = self._dsa_cdata_to_evp_pkey(dsa_cdata) - - return _DSAPublicKey(self, dsa_cdata, evp_pkey) + return rust_openssl.dsa.from_public_numbers(numbers) def load_dsa_parameter_numbers( self, numbers: dsa.DSAParameterNumbers ) -> dsa.DSAParameters: dsa._check_dsa_parameters(numbers) - dsa_cdata = self._lib.DSA_new() - self.openssl_assert(dsa_cdata != self._ffi.NULL) - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - p = self._int_to_bn(numbers.p) - q = self._int_to_bn(numbers.q) - g = self._int_to_bn(numbers.g) - res = self._lib.DSA_set0_pqg(dsa_cdata, p, q, g) - self.openssl_assert(res == 1) - - return _DSAParameters(self, dsa_cdata) - - def _dsa_cdata_to_evp_pkey(self, dsa_cdata): - evp_pkey = self._create_evp_pkey_gc() - res = self._lib.EVP_PKEY_set1_DSA(evp_pkey, dsa_cdata) - self.openssl_assert(res == 1) - return evp_pkey + return rust_openssl.dsa.from_parameter_numbers(numbers) def dsa_supported(self) -> bool: - return not self._fips_enabled + return ( + not self._lib.CRYPTOGRAPHY_IS_BORINGSSL and not self._fips_enabled + ) def dsa_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: if not self.dsa_supported(): @@ -1409,8 +1328,6 @@ def _private_key_bytes( if encoding is serialization.Encoding.PEM: if key_type == self._lib.EVP_PKEY_RSA: write_bio = self._lib.PEM_write_bio_RSAPrivateKey - elif key_type == self._lib.EVP_PKEY_DSA: - write_bio = self._lib.PEM_write_bio_DSAPrivateKey else: assert key_type == self._lib.EVP_PKEY_EC write_bio = self._lib.PEM_write_bio_ECPrivateKey @@ -1426,11 +1343,9 @@ def _private_key_bytes( ) if key_type == self._lib.EVP_PKEY_RSA: write_bio = self._lib.i2d_RSAPrivateKey_bio - elif key_type == self._lib.EVP_PKEY_EC: - write_bio = self._lib.i2d_ECPrivateKey_bio else: - assert key_type == self._lib.EVP_PKEY_DSA - write_bio = self._lib.i2d_DSAPrivateKey_bio + assert key_type == self._lib.EVP_PKEY_EC + write_bio = self._lib.i2d_ECPrivateKey_bio return self._bio_func_output(write_bio, cdata) raise ValueError("Unsupported encoding for TraditionalOpenSSL") diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py deleted file mode 100644 index 411a80820e85..000000000000 --- a/src/cryptography/hazmat/backends/openssl/dsa.py +++ /dev/null @@ -1,246 +0,0 @@ -# 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. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends.openssl.utils import ( - _calculate_digest_and_algorithm, -) -from cryptography.hazmat.primitives import hashes, serialization -from cryptography.hazmat.primitives.asymmetric import dsa -from cryptography.hazmat.primitives.asymmetric import utils as asym_utils - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -def _dsa_sig_sign( - backend: Backend, private_key: _DSAPrivateKey, data: bytes -) -> bytes: - sig_buf_len = backend._lib.DSA_size(private_key._dsa_cdata) - sig_buf = backend._ffi.new("unsigned char[]", sig_buf_len) - buflen = backend._ffi.new("unsigned int *") - - # The first parameter passed to DSA_sign is unused by OpenSSL but - # must be an integer. - res = backend._lib.DSA_sign( - 0, data, len(data), sig_buf, buflen, private_key._dsa_cdata - ) - backend.openssl_assert(res == 1) - backend.openssl_assert(buflen[0]) - - return backend._ffi.buffer(sig_buf)[: buflen[0]] - - -def _dsa_sig_verify( - backend: Backend, - public_key: _DSAPublicKey, - signature: bytes, - data: bytes, -) -> None: - # The first parameter passed to DSA_verify is unused by OpenSSL but - # must be an integer. - res = backend._lib.DSA_verify( - 0, data, len(data), signature, len(signature), public_key._dsa_cdata - ) - - if res != 1: - backend._consume_errors() - raise InvalidSignature - - -class _DSAParameters(dsa.DSAParameters): - def __init__(self, backend: Backend, dsa_cdata): - self._backend = backend - self._dsa_cdata = dsa_cdata - - def parameter_numbers(self) -> dsa.DSAParameterNumbers: - p = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(q[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - return dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(p[0]), - q=self._backend._bn_to_int(q[0]), - g=self._backend._bn_to_int(g[0]), - ) - - def generate_private_key(self) -> dsa.DSAPrivateKey: - return self._backend.generate_dsa_private_key(self) - - -class _DSAPrivateKey(dsa.DSAPrivateKey): - _key_size: int - - def __init__(self, backend: Backend, dsa_cdata, evp_pkey): - self._backend = backend - self._dsa_cdata = dsa_cdata - self._evp_pkey = evp_pkey - - p = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_pqg( - dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL - ) - self._backend.openssl_assert(p[0] != backend._ffi.NULL) - self._key_size = self._backend._lib.BN_num_bits(p[0]) - - @property - def key_size(self) -> int: - return self._key_size - - def private_numbers(self) -> dsa.DSAPrivateNumbers: - p = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - pub_key = self._backend._ffi.new("BIGNUM **") - priv_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(q[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - self._backend._lib.DSA_get0_key(self._dsa_cdata, pub_key, priv_key) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(priv_key[0] != self._backend._ffi.NULL) - return dsa.DSAPrivateNumbers( - public_numbers=dsa.DSAPublicNumbers( - parameter_numbers=dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(p[0]), - q=self._backend._bn_to_int(q[0]), - g=self._backend._bn_to_int(g[0]), - ), - y=self._backend._bn_to_int(pub_key[0]), - ), - x=self._backend._bn_to_int(priv_key[0]), - ) - - def public_key(self) -> dsa.DSAPublicKey: - dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata) - self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL) - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - pub_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_key( - self._dsa_cdata, pub_key, self._backend._ffi.NULL - ) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - pub_key_dup = self._backend._lib.BN_dup(pub_key[0]) - res = self._backend._lib.DSA_set0_key( - dsa_cdata, pub_key_dup, self._backend._ffi.NULL - ) - self._backend.openssl_assert(res == 1) - evp_pkey = self._backend._dsa_cdata_to_evp_pkey(dsa_cdata) - return _DSAPublicKey(self._backend, dsa_cdata, evp_pkey) - - def parameters(self) -> dsa.DSAParameters: - dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata) - self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL) - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - return _DSAParameters(self._backend, dsa_cdata) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - return self._backend._private_key_bytes( - encoding, - format, - encryption_algorithm, - self, - self._evp_pkey, - self._dsa_cdata, - ) - - def sign( - self, - data: bytes, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], - ) -> bytes: - data, _ = _calculate_digest_and_algorithm(data, algorithm) - return _dsa_sig_sign(self._backend, self, data) - - -class _DSAPublicKey(dsa.DSAPublicKey): - _key_size: int - - def __init__(self, backend: Backend, dsa_cdata, evp_pkey): - self._backend = backend - self._dsa_cdata = dsa_cdata - self._evp_pkey = evp_pkey - p = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_pqg( - dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL - ) - self._backend.openssl_assert(p[0] != backend._ffi.NULL) - self._key_size = self._backend._lib.BN_num_bits(p[0]) - - @property - def key_size(self) -> int: - return self._key_size - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _DSAPublicKey): - return NotImplemented - - return ( - self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) - == 1 - ) - - def public_numbers(self) -> dsa.DSAPublicNumbers: - p = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - g = self._backend._ffi.new("BIGNUM **") - pub_key = self._backend._ffi.new("BIGNUM **") - self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(q[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(g[0] != self._backend._ffi.NULL) - self._backend._lib.DSA_get0_key( - self._dsa_cdata, pub_key, self._backend._ffi.NULL - ) - self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL) - return dsa.DSAPublicNumbers( - parameter_numbers=dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(p[0]), - q=self._backend._bn_to_int(q[0]), - g=self._backend._bn_to_int(g[0]), - ), - y=self._backend._bn_to_int(pub_key[0]), - ) - - def parameters(self) -> dsa.DSAParameters: - dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata) - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - return _DSAParameters(self._backend, dsa_cdata) - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def verify( - self, - signature: bytes, - data: bytes, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], - ) -> None: - data, _ = _calculate_digest_and_algorithm(data, algorithm) - return _dsa_sig_verify(self._backend, self, signature, data) diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 9ab4e6c98cd6..82f30d20b0ab 100644 --- a/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -6,6 +6,7 @@ import typing from cryptography.hazmat.bindings._rust.openssl import ( dh, + dsa, ed448, ed25519, hashes, @@ -20,6 +21,7 @@ __all__ = [ "openssl_version", "raise_openssl_error", "dh", + "dsa", "hashes", "hmac", "kdf", diff --git a/src/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi b/src/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi new file mode 100644 index 000000000000..5a56f256d52d --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi @@ -0,0 +1,20 @@ +# 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. + +from cryptography.hazmat.primitives.asymmetric import dsa + +class DSAPrivateKey: ... +class DSAPublicKey: ... +class DSAParameters: ... + +def generate_parameters(key_size: int) -> dsa.DSAParameters: ... +def private_key_from_ptr(ptr: int) -> dsa.DSAPrivateKey: ... +def public_key_from_ptr(ptr: int) -> dsa.DSAPublicKey: ... +def from_private_numbers( + numbers: dsa.DSAPrivateNumbers, +) -> dsa.DSAPrivateKey: ... +def from_public_numbers(numbers: dsa.DSAPublicNumbers) -> dsa.DSAPublicKey: ... +def from_parameter_numbers( + numbers: dsa.DSAParameterNumbers, +) -> dsa.DSAParameters: ... diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 1ebfcd52ad13..a8c52de4fb49 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -7,6 +7,7 @@ import abc import typing +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization, hashes from cryptography.hazmat.primitives.asymmetric import utils as asym_utils @@ -26,6 +27,7 @@ def parameter_numbers(self) -> DSAParameterNumbers: DSAParametersWithNumbers = DSAParameters +DSAParameters.register(rust_openssl.dsa.DSAParameters) class DSAPrivateKey(metaclass=abc.ABCMeta): @@ -77,6 +79,7 @@ def private_bytes( DSAPrivateKeyWithSerialization = DSAPrivateKey +DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey) class DSAPublicKey(metaclass=abc.ABCMeta): @@ -128,6 +131,7 @@ def __eq__(self, other: object) -> bool: DSAPublicKeyWithSerialization = DSAPublicKey +DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey) class DSAParameterNumbers: diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index b4dbaf5dded5..7f523c09e594 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -271,6 +271,7 @@ impl DHPrivateKey { format, encryption_algorithm, true, + false, ) } } @@ -302,7 +303,7 @@ impl DHPublicKey { )); } - utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true, false) } fn parameters(&self) -> CryptographyResult { diff --git a/src/rust/src/backend/dsa.rs b/src/rust/src/backend/dsa.rs new file mode 100644 index 000000000000..59a5a676d5d5 --- /dev/null +++ b/src/rust/src/backend/dsa.rs @@ -0,0 +1,333 @@ +// 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. + +use crate::backend::utils; +use crate::error::{CryptographyError, CryptographyResult}; +use crate::exceptions; +use foreign_types_shared::ForeignTypeRef; + +#[pyo3::prelude::pyclass( + module = "cryptography.hazmat.bindings._rust.openssl.dsa", + name = "DSAPrivateKey" +)] +struct DsaPrivateKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass( + module = "cryptography.hazmat.bindings._rust.openssl.dsa", + name = "DSAPublicKey" +)] +struct DsaPublicKey { + pkey: openssl::pkey::PKey, +} + +#[pyo3::prelude::pyclass( + module = "cryptography.hazmat.bindings._rust.openssl.dsa", + name = "DSAParameters" +)] +struct DsaParameters { + dsa: openssl::dsa::Dsa, +} + +#[pyo3::prelude::pyfunction] +fn private_key_from_ptr(ptr: usize) -> DsaPrivateKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + DsaPrivateKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn public_key_from_ptr(ptr: usize) -> DsaPublicKey { + let pkey = unsafe { openssl::pkey::PKeyRef::from_ptr(ptr as *mut _) }; + DsaPublicKey { + pkey: pkey.to_owned(), + } +} + +#[pyo3::prelude::pyfunction] +fn generate_parameters(key_size: u32) -> CryptographyResult { + let dsa = openssl::dsa::Dsa::generate_params(key_size)?; + Ok(DsaParameters { dsa }) +} + +#[pyo3::prelude::pyfunction] +fn from_private_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let public_numbers = numbers.getattr(pyo3::intern!(py, "public_numbers"))?; + let parameter_numbers = public_numbers.getattr(pyo3::intern!(py, "parameter_numbers"))?; + + let dsa = openssl::dsa::Dsa::from_private_components( + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "p"))?)?, + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "q"))?)?, + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "g"))?)?, + utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "x"))?)?, + utils::py_int_to_bn(py, public_numbers.getattr(pyo3::intern!(py, "y"))?)?, + ) + .unwrap(); + let pkey = openssl::pkey::PKey::from_dsa(dsa)?; + Ok(DsaPrivateKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_public_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let parameter_numbers = numbers.getattr(pyo3::intern!(py, "parameter_numbers"))?; + + let dsa = openssl::dsa::Dsa::from_public_components( + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "p"))?)?, + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "q"))?)?, + utils::py_int_to_bn(py, parameter_numbers.getattr(pyo3::intern!(py, "g"))?)?, + utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "y"))?)?, + ) + .unwrap(); + let pkey = openssl::pkey::PKey::from_dsa(dsa)?; + Ok(DsaPublicKey { pkey }) +} + +#[pyo3::prelude::pyfunction] +fn from_parameter_numbers( + py: pyo3::Python<'_>, + numbers: &pyo3::PyAny, +) -> CryptographyResult { + let dsa = openssl::dsa::Dsa::from_pqg( + utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "p"))?)?, + utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "q"))?)?, + utils::py_int_to_bn(py, numbers.getattr(pyo3::intern!(py, "g"))?)?, + ) + .unwrap(); + Ok(DsaParameters { dsa }) +} + +fn clone_dsa_params( + d: &openssl::dsa::Dsa, +) -> Result, openssl::error::ErrorStack> { + openssl::dsa::Dsa::from_pqg(d.p().to_owned()?, d.q().to_owned()?, d.g().to_owned()?) +} + +#[pyo3::prelude::pymethods] +impl DsaPrivateKey { + fn sign<'p>( + &self, + py: pyo3::Python<'p>, + data: &pyo3::types::PyBytes, + algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + let (data, _): (&[u8], &pyo3::PyAny) = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.backends.openssl.utils" + ))? + .call_method1( + pyo3::intern!(py, "_calculate_digest_and_algorithm"), + (data, algorithm), + )? + .extract()?; + + let mut signer = openssl::pkey_ctx::PkeyCtx::new(&self.pkey)?; + signer.sign_init()?; + let mut sig = vec![]; + signer.sign_to_vec(data, &mut sig)?; + Ok(pyo3::types::PyBytes::new(py, &sig)) + } + + #[getter] + fn key_size(&self) -> i32 { + self.pkey.dsa().unwrap().p().num_bits() + } + + fn public_key(&self) -> CryptographyResult { + let priv_dsa = self.pkey.dsa()?; + let pub_dsa = openssl::dsa::Dsa::from_public_components( + priv_dsa.p().to_owned()?, + priv_dsa.q().to_owned()?, + priv_dsa.g().to_owned()?, + priv_dsa.pub_key().to_owned()?, + ) + .unwrap(); + let pkey = openssl::pkey::PKey::from_dsa(pub_dsa)?; + Ok(DsaPublicKey { pkey }) + } + + fn parameters(&self) -> CryptographyResult { + let dsa = clone_dsa_params(&self.pkey.dsa().unwrap())?; + Ok(DsaParameters { dsa }) + } + + fn private_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let dsa = self.pkey.dsa().unwrap(); + + let py_p = utils::bn_to_py_int(py, dsa.p())?; + let py_q = utils::bn_to_py_int(py, dsa.q())?; + let py_g = utils::bn_to_py_int(py, dsa.g())?; + + let py_pub_key = utils::bn_to_py_int(py, dsa.pub_key())?; + let py_private_key = utils::bn_to_py_int(py, dsa.priv_key())?; + + let dsa_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dsa" + ))?; + + let parameter_numbers = + dsa_mod.call_method1(pyo3::intern!(py, "DSAParameterNumbers"), (py_p, py_q, py_g))?; + let public_numbers = dsa_mod.call_method1( + pyo3::intern!(py, "DSAPublicNumbers"), + (py_pub_key, parameter_numbers), + )?; + + Ok(dsa_mod.call_method1( + pyo3::intern!(py, "DSAPrivateNumbers"), + (py_private_key, public_numbers), + )?) + } + + fn private_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + encryption_algorithm: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_private_bytes( + py, + slf, + &slf.borrow().pkey, + encoding, + format, + encryption_algorithm, + true, + false, + ) + } +} + +#[pyo3::prelude::pymethods] +impl DsaPublicKey { + fn verify( + &self, + py: pyo3::Python<'_>, + signature: &[u8], + data: &pyo3::types::PyBytes, + algorithm: &pyo3::PyAny, + ) -> CryptographyResult<()> { + let (data, _): (&[u8], &pyo3::PyAny) = py + .import(pyo3::intern!( + py, + "cryptography.hazmat.backends.openssl.utils" + ))? + .call_method1( + pyo3::intern!(py, "_calculate_digest_and_algorithm"), + (data, algorithm), + )? + .extract()?; + + let mut verifier = openssl::pkey_ctx::PkeyCtx::new(&self.pkey)?; + verifier.verify_init()?; + let valid = verifier.verify(data, signature).unwrap_or(false); + if !valid { + return Err(CryptographyError::from( + exceptions::InvalidSignature::new_err(()), + )); + } + + Ok(()) + } + + #[getter] + fn key_size(&self) -> i32 { + self.pkey.dsa().unwrap().p().num_bits() + } + + fn parameters(&self) -> CryptographyResult { + let dsa = clone_dsa_params(&self.pkey.dsa().unwrap())?; + Ok(DsaParameters { dsa }) + } + + fn public_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let dsa = self.pkey.dsa().unwrap(); + + let py_p = utils::bn_to_py_int(py, dsa.p())?; + let py_q = utils::bn_to_py_int(py, dsa.q())?; + let py_g = utils::bn_to_py_int(py, dsa.g())?; + + let py_pub_key = utils::bn_to_py_int(py, dsa.pub_key())?; + + let dsa_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dsa" + ))?; + + let parameter_numbers = + dsa_mod.call_method1(pyo3::intern!(py, "DSAParameterNumbers"), (py_p, py_q, py_g))?; + Ok(dsa_mod.call_method1( + pyo3::intern!(py, "DSAPublicNumbers"), + (py_pub_key, parameter_numbers), + )?) + } + + fn public_bytes<'p>( + slf: &pyo3::PyCell, + py: pyo3::Python<'p>, + encoding: &pyo3::PyAny, + format: &pyo3::PyAny, + ) -> CryptographyResult<&'p pyo3::types::PyBytes> { + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true, false) + } + + fn __richcmp__( + &self, + other: pyo3::PyRef<'_, DsaPublicKey>, + op: pyo3::basic::CompareOp, + ) -> pyo3::PyResult { + match op { + pyo3::basic::CompareOp::Eq => Ok(self.pkey.public_eq(&other.pkey)), + pyo3::basic::CompareOp::Ne => Ok(!self.pkey.public_eq(&other.pkey)), + _ => Err(pyo3::exceptions::PyTypeError::new_err("Cannot be ordered")), + } + } +} + +#[pyo3::prelude::pymethods] +impl DsaParameters { + fn generate_private_key(&self) -> CryptographyResult { + let dsa = clone_dsa_params(&self.dsa)?.generate_key()?; + let pkey = openssl::pkey::PKey::from_dsa(dsa)?; + Ok(DsaPrivateKey { pkey }) + } + + fn parameter_numbers<'p>(&self, py: pyo3::Python<'p>) -> CryptographyResult<&'p pyo3::PyAny> { + let py_p = utils::bn_to_py_int(py, self.dsa.p())?; + let py_q = utils::bn_to_py_int(py, self.dsa.q())?; + let py_g = utils::bn_to_py_int(py, self.dsa.g())?; + + let dsa_mod = py.import(pyo3::intern!( + py, + "cryptography.hazmat.primitives.asymmetric.dsa" + ))?; + + Ok(dsa_mod.call_method1(pyo3::intern!(py, "DSAParameterNumbers"), (py_p, py_q, py_g))?) + } +} + +pub(crate) fn create_module(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> { + let m = pyo3::prelude::PyModule::new(py, "dsa")?; + m.add_function(pyo3::wrap_pyfunction!(private_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(public_key_from_ptr, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(generate_parameters, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_private_numbers, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_public_numbers, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(from_parameter_numbers, m)?)?; + + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + + Ok(m) +} diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index 8cad193c7a92..7bee88104482 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -112,6 +112,7 @@ impl Ed25519PrivateKey { format, encryption_algorithm, true, + true, ) } } @@ -145,7 +146,7 @@ impl Ed25519PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true, true) } fn __richcmp__( diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index 925a9fdb14f2..c0c621a321c3 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -110,6 +110,7 @@ impl Ed448PrivateKey { format, encryption_algorithm, true, + true, ) } } @@ -143,7 +144,7 @@ impl Ed448PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, true, true) } fn __richcmp__( diff --git a/src/rust/src/backend/mod.rs b/src/rust/src/backend/mod.rs index 970571193d15..765b0ab199f4 100644 --- a/src/rust/src/backend/mod.rs +++ b/src/rust/src/backend/mod.rs @@ -3,6 +3,7 @@ // for complete details. pub(crate) mod dh; +pub(crate) mod dsa; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] pub(crate) mod ed25519; #[cfg(all(not(CRYPTOGRAPHY_IS_LIBRESSL), not(CRYPTOGRAPHY_IS_BORINGSSL)))] @@ -19,6 +20,7 @@ pub(crate) mod x448; pub(crate) fn add_to_module(module: &pyo3::prelude::PyModule) -> pyo3::PyResult<()> { module.add_submodule(dh::create_module(module.py())?)?; + module.add_submodule(dsa::create_module(module.py())?)?; #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] module.add_submodule(ed25519::create_module(module.py())?)?; diff --git a/src/rust/src/backend/utils.rs b/src/rust/src/backend/utils.rs index 072a80f5f73d..dea36117182b 100644 --- a/src/rust/src/backend/utils.rs +++ b/src/rust/src/backend/utils.rs @@ -37,6 +37,7 @@ pub(crate) fn bn_to_big_endian_bytes(b: &openssl::bn::BigNumRef) -> Cryptography Ok(b.to_vec_padded(b.num_bits() / 8 + 1)?) } +#[allow(clippy::too_many_arguments)] pub(crate) fn pkey_private_bytes<'p>( py: pyo3::Python<'p>, key_obj: &pyo3::PyAny, @@ -45,6 +46,7 @@ pub(crate) fn pkey_private_bytes<'p>( format: &pyo3::PyAny, encryption_algorithm: &pyo3::PyAny, openssh_allowed: bool, + raw_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import(pyo3::intern!( py, @@ -89,8 +91,9 @@ pub(crate) fn pkey_private_bytes<'p>( } #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) + if raw_allowed + && (encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?)) { if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) || !format.is(private_format_class.getattr(pyo3::intern!(py, "Raw"))?) @@ -151,6 +154,33 @@ pub(crate) fn pkey_private_bytes<'p>( )); } + if format.is(private_format_class.getattr(pyo3::intern!(py, "TraditionalOpenSSL"))?) { + if let Ok(dsa) = pkey.dsa() { + if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { + let pem_bytes = if password.is_empty() { + dsa.private_key_to_pem()? + } else { + dsa.private_key_to_pem_passphrase( + openssl::symm::Cipher::aes_256_cbc(), + password, + )? + }; + return Ok(pyo3::types::PyBytes::new(py, &pem_bytes)); + } else if encoding.is(encoding_class.getattr(pyo3::intern!(py, "DER"))?) { + if !password.is_empty() { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Encryption is not supported for DER encoded traditional OpenSSL keys", + ), + )); + } + + let der_bytes = dsa.private_key_to_der()?; + return Ok(pyo3::types::PyBytes::new(py, &der_bytes)); + } + } + } + // OpenSSH + PEM if openssh_allowed && format.is(private_format_class.getattr(pyo3::intern!(py, "OpenSSH"))?) { if encoding.is(encoding_class.getattr(pyo3::intern!(py, "PEM"))?) { @@ -185,6 +215,7 @@ pub(crate) fn pkey_public_bytes<'p>( encoding: &pyo3::PyAny, format: &pyo3::PyAny, openssh_allowed: bool, + raw_allowed: bool, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { let serialization_mod = py.import(pyo3::intern!( py, @@ -213,8 +244,9 @@ pub(crate) fn pkey_public_bytes<'p>( } #[cfg(any(not(CRYPTOGRAPHY_IS_LIBRESSL), CRYPTOGRAPHY_LIBRESSL_370_OR_GREATER))] - if encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) - || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) + if raw_allowed + && (encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) + || format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?)) { if !encoding.is(encoding_class.getattr(pyo3::intern!(py, "Raw"))?) || !format.is(public_format_class.getattr(pyo3::intern!(py, "Raw"))?) diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index faf21ffddfe9..f27c0594ab3c 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -114,6 +114,7 @@ impl X25519PrivateKey { format, encryption_algorithm, false, + true, ) } } @@ -134,7 +135,7 @@ impl X25519PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false, true) } fn __richcmp__( diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index 456e7fa52ab8..97e52ee6cc95 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -113,6 +113,7 @@ impl X448PrivateKey { format, encryption_algorithm, false, + true, ) } } @@ -133,7 +134,7 @@ impl X448PublicKey { encoding: &pyo3::PyAny, format: &pyo3::PyAny, ) -> CryptographyResult<&'p pyo3::types::PyBytes> { - utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false) + utils::pkey_public_bytes(py, slf, &slf.borrow().pkey, encoding, format, false, true) } fn __richcmp__( diff --git a/src/rust/src/error.rs b/src/rust/src/error.rs index 689ae613e8bb..6699520cb397 100644 --- a/src/rust/src/error.rs +++ b/src/rust/src/error.rs @@ -74,13 +74,16 @@ impl From for pyo3::PyErr { .expect("Failed to append to list"); } exceptions::InternalError::new_err(( - "Unknown OpenSSL error. This error is commonly encountered + format!( + "Unknown OpenSSL error. This error is commonly encountered when another library is not cleaning up the OpenSSL error stack. If you are using cryptography with another library that uses OpenSSL try disabling it before reporting a bug. Otherwise please file an issue at https://github.com/pyca/cryptography/issues with - information on how to reproduce this.", + information on how to reproduce this. ({:?})", + errors + ), errors.to_object(py), )) }), diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index b97d7634396e..00920868fc65 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -395,6 +395,8 @@ def test_public_key_equality(self, backend): assert key1 == key2 assert key1 != key3 assert key1 != object() + with pytest.raises(TypeError): + key1 < key2 # type: ignore[operator] @pytest.mark.supported( @@ -711,6 +713,10 @@ def test_private_bytes_encrypted_pem(self, backend, fmt, password): (serialization.Encoding.DER, serialization.PrivateFormat.Raw), (serialization.Encoding.Raw, serialization.PrivateFormat.Raw), (serialization.Encoding.X962, serialization.PrivateFormat.PKCS8), + ( + serialization.Encoding.SMIME, + serialization.PrivateFormat.TraditionalOpenSSL, + ), ], ) def test_private_bytes_rejects_invalid(self, encoding, fmt, backend): diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index ae4f382bc487..2b86d3d5e22b 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -254,6 +254,13 @@ def test_invalid_private_bytes(self, backend): serialization.NoEncryption(), ) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.NoEncryption(), + ) + def test_invalid_public_bytes(self, backend): key = X25519PrivateKey.generate().public_key() with pytest.raises(ValueError): diff --git a/tests/x509/test_x509_crlbuilder.py b/tests/x509/test_x509_crlbuilder.py index 8633f8abba22..95c0677bb777 100644 --- a/tests/x509/test_x509_crlbuilder.py +++ b/tests/x509/test_x509_crlbuilder.py @@ -524,6 +524,10 @@ def test_sign_with_invalid_hash_ed448(self, backend): with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend) + @pytest.mark.supported( + only_if=lambda backend: backend.dsa_supported(), + skip_message="Requires OpenSSL with DSA support", + ) def test_sign_dsa_key(self, backend): private_key = DSA_KEY_2048.private_key(backend) invalidity_date = x509.InvalidityDate( From 31436a486661cd863d4c77e40facf93fbb2d9f54 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 30 May 2023 11:32:57 +0900 Subject: [PATCH 819/827] admit to the existence of nuance in HKDF (#8987) * admit to the existence of nuance in HKDF * Update docs/hazmat/primitives/key-derivation-functions.rst Co-authored-by: Alex Gaynor --------- Co-authored-by: Alex Gaynor --- docs/hazmat/primitives/key-derivation-functions.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst index ff9a5ba0ffe7..7c5c643e2218 100644 --- a/docs/hazmat/primitives/key-derivation-functions.rst +++ b/docs/hazmat/primitives/key-derivation-functions.rst @@ -460,7 +460,8 @@ HKDF to be secret, but may cause stronger security guarantees if secret; see :rfc:`5869` and the `HKDF paper`_ for more details. If ``None`` is explicitly passed a default salt of ``algorithm.digest_size // 8`` null - bytes will be used. + bytes will be used. See `understanding HKDF`_ for additional detail about + the salt and info parameters. :param bytes info: Application specific context information. If ``None`` is explicitly passed an empty byte string will be used. @@ -1037,3 +1038,4 @@ Interface .. _`here`: https://stackoverflow.com/a/30308723/1170681 .. _`recommends`: https://tools.ietf.org/html/rfc7914#section-2 .. _`The scrypt paper`: https://www.tarsnap.com/scrypt/scrypt.pdf +.. _`understanding HKDF`: https://soatok.blog/2021/11/17/understanding-hkdf/ From 8708245ccdeaff21d65eea68a4f8d2a7c5949a22 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 31 May 2023 05:45:23 +0900 Subject: [PATCH 820/827] new openssl day (#8990) --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f79786f3470..c0fe786454e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,15 +28,15 @@ jobs: PYTHON: - {VERSION: "3.11", NOXSESSION: "flake"} - {VERSION: "3.11", NOXSESSION: "rust"} - - {VERSION: "3.11", NOXSESSION: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} + - {VERSION: "3.11", NOXSESSION: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1"}} - {VERSION: "pypy-3.8", NOXSESSION: "tests-nocoverage"} - {VERSION: "pypy-3.9", NOXSESSION: "tests-nocoverage"} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1t"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.0.8"}} - - {VERSION: "3.11", NOXSESSION: "tests-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} - - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.0", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} - - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.0"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1u"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.0.9"}} + - {VERSION: "3.11", NOXSESSION: "tests-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct no-psk"}} + - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1", CONFIG_FLAGS: "no-legacy", NO_LEGACY: "1"}} + - {VERSION: "3.11", NOXSESSION: "tests", NOXARGS: "--enable-fips=1", OPENSSL: {TYPE: "openssl", CONFIG_FLAGS: "enable-fips", VERSION: "3.1.1"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.6.3"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.3"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.8.0"}} From c4d494fd3ee907316bd846e90cbf4a8df75a25ac Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 31 May 2023 06:33:32 +0900 Subject: [PATCH 821/827] 41.0.0 version bump (#8991) * 41.0.0 version bump * bust cache since we don't currently compute cache key including version --- .github/actions/cache/action.yml | 2 +- CHANGELOG.rst | 7 +++---- pyproject.toml | 2 +- src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- vectors/pyproject.toml | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 6d254d398299..9b0c9271300d 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -47,7 +47,7 @@ runs: ~/.cargo/registry/cache/ src/rust/target/ ${{ inputs.additional-paths }} - key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ steps.normalized-key.outputs.key }}-5-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} + key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ steps.normalized-key.outputs.key }}-6-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }} - name: Size of cache items run: | du -sh ~/.cargo/registry/index/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1811f801cbf5..95e2ab25c0d9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,16 +3,15 @@ Changelog .. _v41-0-0: -41.0.0 - `main`_ -~~~~~~~~~~~~~~~~ - -.. note:: This version is not yet released and is under active development. +41.0.0 - 2023-05-30 +~~~~~~~~~~~~~~~~~~~ * **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been removed. Users on older version of OpenSSL will need to upgrade. * **BACKWARDS INCOMPATIBLE:** Support for Python 3.6 has been removed. * **BACKWARDS INCOMPATIBLE:** Dropped support for LibreSSL < 3.6. * Updated the minimum supported Rust version (MSRV) to 1.56.0, from 1.48.0. +* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.1.1. * Added support for the :class:`~cryptography.x509.OCSPAcceptableResponses` OCSP extension. * Added support for the :class:`~cryptography.x509.MSCertificateTemplate` diff --git a/pyproject.toml b/pyproject.toml index 6f786bdb7e9a..c9de27381328 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography" -version = "41.0.0.dev1" +version = "41.0.0" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 5a31e0ff9a59..b66e23c606ba 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -10,7 +10,7 @@ "__copyright__", ] -__version__ = "41.0.0.dev1" +__version__ = "41.0.0" __author__ = "The Python Cryptographic Authority and individual contributors" diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index 24340ac421e4..6030fab339b0 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "41.0.0.dev1" +__version__ = "41.0.0" diff --git a/vectors/pyproject.toml b/vectors/pyproject.toml index f3da68b11abe..44d517f0560e 100644 --- a/vectors/pyproject.toml +++ b/vectors/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography_vectors" -version = "41.0.0.dev1" +version = "41.0.0" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] From b99900596e65f31543d62cf1a52069c709ba7970 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Jun 2023 20:02:55 +0800 Subject: [PATCH 822/827] Backport tolerate (#9006) * tolerate NULL params in ECDSA SHA2 AlgorithmIdentifier (#9002) * tolerate NULL params in ECDSA SHA2 AlgorithmIdentifier Java 11 does this incorrectly. It was fixed in Java16+ and they are planning to do a backport, but we'll need to tolerate this invalid encoding for a while. * test both inner and outer * changelog entry * language --- CHANGELOG.rst | 8 ++++ docs/development/test-vectors.rst | 2 + src/rust/cryptography-x509/src/common.rs | 12 +++-- src/rust/src/x509/certificate.rs | 30 ++++++++++++- src/rust/src/x509/sign.rs | 44 ++++++++++++------- tests/x509/test_x509.py | 15 +++++++ .../x509/custom/ecdsa_null_alg.pem | 9 ++++ 7 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 vectors/cryptography_vectors/x509/custom/ecdsa_null_alg.pem diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 95e2ab25c0d9..6a8b2ec4fb2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog ========= +.. _v41-0-1: + +41.0.1 - 2023-06-01 +~~~~~~~~~~~~~~~~~~~ + +* Temporarily allow invalid ECDSA signature algorithm parameters in X.509 + certificates, which are generated by older versions of Java. + .. _v41-0-0: 41.0.0 - 2023-05-30 diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 56bc9361c555..3e54c40ae43d 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -499,6 +499,8 @@ Custom X.509 Vectors * ``rsa_pss_sha256_no_null.pem`` - A certificate with an RSA PSS signature with no encoded ``NULL`` for the PSS hash algorithm parameters. This certificate was generated by LibreSSL. +* ``ecdsa_null_alg.pem`` - A certificate with an ECDSA signature with ``NULL`` + algorithm parameters. This encoding is invalid, but was generated by Java 11. Custom X.509 Request Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/rust/cryptography-x509/src/common.rs b/src/rust/cryptography-x509/src/common.rs index 466d4b5bd179..a882d985e9cb 100644 --- a/src/rust/cryptography-x509/src/common.rs +++ b/src/rust/cryptography-x509/src/common.rs @@ -45,14 +45,18 @@ pub enum AlgorithmParameters<'a> { #[defined_by(oid::ED448_OID)] Ed448, + // These ECDSA algorithms should have no parameters, + // but Java 11 (up to at least 11.0.19) encodes them + // with NULL parameters. The JDK team is looking to + // backport the fix as of June 2023. #[defined_by(oid::ECDSA_WITH_SHA224_OID)] - EcDsaWithSha224, + EcDsaWithSha224(Option), #[defined_by(oid::ECDSA_WITH_SHA256_OID)] - EcDsaWithSha256, + EcDsaWithSha256(Option), #[defined_by(oid::ECDSA_WITH_SHA384_OID)] - EcDsaWithSha384, + EcDsaWithSha384(Option), #[defined_by(oid::ECDSA_WITH_SHA512_OID)] - EcDsaWithSha512, + EcDsaWithSha512(Option), #[defined_by(oid::ECDSA_WITH_SHA3_224_OID)] EcDsaWithSha3_224, diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 3446bbbbb604..9204d730ba03 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -8,7 +8,7 @@ use crate::asn1::{ use crate::error::{CryptographyError, CryptographyResult}; use crate::x509::{extensions, sct, sign}; use crate::{exceptions, x509}; -use cryptography_x509::common::Asn1ReadableOrWritable; +use cryptography_x509::common::{AlgorithmParameters, Asn1ReadableOrWritable}; use cryptography_x509::extensions::Extension; use cryptography_x509::extensions::{ AuthorityKeyIdentifier, BasicConstraints, DisplayText, DistributionPoint, @@ -391,6 +391,10 @@ fn load_der_x509_certificate( // determine if the serial is negative and raise a warning if it is. We want to drop support // for this sort of invalid encoding eventually. warn_if_negative_serial(py, raw.borrow_value().tbs_cert.serial.as_bytes())?; + // determine if the signature algorithm has incorrect parameters and raise a warning if it + // does. this is a bug in JDK11 and we want to drop support for it eventually. + warn_if_invalid_ecdsa_params(py, raw.borrow_value().signature_alg.params.clone())?; + warn_if_invalid_ecdsa_params(py, raw.borrow_value().tbs_cert.signature_alg.params.clone())?; Ok(Certificate { raw, @@ -413,6 +417,30 @@ fn warn_if_negative_serial(py: pyo3::Python<'_>, bytes: &'_ [u8]) -> pyo3::PyRes Ok(()) } +fn warn_if_invalid_ecdsa_params( + py: pyo3::Python<'_>, + params: AlgorithmParameters<'_>, +) -> pyo3::PyResult<()> { + match params { + AlgorithmParameters::EcDsaWithSha224(Some(..)) + | AlgorithmParameters::EcDsaWithSha256(Some(..)) + | AlgorithmParameters::EcDsaWithSha384(Some(..)) + | AlgorithmParameters::EcDsaWithSha512(Some(..)) => { + let cryptography_warning = py + .import(pyo3::intern!(py, "cryptography.utils"))? + .getattr(pyo3::intern!(py, "DeprecatedIn41"))?; + pyo3::PyErr::warn( + py, + cryptography_warning, + "The parsed certificate contains a NULL parameter value in its signature algorithm parameters. This is invalid and will be rejected in a future version of cryptography. If this certificate was created via Java, please upgrade to JDK16+ or the latest JDK11 once a fix is issued. If this certificate was created in some other fashion please report the issue to the cryptography issue tracker. See https://github.com/pyca/cryptography/issues/8996 for more details.", + 2, + )?; + } + _ => {} + } + Ok(()) +} + fn parse_display_text( py: pyo3::Python<'_>, text: DisplayText<'_>, diff --git a/src/rust/src/x509/sign.rs b/src/rust/src/x509/sign.rs index b3a799b8cb01..4b03a2d9ab8e 100644 --- a/src/rust/src/x509/sign.rs +++ b/src/rust/src/x509/sign.rs @@ -234,19 +234,19 @@ pub(crate) fn compute_signature_algorithm<'p>( (KeyType::Ec, HashType::Sha224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::EcDsaWithSha224, + params: common::AlgorithmParameters::EcDsaWithSha224(None), }), (KeyType::Ec, HashType::Sha256) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::EcDsaWithSha256, + params: common::AlgorithmParameters::EcDsaWithSha256(None), }), (KeyType::Ec, HashType::Sha384) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::EcDsaWithSha384, + params: common::AlgorithmParameters::EcDsaWithSha384(None), }), (KeyType::Ec, HashType::Sha512) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), - params: common::AlgorithmParameters::EcDsaWithSha512, + params: common::AlgorithmParameters::EcDsaWithSha512(None), }), (KeyType::Ec, HashType::Sha3_224) => Ok(common::AlgorithmIdentifier { oid: asn1::DefinedByMarker::marker(), @@ -483,10 +483,10 @@ fn identify_key_type_for_algorithm_params( | common::AlgorithmParameters::RsaWithSha3_384(..) | common::AlgorithmParameters::RsaWithSha3_512(..) | common::AlgorithmParameters::RsaPss(..) => Ok(KeyType::Rsa), - common::AlgorithmParameters::EcDsaWithSha224 - | common::AlgorithmParameters::EcDsaWithSha256 - | common::AlgorithmParameters::EcDsaWithSha384 - | common::AlgorithmParameters::EcDsaWithSha512 + common::AlgorithmParameters::EcDsaWithSha224(..) + | common::AlgorithmParameters::EcDsaWithSha256(..) + | common::AlgorithmParameters::EcDsaWithSha384(..) + | common::AlgorithmParameters::EcDsaWithSha512(..) | common::AlgorithmParameters::EcDsaWithSha3_224 | common::AlgorithmParameters::EcDsaWithSha3_256 | common::AlgorithmParameters::EcDsaWithSha3_384 @@ -616,10 +616,10 @@ pub(crate) fn identify_signature_algorithm_parameters<'p>( .call0()?; Ok(pkcs) } - common::AlgorithmParameters::EcDsaWithSha224 - | common::AlgorithmParameters::EcDsaWithSha256 - | common::AlgorithmParameters::EcDsaWithSha384 - | common::AlgorithmParameters::EcDsaWithSha512 + common::AlgorithmParameters::EcDsaWithSha224(_) + | common::AlgorithmParameters::EcDsaWithSha256(_) + | common::AlgorithmParameters::EcDsaWithSha384(_) + | common::AlgorithmParameters::EcDsaWithSha512(_) | common::AlgorithmParameters::EcDsaWithSha3_224 | common::AlgorithmParameters::EcDsaWithSha3_256 | common::AlgorithmParameters::EcDsaWithSha3_384 @@ -682,10 +682,22 @@ mod tests { &common::AlgorithmParameters::RsaWithSha3_512(Some(())), KeyType::Rsa, ), - (&common::AlgorithmParameters::EcDsaWithSha224, KeyType::Ec), - (&common::AlgorithmParameters::EcDsaWithSha256, KeyType::Ec), - (&common::AlgorithmParameters::EcDsaWithSha384, KeyType::Ec), - (&common::AlgorithmParameters::EcDsaWithSha512, KeyType::Ec), + ( + &common::AlgorithmParameters::EcDsaWithSha224(None), + KeyType::Ec, + ), + ( + &common::AlgorithmParameters::EcDsaWithSha256(None), + KeyType::Ec, + ), + ( + &common::AlgorithmParameters::EcDsaWithSha384(None), + KeyType::Ec, + ), + ( + &common::AlgorithmParameters::EcDsaWithSha512(None), + KeyType::Ec, + ), (&common::AlgorithmParameters::EcDsaWithSha3_224, KeyType::Ec), (&common::AlgorithmParameters::EcDsaWithSha3_256, KeyType::Ec), (&common::AlgorithmParameters::EcDsaWithSha3_384, KeyType::Ec), diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index 662cb9af2b8e..0bac1c271cfb 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -5199,6 +5199,21 @@ def test_load_ecdsa_cert(self, backend): cert.signature_algorithm_parameters, ) + def test_load_ecdsa_cert_null_alg_params(self, backend): + """ + This test verifies that we successfully load certificates with encoded + null parameters in the signature AlgorithmIdentifier. This is invalid, + but Java 11 (up to at least 11.0.19) generates certificates with this + encoding so we need to tolerate it at the moment. + """ + with pytest.warns(utils.DeprecatedIn41): + cert = _load_cert( + os.path.join("x509", "custom", "ecdsa_null_alg.pem"), + x509.load_pem_x509_certificate, + ) + assert isinstance(cert.signature_hash_algorithm, hashes.SHA256) + assert isinstance(cert.public_key(), ec.EllipticCurvePublicKey) + def test_load_bitstring_dn(self, backend): cert = _load_cert( os.path.join("x509", "scottishpower-bitstring-dn.pem"), diff --git a/vectors/cryptography_vectors/x509/custom/ecdsa_null_alg.pem b/vectors/cryptography_vectors/x509/custom/ecdsa_null_alg.pem new file mode 100644 index 000000000000..327ad553ae7f --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/ecdsa_null_alg.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBNDCB2aADAgECAgRnI7YfMAwGCCqGSM49BAMCBQAwDzENMAsGA1UEAxMEdGVz +dDAeFw0yMzA1MzExMjI5MDNaFw0yNDA1MjUxMjI5MDNaMA8xDTALBgNVBAMTBHRl +c3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS2LuMFnF5OcuYcldiufvppacg2 +8fF/KeJ/4QLMOTbnkatgx5wNPOUvlkzfT31MscwYyzkv1oTqe58iQ+R75C27oyEw +HzAdBgNVHQ4EFgQUD6COpW8C9Ns86r2BDE0jP0teCTswDAYIKoZIzj0EAwIFAANI +ADBFAiBKOlNsFpW6Bz7CK7Z5zXrCetnMiSH3NrbKSZBXJV62KQIhAKmjGu3rxlJr +xXpK+Uz8AsoFJ0BlgqPpdMtTGSrDq1AN +-----END CERTIFICATE----- From 53dc686431f59658d892b83383a330d796105843 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Jun 2023 20:08:56 +0800 Subject: [PATCH 823/827] Backport null fix (#9007) * Bump openssl from 0.10.53 to 0.10.54 in /src/rust (#9004) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.53 to 0.10.54. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.53...openssl-v0.10.54) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Added tests for NUL bytes in PKCS8 passphrases (#9001) --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alex Gaynor --- src/rust/Cargo.lock | 4 ++-- src/rust/Cargo.toml | 2 +- src/rust/cryptography-openssl/Cargo.toml | 2 +- tests/hazmat/primitives/test_ed25519.py | 7 +++++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 47d972ff46ff..e139358c75fb 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -162,9 +162,9 @@ checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "openssl" -version = "0.10.53" +version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags", "cfg-if", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 2ca1d79d6802..01fba147e759 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -16,7 +16,7 @@ cryptography-x509 = { path = "cryptography-x509" } cryptography-openssl = { path = "cryptography-openssl" } pem = "1.1" ouroboros = "0.15" -openssl = "0.10.53" +openssl = "0.10.54" openssl-sys = "0.9.88" foreign-types-shared = "0.1" diff --git a/src/rust/cryptography-openssl/Cargo.toml b/src/rust/cryptography-openssl/Cargo.toml index 587a85909565..c85f406ae616 100644 --- a/src/rust/cryptography-openssl/Cargo.toml +++ b/src/rust/cryptography-openssl/Cargo.toml @@ -8,7 +8,7 @@ publish = false rust-version = "1.56.0" [dependencies] -openssl = "0.10.53" +openssl = "0.10.54" ffi = { package = "openssl-sys", version = "0.9.85" } foreign-types = "0.3" foreign-types-shared = "0.1" diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 4b47e0a1657f..2501f1cf1bb1 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -245,6 +245,13 @@ def test_invalid_public_bytes(self, backend): None, serialization.load_der_private_key, ), + ( + serialization.Encoding.DER, + serialization.PrivateFormat.PKCS8, + serialization.BestAvailableEncryption(b"\x00"), + b"\x00", + serialization.load_der_private_key, + ), ], ) def test_round_trip_private_serialization( From d02de9f26e9a2353e89427c1cea8b9ed2bae969e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Jun 2023 20:17:49 +0800 Subject: [PATCH 824/827] changelog and version bump (#9008) --- CHANGELOG.rst | 1 + pyproject.toml | 2 +- src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- vectors/pyproject.toml | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6a8b2ec4fb2f..eca152e92217 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,7 @@ Changelog * Temporarily allow invalid ECDSA signature algorithm parameters in X.509 certificates, which are generated by older versions of Java. +* Allow null bytes in pass phrases when serializing private keys. .. _v41-0-0: diff --git a/pyproject.toml b/pyproject.toml index c9de27381328..b2e511f54caa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography" -version = "41.0.0" +version = "41.0.1" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index b66e23c606ba..a77b057ba076 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -10,7 +10,7 @@ "__copyright__", ] -__version__ = "41.0.0" +__version__ = "41.0.1" __author__ = "The Python Cryptographic Authority and individual contributors" diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index 6030fab339b0..51dd6514b3a8 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "41.0.0" +__version__ = "41.0.1" diff --git a/vectors/pyproject.toml b/vectors/pyproject.toml index 44d517f0560e..e2a75f9c4db9 100644 --- a/vectors/pyproject.toml +++ b/vectors/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography_vectors" -version = "41.0.0" +version = "41.0.1" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] From bb204c8ca7bc0df0c24b6f6c1f59ed5f5bee9226 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 10 Jul 2023 08:10:11 -0400 Subject: [PATCH 825/827] Backport: Added PyPy 3.10 to CI (#8933) (#9210) * Added PyPy 3.10 to CI (#8933) * Bump proc-macro2 for nightly --- .github/workflows/ci.yml | 1 + .github/workflows/wheel-builder.yml | 17 +++++++++++++++++ src/rust/Cargo.lock | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0fe786454e4..53958898d142 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - {VERSION: "3.11", NOXSESSION: "docs", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1"}} - {VERSION: "pypy-3.8", NOXSESSION: "tests-nocoverage"} - {VERSION: "pypy-3.9", NOXSESSION: "tests-nocoverage"} + - {VERSION: "pypy-3.10", NOXSESSION: "tests-nocoverage"} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1u"}} - {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "3.0.9"}} - {VERSION: "3.11", NOXSESSION: "tests-ssh", OPENSSL: {TYPE: "openssl", VERSION: "3.1.1"}} diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 677319b3fa5a..b03df812b8d7 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -60,6 +60,7 @@ jobs: - { VERSION: "cp37-cp37m", ABI_VERSION: 'cp37' } - { VERSION: "pp38-pypy38_pp73" } - { VERSION: "pp39-pypy39_pp73" } + - { VERSION: "pp310-pypy310_pp73" } MANYLINUX: - { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest" } - { NAME: "manylinux_2_28_x86_64", CONTAINER: "cryptography-manylinux_2_28:x86_64", RUNNER: "ubuntu-latest"} @@ -74,19 +75,27 @@ jobs: MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} - PYTHON: { VERSION: "pp39-pypy39_pp73" } MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} + - PYTHON: { VERSION: "pp310-pypy310_pp73" } + MANYLINUX: { NAME: "musllinux_1_1_x86_64", CONTAINER: "cryptography-musllinux_1_1:x86_64", RUNNER: "ubuntu-latest"} - PYTHON: { VERSION: "pp38-pypy38_pp73" } MANYLINUX: { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} - PYTHON: { VERSION: "pp39-pypy39_pp73" } MANYLINUX: { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - PYTHON: { VERSION: "pp310-pypy310_pp73" } + MANYLINUX: { NAME: "musllinux_1_1_aarch64", CONTAINER: "cryptography-musllinux_1_1:aarch64", RUNNER: [self-hosted, Linux, ARM64]} # We also don't build pypy wheels for anything except the latest manylinux - PYTHON: { VERSION: "pp38-pypy38_pp73" } MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} - PYTHON: { VERSION: "pp39-pypy39_pp73" } MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} + - PYTHON: { VERSION: "pp310-pypy310_pp73" } + MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} - PYTHON: { VERSION: "pp38-pypy38_pp73" } MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} - PYTHON: { VERSION: "pp39-pypy39_pp73" } MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} + - PYTHON: { VERSION: "pp310-pypy310_pp73" } + MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}" steps: - name: Ridiculous alpine workaround for actions support on arm64 @@ -175,6 +184,11 @@ jobs: DEPLOYMENT_TARGET: '10.12' _PYTHON_HOST_PLATFORM: 'macosx-10.9-x86_64' ARCHFLAGS: '-arch x86_64' + - VERSION: 'pypy-3.10' + BIN_PATH: 'pypy3' + DEPLOYMENT_TARGET: '10.12' + _PYTHON_HOST_PLATFORM: 'macosx-10.9-x86_64' + ARCHFLAGS: '-arch x86_64' name: "${{ matrix.PYTHON.VERSION }} ABI ${{ matrix.PYTHON.ABI_VERSION }} macOS ${{ matrix.PYTHON.ARCHFLAGS }}" steps: - uses: actions/download-artifact@v3.0.2 @@ -253,12 +267,15 @@ jobs: - {VERSION: "3.11", "ABI_VERSION": "cp37"} - {VERSION: "pypy-3.8"} - {VERSION: "pypy-3.9"} + - {VERSION: "pypy-3.10"} exclude: # We need to exclude the below configuration because there is no 32-bit pypy3 - WINDOWS: {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} PYTHON: {VERSION: "pypy-3.8"} - WINDOWS: {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} PYTHON: {VERSION: "pypy-3.9"} + - WINDOWS: {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} + PYTHON: {VERSION: "pypy-3.10"} name: "${{ matrix.PYTHON.VERSION }} ${{ matrix.WINDOWS.WINDOWS }} ${{ matrix.PYTHON.ABI_VERSION }}" steps: - uses: actions/download-artifact@v3.0.2 diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index e139358c75fb..5dcbe68034c8 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] From e190ef190525999d1f599cf8c3aef5cb7f3a8bc4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Jul 2023 19:46:49 -0500 Subject: [PATCH 826/827] Backport ssh cert fix (#9211) * Fix encoding of SSH certs with critical options (#9208) * Add tests for issue #9207 * Fix encoding of SSH certs with critical options * Test unexpected additional values for crit opts/exts * temporarily allow invalid ssh cert encoding --------- Co-authored-by: jeanluc <2163936+lkubb@users.noreply.github.com> --- CHANGELOG.rst | 11 ++ docs/development/test-vectors.rst | 4 + .../hazmat/primitives/serialization/ssh.py | 28 ++++- tests/hazmat/primitives/test_ssh.py | 111 +++++++++++++----- ...p256-ed25519-non-singular-crit-opt-val.pub | 1 + .../p256-ed25519-non-singular-ext-val.pub | 1 + 6 files changed, 122 insertions(+), 34 deletions(-) create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-crit-opt-val.pub create mode 100644 vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub diff --git a/CHANGELOG.rst b/CHANGELOG.rst index eca152e92217..0f0450b19b72 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,17 @@ Changelog ========= +.. _v41-0-2: + +41.0.2 - 2023-07-10 +~~~~~~~~~~~~~~~~~~~ + +* Fixed bugs in creating and parsing SSH certificates where critical options + with values were handled incorrectly. Certificates are now created correctly + and parsing accepts correct values as well as the previously generated + invalid forms with a warning. In the next release, support for parsing these + invalid forms will be removed. + .. _v41-0-1: 41.0.1 - 2023-06-01 diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 3e54c40ae43d..cfab7edcca69 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -866,6 +866,10 @@ Custom OpenSSH Certificate Test Vectors critical option. * ``p256-p256-non-lexical-crit-opts.pub`` - A certificate with critical options in non-lexical order. +* ``p256-ed25519-non-singular-crit-opt-val.pub`` - A certificate with + a critical option that contains more than one value. +* ``p256-ed25519-non-singular-ext-val.pub`` - A certificate with + an extension that contains more than one value. * ``dsa-p256.pub`` - A certificate with a DSA public key signed by a P256 CA. * ``p256-dsa.pub`` - A certificate with a P256 public key signed by a DSA diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 7725c83543e8..35e53c102875 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -1063,6 +1063,20 @@ def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: if last_name is not None and bname < last_name: raise ValueError("Fields not lexically sorted") value, exts_opts = _get_sshstr(exts_opts) + if len(value) > 0: + try: + value, extra = _get_sshstr(value) + except ValueError: + warnings.warn( + "This certificate has an incorrect encoding for critical " + "options or extensions. This will be an exception in " + "cryptography 42", + utils.DeprecatedIn41, + stacklevel=4, + ) + else: + if len(extra) > 0: + raise ValueError("Unexpected extra data after value") result[bname] = bytes(value) last_name = bname return result @@ -1450,12 +1464,22 @@ def sign(self, private_key: SSHCertPrivateKeyTypes) -> SSHCertificate: fcrit = _FragList() for name, value in self._critical_options: fcrit.put_sshstr(name) - fcrit.put_sshstr(value) + if len(value) > 0: + foptval = _FragList() + foptval.put_sshstr(value) + fcrit.put_sshstr(foptval.tobytes()) + else: + fcrit.put_sshstr(value) f.put_sshstr(fcrit.tobytes()) fext = _FragList() for name, value in self._extensions: fext.put_sshstr(name) - fext.put_sshstr(value) + if len(value) > 0: + fextval = _FragList() + fextval.put_sshstr(value) + fext.put_sshstr(fextval.tobytes()) + else: + fext.put_sshstr(value) f.put_sshstr(fext.tobytes()) f.put_sshstr(b"") # RESERVED FIELD # encode CA public key diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index e5c58062d075..fcd0928a87de 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -1115,26 +1115,28 @@ def test_loads_ssh_cert(self, backend): # secp256r1 public key, ed25519 signing key cert = load_ssh_public_identity( b"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbm" - b"lzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgtdU+dl9vD4xPi8afxERYo" - b"s0c0d9/3m7XGY6fGeSkqn0AAAAIbmlzdHAyNTYAAABBBAsuVFNNj/mMyFm2xB99" - b"G4xiaUJE1lZNjcp+S2tXYW5KorcHpusSlSqOkUPZ2l0644dgiNPDKR/R+BtYENC" - b"8aq8AAAAAAAAAAAAAAAEAAAAUdGVzdEBjcnlwdG9ncmFwaHkuaW8AAAAaAAAACm" - b"NyeXB0b3VzZXIAAAAIdGVzdHVzZXIAAAAAY7KyZAAAAAB2frXAAAAAAAAAAIIAA" - b"AAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9y" - b"d2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGV" - b"ybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3" - b"NoLWVkMjU1MTkAAAAg3P0eyGf2crKGwSlnChbLzTVOFKwQELE1Ve+EZ6rXF18AA" - b"ABTAAAAC3NzaC1lZDI1NTE5AAAAQKoij8BsPj/XLb45+wHmRWKNqXeZYXyDIj8J" - b"IE6dIymjEqq0TP6ntu5t59hTmWlDO85GnMXAVGBjFbeikBMfAQc= reaperhulk" - b"@despoina.local" + b"lzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLfsFv9Gbc6LZSiJFWdYQl" + b"IMNI50GExXW0fBpgGVf+Y4AAAAIbmlzdHAyNTYAAABBBIzVyRgVLR4F38bIOLBN" + b"8CNm8Nf+eBHCVkKDKb9WDyLLD61CEmzjK/ORwFuSE4N60eIGbFidBf0D0xh7G6o" + b"TNxsAAAAAAAAAAAAAAAEAAAAUdGVzdEBjcnlwdG9ncmFwaHkuaW8AAAAaAAAACm" + b"NyeXB0b3VzZXIAAAAIdGVzdHVzZXIAAAAAY7KyZAAAAAB2frXAAAAAWAAAAA1mb" + b"3JjZS1jb21tYW5kAAAALAAAAChlY2hvIGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh" + b"YWFhYWFhYWFhYWFhAAAAD3ZlcmlmeS1yZXF1aXJlZAAAAAAAAACCAAAAFXBlcm1" + b"pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbm" + b"cAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wd" + b"HkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1" + b"NTE5AAAAICH6csEOmGbOfT2B/S/FJg3uyPsaPSZUZk2SVYlfs0KLAAAAUwAAAAt" + b"zc2gtZWQyNTUxOQAAAEDz2u7X5/TFbN7Ms7DP4yArhz1oWWYKkdAk7FGFkHfjtY" + b"/YfNQ8Oky3dCZRi7PnSzScEEjos7723dhF8/y99WwH reaperhulk@despoina." + b"local" ) assert isinstance(cert, SSHCertificate) cert.verify_cert_signature() signature_key = cert.signature_key() assert isinstance(signature_key, ed25519.Ed25519PublicKey) assert cert.nonce == ( - b"\xb5\xd5>v_o\x0f\x8cO\x8b\xc6\x9f\xc4DX\xa2\xcd\x1c\xd1\xdf" - b"\x7f\xden\xd7\x19\x8e\x9f\x19\xe4\xa4\xaa}" + b'-\xfb\x05\xbf\xd1\x9bs\xa2\xd9J"EY\xd6\x10\x94\x83\r#\x9d' + b"\x06\x13\x15\xd6\xd1\xf0i\x80e_\xf9\x8e" ) public_key = cert.public_key() assert isinstance(public_key, ec.EllipticCurvePublicKey) @@ -1145,7 +1147,10 @@ def test_loads_ssh_cert(self, backend): assert cert.valid_principals == [b"cryptouser", b"testuser"] assert cert.valid_before == 1988015552 assert cert.valid_after == 1672655460 - assert cert.critical_options == {} + assert cert.critical_options == { + b"force-command": b"echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"verify-required": b"", + } assert cert.extensions == { b"permit-X11-forwarding": b"", b"permit-agent-forwarding": b"", @@ -1154,6 +1159,31 @@ def test_loads_ssh_cert(self, backend): b"permit-user-rc": b"", } + def test_loads_deprecated_invalid_encoding_cert(self, backend): + with pytest.warns(utils.DeprecatedIn41): + cert = load_ssh_public_identity( + b"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYT" + b"ItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgXE7sJ+xDVVNCO" + b"cEvpZS+SXIbc0nJdny/KqVbnwHslMIAAAAIbmlzdHAyNTYAAABBBI/qcLq8" + b"iiErpAhOWRqdMkpFSCNv7TVUcXCIfAl01JXbe2MvS4V7lFtiyrBjLSV7Iyw" + b"3TrulrWLibjPzZvLwmQcAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA//" + b"////////8AAABUAAAADWZvcmNlLWNvbW1hbmQAAAAoZWNobyBhYWFhYWFhY" + b"WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQAAAA92ZXJpZnktcmVxdWly" + b"ZWQAAAAAAAAAEgAAAApwZXJtaXQtcHR5AAAAAAAAAAAAAABoAAAAE2VjZHN" + b"hLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI/qcLq8iiErpAhOWR" + b"qdMkpFSCNv7TVUcXCIfAl01JXbe2MvS4V7lFtiyrBjLSV7Iyw3TrulrWLib" + b"jPzZvLwmQcAAABlAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABKAAAAIQCi" + b"eCsIhGKrZdkE1+zY5EBucrLzxFpwnm/onIT/6rapvQAAACEAuVQ1yQjlPKr" + b"kfsGfjeG+2umZrOS5Ycx85BQhYf0RgsA=" + ) + assert isinstance(cert, SSHCertificate) + cert.verify_cert_signature() + assert cert.extensions == {b"permit-pty": b""} + assert cert.critical_options == { + b"force-command": b"echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"verify-required": b"", + } + @pytest.mark.parametrize( "filename", [ @@ -1267,6 +1297,8 @@ def test_invalid_cert_type(self): "p256-p256-non-lexical-extensions.pub", "p256-p256-duplicate-crit-opts.pub", "p256-p256-non-lexical-crit-opts.pub", + "p256-ed25519-non-singular-crit-opt-val.pub", + "p256-ed25519-non-singular-ext-val.pub", ], ) def test_invalid_encodings(self, filename): @@ -1693,6 +1725,11 @@ def test_sign_and_byte_compare_rsa(self, monkeypatch): .valid_after(1672531200) .valid_before(1672617600) .type(SSHCertificateType.USER) + .add_extension(b"permit-pty", b"") + .add_critical_option( + b"force-command", b"echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ) + .add_critical_option(b"verify-required", b"") ) cert = builder.sign(private_key) sig_key = cert.signature_key() @@ -1707,19 +1744,21 @@ def test_sign_and_byte_compare_rsa(self, monkeypatch): b"4kyHpbLEIVloBjzetoqXK6u8Hjz/APuagONypNDCySDR6M7jM85HDcLoFFrbBb8" b"pruHSTxQejMeEmJxYf8b7rNl58/IWPB1ymbNlvHL/4oSOlnrtHkjcxRWzpQ7U3g" b"T9BThGyhCiI7EMyEHMgP3r7kTzEUwT6IavWDAAAAAAAAAAAAAAABAAAAAAAAAAA" - b"AAAAAY7DNAAAAAABjsh6AAAAAAAAAAAAAAAAAAAABFwAAAAdzc2gtcnNhAAAAAw" - b"EAAQAAAQEAwXr8fndHTKpaqDA2FYo/+/e1IWhRuiIw5dar/MHGz+9Z6SPqEzC8W" - b"TtzgCq2CKbkozBlI6MRa6WqOWYUUXThO2xJ6beAYuRJ1y77EP1J6R+gi5bQUeeC" - b"6fWrxbWm95hIJ6245z2gDyKy79zbduq0btrZjtZWYnQ/3GwOM2pdDNuqfcKeU2N" - b"eJMh6WyxCFZaAY83raKlyurvB48/wD7moDjcqTQwskg0ejO4zPORw3C6BRa2wW/" - b"Ka7h0k8UHozHhJicWH/G+6zZefPyFjwdcpmzZbxy/+KEjpZ67R5I3MUVs6UO1N4" - b"E/QU4RsoQoiOxDMhBzID96+5E8xFME+iGr1gwAAARQAAAAMcnNhLXNoYTItNTEy" - b"AAABAKCRnfhn6MZs3jRgIDICUpUyWrDCbpStEbdzhmoxF8w2m8klR7owRH/rxOf" - b"nWhKMGnXnoERS+az3Zh9ckiQPujkuEToORKpzu6CEWlzHSzyK1o2X548KkW76HJ" - b"gqzwMas94HY7UOJUgKSFUI0S3jAgqXAKSa1DxvJBu5/n57aUqPq+BmAtoI8uNBo" - b"x4F1pNEop38+oD7rUt8bZ8K0VcrubJZz806K8UNiK0mOahaEIkvZXBfzPGvSNRj" - b"0OjDl1dLUZaP8C1o5lVRomEm7pLcgE9i+ZDq5iz+mvQrSBStlpQ5hPGuUOrZ/oY" - b"ZLZ1G30R5tWj212MHoNZjxFxM8+f2OT4=" + b"AAAAAY7DNAAAAAABjsh6AAAAAWAAAAA1mb3JjZS1jb21tYW5kAAAALAAAAChlY2" + b"hvIGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhAAAAD3Zlcmlme" + b"S1yZXF1aXJlZAAAAAAAAAASAAAACnBlcm1pdC1wdHkAAAAAAAAAAAAAARcAAAAH" + b"c3NoLXJzYQAAAAMBAAEAAAEBAMF6/H53R0yqWqgwNhWKP/v3tSFoUboiMOXWq/z" + b"Bxs/vWekj6hMwvFk7c4Aqtgim5KMwZSOjEWulqjlmFFF04TtsSem3gGLkSdcu+x" + b"D9SekfoIuW0FHngun1q8W1pveYSCetuOc9oA8isu/c23bqtG7a2Y7WVmJ0P9xsD" + b"jNqXQzbqn3CnlNjXiTIelssQhWWgGPN62ipcrq7wePP8A+5qA43Kk0MLJINHozu" + b"MzzkcNwugUWtsFvymu4dJPFB6Mx4SYnFh/xvus2Xnz8hY8HXKZs2W8cv/ihI6We" + b"u0eSNzFFbOlDtTeBP0FOEbKEKIjsQzIQcyA/evuRPMRTBPohq9YMAAAEUAAAADH" + b"JzYS1zaGEyLTUxMgAAAQCYbbNzhflDqZAxyBpdLIX0nLAdnTeFNBudMqgo3KGND" + b"WlU9N17hqBEmcvIOrtNi+JKuKZW89zZrbORHvdjv6NjGSKzJD/XA25YrX1KgMEO" + b"wt5pzMZX+100drwrjQo+vZqeIN3FJNmT3wssge73v+JsxQrdIAz7YM2OZrFr5HM" + b"qZEZ5tMvAf/s5YEMDttEU4zMtmjubQyDM5KyYnZdoDT4sKi2rB8gfaigc4IdI/K" + b"8oXL/3Y7rHuOtejl3lUK4v6DxeRl4aqGYWmhUJc++Rh0cbDgC2S6Cq7gAfG2tND" + b"zbwL217Q93R08bJn1hDWuiTiaHGauSy2gPUI+cnkvlEocHM" ) @pytest.mark.supported( @@ -1745,6 +1784,11 @@ def test_sign_and_byte_compare_ed25519(self, monkeypatch, backend): .valid_after(1672531200) .valid_before(1672617600) .type(SSHCertificateType.USER) + .add_extension(b"permit-pty", b"") + .add_critical_option( + b"force-command", b"echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ) + .add_critical_option(b"verify-required", b"") ) cert = builder.sign(private_key) sig_key = cert.signature_key() @@ -1754,8 +1798,11 @@ def test_sign_and_byte_compare_ed25519(self, monkeypatch, backend): b"ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdj" b"AxQG9wZW5zc2guY29tAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" b"AAAAAAAINdamAGCsQq31Uv+08lkBzoO4XLz2qYjJa8CGmj3B1EaAAAAAAAAAAAA" - b"AAABAAAAAAAAAAAAAAAAY7DNAAAAAABjsh6AAAAAAAAAAAAAAAAAAAAAMwAAAAt" - b"zc2gtZWQyNTUxOQAAACDXWpgBgrEKt9VL/tPJZAc6DuFy89qmIyWvAhpo9wdRGg" - b"AAAFMAAAALc3NoLWVkMjU1MTkAAABAAlF6Lxabxs+8fkOr7KjKYei9konIG13cQ" - b"gJ2tWf3yFcg3OuV5s/AkRmKdwHlQfTUrhRdOmDnGxeLEB0mvkVFCw==" + b"AAABAAAAAAAAAAAAAAAAY7DNAAAAAABjsh6AAAAAWAAAAA1mb3JjZS1jb21tYW5" + b"kAAAALAAAAChlY2hvIGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW" + b"FhAAAAD3ZlcmlmeS1yZXF1aXJlZAAAAAAAAAASAAAACnBlcm1pdC1wdHkAAAAAA" + b"AAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAg11qYAYKxCrfVS/7TyWQHOg7hcvPa" + b"piMlrwIaaPcHURoAAABTAAAAC3NzaC1lZDI1NTE5AAAAQL2aUjeD60C2FrbgHcN" + b"t8yRa8IRbxvOyA9TZYDGG1dRE3DiR0fuudU20v6vqfTd1gx0S5QyEdECXLl9ZI3" + b"AwZgc=" ) diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-crit-opt-val.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-crit-opt-val.pub new file mode 100644 index 000000000000..5510bd5f0f35 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-crit-opt-val.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIbmlzdHAyNTYAAABBBCZWRs4GYIHGJpyXuqvfFGWN49dnJRkZJLDkFrHf6mNHhIMI3vtrLfCZwxPSfnCYWK6YofssZ1FYA6TkVJq8Xi8AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAABjsM0AAAAAAGOyHoAAAABtAAAADWZvcmNlLWNvbW1hbmQAAABBAAAAKGVjaG8gYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEAAAARaW52YWxpZF9taXNjX2RhdGEAAAAPdmVyaWZ5LXJlcXVpcmVkAAAAAAAAABIAAAAKcGVybWl0LXB0eQAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACDdZgztgAFFC7T5PifrUy/kMu0Pnwq1au3vStKHe7FFMAAAAFMAAAALc3NoLWVkMjU1MTkAAABAt/0pBSDBFy1crBPHOBoKFoxRjKd1tKVdOrD3QVgbBfpaHfxi4vrgYe6JfQ54+vu5P+8yrMyACekT8H6hhvxHDw== \ No newline at end of file diff --git a/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub new file mode 100644 index 000000000000..c44b49fceccd --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIbmlzdHAyNTYAAABBBCZWRs4GYIHGJpyXuqvfFGWN49dnJRkZJLDkFrHf6mNHhIMI3vtrLfCZwxPSfnCYWK6YofssZ1FYA6TkVJq8Xi8AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAABjsM0AAAAAAGOyHoAAAAAXAAAAD3ZlcmlmeS1yZXF1aXJlZAAAAAAAAAAvAAAAFGNvbnRhaW5zLWV4dHJhLXZhbHVlAAAAEwAAAAVoZWxsbwAAAAYgd29ybGQAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACDdZgztgAFFC7T5PifrUy/kMu0Pnwq1au3vStKHe7FFMAAAAFMAAAALc3NoLWVkMjU1MTkAAABAY80oIEvooz/k3x9a+yVkjSNRfi4y/q87wVYiT7keTpP4n9JV/Vlc0u7O2QYOHfb4DUkcrvbsksKVsiqoQu5qDg== \ No newline at end of file From 7431db737cf0407560fac689d24f1d2e5efc349d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Jul 2023 20:28:04 -0500 Subject: [PATCH 827/827] bump for 41.0.2 (#9215) --- pyproject.toml | 2 +- src/cryptography/__about__.py | 2 +- vectors/cryptography_vectors/__about__.py | 2 +- vectors/pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b2e511f54caa..001f60598661 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography" -version = "41.0.1" +version = "41.0.2" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ] diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index a77b057ba076..73b3b56ccd63 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -10,7 +10,7 @@ "__copyright__", ] -__version__ = "41.0.1" +__version__ = "41.0.2" __author__ = "The Python Cryptographic Authority and individual contributors" diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py index 51dd6514b3a8..297da704e265 100644 --- a/vectors/cryptography_vectors/__about__.py +++ b/vectors/cryptography_vectors/__about__.py @@ -6,4 +6,4 @@ "__version__", ] -__version__ = "41.0.1" +__version__ = "41.0.2" diff --git a/vectors/pyproject.toml b/vectors/pyproject.toml index e2a75f9c4db9..f468d33dbfa4 100644 --- a/vectors/pyproject.toml +++ b/vectors/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptography_vectors" -version = "41.0.1" +version = "41.0.2" authors = [ {name = "The Python Cryptographic Authority and individual contributors", email = "cryptography-dev@python.org"} ]