Skip to content

Fenrir fixes#66

Open
JeremiahM37 wants to merge 10 commits intowolfSSL:masterfrom
JeremiahM37:fenrir-fixes-2
Open

Fenrir fixes#66
JeremiahM37 wants to merge 10 commits intowolfSSL:masterfrom
JeremiahM37:fenrir-fixes-2

Conversation

@JeremiahM37
Copy link
Copy Markdown
Contributor

-Second pass of fenrir issues
-Fixed F-947, F-948, F-949, F-950, F-957, F-1217, F-1218, F-1219, F-1220, F-1221, F-1222, F-1223, F-1224, F-1225, F-1226, F-1702, F-1703, F-1726, F-1727, F-1728.
-Also added two basic tests for the last batch of fenrir issues.

@classmethod
def enable_debug(self):
_lib.wolfSSL_Debugging_ON()
if _lib.wolfSSL_Debugging_ON() != _SSL_SUCCESS:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description: The diff changes enable_debug() to raise RuntimeError when wolfSSL_Debugging_ON() doesn't return _SSL_SUCCESS (i.e., when wolfSSL is not compiled with --enable-debug). Both example scripts call wolfssl.WolfSSL.enable_debug() unconditionally without any try/except:

# examples/client.py:143
wolfssl.WolfSSL.enable_debug()

# examples/server.py:139
wolfssl.WolfSSL.enable_debug()

Previously, enable_debug() called wolfSSL_Debugging_ON() and silently ignored the return value, so the examples worked whether or not debug was compiled in. Now they will crash with RuntimeError: wolfSSL debugging not available for any non-debug wolfSSL build — which is the common default.

The comments in the examples even acknowledge this: "enable debug, if native wolfSSL has been compiled with '--enable-debug'" — the "if" implies it should be tolerant.

Code:

# wolfssl/__init__.py (new)
@classmethod
def enable_debug(self):
    if _lib.wolfSSL_Debugging_ON() != _SSL_SUCCESS:
        raise RuntimeError(
            "wolfSSL debugging not available")

Recommendation: Wrap enable_debug() calls in the examples in a try/except:

Suggested change
if _lib.wolfSSL_Debugging_ON() != _SSL_SUCCESS:
# examples/client.py and examples/server.py
try:
wolfssl.WolfSSL.enable_debug()
except RuntimeError:
pass

Alternatively, the library could provide a try_enable_debug() that returns a bool, keeping enable_debug() strict.

# API and are provided here for compatibility.
def close(self):
if self.native_object != _ffi.NULL:
_lib.wolfSSL_shutdown(self.native_object)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description: The new close() implementation calls wolfSSL_shutdown() before releasing the native object. While this is correct for clean TLS teardown, wolfSSL_shutdown() on a socket that never completed the handshake (e.g., wrap_socket succeeded but connect/do_handshake was never called) may produce unexpected errors or warnings in the wolfSSL log. The return value of wolfSSL_shutdown() is silently ignored in close(), which is acceptable for cleanup, but there's no guard for the case where the SSL session was never fully established.

Code:

def close(self):
    if self.native_object != _ffi.NULL:
        _lib.wolfSSL_shutdown(self.native_object)
        self._release_native_object()
    self._sock.close()

Recommendation: Consider guarding the shutdown call to only run when a connection was established:

Suggested change
_lib.wolfSSL_shutdown(self.native_object)
def close(self):
if self.native_object != _ffi.NULL:
if self._connected:
_lib.wolfSSL_shutdown(self.native_object)
self._release_native_object()
self._sock.close()

ssl_context.load_verify_locations(cadata=_CADATA)


def test_check_hostname_requires_cert_required(ssl_provider, ssl_context):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description: This diff introduces several significant behavior changes to close(), shutdown(), and unwrap() in SSLSocket, but no tests are added for these changes:

  1. close() now calls wolfSSL_shutdown() before releasing the native object (lines 913-916)
  2. shutdown() now implements two-phase TLS shutdown — calling wolfSSL_shutdown() a second time if the first returns 0 (lines 725-728)
  3. unwrap() now performs a full SSL shutdown + release instead of just detaching the fd (lines 738-740)

The two new tests (test_check_hostname_requires_cert_required and test_wrap_socket_server_side_mismatch) are good additions but cover different code paths.

Recommendation: Add tests that verify:

  • close() on an SSLSocket that hasn't completed handshake doesn't raise
  • close() followed by operations properly raises ValueError ("closed" check)
  • shutdown() properly releases the native object (subsequent calls don't crash)

if secure_socket:
secure_socket.shutdown(socket.SHUT_RDWR)
secure_socket.close()
if not args.u:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description: The new code conditionally skips secure_socket.close() for DTLS (args.u). This is correct because for DTLS, secure_socket wraps bind_socket (the listening UDP socket), and closing it would prevent subsequent loop iterations from accepting new connections. However, the reasoning isn't documented and could confuse future readers.

Code:

finally:
    if secure_socket:
        secure_socket.shutdown(socket.SHUT_RDWR)
        if not args.u:
            secure_socket.close()

Recommendation: Add a comment explaining why close is skipped for DTLS:

Suggested change
if not args.u:
secure_socket.shutdown(socket.SHUT_RDWR)
# Don't close for DTLS - secure_socket wraps the shared
# bind_socket which is needed for subsequent connections
if not args.u:
secure_socket.close()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants