I am trying to configure based on Use TLS and Python for authentication with proper key authentication.
After several days of trying to configure the correct ssl certificates, I get this error.
[Failure instance: Traceback: <class 'OpenSSL.SSL.Error'>: [('SSL routines', 'SSL3_GET_CLIENT_CERTIFICATE', 'no certificate returned')] /usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py:614:_doReadOrWrite /usr/lib/python2.7/dist-packages/twisted/internet/tcp.py:215:doRead /usr/lib/python2.7/dist-packages/twisted/internet/tcp.py:221:_dataReceived /usr/lib/python2.7/dist-packages/twisted/protocols/tls.py:419:dataReceived --- <exception caught here> --- /usr/lib/python2.7/dist-packages/twisted/protocols/tls.py:358:_flushReceiveBIO ]
From the output of this from the server:
def connectionLost(self, reason): print reason
I am not sure where I am wrong in generating certificates.
This is my code for creating a certification authority
Server key
Creating a client certificate:
##------------------------ Create New Client Certs -------------------------## from twisted.python.filepath import FilePath from twisted.internet.ssl import PrivateCertificate, KeyPair, DN def getCAPrivateCert(): #path to a private key ## needs to be the path to a CA private key for signing privatePath = FilePath(b"/etc/ssl/private/cacert.pem") if privatePath.exists(): return PrivateCertificate.loadPEM(privatePath.getContent()) else: print "CRASH TIME" def clientCertFor(name): signingCert = getCAPrivateCert() clientKey = KeyPair.generate(size=4096) csr = clientKey.requestObject(DN(CN=name), "sha1") clientCert = signingCert.signRequestObject( csr, serialNumber=1, digestAlgorithm="sha1") return PrivateCertificate.fromCertificateAndKeyPair(clientCert, clientKey) if __name__ == '__main__': import sys name = sys.argv[1] pem = clientCertFor(name.encode("utf-8")).dumpPEM() FilePath(name.encode("utf-8") + b".client.private.pem").setContent(pem) ##---------------------- Create New Client Certs End -----------------------##
Server creation
##--------------------------------- Server ---------------------------------## ## Note: server.pem is the servers certificate joined with the public key ## servermain.key.pem ## servermain.cert.pem ## ca.cert.pem is the CA public certificate from twisted.python.filepath import FilePath from twisted.internet.endpoints import SSL4ServerEndpoint from twisted.internet.ssl import PrivateCertificate, Certificate from twisted.internet.defer import Deferred from twisted.internet.task import react from twisted.internet.protocol import Protocol, Factory CERTFILE = "/etc/ssl/certs/ca.cert.pem" SERVERCERT = "/etc/ssl/private/server.pem" class ReportWhichClient(Protocol): def dataReceived(self, data): print "****************** NEW PEER REQUEST ******************" ## Get peer cert id peerCertificate = Certificate.peerFromTransport(self.transport) userkey = peerCertificate.getSubject().commonName.decode('utf-8') print userkey def connectionMade(self): print "connected" def connectionLost(self, reason): print reason def main(reactor): print "react" #Path to CA public key cacert = FilePath(CERTFILE).getContent() #Path to Server private key pemBytes = FilePath(SERVERCERT).getContent() ## should be ca public key from sudo mv cacert.pem /etc/ssl/certs/? certificateAuthority = Certificate.loadPEM(pemBytes) myCertificate = PrivateCertificate.loadPEM(pemBytes) serverEndpoint = SSL4ServerEndpoint(reactor, 4321, myCertificate.options(certificateAuthority)) serverEndpoint.listen(Factory.forProtocol(ReportWhichClient)) return Deferred() react(main, []) ##------------------------------- Server End -------------------------------##
Client:
##---------------------------- Client function -----------------------------## ##Main key reading class @inlineCallbacks def main(reactor, name): ## Client private key pem = FilePath(name.encode("client1.key.pem").getContent() #CA public key caPem = FilePath(b"ca.cert.pem").getContent() clientEndpoint = SSL4ClientEndpoint( reactor, u"localhost", 4321, optionsForClientTLS(u"Nameless CA", Certificate.loadPEM(caPem), PrivateCertificate.loadPEM(pem)), ) proto = yield clientEndpoint.connect(Factory.forProtocol(SendAnyData)) yield proto.deferred import sys react(main, sys.argv[1:]) ##-------------------------- Client function End ---------------------------##