不受信任的 SSL 证书

关于 Selenium 2 如何接受不受信任的 SSL 证书的详细信息

此文档之前位于 wiki

简介

此页面详细介绍了 WebDriver 如何能够接受不受信任的 SSL 证书,从而允许用户在测试环境中测试受信任的站点,而在测试环境中,通常不存在有效的证书。对于所有支持的浏览器(当前为 Firefox),此功能默认启用。

Firefox

解决方案概述

Firefox 有一个用于覆盖无效证书的接口,称为 nsICertOverrideService。将此接口实现为原始服务的代理 - 除非 允许不受信任的证书。在这种情况下,当被问及证书时(对无效证书调用 hasMatchingOverride) - 表明它是受信任的。

实现细节

实现这个想法非常简单 - badCertListener.js 是一个独立的模块,当加载时,它会注册一个工厂来返回该服务的实例。有趣的功能是 hasMatchingOverride

WdCertOverrideService.prototype.hasMatchingOverride = function(
    aHostName, aPort, aCert, aOverrideBits, aIsTemporary)

aOverrideBits 和 aIsTemporary 是输出参数。这里事情变得有点棘手:有三种可能的覆盖位

  ERROR_UNTRUSTED: 1,
  ERROR_MISMATCH: 2,
  ERROR_TIME: 4

不可能只是全部设置它们,因为 Firefox 希望由证书生成的违规行为与函数的返回值之间完全匹配:(security/manager/ssl/src/SSLServerCertVerification.cpp:302)

  if (overrideService)
  {
    PRBool haveOverride;
    PRBool isTemporaryOverride; // we don't care
  
    nsrv = overrideService->HasMatchingOverride(hostString, port,
                                                ix509, 
                                                &overrideBits,
                                                &isTemporaryOverride, 
                                                &haveOverride);
    if (NS_SUCCEEDED(nsrv) && haveOverride) 
    {
      // remove the errors that are already overriden
      remaining_display_errors -= overrideBits;
    }
  }

  if (!remaining_display_errors) {
    // all errors are covered by override rules, so let's accept the cert
    return SECSuccess;
  }

可以在 security/manager/pki/resources/content/exceptionDialog.js(在 Firefox 源代码中)轻松查看违规行为到错误代码的确切映射

  var flags = 0;
  if(gSSLStatus.isUntrusted)
    flags |= overrideService.ERROR_UNTRUSTED;
  if(gSSLStatus.isDomainMismatch)
    flags |= overrideService.ERROR_MISMATCH;
  if(gSSLStatus.isNotValidAtThisTime)
    flags |= overrideService.ERROR_TIME;

SSL 状态通常可以从 "@mozilla.org/security/recentbadcerts;1" 获取 - 但是,证书(及其状态)仅在调用 hasMatchingOverride之后才添加到此服务中,因此没有简单的方法来查找证书的 SSLStatus。相反,必须手动执行检查。

执行两项检查

  • 调用 nsIX509Cert.verifyForUsage
  • 将主机名与 nsIX509Cert.commonName 进行比较。如果它们不相等,则设置 ERROR_MISMATCH

第二个检查表明是否应设置 ERROR_MISMATCH。第一个检查应表明是否应设置 ERROR_UNTRUSTEDERROR_TIME。不幸的是,当证书过期 来自不受信任的颁发者时,它无法可靠地工作。当证书过期时,即使它也是不受信任的,返回代码也会是 CERT_EXPIRED。因此,FirefoxDriver 假定证书将不受信任 - 它始终设置 ERROR_UNTRUSTED 位 - 只有在满足它们的条件时才会设置其他两个位。

这可能会给测试具有与所服务主机名不匹配的有效证书的站点的人带来问题(例如,测试环境提供生产证书)。添加了 FirefoxProfile 的附加功能: FirefoxProfile.setAssumeUntrustedCertificateIssuer。使用 false 调用此函数将关闭 ERROR_UNTRUSTED 位,并允许用户在此类情况下工作。

HTMLUnit

尚未测试。

IE

尚未实现。

Chrome

尚未实现。

上次修改时间 2022 年 1 月 12 日:存档其他 wiki 文章 (e75f49c8af3)