I am using the Python (2.7) SSL module to write some server code like follows:
ssock = ssl.wrap_socket(sock, ca_certs="all-ca.crt", keyfile="server.key", certfile="server.crt", server_side=True, ssl_version=ssl.PROTOCOL_TLSv1)
The 'all-ca.crt' contains the signing CA certificate and the root CA certificate:
-----BEGIN CERTIFICATE-----
... (signing CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (root CA)...
-----END CERTIFICATE-----
The documentation for the Python SSL module states:
In general, if you are using SSL3 or TLS1, you don’t need to put the
full chain in your “CA certs” file; you only need the root
certificates, and the remote peer is supposed to furnish the other
certificates necessary to chain from its certificate to a root
certificate.
And this is my experience having written SSL servers in C. It doesn't seem to work here though. If I write a client that uses just the root certificate in its wrap_socket() call:
csock = ssl.wrap_socket(sock, ca_certs="root-ca.crt", cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1)
then an exception is raised:
ssl.SSLError: [Errno 1] _ssl.c:499: error:14094418:SSL
routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
If instead I pass all-ca.crt to the client ca_certs argument, then everything works as expected, but this is inconvenient at the client side and should not be required.
Is there any way I can tell the server side that it needs to provide the intermediate CA certificates to the client on negotiation?