summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_cert_chains.js
blob: 8abcb4e65cc924626545a87dbfc52f0d44d767bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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";

function build_cert_chain(certNames) {
  let certList = Cc["@mozilla.org/security/x509certlist;1"]
                   .createInstance(Ci.nsIX509CertList);
  certNames.forEach(function(certName) {
    let cert = constructCertFromFile("bad_certs/" + certName + ".pem");
    certList.addCert(cert);
  });
  return certList;
}

function test_cert_equals() {
  let certA = constructCertFromFile("bad_certs/default-ee.pem");
  let certB = constructCertFromFile("bad_certs/default-ee.pem");
  let certC = constructCertFromFile("bad_certs/expired-ee.pem");

  ok(certA != certB,
     "Cert objects constructed from the same file should not be equal" +
     " according to the equality operators");
  ok(certA.equals(certB),
     "equals() on cert objects constructed from the same cert file should" +
     " return true");
  ok(!certA.equals(certC),
     "equals() on cert objects constructed from files for different certs" +
     " should return false");
}

function test_cert_list_serialization() {
  let certList = build_cert_chain(['default-ee', 'expired-ee']);

  // Serialize the cert list to a string
  let serHelper = Cc["@mozilla.org/network/serialization-helper;1"]
                    .getService(Ci.nsISerializationHelper);
  certList.QueryInterface(Ci.nsISerializable);
  let serialized = serHelper.serializeToString(certList);

  // Deserialize from the string and compare to the original object
  let deserialized = serHelper.deserializeObject(serialized);
  deserialized.QueryInterface(Ci.nsIX509CertList);
  ok(certList.equals(deserialized),
     "Deserialized cert list should equal the original");
}

function test_security_info_serialization(securityInfo, expectedErrorCode) {
  // Serialize the securityInfo to a string
  let serHelper = Cc["@mozilla.org/network/serialization-helper;1"]
                    .getService(Ci.nsISerializationHelper);
  let serialized = serHelper.serializeToString(securityInfo);

  // Deserialize from the string and compare to the original object
  let deserialized = serHelper.deserializeObject(serialized);
  deserialized.QueryInterface(Ci.nsITransportSecurityInfo);
  equal(securityInfo.securityState, deserialized.securityState,
        "Original and deserialized security state should match");
  equal(securityInfo.errorMessage, deserialized.errorMessage,
        "Original and deserialized error message should match");
  equal(securityInfo.errorCode, expectedErrorCode,
        "Original and expected error code should match");
  equal(deserialized.errorCode, expectedErrorCode,
        "Deserialized and expected error code should match");
}

function run_test() {
  do_get_profile();
  add_tls_server_setup("BadCertServer", "bad_certs");

  // Test nsIX509Cert.equals
  add_test(function() {
    test_cert_equals();
    run_next_test();
  });

  // Test serialization of nsIX509CertList
  add_test(function() {
    test_cert_list_serialization();
    run_next_test();
  });

  // Test successful connection (failedCertChain should be null)
  add_connection_test(
    // re-use pinning certs (keeler)
    "good.include-subdomains.pinning.example.com", PRErrorCodeSuccess, null,
    function withSecurityInfo(aTransportSecurityInfo) {
      aTransportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
      test_security_info_serialization(aTransportSecurityInfo, 0);
      equal(aTransportSecurityInfo.failedCertChain, null,
            "failedCertChain for a successful connection should be null");
    }
  );

  // Test overrideable connection failure (failedCertChain should be non-null)
  add_connection_test(
    "expired.example.com",
    SEC_ERROR_EXPIRED_CERTIFICATE,
    null,
    function withSecurityInfo(securityInfo) {
      securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
      test_security_info_serialization(securityInfo, SEC_ERROR_EXPIRED_CERTIFICATE);
      notEqual(securityInfo.failedCertChain, null,
               "failedCertChain should not be null for an overrideable" +
               " connection failure");
      let originalCertChain = build_cert_chain(["expired-ee", "test-ca"]);
      ok(originalCertChain.equals(securityInfo.failedCertChain),
         "failedCertChain should equal the original cert chain for an" +
         " overrideable connection failure");
    }
  );

  // Test non-overrideable error (failedCertChain should be non-null)
  add_connection_test(
    "inadequatekeyusage.example.com",
    SEC_ERROR_INADEQUATE_KEY_USAGE,
    null,
    function withSecurityInfo(securityInfo) {
      securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
      test_security_info_serialization(securityInfo, SEC_ERROR_INADEQUATE_KEY_USAGE);
      notEqual(securityInfo.failedCertChain, null,
               "failedCertChain should not be null for a non-overrideable" +
               " connection failure");
      let originalCertChain = build_cert_chain(["inadequatekeyusage-ee", "test-ca"]);
      ok(originalCertChain.equals(securityInfo.failedCertChain),
         "failedCertChain should equal the original cert chain for a" +
         " non-overrideable connection failure");
    }
  );

  run_next_test();
}