Conversation
| @classmethod | ||
| def enable_debug(self): | ||
| _lib.wolfSSL_Debugging_ON() | ||
| if _lib.wolfSSL_Debugging_ON() != _SSL_SUCCESS: |
There was a problem hiding this comment.
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:
| 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) |
There was a problem hiding this comment.
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:
| _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): |
There was a problem hiding this comment.
Description: This diff introduces several significant behavior changes to close(), shutdown(), and unwrap() in SSLSocket, but no tests are added for these changes:
close()now callswolfSSL_shutdown()before releasing the native object (lines 913-916)shutdown()now implements two-phase TLS shutdown — callingwolfSSL_shutdown()a second time if the first returns 0 (lines 725-728)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 raiseclose()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: |
There was a problem hiding this comment.
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:
| 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() |
-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.