Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/security/manager/ssl/tests/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  test_ev_certs.js   Sprache: JAVA

 
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

"use strict";

// Tests that end-entity certificates that should successfully verify as EV
// (Extended Validation) do so and that end-entity certificates that should not
// successfully verify as EV do not. Also tests related situations (e.g. that
// failure to fetch an OCSP response results in no EV treatment).
//
// A quick note about the certificates in these tests: generally, an EV
// certificate chain will have an end-entity with a specific policy OID followed
// by an intermediate with the anyPolicy OID chaining to a root with no policy
// OID (since it's a trust anchor, it can be omitted). In these tests, the
// specific policy OID is 1.3.6.1.4.1.13769.666.666.666.1.500.9.1 and is
// referred to as the test OID. In order to reflect what will commonly be
// encountered, the end-entity of any given test path will have the test OID
// unless otherwise specified in the name of the test path. Similarly, the
// intermediate will have the anyPolicy OID, again unless otherwise specified.
// For example, for the path where the end-entity does not have an OCSP URI
// (referred to as "no-ocsp-ee-path-{ee,int}", the end-entity has the test OID
// whereas the intermediate has the anyPolicy OID.
// For another example, for the test OID path ("test-oid-path-{ee,int}"), both
// the end-entity and the intermediate have the test OID.

do_get_profile(); // must be called before getting nsIX509CertDB
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
  Ci.nsIX509CertDB
);

registerCleanupFunction(() => {
  Services.prefs.clearUserPref("network.dns.localDomains");
  Services.prefs.clearUserPref("security.OCSP.enabled");
});

Services.prefs.setCharPref("network.dns.localDomains""www.example.com");
Services.prefs.setIntPref("security.OCSP.enabled", 1);
const evroot = addCertFromFile(certdb, "test_ev_certs/evroot.pem""CTu,,");
addCertFromFile(certdb, "test_ev_certs/non-evroot-ca.pem""CTu,,");

const SERVER_PORT = 8888;

function failingOCSPResponder() {
  return getFailingHttpServer(SERVER_PORT, ["www.example.com"]);
}

class EVCertVerificationResult {
  constructor(
    testcase,
    expectedPRErrorCode,
    expectedEV,
    resolve,
    ocspResponder
  ) {
    this.testcase = testcase;
    this.expectedPRErrorCode = expectedPRErrorCode;
    this.expectedEV = expectedEV;
    this.resolve = resolve;
    this.ocspResponder = ocspResponder;
  }

  verifyCertFinished(prErrorCode, verifiedChain, hasEVPolicy) {
    equal(
      prErrorCode,
      this.expectedPRErrorCode,
      `${this.testcase} should have expected error code`
    );
    equal(
      hasEVPolicy,
      this.expectedEV,
      `${this.testcase} should result in expected EV status`
    );
    this.ocspResponder.stop(this.resolve);
  }
}

function asyncTestEV(
  cert,
  expectedPRErrorCode,
  expectedEV,
  expectedOCSPRequestPaths,
  ocspResponseTypes = undefined
) {
  let now = Date.now() / 1000;
  return new Promise(resolve => {
    let ocspResponder = expectedOCSPRequestPaths.length
      ? startOCSPResponder(
          SERVER_PORT,
          "www.example.com",
          "test_ev_certs",
          expectedOCSPRequestPaths,
          expectedOCSPRequestPaths.slice(),
          null,
          ocspResponseTypes
        )
      : failingOCSPResponder();
    let result = new EVCertVerificationResult(
      cert.subjectName,
      expectedPRErrorCode,
      expectedEV,
      resolve,
      ocspResponder
    );
    certdb.asyncVerifyCertAtTime(
      cert,
      certificateUsageSSLServer,
      0,
      "ev-test.example.com",
      now,
      result
    );
  });
}

function ensureVerifiesAsEV(testcase) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  let expectedOCSPRequestPaths = [`${testcase}-ee`];
  return asyncTestEV(
    cert,
    PRErrorCodeSuccess,
    gEVExpected,
    expectedOCSPRequestPaths
  );
}

function ensureVerifiesAsEVWithNoOCSPRequests(testcase) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  return asyncTestEV(cert, PRErrorCodeSuccess, gEVExpected, []);
}

function ensureVerifiesAsDV(testcase, expectedOCSPRequestPaths = undefined) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  return asyncTestEV(
    cert,
    PRErrorCodeSuccess,
    false,
    expectedOCSPRequestPaths ? expectedOCSPRequestPaths : [`${testcase}-ee`]
  );
}

function ensureVerificationFails(testcase, expectedPRErrorCode) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  return asyncTestEV(cert, expectedPRErrorCode, false, []);
}

function verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, expectSuccess) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  let now = Date.now() / 1000;
  let expectedErrorCode = SEC_ERROR_POLICY_VALIDATION_FAILED;
  if (expectSuccess && gEVExpected) {
    expectedErrorCode = PRErrorCodeSuccess;
  }
  return new Promise(resolve => {
    let ocspResponder = failingOCSPResponder();
    let result = new EVCertVerificationResult(
      cert.subjectName,
      expectedErrorCode,
      expectSuccess && gEVExpected,
      resolve,
      ocspResponder
    );
    let flags =
      Ci.nsIX509CertDB.FLAG_LOCAL_ONLY | Ci.nsIX509CertDB.FLAG_MUST_BE_EV;
    certdb.asyncVerifyCertAtTime(
      cert,
      certificateUsageSSLServer,
      flags,
      "ev-test.example.com",
      now,
      result
    );
  });
}

function ensureNoOCSPMeansNoEV(testcase) {
  return verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, false);
}

function ensureVerifiesAsEVWithFLAG_LOCAL_ONLY(testcase) {
  return verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, true);
}

function verifyWithOCSPResponseType(testcase, response, expectEV) {
  let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`);
  addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,");
  let expectedOCSPRequestPaths = [`${testcase}-ee`];
  let ocspResponseTypes = [response];
  return asyncTestEV(
    cert,
    PRErrorCodeSuccess,
    gEVExpected && expectEV,
    expectedOCSPRequestPaths,
    ocspResponseTypes
  );
}

function ensureVerifiesAsDVWithOldEndEntityOCSPResponse(testcase) {
  return verifyWithOCSPResponseType(testcase, "longvalidityalmostold"false);
}

function ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse(testcase) {
  return verifyWithOCSPResponseType(testcase, "ancientstillvalid"false);
}

// These should all verify as EV.
add_task(async function plainExpectSuccessEVTests() {
  await ensureVerifiesAsEV("anyPolicy-int-path");
  await ensureVerifiesAsEV("test-oid-path");
  await ensureVerifiesAsEV("cabforum-oid-path");
  await ensureVerifiesAsEV("cabforum-and-test-oid-ee-path");
  await ensureVerifiesAsEV("test-and-cabforum-oid-ee-path");
  await ensureVerifiesAsEV("reverse-order-oids-path");
  // In this case, the end-entity has both the CA/B Forum OID and the test OID
  // (in that order). The intermediate has the CA/B Forum OID. Since the
  // implementation tries all EV policies it encounters, this successfully
  // verifies as EV.
  await ensureVerifiesAsEV("cabforum-and-test-oid-ee-cabforum-oid-int-path");
  // In this case, the end-entity has both the test OID and the CA/B Forum OID
  // (in that order). The intermediate has only the CA/B Forum OID. Since the
  // implementation tries all EV policies it encounters, this successfully
  // verifies as EV.
  await ensureVerifiesAsEV("test-and-cabforum-oid-ee-cabforum-oid-int-path");
});

// These fail for various reasons to verify as EV, but fallback to DV should
// succeed.
add_task(async function expectDVFallbackTests() {
  await ensureVerifiesAsDV("anyPolicy-ee-path");
  await ensureVerifiesAsDV("non-ev-root-path");
  await ensureVerifiesAsDV("no-ocsp-ee-path", []);
  await ensureVerifiesAsEV("no-ocsp-int-path");
  // In this case, the end-entity has the test OID and the intermediate has the
  // CA/B Forum OID. Since the CA/B Forum OID is not treated the same as the
  // anyPolicy OID, this will not verify as EV.
  await ensureVerifiesAsDV("test-oid-ee-cabforum-oid-int-path");
});

// Test that removing the trust bits from an EV root causes verifications
// relying on that root to fail (and then test that adding back the trust bits
// causes the verifications to succeed again).
add_task(async function evRootTrustTests() {
  clearOCSPCache();
  info("untrusting evroot");
  certdb.setCertTrust(
    evroot,
    Ci.nsIX509Cert.CA_CERT,
    Ci.nsIX509CertDB.UNTRUSTED
  );
  await ensureVerificationFails("test-oid-path", SEC_ERROR_UNKNOWN_ISSUER);
  info("re-trusting evroot");
  certdb.setCertTrust(
    evroot,
    Ci.nsIX509Cert.CA_CERT,
    Ci.nsIX509CertDB.TRUSTED_SSL
  );
  await ensureVerifiesAsEV("test-oid-path");
});

// Test that if FLAG_LOCAL_ONLY and FLAG_MUST_BE_EV are specified, that no OCSP
// requests are made (this also means that nothing will verify as EV).
add_task(async function localOnlyMustBeEVTests() {
  clearOCSPCache();
  await ensureNoOCSPMeansNoEV("anyPolicy-ee-path");
  await ensureNoOCSPMeansNoEV("anyPolicy-int-path");
  await ensureNoOCSPMeansNoEV("non-ev-root-path");
  await ensureNoOCSPMeansNoEV("no-ocsp-ee-path");
  await ensureNoOCSPMeansNoEV("no-ocsp-int-path");
  await ensureNoOCSPMeansNoEV("test-oid-path");
});

// Prime the OCSP cache and then ensure that we can validate certificates as EV
// without hitting the network. There's two cases here: one where we simply
// validate like normal and then check that the network was never accessed and
// another where we use flags to mandate that the network not be used.
add_task(async function ocspCachingTests() {
  clearOCSPCache();

  await ensureVerifiesAsEV("anyPolicy-int-path");
  await ensureVerifiesAsEV("test-oid-path");

  await ensureVerifiesAsEVWithNoOCSPRequests("anyPolicy-int-path");
  await ensureVerifiesAsEVWithNoOCSPRequests("test-oid-path");

  await ensureVerifiesAsEVWithFLAG_LOCAL_ONLY("anyPolicy-int-path");
  await ensureVerifiesAsEVWithFLAG_LOCAL_ONLY("test-oid-path");
});

// Old-but-still-valid OCSP responses are accepted for intermediates but not
// end-entity certificates (because of OCSP soft-fail this results in DV
// fallback).
add_task(async function oldOCSPResponseTests() {
  clearOCSPCache();

  clearOCSPCache();
  await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("anyPolicy-int-path");
  await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("test-oid-path");

  clearOCSPCache();
  await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse(
    "anyPolicy-int-path"
  );
  await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse("test-oid-path");
});

Messung V0.5
C=89 H=93 G=90

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.