Raise cryptography version and prepare the 24.3.0 release (#1381)

Also fixes tests under OpenSSL 3.4.0
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cede8be..6881550 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,6 +7,7 @@
   linux:
     runs-on: ${{ matrix.PYTHON.OS || 'ubuntu-22.04' }}
     strategy:
+      fail-fast: false
       matrix:
         PYTHON:
           # Base builds
@@ -66,6 +67,7 @@
     runs-on: ubuntu-latest
     container: ghcr.io/pyca/cryptography-runner-${{ matrix.TEST.CONTAINER }}
     strategy:
+      fail-fast: false
       matrix:
         TEST:
           # cryptographyMain used since there's no wheel
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 76d32c2..4901612 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,7 +4,7 @@
 Versions are year-based with a strict backward-compatibility policy.
 The third digit is only for regressions.
 
-24.3.0 (UNRELEASED)
+24.3.0 (2024-11-27)
 -------------------
 
 Backward-incompatible changes:
@@ -25,6 +25,7 @@
 Changes:
 ^^^^^^^^
 
+* ``cryptography`` maximum version has been increased to 44.0.x.
 * ``OpenSSL.SSL.Connection.get_certificate``, ``OpenSSL.SSL.Connection.get_peer_certificate``, ``OpenSSL.SSL.Connection.get_peer_cert_chain``, and ``OpenSSL.SSL.Connection.get_verified_chain`` now take an ``as_cryptography`` keyword-argument. When ``True`` is passed then ``cryptography.x509.Certificate`` are returned, instead of ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated.
 
 
diff --git a/pyproject.toml b/pyproject.toml
index e90fcd2..1a45df9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,6 +42,8 @@
 [tool.ruff]
 lint.select = ['E', 'F', 'I', 'W', 'UP', 'RUF']
 line-length = 79
+# Remove if/when we move setup.py python-requires metadata to pyproject.toml
+target-version = "py37"
 
 [tool.ruff.lint.isort]
 known-first-party = ["OpenSSL", "tests"]
diff --git a/setup.py b/setup.py
index 37c0fa2..fa54635 100644
--- a/setup.py
+++ b/setup.py
@@ -94,7 +94,7 @@
         packages=find_packages(where="src"),
         package_dir={"": "src"},
         install_requires=[
-            "cryptography>=41.0.5,<44",
+            "cryptography>=41.0.5,<45",
         ],
         extras_require={
             "test": ["pytest-rerunfailures", "pretend", "pytest>=3.0.1"],
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index a7da79f..eed27a0 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -4,11 +4,12 @@
 import socket
 import typing
 import warnings
+from collections.abc import Sequence
 from errno import errorcode
 from functools import partial, wraps
 from itertools import chain, count
 from sys import platform
-from typing import Any, Callable, List, Optional, Sequence, TypeVar
+from typing import Any, Callable, Optional, TypeVar
 from weakref import WeakValueDictionary
 
 from cryptography import x509
@@ -288,7 +289,7 @@
 _ALPNSelectCallback = Callable[
     [
         "Connection",
-        typing.Union[List[bytes], _NoOverlappingProtocols],
+        typing.Union[typing.List[bytes], _NoOverlappingProtocols],
     ],
     None,
 ]
@@ -766,7 +767,7 @@
         raise TypeError("argument must be an int, or have a fileno() method.")
     elif fd < 0:
         raise ValueError(
-            "file descriptor cannot be a negative integer (%i)" % (fd,)
+            f"file descriptor cannot be a negative integer ({fd:i})"
         )
 
     return fd
@@ -1952,18 +1953,16 @@
             # TODO: This is untested.
             raise WantX509LookupError()
         elif error == _lib.SSL_ERROR_SYSCALL:
-            if _lib.ERR_peek_error() == 0:
-                if result < 0:
-                    if platform == "win32":
-                        errno = _ffi.getwinerror()[0]
-                    else:
-                        errno = _ffi.errno
-
-                    if errno != 0:
-                        raise SysCallError(errno, errorcode.get(errno))
+            if platform == "win32":
+                errno = _ffi.getwinerror()[0]
+            else:
+                errno = _ffi.errno
+            if _lib.ERR_peek_error() == 0 or errno != 0:
+                if result < 0 and errno != 0:
+                    raise SysCallError(errno, errorcode.get(errno))
                 raise SysCallError(-1, "Unexpected EOF")
             else:
-                # TODO: This is untested.
+                # TODO: This is untested, but I think twisted hits it?
                 _raise_current_error()
         elif error == _lib.SSL_ERROR_SSL and _lib.ERR_peek_error() != 0:
             # In 3.0.x an unexpected EOF no longer triggers syscall error
diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py
index 7a102e6..046e40c 100644
--- a/src/OpenSSL/_util.py
+++ b/src/OpenSSL/_util.py
@@ -1,7 +1,9 @@
+from __future__ import annotations
+
 import os
 import sys
 import warnings
-from typing import Any, Callable, NoReturn, Type, Union
+from typing import Any, Callable, NoReturn, Union
 
 from cryptography.hazmat.bindings.openssl.binding import Binding
 
@@ -31,7 +33,7 @@
     return ffi.string(charp).decode("utf-8")
 
 
-def exception_from_error_queue(exception_type: Type[Exception]) -> NoReturn:
+def exception_from_error_queue(exception_type: type[Exception]) -> NoReturn:
     """
     Convert an OpenSSL library failure into a Python exception.
 
@@ -57,7 +59,7 @@
     raise exception_type(errors)
 
 
-def make_assert(error: Type[Exception]) -> Callable[[bool], Any]:
+def make_assert(error: type[Exception]) -> Callable[[bool], Any]:
     """
     Create an assert function that uses :func:`exception_from_error_queue` to
     raise an exception wrapped by *error*.
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index d3beb8e..448a19a 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -6,13 +6,12 @@
 import typing
 import warnings
 from base64 import b16encode
+from collections.abc import Iterable, Sequence
 from functools import partial
 from os import PathLike
 from typing import (
     Any,
     Callable,
-    Iterable,
-    Sequence,
     Union,
 )
 
diff --git a/src/OpenSSL/version.py b/src/OpenSSL/version.py
index 0cfb065..9c80234 100644
--- a/src/OpenSSL/version.py
+++ b/src/OpenSSL/version.py
@@ -17,7 +17,7 @@
     "__version__",
 ]
 
-__version__ = "24.2.1"
+__version__ = "24.3.0"
 
 __title__ = "pyOpenSSL"
 __uri__ = "https://pyopenssl.org/"
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index b009cd6..ba3fa33 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -3832,7 +3832,10 @@
         if platform == "win32":
             assert err.value.args == (10054, "WSAECONNRESET")
         else:
-            assert err.value.args == (-1, "Unexpected EOF")
+            assert err.value.args in [
+                (-1, "Unexpected EOF"),
+                (54, "ECONNRESET"),
+            ]
 
     def _check_client_ca_list(self, func):
         """