扭曲的Python,TLS和客户端/服务器证书身份验证错误 [英] Twisted Python, TLS and client/server certificate authentication error
问题描述
我一直在尽力学习Twisted,但是加上有限的TLS知识,事实证明这是充满挑战的.我正在尝试(最终)编写一个SMTP服务器,该服务器可以发送和接收纯文本格式或通过TLS的邮件,具体取决于要发送/接收的特定邮件的要求.
I've been learning Twisted as best I can, but together with limited TLS knowledge it's proving challenging. I'm trying to write (ultimately) an SMTP server that can send and receive messages both as plain text, or via TLS depending on requirements of a specific message to be sent / received.
我的示例服务器代码(到目前为止,仅处理TLS连接,尚无SMTP位!)是从
My sample server code (thus far, just handling the TLS connection, no SMTP bits yet!) is borrowed from http://twistedmatrix.com/documents/11.0.0/core/howto/ssl.html#auto5 and looks like:
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)
但是当我让服务器监听并且运行客户端时,我得到了:
But when I have the server listening, and I run the client I get:
/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: []
奇怪的是-我知道证书和密钥很好-我还有其他虚拟"代码(此处未粘贴,我认为这篇文章足够长!!)可以使用它们进行验证.谁能解释上面的代码在哪里?我很茫然...
The strange thing is - I know the certificate and key are fine - I have other "dummy" code (not pasted here, I figured this post is long enough!!) that uses them for validation just fine. Can anyone explain where the code above falls over? I'm at a loss...
谢谢:)
推荐答案
So it looks like there is a bug in the sample code found at: http://twistedmatrix.com/documents/14.0.0/core/howto/ssl.html
以示例"echoclient_ssl.py"为例:
Looking at the example "echoclient_ssl.py" there is the line:
authority = ssl.Certificate.loadPEM(certData)
但是,"starttls_client.py"示例代码中的等效代码是:
However, the equivalent bit of code in the "starttls_client.py" example code is:
ssl.PrivateCertificate.loadPEM(certData)
客户端上的
PrivateCertificate?即使我对TLS的了解有限,这似乎还是错误的.确实,我修改了代码以删除私人" ...,以上错误消失了!
PrivateCertificate on the client side? Even with my limited understanding of TLS, this seems wrong. Indeed, I modified my code to remove the "Private"... and the error above disappears!
正如我所说,我的知识和理解正在这里增长-但这肯定是我问题的解决方案!
As I say, my knowledge and understanding is growing here - but this certainly seems to be the issue / solution to my question!
这篇关于扭曲的Python,TLS和客户端/服务器证书身份验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!