I am building a TLS server using python (3.13 on macos) and ssl lib. The setup is very simple:
the ssl context is created as follows:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # Disable older versions
context.minimum_version = ssl.TLSVersion.TLSv1_2 # Ensure TLSv1.2 is the minimum
context.set_ciphers("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384")
context.load_cert_chain(certfile='tlsserver.fc.crt', keyfile='tlsserver.key')
context.load_verify_locations(cafile='root.crt')
context.verify_mode = ssl.CERT_REQUIRED
return context
My CA has the following tree
**** TLS Server
**** Webservers ***{
Root ** **** OpenSSL Client
*
**** Charles CA *** Charles Client
now the ca for verify_locations
has only the root certificate.
I have been trying to connect to the server using openssl s_client
and it works ok. If I provide a leaf certificate ossl.crt
it is rejected unless I provide -CAfile ca.crt
that contains cat webservers.crt root.crt
then it works.
However, I started trying charles as a proxy to examine the ssl communication. I created a charles-client.crt
from charles-root.crt
and put the client crt in charles proxy under Client Certificates
for my TLS server host and port.
And then I setup port forwarding from 6001 (charles) to 6000 (tls server). Now I can still contact and authenticate with the server using port 6001 and without any crt or key file openssl s_client -connect localhost:6001 -state
and the connection is established.
My question is how can this happen? Charles Proxy is forwarding to 6000 but how is it authenticating with the server? It has a leaf certificate that is from a different branch and neither charles nor the server know anything about Charles CA
intermediary certificate. How can the connection be established?
I tried using charles-client.crt
with openssl directly and it was rejected. But when I use it with port forwarding it works.
Bare with me as I am trying to learn this but if you can direct me somewhere where I can learn how is this happening? or is my setup wrong?
After checking Charles .keystore
manually, I did find a reference to the intermediate CA. It was added as a root CA some time ago but then manually removed from the GUI for another root CA; however, it was not actually deleted from the keystore, and Charles was sending it behind the scenes. I had to reset the keystore, and now the behavior is as expected.