2014-10-01 28 views
1

按照Jean-Paul Calderone的建议,我试图修改以下扭曲的“starttls_server”示例以支持使用ssl.ClientCertificateOptions ,让我指定我的私钥,证书和可信根按http://twistedmatrix.com/documents/14.0.0/api/twisted.internet.ssl.CertificateOptions.html扭曲的Python,在从纯文本切换到安全连接时使用ssl.CertificateOptions

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

class TLSServer(LineReceiver): 
    def lineReceived(self, line): 
     print("received: " + line) 
     if line == "STARTTLS": 
      print("-- Switching to TLS") 
      self.sendLine('READY') 
      self.transport.startTLS(self.factory.options) 

def main(reactor): 
    certData = getModule(__name__).filePath.sibling('server.pem').getContent() 
    cert = ssl.PrivateCertificate.loadPEM(certData) 
    factory = protocol.Factory.forProtocol(TLSServer) 
    factory.options = cert.options() 
    endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000) 
    endpoint.listen(factory) 
    return defer.Deferred() 

if __name__ == '__main__': 
    import starttls_server 
    task.react(starttls_server.main) 

我的理解是,我切实需要更换cert = ssl.PrivateCertificate...cert.options = ssl.PrivateCertificate....线,像certopts = ssl.CertificateOptions(privateKey=pKeyData, certificate=certData, trustRoot=caCertsData)(看了相应的文件in到certData,caCertsData和pKeyData),然后将它传递给factory.options - 但没有pasti在我尝试过的每一个代码变体中,我还没有正确地解决这个问题 - 我的努力从经典的“OpenSSL.crypto.Error:[]”中产生了不同的结果 - 通过看似只是倾销我的3的内容PEM文件来屏幕和退出!

任何人都可以启发我吗?谢谢:)

回答

1

cert.options()已经返回CertificateOptions。问题是options需要权限(如Certificate对象)作为位置参数,并且不允许您通过所有其他配置值,所以您可能想要直接构建CertificateOptions

只需将factory.options = cert.options()行更改为factory.options = ssl.CertificateOptions(...)即可。

但是,CertificateOptions需要一个pyOpenSSL PKey对象作为它的privateKey,而不是关键数据。因此,您需要使用OpenSSL API来加载该密钥,或者您可以从PrivateCertificate中提取该密钥。

If you read the signature of CertificateOptions very carefully,所需的类型应该很清楚。您也可能需要咨询pyOpenSSL文档。

+1

嗨@Glyph,非常感谢。所以我有我的服务器运行,'factory.options = ssl.CertificateOptions(privateKey = pKeyData,certificate = certData,trustRoot = caCert)'(这三个值从文件加载(我相信)是适当的。但是,exceptions.TypeError:cert的服务器错误必须是一个X509实例 - 客户端提供了cert的一个pem副本,你能否在这里给我启发一下呢?还是将它作为一个新问题提出来更有意义?谢谢! – 2014-10-02 15:27:30

+2

确保你将证书作为pyOpenSSL X509实例传递给'CertificateOptions' - 而不是Twisted的'PrivateCertificate'类型 – 2014-10-02 16:04:00

+1

Hi @ Jean-PaulCalderone ...我正在使用filePath.sibling从文件读取3个参数。 ('xxxxx')。getContent()。caCert是一个只有BEGIN CERTIFICATE [数据] END CERTIFICATE的PEM.CertData与BEGIN RSA PRIVATE KEY [data] END RSA PRIVATE KEY相同,pKeyData是不同的(因为我相信预期) - 包含'私钥(1024位)/模数/ [hex stuff]/publicExponent:65537(.... etc)'。这是不正确的?这3个参数中我没有使用ssl。[Private]证书吗? – 2014-10-03 07:21:06