2014-09-23 2 views
2

Я изучаю Twisted как можно лучше, но вместе с ограниченными знаниями 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 это кажется неправильным. Действительно, я изменил свой код, чтобы удалить «Частный» ... и ошибка выше исчезнет!

Как я уже сказал, мои знания и понимание здесь растут - но это, безусловно, проблема/решение моего вопроса!

Смежные вопросы