不信任的 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_UNTRUSTED 和 ERROR_TIME。不幸的是,當憑證過期且來自不信任的發行者時,它無法可靠地運作。當憑證過期時,即使它也是不信任的,回傳代碼也會是 CERT_EXPIRED。因此,FirefoxDriver 假設憑證將是不信任的 - 它總是設定 ERROR_UNTRUSTED 位元 - 其他兩個位元只有在滿足條件時才會設定。

這可能會為測試具有有效憑證但與其服務的主機名稱不符的網站(例如,測試環境服務生產憑證)的人帶來問題。為 FirefoxProfile 新增了一個額外功能:FirefoxProfile.setAssumeUntrustedCertificateIssuer。使用 false 呼叫此函數將關閉 ERROR_UNTRUSTED 位元,並允許使用者在這種情況下工作。

HTMLUnit

尚未測試。

IE

尚未實作。

Chrome

尚未實作。

最後修改日期:2022 年 1 月 12 日:封存其他 wiki 文章 (e75f49c8af3)