Skip to content
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
63 changes: 63 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

import pytest
import wolfssl
from wolfssltestserver import wolfSSLTestServer
from threading import Thread

HOST = "www.python.org"
PORT = 443
Expand Down Expand Up @@ -89,3 +91,64 @@ def test_get_version(ssl_server, ssl_version, tcp_socket):
assert secure_socket.version() == protocol_name
secure_socket.write(b'hello wolfssl')
secure_socket.read(1024)


def test_client_cert_verification_failure():
"""
Test that a connection fails when the server requires client certificates
but the server's CA (globalsign) does not verify the client's certificate.
"""
import socket
import time

# Create a server with CERT_REQUIRED and globalsign CA
# This server will require client certificates but won't accept
# certificates signed by a different CA
port = 11111
with wolfSSLTestServer(
('localhost', port),
version=wolfssl.PROTOCOL_TLS,
verify=wolfssl.CERT_REQUIRED
) as server:
server_thread = Thread(target=server.handle_request)
server_thread.daemon = True
server_thread.start()

# Give the server a moment to start
time.sleep(0.1)

# Create a client socket
client_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Create a client context
client_ctx = wolfssl.SSLContext(wolfssl.PROTOCOL_TLS)

# Wrap the socket with the client context
# Set do_handshake_on_connect=False so we can explicitly call do_handshake()
# and catch the error
client_socket = client_ctx.wrap_socket(
client_tcp_socket,
do_handshake_on_connect=False
)

# Connect the TCP socket first
client_socket.connect(('127.0.0.1', port))

# Attempt handshake - this should fail because the client does not
# send a cert/key.
with pytest.raises(wolfssl.SSLError) as exc_info:
client_socket.do_handshake()
# Handshake appeared to succeed, try to read/write to trigger the error
# The server should reject the connection due to certificate verification failure
client_socket.write(b'hello')
client_socket.read(1024)

# Clean up (errors during close are expected if connection failed)
try:
client_socket.close()
except Exception:
pass
try:
client_tcp_socket.close()
except Exception:
pass
3 changes: 3 additions & 0 deletions tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def test_verify_mode(ssl_provider, ssl_context):

assert ssl_context.verify_mode == ssl_provider.CERT_NONE

ssl_context.verify_mode = ssl_provider.CERT_OPTIONAL
assert ssl_context.verify_mode == ssl_provider.CERT_OPTIONAL

ssl_context.verify_mode = ssl_provider.CERT_REQUIRED
assert ssl_context.verify_mode == ssl_provider.CERT_REQUIRED

Expand Down
11 changes: 8 additions & 3 deletions wolfssl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,15 @@
PROTOCOL_DTLSv1_3, WolfSSLMethod as _WolfSSLMethod
)

CERT_NONE = 0
CERT_REQUIRED = 1
_SSL_VERIFY_NONE = 0
_SSL_VERIFY_PEER = 1
_SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2

_VERIFY_MODE_LIST = [CERT_NONE, CERT_REQUIRED]
CERT_NONE = _SSL_VERIFY_NONE
CERT_OPTIONAL = _SSL_VERIFY_PEER
CERT_REQUIRED = (_SSL_VERIFY_PEER | _SSL_VERIFY_FAIL_IF_NO_PEER_CERT)

_VERIFY_MODE_LIST = [CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED]

_SSL_SUCCESS = 1
_SSL_FILETYPE_PEM = 1
Expand Down