On 2017-10-25, at 21:07, Enoch W. <[email protected]> wrote:
> Hi,
>
> I am using a self-signed CA to issue server and client(s) certificates.
>
> My server is using the standard Python ssl module.
> One client, that is using twisted.internet.ssl, consistently fails to connect
> with:
> On the Server: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca
> (_ssl.c:661),
> On the Client: [WARNING] [('SSL routines',
> 'tls_process_server_certificate', 'certificate verify failed')]
>
> This is my code:
>
> path = getModule(__name__).filePath.sibling(u'data')
>
> txt = path.child(u'ca.crt').getContent()
> cacert = ssl.Certificate.loadPEM(txt)
> root = ssl.trustRootFromCertificates([cacert])
>
> txt = path.child(u'client.pem').getContent()
> mycert = ssl.PrivateCertificate.loadPEM(txt)
>
> ctx = ssl.optionsForClientTLS(hostName, trustRoot=root,
> clientCertificate=mycert)
>
> reactor.connectSSL(hostName, portNumber, factory, ctx)
>
>
> I am using the latest git trunk code.
> With a regular ssl client I don't have an issue.
>
> A known bug?
I would review a few things before suspecting a bug.
Your code is using client side certificates (nice, not often seen) so both
server and client need to validate each other's certificates on connection
establishment. It seems they are both failing, but we're only looking at your
client code though.
Here are a few ideas:
1. Double check your certificates: Issuers, Subjects, Dates, SANs, etc.
2. Check that the hostName in optionsForClientTLS matches the name in the
server certificate.
3. Use the latest Twisted release instead of trunk, if possible.
Do the same for pyOpenSSL and other dependencies.
4. On the client side try using SSL4ClientEndpoint instead of connectSSL.
I'm almost sure they behave differently regarding validation (could not
quickly find
docs on that, though: I've had your problem before and I think I addressed
it this way).
Instead of reactor.connectSSL(...) go for something like:
ep = endpoints.SSL4ClientEndpoint(
reactor,
host=hostName,
port=portNumber,
sslContextFactory=ctx,
)
client = yield ep.connect(factory)
For completeness, even though my client skeleton is mostly your client code
with
this diff, a quick test shows that my client also establishes the TLS
connection
if I do the reverse: replace SSL4ClientEndpoint with connectSSL in my code.
This may not be the culprit, but I would try and see if anything changes.
5. On the server side I have the following Twisted code skeleton:
dhFile = filepath.FilePath(...)
dhParams = ssl.DiffieHellmanParameters.fromFile(dhFile)
caCert = ssl.Certificate.loadPEM(...)
privateCert = ssl.PrivateCertificate.loadPEM(...)
cf = ssl.CertificateOptions(
privateKey=privateCert.privateKey.original,
certificate=privateCert.original,
trustRoot=caCert,
dhParameters=dhParams,
)
ep = endpoints.SSL4ServerEndpoint(
reactor,
port=...,
sslContextFactory=cf,
)
f = protocol.Factory.forProtocol(...)
ep.listen(f)
reactor.run()
Your code is obviously different, if based on the standard library's ssl
module.
If 1 to 4 don't produce results, this is a good candidate for needing some
work.
Can you share a minimal version of that? I'll be glad to take it for a spin.
6. Double check your certificates, again. Triple-check them if managed manually.
For completeness and reference:
- See http://twistedmatrix.com/documents/current/core/howto/ssl.html as a
starting point
Twisted TLS, containing useful information and working examples.
- My working test environment runs Linux with OpenSSL 1.0.1t.
Cheers,
--
exvito
_______________________________________________
Twisted-Python mailing list
[email protected]
https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python