diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c342d4d..437ac20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: - "dependabot/**" pull_request: +env: + FORCE_COLOR: "1" + jobs: test: strategy: @@ -16,9 +19,11 @@ jobs: - macos-latest - windows-latest - ubuntu-latest + nox-session: [''] include: - python-version: pypy3.10 os: ubuntu-latest + nox-session: test-pypy3.10 name: ${{ fromJson('{"macos-latest":"macOS","windows-latest":"Windows","ubuntu-latest":"Ubuntu"}')[matrix.os] }} (${{ matrix.python-version }}) timeout-minutes: 20 runs-on: ${{ matrix.os }} @@ -31,8 +36,13 @@ jobs: python-version: '${{ matrix.python-version }}' allow-prereleases: true - name: Run tests - run: ./ci.sh + run: | + python -m pip install --upgrade nox + nox -s ${NOX_SESSION:-test-$PYTHON_VERSION} shell: bash + env: + PYTHON_VERSION: ${{ matrix.python-version }} + NOX_SESSION: ${{ matrix.nox-session }} - name: "Upload coverage data" uses: "actions/upload-artifact@v4" with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dd4872f..d66ee3d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,6 +6,9 @@ on: - "dependabot/**" pull_request: +env: + FORCE_COLOR: "1" + jobs: Lint: name: 'Lint' @@ -19,4 +22,6 @@ jobs: with: python-version: '3.x' - name: Run lint - run: ./lint.sh + run: | + python -m pip install --upgrade nox + nox -s lint diff --git a/ci.sh b/ci.sh deleted file mode 100755 index f167c8d..0000000 --- a/ci.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -exu -o pipefail - -python -c "import sys, struct, ssl; print('#' * 70); print('python:', sys.version); print('version_info:', sys.version_info); print('bits:', struct.calcsize('P') * 8); print('openssl:', ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO); print('#' * 70)" - -python -m pip install -U pip build -python -m pip --version - -python -m build --sdist -python -m pip install dist/*.tar.gz - -# Actual tests - -python -m pip install -Ur test-requirements.txt -if [ -n "${OLD_CRYPTOGRAPHY:-}" ]; then - python -m pip install cryptography=="${OLD_CRYPTOGRAPHY}" -fi - -coverage run --parallel-mode -m pytest -W error -ra -s tests diff --git a/docs-requirements.txt b/docs-requirements.txt index 401b44d..7a2aed2 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -12,13 +12,13 @@ certifi==2024.8.30 # via requests cffi==1.17.1 # via cryptography -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via requests -cryptography==42.0.4 +cryptography==43.0.3 # via -r docs-requirements.in docutils==0.21.2 # via sphinx -idna==3.4 +idna==3.10 # via # -r docs-requirements.in # requests @@ -26,9 +26,9 @@ imagesize==1.4.1 # via sphinx jinja2==3.1.2 # via sphinx -markupsafe==2.1.1 +markupsafe==3.0.2 # via jinja2 -packaging==24.1 +packaging==24.2 # via sphinx pycparser==2.22 # via cffi @@ -38,7 +38,7 @@ requests==2.32.3 # via sphinx snowballstemmer==2.2.0 # via sphinx -sphinx==8.0.2 +sphinx==8.1.3 # via sphinxcontrib-trio sphinxcontrib-applehelp==2.0.0 # via sphinx diff --git a/docs/source/index.rst b/docs/source/index.rst index 6c5cd9a..0be2520 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -122,13 +122,22 @@ Change history .. towncrier release notes start +Trustme 1.2.1 (2025-01-02) +-------------------------- + +Bugfixes +~~~~~~~~ + +- Update from deprecated pyOpenSSL APIs to non-deprecated cryptography APIs. (`#670 `__) + + Trustme 1.2.0 (2024-10-07) -------------------------- Features ~~~~~~~~ -- Add support for PyPy 3.10, Python 3.12 and Python 3.13. (`#609 `__, `#664 `__) +- Add support for Python 3.13. (`#664 `__) - Allow setting of cert's notBefore attribute (`#628 `__) @@ -141,7 +150,7 @@ Bugfixes Deprecations and Removals ~~~~~~~~~~~~~~~~~~~~~~~~~ -- Remove support for Python 3.7, Python 3.8 and PyPy 3.9. (`#609 `__, `#664 `__) +- Remove support for Python 3.8 and PyPy 3.9. (`#664 `__) Trustme 1.1.0 (2023-07-10) diff --git a/lint-requirements.in b/lint-requirements.in index 9a38e30..0a153f1 100644 --- a/lint-requirements.in +++ b/lint-requirements.in @@ -5,3 +5,4 @@ pytest>=6.2 idna>=3.2 black isort +nox diff --git a/lint-requirements.txt b/lint-requirements.txt index 440738c..4ebe6b5 100644 --- a/lint-requirements.txt +++ b/lint-requirements.txt @@ -1,50 +1,66 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile lint-requirements.in -# -black==24.8.0 +# This file was autogenerated by uv via the following command: +# uv pip compile --universal lint-requirements.in +argcomplete==3.5.1 + # via nox +black==24.10.0 # via -r lint-requirements.in -cffi==1.17.1 +cffi==1.17.1 ; platform_python_implementation != 'PyPy' # via cryptography click==8.1.7 # via black -cryptography==42.0.4 +colorama==0.4.6 ; sys_platform == 'win32' or platform_system == 'Windows' + # via + # click + # colorlog + # pytest +colorlog==6.9.0 + # via nox +cryptography==44.0.0 # via # -r lint-requirements.in # types-pyopenssl -idna==3.6 +distlib==0.3.9 + # via virtualenv +filelock==3.16.1 + # via virtualenv +idna==3.10 # via -r lint-requirements.in iniconfig==2.0.0 # via pytest isort==5.13.2 # via -r lint-requirements.in -mypy==1.11.2 +mypy==1.13.0 # via -r lint-requirements.in mypy-extensions==1.0.0 # via # black # mypy -packaging==24.1 +nox==2024.10.9 + # via -r lint-requirements.in +packaging==24.2 # via # black + # nox # pytest pathspec==0.12.1 # via black platformdirs==4.3.6 - # via black + # via + # black + # virtualenv pluggy==1.5.0 # via pytest -pycparser==2.22 +pycparser==2.22 ; platform_python_implementation != 'PyPy' # via cffi -pytest==8.3.3 +pytest==8.3.4 # via -r lint-requirements.in types-cffi==1.16.0.20240331 # via types-pyopenssl types-pyopenssl==24.1.0.20240722 # via -r lint-requirements.in -types-setuptools==75.1.0.20240917 +types-setuptools==75.6.0.20241126 # via types-cffi typing-extensions==4.12.2 # via mypy +virtualenv==20.28.0 + # via nox diff --git a/lint.sh b/lint.sh deleted file mode 100755 index 90162c8..0000000 --- a/lint.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -exu -o pipefail - -python -c "import sys, struct, ssl; print('#' * 70); print('python:', sys.version); print('version_info:', sys.version_info); print('bits:', struct.calcsize('P') * 8); print('openssl:', ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO); print('#' * 70)" - -python -m pip install -U pip -python -m pip --version - -# Dependencies - -python -m pip install -Ur lint-requirements.txt - -# Linting -black --check src/trustme tests -isort --profile black src/trustme tests -mypy src/trustme tests diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 0000000..6ad0230 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,32 @@ +import os + +import nox + + +@nox.session() +def lint(session: nox.Session) -> None: + session.install("-r", "lint-requirements.txt") + LINT_PATHS = ("src/trustme", "tests", "noxfile.py") + session.run("black", *LINT_PATHS) + session.run("isort", "--profile", "black", *LINT_PATHS) + session.run("mypy", *LINT_PATHS) + + +@nox.session(python=["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.10"]) +def test(session: nox.Session) -> None: + session.install(".", "-r", "test-requirements.txt") + session.run( + "coverage", + "run", + "--parallel-mode", + "-m", + "pytest", + "-W", + "error", + "-ra", + "-s", + *(session.posargs or ("tests/",)), + ) + if os.environ.get("CI") != "true": + session.run("coverage", "combine") + session.run("coverage", "report", "-m") diff --git a/src/trustme/__init__.py b/src/trustme/__init__.py index ff87ab7..1040892 100644 --- a/src/trustme/__init__.py +++ b/src/trustme/__init__.py @@ -545,15 +545,13 @@ def configure_cert(self, ctx: Union[ssl.SSLContext, OpenSSL.SSL.Context]) -> Non with self.private_key_and_cert_chain_pem.tempfile() as path: ctx.load_cert_chain(path) elif _smells_like_pyopenssl(ctx): - from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey - - key = load_privatekey(FILETYPE_PEM, self.private_key_pem.bytes()) - ctx.use_privatekey(key) - cert = load_certificate(FILETYPE_PEM, self.cert_chain_pems[0].bytes()) - ctx.use_certificate(cert) + key = load_pem_private_key(self.private_key_pem.bytes(), None) + ctx.use_privatekey(key) # type: ignore[arg-type] + cert = x509.load_pem_x509_certificate(self.cert_chain_pems[0].bytes()) + ctx.use_certificate(cert) # type: ignore[arg-type] for pem in self.cert_chain_pems[1:]: - cert = load_certificate(FILETYPE_PEM, pem.bytes()) - ctx.add_extra_chain_cert(cert) + cert = x509.load_pem_x509_certificate(pem.bytes()) + ctx.add_extra_chain_cert(cert) # type: ignore[arg-type] else: raise TypeError( "unrecognized context type {!r}".format(ctx.__class__.__name__) diff --git a/src/trustme/_version.py b/src/trustme/_version.py index c68196d..a955fda 100644 --- a/src/trustme/_version.py +++ b/src/trustme/_version.py @@ -1 +1 @@ -__version__ = "1.2.0" +__version__ = "1.2.1" diff --git a/test-requirements.txt b/test-requirements.txt index 32c6620..5555fa4 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -8,18 +8,18 @@ attrs==24.2.0 # via service-identity cffi==1.17.1 # via cryptography -coverage[toml]==7.6.1 +coverage[toml]==7.6.8 # via -r test-requirements.in -cryptography==42.0.4 +cryptography==43.0.3 # via # -r test-requirements.in # pyopenssl # service-identity -idna==3.4 +idna==3.10 # via -r test-requirements.in iniconfig==2.0.0 # via pytest -packaging==24.1 +packaging==24.2 # via pytest pluggy==1.5.0 # via pytest @@ -31,9 +31,9 @@ pyasn1-modules==0.4.1 # via service-identity pycparser==2.22 # via cffi -pyopenssl==24.2.1 +pyopenssl==24.3.0 # via -r test-requirements.in pytest==8.3.3 # via -r test-requirements.in -service-identity==24.1.0 +service-identity==24.2.0 # via -r test-requirements.in