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

2024-06-26 05:36:33 发布

您现在位置:Python中文网/ 问答频道 /正文

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

exceptions.TypeError: ('Could not adapt', <OpenSSL.crypto.X509 object at 0x280b290>, <InterfaceClass twisted.internet._sslverify.IOpenSSLTrustRoot>)

我可以在t.i._sslverify中看到OpenSSLCertificateAuthorities以某种方式适应了IOpenSSLTrustRoot,但我并不清楚这是如何发生的。在

我知道股票经纪人不做任何证书检查。我正在使用treq的一个分支,并尝试添加一个选项来提供一个定制代理。在

任何关于trustRoot论点的帮助都将不胜感激。如果我很难做到这一点,也请告诉我。在


Tags: 文档服务器代理参数源代码格式pemca
2条回答

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实例作为trustRootBrowserLikePolicyForHTTPS参数。请确保至少使用Twisted 14.0.2,因为早期版本实际上忽略了传递给BrowserLikePolicyForHTTPStrustRoot。在

例如,如果受信任的“CA”证书位于/foo/ca.pem

^{pr2}$

您在这里的问题突出了文档中的一个严重疏忽;无论是在API文档中,还是在的叙述性文档中。如果Jean-Paul不能找到“正确的方法”来做到这一点,那么对于一个普通用户来说显然是没有希望的。I have filed a bug to correct this oversight。在

同时,请避免让保罗的解决办法。虽然它是功能性的,但它所涉及的技术几乎肯定会在未来的版本中毫无预警地崩溃(正如他明确指出的那样)。幸运的是,有一些支持的方法可以做到这一点。如果您有一个备用信任根,^{}可用作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)

相关问题 更多 >