Twisted Python如何使用自定义trustRoot创建twisted.web.client.BrowserLikePolicyForHTTPS?

时间:2014-10-02 17:44:14

标签: python http ssl twisted

我正在尝试创建t.w.c.BrowserLikePolicyForHTTPS以用作ContextFactory的{​​{1}}。我正在为我希望代理与之通信的所有服务器使用内部CA,因此我希望能够告诉您加载CA证书(PEM格式)并将其用作{{1的trustRoot参数}}。我已阅读文档并查看了源代码,但我不知道我应该提供什么作为参数。我尝试提供PyOPenSSL x509对象,但是我收到错误:

t.w.c.Agent

我可以在BrowserLikePolicyForHTTPS的代码中看到exceptions.TypeError: ('Could not adapt', <OpenSSL.crypto.X509 object at 0x280b290>, <InterfaceClass twisted.internet._sslverify.IOpenSSLTrustRoot>) 以某种方式适应t.i._sslverify,但我不清楚这是如何发生的。

我知道股票代理商不进行任何证书检查。我正在使用treq的分支,并正在尝试添加一个选项以提供自定义代理。

任何有关trustRoot参数的帮助都将不胜感激。如果我正在努力解决这个问题,请让我知道。

2 个答案:

答案 0 :(得分:6)

这里的问题突出了文档中的可怕疏忽;在API文档和叙述文档中都有。如果让 - 保罗无法弄清楚这样做的“正确方法”,那么普通用户显然没有希望。 I have filed a bug to correct this oversight

同时,请避免让 - 保罗的解决方案。虽然它是功能性的,但它涉及的技术在未来的版本中几乎肯定会在没有警告的情况下破坏(正如他清楚地指出的)幸运的是,有支持的方法来做到这一点。如果您有一个备用信任根,则Certificate可用作trustRoot参数的值。您可以像这样使用它(我已经使用Twisted 14.0.2测试了以下示例):

from __future__ import print_function
from twisted.web.client import Agent, BrowserLikePolicyForHTTPS
from twisted.internet.task import react
from twisted.internet.ssl import Certificate
from twisted.internet.protocol import Protocol
from twisted.python.filepath import FilePath
from twisted.internet.defer import inlineCallbacks, Deferred

@inlineCallbacks
def main(reactor):
    customPolicy = BrowserLikePolicyForHTTPS(
        Certificate.loadPEM(FilePath("your-trust-root.pem").getContent())
    )
    agent = Agent(reactor, customPolicy)
    response = yield agent.request(
        "GET", "https://your-web-site.example.com/"
    )
    done = Deferred()
    class CaptureString(Protocol):
        def dataReceived(self, data):
            print("Received:", data)
        def connectionLost(self, reason):
            done.callback(None)
    response.deliverBody(CaptureString())
    yield done

react(main)

答案 1 :(得分:0)

IOpenSSLTrustRoot有点无意义的API。

它本身不是公共接口 - 因此您无法实现自己的接口。如果是,它没有公共方法,因此不清楚如何定制其行为。

考虑到这个界面的安全敏感性,我打赌Twisted会竭尽全力确保你编写的代码继续工作 - 即使界面是私有的,界面上只有私有方法。

如果你编写了一些依赖于这个界面的代码,它总是像它现在一样工作,那么你至少可以发布到Twisted邮件列表并说出来,那里的人可能会尝试不破坏你的应用程序。

就是说,正如我上面所指出的,这部分内容都是私密的。 Twisted的声明的政策是不保证这里的向后兼容性。因此,请自担风险。

无论如何,你可以这样写:

from zope.interface import implementer

from characteristic import attributes

from twisted.internet._sslverify import IOpenSSLTrustRoot

@implementer(IOpenSSLTrustRoot)
@attributes(["root_certificate_path"])
class MyCATrustRoot(object):
    def _addCACertsToContext(self, context):
        context.load_verify_locations(self.root_certificate_path)

然后使用MyCATrustRoot实例作为trustRoot的{​​{1}}参数。确保至少使用Twisted 14.0.2,因为早期版本实际上忽略了传递给BrowserLikePolicyForHTTPS的{​​{1}}。

例如,如果您的可信“CA”证书位于trustRoot

BrowserLikePolicyForHTTPS