2014-09-23 91 views
2

我一直在学习扭曲尽我所能,但与有限的TLS知识一起,它证明具有挑战性。我试图编写(最终)一个SMTP服务器,它可以以纯文本形式发送和接收消息,也可以通过TLS发送和接收消息,具体取决于要发送/接收的特定消息的要求。扭曲的Python,TLS和客户端/服务器证书认证错误

我的示例服务器代码(到目前为止,只处理TLS连接,没有SMTP位呢!)从http://twistedmatrix.com/documents/11.0.0/core/howto/ssl.html#auto5借来的,看起来像:

from OpenSSL import SSL 
from twisted.internet import reactor, ssl 
from twisted.internet.protocol import ServerFactory 
from twisted.protocols.basic import LineReceiver 

class TLSServer(LineReceiver): 
    def lineReceived(self, line): 
     print "received: " + line 

     if line == "STARTTLS": 
      print "-- Switching to TLS" 
      self.sendLine('READY') 
      ctx = ServerTLSContext(
       privateKeyFileName='SSCerts/serverkey.pem', 
       certificateFileName='SSCerts/servercert.pem', 
       ) 
      self.transport.startTLS(ctx, self.factory) 


class ServerTLSContext(ssl.DefaultOpenSSLContextFactory): 
    def __init__(self, *args, **kw): 
     kw['sslmethod'] = SSL.TLSv1_METHOD 
     ssl.DefaultOpenSSLContextFactory.__init__(self, *args, **kw) 

if __name__ == '__main__': 
    factory = ServerFactory() 
    factory.protocol = TLSServer 
    reactor.listenTCP(8000, factory) 
    reactor.run() 

当客户端从http://twistedmatrix.com/documents/14.0.0/core/howto/ssl.html#starttls-client借来的,看起来像:

from twisted.internet import ssl, endpoints, task, protocol, defer 
from twisted.protocols.basic import LineReceiver 
from twisted.python.modules import getModule 

class StartTLSClient(LineReceiver): 
    def connectionMade(self): 
     self.sendLine("plain text") 
     self.sendLine("STARTTLS") 

    def lineReceived(self, line): 
     print("received: " + line) 
     if line == "READY": 
      self.transport.startTLS(self.factory.options) 
      self.sendLine("secure text") 
      self.transport.loseConnection() 

@defer.inlineCallbacks 
def main(reactor): 
    factory = protocol.Factory.forProtocol(StartTLSClient) 
    certData = getModule(__name__).filePath.sibling('servercert.pem').getContent() 
    factory.options = ssl.optionsForClientTLS(
     u"example.com", ssl.PrivateCertificate.loadPEM(certData) 
    ) 
    endpoint = endpoints.HostnameEndpoint(reactor, 'localhost', 8000) 
    startTLSClient = yield endpoint.connect(factory) 

    done = defer.Deferred() 
    startTLSClient.connectionLost = lambda reason: done.callback(None) 
    yield done 

if __name__ == "__main__": 
    import starttls_client 
    task.react(starttls_client.main) 

但是,当我在服务器听,我运行客户端,我得到:

/usr/lib64/python2.6/site-packages/twisted/internet/endpoints.py:30: DeprecationWarning: twisted.internet.interfaces.IStreamClientEndpointStringParser was deprecated in Twisted 14.0.0: This interface has been superseded by IStreamClientEndpointStringParserWithReactor. 
    from twisted.internet.interfaces import (
main function encountered error 
Traceback (most recent call last): 
    File "starttls_client.py", line 33, in <module> 
    task.react(starttls_client.main) 
    File "/usr/lib64/python2.6/site-packages/twisted/internet/task.py", line 875, in react 
    finished = main(_reactor, *argv) 
    File "/usr/lib64/pytho 

n2.6/site-packages/twisted/internet/defer.py", line 1237, in unwindGenerator 
     return _inlineCallbacks(None, gen, Deferred()) 
    --- <exception caught here> --- 
     File "/usr/lib64/python2.6/site-packages/twisted/internet/defer.py", line 1099, in _inlineCallbacks 
     result = g.send(result) 
     File "/root/Robot/Twisted/starttls_client.py", line 22, in main 
     u"example.com", ssl.PrivateCertificate.loadPEM(certData) 
     File "/usr/lib64/python2.6/site-packages/twisted/internet/_sslverify.py", line 619, in loadPEM 
     return Class.load(data, KeyPair.load(data, crypto.FILETYPE_PEM), 
     File "/usr/lib64/python2.6/site-packages/twisted/internet/_sslverify.py", line 725, in load 
     return Class(crypto.load_privatekey(format, data)) 
     File "build/bdist.linux-x86_64/egg/OpenSSL/crypto.py", line 2010, in load_privatekey 

    File "build/bdist.linux-x86_64/egg/OpenSSL/_util.py", line 22, in exception_from_error_queue 

OpenSSL.crypto.Error: [] 

奇怪的是 - 我知道证书和密钥都很好 - 我有其他的“虚拟”代码(这里没有粘贴,我认为这篇文章足够长了!!),它使用它们进行验证就好了。任何人都可以解释上面的代码落在哪里?我不知所措......

谢谢:)

回答

0

所以它看起来像有是发现在示例代码中的错误:http://twistedmatrix.com/documents/14.0.0/core/howto/ssl.html

望着如“echoclient_ssl.py”有是线:

authority = ssl.Certificate.loadPEM(certData) 

然而,代码在 “starttls_client.py” 例如码等效位是:

ssl.PrivateCertificate.loadPEM(certData) 

客户端的PrivateCertificate?即使对TLS的理解有限,这似乎也是错误的。事实上,我修改了我的代码以删除“私人”......上面的错误消失了!

正如我所说,我的知识和理解在这里不断增长 - 但这似乎是我的问题的解决方案!