Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev v5.2.0 #116

Merged
merged 7 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
os: [ubuntu-22.04, macos-12, windows-2022]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Install Windows 8.1 SDK
shell: powershell
Expand All @@ -31,16 +31,16 @@ jobs:
Start-Process -Wait vs_enterprise.exe -ArgumentList 'modify', '--installPath "C:\Program Files\Microsoft Visual Studio\2022\Enterprise"', '--add', 'Microsoft.VisualStudio.Component.VC.140', '--quiet', '--norestart', '--wait'
if: runner.os == 'Windows'

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
name: Install Python

- name: Install cibuildwheel
run: python -m pip install "cibuildwheel<2.13"
run: python -m pip install "cibuildwheel>=2.16,<2.17"

- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: "cp37-* cp38-* cp39-* cp310-* cp311-*"
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*"
CIBW_SKIP: "*-win32 pp* *-musllinux_i686" # Skip win32, PyPy and muslinux32 builds
# Build wheels for Apple x86_64 only; we use another workflow for Apple arm64
CIBW_ARCHS_MACOS: "x86_64"
Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.11
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade pip setuptools wheel
pip install -r requirements-dev.txt

- name: Build C extension
run: invoke build.all

- name: Lint and test
run: invoke test
- name: Lint
run: invoke lint

- name: Test
run: invoke test
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
.venv
.venv311
bin
.cache
requirements.txt
deps
.pytest_cache

.vscode
.ruff_cache/
.mypy_cache/

# OpenSSL build artifacts
Expand Down
3 changes: 0 additions & 3 deletions MANIFEST.in

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ nassl
[![PyPI wheel](https://img.shields.io/pypi/wheel/nassl.svg)](https://pypi.org/project/nassl/)
[![PyPI version](https://img.shields.io/pypi/pyversions/nassl.svg)](https://pypi.org/project/nassl/)

Experimental OpenSSL wrapper for Python 3.7+ and [SSLyze](https://github.com/nabla-c0d3/sslyze).
Experimental OpenSSL wrapper for Python 3.8+ and [SSLyze](https://github.com/nabla-c0d3/sslyze).

**Do NOT use for anything serious**. This code has not been properly tested/reviewed and is not production ready.

Expand Down
85 changes: 56 additions & 29 deletions build_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@
from typing import Optional, Any, List
from urllib.request import urlopen

# Monkeypatch for Python 3.11
# TODO: Remove after this is fixed: https://github.com/pyinvoke/invoke/issues/833
import inspect

if not hasattr(inspect, "getargspec"):
inspect.getargspec = inspect.getfullargspec

try:
from invoke import task, Context
except ImportError:
Expand Down Expand Up @@ -206,9 +199,16 @@ def build(
_OPENSSL_CONF_CMD: str = None

def _run_configure_command(
self, ctx: Context, openssl_target: str, zlib_lib_path: Path, zlib_include_path: Path
self,
ctx: Context,
openssl_target: str,
zlib_lib_path: Path,
zlib_include_path: Path,
) -> None:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
extra_args = "-no-asm -DZLIB_WINAPI" # *hate* zlib
# On Windows OpenSSL wants the full path to the lib file
final_zlib_path = zlib_lib_path
Expand All @@ -227,15 +227,16 @@ def _run_configure_command(
)

def _run_build_steps(self, ctx: Context) -> None:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
if self.platform == SupportedPlatformEnum.WINDOWS_32:
ctx.run("ms\\do_ms")
else:
ctx.run("ms\\do_win64a.bat")

ctx.run(
"nmake -f ms\\nt.mak clean", warn=True
) # Does not work if tmp32 does not exist (fresh build)
ctx.run("nmake -f ms\\nt.mak clean", warn=True) # Does not work if tmp32 does not exist (fresh build)
ctx.run("nmake -f ms\\nt.mak")

else:
Expand Down Expand Up @@ -268,28 +269,40 @@ def _get_build_target(self, should_build_for_debug: bool) -> str:

@property
def include_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "inc32"
else:
return self.src_path / "include"

@property
def libcrypto_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "out32" / "libeay32.lib"
else:
return self.src_path / "libcrypto.a"

@property
def libssl_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "out32" / "ssleay32.lib"
else:
return self.src_path / "libssl.a"

@property
def exe_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "out32" / "openssl.exe"
else:
return self.src_path / "apps" / "openssl"
Expand All @@ -307,22 +320,31 @@ def _openssl_git_tag(self) -> str:
)

def _run_build_steps(self, ctx: Context) -> None:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
ctx.run("nmake clean", warn=True)
ctx.run("nmake")
else:
return super()._run_build_steps(ctx)

@property
def libcrypto_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "libcrypto.lib"
else:
return self.src_path / "libcrypto.a"

@property
def libssl_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "libssl.lib"
else:
return self.src_path / "libssl.a"
Expand All @@ -333,7 +355,10 @@ def include_path(self) -> Path:

@property
def exe_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
return self.src_path / "apps" / "openssl.exe"
else:
return self.src_path / "apps" / "openssl"
Expand All @@ -349,7 +374,10 @@ def src_path(self) -> Path:
return _DEPS_PATH / "zlib-1.2.13"

def build(self, ctx: Context) -> None:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
if self.platform == SupportedPlatformEnum.WINDOWS_32:
build_platform = "Win32"
else:
Expand All @@ -363,9 +391,7 @@ def build(self, ctx: Context) -> None:

vs_contrib_path = self.src_path / "contrib" / "vstudio"
with ctx.cd(str(vs_contrib_path)):
ctx.run(
f'"{msbuild_path}" vc14\\zlibvc.sln /P:Configuration=Release /P:Platform={build_platform}'
)
ctx.run(f'"{msbuild_path}" vc14\\zlibvc.sln /P:Configuration=Release /P:Platform={build_platform}')

else:
# Linux/macOS build
Expand All @@ -376,11 +402,12 @@ def build(self, ctx: Context) -> None:

@property
def libz_path(self) -> Path:
if self.platform in [SupportedPlatformEnum.WINDOWS_32, SupportedPlatformEnum.WINDOWS_64]:
if self.platform in [
SupportedPlatformEnum.WINDOWS_32,
SupportedPlatformEnum.WINDOWS_64,
]:
arch = "x86" if self.platform == SupportedPlatformEnum.WINDOWS_32 else "x64"
zlib_lib_path = (
self.src_path / "contrib" / "vstudio" / "vc14" / arch / "ZlibStatRelease" / "zlibstat.lib"
)
zlib_lib_path = self.src_path / "contrib" / "vstudio" / "vc14" / arch / "ZlibStatRelease" / "zlibstat.lib"
else:
zlib_lib_path = self.src_path / "libz.a"
return zlib_lib_path
Expand Down
2 changes: 1 addition & 1 deletion nassl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__author__ = "Alban Diquet"
__version__ = "5.1.0"
__version__ = "5.2.0"
10 changes: 6 additions & 4 deletions nassl/ephemeral_key_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,11 @@ class EphemeralKeyInfo(ABC):

def __post_init__(self) -> None:
# Required because of frozen=True; https://docs.python.org/3/library/dataclasses.html#frozen-instances
object.__setattr__(self, "type_name", _OPENSSL_EVP_PKEY_TO_NAME_MAPPING.get(self.type, "UNKNOWN"))
object.__setattr__(
self,
"type_name",
_OPENSSL_EVP_PKEY_TO_NAME_MAPPING.get(self.type, "UNKNOWN"),
)


@dataclass(frozen=True)
Expand All @@ -156,9 +160,7 @@ class EcDhEphemeralKeyInfo(EphemeralKeyInfo):

def __post_init__(self) -> None:
super().__post_init__()
curve_name = _OPENSSL_NID_TO_SECG_ANSI_X9_62.get(
self.curve, f"unknown-curve-with-openssl-id-{self.curve}"
)
curve_name = _OPENSSL_NID_TO_SECG_ANSI_X9_62.get(self.curve, f"unknown-curve-with-openssl-id-{self.curve}")
# Required because of frozen=True; https://docs.python.org/3/library/dataclasses.html#frozen-instances
object.__setattr__(self, "curve_name", curve_name)

Expand Down
3 changes: 2 additions & 1 deletion nassl/ocsp_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def verify_ocsp_response(ocsp_response: _nassl.OCSP_RESPONSE, trust_store_path:
except _nassl.OpenSSLError as e:
if "certificate verify error" in str(e):
raise OcspResponseNotTrustedError(
"OCSP Response verification failed: the response is not trusted", trust_store_path
"OCSP Response verification failed: the response is not trusted",
trust_store_path,
)
raise
25 changes: 12 additions & 13 deletions nassl/ssl_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
from enum import IntEnum
from typing import List, Any

try:
from typing import Protocol
except ImportError:
# Will happen on Python 3.7
from typing_extensions import Protocol # type: ignore
from typing import Protocol


from typing import Optional
Expand Down Expand Up @@ -123,7 +119,9 @@ def __init__(
self._ssl.set_tlsext_host_name(server_name_indication)

def _init_base_objects(
self, ssl_version: OpenSslVersionEnum, underlying_socket: Optional[socket.socket]
self,
ssl_version: OpenSslVersionEnum,
underlying_socket: Optional[socket.socket],
) -> None:
"""Setup the socket and SSL_CTX objects."""
self._is_handshake_completed = False
Expand All @@ -133,9 +131,7 @@ def _init_base_objects(
# A Python socket handles transmission of the data
self._sock = underlying_socket

def _init_server_authentication(
self, ssl_verify: OpenSslVerifyEnum, ssl_verify_locations: Optional[Path]
) -> None:
def _init_server_authentication(self, ssl_verify: OpenSslVerifyEnum, ssl_verify_locations: Optional[Path]) -> None:
"""Setup the certificate validation logic for authenticating the server."""
self._ssl_ctx.set_verify(ssl_verify.value)
if ssl_verify_locations:
Expand All @@ -154,13 +150,16 @@ def _init_client_authentication(
) -> None:
"""Setup client authentication using the supplied certificate and key."""
if client_certificate_chain is not None and client_key is not None:
self._use_private_key(client_certificate_chain, client_key, client_key_type, client_key_password)
self._use_private_key(
client_certificate_chain,
client_key,
client_key_type,
client_key_password,
)

if ignore_client_authentication_requests:
if client_certificate_chain:
raise ValueError(
"Cannot enable both client_certchain_file and ignore_client_authentication_requests"
)
raise ValueError("Cannot enable both client_certchain_file and ignore_client_authentication_requests")

self._ssl_ctx.set_client_cert_cb_NULL()

Expand Down
29 changes: 7 additions & 22 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
[tool.black]
line-length = 110
target_version = ['py37']
include = '\.pyi?$'
exclude = '''
[tool.ruff]
line-length = 120

(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| \.venv311
| _build
| buck-out
| build
| dist
| deps # OpenSSL has some Python scripts that black rejects
)/
)
'''
[tool.mypy]
python_version = "3.8"
ignore_missing_imports = true
strict_optional = true
disallow_untyped_defs = true
Loading
Loading