nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: pyca/pyopenssl
Pull request #1166 (2022-12-15 23:26:04)

Add support for X509_V_FLAG_PARTIAL_CHAIN
Add support for the X509_V_FLAG_PARTIAL_CHAIN constant. This is similar to the following cPython changes made to support partial certificate chain verification:

https://bugs.python.org/issue40849
https://github.com/python/cpython/pull/20463/files

While the cPython changes are in 3.10+, this would allow users with older python libraries to take advantage of this flag.

alex: thanks for the PR.

test failures look to be related to tox4 -- https://github.com/pyca/pyopenssl/pull/1167 should fix those.
alex: ok, if you can rebase/merge main we can test/review/merge

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e09f648..04b24a0 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,6 +16,9 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
+- Add ``OpenSSL.SSL.X509StoreFlags.PARTIAL_CHAIN`` constant to allow for users
+  to perform certificate verification on partial certificate chains.
+  `#1166 <https://github.com/pyca/pyopenssl/pull/1166>`_
 
 22.1.0 (2022-09-25)
 -------------------
diff --git a/doc/api/crypto.rst b/doc/api/crypto.rst
index cdaa736..ead4ad0 100644
--- a/doc/api/crypto.rst
+++ b/doc/api/crypto.rst
@@ -149,6 +149,7 @@ X509StoreFlags constants
     .. data:: INHIBIT_MAP
     .. data:: NOTIFY_POLICY
     .. data:: CHECK_SS_SIGNATURE
+    .. data:: PARTIAL_CHAIN
 
 .. _openssl-x509storeflags:
 
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index 18b4590..4d7d03a 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -1611,6 +1611,7 @@ class X509StoreFlags:
     INHIBIT_MAP: int = _lib.X509_V_FLAG_INHIBIT_MAP
     NOTIFY_POLICY: int = _lib.X509_V_FLAG_NOTIFY_POLICY
     CHECK_SS_SIGNATURE: int = _lib.X509_V_FLAG_CHECK_SS_SIGNATURE
+    PARTIAL_CHAIN: int = _lib.X509_V_FLAG_PARTIAL_CHAIN
 
 
 class X509Store:


Test patch:
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index e7b13fc..88756f0 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -4285,6 +4285,19 @@ class TestX509StoreContext:
 
         assert str(exc.value) == "unable to get local issuer certificate"
 
+    def test_verify_with_partial_chain(self):
+        store = X509Store()
+        store.add_cert(self.intermediate_cert)
+
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+        with pytest.raises(X509StoreContextError):
+            store_ctx.verify_certificate()
+
+        # Now set the partial verification flag for verification.
+        store.set_flags(X509StoreFlags.PARTIAL_CHAIN)
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+        assert store_ctx.verify_certificate() is None
+
 
 class TestSignVerify:
     """
Repository: pyca/pyopenssl
Pull request #1205 (2023-03-28 03:37:52)

port changelog


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8de589f..f219137 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,6 +16,21 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
+23.1.1 (2023-03-28)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Deprecations:
+^^^^^^^^^^^^^
+
+Changes:
+^^^^^^^^
+
+- Worked around an issue in OpenSSL 3.1.0 which caused `X509Extension.get_short_name` to raise an exception when no short name was known to OpenSSL.
+  `#1204 <https://github.com/pyca/pyopenssl/pull/1204>`_.
+
 23.1.0 (2023-03-24)
 -------------------
 
@@ -56,7 +71,7 @@ Backward-incompatible changes:
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Remove support for SSLv2 and SSLv3.
-- The minimum ``cryptography`` version is now 38.0.x (and we now pin releases 
+- The minimum ``cryptography`` version is now 38.0.x (and we now pin releases
   against ``cryptography`` major versions to prevent future breakage)
 - The ``OpenSSL.crypto.X509StoreContextError`` exception has been refactored,
   changing its internal attributes.
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index 8b12769..f5dd312 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -904,7 +904,14 @@ class X509Extension:
         """
         obj = _lib.X509_EXTENSION_get_object(self._extension)
         nid = _lib.OBJ_obj2nid(obj)
-        return _ffi.string(_lib.OBJ_nid2sn(nid))
+        # OpenSSL 3.1.0 has a bug where nid2sn returns NULL for NIDs that
+        # previously returned UNDEF. This is a workaround for that issue.
+        # https://github.com/openssl/openssl/commit/908ba3ed9adbb3df90f76
+        buf = _lib.OBJ_nid2sn(nid)
+        if buf != _ffi.NULL:
+            return _ffi.string(buf)
+        else:
+            return b"UNDEF"
 
     def get_data(self) -> bytes:
         """


Test patch:
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index 4b63fa2..3212fba 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -1681,6 +1681,14 @@ class TestX509Req(_PKeyInteractionTestsMixin):
         exts = request.get_extensions()
         assert len(exts) == 2
 
+    def test_undef_oid(self):
+        assert (
+            X509Extension(
+                b"1.2.3.4.5.6.7", False, b"DER:05:00"
+            ).get_short_name()
+            == b"UNDEF"
+        )
+
     def test_add_extensions_wrong_args(self):
         """
         `X509Req.add_extensions` raises `TypeError` if called with a
Repository: pyca/pyopenssl
Pull request #1208 (2023-03-31 12:48:50)

Reject invalid versions in X509Req.set_version


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f219137..8a0957e 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,6 +16,8 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
+- Invalid versions are now rejected in ``OpenSSL.crypto.X509Req.set_version``.
+
 23.1.1 (2023-03-28)
 -------------------
 
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index f5dd312..a3d9e9a 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -1010,6 +1010,12 @@ class X509Req:
         :param int version: The version number.
         :return: ``None``
         """
+        if not isinstance(version, int):
+            raise TypeError("version must be an int")
+        if version != 0:
+            raise ValueError(
+                "Invalid version. The only valid version for X509Req is 0."
+            )
         set_result = _lib.X509_REQ_set_version(self._req, version)
         _openssl_assert(set_result == 1)
 


Test patch:
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index 3212fba..0f67d20 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -1601,20 +1601,12 @@ class TestX509Req(_PKeyInteractionTestsMixin):
         """
         `X509Req.set_version` sets the X.509 version of the certificate
         request. `X509Req.get_version` returns the X.509 version of the
-        certificate request. The only defined version is 0. Others may or
-        may not be supported depending on backend.
+        certificate request. The only defined version is 0.
         """
         request = X509Req()
         assert request.get_version() == 0
         request.set_version(0)
         assert request.get_version() == 0
-        try:
-            request.set_version(1)
-            assert request.get_version() == 1
-            request.set_version(3)
-            assert request.get_version() == 3
-        except Error:
-            pass
 
     def test_version_wrong_args(self):
         """
@@ -1624,6 +1616,8 @@ class TestX509Req(_PKeyInteractionTestsMixin):
         request = X509Req()
         with pytest.raises(TypeError):
             request.set_version("foo")
+        with pytest.raises(ValueError):
+            request.set_version(2)
 
     def test_get_subject(self):
         """
Repository: pyca/pyopenssl
Pull request #1351 (2024-08-09 14:32:51)

Allow Connection.get_certificate to return a cryptography certificate
refs https://github.com/pyca/pyopenssl/issues/1321


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e10c956..443a06c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -21,6 +21,8 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
+* ``OpenSSL.SSL.Connection.get_certificate`` now takes an ``as_cryptography`` keyword-argument. When ``True`` is passed then a ``cryptography.x509.Certificate`` is returned, instead of an ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated.
+
 
 24.2.1 (2024-07-20)
 -------------------
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index e4d9ce1..a25be26 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -2696,16 +2696,43 @@ class Connection:
         """
         return self._socket.shutdown(*args, **kwargs)  # type: ignore[return-value, union-attr]
 
-    def get_certificate(self) -> X509 | None:
+    @typing.overload
+    def get_certificate(
+        self, *, as_cryptography: typing.Literal[True]
+    ) -> x509.Certificate | None:
+        pass
+
+    @typing.overload
+    def get_certificate(
+        self, *, as_cryptography: typing.Literal[False] = False
+    ) -> X509 | None:
+        pass
+
+    @typing.overload
+    def get_certificate(
+        self, *, as_cryptography: bool = False
+    ) -> X509 | x509.Certificate | None:
+        pass
+
+    def get_certificate(
+        self, *, as_cryptography: bool = False
+    ) -> X509 | x509.Certificate | None:
         """
         Retrieve the local certificate (if any)
 
+        :param bool as_cryptography: Controls whether a
+            ``cryptography.x509.Certificate`` or an ``OpenSSL.crypto.X509``
+            object should be returned.
+
         :return: The local certificate
         """
         cert = _lib.SSL_get_certificate(self._ssl)
         if cert != _ffi.NULL:
             _lib.X509_up_ref(cert)
-            return X509._from_raw_x509_ptr(cert)
+            pycert = X509._from_raw_x509_ptr(cert)
+            if as_cryptography:
+                return pycert.to_cryptography()
+            return pycert
         return None
 
     def get_peer_certificate(self) -> X509 | None:


Test patch:
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index fa6f40a..9be03b0 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -2556,6 +2556,13 @@ class TestConnection:
         assert cert is not None
         assert "Server Certificate" == cert.get_subject().CN
 
+        cryptography_cert = client.get_certificate(as_cryptography=True)
+        assert cryptography_cert is not None
+        assert (
+            cryptography_cert.subject.rfc4514_string()
+            == "CN=Server Certificate"
+        )
+
     def test_get_certificate_none(self):
         """
         `Connection.get_certificate` returns the local certificate.
Repository: pyca/pyopenssl
Pull request #806 (2019-01-21 18:25:00)

upgrade macos builders to newer travis image


Patch:
diff --git a/.travis.yml b/.travis.yml
index cac7107..52131e8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,11 +14,11 @@ matrix:
   include:
   - language: generic
     os: osx
-    osx_image: xcode9.3
+    osx_image: xcode10.1
     env: TOXENV=py27
   - language: generic
     os: osx
-    osx_image: xcode9.3
+    osx_image: xcode10.1
     env: TOXENV=py27 OPENSSL=1.1.0
   - python: "2.7" # these are just to make travis's UI a bit prettier
     env: TOXENV=py27
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index d555083..12e92df 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -71,6 +71,8 @@ FILETYPE_TEXT = 2 ** 16 - 1
 
 TYPE_RSA = _lib.EVP_PKEY_RSA
 TYPE_DSA = _lib.EVP_PKEY_DSA
+TYPE_DH = _lib.EVP_PKEY_DH
+TYPE_EC = _lib.EVP_PKEY_EC
 
 
 class Error(Exception):
@@ -695,11 +697,11 @@ class X509Name(object):
             nid = _lib.OBJ_obj2nid(fname)
             name = _lib.OBJ_nid2sn(nid)
 
-            result.append((
-                _ffi.string(name),
-                _ffi.string(
-                    _lib.ASN1_STRING_data(fval),
-                    _lib.ASN1_STRING_length(fval))))
+            # ffi.string does not handle strings containing NULL bytes
+            # (which may have been generated by old, broken software)
+            value = _ffi.buffer(_lib.ASN1_STRING_data(fval),
+                                _lib.ASN1_STRING_length(fval))[:]
+            result.append((_ffi.string(name), value))
 
         return result
 
@@ -902,7 +904,7 @@ class X509Req(object):
         :param crypto_req: A ``cryptography`` X.509 certificate signing request
         :type crypto_req: ``cryptography.x509.CertificateSigningRequest``
 
-        :rtype: PKey
+        :rtype: X509Req
 
         .. versionadded:: 17.1.0
         """
@@ -1115,7 +1117,7 @@ class X509(object):
         :param crypto_key: A ``cryptography`` X.509 certificate.
         :type crypto_key: ``cryptography.x509.Certificate``
 
-        :rtype: PKey
+        :rtype: X509
 
         .. versionadded:: 17.1.0
         """


Test patch:
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index ec632d9..c938021 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -1214,6 +1214,17 @@ class TestX509Name(object):
         subject = cert.get_subject()
         assert "null.python.org\x00example.org" == subject.commonName
 
+    def test_load_nul_byte_components(self):
+        """
+        An `X509Name` from an `X509` instance loaded from a file can have a
+        NUL byte in the value of its components
+        """
+        cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
+        subject = cert.get_subject()
+        components = subject.get_components()
+        ccn = [value for name, value in components if name == b'CN']
+        assert ccn[0] == b'null.python.org\x00example.org'
+
     def test_set_attribute_failure(self):
         """
         If the value of an attribute cannot be set for some reason then