diff options
Diffstat (limited to 'security/manager/ssl/tests')
1164 files changed, 42767 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/.eslintrc.js b/security/manager/ssl/tests/.eslintrc.js new file mode 100644 index 0000000000..379eabb2d0 --- /dev/null +++ b/security/manager/ssl/tests/.eslintrc.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = { + rules: { + // Disallow non-top level |var| declarations. + "mozilla/var-only-at-top-level": "error", + }, +}; diff --git a/security/manager/ssl/tests/gtest/CertDBTest.cpp b/security/manager/ssl/tests/gtest/CertDBTest.cpp new file mode 100644 index 0000000000..310b0226e1 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CertDBTest.cpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsIPrefService.h" +#include "nsIX509Cert.h" +#include "nsIX509CertDB.h" +#include "nsServiceManagerUtils.h" + +TEST(psm_CertDB, Test) +{ + { + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + ASSERT_TRUE(prefs) + << "couldn't get nsIPrefBranch"; + + // When PSM initializes, it attempts to get some localized strings. + // As a result, Android flips out if this isn't set. + nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't set pref 'intl.locale.matchOS'"; + + nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID)); + ASSERT_TRUE(certdb) + << "couldn't get certdb"; + + nsTArray<RefPtr<nsIX509Cert>> certList; + rv = certdb->GetCerts(certList); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't get list of certificates"; + + bool foundBuiltIn = false; + for (const auto& cert : certList) { + ASSERT_TRUE(cert) + << "certlist shouldn't have null certificate"; + ASSERT_TRUE(NS_SUCCEEDED(cert->GetIsBuiltInRoot(&foundBuiltIn))) + << "GetIsBuiltInRoot failed"; + if (foundBuiltIn) { + break; + } + } + + ASSERT_TRUE(foundBuiltIn) + << "didn't load any built-in certificates"; + + printf("successfully loaded at least one built-in certificate\n"); + + } // this scopes the nsCOMPtrs +} diff --git a/security/manager/ssl/tests/gtest/CertListTest.cpp b/security/manager/ssl/tests/gtest/CertListTest.cpp new file mode 100644 index 0000000000..db4cec19e5 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CertListTest.cpp @@ -0,0 +1,332 @@ +/* -*- Mode: C++; 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsIPrefService.h" +#include "nsIX509Cert.h" +#include "nsIX509CertDB.h" +#include "nsNSSCertificate.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" + +// certspec (for pycert.py) +// +// issuer:ca +// subject:ca +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:1 +const char* kCaPem = + "-----BEGIN CERTIFICATE-----\n" + "MIICsjCCAZygAwIBAgIBATALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP\n" + "MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowDTELMAkGA1UEAwwCY2Ew\n" + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ\n" + "PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH\n" + "9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw\n" + "4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86\n" + "exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0\n" + "ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N\n" + "AgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEB\n" + "CwOCAQEAchHf1yV+blE6fvS53L3DGmvxEpn9+t+xwOvWczBmLFEzUPdncakdaWlQ\n" + "v7q81BPyjBqkYbQi15Ws81hY3dnXn8LT1QktCL9guvc3z4fMdQbRjpjcIReCYt3E\n" + "PB22Jl2FCm6ii4XL0qDFD26WK3zMe2Uks6t55f8VeDTBGNoPp2JMsWY1Pi4vR6wK\n" + "AY96WoXS/qrYkmMEOgFu907pApeAeE8VJzXjqMLF6/W1VN7ISnGzWQ8zKQnlp3YA\n" + "mvWZQcD6INK8mvpZxIeu6NtHaKEXGw7tlGekmkVhapPtQZYnWcsXybRrZf5g3hOh\n" + "JFPl8kW42VoxXL11PP5NX2ylTsJ//g==\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca +// subject:ca-intermediate +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:2 +const char* kCaIntermediatePem = + "-----BEGIN CERTIFICATE-----\n" + "MIICvzCCAamgAwIBAgIBAjALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP\n" + "MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPY2Et\n" + "aW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR\n" + "qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv\n" + "WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+\n" + "rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv\n" + "JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5\n" + "Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6\n" + "clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB\n" + "BjALBgkqhkiG9w0BAQsDggEBAC0ys8UOmYgvH5rrTeV6u79ocHqdQFwdmR7/4d08\n" + "i3asC7b70dw0ehA5vi4cq5mwBvQOGZq4wvsR4jSJW0+0hjWL1dr2M6VxmCfjdqhU\n" + "NQHPlY6y7lLfYQbFfUHX99ZgygJjdmmm7H8MBP4UgPb8jl6Xq53FgYykiX/qPmfb\n" + "pzpOFHDi+Tk67DLCvPz03UUDYNx1H0OhRimj0DWhdYGUg2DHfLQkOEYvrYG4wYB8\n" + "AB/0hrG51yFsuXrzhYcinTKby11Qk6PjnOQ/aZvK00Jffep/RHs8lIOWty9SarMG\n" + "oNSECn+6I9AgStJdo6LuP1QPyrQe3DZtAHhRJAPAoU7BSqM=\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca-intermediate +// subject:ca-second-intermediate +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:3 +const char* kCaSecondIntermediatePem = + "-----BEGIN CERTIFICATE-----\n" + "MIIC0zCCAb2gAwIBAgIBAzALBgkqhkiG9w0BAQswGjEYMBYGA1UEAwwPY2EtaW50\n" + "ZXJtZWRpYXRlMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAwMDBaMCEx\n" + "HzAdBgNVBAMMFmNhLXNlY29uZC1pbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEB\n" + "AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk\n" + "e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg\n" + "KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI\n" + "YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi\n" + "lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL\n" + "HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1Ud\n" + "EwQFMAMBAf8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEBCwOCAQEAaK6K7/0Y+PkG\n" + "MQJjumTlt6XUQjQ3Y6zuSOMlZ1wmJoBqWabYhJ4qXfcSMQiw+kZ+mQTFk+IdurGC\n" + "RHrAKwDGNRqmjnQ56qjwHNTTxhJozP09vBCgs3fIQQY/Nq/uISoQvOZmoIriFZf6\n" + "8czHMlj1vIC6zp4XHWdqkQ7aF4YFsTfM0kBPrm0Y6Nn0VKzWNdmaIs/X5OcR6ZAG\n" + "zGN9UZV+ZftcfdqI0XSVCVRAK5MeEa+twLr5PE/Nl7/Ig/tUJMWGSbcrWRZQTXQu\n" + "Rx7CSKcoatyMhJOd2YT4BvoijEJCxTKWMJzFe2uZAphQHUlVmE9IbUQM0T1N6RNd\n" + "1dH4o4UeuQ==\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca-second-intermediate +// subject:ee +const char* kEePem = + "-----BEGIN CERTIFICATE-----\n" + "MIICujCCAaSgAwIBAgIUMy8NE67P/4jkaCra7rOVVvX4+GswCwYJKoZIhvcNAQEL\n" + "MCExHzAdBgNVBAMMFmNhLXNlY29uZC1pbnRlcm1lZGlhdGUwIhgPMjAxNTExMjgw\n" + "MDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqG\n" + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0\n" + "7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D\n" + "/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw\n" + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX\n" + "rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd\n" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJ\n" + "KoZIhvcNAQELA4IBAQCE5V5YiFPtbb1dOCIMGC5X/6kfQkQmIfvEZIol0MRXmP4g\n" + "CsOPbTI+BNxYVNk5RHIlr+6e0d8TNiABem4FZK3kea4ugN8ez3IsK7ug7qdrooNA\n" + "MiHOvrLmAw2nQWexdDRf7OPeVj03BwELzGTOGPjAqDktTsK57OfXyFTm9nl75WQo\n" + "+EWX+CdV4L1o2rgABvSiMnMdycftCC73Hr/3ypADqY7nDrKpxYdrGgzAQvx3DjPv\n" + "b7nBKH/gXg3kzoWpeQmJYPl9Vd+DvGljS5i71oLbvCwlDX7ZswGcvb8pQ7Tni5HA\n" + "VYpAYLokxIDFnyVT9oCACJuJ5LvpBBrhd0+1uUPE\n" + "-----END CERTIFICATE-----"; + +class psm_CertList : public ::testing::Test { + protected: + void SetUp() override { + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + ASSERT_TRUE(prefs) + << "couldn't get nsIPrefBranch"; + + // When PSM initializes, it attempts to get some localized strings. + // As a result, Android flips out if this isn't set. + nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't set pref 'intl.locale.matchOS'"; + + nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID)); + ASSERT_TRUE(certdb) + << "couldn't get certdb"; + } +}; + +static nsresult AddCertFromStringToList( + const char* aPem, nsTArray<RefPtr<nsIX509Cert>>& aCertList) { + RefPtr<nsIX509Cert> cert; + cert = + nsNSSCertificate::ConstructFromDER(const_cast<char*>(aPem), strlen(aPem)); + if (!cert) { + return NS_ERROR_FAILURE; + } + + aCertList.AppendElement(cert); + return NS_OK; +} + +TEST_F(psm_CertList, TestInvalidSegmenting) { + nsTArray<RefPtr<nsIX509Cert>> certList; + + nsCOMPtr<nsIX509Cert> rootCert; + nsTArray<RefPtr<nsIX509Cert>> intCerts; + nsCOMPtr<nsIX509Cert> eeCert; + nsresult rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, + intCerts, eeCert); + ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Empty lists can't be segmented"; + + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Lists of one can't be segmented"; +} + +TEST_F(psm_CertList, TestValidSegmenting) { + nsTArray<RefPtr<nsIX509Cert>> certList; + + nsresult rv = AddCertFromStringToList(kEePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + nsCOMPtr<nsIX509Cert> rootCert; + nsTArray<RefPtr<nsIX509Cert>> intCerts; + nsCOMPtr<nsIX509Cert> eeCert; + + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(0)) + << "There should be no intermediates"; + + nsAutoString rootCn; + ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + ASSERT_TRUE(rootCn.EqualsLiteral("ca-second-intermediate")) + << "Second Intermediate CN should match"; + + rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(1)) + << "There should be one intermediate"; + + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(2)) + << "There should be two intermediates"; + + ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + ASSERT_TRUE(rootCn.EqualsLiteral("ca")) + << "Root CN should match"; + + nsAutoString eeCn; + ASSERT_TRUE(NS_SUCCEEDED(eeCert->GetCommonName(eeCn))) + << "Getters should work."; + ASSERT_TRUE(eeCn.EqualsLiteral("ee")) + << "EE CN should match"; + + for (size_t i = 0; i < intCerts.Length(); ++i) { + nsAutoString cn; + const auto& cert = intCerts[i]; + rv = cert->GetCommonName(cn); + if (NS_FAILED(rv)) { + break; + } + + if (i < intCerts.Length() - 1) { + if (!cn.EqualsLiteral("ca-second-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } else { + if (!cn.EqualsLiteral("ca-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } + } + + ASSERT_EQ(rv, NS_OK) << "Should have looped OK."; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainTwo) { + nsTArray<RefPtr<nsIX509Cert>> certList; + + nsresult rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + + nsCOMPtr<nsIX509Cert> rootCert; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + + nsAutoString rootCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; + + // Re-fetch and ensure we get the same certificate. + nsCOMPtr<nsIX509Cert> rootCertRepeat; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCertRepeat); + EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK the second time"; + ASSERT_TRUE(rootCertRepeat) + << "Root cert should still be filled in"; + + nsAutoString rootRepeatCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCertRepeat->GetCommonName(rootRepeatCn))) + << "Getters should work."; + EXPECT_TRUE(rootRepeatCn.EqualsLiteral("ca")) << "Root CN should still match"; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainFour) { + nsTArray<RefPtr<nsIX509Cert>> certList; + + nsresult rv = AddCertFromStringToList(kEePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + + nsCOMPtr<nsIX509Cert> rootCert; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_OK, rv) << "Should have again fetched the root OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + + nsAutoString rootCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainEmpty) { + nsTArray<RefPtr<nsIX509Cert>> certList; + + nsCOMPtr<nsIX509Cert> rootCert; + nsresult rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_ERROR_FAILURE, rv) + << "Should have returned NS_ERROR_FAILURE because certList was empty"; + EXPECT_FALSE(rootCert) << "Root cert should be empty"; +} diff --git a/security/manager/ssl/tests/gtest/CoseTest.cpp b/security/manager/ssl/tests/gtest/CoseTest.cpp new file mode 100644 index 0000000000..2f05cad3a7 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CoseTest.cpp @@ -0,0 +1,756 @@ +/* -*- Mode: C++; 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/. */ + +#include "gtest/gtest.h" + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <cstddef> +#include <memory> + +#include <keyhi.h> +#include <nss.h> +#include <pk11pub.h> + +#include <pkcs11t.h> +#include <secmodt.h> +#include <cert.h> + +#include "ScopedNSSTypes.h" +#include "cosec.h" + +namespace mozilla { + +// "This is the content." +const uint8_t PAYLOAD[] = {84, 104, 105, 115, 32, 105, 115, 32, 116, 104, + 101, 32, 99, 111, 110, 116, 101, 110, 116, 46}; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed with the P256 key from +// pykey.py. +const uint8_t SIGNATURE[] = { + 0xd8, 0x62, 0x84, 0x59, 0x02, 0xa3, 0xa1, 0x04, 0x82, 0x59, 0x01, 0x4e, + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b, 0x59, 0x01, + 0x4c, 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, + 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, + 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, + 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, + 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, + 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7, 0xa0, 0xf6, 0x81, + 0x83, 0x59, 0x01, 0x33, 0xa2, 0x01, 0x26, 0x04, 0x59, 0x01, 0x2c, 0x30, + 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, 0x13, 0x92, 0xd6, + 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, + 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, 0x70, 0x32, + 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61, 0xe0, 0xf8, + 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec, 0x05, 0x0b, + 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, + 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, + 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, + 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, + 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, + 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, + 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, + 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, 0x36, 0x6b, 0x75, + 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, 0xc5, 0x89, 0xc1, + 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, 0xfa, 0x0b, 0xa0, + 0x58, 0x40, 0x1e, 0x6e, 0x08, 0xdf, 0x8f, 0x4f, 0xd6, 0xab, 0x23, 0xae, + 0x84, 0xaa, 0xf3, 0x43, 0x35, 0x9a, 0x53, 0xb9, 0x8b, 0xf9, 0x81, 0xa1, + 0xbc, 0x1e, 0x5c, 0x57, 0x5c, 0x0a, 0x20, 0x37, 0xf4, 0x3d, 0x11, 0x08, + 0xa0, 0x97, 0x4b, 0x68, 0xa4, 0x0f, 0x80, 0xe9, 0x96, 0x30, 0x04, 0x24, + 0x0e, 0x81, 0x3d, 0x2a, 0x8a, 0x64, 0x40, 0x61, 0x5a, 0x19, 0x00, 0xff, + 0x74, 0x40, 0x71, 0x82, 0x65, 0xe9}; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed twice; with the P256 and the +// RSA key from pykey.py. +const uint8_t SIGNATURE_ES256_PS256[] = { + 0xd8, 0x62, 0x84, 0x59, 0x08, 0x52, 0xa1, 0x04, 0x84, 0x59, 0x01, 0x4e, + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b, 0x59, 0x01, + 0x4c, 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, + 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, + 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, + 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, + 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, + 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7, 0x59, 0x02, 0xd5, + 0x30, 0x82, 0x02, 0xd1, 0x30, 0x82, 0x01, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x29, 0x6c, 0x1a, 0xd8, 0x20, 0xcd, 0x74, 0x6d, 0x4b, + 0x00, 0xf3, 0x16, 0x88, 0xd9, 0x66, 0x87, 0x5f, 0x28, 0x56, 0x6a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, + 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, + 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, + 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, + 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, + 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, + 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, + 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, + 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, + 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, + 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, + 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, + 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, + 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, + 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, + 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, + 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, + 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, + 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, + 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, + 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, + 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x2f, 0x9f, 0x72, 0xeb, 0x70, 0x6d, 0x9e, 0x3e, 0x9f, 0xd7, + 0x9c, 0xd9, 0x19, 0x7c, 0x99, 0x07, 0xc5, 0x5c, 0x9d, 0xf5, 0x66, 0x9f, + 0x28, 0x8d, 0xfe, 0x0e, 0x3f, 0x38, 0x75, 0xed, 0xee, 0x4e, 0x3f, 0xf6, + 0x6e, 0x35, 0xe0, 0x95, 0x3f, 0x08, 0x4a, 0x71, 0x5a, 0xf2, 0x4f, 0xc9, + 0x96, 0x61, 0x8d, 0x45, 0x4b, 0x97, 0x85, 0xff, 0xb0, 0xe3, 0xbb, 0xb5, + 0xd7, 0x7e, 0xfb, 0xd2, 0xfc, 0xec, 0xfe, 0x42, 0x9f, 0x4e, 0x7b, 0xbf, + 0x97, 0xbb, 0xb4, 0x3a, 0x93, 0x0b, 0x13, 0x61, 0x90, 0x0c, 0x3a, 0xce, + 0xf7, 0x8e, 0xef, 0x80, 0xf5, 0x4a, 0x92, 0xc5, 0xa5, 0x03, 0x78, 0xc2, + 0xee, 0xb8, 0x66, 0x60, 0x6b, 0x76, 0x4f, 0x32, 0x5a, 0x1a, 0xa2, 0x4b, + 0x7e, 0x2b, 0xa6, 0x1a, 0x89, 0x01, 0xe3, 0xbb, 0x55, 0x13, 0x7c, 0x4c, + 0xf4, 0x6a, 0x99, 0x94, 0xd1, 0xa0, 0x84, 0x1c, 0x1a, 0xc2, 0x7b, 0xb4, + 0xa0, 0xb0, 0x3b, 0xdc, 0x5a, 0x7b, 0xc7, 0xe0, 0x44, 0xb2, 0x1f, 0x46, + 0xd5, 0x8b, 0x39, 0x8b, 0xdc, 0x9e, 0xce, 0xa8, 0x7f, 0x85, 0x1d, 0x4b, + 0x63, 0x06, 0x1e, 0x8e, 0xe5, 0xe5, 0x99, 0xd9, 0xf7, 0x4d, 0x89, 0x0b, + 0x1d, 0x5c, 0x27, 0x33, 0x66, 0x21, 0xcf, 0x9a, 0xbd, 0x98, 0x68, 0x23, + 0x3a, 0x66, 0x9d, 0xd4, 0x46, 0xed, 0x63, 0x58, 0xf3, 0x42, 0xe4, 0x1d, + 0xe2, 0x47, 0x65, 0x13, 0x8d, 0xd4, 0x1f, 0x4b, 0x7e, 0xde, 0x11, 0x56, + 0xf8, 0x6d, 0x01, 0x0c, 0x99, 0xbd, 0x8d, 0xca, 0x8a, 0x2e, 0xe3, 0x8a, + 0x9c, 0x3d, 0x83, 0x8d, 0x69, 0x62, 0x8d, 0x05, 0xea, 0xb7, 0xf5, 0xa3, + 0x4b, 0xfc, 0x96, 0xcf, 0x18, 0x21, 0x0a, 0xc7, 0xf3, 0x23, 0x7e, 0x1c, + 0xab, 0xe2, 0xa2, 0xd1, 0x83, 0xc4, 0x25, 0x93, 0x37, 0x80, 0xca, 0xda, + 0xf0, 0xef, 0x7d, 0x94, 0xb5, 0x59, 0x02, 0xd4, 0x30, 0x82, 0x02, 0xd0, + 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x07, + 0x10, 0xaf, 0xc4, 0x1a, 0x3a, 0x56, 0x4f, 0xd8, 0xc2, 0xcc, 0x46, 0xd7, + 0x5b, 0xdf, 0x1c, 0x4e, 0x2f, 0x49, 0x3a, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x30, 0x13, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, + 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x73, + 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, + 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x88, + 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, 0x88, 0x06, + 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, 0xb4, 0xec, + 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, 0xe0, 0xd8, + 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, 0x6b, 0xe2, + 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, 0x7a, 0xa5, 0x5a, 0xa7, + 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 0x7e, 0xcd, 0x43, 0xfc, + 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, 0x49, 0xe4, + 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, 0x0f, 0xf1, + 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, 0x41, 0xee, + 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, 0xb0, 0x24, + 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, 0x90, 0x3d, + 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, 0x37, 0xd3, 0x88, 0x43, + 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 0xaa, 0x7e, 0x02, 0x90, + 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, 0x97, 0xad, + 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, 0xa3, 0x0c, + 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, 0x09, 0xef, + 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, 0x6f, 0x69, + 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, 0x9d, 0xab, + 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, 0x2c, 0xbf, 0x16, 0x8b, + 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 0xb3, 0xfe, 0x49, 0x23, + 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, 0x0a, 0x35, + 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x1d, 0x30, 0x1b, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, + 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, + 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5e, 0xba, 0x69, 0x55, + 0x9f, 0xf8, 0xeb, 0x16, 0x21, 0x98, 0xde, 0xb7, 0x31, 0x3e, 0x66, 0xe1, + 0x3b, 0x0c, 0x29, 0xf7, 0x48, 0x73, 0x05, 0xd9, 0xce, 0x5e, 0x4c, 0xbe, + 0x03, 0xc4, 0x51, 0xd6, 0x21, 0x92, 0x40, 0x38, 0xaa, 0x5b, 0x28, 0xb5, + 0xa1, 0x10, 0x52, 0x57, 0xff, 0x91, 0x54, 0x82, 0x86, 0x9e, 0x74, 0xd5, + 0x3d, 0x82, 0x29, 0xee, 0xd1, 0xcf, 0x93, 0xb1, 0x24, 0x76, 0xbb, 0x95, + 0x41, 0x06, 0x7e, 0x40, 0x9b, 0xb4, 0xab, 0x44, 0x34, 0x10, 0x8f, 0xb1, + 0x51, 0x6f, 0xc0, 0x89, 0xd1, 0xa3, 0xc4, 0x9f, 0xb3, 0x48, 0xe1, 0xcd, + 0x73, 0xad, 0xff, 0x42, 0x5f, 0x76, 0x05, 0x60, 0xc5, 0xe0, 0x45, 0x79, + 0x18, 0xa1, 0x19, 0xb8, 0xa7, 0x3a, 0x64, 0xb3, 0x19, 0xba, 0x14, 0xa1, + 0xb5, 0xdc, 0x32, 0xec, 0x09, 0x39, 0x58, 0x54, 0x5b, 0x04, 0xdc, 0x1b, + 0x66, 0x0d, 0x1d, 0x0d, 0xce, 0x7f, 0xfa, 0x24, 0x52, 0x6a, 0xad, 0xe2, + 0xc8, 0x30, 0xaf, 0xf2, 0xaf, 0x63, 0xc5, 0xe2, 0xbf, 0xe2, 0x20, 0x1b, + 0x9e, 0xf9, 0x3d, 0xbc, 0xfb, 0x04, 0x8e, 0xda, 0x7a, 0x1a, 0x5d, 0xd3, + 0x13, 0xd7, 0x00, 0x8e, 0x9b, 0x5d, 0x85, 0x51, 0xda, 0xd3, 0x91, 0x25, + 0xf5, 0x67, 0x85, 0x3e, 0x25, 0x89, 0x5e, 0xcb, 0x89, 0x8a, 0xec, 0x8a, + 0xde, 0x8b, 0xf4, 0x33, 0x5f, 0x76, 0xdb, 0x3d, 0xfc, 0x6a, 0x05, 0x21, + 0x43, 0xb2, 0x41, 0xd8, 0x33, 0x8d, 0xfd, 0x05, 0x5c, 0x22, 0x0a, 0xf6, + 0x90, 0x65, 0x9c, 0x4f, 0x8c, 0x44, 0x9f, 0x2d, 0xca, 0xf3, 0x49, 0x9c, + 0x3a, 0x14, 0x88, 0xab, 0xe4, 0xce, 0xb7, 0xbc, 0x95, 0x22, 0x2e, 0xb1, + 0x82, 0x4c, 0xbf, 0x83, 0x3e, 0x49, 0x72, 0x03, 0x2a, 0x68, 0xe7, 0x2d, + 0xe5, 0x2d, 0x4b, 0x61, 0xb0, 0x8d, 0x0d, 0x0c, 0x87, 0xc6, 0x5c, 0x51, + 0xa0, 0xf6, 0x82, 0x83, 0x59, 0x01, 0x33, 0xa2, 0x01, 0x26, 0x04, 0x59, + 0x01, 0x2c, 0x30, 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, + 0x13, 0x92, 0xd6, 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x69, 0x6e, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, + 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, + 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, + 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, + 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, + 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, + 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, + 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, + 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, + 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, + 0x36, 0x6b, 0x75, 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, + 0xc5, 0x89, 0xc1, 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, + 0xfa, 0x0b, 0xa0, 0x58, 0x40, 0xa3, 0xfb, 0x49, 0xe6, 0x45, 0x29, 0x64, + 0x76, 0xeb, 0x9d, 0xbd, 0xf5, 0x38, 0x56, 0xbe, 0x6e, 0x31, 0x57, 0x73, + 0xc1, 0x2d, 0x3e, 0xac, 0xee, 0xba, 0x55, 0x8e, 0x37, 0xd4, 0xea, 0x80, + 0x25, 0x31, 0x99, 0x9f, 0x4a, 0xb0, 0xf9, 0xd8, 0xb0, 0xed, 0x74, 0xfc, + 0x8c, 0x02, 0xf0, 0x9f, 0x95, 0xf1, 0xaa, 0x71, 0xcc, 0xd2, 0xe7, 0x1a, + 0x6d, 0xd4, 0xed, 0xff, 0xf2, 0x78, 0x09, 0x83, 0x7e, 0x83, 0x59, 0x02, + 0xbb, 0xa2, 0x01, 0x38, 0x24, 0x04, 0x59, 0x02, 0xb3, 0x30, 0x82, 0x02, + 0xaf, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, + 0x07, 0x1c, 0x3b, 0x71, 0x08, 0xbe, 0xd7, 0x9f, 0xfd, 0xaf, 0x26, 0xb6, + 0x08, 0xa3, 0x99, 0x06, 0x77, 0x69, 0x32, 0x7e, 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, + 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x11, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x65, 0x65, 0x2d, 0x72, 0x73, 0x61, + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, + 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, + 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, + 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, + 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, + 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, + 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, + 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, + 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, + 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, + 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, + 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, + 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, + 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, + 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, + 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, + 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, + 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, + 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, + 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, + 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, + 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, + 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x44, 0x92, 0xbb, 0x8e, 0x83, 0x58, 0x56, 0x2e, 0x7a, 0x86, 0xfa, 0x1d, + 0x77, 0x50, 0x3f, 0x45, 0x8d, 0x90, 0xc4, 0x62, 0x27, 0x21, 0x96, 0x5a, + 0xef, 0x51, 0x78, 0xd7, 0x7d, 0x0d, 0x02, 0x2d, 0x5a, 0x0e, 0x3c, 0x82, + 0x6f, 0x1d, 0x92, 0x87, 0xd5, 0x1a, 0x44, 0xae, 0xa7, 0x92, 0xd1, 0x8b, + 0xfa, 0x16, 0x53, 0x7f, 0xa3, 0x22, 0x96, 0x1a, 0x51, 0x8c, 0xeb, 0xa1, + 0xe6, 0xf6, 0x37, 0x11, 0xfe, 0x7d, 0x53, 0x3f, 0xae, 0xf0, 0x6b, 0xb9, + 0xb1, 0x7a, 0x73, 0x07, 0x14, 0xcf, 0x04, 0x05, 0x93, 0x9e, 0xe3, 0xd2, + 0x4d, 0x9d, 0x6d, 0x35, 0x68, 0xf9, 0x36, 0xe5, 0x10, 0x0a, 0x36, 0xd9, + 0x48, 0xb0, 0x83, 0xd0, 0xb9, 0x58, 0x74, 0x53, 0xb3, 0xbc, 0x99, 0xab, + 0xe1, 0x3e, 0xd5, 0x01, 0x8e, 0xcf, 0x3a, 0x69, 0x93, 0x9e, 0xa7, 0x88, + 0xd4, 0xad, 0x95, 0xf9, 0x2a, 0xb4, 0x7f, 0x95, 0x97, 0x86, 0x50, 0x38, + 0xb1, 0x04, 0x0a, 0xe4, 0x7a, 0xd5, 0x2d, 0x6c, 0xde, 0x3e, 0x1a, 0x47, + 0x17, 0x88, 0x63, 0x20, 0x9d, 0x21, 0x3e, 0x0c, 0x6f, 0xfd, 0x20, 0x54, + 0xd0, 0x67, 0xd2, 0x6b, 0x06, 0xfe, 0x60, 0x13, 0x42, 0x3d, 0xb7, 0xca, + 0xcb, 0xab, 0x7b, 0x5f, 0x5d, 0x01, 0x56, 0xd3, 0x99, 0x80, 0x0f, 0xde, + 0x7f, 0x3a, 0x61, 0x9c, 0xd3, 0x6b, 0x5e, 0xfe, 0xb5, 0xfc, 0x39, 0x8b, + 0x8e, 0xf0, 0x8c, 0x8b, 0x65, 0x46, 0x45, 0xff, 0x47, 0x8f, 0xd4, 0xdd, + 0xae, 0xc9, 0x72, 0xc7, 0x7f, 0x28, 0x86, 0xf1, 0xf7, 0x6e, 0xcb, 0x86, + 0x03, 0xeb, 0x0c, 0x46, 0xe5, 0xa0, 0x6b, 0xef, 0xd4, 0x5e, 0xa4, 0x0f, + 0x53, 0xe1, 0xbc, 0xb4, 0xc9, 0x37, 0x0e, 0x75, 0xdd, 0x93, 0xe8, 0x0f, + 0x18, 0x0a, 0x02, 0x83, 0x17, 0x74, 0xbb, 0x1a, 0x42, 0x5b, 0x63, 0x2c, + 0x80, 0x80, 0xa6, 0x84, 0xa0, 0x59, 0x01, 0x00, 0x51, 0xf4, 0xe6, 0x1c, + 0x18, 0x7b, 0x28, 0xa0, 0x1f, 0x63, 0xbf, 0xa5, 0xbd, 0x89, 0x9f, 0xd9, + 0x30, 0x46, 0x4b, 0x34, 0x9b, 0x9d, 0x0f, 0xb0, 0x33, 0x11, 0xf8, 0xaa, + 0x84, 0x4e, 0xb2, 0xca, 0x29, 0x83, 0x54, 0x28, 0x99, 0x2a, 0x43, 0x7f, + 0xe0, 0xe6, 0xd8, 0xdc, 0xd7, 0xf4, 0xb3, 0xd7, 0xf7, 0x39, 0xd5, 0xdc, + 0xde, 0xdc, 0x23, 0x78, 0xd7, 0x90, 0xc0, 0x52, 0xf5, 0xd2, 0x14, 0x6f, + 0xf9, 0x24, 0x48, 0xc8, 0x75, 0x4a, 0x9a, 0x4c, 0x61, 0x2f, 0x96, 0x4e, + 0xc8, 0x02, 0x95, 0x72, 0xef, 0xbc, 0x91, 0xae, 0xf8, 0x23, 0xfb, 0xba, + 0x9f, 0xfd, 0xe0, 0x1a, 0x8e, 0xa9, 0x03, 0x16, 0x76, 0xf4, 0xdb, 0x81, + 0x5a, 0x69, 0xeb, 0xf5, 0x55, 0xd7, 0x68, 0x28, 0xe4, 0xce, 0xde, 0x1b, + 0xb4, 0x90, 0xac, 0x97, 0x07, 0x15, 0xe0, 0xce, 0x5f, 0x3f, 0x89, 0xaf, + 0xc1, 0xb8, 0x46, 0x5e, 0x87, 0xa1, 0x8d, 0xa7, 0x44, 0x09, 0x02, 0x4e, + 0xbe, 0x6b, 0xfb, 0xab, 0xeb, 0x19, 0x62, 0x9e, 0xb0, 0xef, 0x0a, 0x6b, + 0xcf, 0xe0, 0x00, 0xa9, 0x68, 0x2a, 0x8e, 0xfe, 0x8a, 0xb9, 0x57, 0x52, + 0xb3, 0x08, 0x80, 0x5e, 0xa6, 0x88, 0x5f, 0x31, 0xd1, 0xe9, 0x6d, 0xf7, + 0x54, 0x4e, 0xf8, 0x17, 0xb0, 0x1c, 0xca, 0xa6, 0xa6, 0x80, 0xf8, 0xd8, + 0xf5, 0x94, 0xa4, 0xb2, 0xd0, 0x7e, 0xbb, 0x4f, 0xdb, 0x3a, 0x91, 0x5f, + 0xb3, 0xc1, 0xfa, 0x60, 0xe4, 0xce, 0xe3, 0xe5, 0x14, 0x1f, 0x9c, 0x01, + 0x60, 0xff, 0xe2, 0x09, 0xe6, 0x1a, 0x82, 0x69, 0xb6, 0xeb, 0x52, 0x1e, + 0x3d, 0xc7, 0xfd, 0x69, 0x9d, 0x2a, 0xa5, 0xdb, 0xc1, 0x6a, 0x5a, 0x7d, + 0x23, 0x2a, 0x00, 0xe4, 0x53, 0x16, 0x8e, 0xc1, 0x56, 0xf5, 0x5a, 0x8d, + 0x59, 0x1f, 0x7f, 0xff, 0x77, 0x6f, 0x92, 0xea, 0x5d, 0x31, 0xe9, 0x18}; + +// The RSA intermediate certificate that issued the EE cert used in the +// signature above. The certificate was generated with pycert.py +const uint8_t RSA_INT[] = { + 0x30, 0x82, 0x02, 0xd0, 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x07, 0x10, 0xaf, 0xc4, 0x1a, 0x3a, 0x56, 0x4f, 0xd8, + 0xc2, 0xcc, 0x46, 0xd7, 0x5b, 0xdf, 0x1c, 0x4e, 0x2f, 0x49, 0x3a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, + 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, + 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, + 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, + 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, + 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, + 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, + 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, + 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, + 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, + 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, + 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, + 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, + 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, + 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, + 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, + 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, + 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, + 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, + 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, + 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, + 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x5e, 0xba, 0x69, 0x55, 0x9f, 0xf8, 0xeb, 0x16, 0x21, 0x98, 0xde, 0xb7, + 0x31, 0x3e, 0x66, 0xe1, 0x3b, 0x0c, 0x29, 0xf7, 0x48, 0x73, 0x05, 0xd9, + 0xce, 0x5e, 0x4c, 0xbe, 0x03, 0xc4, 0x51, 0xd6, 0x21, 0x92, 0x40, 0x38, + 0xaa, 0x5b, 0x28, 0xb5, 0xa1, 0x10, 0x52, 0x57, 0xff, 0x91, 0x54, 0x82, + 0x86, 0x9e, 0x74, 0xd5, 0x3d, 0x82, 0x29, 0xee, 0xd1, 0xcf, 0x93, 0xb1, + 0x24, 0x76, 0xbb, 0x95, 0x41, 0x06, 0x7e, 0x40, 0x9b, 0xb4, 0xab, 0x44, + 0x34, 0x10, 0x8f, 0xb1, 0x51, 0x6f, 0xc0, 0x89, 0xd1, 0xa3, 0xc4, 0x9f, + 0xb3, 0x48, 0xe1, 0xcd, 0x73, 0xad, 0xff, 0x42, 0x5f, 0x76, 0x05, 0x60, + 0xc5, 0xe0, 0x45, 0x79, 0x18, 0xa1, 0x19, 0xb8, 0xa7, 0x3a, 0x64, 0xb3, + 0x19, 0xba, 0x14, 0xa1, 0xb5, 0xdc, 0x32, 0xec, 0x09, 0x39, 0x58, 0x54, + 0x5b, 0x04, 0xdc, 0x1b, 0x66, 0x0d, 0x1d, 0x0d, 0xce, 0x7f, 0xfa, 0x24, + 0x52, 0x6a, 0xad, 0xe2, 0xc8, 0x30, 0xaf, 0xf2, 0xaf, 0x63, 0xc5, 0xe2, + 0xbf, 0xe2, 0x20, 0x1b, 0x9e, 0xf9, 0x3d, 0xbc, 0xfb, 0x04, 0x8e, 0xda, + 0x7a, 0x1a, 0x5d, 0xd3, 0x13, 0xd7, 0x00, 0x8e, 0x9b, 0x5d, 0x85, 0x51, + 0xda, 0xd3, 0x91, 0x25, 0xf5, 0x67, 0x85, 0x3e, 0x25, 0x89, 0x5e, 0xcb, + 0x89, 0x8a, 0xec, 0x8a, 0xde, 0x8b, 0xf4, 0x33, 0x5f, 0x76, 0xdb, 0x3d, + 0xfc, 0x6a, 0x05, 0x21, 0x43, 0xb2, 0x41, 0xd8, 0x33, 0x8d, 0xfd, 0x05, + 0x5c, 0x22, 0x0a, 0xf6, 0x90, 0x65, 0x9c, 0x4f, 0x8c, 0x44, 0x9f, 0x2d, + 0xca, 0xf3, 0x49, 0x9c, 0x3a, 0x14, 0x88, 0xab, 0xe4, 0xce, 0xb7, 0xbc, + 0x95, 0x22, 0x2e, 0xb1, 0x82, 0x4c, 0xbf, 0x83, 0x3e, 0x49, 0x72, 0x03, + 0x2a, 0x68, 0xe7, 0x2d, 0xe5, 0x2d, 0x4b, 0x61, 0xb0, 0x8d, 0x0d, 0x0c, + 0x87, 0xc6, 0x5c, 0x51}; + +// The RSA root certificate that issued the RSA intermediate certificate above. +// The certificate was generated with pycert.py +const uint8_t RSA_ROOT[] = { + 0x30, 0x82, 0x02, 0xd1, 0x30, 0x82, 0x01, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x29, 0x6c, 0x1a, 0xd8, 0x20, 0xcd, 0x74, 0x6d, 0x4b, + 0x00, 0xf3, 0x16, 0x88, 0xd9, 0x66, 0x87, 0x5f, 0x28, 0x56, 0x6a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, + 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, + 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, + 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, + 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, + 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, + 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, + 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, + 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, + 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, + 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, + 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, + 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, + 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, + 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, + 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, + 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, + 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, + 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, + 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, + 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, + 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x2f, 0x9f, 0x72, 0xeb, 0x70, 0x6d, 0x9e, 0x3e, 0x9f, 0xd7, + 0x9c, 0xd9, 0x19, 0x7c, 0x99, 0x07, 0xc5, 0x5c, 0x9d, 0xf5, 0x66, 0x9f, + 0x28, 0x8d, 0xfe, 0x0e, 0x3f, 0x38, 0x75, 0xed, 0xee, 0x4e, 0x3f, 0xf6, + 0x6e, 0x35, 0xe0, 0x95, 0x3f, 0x08, 0x4a, 0x71, 0x5a, 0xf2, 0x4f, 0xc9, + 0x96, 0x61, 0x8d, 0x45, 0x4b, 0x97, 0x85, 0xff, 0xb0, 0xe3, 0xbb, 0xb5, + 0xd7, 0x7e, 0xfb, 0xd2, 0xfc, 0xec, 0xfe, 0x42, 0x9f, 0x4e, 0x7b, 0xbf, + 0x97, 0xbb, 0xb4, 0x3a, 0x93, 0x0b, 0x13, 0x61, 0x90, 0x0c, 0x3a, 0xce, + 0xf7, 0x8e, 0xef, 0x80, 0xf5, 0x4a, 0x92, 0xc5, 0xa5, 0x03, 0x78, 0xc2, + 0xee, 0xb8, 0x66, 0x60, 0x6b, 0x76, 0x4f, 0x32, 0x5a, 0x1a, 0xa2, 0x4b, + 0x7e, 0x2b, 0xa6, 0x1a, 0x89, 0x01, 0xe3, 0xbb, 0x55, 0x13, 0x7c, 0x4c, + 0xf4, 0x6a, 0x99, 0x94, 0xd1, 0xa0, 0x84, 0x1c, 0x1a, 0xc2, 0x7b, 0xb4, + 0xa0, 0xb0, 0x3b, 0xdc, 0x5a, 0x7b, 0xc7, 0xe0, 0x44, 0xb2, 0x1f, 0x46, + 0xd5, 0x8b, 0x39, 0x8b, 0xdc, 0x9e, 0xce, 0xa8, 0x7f, 0x85, 0x1d, 0x4b, + 0x63, 0x06, 0x1e, 0x8e, 0xe5, 0xe5, 0x99, 0xd9, 0xf7, 0x4d, 0x89, 0x0b, + 0x1d, 0x5c, 0x27, 0x33, 0x66, 0x21, 0xcf, 0x9a, 0xbd, 0x98, 0x68, 0x23, + 0x3a, 0x66, 0x9d, 0xd4, 0x46, 0xed, 0x63, 0x58, 0xf3, 0x42, 0xe4, 0x1d, + 0xe2, 0x47, 0x65, 0x13, 0x8d, 0xd4, 0x1f, 0x4b, 0x7e, 0xde, 0x11, 0x56, + 0xf8, 0x6d, 0x01, 0x0c, 0x99, 0xbd, 0x8d, 0xca, 0x8a, 0x2e, 0xe3, 0x8a, + 0x9c, 0x3d, 0x83, 0x8d, 0x69, 0x62, 0x8d, 0x05, 0xea, 0xb7, 0xf5, 0xa3, + 0x4b, 0xfc, 0x96, 0xcf, 0x18, 0x21, 0x0a, 0xc7, 0xf3, 0x23, 0x7e, 0x1c, + 0xab, 0xe2, 0xa2, 0xd1, 0x83, 0xc4, 0x25, 0x93, 0x37, 0x80, 0xca, 0xda, + 0xf0, 0xef, 0x7d, 0x94, 0xb5}; + +// The P256 intermediate certificate that issued the EE cert used in the +// signatures above. The certificate was generated with pycert.py +const uint8_t P256_INT[] = { + 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, 0xec, + 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, 0x74, + 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, + 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, + 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, + 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, + 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, + 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, + 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, 0xd1, + 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, 0x5c, + 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, 0x20, + 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, 0x56, + 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, 0x20, + 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7}; + +// The P256 root certificate that issued the P256 intermediate certificate +// above. The certificate was generated with pycert.py +const uint8_t P256_ROOT[] = { + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b}; + +void check_hard_coded_certs(const uint8_t** cert_chain, size_t cert_chain_len, + const size_t* certs_len) { + // Very hacky and fragile check that the intermediate certs are correct. + switch (cert_chain_len) { + case 2: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + break; + } + case 4: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + cert = cert_chain[2]; + cert_len = certs_len[2]; + ASSERT_EQ(cert_len, sizeof(RSA_ROOT)); + ASSERT_EQ(0, memcmp(cert, RSA_ROOT, cert_len)); + cert = cert_chain[3]; + cert_len = certs_len[3]; + ASSERT_EQ(cert_len, sizeof(RSA_INT)); + ASSERT_EQ(0, memcmp(cert, RSA_INT, cert_len)); + break; + } + default: + // In this case something went wrong. + ASSERT_EQ(true, false); + } +} + +/* Verification function called from cose-rust. + * Returns true if everything goes well and the signature is good, false in any + * other case. */ +bool verify_callback(const uint8_t* payload, size_t payload_len, + const uint8_t** cert_chain, size_t cert_chain_len, + const size_t* certs_len, const uint8_t* ee_cert, + size_t ee_cert_len, const uint8_t* signature, + size_t signature_len, uint8_t signature_algorithm, + void* ctx) { + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return false; + } + + CK_MECHANISM_TYPE mechanism; + SECOidTag oid; + uint32_t hash_length; + SECItem param = {siBuffer, nullptr, 0}; + CK_RSA_PKCS_PSS_PARAMS rsa_pss_params = {CKM_SHA256, CKG_MGF1_SHA256, + SHA256_LENGTH}; + switch (signature_algorithm) { + case (ES256): + mechanism = CKM_ECDSA; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + break; + case (PS256): + mechanism = CKM_RSA_PKCS_PSS; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + param = {siBuffer, reinterpret_cast<unsigned char*>(&rsa_pss_params), + sizeof(rsa_pss_params)}; + break; + default: + return false; + } + check_hard_coded_certs(cert_chain, cert_chain_len, certs_len); + + uint8_t hash_buf[HASH_LENGTH_MAX]; + SECStatus rv = PK11_HashBuf(oid, hash_buf, payload, payload_len); + if (rv != SECSuccess) { + return false; + } + SECItem hash_item = {siBuffer, hash_buf, hash_length}; + CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); + if (!db_handle) { + return false; + } + SECItem der_cert = {siBuffer, const_cast<uint8_t*>(ee_cert), + static_cast<unsigned int>(ee_cert_len)}; + UniqueCERTCertificate cert( + CERT_NewTempCertificate(db_handle, &der_cert, nullptr, false, true)); + if (!cert) { + return false; + } + UniqueSECKEYPublicKey key(CERT_ExtractPublicKey(cert.get())); + if (!key) { + return false; + } + SECItem signature_item = {siBuffer, const_cast<uint8_t*>(signature), + static_cast<unsigned int>(signature_len)}; + rv = PK11_VerifyWithMechanism(key.get(), mechanism, ¶m, &signature_item, + &hash_item, nullptr); + if (rv != SECSuccess) { + return false; + } + + return true; +} + +class psm_COSE : public ::testing::Test {}; + +TEST_F(psm_COSE, CoseTestingSingleSignature) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = + verify_cose_signature_ffi(PAYLOAD, sizeof(PAYLOAD), SIGNATURE, + sizeof(SIGNATURE), nullptr, verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingTwoSignatures) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = verify_cose_signature_ffi( + PAYLOAD, sizeof(PAYLOAD), SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), nullptr, verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingAlteredPayload) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + uint8_t altered_payload[20] = {84, 104, 105, 115, 32, 104, 115, + 32, 116, 104, 101, 32, 99, 111, + 110, 116, 101, 110, 116, 46}; + bool result = verify_cose_signature_ffi( + altered_payload, sizeof(altered_payload), SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), nullptr, verify_callback); + ASSERT_FALSE(result); +} + +} // namespace mozilla diff --git a/security/manager/ssl/tests/gtest/DataStorageTest.cpp b/security/manager/ssl/tests/gtest/DataStorageTest.cpp new file mode 100644 index 0000000000..791ef87f7d --- /dev/null +++ b/security/manager/ssl/tests/gtest/DataStorageTest.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "gtest/gtest.h" + +#include "mozilla/DataStorage.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsNetUtil.h" +#include "nsPrintfCString.h" +#include "nsStreamUtils.h" +#include "prtime.h" + +using namespace mozilla; + +class psm_DataStorageTest : public ::testing::Test { + protected: + void SetUp() override { + const ::testing::TestInfo* const testInfo = + ::testing::UnitTest::GetInstance()->current_test_info(); + NS_ConvertUTF8toUTF16 testName(testInfo->name()); + storage = DataStorage::GetFromRawFileName(testName); + storage->Init(nullptr); + } + + RefPtr<DataStorage> storage; +}; + +constexpr auto testKey = "test"_ns; +constexpr auto testValue = "value"_ns; +constexpr auto privateTestValue = "private"_ns; + +TEST_F(psm_DataStorageTest, GetPutRemove) { + // Test Put/Get on Persistent data + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + // Don't re-use testKey / testValue here, to make sure that this works as + // expected with objects that have the same semantic value but are not + // literally the same object. + nsCString result = storage->Get("test"_ns, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + + // Get on Temporary/Private data with the same key should give nothing + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_TRUE(result.IsEmpty()); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); + + // Put with Temporary/Private data shouldn't affect Persistent data + constexpr auto temporaryTestValue = "temporary"_ns; + EXPECT_EQ(NS_OK, + storage->Put(testKey, temporaryTestValue, DataStorage_Temporary)); + EXPECT_EQ(NS_OK, + storage->Put(testKey, privateTestValue, DataStorage_Private)); + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_STREQ("temporary", result.get()); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + + // Put of a previously-present key overwrites it (if of the same type) + constexpr auto newValue = "new"_ns; + EXPECT_EQ(NS_OK, storage->Put(testKey, newValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("new", result.get()); + + // Removal should work + storage->Remove(testKey, DataStorage_Temporary); + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_TRUE(result.IsEmpty()); + // But removing one type shouldn't affect the others + result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("new", result.get()); + // Test removing the other types as well + storage->Remove(testKey, DataStorage_Private); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); + storage->Remove(testKey, DataStorage_Persistent); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, InputValidation) { + // Keys may not have tabs or newlines + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put("key\thas tab"_ns, testValue, DataStorage_Persistent)); + nsCString result = storage->Get("key\thas tab"_ns, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + EXPECT_EQ(NS_ERROR_INVALID_ARG, storage->Put("key has\nnewline"_ns, testValue, + DataStorage_Persistent)); + result = storage->Get("keyhas\nnewline"_ns, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + // Values may not have newlines + EXPECT_EQ(NS_ERROR_INVALID_ARG, storage->Put(testKey, "value\nhas newline"_ns, + DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + // Values may have tabs + EXPECT_TRUE(result.IsEmpty()); + EXPECT_EQ(NS_OK, storage->Put(testKey, "val\thas tab; this is ok"_ns, + DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("val\thas tab; this is ok", result.get()); + + nsCString longKey("a"); + for (int i = 0; i < 8; i++) { + longKey.Append(longKey); + } + // A key of length 256 will work + EXPECT_EQ(NS_OK, storage->Put(longKey, testValue, DataStorage_Persistent)); + result = storage->Get(longKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + longKey.AppendLiteral("a"); + // A key longer than that will not work + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put(longKey, testValue, DataStorage_Persistent)); + result = storage->Get(longKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + + nsCString longValue("a"); + for (int i = 0; i < 10; i++) { + longValue.Append(longValue); + } + // A value of length 1024 will work + EXPECT_EQ(NS_OK, storage->Put(testKey, longValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ(longValue.get(), result.get()); + longValue.AppendLiteral("a"); + // A value longer than that will not work + storage->Remove(testKey, DataStorage_Persistent); + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put(testKey, longValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, Eviction) { + // Eviction is on a per-table basis. Tables shouldn't affect each other. + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + for (int i = 0; i < 1025; i++) { + EXPECT_EQ(NS_OK, + storage->Put(nsPrintfCString("%d", i), nsPrintfCString("%d", i), + DataStorage_Temporary)); + nsCString result = + storage->Get(nsPrintfCString("%d", i), DataStorage_Temporary); + EXPECT_STREQ(nsPrintfCString("%d", i).get(), result.get()); + } + // We don't know which entry got evicted, but we can count them. + int entries = 0; + for (int i = 0; i < 1025; i++) { + nsCString result = + storage->Get(nsPrintfCString("%d", i), DataStorage_Temporary); + if (!result.IsEmpty()) { + entries++; + } + } + EXPECT_EQ(entries, 1024); + nsCString result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); +} + +TEST_F(psm_DataStorageTest, ClearPrivateData) { + EXPECT_EQ(NS_OK, + storage->Put(testKey, privateTestValue, DataStorage_Private)); + nsCString result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + storage->Observe(nullptr, "last-pb-context-exited", nullptr); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, Shutdown) { + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + nsCString result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + // Get "now" (in days) close to when the data was last touched, so we won't + // get intermittent failures with the day not matching. + int64_t microsecondsPerDay = 24 * 60 * 60 * int64_t(PR_USEC_PER_SEC); + int32_t nowInDays = int32_t(PR_Now() / microsecondsPerDay); + // Simulate shutdown. + storage->Observe(nullptr, "profile-before-change", nullptr); + nsCOMPtr<nsIFile> backingFile; + EXPECT_EQ(NS_OK, NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(backingFile))); + const ::testing::TestInfo* const testInfo = + ::testing::UnitTest::GetInstance()->current_test_info(); + NS_ConvertUTF8toUTF16 testName(testInfo->name()); + EXPECT_EQ(NS_OK, backingFile->Append(testName)); + nsCOMPtr<nsIInputStream> fileInputStream; + EXPECT_EQ(NS_OK, NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), + backingFile)); + nsCString data; + EXPECT_EQ(NS_OK, NS_ConsumeStream(fileInputStream, UINT32_MAX, data)); + // The data will be of the form 'test\t0\t<days since the epoch>\tvalue' + EXPECT_STREQ(nsPrintfCString("test\t0\t%d\tvalue\n", nowInDays).get(), + data.get()); +} diff --git a/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp new file mode 100644 index 0000000000..005dc03ea6 --- /dev/null +++ b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsISimpleEnumerator.h" +#include "nsITransportSecurityInfo.h" +#include "nsIX509Cert.h" +#include "nsSerializationHelper.h" +#include "nsString.h" + +// nsITransportSecurityInfo de-serializatin tests +// +// These tests verify that we can still deserialize old binary strings +// generated for security info. This is necessary because service workers +// stores these strings on disk. +// +// If you make a change and start breaking these tests, you will need to +// add a compat fix for loading the old versions. For things that affect +// the UUID, but do not break the rest of the format you can simply add +// another hack condition in nsBinaryInputStream::ReadObject(). If you +// change the overall format of the serialization then we will need more +// complex handling in the security info concrete classes. +// +// We would like to move away from this binary compatibility requirement +// in service workers. See bug 1248628. +void deserializeAndVerify(const nsCString& serializedSecInfo, + bool hasFailedCertChain, + size_t failedCertChainLength = 0) { + nsCOMPtr<nsISupports> secInfo; + nsresult rv = + NS_DeserializeObject(serializedSecInfo, getter_AddRefs(secInfo)); + ASSERT_EQ(NS_OK, rv); + ASSERT_TRUE(secInfo); + + nsCOMPtr<nsITransportSecurityInfo> securityInfo = do_QueryInterface(secInfo); + ASSERT_TRUE(securityInfo); + + nsCOMPtr<nsIX509Cert> cert; + rv = securityInfo->GetServerCert(getter_AddRefs(cert)); + ASSERT_EQ(NS_OK, rv); + ASSERT_TRUE(cert); + + nsTArray<RefPtr<nsIX509Cert>> failedCertArray; + rv = securityInfo->GetFailedCertChain(failedCertArray); + ASSERT_EQ(NS_OK, rv); + + if (hasFailedCertChain) { + ASSERT_FALSE(failedCertArray.IsEmpty()); + for (const auto& cert : failedCertArray) { + ASSERT_TRUE(cert); + } + ASSERT_EQ(failedCertChainLength, failedCertArray.Length()); + } else { + ASSERT_TRUE(failedCertArray.IsEmpty()); + } +} + +TEST(psm_DeserializeCert, gecko33) +{ + // clang-format off + // Gecko 33+ vintage Security info serialized with UUIDs: + // - nsISupports 00000000-0000-0000-c000-000000000046 + // - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8 + // - nsIX509Cert f8ed8364-ced9-4c6e-86ba-48af53c393e6 + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAQAAgAAAAAAAAAAAAAAAAAAAAA" + "B4vFIJp5wRkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8F+O2DZM7ZTG6GukivU8OT5gAAAAIAAAWpMII" + "FpTCCBI2gAwIBAgIQD4svsaKEC+QtqtsU2TF8ITANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUN" + "lcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFN" + "lcnZlciBDQTAeFw0xNTAyMjMwMDAwMDBaFw0xNjAzMDIxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMRYwFAYDVQQHEw1TYW4gRnJhbmN" + "pc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRUwEwYDVQQKEwxGYXN0bHksIEluYy4xFzAVBgNVBAMTDnd3dy5naXRodWIuY29tMII" + "BIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+9WUCgrgUNwP/JC3cUefLAXeDpq8Ko/U8p8IRvny0Ri0I6Uq0t+RP/nF0LJ" + "Avda8QHYujdgeDTePepBX7+OiwBFhA0YO+rM3C2Z8IRaN/i9eLln+Yyc68+1z+E10s1EXdZrtDGvN6MHqygGsdfkXKfBLUJ1BZEh" + "s9sBnfcjq3kh5gZdBArdG9l5NpdmQhtceaFGsPiWuJxGxRzS4i95veUHWkhMpEYDEEBdcDGxqArvQCvzSlngdttQCfx8OUkBTb3B" + "A2okpTwwJfqPsxVetA6qR7UNc+fVb6KHwvm0bzi2rQ3xw3D/syRHwdMkpoVDQPCk43H9WufgfBKRen87dFwIDAQABo4ICPzCCAjs" + "wHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFGS/RLNGCZvPWh1xSaIEcouINIQjMHsGA1UdEQR0MHK" + "CDnd3dy5naXRodWIuY29tggpnaXRodWIuY29tggwqLmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvgglnaXRodWIuaW+CFyouZ2l0aHV" + "idXNlcmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwM" + "BBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3J" + "sMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb" + "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQc" + "wAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUN" + "lcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAc4dbVmuKvyI7" + "KZ4Txk+ZqcAYToJGKUIVaPL94e5SZGweUisjaCbplAOihnf6Mxt8n6vnuH2IsCaz2NRHqhdcosjT3CwAiJpJNkXPKWVL/txgdSTV" + "2cqB1GG4esFOalvI52dzn+J4fTIYZvNF+AtGyHSLm2XRXYZCw455laUKf6Sk9RDShDgUvzhOKL4GXfTwKXv12MyMknJybH8UCpjC" + "HZmFBVHMcUN/87HsQo20PdOekeEvkjrrMIxW+gxw22Yb67yF/qKgwrWr+43bLN709iyw+LWiU7sQcHL2xk9SYiWQDj2tYz2soObV" + "QYTJm0VUZMEVFhtALq46cx92Zu4vFwC8AAwAAAAABAQAA"); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, gecko46) +{ + // clang-format off + // Gecko 46+ vintage Security info serialized with UUIDs: + // - nsISupports 00000000-0000-0000-c000-000000000046 + // - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8 + // - nsIX509Cert bdc3979a-5422-4cd5-8589-696b6e96ea83 + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAQAAgAAAAAAAAAAAAAAAAAAAAA" + "B4vFIJp5wRkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAIAAAWzMII" + "FrzCCBJegAwIBAgIQB3pdwzYjAfmJ/lT3+G8+ZDANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUN" + "lcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFN" + "lcnZlciBDQTAeFw0xNjAxMjAwMDAwMDBaFw0xNzA0MDYxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybml" + "hMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxGYXN0bHksIEluYy4xFzAVBgNVBAMTDnd3dy5naXRodWIuY29tMII" + "BIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+9WUCgrgUNwP/JC3cUefLAXeDpq8Ko/U8p8IRvny0Ri0I6Uq0t+RP/nF0LJ" + "Avda8QHYujdgeDTePepBX7+OiwBFhA0YO+rM3C2Z8IRaN/i9eLln+Yyc68+1z+E10s1EXdZrtDGvN6MHqygGsdfkXKfBLUJ1BZEh" + "s9sBnfcjq3kh5gZdBArdG9l5NpdmQhtceaFGsPiWuJxGxRzS4i95veUHWkhMpEYDEEBdcDGxqArvQCvzSlngdttQCfx8OUkBTb3B" + "A2okpTwwJfqPsxVetA6qR7UNc+fVb6KHwvm0bzi2rQ3xw3D/syRHwdMkpoVDQPCk43H9WufgfBKRen87dFwIDAQABo4ICSTCCAkU" + "wHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFGS/RLNGCZvPWh1xSaIEcouINIQjMHsGA1UdEQR0MHK" + "CDnd3dy5naXRodWIuY29tggwqLmdpdGh1Yi5jb22CCmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvgglnaXRodWIuaW+CFyouZ2l0aHV" + "idXNlcmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwM" + "BBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3J" + "sMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb" + "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHU" + "wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQ" + "uY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQE" + "ATxbRdPg+o49+96/P+rbdp4ie+CGtfCgUubT/Z9C54k+BfQO0nbxVgCSM5WZQuLgo2Q+0lcxisod8zxZeU0j5wviQINwOln/iN89" + "Bx3VmDRynTe4CqhsAwOoO1ERmCAmsAJBwY/rNr4mK22p8erBrqMW0nYXYU5NFynI+pNTjojhKD4II8PNV8G2yMWwYOb/u4+WPzUA" + "HC9DpZdrWTEH/W69Cr/KxRqGsWPwpgMv2Wqav8jaT35JxqTXjOlhQqzo6fNn3eYOeCf4PkCxZKwckWjy10qDaRbjhwAMHAGj2TPr" + "idlvOj/7QyyX5m8up/1US8z1fRW4yoCSOt6V2bwuH6cAvAAMAAAAAAQEAAA=="); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, preSSLStatusConsolidation) +{ + // clang-format off + // Generated using serialized output of test "good.include-subdomains.pinning.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAgAAgAAAAAAAAAAAAAAAAAAAAAB4vFIJp5w" + "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAONMIIDiTCCAnGg" + "AwIBAgIUWbWLTwLBvfwcoiU7I8lDz9snfUgwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE2MTEyNzAw" + "MDAwMFoYDzIwMTkwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw" + "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV" + "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o" + "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0" + "gg0qLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs" + "ZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAB" + "hhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQBE+6IPJK5OeonoQPC4CCWMd69SjhwS7X6TNgxDJzW7" + "qpVm4SFyYZ2xqzr2zib5LsYek6/jok5LPSpJVeFuSeiesvGMxk0O4ZEihPxSM4uR4xpCnPzz7LoFIzMELJv5i+cgLw4+6cINPkLj" + "oCUdb+AXSTur7THJaO75B44I2JjJfMfzgW1FwoWgXL/PQWRw+VY6OY1glqZOXzP+vfSja1SoggpiCzdPx7h1/SEEZov7zhCZXv1C" + "enx1njlpcj9wWEJMsyZczMNtiz5GkRrLaqCz9F8ah3NvkvPAZ0oOqtxuQgMXK/c0OXJVKi0SCJsWqZDoZhCrS/dE9guxlseZqhSI" + "wC8DAwAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+xZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgA" + "AAACZgoyJpFcT/u7IImFpjLfBb3Dl5pUIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFFm1i08Cwb38HKIlOyPJQ8/b" + "J31IMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNjExMjcwMDAwMDBaGA8yMDE5MDIwNTAwMDAwMFow" + "GjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2" + "ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC" + "a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk" + "zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+" + "SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbYIVKi5waW5u" + "aW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZG9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9t" + "YWlucy5waW5uaW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4" + "LzANBgkqhkiG9w0BAQsFAAOCAQEARPuiDySuTnqJ6EDwuAgljHevUo4cEu1+kzYMQyc1u6qVZuEhcmGdsas69s4m+S7GHpOv46JO" + "Sz0qSVXhbknonrLxjMZNDuGRIoT8UjOLkeMaQpz88+y6BSMzBCyb+YvnIC8OPunCDT5C46AlHW/gF0k7q+0xyWju+QeOCNiYyXzH" + "84FtRcKFoFy/z0FkcPlWOjmNYJamTl8z/r30o2tUqIIKYgs3T8e4df0hBGaL+84QmV79Qnp8dZ45aXI/cFhCTLMmXMzDbYs+RpEa" + "y2qgs/RfGodzb5LzwGdKDqrcbkIDFyv3NDlyVSotEgibFqmQ6GYQq0v3RPYLsZbHmaoUiGYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM" + "1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYD" + "VQQDDAdUZXN0IENBMCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0G" + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr" + "4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk" + "fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo" + "4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQF" + "MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK" + "9cZFVtzRWYEYkIlicAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK9" + "22MsOsnrLjNlpRDmuH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZB" + "bEw7P6+V9zz5cAzaaq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAAA="); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, preSSLStatusConsolidationFailedCertChain) +{ + // clang-format off + // Generated using serialized output of test "expired.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAAAAAAAAAAA///gCwAAAAAB4vFIJp5w" + "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAMgMIIDHDCCAgSg" + "AwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAw" + "MDAwMFoYDzIwMTQwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEB" + "BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6" + "pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9" + "0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK" + "lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJl" + "ZC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcN" + "AQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7" + "IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l" + "297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6" + "laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7IAAAMAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vY" + "kTvlMZeudM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKAD" + "AgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAw" + "MDAwWhgPMjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEF" + "AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql" + "WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S" + "O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV" + "YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVk" + "LmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0B" + "AQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4Xsg" + "Aw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb" + "3tlpKXSdsp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qV" + "oHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAA" + "AAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENB" + "MCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa" + "p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7" + "xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh" + "He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P" + "BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIli" + "cAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDm" + "uH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAza" + "aq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAZWfsWVlF0h/q5vYkTvlMZeu" + "dM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKADAgECAhRj" + "0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgP" + "MjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A" + "MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc" + "1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf" + "qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl" + "nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1w" + "bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOC" + "AQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvk" + "VV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSd" + "sp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qVoHRS/lbq" + "5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcw" + "ggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIw" + "MTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw" + "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV" + "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o" + "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEG" + "MA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIlicAyTiPw3" + "4bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDmuH0VFhb5" + "uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAzaaq7EB0mC" + "E+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBC"); + // clang-format on + + deserializeAndVerify(base64Serialization, true, 2); +} diff --git a/security/manager/ssl/tests/gtest/MD4Test.cpp b/security/manager/ssl/tests/gtest/MD4Test.cpp new file mode 100644 index 0000000000..6e28e6dbc4 --- /dev/null +++ b/security/manager/ssl/tests/gtest/MD4Test.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +// This file tests the md4.c implementation. + +#include "gtest/gtest.h" +#include "md4.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Casting.h" + +struct RFC1320TestParams { + const char* data; + const uint8_t expectedHash[16]; +}; + +static const RFC1320TestParams RFC1320_TEST_PARAMS[] = { + {"", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, + 0xe0, 0xc0, 0x89, 0xc0}}, + {"a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05, 0xfb, + 0xdb, 0xd6, 0xfb, 0x24}}, + {"abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, + 0x7a, 0xa6, 0x72, 0x9d}}, + {"message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, + 0xe1, 0xc7, 0x01, 0x4b}}, + { + "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, + 0xdf, 0x41, 0x2d, 0xa9}, + }, + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, + 0x53, 0xe7, 0xf0, 0xe4}, + }, + { + "1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, + 0x4f, 0xcc, 0x05, 0x36}, + }}; + +class psm_MD4 : public ::testing::Test, + public ::testing::WithParamInterface<RFC1320TestParams> {}; + +TEST_P(psm_MD4, RFC1320TestValues) { + const RFC1320TestParams& params(GetParam()); + uint8_t actualHash[16]; + md4sum(mozilla::BitwiseCast<const uint8_t*, const char*>(params.data), + strlen(params.data), actualHash); + EXPECT_TRUE(mozilla::ArrayEqual(actualHash, params.expectedHash)) + << "MD4 hashes aren't equal for input: '" << params.data << "'"; +} + +INSTANTIATE_TEST_CASE_P(psm_MD4, psm_MD4, + testing::ValuesIn(RFC1320_TEST_PARAMS)); diff --git a/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp new file mode 100644 index 0000000000..77e9368ff6 --- /dev/null +++ b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp @@ -0,0 +1,321 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "CertVerifier.h" +#include "OCSPCache.h" +#include "gtest/gtest.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/Casting.h" +#include "mozilla/Sprintf.h" +#include "nss.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/test/pkixtestutil.h" +#include "prerr.h" +#include "secerr.h" + +using namespace mozilla::pkix; +using namespace mozilla::pkix::test; + +using mozilla::OriginAttributes; + +template <size_t N> +inline Input LiteralInput(const char (&valueString)[N]) { + // Ideally we would use mozilla::BitwiseCast() here rather than + // reinterpret_cast for better type checking, but the |N - 1| part trips + // static asserts. + return Input(reinterpret_cast<const uint8_t(&)[N - 1]>(valueString)); +} + +const int MaxCacheEntries = 1024; + +class psm_OCSPCacheTest : public ::testing::Test { + protected: + psm_OCSPCacheTest() : now(Now()) {} + + static void SetUpTestCase() { NSS_NoDB_Init(nullptr); } + + const Time now; + mozilla::psm::OCSPCache cache; +}; + +static void PutAndGet( + mozilla::psm::OCSPCache& cache, const CertID& certID, Result result, + Time time, const OriginAttributes& originAttributes = OriginAttributes()) { + // The first time is thisUpdate. The second is validUntil. + // The caller is expecting the validUntil returned with Get + // to be equal to the passed-in time. Since these values will + // be different in practice, make thisUpdate less than validUntil. + Time thisUpdate(time); + ASSERT_EQ(Success, thisUpdate.SubtractSeconds(10)); + Result rv = cache.Put(certID, originAttributes, result, thisUpdate, time); + ASSERT_TRUE(rv == Success); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, originAttributes, resultOut, timeOut)); + ASSERT_EQ(result, resultOut); + ASSERT_EQ(time, timeOut); +} + +Input fakeIssuer1(LiteralInput("CN=issuer1")); +Input fakeKey000(LiteralInput("key000")); +Input fakeKey001(LiteralInput("key001")); +Input fakeSerial0000(LiteralInput("0000")); + +TEST_F(psm_OCSPCacheTest, TestPutAndGet) { + Input fakeSerial000(LiteralInput("000")); + Input fakeSerial001(LiteralInput("001")); + + SCOPED_TRACE(""); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial001), Success, + now); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial000), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestVariousGets) { + SCOPED_TRACE(""); + for (int i = 0; i < MaxCacheEntries; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + + Time timeIn(now); + Result resultOut; + Time timeOut(Time::uninitialized); + + // This will be at the end of the list in the cache + CertID cert0000(fakeIssuer1, fakeKey000, fakeSerial0000); + ASSERT_TRUE(cache.Get(cert0000, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + // Once we access it, it goes to the front + ASSERT_TRUE(cache.Get(cert0000, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + + // This will be in the middle + Time timeInPlus512(now); + ASSERT_EQ(Success, timeInPlus512.AddSeconds(512)); + + static const Input fakeSerial0512(LiteralInput("0512")); + CertID cert0512(fakeIssuer1, fakeKey000, fakeSerial0512); + ASSERT_TRUE(cache.Get(cert0512, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeInPlus512, timeOut); + ASSERT_TRUE(cache.Get(cert0512, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeInPlus512, timeOut); + + // We've never seen this certificate + static const Input fakeSerial1111(LiteralInput("1111")); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey000, fakeSerial1111), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestEviction) { + SCOPED_TRACE(""); + // By putting more distinct entries in the cache than it can hold, + // we cause the least recently used entry to be evicted. + for (int i = 0; i < MaxCacheEntries + 1; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial0000), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses) { + SCOPED_TRACE(""); + CertID notEvicted(fakeIssuer1, fakeKey000, fakeSerial0000); + Time timeIn(now); + PutAndGet(cache, notEvicted, Result::ERROR_REVOKED_CERTIFICATE, timeIn); + // By putting more distinct entries in the cache than it can hold, + // we cause the least recently used entry that isn't revoked to be evicted. + for (int i = 1; i < MaxCacheEntries + 1; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(notEvicted, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); + ASSERT_EQ(timeIn, timeOut); + + Input fakeSerial0001(LiteralInput("0001")); + CertID evicted(fakeIssuer1, fakeKey000, fakeSerial0001); + ASSERT_FALSE(cache.Get(evicted, OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked) { + SCOPED_TRACE(""); + Time timeIn(now); + // Fill up the cache with revoked responses. + for (int i = 0; i < MaxCacheEntries; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), + Result::ERROR_REVOKED_CERTIFICATE, timeIn); + } + static const Input fakeSerial1025(LiteralInput("1025")); + CertID good(fakeIssuer1, fakeKey000, fakeSerial1025); + // This will "succeed", allowing verification to continue. However, + // nothing was actually put in the cache. + Time timeInPlus1025(timeIn); + ASSERT_EQ(Success, timeInPlus1025.AddSeconds(1025)); + Time timeInPlus1025Minus50(timeInPlus1025); + ASSERT_EQ(Success, timeInPlus1025Minus50.SubtractSeconds(50)); + Result result = cache.Put(good, OriginAttributes(), Success, + timeInPlus1025Minus50, timeInPlus1025); + ASSERT_EQ(Success, result); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(good, OriginAttributes(), resultOut, timeOut)); + + static const Input fakeSerial1026(LiteralInput("1026")); + CertID revoked(fakeIssuer1, fakeKey000, fakeSerial1026); + // This will fail, causing verification to fail. + Time timeInPlus1026(timeIn); + ASSERT_EQ(Success, timeInPlus1026.AddSeconds(1026)); + Time timeInPlus1026Minus50(timeInPlus1026); + ASSERT_EQ(Success, timeInPlus1026Minus50.SubtractSeconds(50)); + result = + cache.Put(revoked, OriginAttributes(), Result::ERROR_REVOKED_CERTIFICATE, + timeInPlus1026Minus50, timeInPlus1026); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, result); +} + +TEST_F(psm_OCSPCacheTest, VariousIssuers) { + SCOPED_TRACE(""); + Time timeIn(now); + static const Input fakeIssuer2(LiteralInput("CN=issuer2")); + static const Input fakeSerial001(LiteralInput("001")); + CertID subject(fakeIssuer1, fakeKey000, fakeSerial001); + PutAndGet(cache, subject, Success, now); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(subject, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + // Test that we don't match a different issuer DN + ASSERT_FALSE(cache.Get(CertID(fakeIssuer2, fakeKey000, fakeSerial001), + OriginAttributes(), resultOut, timeOut)); + // Test that we don't match a different issuer key + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial001), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, Times) { + SCOPED_TRACE(""); + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + PutAndGet(cache, certID, Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(100)); + PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); + // This should not override the more recent entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(100), TimeFromElapsedSecondsAD(100))); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + // Here we see the more recent time. + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); + + // Result::ERROR_REVOKED_CERTIFICATE overrides everything + PutAndGet(cache, certID, Result::ERROR_REVOKED_CERTIFICATE, + TimeFromElapsedSecondsAD(50)); +} + +TEST_F(psm_OCSPCacheTest, NetworkFailure) { + SCOPED_TRACE(""); + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + PutAndGet(cache, certID, Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(100)); + PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(300), TimeFromElapsedSecondsAD(350))); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); + + PutAndGet(cache, certID, Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(400)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(500), TimeFromElapsedSecondsAD(550))); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(400), timeOut); + + PutAndGet(cache, certID, Result::ERROR_REVOKED_CERTIFICATE, + TimeFromElapsedSecondsAD(600)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(700), TimeFromElapsedSecondsAD(750))); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(600), timeOut); +} + +TEST_F(psm_OCSPCacheTest, TestOriginAttributes) { + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + + SCOPED_TRACE(""); + OriginAttributes attrs; + attrs.mFirstPartyDomain.AssignLiteral("foo.com"); + PutAndGet(cache, certID, Success, now, attrs); + + Result resultOut; + Time timeOut(Time::uninitialized); + attrs.mFirstPartyDomain.AssignLiteral("bar.com"); + ASSERT_FALSE(cache.Get(certID, attrs, resultOut, timeOut)); + + // OCSP cache should not be isolated by containers. + attrs.mUserContextId = 1; + attrs.mFirstPartyDomain.AssignLiteral("foo.com"); + ASSERT_TRUE(cache.Get(certID, attrs, resultOut, timeOut)); +} diff --git a/security/manager/ssl/tests/gtest/README.txt b/security/manager/ssl/tests/gtest/README.txt new file mode 100644 index 0000000000..0e51322690 --- /dev/null +++ b/security/manager/ssl/tests/gtest/README.txt @@ -0,0 +1,2 @@ +Please name all test cases in this directory with the prefix "psm". This makes +it easier to run all PSM related GTests at once. diff --git a/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp b/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp new file mode 100644 index 0000000000..0c9d3ef60d --- /dev/null +++ b/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp @@ -0,0 +1,383 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "nsNSSIOLayer.h" +#include "sslproto.h" +#include "sslerr.h" + +#include "gtest/gtest.h" + +constexpr auto HOST = "example.org"_ns; +const int16_t PORT = 443; + +class psm_TLSIntoleranceTest : public ::testing::Test { + protected: + nsSSLIOLayerHelpers helpers; +}; + +TEST_F(psm_TLSIntoleranceTest, FullFallbackProcess) { + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, helpers.mVersionFallbackLimit); + + // No adjustment made when there is no entry for the site. + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + + ASSERT_TRUE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + + ASSERT_TRUE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.max); + + ASSERT_FALSE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + // When rememberIntolerantAtVersion returns false, it also resets the + // intolerance information for the server. + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, DisableFallbackWithHighLimit) { + // this value disables version fallback entirely: with this value, all efforts + // to mark an origin as version intolerant fail + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_2; + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_0, 0)); +} + +TEST_F(psm_TLSIntoleranceTest, FallbackLimitBelowMin) { + // check that we still respect the minimum version, + // when it is higher than the fallback limit + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_1, 0)); +} + +TEST_F(psm_TLSIntoleranceTest, TolerantOverridesIntolerant1) { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, TolerantOverridesIntolerant2) { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_2); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, IntolerantDoesNotOverrideTolerant) { + // No adjustment made when there is no entry for the site. + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + // false because we reached the floor set by rememberTolerantAtVersion. + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, PortIsRelevant) { + helpers.rememberTolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, 2, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, 1, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, 2, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonInitial) { + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberTolerantAtVersion(HOST, 2, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 2)); +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonStored) { + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2, + SSL_ERROR_BAD_SERVER); + ASSERT_EQ(SSL_ERROR_BAD_SERVER, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_1, + SSL_ERROR_BAD_MAC_READ); + ASSERT_EQ(SSL_ERROR_BAD_MAC_READ, helpers.getIntoleranceReason(HOST, 1)); +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonCleared) { + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2, + SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); + ASSERT_EQ(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, + helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberTolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); +} + +TEST_F(psm_TLSIntoleranceTest, TLSForgetIntolerance) { + { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, + 0)); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + { + helpers.forgetIntolerance(HOST, PORT); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, TLSDontForgetTolerance) { + { + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, + 0)); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + { + helpers.forgetIntolerance(HOST, PORT); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, TLSPerSiteFallbackLimit) { + constexpr auto example_com = "example.com"_ns; + constexpr auto example_net = "example.net"_ns; + constexpr auto example_org = "example.org"_ns; + + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_0; + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_2; + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(example_com); + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites("example.com,example.net"_ns); + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(example_net); + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(""_ns); + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); +} diff --git a/security/manager/ssl/tests/gtest/moz.build b/security/manager/ssl/tests/gtest/moz.build new file mode 100644 index 0000000000..caa4b839ab --- /dev/null +++ b/security/manager/ssl/tests/gtest/moz.build @@ -0,0 +1,29 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +SOURCES += [ + "CertDBTest.cpp", + "CertListTest.cpp", + "CoseTest.cpp", + "DataStorageTest.cpp", + "DeserializeCertTest.cpp", + "MD4Test.cpp", + "OCSPCacheTest.cpp", + "TLSIntoleranceTest.cpp", +] + +LOCAL_INCLUDES += [ + "/security/certverifier", + "/security/manager/ssl", + "/third_party/rust/cose-c/include", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul-gtest" + +if CONFIG["CC_TYPE"] in ("clang", "gcc"): + CXXFLAGS += ["-Wno-error=shadow"] diff --git a/security/manager/ssl/tests/mochitest/browser/browser.ini b/security/manager/ssl/tests/mochitest/browser/browser.ini new file mode 100644 index 0000000000..4a590a74e4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser.ini @@ -0,0 +1,25 @@ +[DEFAULT] +tags = psm +support-files = + head.js + *.pem + +[browser_bug627234_perwindowpb.js] +[browser_certificateManager.js] +[browser_certViewer.js] +skip-if = verify +[browser_clientAuth_connection.js] +# Any test that has to delete certificates (e.g. as part of cleanup) is +# fundamentally incompatible with verify due to how NSS handles deleting +# certificates. +skip-if = verify +[browser_clientAuth_ui.js] +[browser_clientAuthRememberService.js] +[browser_deleteCert_ui.js] +[browser_downloadCert_ui.js] +[browser_editCACertTrust.js] +# An earlier attempt at landing this test resulted in frequent intermittent +# failures, almost entirely on Linux. See Bug 1309519. +skip-if = os == "linux" +[browser_exportP12_passwordUI.js] +[browser_loadPKCS11Module_ui.js] diff --git a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js new file mode 100644 index 0000000000..a1be1d2a29 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js @@ -0,0 +1,101 @@ +/* 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 whenNewWindowLoaded(aOptions, aCallback) { + let win = OpenBrowserWindow(aOptions); + win.addEventListener( + "load", + function() { + aCallback(win); + }, + { once: true } + ); +} + +// This is a template to help porting global private browsing tests +// to per-window private browsing tests +function test() { + // initialization + waitForExplicitFinish(); + let windowsToClose = []; + let testURI = "about:blank"; + let uri; + let gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + function privacyFlags(aIsPrivateMode) { + return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + } + + function doTest(aIsPrivateMode, aWindow, aCallback) { + BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser).then( + () => { + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + uri = aWindow.Services.io.newURI("https://localhost/img.png"); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + privacyFlags(aIsPrivateMode), + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + privacyFlags(aIsPrivateMode) + ), + "checking sts host" + ); + + aCallback(); + } + ); + + BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI); + } + + function testOnWindow(aOptions, aCallback) { + whenNewWindowLoaded(aOptions, function(aWin) { + windowsToClose.push(aWin); + // execute should only be called when need, like when you are opening + // web pages on the test. If calling executeSoon() is not necesary, then + // call whenNewWindowLoaded() instead of testOnWindow() on your test. + executeSoon(function() { + aCallback(aWin); + }); + }); + } + + // this function is called after calling finish() on the test. + registerCleanupFunction(function() { + windowsToClose.forEach(function(aWin) { + aWin.close(); + }); + uri = Services.io.newURI("http://localhost"); + gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + }); + + // test first when on private mode + testOnWindow({ private: true }, function(aWin) { + doTest(true, aWin, function() { + // test when not on private mode + testOnWindow({}, function(aWin) { + doTest(false, aWin, function() { + // test again when on private mode + testOnWindow({ private: true }, function(aWin) { + doTest(true, aWin, function() { + finish(); + }); + }); + }); + }); + }); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js new file mode 100644 index 0000000000..d686653413 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js @@ -0,0 +1,107 @@ +/* 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"; + +// Repeatedly opens the certificate viewer dialog with various certificates and +// determines that the viewer correctly identifies either what usages those +// certificates are valid for or what errors prevented the certificates from +// being verified. + +var { AppConstants } = ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" +); +var { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm"); + +add_task(async function testCAandTitle() { + let cert = await readCertificate("ca.pem", "CTu,CTu,CTu"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "ca"); +}); + +add_task(async function testSSLEndEntity() { + let cert = await readCertificate("ssl-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "ssl-ee"); +}); + +add_task(async function testEmailEndEntity() { + let cert = await readCertificate("email-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "email-ee"); +}); + +add_task(async function testCodeSignEndEntity() { + let cert = await readCertificate("code-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "code-ee"); +}); + +add_task(async function testExpired() { + let cert = await readCertificate("expired-ca.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "expired-ca"); +}); + +add_task(async function testUntrusted() { + let cert = await readCertificate("untrusted-ca.pem", "p,p,p"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "untrusted-ca"); +}); + +add_task(async function testInvalid() { + // This certificate has a keyUsage extension asserting cRLSign and + // keyCertSign, but it doesn't have a basicConstraints extension. This + // shouldn't be valid for any usage. Sadly, we give a pretty bad error + // message in this case. + let cert = await readCertificate("invalid.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "invalid"); +}); + +add_task(async function testLongOID() { + // This certificate has a certificatePolicies extension with a policy with a + // very long OID. This tests that we don't crash when looking at it. + let cert = await readCertificate("longOID.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "Long OID"); +}); + +/** + * Given a certificate, returns its PEMs (each one of the certificate chain) string in a url. + * @param {Object} cert + * A certificate object + * @returns {String} an URL for opening the certificate viewer + */ +function getURL(cert) { + // Note that we don't get the certificate chain as in e.g browser/base/content/browser.js, + // because all the .pem files when opened with CS (https://github.com/april/certainly-something) + // shows only one certificate + let derb64 = encodeURIComponent(cert.getBase64DERString()); + return `about:certificate?cert=${derb64}`; +} + +/** + * Given an certificate URL, opens the new certificate viewer and check + * if a certain element exists, with its expected result. + * + * @param {String} url + * The URL with the certificate info + * @param {String} expectedTabName + * The expected name of the tab in the certificate viewer + */ +async function openCertViewerAndCheckTabName(url, expectedTabName) { + await BrowserTestUtils.withNewTab({ gBrowser, url }, async function(browser) { + await SpecialPowers.spawn(browser, [expectedTabName], async function( + expectedTabName + ) { + let certificateSection = await ContentTaskUtils.waitForCondition(() => { + return content.document.querySelector("certificate-section"); + }, "Certificate section found"); + let tabName = certificateSection.shadowRoot.querySelector( + ".tab[idnumber='0']" + ).textContent; + Assert.equal(tabName, expectedTabName); + }); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js b/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js new file mode 100644 index 0000000000..3b6ab0d6f3 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js @@ -0,0 +1,179 @@ +/* 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"; + +const TEST_CERT_BASE64 = + "MIICrjCCAZagAwIBAgIUCR+2dzKgSt0CBU86EgRdJIa/72owDQYJKoZIhvcNAQEEBQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowETEPMA0GA1UEAwwGbWQ1LWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQArfDtm5sEuzsPZps2oZhvrOYRViP0sRIAbAjuJVnAMA/7xLzI3LweXOlQJHBh3m3mrPUMAXfr4xJ5XjGySqHBUtFat9EBl/0bynd67sCMA7UOf51GC4ABOPAV0CkDj/FNqL/KSt8WB90FW+ZKnt1ojKikMIjmPjxDaaHj7KZVBQ2KtBEz1Igt5Bvbrp2AMNvjyhUCN4/z4NDPPbzkeDKYC7vmvYhN1Cs/73Jp3A0LU4z0gIyrWi6a7YEAVBzhIvJJ98U8AQQMm+iiIDGZMoAZyvEFouofF9te4xMHStUnYfa1jLY93dL1TuXrWvKB0pWg4REoQuFZUE8GS/LczW5xX"; + +async function checkServerCertificates(win, expectedValues = []) { + await TestUtils.waitForCondition(() => { + return ( + win.document.getElementById("serverList").itemChildren.length == + expectedValues.length + ); + }, `Expected to have ${expectedValues.length} but got ${win.document.getElementById("serverList").itemChildren.length}`); + + let labels = win.document + .getElementById("serverList") + .querySelectorAll("label"); + + expectedValues.forEach((item, i) => { + let hostPort = labels[i * 3].value; + let certString = labels[i * 3 + 1].value || labels[i * 3 + 1].textContent; + let isTemporaryString = + labels[i * 3 + 2].value || labels[i * 3 + 2].textContent; + + Assert.equal( + hostPort, + item.hostPort, + `Expected override to be ${item.hostPort} but got ${hostPort}` + ); + + Assert.equal( + certString, + item.certName, + `Expected override to have field ${item.certName}` + ); + + Assert.equal( + isTemporaryString, + item.isTemporary ? "Temporary" : "Permanent", + `Expected override to be ${item.isTemporary ? "Temporary" : "Permanent"}` + ); + }); +} + +async function deleteOverride(win, expectedLength) { + win.document.getElementById("serverList").selectedIndex = 0; + await TestUtils.waitForCondition(() => { + return ( + win.document.getElementById("serverList").itemChildren.length == + expectedLength + ); + }); + let newWinPromise = BrowserTestUtils.domWindowOpenedAndLoaded(); + // Since the .click() blocks we need to dispatch it to the main thread avoid that. + Services.tm.dispatchToMainThread(() => + win.document.getElementById("websites_deleteButton").click() + ); + let newWin = await newWinPromise; + newWin.document.getElementById("deleteCertificate").acceptDialog(); + Assert.equal( + win.document.getElementById("serverList").selectedIndex, + 0, + "After deletion we expect the selectedItem to be reset." + ); +} + +async function testViewButton(win) { + win.document.getElementById("serverList").selectedIndex = 1; + + Assert.ok( + win.document.getElementById("websites_viewButton").disabled, + "View button should be disabled for override without cert" + ); + + win.document.getElementById("serverList").selectedIndex = 0; + + Assert.ok( + !win.document.getElementById("websites_viewButton").disabled, + "View button should be enabled for override with cert" + ); + + let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true); + + win.document.getElementById("websites_viewButton").click(); + + let newTab = await loaded; + let spec = newTab.linkedBrowser.documentURI.spec; + + Assert.ok( + spec.startsWith("about:certificate"), + "about:certificate should habe been opened" + ); + + let newUrl = new URL(spec); + let certEncoded = newUrl.searchParams.get("cert"); + let certDecoded = decodeURIComponent(certEncoded); + Assert.equal( + TEST_CERT_BASE64, + certDecoded, + "Loaded cert should match expected cert" + ); + + gBrowser.removeCurrentTab(); +} + +add_task(async function test_cert_manager_server_tab() { + let win = await openCertManager(); + + await checkServerCertificates(win); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + let cert = await readCertificate("md5-ee.pem", ",,"); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + "example.com", + 443, + cert, + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + false + ); + + win = await openCertManager(); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:443", + certName: "md5-ee", + isTemporary: false, + }, + ]); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + certOverrideService.rememberTemporaryValidityOverrideUsingFingerprint( + "example.com", + 9999, + "40:20:3E:57:FB:82:95:0D:3F:62:D7:04:39:F6:32:CC:B2:2F:70:9F:3E:66:C5:35:64:6E:49:2A:F1:02:75:9F", + Ci.nsICertOverrideService.ERROR_UNTRUSTED + ); + + win = await openCertManager(); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:443", + certName: "md5-ee", + isTemporary: false, + }, + { + hostPort: "example.com:9999", + certName: "(Not Stored)", + isTemporary: true, + }, + ]); + + await testViewButton(win); + + await deleteOverride(win, 2); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:9999", + certName: "(Not Stored)", + isTemporary: true, + }, + ]); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + certOverrideService.clearAllOverrides(); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js new file mode 100644 index 0000000000..3ab2d9792e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js @@ -0,0 +1,257 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +/** + * Test certificate (i.e. build/pgo/certs/mochitest.client). + * @type nsIX509Cert + */ +var cert; +var cert2; +var cert3; + +var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +var deleted = false; + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +function findCertByCommonName(commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +async function testHelper(connectURL, expectedURL) { + let win = await BrowserTestUtils.openNewBrowserWindow(); + + await SpecialPowers.pushPrefEnv({ + set: [["security.default_personal_cert", "Ask Every Time"]], + }); + + BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, connectURL); + + await BrowserTestUtils.browserLoaded( + win.gBrowser.selectedBrowser, + false, + expectedURL, + true + ); + let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec; + Assert.ok( + loadedURL.startsWith(expectedURL), + `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')` + ); + + await win.close(); + + // This clears the TLS session cache so we don't use a previously-established + // ticket to connect and bypass selecting a client auth certificate in + // subsequent tests. + sdr.logout(); +} + +async function openRequireClientCert() { + gClientAuthDialogs.chooseCertificateCalled = false; + await testHelper( + "https://requireclientcert.example.com:443", + "https://requireclientcert.example.com/" + ); +} + +async function openRequireClientCert2() { + gClientAuthDialogs.chooseCertificateCalled = false; + await testHelper( + "https://requireclientcert-2.example.com:443", + "https://requireclientcert-2.example.com/" + ); +} + +// Mock implementation of nsIClientAuthRememberService +const gClientAuthRememberService = { + forgetRememberedDecision(key) { + deleted = true; + Assert.equal( + key, + "exampleKey2", + "Expected to get the same key that was passed in getDecisions()" + ); + }, + + getDecisions() { + return [ + { + asciiHost: "example.com", + dbKey: cert.dbKey, + entryKey: "exampleKey1", + }, + { + asciiHost: "example.org", + dbKey: cert2.dbKey, + entryKey: "exampleKey2", + }, + { + asciiHost: "example.test", + dbKey: cert3.dbKey, + entryKey: "exampleKey3", + }, + ]; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIClientAuthRememberService"]), +}; + +const gClientAuthDialogs = { + _chooseCertificateCalled: false, + + get chooseCertificateCalled() { + return this._chooseCertificateCalled; + }, + + set chooseCertificateCalled(value) { + this._chooseCertificateCalled = value; + }, + + chooseCertificate( + hostname, + port, + organization, + issuerOrg, + certList, + selectedIndex, + rememberClientAuthCertificate + ) { + rememberClientAuthCertificate.value = true; + this.chooseCertificateCalled = true; + selectedIndex.value = 0; + return true; + }, + + QueryInterface: ChromeUtils.generateQI([Ci.nsIClientAuthDialogs]), +}; + +add_task(async function testRememberedDecisionsUI() { + cert = findCertByCommonName("Mochitest client"); + cert2 = await readCertificate("pgo-ca-all-usages.pem", ",,"); + cert3 = await readCertificate("client-cert-via-intermediate.pem", ",,"); + isnot(cert, null, "Should be able to find the test client cert"); + isnot(cert2, null, "Should be able to find pgo-ca-all-usages.pem"); + isnot(cert3, null, "Should be able to find client-cert-via-intermediate.pem"); + + let clientAuthRememberServiceCID = MockRegistrar.register( + "@mozilla.org/security/clientAuthRememberService;1", + gClientAuthRememberService + ); + + let win = await openCertManager(); + + let listItems = win.document + .getElementById("rememberedList") + .querySelectorAll("richlistitem"); + + Assert.equal( + listItems.length, + 3, + "Expected rememberedList to only have one item" + ); + + let labels = win.document + .getElementById("rememberedList") + .querySelectorAll("label"); + + Assert.equal( + labels.length, + 9, + "Expected the rememberedList to have three labels" + ); + + let expectedHosts = ["example.com", "example.org", "example.test"]; + let hosts = [labels[0].value, labels[3].value, labels[6].value]; + let expectedNames = [cert.commonName, cert2.commonName, cert3.commonName]; + let names = [labels[1].value, labels[4].value, labels[7].value]; + let expectedSerialNumbers = [ + cert.serialNumber, + cert2.serialNumber, + cert3.serialNumber, + ]; + let serialNumbers = [labels[2].value, labels[5].value, labels[8].value]; + + for (let i = 0; i < 3; i++) { + Assert.equal(hosts[i], expectedHosts[i], "Expected host to be asciiHost"); + Assert.equal( + names[i], + expectedNames[i], + "Expected name to be the commonName of the cert" + ); + Assert.equal( + serialNumbers[i], + expectedSerialNumbers[i], + "Expected serialNumber to be the serialNumber of the cert" + ); + } + + win.document.getElementById("rememberedList").selectedIndex = 1; + + win.document.getElementById("remembered_deleteButton").click(); + + Assert.ok(deleted, "Expected forgetRememberedDecision() to get called"); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + MockRegistrar.unregister(clientAuthRememberServiceCID); +}); + +add_task(async function testDeletingRememberedDecisions() { + let clientAuthDialogsCID = MockRegistrar.register( + "@mozilla.org/nsClientAuthDialogs;1", + gClientAuthDialogs + ); + let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService( + Ci.nsIClientAuthRememberService + ); + + await openRequireClientCert(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called if visiting 'requireclientcert.example.com' for the first time" + ); + + await openRequireClientCert(); + Assert.ok( + !gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should not have been called if visiting 'requireclientcert.example.com' for the second time" + ); + + await openRequireClientCert2(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called if visiting'requireclientcert-2.example.com' for the first time" + ); + + let originAttributes = { privateBrowsingId: 0 }; + cars.deleteDecisionsByHost("requireclientcert.example.com", originAttributes); + + await openRequireClientCert(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called after removing all remembered decisions for 'requireclientcert.example.com'" + ); + + await openRequireClientCert2(); + Assert.ok( + !gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should not have been called if visiting 'requireclientcert-2.example.com' for the second time" + ); + + MockRegistrar.unregister(clientAuthDialogsCID); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js new file mode 100644 index 0000000000..a0e9723f43 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js @@ -0,0 +1,342 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various scenarios connecting to a server that requires client cert +// authentication. Also tests that nsIClientAuthDialogs.chooseCertificate +// is called at the appropriate times and with the correct arguments. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +const DialogState = { + // Assert that chooseCertificate() is never called. + ASSERT_NOT_CALLED: "ASSERT_NOT_CALLED", + // Return that the user selected the first given cert. + RETURN_CERT_SELECTED: "RETURN_CERT_SELECTED", + // Return that the user canceled. + RETURN_CERT_NOT_SELECTED: "RETURN_CERT_NOT_SELECTED", +}; + +var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); +let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService( + Ci.nsIClientAuthRememberService +); + +var gExpectedClientCertificateChoices; + +// Mock implementation of nsIClientAuthDialogs. +const gClientAuthDialogs = { + _state: DialogState.ASSERT_NOT_CALLED, + _rememberClientAuthCertificate: false, + _chooseCertificateCalled: false, + + set state(newState) { + info(`old state: ${this._state}`); + this._state = newState; + info(`new state: ${this._state}`); + }, + + get state() { + return this._state; + }, + + set rememberClientAuthCertificate(value) { + this._rememberClientAuthCertificate = value; + }, + + get rememberClientAuthCertificate() { + return this._rememberClientAuthCertificate; + }, + + get chooseCertificateCalled() { + return this._chooseCertificateCalled; + }, + + set chooseCertificateCalled(value) { + this._chooseCertificateCalled = value; + }, + + chooseCertificate( + hostname, + port, + organization, + issuerOrg, + certList, + selectedIndex, + rememberClientAuthCertificate + ) { + this.chooseCertificateCalled = true; + Assert.notEqual( + this.state, + DialogState.ASSERT_NOT_CALLED, + "chooseCertificate() should be called only when expected" + ); + + rememberClientAuthCertificate.value = this.rememberClientAuthCertificate; + + Assert.equal( + hostname, + "requireclientcert.example.com", + "Hostname should be 'requireclientcert.example.com'" + ); + Assert.equal(port, 443, "Port should be 443"); + Assert.equal( + organization, + "", + "Server cert Organization should be empty/not present" + ); + Assert.equal( + issuerOrg, + "Mozilla Testing", + "Server cert issuer Organization should be 'Mozilla Testing'" + ); + + // For mochitests, the cert at build/pgo/certs/mochitest.client should be + // selectable as well as one of the PGO certs we loaded in `setup`, so we do + // some brief checks to confirm this. + Assert.notEqual(certList, null, "Cert list should not be null"); + Assert.equal( + certList.length, + gExpectedClientCertificateChoices, + `${gExpectedClientCertificateChoices} certificates should be available` + ); + + for (let cert of certList.enumerate(Ci.nsIX509Cert)) { + Assert.notEqual(cert, null, "Cert list should contain nsIX509Certs"); + Assert.equal( + cert.issuerCommonName, + "Temporary Certificate Authority", + "cert should have expected issuer CN" + ); + } + + if (this.state == DialogState.RETURN_CERT_SELECTED) { + selectedIndex.value = 0; + return true; + } + return false; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIClientAuthDialogs"]), +}; + +add_task(async function setup() { + let clientAuthDialogsCID = MockRegistrar.register( + "@mozilla.org/nsClientAuthDialogs;1", + gClientAuthDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(clientAuthDialogsCID); + }); + + // This CA has the expected keyCertSign and cRLSign usages. It should not be + // presented for use as a client certificate. + await readCertificate("pgo-ca-regular-usages.pem", "CTu,CTu,CTu"); + // This CA has all keyUsages. For compatibility with preexisting behavior, it + // will be presented for use as a client certificate. + await readCertificate("pgo-ca-all-usages.pem", "CTu,CTu,CTu"); + // This client certificate was issued by an intermediate that was issued by + // the test CA. The server only lists the test CA's subject distinguished name + // as an acceptible issuer name for client certificates. If the implementation + // can determine that the test CA is a root CA for the client certificate and + // thus is acceptible to use, it should be included in the chooseCertificate + // callback. At the beginning of this test (speaking of this file as a whole), + // the client is not aware of the intermediate, and so it is not available in + // the callback. + await readCertificate("client-cert-via-intermediate.pem", ",,"); + // This certificate has an id-kp-OCSPSigning EKU. Client certificates + // shouldn't have this EKU, but there is at least one private PKI where they + // do. For interoperability, such certificates will be presented for use. + await readCertificate("client-cert-with-ocsp-signing.pem", ",,"); + gExpectedClientCertificateChoices = 3; +}); + +/** + * Test helper for the tests below. + * + * @param {String} prefValue + * Value to set the "security.default_personal_cert" pref to. + * @param {String} expectedURL + * If the connection is expected to load successfully, the URL that + * should load. If the connection is expected to fail and result in an + * error page, |undefined|. + * @param {Boolean} expectCallingChooseCertificate + * Determines whether we expect chooseCertificate to be called. + * @param {Object} options + * Optional options object to pass on to the window that gets opened. + */ +async function testHelper( + prefValue, + expectedURL, + expectCallingChooseCertificate, + options = undefined +) { + gClientAuthDialogs.chooseCertificateCalled = false; + await SpecialPowers.pushPrefEnv({ + set: [["security.default_personal_cert", prefValue]], + }); + + let win = await BrowserTestUtils.openNewBrowserWindow(options); + + BrowserTestUtils.loadURI( + win.gBrowser.selectedBrowser, + "https://requireclientcert.example.com:443" + ); + + await BrowserTestUtils.browserLoaded( + win.gBrowser.selectedBrowser, + false, + "https://requireclientcert.example.com/", + true + ); + let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec; + Assert.ok( + loadedURL.startsWith(expectedURL), + `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')` + ); + Assert.equal( + gClientAuthDialogs.chooseCertificateCalled, + expectCallingChooseCertificate, + "chooseCertificate should have been called if we were expecting it to be called" + ); + + await win.close(); + + // This clears the TLS session cache so we don't use a previously-established + // ticket to connect and bypass selecting a client auth certificate in + // subsequent tests. + sdr.logout(); +} + +// Test that if a certificate is chosen automatically the connection succeeds, +// and that nsIClientAuthDialogs.chooseCertificate() is never called. +add_task(async function testCertChosenAutomatically() { + gClientAuthDialogs.state = DialogState.ASSERT_NOT_CALLED; + await testHelper( + "Select Automatically", + "https://requireclientcert.example.com/", + false + ); + // This clears all saved client auth certificate state so we don't influence + // subsequent tests. + cars.clearRememberedDecisions(); +}); + +// Test that if the user doesn't choose a certificate, the connection fails and +// an error page is displayed. +add_task(async function testCertNotChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED; + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); +}); + +// Test that if the user chooses a certificate the connection suceeeds. +add_task(async function testCertChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); +}); + +// Test that the cancel decision is remembered correctly +add_task(async function testEmptyCertChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED; + gClientAuthDialogs.rememberClientAuthCertificate = true; + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + true + ); + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + false + ); + cars.clearRememberedDecisions(); +}); + +// Test that if the user chooses a certificate in a private browsing window, +// configures Firefox to remember this certificate for the duration of the +// session, closes that window (and thus all private windows), reopens a private +// window, and visits that site again, they are re-asked for a certificate (i.e. +// any state from the previous private session should be gone). Similarly, after +// closing that private window, if the user opens a non-private window, they +// again should be asked to choose a certificate (i.e. private state should not +// be remembered/used in non-private contexts). +add_task(async function testClearPrivateBrowsingState() { + gClientAuthDialogs.rememberClientAuthCertificate = true; + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true, + { + private: true, + } + ); + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true, + { + private: true, + } + ); + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + // NB: we don't `cars.clearRememberedDecisions()` in between the two calls to + // `testHelper` because that would clear all client auth certificate state and + // obscure what we're testing (that Firefox properly clears the relevant state + // when the last private window closes). + cars.clearRememberedDecisions(); +}); + +// Test that 3rd party certificates are taken into account when filtering client +// certificates based on the acceptible CA list sent by the server. +add_task(async function testCertFilteringWithIntermediate() { + let intermediateBytes = await OS.File.read( + getTestFilePath("intermediate.pem") + ).then( + data => { + let decoder = new TextDecoder(); + let pem = decoder.decode(data); + let base64 = pemToBase64(pem); + let bin = atob(base64); + let bytes = []; + for (let i = 0; i < bin.length; i++) { + bytes.push(bin.charCodeAt(i)); + } + return bytes; + }, + error => { + throw error; + } + ); + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + nssComponent.addEnterpriseIntermediate(intermediateBytes); + gExpectedClientCertificateChoices = 4; + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); + // This will reset the added intermediate. + await SpecialPowers.pushPrefEnv({ + set: [["security.enterprise_roots.enabled", true]], + }); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js new file mode 100644 index 0000000000..c75cf02482 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js @@ -0,0 +1,199 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the client authentication certificate chooser correctly displays +// provided information and correctly returns user input. + +const TEST_HOSTNAME = "Test Hostname"; +const TEST_ORG = "Test Org"; +const TEST_ISSUER_ORG = "Test Issuer Org"; +const TEST_PORT = 123; + +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); +/** + * Test certificate (i.e. build/pgo/certs/mochitest.client). + * @type nsIX509Cert + */ +var cert; + +/** + * Opens the client auth cert chooser dialog. + * + * @param {nsIX509Cert} cert The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openClientAuthDialog(cert) { + let certList = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + certList.appendElement(cert); + + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/clientauthask.xhtml", + "", + "", + TEST_HOSTNAME, + TEST_ORG, + TEST_ISSUER_ORG, + TEST_PORT, + certList, + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +/** + * Checks that the contents of the given cert chooser dialog match the details + * of build/pgo/certs/mochitest.client. + * + * @param {window} win The cert chooser window. + * @param {String} notBefore + * The notBeforeLocalTime attribute of mochitest.client. + * @param {String} notAfter + * The notAfterLocalTime attribute of mochitest.client. + */ +function checkDialogContents(win, notBefore, notAfter) { + is( + win.document.getElementById("hostname").textContent, + `${TEST_HOSTNAME}:${TEST_PORT}`, + "Actual and expected hostname and port should be equal" + ); + is( + win.document.getElementById("organization").textContent, + `Organization: “${TEST_ORG}”`, + "Actual and expected organization should be equal" + ); + is( + win.document.getElementById("issuer").textContent, + `Issued Under: “${TEST_ISSUER_ORG}”`, + "Actual and expected issuer organization should be equal" + ); + + is( + win.document.getElementById("nicknames").label, + "Mochitest client [03]", + "Actual and expected selected cert nickname and serial should be equal" + ); + is( + win.document.getElementById("nicknames").itemCount, + 1, + "correct number of items" + ); + + let [ + subject, + serialNum, + validity, + issuer, + tokenName, + ] = win.document.getElementById("details").value.split("\n"); + is( + subject, + "Issued to: CN=Mochitest client", + "Actual and expected subject should be equal" + ); + is( + serialNum, + "Serial number: 03", + "Actual and expected serial number should be equal" + ); + is( + validity, + `Valid from ${notBefore} to ${notAfter}`, + "Actual and expected validity should be equal" + ); + is( + issuer, + "Issued by: OU=Profile Guided Optimization,O=Mozilla Testing,CN=Temporary Certificate Authority", + "Actual and expected issuer should be equal" + ); + is( + tokenName, + "Stored on: Software Security Device", + "Actual and expected token name should be equal" + ); +} + +function findCertByCommonName(commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +add_task(async function setup() { + cert = findCertByCommonName("Mochitest client"); + isnot(cert, null, "Should be able to find the test client cert"); +}); + +// Test that the contents of the dialog correspond to the details of the +// provided cert. +add_task(async function testContents() { + let [win] = await openClientAuthDialog(cert); + checkDialogContents( + win, + cert.validity.notBeforeLocalTime, + cert.validity.notAfterLocalTime + ); + await BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = true; + info("Accepting dialog"); + win.document.getElementById("certAuthAsk").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + ok( + retVals.get("certChosen"), + "Return value should signal user chose a certificate" + ); + is( + retVals.get("selectedIndex"), + 0, + "0 should be returned as the selected index" + ); + ok( + retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was checked" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = false; + info("Canceling dialog"); + win.document.getElementById("certAuthAsk").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + ok( + !retVals.get("certChosen"), + "Return value should signal user did not choose a certificate" + ); + ok( + !retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was unchecked" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js new file mode 100644 index 0000000000..0d06c553a2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js @@ -0,0 +1,257 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various aspects of the cert delete confirmation dialog. +// Among other things, tests that for each type of cert that can be deleted: +// 1. The various lines of explanation text are correctly set. +// 2. The implementation correctly falls back through multiple cert attributes +// to determine what to display to represent a cert. + +/** + * An array of tree items corresponding to TEST_CASES. + * @type nsICertTreeItem[] + */ +var gCertArray = []; + +const FAKE_HOST_PORT = "Fake host and port"; + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert, or null if we don't want to import a cert for + * this test case (i.e. we expect the hostPort attribute of + * nsICertTreeItem to be used). + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + * @property {String} expectedSerialNumber + * The serial number we expect the UI to display if it exists. + */ + +/** + * A list of test cases representing certs that get "deleted". + * @type TestCase[] + */ +const TEST_CASES = [ + { + certFilename: null, + expectedDisplayString: FAKE_HOST_PORT, + expectedSerialNumber: null, + }, + { + certFilename: "has-cn.pem", + expectedDisplayString: "Foo", + expectedSerialNumber: null, + }, + { + certFilename: "has-ou.pem", + expectedDisplayString: "Bar", + expectedSerialNumber: null, + }, + { + certFilename: "has-o.pem", + expectedDisplayString: "Baz", + expectedSerialNumber: null, + }, + { + certFilename: "has-non-empty-subject.pem", + expectedDisplayString: "C=US", + expectedSerialNumber: null, + }, + { + certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate with serial number: 0A", + expectedSerialNumber: "0A", + }, +]; + +/** + * Opens the cert delete confirmation dialog. + * + * @param {String} tabID + * The ID of the cert category tab the certs to delete belong to. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value object passed to the dialog. + */ +function openDeleteCertConfirmDialog(tabID) { + let retVals = { + deleteConfirmed: false, + }; + let win = window.openDialog( + "chrome://pippki/content/deletecert.xhtml", + "", + "", + tabID, + gCertArray, + retVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, retVals])); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + for (let testCase of TEST_CASES) { + let cert = null; + if (testCase.certFilename) { + cert = await readCertificate(testCase.certFilename, ",,"); + } + let certTreeItem = { + hostPort: FAKE_HOST_PORT, + cert, + QueryInterface: ChromeUtils.generateQI(["nsICertTreeItem"]), + }; + gCertArray.push(certTreeItem); + } +}); + +/** + * Test helper for the below test cases. + * + * @param {String} tabID + * ID of the cert category tab the certs to delete belong to. + * @param {String} expectedTitleL10nId + * The L10nId of title the dialog is expected to have. + * @param {String} expectedConfirmL10nId + * The l10n id of confirmation message the dialog expected to show. + * @param {String} expectedImpactL10nId + * The l10n id of impact the dialog expected to show. + */ +async function testHelper( + tabID, + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId +) { + let [win] = await openDeleteCertConfirmDialog(tabID); + let certList = win.document.getElementById("certlist"); + + Assert.deepEqual( + win.document.l10n.getAttributes(win.document.documentElement), + expectedTitleL10nId, + `Actual and expected titles should match for ${tabID}` + ); + let confirm = win.document.getElementById("confirm"); + Assert.deepEqual( + win.document.l10n.getAttributes(confirm), + expectedConfirmL10nId, + `Actual and expected confirm message should match for ${tabID}` + ); + let impact = win.document.getElementById("impact"); + Assert.deepEqual( + win.document.l10n.getAttributes(impact), + expectedImpactL10nId, + `Actual and expected impact should match for ${tabID}` + ); + + Assert.equal( + certList.itemCount, + TEST_CASES.length, + `No. of certs displayed should match for ${tabID}` + ); + for (let i = 0; i < certList.itemCount; i++) { + let item = certList.getItemAtIndex(i); + if (TEST_CASES[i].expectedSerialNumber == null) { + Assert.equal( + item.label, + TEST_CASES[i].expectedDisplayString, + "Actual and expected display string should match for " + + `index ${i} for ${tabID}` + ); + } else { + Assert.deepEqual( + win.document.l10n.getAttributes(item.children[0]), + { + id: "cert-with-serial", + args: { serialNumber: TEST_CASES[i].expectedSerialNumber }, + }, + "Actual and expected display string should match for " + + `index ${i} for ${tabID}` + ); + } + } + + await BrowserTestUtils.closeWindow(win); +} + +// Test deleting certs from the "Your Certificates" tab. +add_task(async function testDeletePersonalCerts() { + const expectedTitleL10nId = { id: "delete-user-cert-title", args: null }; + const expectedConfirmL10nId = { id: "delete-user-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-user-cert-impact", args: null }; + await testHelper( + "mine_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test deleting certs from the "People" tab. +add_task(async function testDeleteOtherPeopleCerts() { + const expectedTitleL10nId = { id: "delete-email-cert-title", args: null }; + // ’ doesn't seem to work when embedded in the following literals, which is + // why escape codes are used instead. + const expectedConfirmL10nId = { id: "delete-email-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-email-cert-impact", args: null }; + await testHelper( + "others_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test deleting certs from the "Authorities" tab. +add_task(async function testDeleteCACerts() { + const expectedTitleL10nId = { id: "delete-ca-cert-title", args: null }; + const expectedConfirmL10nId = { id: "delete-ca-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-ca-cert-impact", args: null }; + await testHelper( + "ca_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openDeleteCertConfirmDialog( + "ca_tab" /* arbitrary */ + ); + info("Accepting dialog"); + win.document.getElementById("deleteCertificate").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.deleteConfirmed, + "Return value should signal user accepted" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openDeleteCertConfirmDialog( + "ca_tab" /* arbitrary */ + ); + info("Canceling dialog"); + win.document.getElementById("deleteCertificate").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.deleteConfirmed, + "Return value should signal user did not accept" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js new file mode 100644 index 0000000000..876124d5c2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js @@ -0,0 +1,133 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the cert download/import UI correctly identifies the cert being +// downloaded, and allows the trust of the cert to be specified. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert for this test case. + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + * @property {nsIX509Cert} cert + * Handle to the cert once read in setup(). + */ + +/** + * A list of test cases representing certs that get "downloaded". + * @type TestCase[] + */ +const TEST_CASES = [ + { certFilename: "has-cn.pem", expectedDisplayString: "Foo", cert: null }, + { + certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate Authority (unnamed)", + cert: null, + }, +]; + +/** + * Opens the cert download dialog. + * + * @param {nsIX509Cert} cert + * The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openCertDownloadDialog(cert) { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/downloadcert.xhtml", + "", + "", + cert, + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + for (let testCase of TEST_CASES) { + testCase.cert = await readCertificate(testCase.certFilename, ",,"); + Assert.notEqual( + testCase.cert, + null, + `'${testCase.certFilename}' should have been read` + ); + } +}); + +// Test that the trust header message corresponds to the provided cert, and that +// the View Cert button launches the cert viewer for the provided cert. +add_task(async function testTrustHeaderAndViewCertButton() { + for (let testCase of TEST_CASES) { + let [win] = await openCertDownloadDialog(testCase.cert); + let expectedTrustHeaderString = + `Do you want to trust \u201C${testCase.expectedDisplayString}\u201D ` + + "for the following purposes?"; + Assert.equal( + win.document.getElementById("trustHeader").textContent, + expectedTrustHeaderString, + "Actual and expected trust header text should match for " + + `${testCase.certFilename}` + ); + + await BrowserTestUtils.closeWindow(win); + } +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openCertDownloadDialog(TEST_CASES[0].cert); + win.document.getElementById("trustSSL").checked = true; + win.document.getElementById("trustEmail").checked = false; + info("Accepting dialog"); + win.document.getElementById("download_cert").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.get("importConfirmed"), + "Return value should signal user chose to import the cert" + ); + Assert.ok( + retVals.get("trustForSSL"), + "Return value should signal SSL trust checkbox was checked" + ); + Assert.ok( + !retVals.get("trustForEmail"), + "Return value should signal E-mail trust checkbox was unchecked" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openCertDownloadDialog(TEST_CASES[0].cert); + info("Canceling dialog"); + win.document.getElementById("download_cert").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.get("importConfirmed"), + "Return value should signal user chose not to import the cert" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js new file mode 100644 index 0000000000..f4592ea9dc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js @@ -0,0 +1,140 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for editing the trust of a CA certificate correctly +// reflects trust in the cert DB, and correctly updates trust in the cert DB +// when requested. + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * The cert we're editing the trust of. + * @type nsIX509Cert + */ +var gCert; + +/** + * Opens the cert trust editing dialog. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading with + * the window of the opened dialog. + */ +function openEditCertTrustDialog() { + let win = window.openDialog( + "chrome://pippki/content/editcacert.xhtml", + "", + "", + gCert + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + // Initially trust ca.pem for SSL but not e-mail. + gCert = await readCertificate("ca.pem", "CT,,"); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Sanity check: ca.pem should be trusted for SSL" + ); + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Sanity check: ca.pem should not be trusted for e-mail" + ); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in setup(). +// 2. Accepting the dialog after flipping some of the checkboxes results in the +// correct trust being set in the cert DB. +add_task(async function testAcceptDialog() { + let win = await openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + Assert.ok(sslCheckbox.checked, "Cert should be trusted for SSL in UI"); + Assert.ok( + !emailCheckbox.checked, + "Cert should not be trusted for e-mail in UI" + ); + + sslCheckbox.checked = false; + emailCheckbox.checked = true; + + info("Accepting dialog"); + win.document.getElementById("editCaCert").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Cert should no longer be trusted for SSL" + ); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Cert should now be trusted for e-mail" + ); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in testAcceptDialog(). +// 2. Canceling the dialog even after flipping the checkboxes doesn't result in +// a change of trust in the cert DB. +add_task(async function testCancelDialog() { + let win = await openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + Assert.ok(!sslCheckbox.checked, "Cert should not be trusted for SSL in UI"); + Assert.ok(emailCheckbox.checked, "Cert should be trusted for e-mail in UI"); + + sslCheckbox.checked = true; + emailCheckbox.checked = false; + + info("Canceling dialog"); + win.document.getElementById("editCaCert").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Cert should still not be trusted for SSL" + ); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Cert should still be trusted for e-mail" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js new file mode 100644 index 0000000000..b36690be06 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js @@ -0,0 +1,163 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for setting the password on a to be exported PKCS #12 file: +// 1. Correctly requires the password to be typed in twice as confirmation. +// 2. Calculates and displays the strength of said password. + +/** + * @typedef {TestCase} + * @type Object + * @property {String} name + * The name of the test case for display purposes. + * @property {String} password1 + * The password to enter into the first password textbox. + * @property {String} password2 + * The password to enter into the second password textbox. + * @property {String} strength + * The expected strength of the password in the range [0, 100]. + */ + +/** + * A list of test cases representing various inputs to the password textboxes. + * @type TestCase[] + */ +const TEST_CASES = [ + { name: "empty", password1: "", password2: "", strength: "0" }, + { name: "match-weak", password1: "foo", password2: "foo", strength: "10" }, + { + name: "match-medium", + password1: "foo123", + password2: "foo123", + strength: "60", + }, + { + name: "match-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + strength: "100", + }, + { name: "mismatch-weak", password1: "foo", password2: "bar", strength: "10" }, + { + name: "mismatch-medium", + password1: "foo123", + password2: "bar", + strength: "60", + }, + { + name: "mismatch-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "bar", + strength: "100", + }, +]; + +/** + * Opens the dialog shown to set the password on a PKCS #12 file being exported. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openSetP12PasswordDialog() { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/setp12password.xhtml", + "", + "", + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +// Tests that the first password textbox is the element that is initially +// focused. +add_task(async function testFocus() { + let [win] = await openSetP12PasswordDialog(); + Assert.equal( + win.document.activeElement, + win.document.getElementById("pw1"), + "First password textbox should have focus" + ); + await BrowserTestUtils.closeWindow(win); +}); + +// Tests that the password strength algorithm used is reasonable, and that the +// Accept button is only enabled if the two passwords match. +add_task(async function testPasswordStrengthAndEquality() { + let [win] = await openSetP12PasswordDialog(); + let password1Textbox = win.document.getElementById("pw1"); + let password2Textbox = win.document.getElementById("pw2"); + let strengthProgressBar = win.document.getElementById("pwmeter"); + + for (let testCase of TEST_CASES) { + password1Textbox.value = testCase.password1; + password2Textbox.value = testCase.password2; + // Setting the value of the password textboxes via |.value| apparently + // doesn't cause the oninput handlers to be called, so we do it here. + password1Textbox.oninput(); + password2Textbox.oninput(); + + Assert.equal( + win.document.getElementById("setp12password").getButton("accept") + .disabled, + password1Textbox.value != password2Textbox.value, + "Actual and expected accept button disable state should " + + `match for ${testCase.name}` + ); + Assert.equal( + strengthProgressBar.value, + testCase.strength, + `Actual and expected strength value should match for ${testCase.name}` + ); + } + + await BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openSetP12PasswordDialog(); + const password = "fooBAR 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三"; + win.document.getElementById("pw1").value = password; + win.document.getElementById("pw2").value = password; + info("Accepting dialog"); + win.document.getElementById("setp12password").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.get("confirmedPassword"), + "Return value should signal user confirmed a password" + ); + Assert.equal( + retVals.get("password"), + password, + "Actual and expected password should match" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openSetP12PasswordDialog(); + info("Canceling dialog"); + win.document.getElementById("setp12password").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.get("confirmedPassword"), + "Return value should signal user didn't confirm a password" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js new file mode 100644 index 0000000000..4c278d6c1b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js @@ -0,0 +1,312 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the dialog used for loading PKCS #11 modules. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +const gMockPKCS11ModuleDB = { + addModuleCallCount: 0, + expectedLibPath: "", + expectedModuleName: "", + throwOnAddModule: false, + + addModule(moduleName, libraryFullPath, cryptoMechanismFlags, cipherFlags) { + this.addModuleCallCount++; + Assert.equal( + moduleName, + this.expectedModuleName, + "addModule: Name given should be what's in the name textbox" + ); + Assert.equal( + libraryFullPath, + this.expectedLibPath, + "addModule: Path given should be what's in the path textbox" + ); + Assert.equal( + cryptoMechanismFlags, + 0, + "addModule: No crypto mechanism flags should be passed" + ); + Assert.equal(cipherFlags, 0, "addModule: No cipher flags should be passed"); + + if (this.throwOnAddModule) { + throw new Error(`addModule: Throwing exception`); + } + }, + + deleteModule(moduleName) { + Assert.ok(false, `deleteModule: should not be called`); + }, + + getInternal() { + throw new Error("not expecting getInternal() to be called"); + }, + + getInternalFIPS() { + throw new Error("not expecting getInternalFIPS() to be called"); + }, + + listModules() { + throw new Error("not expecting listModules() to be called"); + }, + + get canToggleFIPS() { + throw new Error("not expecting get canToggleFIPS() to be called"); + }, + + toggleFIPSMode() { + throw new Error("not expecting toggleFIPSMode() to be called"); + }, + + get isFIPSEnabled() { + throw new Error("not expecting get isFIPSEnabled() to be called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPKCS11ModuleDB"]), +}; + +const gMockPromptService = { + alertCallCount: 0, + expectedText: "", + expectedWindow: null, + + alert(parent, dialogTitle, text) { + this.alertCallCount++; + Assert.equal( + parent, + this.expectedWindow, + "alert: Parent should be expected window" + ); + Assert.equal(dialogTitle, null, "alert: Title should be null"); + Assert.equal( + text, + this.expectedText, + "alert: Actual and expected text should match" + ); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]), +}; + +var gMockPKCS11CID = MockRegistrar.register( + "@mozilla.org/security/pkcs11moduledb;1", + gMockPKCS11ModuleDB +); +var gMockPromptServiceCID = MockRegistrar.register( + "@mozilla.org/embedcomp/prompt-service;1", + gMockPromptService +); + +var gMockFilePicker = SpecialPowers.MockFilePicker; +gMockFilePicker.init(window); + +var gTempFile = Services.dirsvc.get("TmpD", Ci.nsIFile); +gTempFile.append("browser_loadPKCS11Module_ui-fakeModule"); + +registerCleanupFunction(() => { + gMockFilePicker.cleanup(); + MockRegistrar.unregister(gMockPKCS11CID); + MockRegistrar.unregister(gMockPromptServiceCID); +}); + +function resetCallCounts() { + gMockPKCS11ModuleDB.addModuleCallCount = 0; + gMockPromptService.alertCallCount = 0; +} + +/** + * Opens the dialog shown to load a PKCS #11 module. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * the window of the opened dialog. + */ +function openLoadModuleDialog() { + let win = window.openDialog( + "chrome://pippki/content/load_device.xhtml", + "", + "" + ); + return new Promise(resolve => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} + +/** + * Presses the browse button and simulates interacting with the file picker that + * should be triggered. + * + * @param {window} win + * The dialog window. + * @param {Boolean} cancel + * If true, the file picker is canceled. If false, gTempFile is chosen in + * the file picker and the file picker is accepted. + */ +async function browseToTempFile(win, cancel) { + gMockFilePicker.showCallback = () => { + gMockFilePicker.setFiles([gTempFile]); + + if (cancel) { + info("MockFilePicker returning cancel"); + return Ci.nsIFilePicker.returnCancel; + } + + info("MockFilePicker returning OK"); + return Ci.nsIFilePicker.returnOK; + }; + + info("Pressing browse button"); + win.document.getElementById("browse").doCommand(); + await TestUtils.topicObserved("LoadPKCS11Module:FilePickHandled"); +} + +add_task(async function testBrowseButton() { + let win = await openLoadModuleDialog(); + let pathBox = win.document.getElementById("device_path"); + let originalPathBoxValue = "expected path if picker is canceled"; + pathBox.value = originalPathBoxValue; + + // Test what happens if the file picker is canceled. + await browseToTempFile(win, true); + Assert.equal( + pathBox.value, + originalPathBoxValue, + "Path shown should be unchanged due to canceled picker" + ); + + // Test what happens if the file picker is not canceled. + await browseToTempFile(win, false); + Assert.equal( + pathBox.value, + gTempFile.path, + "Path shown should be same as the one chosen in the file picker" + ); + + await BrowserTestUtils.closeWindow(win); +}); + +function testAddModuleHelper(win, throwOnAddModule) { + resetCallCounts(); + gMockPKCS11ModuleDB.expectedLibPath = gTempFile.path; + gMockPKCS11ModuleDB.expectedModuleName = "test module"; + gMockPKCS11ModuleDB.throwOnAddModule = throwOnAddModule; + + win.document.getElementById("device_name").value = + gMockPKCS11ModuleDB.expectedModuleName; + win.document.getElementById("device_path").value = + gMockPKCS11ModuleDB.expectedLibPath; + + info("Accepting dialog"); + win.document.getElementById("loaddevice").acceptDialog(); +} + +add_task(async function testAddModuleSuccess() { + let win = await openLoadModuleDialog(); + + testAddModuleHelper(win, false); + await BrowserTestUtils.windowClosed(win); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 1, + "addModule() should have been called once" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 0, + "alert() should never have been called" + ); +}); + +add_task(async function testAddModuleFailure() { + let win = await openLoadModuleDialog(); + gMockPromptService.expectedText = "Unable to add module"; + gMockPromptService.expectedWindow = win; + + // The exception we throw in addModule is first reported as an uncaught + // exception by XPConnect before an exception is propagated to the actual + // caller. + expectUncaughtException(true); + + testAddModuleHelper(win, true); + expectUncaughtException(false); + // If adding a module fails, the dialog will not close. As such, we have to + // close the window ourselves. + await BrowserTestUtils.closeWindow(win); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 1, + "addModule() should have been called once" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 1, + "alert() should have been called once" + ); +}); + +add_task(async function testCancel() { + let win = await openLoadModuleDialog(); + resetCallCounts(); + + info("Canceling dialog"); + win.document.getElementById("loaddevice").cancelDialog(); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 0, + "addModule() should never have been called" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 0, + "alert() should never have been called" + ); + + await BrowserTestUtils.windowClosed(win); +}); + +async function testModuleNameHelper(moduleName, acceptButtonShouldBeDisabled) { + let win = await openLoadModuleDialog(); + resetCallCounts(); + + info(`Setting Module Name to '${moduleName}'`); + let moduleNameBox = win.document.getElementById("device_name"); + moduleNameBox.value = moduleName; + // this makes this not a great test, but it's the easiest way to simulate this + moduleNameBox.onchange(); + + let dialogNode = win.document.querySelector("dialog"); + Assert.equal( + dialogNode.getAttribute("buttondisabledaccept"), + acceptButtonShouldBeDisabled ? "true" : "", // it's a string + `dialog accept button should ${ + acceptButtonShouldBeDisabled ? "" : "not " + }be disabled` + ); + + return BrowserTestUtils.closeWindow(win); +} + +add_task(async function testEmptyModuleName() { + await testModuleNameHelper("", true); +}); + +add_task(async function testReservedModuleName() { + await testModuleNameHelper("Root Certs", true); +}); + +add_task(async function testAcceptableModuleName() { + await testModuleNameHelper("Some Module Name", false); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem b/security/manager/ssl/tests/mochitest/browser/ca.pem new file mode 100644 index 0000000000..48031d478c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUb2Np/S2xMtQR+BvitAuzKtjWxMswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBPEDwwrdd6h+SHkc0J+p4Ik/yc +aoLWNdGsVD4hJYa0IOgNh6Z/GyhTXM9hr/q0f7fewjfNhXi/nrXNcW5w4FJERhHp +HvZO6Z08i8CrVYSiijFcLf6ClK4e163j0LXUutBWY2PCf4TDS+fnF9PJmle0kPLU +IxqptfSSoCjLuWyYyRmjZIdNCtrNCU9g85SDaUO6l79vBm0TYOLhOiPBN0F7DWXo +JlOZKWEco6qqS22yIM1r/5KNc5ekPTD+UJFh7qprAq0riEfR38DYJmUq3w07q5Tb +HQdG8JHEtemi7dHr/WoJY18MLZaF7BSLAwBWmBWzx8Lj2V+/4TP4NtRWkL7y +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec new file mode 100644 index 0000000000..6660f5d478 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem new file mode 100644 index 0000000000..698b70da88 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUcepT9pQ4IQkGYiLxzM+rfwju1TYwDQYJKoZIhvcNAQEL +BQAwQTEoMCYGA1UEAwwfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEV +MBMGA1UECwwMSW50ZXJtZWRpYXRlMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCcxJTAjBgNVBAMMHGNsaWVudCBjZXJ0IHZpYSBpbnRlcm1lZGlh +dGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUA +A4IBAQAcVbcUEeT+hYt/z82f9Ut81G6QKtq5lr/1ifSkLqV6t7P5chDt7bpujsFw +ZI4jxHLZLL3M1znCSMBNseNRGWLW8cGlapOsO2KDNQdXbHcNJpLxETiWMRp/62Ii +jW2/rdp4wYekjp/lYy6qQDj85N2Zc+zimqz1ELIPHQyxGQUy5uQ78+sE/eLIR8A4 +XvYwyd1pIatfYHkc2pb8LeZAAtSQ9lFQ2sJiBMac2n68wAOj1Dq3AG9MdcBuGMsh +TiA7k4mdBiQywg8QG4GmXoP1j6QDJG0o5/8hIpbo95cmZ81Jye3TsZ8Sbmz3LR1J +6lOk2w1lAfxwCim2cMMZ44StOBsq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec new file mode 100644 index 0000000000..cab2448889 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec @@ -0,0 +1,3 @@ +issuer:/CN=Temporary Certificate Authority/OU=Intermediate +subject:client cert via intermediate +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem new file mode 100644 index 0000000000..a9052d4611 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIUUZw/zP5GmSytJJWBwEzzqZzjcTYwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowKzEpMCcGA1UEAwwgY2xpZW50IGNlcnQgd2l0aCBPQ1NQU2lnbmluZyBla3Uw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjITAfMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDCTANBgkqhkiG +9w0BAQsFAAOCAQEAFuiPgjMg34f/TNocFSU4Qc3hPod0s0W7oH53wp8I3kJXsPGs +/P16w6YJ5dd5R9JZh6xBq63OnhFjS+j1Z6+NXalZrgSD2Q8FVNFS1z3P7bR+GSQ+ +r8ltlqkNV+Wu+Hk6TvfkrZhDX3VQ1IXtXXDQ0SuWLvczrPK3h+GCBE/LG1KybyBw +aHHl8aqXSd7eXcwJF5/hLQlaGZlHHxVh451WHrE1i8/kX+9GdyNwlAXMP9JySqei +YRwQPMa7MPDM5qkmFhlDh4+LWj8ugssv6n+6L5gFRNm6Db52aeNR17H2vezI7OUO +5u0gDZ8IG4XwS1u1IRPxNtK5ZT8uV+BqhOPmhg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec new file mode 100644 index 0000000000..5cbd5af8f0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec @@ -0,0 +1,3 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:client cert with OCSPSigning eku +extension:extKeyUsage:clientAuth,OCSPSigning diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem b/security/manager/ssl/tests/mochitest/browser/code-ee.pem new file mode 100644 index 0000000000..2e5941318a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyDCCAbCgAwIBAgIUUaEQHoacA0ankeJpt9iGsfyV7rYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHY29kZS1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMXMBUwEwYDVR0lBAwwCgYI +KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAADhEW+xHUzkTkX1/RW4aODeW+NM +aSI20y3CtLtF2BDcl08YoCCnPVdbBG/DSbKb+eZecgvKWgHGOPKFRWA4YXm8TXXW +naVEWTDbbspVKjC6GzViuy2CsnNS5Bb5mhnGiMTI/zFvnfE+OwnfPFL+FAsLIaOm +OhyWU6/pwWN3hQytWHK6+QI22A58nVc/vLiyLMfWnn/8Akkolob3gFj0hOZaXYbn +mSSvBmWVTjq/7PfZLb/SD0VfGhbZMx7BebJGkUaikICS1w5F3bnM9ToRzkshhsBw +9nI7Kq8kff8PHBSaVWR36Ygix157D7bMiGuZ5ZLpXAayYcXhGQhhIZs2+lE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec new file mode 100644 index 0000000000..93f9a84265 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:code-ee +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem new file mode 100644 index 0000000000..f4ff304c1c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwjCCAaqgAwIBAgIUa3NpO02kyKRl+mnC7LrTUIC0W8EwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKZXhwaXJlZC1jYTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAdMRswGQYDVQQDDBJlZS1mcm9tLWV4cGlyZWQtY2EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAB7gNu/A0HmfIZQmKxaZno6txhlnzqU3jtCy +TwmiYWpqCJgjNHdKKaPDNTILaDtcPtdG55JqbIxbv3mpHfbiwy9XLSYT56V3/XJy +buMpUpXYTpsm+bXfU6aqsndiGwwuSSSrKP0MHi3R9hz/A+3hOqldu+a0d6zs4ByK +YSjAvQwORGgLf0cLRY0CIroiMttCC2x1whvwVl4jWsa3p0wciRstsIwHUxbhcGJC +R8bKFvK0VbNxcvyU3zwWwFnN+3ACBJT8ucI+MStFtR4oCILvvo0kL1O9C+tpWhEA +9b7J+h9WJVroYvfDIjvuYrdkeBhaQaSk0b1WvO+0ZGKGstLFC/c= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec new file mode 100644 index 0000000000..3e280fc4fc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:expired-ca +subject:ee-from-expired-ca diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem new file mode 100644 index 0000000000..890292763c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUd3uwPuHZt768G7dbGuv/MlnjS4YwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMdW50cnVzdGVkLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGVlLWZyb20tdW50cnVzdGVkLWNh +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCE43NUMM7jR2Xic3/8RdN8axQxqqnA +YlRedr8BaEVDdiwneEG17EEGil1NU/a2DyBn6OC0I9Xx7NaB4ukYcJqheaczMHkG +1SvpddaNmjteAtdfc+vQ2ktvwvVAi+wQDtV23Bz5kgYvONRHhk2NgTb/HPrAyG3x +jg40Gi6wePb2vrzXQUxat88AEqh7BjCkeyJSXu/o56Pxo+TxHMX8QlZhaFT22Kj+ +J5u+WXEYygNdeTwDfIsyh0a6R/Eko+onzcT4JkNdFwI5u5bmoDQn1SjW1MBCmhJy +Css4M/wP5BY4RzgbKA2uDdVQ2M2xPg2IeGi3bS4qwlUNNPm1iOx8WlZK +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec new file mode 100644 index 0000000000..833e1a23a6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:untrusted-ca +subject:ee-from-untrusted-ca diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem b/security/manager/ssl/tests/mochitest/browser/email-ee.pem new file mode 100644 index 0000000000..eb51c01b1b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUZcgkXcHN7EQAuaIttjnYPdQFvOIwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZW1haWwtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoG +CCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4IBAQBSMjBmd3FC9Q/AOByGmK8GhlFk +XhlBYmeVmxDJVDN0Z3OIcZUK1DWUl9M7hLJAUMbanng0jF98npAO1exDYx5ECyhV +SEe+KjfsQuPj7AS0zb60Uf/4w7b5dFW3y1pKo2ruEoPWvjLzR4IYfkc5p+utc1VT +0m568rEnF8dDGF19/FpsVjnzfwa8vmafXyXrogocOjk3qxRpx2wUqotbDwz6qDA1 +N/+LeE5+WHEgVDPF22BBECf/iPi1mUQQLURoUbQ499ELSZIRfIzI/MQUHBrF4Cx1 +TRnTDRhtzWvrcSaDBplLZzxTTWNhExwQUlg2rdFAPd9rdLuraimsLcly8xUC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec new file mode 100644 index 0000000000..82e3296706 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:email-ee +extension:extKeyUsage:emailProtection diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem new file mode 100644 index 0000000000..e019b37127 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUS6xUkMzG2REizII2g+VecO/KqX8wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDExMDEwMTAw +MDAwMFowFTETMBEGA1UEAwwKZXhwaXJlZC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABJdjrt25wocw4aP +eR1kZuu3WS0bKfuvhQQPFkAG+HYSC5eu0OriQCRlxn+qHY7du9dePcD6DTMDIVDW +r+oBJ9BwCEREyTcV8AEaHdcTAakXOMhq6OOltl6HUu3lSlqRslzAhtl1chM0P8m1 +Aj+ceOkCFHvnsDd+zcSP75u8zzJKypSWQwAg/i5S0BNLOWYarPiczuYi4HAOpwtX +QqlmDNMYySqPFfH72BuQdCLuviBXmMP8/kOouBNP4ti06RR88XgqfoL/jV4gkIM7 +92hXt0WpS/QffjWzLaej39YhW4pMZ+hF4bk9nUCtN/MHtg8WDj1CgfSJZegrl28W +3riMotA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec new file mode 100644 index 0000000000..15bdcd7d73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:expired-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:20100101-20110101 diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem b/security/manager/ssl/tests/mochitest/browser/has-cn.pem new file mode 100644 index 0000000000..f334d5a887 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUXfOLVuh26E15Y2GJNpqg+kEUVBEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowNzEMMAoGA1UEAwwDRm9vMQwwCgYDVQQLDANCYXIxDDAKBgNVBAoMA0Jh +ejELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAI8sysFQZh4G +EZKpcpOiGC0KLdbzkYAoALxjgvI+WPgOQBQBHSLGGTeIAe677xToSO6E/n9xocMh +62YRiZc5PGpUb+T7hinZ1pq+10SXN5ERZKJiKbDfp4iUStySiRs3OL0tNpnjtcVv +gIMZRcGr50vWBebe8fCRa/TFA3TilspiTjmRZCS6dUO7YHW8aMPWfG4gaSBF8E+6 +JCoK7YL1R/JxP4y7uAoU5+xfDBmC/vOUekUYZOH8w4Vs7dijC+weUU4zhe2L+QMb +OC1SyG1/MZ9Orzetz3tYGZ0shZTONn/wjAnzRrUGRUmAl+LVlW+Wxs1YL3TjKqTr +0QZaPOUVoms= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec new file mode 100644 index 0000000000..a4a0fcb5fa --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/CN=Foo/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem new file mode 100644 index 0000000000..e4cf5a14fd --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICijCCAXKgAwIBAgIBCjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJjYTAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAAMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQAMkmx5NF2dju8/ckdgRK2M3fvoyEmBAYLOjWNh5ZfBX7VL +vL6bjzwcwza41feaDwgZbIWzzqKwVJhkOb9ULFMFlkEO0k2WhvTpEc/ELJnE1uCr +qKokl0b5BdllNGQQ9tSzhAwWumjfkhmVRZXziawWIiquA2UzowsdQX7Qf675Ae1e +B9WJvTxfxfSscON3xKAThOcMbjs5G9SaIp+C43qRJMn2KBsbu0qmWuMXG7Iy7Dbd +ak9CD2QG9tKDYOgjcvZRxdyErfjfIRoz3/4fiac7Ca6ooSc+TCF7va1yHNqhaYcH +VNTl7xyArMu5uPXtcLwEBudlJgPNuLy5A3HgChh4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec new file mode 100644 index 0000000000..6346f7b83a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject: +serialNumber:10 diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem new file mode 100644 index 0000000000..85bd93c62a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqjCCAZKgAwIBAgIUQ1K/9yfCiqPsZYUo+7EBrddrWTowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJXk +OiIktljwCkbDVVSyHlMX/kXOlzt4sVjWfL/YyFIaNVuiUpOYfEXlYFUc7nX8PXsL +a4RvATrJ90fUcGxHqWdqJr19zrWW5co+vjDNFMTFFltootym0fQocq55JvVUK9ml +BmZ+B60I82gI7L/M1NCPkylNvrG/UdD034pqY4ppgu6z/9lH6P6EpXZPseo6Ofx8 +tpSeTfYdtebvBbAkWmel56jzyN6C40ddIIjVHYKfLFgFsuavVhbwMm0AB1dFCnGQ +06x1QGsAthQ7C7q7mYtoe+TZ6sHahUofE4gNJyQprIyBn/Itae/H6qO6qBewoYWX +cBATil0Vqe2ZQ7FS5nk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec new file mode 100644 index 0000000000..cc1b668a63 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem b/security/manager/ssl/tests/mochitest/browser/has-o.pem new file mode 100644 index 0000000000..9e4d7e3a28 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUL+2cA4H9fH3BS4yDvSfNqAx+SDkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEMMAoGA1UECgwDQmF6MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEABlpU9dWi5TSGL0CISRugnOlpBATWlZbB2UYqN4H8n0R9mA28 +ss8F7+dzWq9yldVP5shpCqoHYbKgvcKwM7ki7l3QjaKvk4jqkxkp+0qw7LlNreFB +9xH86vn0zcu/9PUYVjAAS2B5pObLhf0RpdS9km026WpL11o298hbuR8sOeADAPwh +yqxrZz8i+ZCzBzwgNGGIwcgfpIRSQD+4rbpN5h2r3HmZupRuChA5rGR/z3xywD4J +/81ELM7raPXtq15RoUUc/dR4rIqgDwI8zOL4zndw5Eiuxmw79BnsW7ziXSgZw2rJ +vpxukd+42dBTnPEPHlFVZlnjn4zd97YwnuKXgw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec new file mode 100644 index 0000000000..f7cc3ffc73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem b/security/manager/ssl/tests/mochitest/browser/has-ou.pem new file mode 100644 index 0000000000..dfb8b2266b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUB17J0zfbRaw+XdVWt9xzDjrY3o0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKTEMMAoGA1UECwwDQmFyMQwwCgYDVQQKDANCYXoxCzAJBgNVBAYTAlVT +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQB83qFAuJObc3l0cOKL6NW2krNxkt/X +ynRDZV1oVJ8Bw5vKb4PX8owP/answOwYsBK+Sy0g2+Y/JvhaI+PD/i/2MjwdP8qu +vRXKGbbtfgKqfBonwZl1/6BNNS65Mb0Z1VLdE1Ah79afpHamppD07O7cqA+Hw2qj +9mnoDoAiCBKDdKHDp+wLs7mUh8JSIOb0ZWkCqtED5l81KUB4T0bOI0HCuS15Zu+E +wWCGw0w3Un0W0l6sUVIE23J1exo6qJKk9gFWl3mOOZLOCT4Rgpvwyx13PpzU4JqS +vrxcuwwPKtEo7+smxl3DSpU/Vq0cuYbc2aS1xlCU2Vpl1VBNmao5KKAo +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec new file mode 100644 index 0000000000..8879dabf51 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/head.js b/security/manager/ssl/tests/mochitest/browser/head.js new file mode 100644 index 0000000000..af3c62ca43 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/head.js @@ -0,0 +1,83 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * List of certs imported via readCertificate(). Certs in this list are + * automatically deleted from the cert DB when a test including this head file + * finishes. + * @type nsIX509Cert[] + */ +var gImportedCerts = []; + +registerCleanupFunction(() => { + for (let cert of gImportedCerts) { + gCertDB.deleteCertificate(cert); + } +}); + +// This function serves the same purpose as the one defined in head_psm.js. +function pemToBase64(pem) { + return pem + .replace(/-----BEGIN CERTIFICATE-----/, "") + .replace(/-----END CERTIFICATE-----/, "") + .replace(/[\r\n]/g, ""); +} + +/** + * Given the filename of a certificate, returns a promise that will resolve with + * a handle to the certificate when that certificate has been read and imported + * with the given trust settings. + * + * Certs imported via this function will automatically be deleted from the cert + * DB once the calling test finishes. + * + * @param {String} filename + * The filename of the certificate (assumed to be in the same directory). + * @param {String} trustString + * A string describing how the certificate should be trusted (see + * `certutil -A --help`). + * @return {Promise} + * A promise that will resolve with a handle to the certificate. + */ +function readCertificate(filename, trustString) { + return OS.File.read(getTestFilePath(filename)).then( + data => { + let decoder = new TextDecoder(); + let pem = decoder.decode(data); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let base64 = pemToBase64(pem); + certdb.addCertFromBase64(base64, trustString); + let cert = certdb.constructX509FromBase64(base64); + gImportedCerts.push(cert); + return cert; + }, + error => { + throw error; + } + ); +} + +/** + * Asynchronously opens the certificate manager. + * + * @return {Window} a handle on the opened certificate manager window + */ +async function openCertManager() { + let win = window.openDialog("chrome://pippki/content/certManager.xhtml"); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/intermediate.pem b/security/manager/ssl/tests/mochitest/browser/intermediate.pem new file mode 100644 index 0000000000..dd9c5ec6c5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUf/ZI9pFYXbeWG/5AXJ9EJIgxBtcwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowQTEoMCYGA1UEAwwfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEV +MBMGA1UECwwMSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKO/vWs1AonZSTOAG+k2uA+HF +m6clrXdQxq3cbXG/bHT1c1lMNLu8p3HYojZq4S6394iNDFBKR/EV0RIdYRVW8NOJ +zfEFK4HIh6ReH5JBNbNqGGBbxBu1OR4UGXiTiKJh8VAPcuKhb01lAlkmmLWwE0em +rX3YaC7syGCQX/7Il3W8Kt4xvPjTkx8UX6+SiIezaw9thUAFvynaYK+1uw3/3W31 +ObPIQke9dKhth/3+87zrmiZI95CdCpWXzsL48OJseU53HpEnA3Du0CHQYLWrAS+T +fQIyV1qGMIXYRP0QW4eBVfVlKfACYZqRMOozR5AXIBp3ns5t3MXlyWS/0uAfJA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec b/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec new file mode 100644 index 0000000000..a562814041 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:/CN=Temporary Certificate Authority/OU=Intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem b/security/manager/ssl/tests/mochitest/browser/invalid.pem new file mode 100644 index 0000000000..dc8c0730fc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwDCCAaigAwIBAgIUaXqQ23/rq8JrbOwIIDACtHsydH0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHaW52YWxpZDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4IBAQAUtQnvaYAoyfHVMIPYiEctg/dBhiqjp1ZYUbQO +nIuHETKtzTLUGJOSNFBIAaDcGHvJH7K4Ldp74+73EwDpGlK/wOQ4Of57pfNlYuCe +PQ9CGRKsEGSPsE6w9EstcbnEvqZJmKFY+YEJU936KqJOA052EMBnW3dy2sXwqyX5 +zzNKSC5+3gLGn2rk0Xa1CIyZpNSGLP5Q801iO7bXXkKG5rOV0FTfR1mu39vnu/RI +vO7BdLSbGPfdAv0io6aFLYw3kP5vSLFzUAoYHxrPokIoEM7pZtlSfECAXengcfis +L5WYqNQ3Y+XXf02VaRhEGnyL1MMmPGVpvBwWAJnR97YSfylx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec new file mode 100644 index 0000000000..71a1707c35 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:invalid +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/longOID.pem b/security/manager/ssl/tests/mochitest/browser/longOID.pem new file mode 100644 index 0000000000..a966355b2d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/longOID.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgIUUUlZgo9gztazitkyNqsantBeQO4wDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwITG9uZyBPSUQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIy +MDIwNTAwMDAwMFowEzERMA8GA1UEAwwITG9uZyBPSUQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjggGQMIIBjDAM +BgNVHRMEBTADAQH/MIIBegYDVR0gBIIBcTCCAW0wggFpBoIBZSqD3OuTf4Pc65N/ +g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zr +k3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D +3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuT +f4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc +65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/ +g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zr +k3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D +3OuTf4Pc65N/ATANBgkqhkiG9w0BAQsFAAOCAQEAcsD8I4kt/jjepOgtZMI38IB5 +wRhrnfvGvPE7/1mWkQyz2tRRdbMOrhLrWzMHjZwQtwWmEeQczPVeXHEyt9Sz+v0/ +rghH+32VAPI6fDYzj9KNBn60sNiLCBlOucegpW/Dechcf25O/xhF6G9ljU2RIbpj +BAwTGd9gIYOpuAYGprht9d9smznPkO5qBpU7GV1SOzzhAldFYOMuYvjpgvtL7UXJ +2FhaWxyC11Sw1aUdm8V93Mf4rs8RzizjY/4pKyl6yRarNXx7lP6qf95fWi0A3LYT +3giV0e6NKrWjGLl1vnj8919wTzsh3OsVaAKDQNMz3I9/ENdDHMFl0WpAWjfQpg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec b/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec new file mode 100644 index 0000000000..c3c08ac84b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec @@ -0,0 +1,4 @@ +issuer:Long OID +subject:Long OID +extension:basicConstraints:cA, +extension:certificatePolicies:1.2.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.1 diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem new file mode 100644 index 0000000000..39fab2dbea --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAZagAwIBAgIUCR+2dzKgSt0CBU86EgRdJIa/72owDQYJKoZIhvcNAQEE +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGbWQ1LWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEBBAUAA4IB +AQArfDtm5sEuzsPZps2oZhvrOYRViP0sRIAbAjuJVnAMA/7xLzI3LweXOlQJHBh3 +m3mrPUMAXfr4xJ5XjGySqHBUtFat9EBl/0bynd67sCMA7UOf51GC4ABOPAV0CkDj +/FNqL/KSt8WB90FW+ZKnt1ojKikMIjmPjxDaaHj7KZVBQ2KtBEz1Igt5Bvbrp2AM +NvjyhUCN4/z4NDPPbzkeDKYC7vmvYhN1Cs/73Jp3A0LU4z0gIyrWi6a7YEAVBzhI +vJJ98U8AQQMm+iiIDGZMoAZyvEFouofF9te4xMHStUnYfa1jLY93dL1TuXrWvKB0 +pWg4REoQuFZUE8GS/LczW5xX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec new file mode 100644 index 0000000000..279c158026 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:md5-ee +signature:md5WithRSAEncryption diff --git a/security/manager/ssl/tests/mochitest/browser/moz.build b/security/manager/ssl/tests/mochitest/browser/moz.build new file mode 100644 index 0000000000..51ea96f9e2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/moz.build @@ -0,0 +1,41 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +BROWSER_CHROME_MANIFESTS += ["browser.ini"] + +# Temporarily disabled. See bug 1256495. +# (Note that when this gets enabled, some extra work will have to happen so +# that the mochitest harness knows where to get the generated certificates - +# right now it assumes they're in the source directory, which isn't the case +# when they're automatically generated.) +# test_certificates = ( +# 'ca.pem', +# 'client-cert-via-intermediate.pem', +# 'client-cert-with-ocsp-signing.pem', +# 'code-ee.pem', +# 'ee-from-expired-ca.pem', +# 'ee-from-untrusted-ca.pem', +# 'email-ee.pem', +# 'expired-ca.pem', +# 'has-cn.pem', +# 'has-empty-subject.pem', +# 'has-non-empty-subject.pem', +# 'has-o.pem', +# 'has-ou.pem', +# 'intermediate.pem', +# 'invalid.pem', +# 'longOID.pem', +# 'md5-ee.pem', +# 'pgo-ca-all-usages.pem', +# 'pgo-ca-regular-usages.pem', +# 'revoked.pem', +# 'ssl-ee.pem', +# 'unknown-issuer.pem', +# 'untrusted-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem new file mode 100644 index 0000000000..b67283580b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgzCCAmugAwIBAgIUCYMVPDJVUSkrLVxErDqoXsUuy2AwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgH+MA0GCSqGSIb3DQEBCwUAA4IBAQBXqqT2fBXtmQaPHr86unEVaXirLmnc9qR2 +yMhrBSbZP1w6MWQDD/TWXjnjqeADqXZy1feI/yBBQDnkJa1x4IVz5oujQDuf/chQ +vAemh7t7DhyfIZ+OQCMadSIOva06PhQuiwYXqM3Pg5MyBNp8NKP9fwSri39if4ru +4VgSudV5yo2Z/pduJMl2zFGsu+ZbYco0AKqN4RX7Rwkp7Uf7uiizgAPVEpCrm+Ja +EJUitKh1ejVH3SakdUfQEboQYsZl9c2S5/oKUlON4weoYctvc0zQkscRnqyuBkBJ +RB/YMKaHcphMRfmJFbwA5Vs0AOJ5E9u/hhvhcdBL6ZTUi3uEermS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..4def496f67 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem new file mode 100644 index 0000000000..c52d36d1bc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgzCCAmugAwIBAgIUF5e1WSjUvqgAuz9/WyPcq+OgkOAwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgEGMA0GCSqGSIb3DQEBCwUAA4IBAQA2+3qj2Bme+jVFlNva/gyvL0QOg8lgDc++ +pWTDd+NMpeqwarX6z4+wjzXh9ZPKk29alBWpnhVVvD4WAOa1TSLbevTlV+viGloP +uvZwoxn6naumwv992hJS8TJda8ZgKB5N5REdsDoD1hWeLevjWACMToSaXN+Bx8jF +GFoh1ifj1SD4DN51sc4KkKscjcSbBwyWJUCJGsDw7H5FtSSNEfGnctdsoLCWS84z +Jw/WUs/3hOB+MRsdqPBISlLrd5fnmL6RL7ZkDqad1Fi69GZQBDZUBmTxXhNl4VHK +RkQZCVLg9YWDzaKDj1Q326+sSur3PvQGJBplMEOWIOz/MVs2skeT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec new file mode 100644 index 0000000000..448e167bd0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem b/security/manager/ssl/tests/mochitest/browser/revoked.pem new file mode 100644 index 0000000000..02c06872e1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrzCCAZegAwIBAgIUJf4afZUeBhMdHovc6HjvffKmXJYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHcmV2b2tlZDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAKYqs7wd9/1ufx9s+YsRsd/MBRE/figWWVI+Gha3qLnx2NI7389n9qY8ES0az +bqNV71w8qYcn8tzlLCTLrgkhnt/rkMwXorvI+vfF+7fQeFlqFgXw46WxM4NtzLTz +0Hdt3+QULysZdG/my/HB1mcBWPRSrSZer7s1oKRcsoNgbSvmuyIWrrUVmn/tiaKy +kC5oOADLIoSHeGh4SvyUnP1oF3Aq5vxsykd66q/bP4MrmZinlJYNq/ybeEvrTEuA +XrBkRkslcVE6+VS/1ieT/5aa4IUyQ7DYy8i+IyspkD0xJ6cklSNodMl55odQK67Y +iC/MEn7uG9DJmwEH0ZN6Qxc3LA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec new file mode 100644 index 0000000000..daf75c670f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:revoked diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem new file mode 100644 index 0000000000..aff528d39b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUU9i1j3V1LGw7IBlKgfVezTka1I0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGc3NsLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyEwHzAdBgNVHSUEFjAUBggr +BgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBACoLO/x/rat1m2td +0FMcOoXAJiTmHIIg22yC7RgFZxkSxnp8Wr2cevTUkBhwsITD6I7T6UTkqwnaXFBt +eeTxYuGoYx7VdefLNvAIdBKWZgtMvBr9+KHrhoFXOxL/+7oBFjFH0EP7B53aflJc +/rVf0CUb4iwS3ebjk5wOLZhB+sk3PfuzsdSOPjpUQZSmni/hI1d+Am1Kn0Qs0COI +0SPezVt7U5Gr0Ewc3eP2fI1I7YJbWKP/s5bd0C/aWW+tLBWxolYT3X4+S/7Bg52N +bCxwkd5GHJZkpA/M2++kiDQVfedMsN2E7IlsXILxckQsGlODJgrSbQb9vIYP1hGm +ryWS8kc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec new file mode 100644 index 0000000000..c4037675f1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ssl-ee +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem new file mode 100644 index 0000000000..ef4515983d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIUI0xny6j77OiAn+msMVdsgBLMj/swDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHdW5rbm93bjAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAZMRcwFQYDVQQDDA51bmtub3duLWlzc3VlcjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEAP/jp5cJkeSP5DmAgvymt6zviEHmm24nHgHuLDwTPf446 +pCl4YGFSwzV44d6503AyFNOUbTg+l+2lOpG3CU3mDi+agcG+r4QEG3a01Mh9uWfB +I60VBHfQwq4yoA7gwnhUyf5dEOgwJkerc8uZMaoVv0OlRjp89ycqkmBjHpzRUR9A +6WzIKzA69foFI5b2UVMtUuXAZPyzPep2D35XNc1iSA4OsA5IhLJD7n7caQKoEiYv +i6A0Ze4ZgOHU/w7Aj+DUjq8JK85cdpUksCxAnPGannRhpK90/uc+d6IyovxjCdo1 +YQCfU6R3RXWPQmhHRxrQX6LMde5sxUADtW/GDutaAQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec new file mode 100644 index 0000000000..c76a4e2c7b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec @@ -0,0 +1,2 @@ +issuer:unknown +subject:unknown-issuer diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem new file mode 100644 index 0000000000..0be7744cc8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUA0ih/Zea7LtjFynUOzwIwcOQCjkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMdW50cnVzdGVkLWNhMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAb7HneKXYzHjB +ehF6bTye2hTACi84WqaW9c2K7KrqBa+zqR+/aF5pjRdlYoSOOiAKIWzHdJZYY0sh +fgoDFCCYuPg6Bim4AVthRxMDn07TDAkSxAV+M1P3bJLEeWx3/muTL0t98P/JXTS3 +GfmXjcWJ1E1bCMSrUclSk9Y6AKhyIOeapB0YovhvP8fWLso9RT7mv7W/xGmWohhP +bdjjislgWouFtOWBrata/u4ifS3hsBpYESXL9D2EzdoDtgzRG0yetCLmxTogfDqm +MeW75eQqQYiqU+VfnbvI46AvI9ihfXXzEfqVSzKkLwuYKiPa42QtU/sLNTbZeSqB +bR9mMRqyKQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec new file mode 100644 index 0000000000..04f4430574 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:untrusted-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs new file mode 100644 index 0000000000..8e9afb098c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.write("<html><body>hello!</body></html>"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/backward.html b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html new file mode 100644 index 0000000000..8699a07dda --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="text/javascript"> + "use strict"; + window.onload = function() + { + window.setTimeout(function() + { + SpecialPowers.wrap(window).docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .goBack(); + }, 100); + }; + + </script> +</head> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js new file mode 100644 index 0000000000..9d67ba1f92 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js @@ -0,0 +1,11 @@ +/* import-globals-from mixedContentTest.js */ +"use strict"; + +document.open(); +// eslint-disable-next-line no-unsanitized/method +document.write("This is insecure XSS script " + document.cookie); +isSecurityState( + "broken", + "security broken after document write from unsecure script" +); +finish(); diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html new file mode 100644 index 0000000000..4bbf9bfe8c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test, step 2</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/does_not_exist.css"> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + window.onload = function runTest() { + window.setTimeout(function () { + window.location = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html?runtest"; + }, 0); + }; + + async function afterNavigationTest() + { + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html new file mode 100644 index 0000000000..276c2343fd --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test, final step</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("secure", "secure page after insecure download and insecure subcontent still secure"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "still secure after back/forward"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto new file mode 100644 index 0000000000..4d2fb7d5ae --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto @@ -0,0 +1 @@ +Temporary file for security/mixedconent tests
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ new file mode 100644 index 0000000000..9c3159e153 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ @@ -0,0 +1,2 @@ +Content-disposition: "attachment" +Content-type: application/x-auto-download diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs new file mode 100644 index 0000000000..5cce2826f8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + //response.setHeader("Content-type", "image/gif"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs new file mode 100644 index 0000000000..20d9dea829 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-type", "image/bitmap"); + + let bmpheader = "\x42\x4D\x36\x10\x0E\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\xE0\x01\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x00\x10\x0E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + let bmpdatapiece = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + response.bodyOutputStream.write(bmpheader, 54); + // Fill 640*480*3 nulls + for (let i = 0; i < (640 * 480 * 3) / 64; ++i) + response.bodyOutputStream.write(bmpdatapiece, 64); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html new file mode 100644 index 0000000000..064783e0cb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + This is frame 1: + <script> + "use strict"; + // eslint-disable-next-line no-unsanitized/method + document.write(location.href); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html new file mode 100644 index 0000000000..37fc604ea6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + This is frame 2: + <script> + "use strict"; + // eslint-disable-next-line no-unsanitized/method + document.write(location.href); + </script> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html new file mode 100644 index 0000000000..6c7a5473cb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html @@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<META http-equiv="Refresh" + Content="0; URL=http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"> +<html> + <body> + Redirecting by meta tag... + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs new file mode 100644 index 0000000000..ea93b80b7d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs new file mode 100644 index 0000000000..937e29954f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs new file mode 100644 index 0000000000..7af6116e10 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs new file mode 100644 index 0000000000..a8eb26642a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js new file mode 100644 index 0000000000..6c300b7fc3 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js @@ -0,0 +1,211 @@ +"use strict"; + +/** + * Helper script for mixed content testing. It opens a new top-level window + * from a secure origin and '?runtest' query. That tells us to run the test + * body, function runTest(). Then we wait for call of finish(). On its first + * call it loads helper page 'backward.html' that immediately navigates + * back to the test secure test. This checks the bfcache. We got second call + * to onload and this time we call afterNavigationTest() function to let the + * test check security state after re-navigation back. Then we again wait for + * finish() call, that this time finishes completelly the test. + */ + +// Tells the framework if to load the test in an insecure page (http://) +var loadAsInsecure = false; +// Set true to bypass the navigation forward/back test +var bypassNavigationTest = false; +// Set true to do forward/back navigation over an http:// page, test state leaks +var navigateToInsecure = false; +// Open the test in two separate windows, test requests sharing among windows +var openTwoWindows = false; +// Override the name of the test page to load, useful e.g. to prevent load +// of images or other content before the test starts; this is actually +// a 'redirect' to a different test page. +var testPage = ""; +// Assign a function to this variable to have a clean up at the end +var testCleanUp = null; +// Contains mixed active content that needs to load to run the test +var hasMixedActiveContent = false; + +// Internal variables +var _windowCount = 0; + +window.onload = async function onLoad() { + if (location.search == "?runtest") { + try { + if (history.length == 1) { + // Each test that includes this helper file is supposed to define + // runTest(). See the top level comment. + await runTest(); // eslint-disable-line no-undef + } else { + // Each test that includes this helper file is supposed to define + // afterNavigationTest(). See the top level comment. + await afterNavigationTest(); // eslint-disable-line no-undef + } + } catch (ex) { + ok(false, "Exception thrown during test: " + ex); + finish(); + } + } else { + window.addEventListener("message", onMessageReceived); + + let secureTestLocation = loadAsInsecure + ? "http://example.com" + : "https://example.com"; + secureTestLocation += location.pathname; + if (testPage != "") { + let array = secureTestLocation.split("/"); + array.pop(); + array.push(testPage); + secureTestLocation = array.join("/"); + } + secureTestLocation += "?runtest"; + + if (hasMixedActiveContent) { + SpecialPowers.pushPrefEnv( + { set: [["security.mixed_content.block_active_content", false]] }, + null + ); + } + if (openTwoWindows) { + _windowCount = 2; + window.open(secureTestLocation, "_new1", ""); + window.open(secureTestLocation, "_new2", ""); + } else { + _windowCount = 1; + window.open(secureTestLocation); + } + } +}; + +function onMessageReceived(event) { + switch (event.data) { + // Indication of all test parts finish (from any of the frames) + case "done": + if (--_windowCount == 0) { + if (testCleanUp) { + testCleanUp(); + } + if (hasMixedActiveContent) { + SpecialPowers.popPrefEnv(null); + } + + SimpleTest.finish(); + } + break; + + // Any other message is an error or success message of a test. + default: + SimpleTest.ok(!event.data.match(/^FAILURE/), event.data); + break; + } +} + +function postMsg(message) { + opener.postMessage(message, "http://mochi.test:8888"); +} + +function finish() { + if (history.length == 1 && !bypassNavigationTest) { + window.setTimeout(() => { + window.location.assign( + navigateToInsecure + ? "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" + : "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" + ); + }, 0); + } else { + postMsg("done"); + window.close(); + } +} + +function ok(a, message) { + if (!a) { + postMsg("FAILURE: " + message); + } else { + postMsg(message); + } +} + +function is(a, b, message) { + if (a != b) { + postMsg(`FAILURE: ${message}, expected ${b} got ${a}`); + } else { + postMsg(`${message}, expected ${b} got ${a}`); + } +} + +async function isSecurityState(expectedState, message, test) { + if (!test) { + test = ok; + } + + let state = await SpecialPowers.getSecurityState(window); + + let isInsecure = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_INSECURE; + let isBroken = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_BROKEN; + let isEV = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL; + + let gotState = "secure"; + if (isInsecure) { + gotState = "insecure"; + } else if (isBroken) { + gotState = "broken"; + } else if (isEV) { + gotState = "EV"; + } + + test( + gotState == expectedState, + (message || "") + ", expected " + expectedState + " got " + gotState + ); + + switch (expectedState) { + case "insecure": + test( + isInsecure && !isBroken && !isEV, + "for 'insecure' excpected flags [1,0,0], " + (message || "") + ); + break; + case "broken": + test( + !isInsecure && isBroken && !isEV, + "for 'broken' expected flags [0,1,0], " + (message || "") + ); + break; + case "secure": + test( + !isInsecure && !isBroken && !isEV, + "for 'secure' expected flags [0,0,0], " + (message || "") + ); + break; + case "EV": + test( + !isInsecure && !isBroken && isEV, + "for 'EV' expected flags [0,0,1], " + (message || "") + ); + break; + default: + throw new Error("Invalid isSecurityState state"); + } +} + +function waitForSecurityState(expectedState, callback) { + let roundsLeft = 200; // Wait for 20 seconds (=200*100ms) + let interval = window.setInterval(async () => { + await isSecurityState(expectedState, "", isok => { + if (isok) { + roundsLeft = 0; + } + }); + if (!roundsLeft--) { + window.clearInterval(interval); + callback(); + } + }, 100); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini new file mode 100644 index 0000000000..b63031004f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini @@ -0,0 +1,65 @@ +[DEFAULT] +prefs = + security.mixed_content.upgrade_display_content=false +support-files = + alloworigin.sjs + backward.html + bug329869.js + bug383369step2.html + bug383369step3.html + download.auto + download.auto^headers^ + emptyimage.sjs + hugebmp.sjs + iframe.html + iframe2.html + iframeMetaRedirect.html + iframesecredirect.sjs + iframeunsecredirect.sjs + imgsecredirect.sjs + imgunsecredirect.sjs + mixedContentTest.js + moonsurface.jpg + nocontent.sjs + redirecttoemptyimage.sjs + somestyle.css + unsecureIframe.html + unsecurePictureDup.html + +[test_bug329869.html] +[test_bug383369.html] +skip-if = toolkit == 'android' +[test_bug455367.html] +[test_bug472986.html] +[test_bug477118.html] +[test_bug521461.html] +[test_cssBefore1.html] +[test_cssContent1.html] +[test_cssContent2.html] +[test_documentWrite1.html] +[test_documentWrite2.html] +[test_dynDelayedUnsecurePicture.html] +[test_dynDelayedUnsecureXHR.html] +[test_dynUnsecureBackground.html] +[test_dynUnsecureIframeRedirect.html] +[test_dynUnsecurePicture.html] +[test_dynUnsecurePicturePreload.html] +[test_dynUnsecureRedirect.html] +disabled=intermitently fails, quite often, bug 487402 +[test_innerHtmlDelayedUnsecurePicture.html] +[test_innerHtmlUnsecurePicture.html] +[test_javascriptPicture.html] +[test_secureAll.html] +[test_securePicture.html] +[test_unsecureBackground.html] +[test_unsecureCSS.html] +[test_unsecureIframe.html] +[test_unsecureIframe2.html] +[test_unsecureIframeMetaRedirect.html] +disabled=intermittently fails, less often, bug 487632 +[test_unsecureIframeRedirect.html] +[test_unsecurePicture.html] +[test_unsecurePictureDup.html] +[test_unsecurePictureInIframe.html] +[test_unsecureRedirect.html] +skip-if = verify && debug && (os == 'linux' || os == 'mac') diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg Binary files differnew file mode 100644 index 0000000000..c0ffca256a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moz.build b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build new file mode 100644 index 0000000000..7c990fbc62 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +MOCHITEST_MANIFESTS += ["mochitest.ini"] diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs new file mode 100644 index 0000000000..53fa4bc0c2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 204, "No Content"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs new file mode 100644 index 0000000000..4d85e16581 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css new file mode 100644 index 0000000000..9867e3c41e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css @@ -0,0 +1,4 @@ +body +{ + background-color: lightBlue; +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html new file mode 100644 index 0000000000..ccb9a8d9cf --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>dymanic script load</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("secure"); + window.setTimeout(function () { + let newElement = document.createElement("script"); + newElement.src = "http://example.org/tests/security/manager/ssl/tests/" + + "mochitest/mixedcontent/bug329869.js"; + document.body.appendChild(newElement); + }, 0); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "when we navigate back, we're loading our secure page again and not loading an insecure script, so our security state is secure"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html new file mode 100644 index 0000000000..d45d5eb761 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* sendAsyncMessage isn't actually a global - this just mollifies eslint */ + /* global sendAsyncMessage */ + "use strict"; + + // We want to start this test from an insecure context + loadAsInsecure = true; + // We don't want to go through the navigation back/forward test + bypassNavigationTest = true; + + async function runTest() { + let script = SpecialPowers.loadChromeScript(function() { + const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + // Force download to be w/o user assistance for our testing mime type + const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); + let handlerInfo = + mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto"); + handlerInfo.preferredAction = Ci.nsIHandlerInfo.saveToDisk; + handlerInfo.alwaysAskBeforeHandling = false; + handlerInfo.preferredApplicationHandler = null; + + const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"] + .getService(Ci.nsIHandlerService); + handlerSvc.store(handlerInfo); + + let profileDir = Services.dirsvc.get("ProfDS", Ci.nsIFile); + profileDir.append("downloads"); + + let prefBranch = Services.prefs.getBranch("browser.download."); + + prefBranch.setCharPref("dir", profileDir.path); + prefBranch.setBoolPref("useDownloadDir", true); + prefBranch.setIntPref("folderList", 2); + + const { Downloads } = + ChromeUtils.import("resource://gre/modules/Downloads.jsm"); + Downloads.getList(Downloads.PUBLIC).then(list => { + list.addView({ + onDownloadAdded(aDownload) { + list.removeView(this); + aDownload.whenSucceeded().then(() => { + list.removeFinished(); + sendAsyncMessage("navigate", "bug383369step2.html"); + }); + }, + }); + sendAsyncMessage("navigate", "download.auto"); + }).catch(Cu.reportError); + }); + script.addMessageListener("navigate", function(url) { + window.location = url; + }); + } + + async function afterNavigationTest() {} + + testCleanUp = function cleanup() { + SpecialPowers.loadChromeScript(function() { + const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); + let handlerInfo = + mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto"); + + const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"] + .getService(Ci.nsIHandlerService); + handlerSvc.remove(handlerInfo); + + let prefBranch = Services.prefs.getBranch("browser.download."); + + const prefKeys = ["dir", "useDownloadDir", "folderList"]; + for (let prefKey of prefKeys) { + if (prefBranch.prefHasUserValue(prefKey)) { + prefBranch.clearUserPref(prefKey); + } + } + }); + }; + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html new file mode 100644 index 0000000000..d2ad64c454 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>No content image doesn't break security</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + SpecialPowers.pushPrefEnv( + {"set": [["security.mixed_content.upgrade_display_content", false]]}, + null); + await isSecurityState("broken", "broken"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html new file mode 100644 index 0000000000..bd55a600ca --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src replace</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + SimpleTest.expectAssertions(0, 4); + + // Clear the default onload assigned to test start because we must + // wait for replaced image to load and only after that test the security state + var onLoadFunction = window.onload; + window.onload = function() + { + let img1 = document.getElementById("img1"); + img1.addEventListener("load", onLoadFunction); + img1.src = "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + }; + + async function runTest() + { + await isSecurityState("secure", "secure"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "secure after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="img1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html new file mode 100644 index 0000000000..90932790f0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 477118</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("secure", "data <img> doesn't break security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "still secure after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB9kBDxIAOdxBIbcAAAI+SURBVDjLxZO7TxRhFMV/M/PN7EPYhS02yytggo+ERAgxERsNhYnGzsQojaHT3r9F0cTaUjs6NUQLBRKDi4I8FEwkLMgO+5rdeX3XAoVYiZWnP797cu69Bv8gqZ+0QTqIdRpl1VHGvnV884CJwQgwicVtoB/ku/H4ycOnURgP/Q1g21Fw4+r0RjbbNmaq4ayO35UkXp9S2UzHxK2bE4QNl82FVwD0D49jn+hERBCRgwTiIX7pvGUGYF/BlO327d3ENfV7wuL0AyjPICIsfPvAmev3qdVqlMtlCoUCGxurDPT1kEnPomQKkRTFpXOjh4DN4kvGLuSJ/JC38y/ouXyXYrGIiBDHMVtbu1SrvXTlbfp6HcQcoVwp5hRAaWedPXFYfL+E1lAKswSRy+joKEEQICLkcjm01hiGgRcksW0b4SMKYHb+OSt6ma+VffxWRF3S5OeeMX7pHkqpwy5EBK31H90ogFODF1lbm8OtlEhloDORpbdnhDAMaTabhwbbtkkkEkRRhGVZR4BCfojJO4+o1VwQAItEIolpmliWRVtbG7s/dlDKotGo47U8CvkuAEwA3/eJoxhE0WyGuO4+nucRBAHVahXDMKg3agRhQBAGVKsVtNZHCRzHwTAMcrnc0eX9it3e3g7A6cGzhx0AKHWwQOV5jdXXb2ZOaa3BOP5ffF5ZptVqflG+3xpbWv5kh2FolEo7dnmv7Lium6zXG0nf95MiguM4QTqd9jPZTCvX2eF393QHqVRKZ7KZkP+unzPGLX8Jr7F8AAAAAElFTkSuQmCC" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html new file mode 100644 index 0000000000..59085a5ec4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 521461</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + SimpleTest.requestFlakyTimeout("Timeout in mixedContentTest"); + + loadAsInsecure = true; + + async function runTest() + { + window.location = "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs"; + window.setTimeout(async () => { + await isSecurityState("insecure", "location.href doesn't effect the security state"); + is(document.body.innerHTML, "This is an unsecure page!\n", "Document has not changed content"); + finish(); + }, 1000); + } + + async function afterNavigationTest() + { + await isSecurityState("insecure", "still not secure after navigation"); + is(document.body.innerHTML, "This is an unsecure page!\n", "Document has not changed content"); + finish(); + } + + </script> +</head> + +<body>This is an unsecure page!</body></html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html new file mode 100644 index 0000000000..98cee1bb53 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS :before styling 1</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style type="text/css"> + p:before + { + content: url(http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg); + } + </style> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("broken", "insecure content added by :before styling breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p> + There is a moon surface left to this text + </p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html new file mode 100644 index 0000000000..5c5019ca78 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS conent styling 1</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <style type="text/css"> + p + { + content: url(http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg); + } + </style> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("broken", "insecure content added by :before styling breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p></p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html new file mode 100644 index 0000000000..19e5784334 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS conent styling 2</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + if (navigator.platform.startsWith("Mac")) { + SimpleTest.expectAssertions(0, 1); + } + + async function runTest() + { + await isSecurityState("secure"); + document.getElementById("para").style.content = + "url('http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg')"; + + waitForSecurityState("broken", async () => + { + await isSecurityState("broken", "insecure content added by styling breaks security"); + finish(); + }); + } + + async function afterNavigationTest() + { + is(document.getElementById("para").style.content, ""); + await isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p id="para"></p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html new file mode 100644 index 0000000000..90eca5bcdb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>document.write('<img src="http://">')</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> written dynamically breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <script class="testbody" type="text/javascript"> + "use strict"; + document.write( + "<img src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html new file mode 100644 index 0000000000..e009fd4f54 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>document.write('<iframe src="http://">')</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure iframe written dynamically breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <script class="testbody" type="text/javascript"> + "use strict"; + document.write( + "<iframe src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html'></iframe>"); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html new file mode 100644 index 0000000000..514902d047 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("secure"); + window.setTimeout(function() { + // Don't do this synchronously from onload handler + document.getElementById("image1").src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + }, 0); + + waitForSecurityState("broken", async () => + { + await isSecurityState("broken", "src='http://...' changed to broken"); + finish(); + }); + } + + async function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + await isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html new file mode 100644 index 0000000000..d9a8cc8af7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>unsecure XHR test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("secure"); + window.setTimeout(async () => { + try { + let req = new XMLHttpRequest(); + req.open("GET", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs", false); + req.send(null); + + // Change should be immediate, the request was sent synchronously + await isSecurityState("broken", "security broken after insecure XHR"); + } catch (ex) { + ok(false, ex); + } + + finish(); + }, 0); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html new file mode 100644 index 0000000000..fd66b21a64 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>body.background changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + async function runTest() + { + await isSecurityState("secure"); + document.body.background = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + waitForSecurityState("broken", async () => { + await isSecurityState("broken", "document.body.background='http://...' changed to broken"); + finish(); + }); + } + + async function afterNavigationTest() + { + is(document.body.background, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "document backround secure again"); + await isSecurityState("secure", "secure after re-navigation"); + finish(); + } + + </script> +</head> + +<body background="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html new file mode 100644 index 0000000000..8934de4b79 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>iframe.src changes to unsecure redirect test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("secure"); + let self = window; + let iframe = document.getElementById("iframe1"); + iframe.onload = async () => { + await self.isSecurityState("broken", "src='redirect to unsecure' changed to broken"); + self.finish(); + }; + + iframe.src = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs"; + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe id="iframe1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html new file mode 100644 index 0000000000..5ef5a28b2c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + SimpleTest.requestFlakyTimeout("Timeout in mixedContentTest"); + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + async function runTest() + { + await isSecurityState("secure"); + document.getElementById("image1").src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + window.setTimeout(async () => { + await isSecurityState("broken", "src='http://...' changed to broken"); + finish(); + }, 500); + } + + async function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + await isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html new file mode 100644 index 0000000000..d8506e8cc5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + (new Image()).src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + async function runTest() + { + await isSecurityState("broken", "(new Image()).src='http://...' changed to broken"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security broken after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html new file mode 100644 index 0000000000..a73c7f8619 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure redirect test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("secure"); + document.getElementById("image1").src = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs"; + + window.setTimeout(async () => { + await isSecurityState("broken", "src='redirect to unsecure' changed to broken"); + finish(); + }, 500); + } + + async function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + await isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html new file mode 100644 index 0000000000..45bf140384 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>innerHTML changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + SimpleTest.requestFlakyTimeout("Timeout in mixedContentTest"); + + async function runTest() + { + await isSecurityState("secure"); + + window.setTimeout(function () { + document.getElementById("buddy").innerHTML = + "<img id='image1' src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"; + }, 1); + + waitForSecurityState("broken", async () => { + await isSecurityState("broken", "innerHTML loading insecure changed to broken"); + finish(); + }); + } + + async function afterNavigationTest() + { + is(document.getElementById("buddy").innerHTML, "\n", "innerHTML back to previous"); + await isSecurityState("secure"); + finish(); + } + + </script> +</head> + +<body id="buddy"></body></html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html new file mode 100644 index 0000000000..d8b3e5f6e0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>innerHTML changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + SimpleTest.requestFlakyTimeout("Timeout in mixedContentTest"); + + async function runTest() + { + await isSecurityState("secure"); + + document.getElementById("buddy").innerHTML = + "<img id='image1' src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"; + + window.setTimeout(async () => { + await isSecurityState("broken", "innerHTML loading insecure changed to broken"); + finish(); + }, 500); + } + + async function afterNavigationTest() + { + is(document.getElementById("buddy").innerHTML, "\n", "innerHTML back to previous"); + await isSecurityState("secure"); + finish(); + } + + </script> +</head> + +<body id="buddy"></body></html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html new file mode 100644 index 0000000000..66a28ce74e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Secure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("secure", "javascript: <img> should not break security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "Still secure after renavigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="javascript:'Random data'" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html new file mode 100644 index 0000000000..efd754dd58 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>All secure anti-regression check</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <link rel="stylesheet" type="text/css" + href="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + // Navigation test goes over an insecure page, test state leak + navigateToInsecure = true; + + async function runTest() + { + await isSecurityState("secure", "insecure <img> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("secure", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs" /> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html new file mode 100644 index 0000000000..961713a2da --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Secure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + loadAsInsecure = true; + + async function runTest() + { + await isSecurityState("insecure", "left insecure"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("insecure", "left insecure after renavigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html new file mode 100644 index 0000000000..02fdb29d41 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>background unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + async function runTest() + { + await isSecurityState("broken", "security broken"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security after navigation"); + finish(); + } + + </script> +</head> + +<body background="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html new file mode 100644 index 0000000000..c775347e72 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure css load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <link rel="stylesheet" type="text/css" + href="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html new file mode 100644 index 0000000000..291ce3747e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html new file mode 100644 index 0000000000..8f49ecda51 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html new file mode 100644 index 0000000000..4eebbf5b22 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure redirect iframe load</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + window.setTimeout(async () => + { + await isSecurityState("broken", "insecure meta-tag <iframe> load breaks security"); + finish(); + }, 500); + } + + async function afterNavigationTest() + { + window.setTimeout(async () => + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + }, 500); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html new file mode 100644 index 0000000000..12a4233494 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure redirect iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html new file mode 100644 index 0000000000..3c19811db9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html new file mode 100644 index 0000000000..81ed58ffde --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load in two windows</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + openTwoWindows = true; + testPage = "unsecurePictureDup.html"; + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html new file mode 100644 index 0000000000..21bcf5f810 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img in iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> in an <iframe> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html new file mode 100644 index 0000000000..82611ff3fe --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Redirect from secure to unsecure img</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + hasMixedActiveContent = true; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html new file mode 100644 index 0000000000..2282677418 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html new file mode 100644 index 0000000000..7ce3701620 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load in two windows</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + async function runTest() + { + await isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + async function afterNavigationTest() + { + await isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/moz.build b/security/manager/ssl/tests/mochitest/moz.build new file mode 100644 index 0000000000..3b7f2ba585 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/moz.build @@ -0,0 +1,11 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +TEST_DIRS += [ + "browser", + "mixedcontent", + "stricttransportsecurity", +] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini new file mode 100644 index 0000000000..b2ce8fef00 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini @@ -0,0 +1,6 @@ +[DEFAULT] +tags = psm +skip-if = os == 'android' +support-files = page_blank.html + +[test_sts_privatebrowsing_perwindowpb.html] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini new file mode 100644 index 0000000000..7970639053 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini @@ -0,0 +1,12 @@ +[DEFAULT] +tags = psm +support-files = + nosts_bootstrap.html + nosts_bootstrap.html^headers^ + plain_bootstrap.html + plain_bootstrap.html^headers^ + subdom_bootstrap.html + subdom_bootstrap.html^headers^ + verify.sjs + +[test_stricttransportsecurity.html] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build new file mode 100644 index 0000000000..28769dedc1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build @@ -0,0 +1,9 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +MOCHITEST_MANIFESTS += ["mochitest.ini"] + +MOCHITEST_CHROME_MANIFESTS += ["chrome.ini"] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html new file mode 100644 index 0000000000..e528a40abb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html @@ -0,0 +1,28 @@ +<!-- 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/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP plain", + "http://mochi.test:8888"); + }); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + "use strict"; + // eslint-disable-next-line no-unsanitized/method + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ new file mode 100644 index 0000000000..9e23c73b7f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ @@ -0,0 +1 @@ +Cache-Control: no-cache diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html new file mode 100644 index 0000000000..db5d31a96b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html @@ -0,0 +1,5 @@ +<html> +<body> + PAGE BLANK +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html new file mode 100644 index 0000000000..e528a40abb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html @@ -0,0 +1,28 @@ +<!-- 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/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP plain", + "http://mochi.test:8888"); + }); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + "use strict"; + // eslint-disable-next-line no-unsanitized/method + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ new file mode 100644 index 0000000000..a46bf65bd9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60 diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html new file mode 100644 index 0000000000..9fca3457e4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html @@ -0,0 +1,28 @@ +<!-- 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/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP subdom", + "http://mochi.test:8888"); + }); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + "use strict"; + // eslint-disable-next-line no-unsanitized/method + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ new file mode 100644 index 0000000000..e54fc6a1d5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60; includeSubDomains diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html new file mode 100644 index 0000000000..040357d8b8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html @@ -0,0 +1,126 @@ +<!-- 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/. --> + +<!DOCTYPE HTML> +<html> +<head> + <title>opens additional content that should be converted to https</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + const STSPATH = + "tests/security/manager/ssl/tests/mochitest/stricttransportsecurity"; + + // initialized manually here + var testsleft = {plain: 4, subdom: 4}; + var roundsLeft = 2; + + var testframes = { + samedom: { + url: `http://example.com/${STSPATH}/verify.sjs`, + expected: {plain: "SECURE", subdom: "SECURE"}, + }, + subdom: { + url: `http://test1.example.com/${STSPATH}/verify.sjs`, + expected: {plain: "INSECURE", subdom: "SECURE"}, + }, + otherdom: { + url: `http://example.org/${STSPATH}/verify.sjs`, + expected: {plain: "INSECURE", subdom: "INSECURE"}, + }, + alreadysecure: { + url: `https://test2.example.com/${STSPATH}/verify.sjs`, + expected: {plain: "SECURE", subdom: "SECURE"}, + }, + }; + + function startRound(round) { + let frame = document.createElement("iframe"); + frame.setAttribute("id", "ifr_bootstrap"); + frame.setAttribute("src", + `https://example.com/${STSPATH}/${round}_bootstrap.html`); + document.body.appendChild(frame); + } + + function endRound(round) { + // remove all the iframes in the document + document.body.removeChild(document.getElementById("ifr_bootstrap")); + for (let test in testframes) { + document.body.removeChild(document.getElementById("ifr_" + test)); + } + + // clean up the STS state + SpecialPowers.cleanUpSTSData("http://example.com"); + } + + function loadVerifyFrames(round) { + for (let test in testframes) { + let frame = document.createElement("iframe"); + frame.setAttribute("id", "ifr_" + test); + frame.setAttribute("src", testframes[test].url + "?id=" + test); + document.body.appendChild(frame); + } + } + + /* Messages received are in this format: + * (BOOTSTRAP|SECURE|INSECURE) testid + * For example: "BOOTSTRAP plain" + * or: "INSECURE otherdom" + */ + function onMessageReceived(event) { + let result = event.data.split(/\s+/); + if (result.length != 2) { + SimpleTest.ok(false, event.data); + return; + } + + // figure out which round of tests we're in + let round = (roundsLeft == 2) ? "plain" : "subdom"; + + if (result[0] === "BOOTSTRAP") { + loadVerifyFrames(round); + return; + } + + // check if the result (SECURE/INSECURE) is expected for this round/test combo + SimpleTest.is(result[0], testframes[result[1]].expected[round], + "in ROUND " + round + ", test " + result[1]); + testsleft[round]--; + + // check if there are more tests to run. + if (testsleft[round] < 1) { + // if not, advance to next round + endRound(round); + roundsLeft--; + + // defer this so it doesn't muck with the stack too much. + if (roundsLeft == 1) { + setTimeout(function () { + startRound("subdom"); + }, 0); + } + } + + if (roundsLeft < 1) { + SimpleTest.finish(); + } + } + + // listen for calls back from the sts-setting iframe and then + // the verification frames. + window.addEventListener("message", onMessageReceived); + window.addEventListener("load", () => { startRound("plain"); }); + </script> +</head> + +<body> + This test will load some iframes and do some tests. + +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html new file mode 100644 index 0000000000..510b6f7435 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html @@ -0,0 +1,268 @@ +<!-- 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/. --> + +<!DOCTYPE HTML> +<html> +<head> + <title>opens additional content that should be converted to https</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + + <script class="testbody" type="text/javascript"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + const STSPATH = + "tests/security/manager/ssl/tests/mochitest/stricttransportsecurity"; + const NUM_TEST_FRAMES = 4; + const CONTENT_PAGE = + "http://mochi.test:8888/chrome/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html"; + + const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm"); + const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + + // This is how many sub-tests (testframes) in each round. + // When the round begins, this will be initialized. + var testsleftinround = 0; + var currentround = ""; + var mainWindow = window.browsingContext.topChromeWindow; + + SpecialPowers.Services.prefs.setIntPref("browser.startup.page", 0); + SpecialPowers.Services.prefs.setBoolPref("privacy.partition.network_state", false); + + var testframes = { + samedom: { + url: `http://example.com/${STSPATH}/verify.sjs`, + expected: {plain: "SECURE", subdom: "SECURE", nosts: "INSECURE"}, + }, + subdom: { + url: `http://test1.example.com/${STSPATH}/verify.sjs`, + expected: {plain: "INSECURE", subdom: "SECURE", nosts: "INSECURE"}, + }, + otherdom: { + url: `http://example.org/${STSPATH}/verify.sjs`, + expected: {plain: "INSECURE", subdom: "INSECURE", nosts: "INSECURE"}, + }, + alreadysecure: { + url: `https://test2.example.com/${STSPATH}/verify.sjs`, + expected: {plain: "SECURE", subdom: "SECURE", nosts: "SECURE"}, + }, + }; + + function whenDelayedStartupFinished(aWindow, aCallback) { + SpecialPowers.Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + SpecialPowers.Services.obs.removeObserver(observer, aTopic); + SimpleTest.executeSoon(aCallback); + } + }, "browser-delayed-startup-finished"); + } + + function testOnWindow(aIsPrivate, aCallback) { + let win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); + + (async function() { + await new Promise(resolve => whenDelayedStartupFinished(win, resolve)); + + let browser = win.gBrowser.selectedBrowser; + BrowserTestUtils.loadURI(browser, CONTENT_PAGE); + await BrowserTestUtils.browserLoaded(browser); + + aCallback(win); + })(); + } + + function startRound(win, isPrivate, round) { + currentround = round; + testsleftinround = NUM_TEST_FRAMES; + SimpleTest.info("TESTS LEFT IN ROUND " + currentround + ": " + testsleftinround); + + let browser = win.gBrowser.selectedBrowser; + let src = `https://example.com/${STSPATH}/${round}_bootstrap.html`; + + SpecialPowers.spawn(browser, [src], async function(contentSrc) { + let frame = content.document.createElement("iframe"); + frame.setAttribute("id", "ifr_bootstrap"); + frame.setAttribute("src", contentSrc); + + return new Promise(resolve => { + frame.addEventListener("load", () => resolve(), { once: true }); + content.document.body.appendChild(frame); + }); + }).then(() => { + onMessageReceived(win, isPrivate, "BOOTSTRAP " + round); + }); + } + + function loadVerifyFrames(win, isPrivate, round) { + loadVerifyFrame(win, isPrivate, testframes.samedom, "samedom", function() { + loadVerifyFrame(win, isPrivate, testframes.subdom, "subdom", function() { + loadVerifyFrame(win, isPrivate, testframes.otherdom, "otherdom", function() { + loadVerifyFrame(win, isPrivate, testframes.alreadysecure, "alreadysecure"); + }); + }); + }); + } + + function loadVerifyFrame(win, isPrivate, test, testName, aCallback) { + let id = "ifr_" + testName; + let src = test.url + "?id=" + testName; + let browser = win.gBrowser.selectedBrowser; + + SpecialPowers.spawn(browser, [[id, src]], async function([contentId, contentSrc]) { + let frame = content.document.createElement("iframe"); + frame.setAttribute("id", contentId); + frame.setAttribute("src", contentSrc); + + return new Promise(resolve => { + frame.addEventListener("load", () => { + resolve(frame.contentDocument.location.protocol); + }); + + content.document.body.appendChild(frame); + }); + }).then(scheme => { + if (scheme == "https:") { + onMessageReceived(win, isPrivate, "SECURE " + testName); + } else { + onMessageReceived(win, isPrivate, "INSECURE " + testName); + } + + if (aCallback) { + aCallback(); + } + }); + } + + /** + * @param {DOMWindow} win + * Test window. + * @param {Boolean} isPrivate + * Whether the given window is in private browsing mode. + * @param {String} data + * A message that is expected to be in this format: + * (BOOTSTRAP|SECURE|INSECURE) testid + * For example: "BOOTSTRAP subdom" + * or: "INSECURE otherdom" + */ + function onMessageReceived(win, isPrivate, data) { + let result = data.split(/\s+/); + if (result.length != 2) { + SimpleTest.ok(false, data); + return; + } + + if (result[0] === "BOOTSTRAP") { + loadVerifyFrames(win, isPrivate, currentround); + return; + } + + // check if the result (SECURE/INSECURE) is expected for this round/test + // combo + dump_STSState(isPrivate); + SimpleTest.is(result[0], testframes[result[1]].expected[currentround], + "in ROUND " + currentround + + ", test " + result[1]); + testsleftinround--; + + // if this round is complete... + if (testsleftinround < 1) { + SimpleTest.info("DONE WITH ROUND " + currentround); + // remove all the iframes in the document + let browser = win.gBrowser.selectedBrowser; + SpecialPowers.spawn(browser, [testframes], async function(contentTestFrames) { + content.document.body.removeChild( + content.document.getElementById("ifr_bootstrap")); + for (let test in contentTestFrames) { + content.document.body.removeChild( + content.document.getElementById("ifr_" + test)); + } + }).then(async () => { + currentround = ""; + + if (!isPrivate) { + await clean_up_sts_state(isPrivate); + } + // Close test window. + win.close(); + // And advance to the next test. + // Defer this so it doesn't muck with the stack too much. + SimpleTest.executeSoon(nextTest); + }); + } + } + + function test_sts_before_private_mode() { + testOnWindow(false, function(win) { + SimpleTest.info("In public window"); + dump_STSState(false); + startRound(win, false, "plain"); + }); + } + + function test_sts_in_private_mode() { + testOnWindow(true, function(win) { + SimpleTest.info("In private window"); + dump_STSState(true); + startRound(win, true, "subdom"); + }); + } + + function test_sts_after_exiting_private_mode() { + testOnWindow(false, function(win) { + SimpleTest.info("In a new public window"); + dump_STSState(false); + startRound(win, false, "nosts"); + }); + } + + async function clean_up_sts_state(isPrivate) { + // erase all signs that this test ran. + SimpleTest.info("Cleaning up STS data"); + let flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + await SpecialPowers.cleanUpSTSData("http://example.com", flags); + dump_STSState(isPrivate); + } + + function dump_STSState(isPrivate) { + let sss = Cc["@mozilla.org/ssservice;1"] + .getService(Ci.nsISiteSecurityService); + let flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + SimpleTest.info("State of example.com: " + + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example.com"), flags)); + } + + // These are executed in the order presented. + // 0. test that STS works before entering private browsing mode. + // (load sts-bootstrapped "plain" tests) + // ... clear any STS data ... + // 1. test that STS works in private browsing mode + // (load sts-bootstrapped "subdomain" tests) + // 2. test that after exiting private browsing, STS data is forgotten + // (verified with non-sts-bootstrapped pages) + // ... clear any STS data ... + var tests = [ + test_sts_before_private_mode, + test_sts_in_private_mode, + test_sts_after_exiting_private_mode, + ]; + + function finish() { + SpecialPowers.Services.prefs.clearUserPref("browser.startup.page"); + SimpleTest.finish(); + } + function nextTest() { + SimpleTest.executeSoon(tests.length ? tests.shift() : finish); + } + window.addEventListener("load", nextTest); + </script> +</head> + +<body> + This test will load some iframes and do some tests. +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs new file mode 100644 index 0000000000..e5e4eb5f67 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs @@ -0,0 +1,47 @@ +/* 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/. */ + +// SJS file that serves un-cacheable responses for STS tests that postMessage +// to the parent saying whether or not they were loaded securely. + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + if ('id' in query) { + var outstr = [ + " <!DOCTYPE html>", + " <html> <head> <title>subframe for STS</title>", + " <script type='text/javascript'>", + " var self = window;", + " window.addEventListener('load', function() {", + " if (document.location.protocol === 'https:') {", + " self.parent.postMessage('SECURE " + query['id'] + "',", + " 'http://mochi.test:8888');", + " } else {", + " self.parent.postMessage('INSECURE " + query['id'] + "',", + " 'http://mochi.test:8888');", + " }", + " }, false);", + " </script>", + " </head>", + " <body>", + " STS state verification frame loaded via", + " <script>", + " document.write(document.location.protocol);", + " </script>", + " </body>", + " </html>"].join("\n"); + response.write(outstr); + } else { + response.write("ERROR: no id provided"); + } +} diff --git a/security/manager/ssl/tests/moz.build b/security/manager/ssl/tests/moz.build new file mode 100644 index 0000000000..d39ca0ff17 --- /dev/null +++ b/security/manager/ssl/tests/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ["unit"] + +TEST_DIRS += [ + "gtest", + "mochitest", +] + +XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell.ini"] + +if not CONFIG["MOZ_NO_SMART_CARDS"]: + XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell-smartcards.ini"] diff --git a/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem new file mode 100644 index 0000000000..9d8aae350d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6DCCAdCgAwIBAgIUL/mOXLOH4zs7sAoXCffwl7mbFPMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAmMSQwIgYDVQQDDBtFRSB3aXRoIGJhZCBzdWJqZWN0QWx0TmFt +ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjHjAcMBoGA1UdEQQTMBGCDyouKi5leGFtcGxlLmNvbTANBgkqhkiG +9w0BAQsFAAOCAQEAnyhjk+PoHjlqMAOhxlX6+Xn7x5HXzVRmOYPSHlrKtaSDF2/y +Io1L/Ji7aMJ932MhaUNc83sFfHqGHLTHGhAe3icjuv745WdGsXzykAI+y4Z1gAH+ ++0yzUJsYlNmYgn+8kaYTTI9P+HIRoqYPZ2YqshwNNSxdXnSs1jDYCg3yDsKX6DO6 +5vTET9ef5Ea6ePYZiGbwyvYA6lGz1JorrnZPD8uiQnx8CSa20YywYeZH0UGc8Jd+ +G/xRGd+T0eRMy4Xsvv4kZyiAQFPVRsYCDhrgpkeiYsWwlrgZ/LTZN7muBwsPPyy3 +fM2Y6VfVJhEjyv/nv8C44PnKaYYSK7ZWU+dpkw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec new file mode 100644 index 0000000000..1b368c26f1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:EE with bad subjectAltNames +extension:subjectAlternativeName:*.*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem new file mode 100644 index 0000000000..9faffde6d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKzCCAhOgAwIBAgIUPU/rVUoMybyCeEAWx++fMAuZ6k0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8xOTQ2MDIxNDAwMDAwMFoYDzIwMzEw +MTAxMDAwMDAwWjAsMSowKAYDVQQDDCFCZWZvcmUgVU5JWCBFcG9jaCBUZXN0IEVu +ZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjWzBZMCMGA1UdEQQcMBqCGGJlZm9yZS1lcG9jaC5leGFt +cGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2Nh +bGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBALocgfctX/9NDtkQ7zAkGl14 +UXkXBCq7vn5fKss2bCG7D6M/+Q4ZJ64/QXGK96tKqdJctiyIN3KArnk4/pWfYCQG +DgIHXFAgbKUQU0uiGmPwbPQnYq8la6VEarMrzWnGhqVPG1wsqiO1cnecycvm2W7W +9n7qvw3s2Gf0WZIQKqpNmuhouboeiK1xFxryLWiNaG087WPHb71e1C+1enVb/hJN +E1KD7dBtBh0sOC6bOFdc4BzhDHnDzPSznSqouotHf5U8YniKoPcDCml544msKwP8 +LCj3tG1VdMxL+p83ETDHG6GLUY20R0E6WJJfvfZ3hdxRUKgaAs+diT3xYXXYqTA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec new file mode 100644 index 0000000000..ac97b2231a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Before UNIX Epoch Test End-entity +validity:19460214-20310101 +extension:subjectAlternativeName:before-epoch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem new file mode 100644 index 0000000000..6cdfa86a25 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUL5tQyA2FR4V3eMcfGyWTxS4vmp0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8xOTQ2MDIxNDAwMDAwMFoYDzIwMzEw +MTAxMDAwMDAwWjAuMSwwKgYDVQQDDCNCZWZvcmUgVU5JWCBFcG9jaCBUZXN0IElu +dGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQELBQADggEBAGDlMbdxc1BHrn6l1svyskkHx68lSeTGVucIpClu +mJIT3rsTR5swYuyvrWe/gqkVqGRv2gIpMUYAJoHWjF4fRyWkIjJz5JnSP5qxFKKk +NFrjXFpGSqxJGtuMUNNGk7P30RLje5aE00bqrZHokfrokzChC3G3QJPOwvJtP1Gk +wldQ8AeoHu/u3oEB3caoC1QpFfgF5kunNETSIxX5bTmsjTSSJnJjnf46FQdbOWUh +P5Qkr6ZNK4ZAOIm+PRRyJ44JiHab+up/cEs17/T5dNcnHCy4TYXquNKwOe35qakm +iexwhKycaAEM0TcTI1OA5K4tCwFvaiOr4eTzxN28Cemd89E= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec new file mode 100644 index 0000000000..835e63f2b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Before UNIX Epoch Test Intermediate +validity:19460214-20310101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem new file mode 100644 index 0000000000..070de1796b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUVV34jakVUF6D+5QkiXJ1kemF5q0wDQYJKoZIhvcNAQEL +BQAwLjEsMCoGA1UEAwwjQmVmb3JlIFVOSVggRXBvY2ggVGVzdCBJbnRlcm1lZGlh +dGUwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowODE2MDQGA1UE +AwwtVGVzdCBFbmQtZW50aXR5IHdpdGggQmVmb3JlIFVOSVggRXBvY2ggaXNzdWVy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABo2IwYDAqBgNVHREEIzAhgh9iZWZvcmUtZXBvY2gtaXNzdWVyLmV4YW1w +bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2Fs +aG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAhJFzxTYfWOkyMlXOowz7kFnK +ChekuiwNJB3r0ZGwExAXmrdPKCfBz+OKsPM+3i+bNzIlJNrI2ZhKzylsAJ1mIeRF +vvpviu5NeZ0TgT7Man5n7WSBylFgSiKymk6V529k0ZrCvVxU1BZK0kXbqYZmGVDt +TOtkHEKP1YkNnjOs7pYZ7bslkH94oWbT2Cd+W3362o/ko6CCmkhaj2WAqSRyVEUy ++qdQndSpyvp85tRFZLb8bQkCqTtOVCLQfLHYWXRQ4qZQWy8kFPA7OpCMdXlR6Bwu +vyYi9dw5cRXwAdbLzMpVouPBBXLbTT2b+R+vW5L/LoNGTgrnL+K8WshCSYZ+YQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec new file mode 100644 index 0000000000..9aabe21628 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Before UNIX Epoch Test Intermediate +subject:Test End-entity with Before UNIX Epoch issuer +extension:subjectAlternativeName:before-epoch-issuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem new file mode 100644 index 0000000000..3fffeaf56f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUF4tSVpnzLjrUBoa9WMfShlqrEjwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IEludGVybWVkaWF0ZSB1c2VkIGFz +IEVuZC1FbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjcjBwMAwGA1UdEwQFMAMBAf8wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMCwGA1UdEQQl +MCOCIWNhLXVzZWQtYXMtZW5kLWVudGl0eS5leGFtcGxlLmNvbTANBgkqhkiG9w0B +AQsFAAOCAQEAllsGy7B4yROdLH5rmLV6Q6AxUMKk/ixwfCnkt3ibKGtoypvAG6wn +vevqezN7BUeqIZd0QeoZBEtKwxv87oCiVDgSPXhkGqxryN9i8Zii07Sa27rCVZHd +F/AJv7qSgl2mYPYAAcyDX5F5ecbc3i9tc96mYSUJawhgPCwNB6PGB+HUr5fSskzx +j7Rg+0k9TEpk5bcTlsqH2hFvM9ZycEFC0/9trBVvnvh51WTHX/AzZDaaHPyOd2jD +RxqCMwde0EfpNQmpz39WnRJqs7bf2Cdc080m/apFL9yjZOuCfNaWdezfNjWoBKNC +S5tpZOoqNYzdV/8VAy74Nv+cXGNX4Ct7RA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec new file mode 100644 index 0000000000..8e16705b50 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate used as End-Entity +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:ca-used-as-end-entity.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.key b/security/manager/ssl/tests/unit/bad_certs/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.pem b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem new file mode 100644 index 0000000000..3ea3efa405 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUN/wGbPUAtIu5Cd7Ojx955mKb5Y0wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUTWlzc2luZyBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowJzElMCMGA1UEAwwcZWUtZnJvbS1taXNz +aW5nLWludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMnMCUwIwYDVR0RBBwwGoIJbG9jYWxob3N0 +gg0qLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAmRFIXGwnArqj8ekdT +bg+l3r5pkovY9UJpm5hdAvgKuTuFE3fvrfNt+TaftS90i/OlF9LcyIMzWehiJa3O +axNeKptICjkcX6U6hF+4qvBxCpw3pD+SAsRgWugNzdFdytUxjX5cEnWMFq2MXSNc +FRpzVJvspN/NdfoF8HYvnYszH4ReKaKF7uZKUVhu0MZ1+zSZBU9ajOyZ+Zo+AIdL +Hhq3XsTxGcKwjEQZGaRoyKQe6bBxfejISetjsSsW+ZpFQsA1S+oUaIhHR1FzIMiG +qyEhll/97Ub1PU3u/XNVBUcNETdHO+HERPpHkQPS8pNdZSzPR9aLY/te7iEv634D +L4J2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec new file mode 100644 index 0000000000..48bb1c6e4a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec @@ -0,0 +1,3 @@ +issuer:Missing Intermediate +subject:ee-from-missing-intermediate +extension:subjectAlternativeName:localhost,*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem new file mode 100644 index 0000000000..e47d2c7c6f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUIeBfVf/r/GMhsN7xxnsSiVo7hQswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDEyBJbW1pbmVudGx5IERpc3RydXN0ZWQgRW5k +IEVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaNvMG0wNwYDVR0RBDAwLoIJbG9jYWxob3N0giFpbW1pbmVu +dGx5LWRpc3RydXN0ZWQuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsG +AQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IB +AQCmalWWhf0TDhN3e7UAbXC4mrg766FnGqrGsmbL2wm0q4IuzF9Xc4x26Y2mFaWg +tkyv0W5YCpSwwbCI2wL6h2iWBZgz55APndydlwCDO5zrDWMx0tlaVSG6ZJiafQFk +G3Mjky9dzmBMgAsS1L4y+rpP0Wla6WYxjtXmMOMEfLuOOhEK/8CjYru4bWSLKHxL +baBhvXM3bMbFl/G3c6AAcLMwi+jau3NCZEXORFAoeoxskAIlyfRaqGatXcO19AZp +5zURdW4WYMVM1DwuUTdKLR/I17xYuTnXdO9qOW6jUssGrspEpg+5Ruec0Q6kJsx3 +ZSJwMRGt69Y0hEGHDzjE3uwZ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec new file mode 100644 index 0000000000..dd8c6707ce --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:printableString/CN=Imminently Distrusted End Entity +extension:subjectAlternativeName:localhost,imminently-distrusted.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem new file mode 100644 index 0000000000..d11edd2ca8 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJTCCAg2gAwIBAgIUY5v46X4dh8IilHQNDrSwO5u+Og4wDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB4xHDAaBgNVBAMME0VFIElzc3VlZCBieSBub24t +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjWzBZMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNv +bTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6 +ODg4OC8wDQYJKoZIhvcNAQELBQADggEBACbMjO/TTypmr3K1qgJHG4YVBzfXrj/u +eARxTnPhbHivqP/e1wgVyHHhp/5QMBooXN9sykYwA22ZyzXRGYIXpsvfW/gx6fBT +VVPNF5F6vt+FVtJEUZ4x101cArcWsizao5dRua1t3mE8tGiju+FIDZksF0m/UAQu +JoNexlBnG2ooLZ8j+vwzLuo74K/VzVDktNPcNRnaF0TAaS078OYgmZfKHvkF/13z +lyW5vCzqZLDMNnoszP95n4X9EjI+xo4kp+WfRz6c/bq6bQZdtRZAUo4vZSwxYnDm ++tH+r13KhZGekLczAgxK510RJrykZY+XrpZSBpGesSPzlwe8Ne+nkfI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec new file mode 100644 index 0000000000..63c36d34b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test End-entity +subject:EE Issued by non-CA +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem new file mode 100644 index 0000000000..0045add98f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIUf83/oBwb560grMAqpqiLeF/len4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVjEgQ2VydDAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRFRSBJc3N1ZWQgYnkgVjEgQ2VydDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMnMCUwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMA0GCSqG +SIb3DQEBCwUAA4IBAQCzt3ZusWZ/JxpErDDTk0/Y3DHseHv+7h4UY/wkMyGycn26 +qEDxDcAR2Xkj5b72DXt/et94b+BT0zd1lq8FFfjL29tSIdSsu+7fwO+lN8JMqGjT +6F4u2BTjgvpAgoO7Zg9fqblE+r0YNOxlXL0EqDzsFFrz/u6PgsBWdKgEY6nWVFzg +Pay4REzvXrJMIs0UA8mGgN6Bd9kYA7wGatLU7sa0AWtYppaTk1E+e7F2R4K26JEk +Zo1BXuSITiYB8GKYyQU9q6HyVm38hq1TCzd8lewuLeLuTh69u7vvnMvIjeN+bjSz +ExfzO3SZQeTHibGLf7oH2e72Fi+MN1OyTu0C6b2F +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec new file mode 100644 index 0000000000..9ed9b33db7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec @@ -0,0 +1,3 @@ +issuer:V1 Cert +subject:EE Issued by V1 Cert +extension:subjectAlternativeName:localhost,*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem new file mode 100644 index 0000000000..b42f270d1b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUVQ7hP4Gor8gwKkSGLxvowMGx/BswDQYJKoZIhvcNAQEL +BQAwADAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAtMSswKQYD +VQQDDCJFbmQgZW50aXR5IHNpZ25lZCBieSBlbXB0eSBuYW1lIENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyow +KDAmBgNVHREEHzAdghtlbXB0eWlzc3Vlcm5hbWUuZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAC8PShkXwq0NGcZQ5nsyWwQDW0mRVL8lOyTU8O9GhHNSlwzs +zhh1QgRmksWIXuxctIODYUlxLnQSCkUVMJjUNpXkZcnmxcgrazC+dfx9B49TQm8a +9bvjlmZwWGtXi4fuI+mn0447GSOOBTjo5d7rHuwMZM+tZRNifXdBxFi6458xmFbP +73+IxRc3Yl5jcCmlN+yb5D1elR9oeH2Sn6MrmNr9OEEWumTXb5Wqzb5D1gxNMV/Y +V0h+u8QLgG3w1KJGL6u/Ahr2KnkfMMq2VuTvJ5wtjSMnA/9UJH1icJ+Ij9grvuZn +4LbHY07qNnSr50j0Lki4rM/vrI23/T56QKwYndM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec new file mode 100644 index 0000000000..a99d84b79e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec @@ -0,0 +1,3 @@ +issuer: +subject:End entity signed by empty name CA +extension:subjectAlternativeName:emptyissuername.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem new file mode 100644 index 0000000000..848e776155 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAamgAwIBAgIUVYzw/kKPlc6jC3ssIBL3rywd/VQwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAQEAl6tTwSFSaEMVA8N+h/pQuCF+yG7XKBJKgETn +y5fYobUbYrT5IOhxLotk/DmXTrNRwY7dycRz+zcbWCLypfpKK45XDHe9OXlMa5SE +RoR++XrS6Q3xSK/Sg1LFZPcc5crNwKGWYTg+1ec4pwN71fKxi0Dk+y2UiJ6MMc1m +z8o46kqOVQj1Ct4PiHsHQffKKAFPFnU4S49mOK8oEpn42YPMylfDd+xaSS5NEw1R +SwUceewlaEOzfO1V6RK1EGNtfLqS4A2PHIDOtTvD6E8EMi1MLIvnXEIpduOuk0zQ +zmC/1+oG/sadO27BdGLFkCLBQu+TYQ+j4B1n53lEV00vJ599xw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec new file mode 100644 index 0000000000..0a7cfdfd84 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject: +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem new file mode 100644 index 0000000000..2c2e5da70c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOzCCAiOgAwIBAgIUL6Ownjd7KeqXI1vuKoBnuMLqzpswDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB8xHTAbBgNVBAMMFGV2LXRlc3QtaW50ZXJtZWRpYXRlMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +o3kwdzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBHBggrBgEFBQcBAQQ7MDkw +NwYIKwYBBQUHMAGGK2h0dHA6Ly9sb2NhbGhvc3Q6ODg4OC9ldi10ZXN0LWludGVy +bWVkaWF0ZS8wEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBCwUAA4IBAQAJ +gL0sq/Ak2xI3iYXPHg9ECQVPlnKRM09u7Ykj2ehg6INT9vf4XJ9Dyj8BWt0B3qtY +y29bUl7SREVCuMgNWRu6OiflmVuwccJkNm7fYRrq9dto3sYTU1VPANq7jJ7J6S9X +7kizD5UgV664WfA61uSfXdTb1z8NKCbQv3bO4v4mXeAPe1i2GTHN0fk1wpex1ETp +XqaIgVULkgdl8wIPXXhbGXugogc1uXytcVPxLAqfH329qPQnSW3S71jMqGE2HxzL +5oIbWqHJJba8YkDjk8/KC9cyk08bA5OXJ4IPxxRJfQ4+q4EPjXpKKhXdfMjsgryX +wMwN88kEWkSl+VVy4uWk +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec new file mode 100644 index 0000000000..d5b5859672 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:ev-test-intermediate +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://localhost:8888/ev-test-intermediate/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test.pem b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem new file mode 100644 index 0000000000..36a96ce2ba --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQjCCAiqgAwIBAgIUQyrN+2RfvyLlvHscTU0HNQdN9O0wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUZXYtdGVzdC1pbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowEjEQMA4GA1UEAwwHZXYtdGVzdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaN/MH0wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vbG9jYWxo +b3N0Ojg4ODgvZXYtdGVzdC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0 +CQEwHgYDVR0RBBcwFYITZXYtdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF +AAOCAQEAcpJJ7FQJ8rtBQBitqPDdYgLYIuPq7kCNTwT2B2m60a8nIzc/wGtAePrN +80x/VbLXeXOW+Pl6tzPWvja17SMzeEsakXkVZnE0qnQyfxxY69T7tKUsbGCUIIug +Iwqdz11q2MbiWdOlZDh4o8G/dPM6FVLpKzfC6OmeUrLLmYE0Tme0+ejlZ0kVe4GZ +CYrvCmXpIjXaF84mAWhd9LdJ42iVGusVbdTGN7xh8FACVZS80h4BKQXyYUzrPFpW +boKOjshNrzvoTi7ihg46HMHNSAE7zdBrAieQpIZvRqCJbqk8hRvdCk6s1vj2w5hc +NTE6HialIan5T7+ok0K5ok+ILT4Etg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec new file mode 100644 index 0000000000..10f8022585 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev-test-intermediate +subject:ev-test +extension:authorityInformationAccess:http://localhost:8888/ev-test/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.key b/security/manager/ssl/tests/unit/bad_certs/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.pem b/security/manager/ssl/tests/unit/bad_certs/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem new file mode 100644 index 0000000000..a7d657a970 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyBggrBgEF +BQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ +KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzf +T+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5h +mu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3 +L9zJ2JqNc60+hB8l297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74V +kQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZ +gBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7I= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec new file mode 100644 index 0000000000..0a03bc36f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Expired Test End-entity +validity:20130101-20140101 +extension:subjectAlternativeName:expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem new file mode 100644 index 0000000000..e03d862761 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUY9VlD+O8GH3DRfxtYTip4pS6eBYwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoYDzIwMTMw +MTAxMDAwMDAwWjAkMSIwIAYDVQQDDBlFeHBpcmVkIFRlc3QgSW50ZXJtZWRpYXRl +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B +AQsFAAOCAQEANf+C+WsnAgYfISDS37prll2DOGYWKajcVZNzkScDzNGkK2s0c/td +Mb+HXehqvYz20hT4wEwQZnPt9qMWH7bBEWiJfw85OINbKmG/i0gjZZDgbFMMdHvc +j6BXJoxL0gAy8fOQyTDuMNX0NBJzSmWhzBsL99BHAWdG6XXQTzSyumiekc8ip4GG +EhJvArbZwgIBigzdpbc/lQI0dR2qER0BUXamWU8fi2RuvQqtEi2ANjJHrWOillXU +PR3j0F2LyvoiYlhiNhE1g3JH4VYZ+3eboRCrjel4J3rZHksN17r6+Fla1/YZdz2l +nAGA5McLBKXYBVcARV4adXlBe1z79TiDeQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec new file mode 100644 index 0000000000..38a0abd8a4 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Expired Test Intermediate +validity:20110101-20130101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem new file mode 100644 index 0000000000..2d00c1ca6c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUfTvvLki+Legnl10m+fcP7kxDp1YwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZRXhwaXJlZCBUZXN0IEludGVybWVkaWF0ZTAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAuMSwwKgYDVQQDDCNUZXN0IEVu +ZC1lbnRpdHkgd2l0aCBleHBpcmVkIGlzc3VlcjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNcMFowJAYDVR0RBB0w +G4IZZXhwaXJlZGlzc3Vlci5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYI +KwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQAD +ggEBAF4T4Ye5qxMLGz/5dOgRxn/LXh717T2FKxXcWM50cShOGBU5NOjIVB5fkRS7 +uJsfgvHrT05123/ttDzVZefz2N1ZvXSxuzzJoA0DFhX/XSr4VXgLPEYHO0usDwxE +HJq8ZmtgM4Xw39QlFU4Sw8ZA5tjOfFjdKv5Ow1ulbVVGZyk/9FsmcsSYZuPXFIvH +DZyxrz8wFJOyrB/6Q/fOcTHeeh7bcC8YSAVtQvCFYOoKK1dJHwttpIa4/mdfsjpl +aP+ixciWjoKNmiPTqTZy8BdDSlh+pRFJppGfNfkub55T4+5XegcQPUWkJA1w6woM +hNZU708Mvf7u8j3XJuWlxNI8rHI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec new file mode 100644 index 0000000000..855f454221 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Expired Test Intermediate +subject:Test End-entity with expired issuer +extension:subjectAlternativeName:expiredissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem new file mode 100644 index 0000000000..9f306fcb94 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUBT+m5UYwTuABfetlYca4GEtsukAwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVW5rbm93biBJc3N1ZXIwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPSUROIENlcnRpZmljYXRlMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABozgwNjA0BgNVHREELTArgilidWc0MTM5MDkueG4tLWh4YWpiaGVnMmF6M2Fs +LnhuLS1qeGFscGRscDANBgkqhkiG9w0BAQsFAAOCAQEABk5q77He1tAU87VBBq2R +E/lyg2rTNFU6oOgGUY9sWbz+RbTSxk8xjg89d6BhW8K9KFEzkTdS74sjxTKc9pMB +jXDpKL5LzhPtBBRndtzsAaaKMfnR0r7EkxihAP7TNTkLgYBQzIyOXIAZvyDr+fnG +J3om1g4pkt1rVFc4CtrTqSzr4Bdm7vwYWIU5ogwsF9Gpg7shShacbJam4pA6VzHE +fl1v1bAmpCyfGiYFbDTSLLFMYiZvf03sy8MrCCxPftGqr9n6trkQfN+hzbImGJFw +hkSt9hniJmVVglf0UVBmJTJ1Ud8rl9aoeOr9Ic2QvQ6HTvq5xzu8NECInNkzDENt +Kw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec new file mode 100644 index 0000000000..b3d840fbd3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec @@ -0,0 +1,3 @@ +issuer:Unknown Issuer +subject:IDN Certificate +extension:subjectAlternativeName:bug413909.xn--hxajbheg2az3al.xn--jxalpdlp diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key new file mode 100644 index 0000000000..d43495f851 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICcAIBADANBgkqhkiG9w0BAQEFAASCAlowggJWAgEAAoGAANKbsS+4T93NKbOl +GctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZ +BX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvmnZoIMTbh +WvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAQJ/PEllBwvzkMJR1aLFJ3xbX9C97oXK +1/4rJ5grsoURSlBwBANq4c+K5Usl5Ns5IVq9fpA/YYwtiy8IzGzRLbzNciBeSUW2 +s984nl5D3goUi7LITiQx/b5ZILBEuycvRez/ByG337YDl/xhOp6jXCIwBTDK6PkV +nFNN878JEJUZAQJAD58XWXyFuAUbnGmvtV71dsmW29CQR9DM3ludYOpcZ/5PrGe+ +gD9LasWj8FD3a5ZvsU9c8QV2HlrebdlgsYO6VQJADXtjcRLOYaVRaMD5yThvsnmr +QMug1Ukza7plJ3JjqseCYRosgdm2Nc94xAAYhZ4BjF6QBtEuPS7m80bnn6QzaQJA +Cf1smj6m6RrjIHD5/BwhD/k1L5e+XR7rlRuzloHp3FtnKlMiIbPYkAyanZm50KTh +AtxFDKG4ewsTid5lFsCuDQJAAUG4MkkbfdSoMwiSACTHnK5kvUR9+IO7TFZyqWur +SLcSOzTyYyRFLNzrF/IeVw40fL4v1MLY+ZEOrCy22JW4yQJABFjdau4YyIsvm4Hx +vDB1riDcH5lz0gck8gsGBD1hR8h4nUoHroi8gshDjIk+AXsTlH9i4LGJWKMetmSx +nmTT4A== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec new file mode 100644 index 0000000000..21ed73d60b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec @@ -0,0 +1 @@ +rsa1016 diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem new file mode 100644 index 0000000000..de4b933cf1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAZ+gAwIBAgIUUTSENycPfy4QVpNTpBCq/pVp3nowDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowKTEnMCUGA1UEAwweSW5hZGVxdWF0ZSBLZXkg +U2l6ZSBFbmQtRW50aXR5MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgADSm7Ev +uE/dzSmzpRnLZsQ7jY+L5UW6eThM5mPtA991mRYA65IHkNJTDOzlRNuZpx8FiWo+ +0gcWVTSqmQV+R8R+O8ga2m+h4S43JotQRqVSaPna18y0hdgaLhnVDU8LaFSsr217 +5p2aCDE24Vr6j1PByMhPxgdyed0OVdc2mlvdAgMBAAGjZTBjMC0GA1UdEQQmMCSC +ImluYWRlcXVhdGUta2V5LXNpemUtZWUuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3 +DQEBCwUAA4IBAQCf8g6xupfTgr6N78Zru3/XdJ9zzf8gNLNDEzncs8YipkkPEkUY +F2yGf0bNOwqZnHMTo0D4lwaNTFFv1obY7kZd5auFt9WqI1GUWdPM7FaQS4a1oAqU +6gWCz+tIbTJXVDrAJ+yYXntV030Qqr7i0DFvwJz5fPFk6V1192Xa2aLUDoenxv5d +eiczsYvJMgBD6zkXSef+rSf24FgS23km6DHja89recbZ/fz09HJ5q9NDQ/EMilHf +EJMP1Ny/73Ht6V+Q9RJdtA5PXDyOgc7WHjFY+Z2LZH51VDg1XJ49W4ClYqxB1Yg4 +4qhh6OwIoFEipevWJ2uGNwJfD9KV4jiDwUAB +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec new file mode 100644 index 0000000000..02b595dc9a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test Intermediate +subject:Inadequate Key Size End-Entity +subjectKey:rsa1016 +extension:subjectAlternativeName:inadequate-key-size-ee.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem new file mode 100644 index 0000000000..0899f9d613 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgIUJ8CbecVvBfSdpQSAm71sCRjoCTUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRJbmFkZXF1YXRlIEtleSBVc2FnZSBUZXN0 +IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjbjBsMAsGA1UdDwQEAwIBAjApBgNVHREEIjAggh5p +bmFkZXF1YXRla2V5dXNhZ2UuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIG +CCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUA +A4IBAQCog4fCed4qaa2aLX7kx1l+03kSlDg9ZmnyIDR2kBsFZePto9TM6488Gaem +m3GEHT6d/RQK1g7zG40lmYDAg33PShzxZqgCmyxzpSfc1HbFfh9w4m47JANY7Q7E +NWDg42P64v/+Vdvxoprn594XklxYc8ci+y0NL9c79BWVEBlpyXaRwCJiKwfkcr6o +1X/07hkbKCPi9uBR6GFPtQSJmnFRKGT4ePdRHAccqn6CExIhamCK0I/y+lsr8Atg +ZtSrWLnXbqwYvdDyofhMWttDXPXCiWEdUq031KpQ/ENXxHi2cs7eEAtjjSZNefBv +vX+wC4ZNznyAb8tR5Zvx3sDoasRT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec new file mode 100644 index 0000000000..4d553890b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Inadequate Key Usage Test End-entity +extension:keyUsage:cRLSign +extension:subjectAlternativeName:inadequatekeyusage.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem new file mode 100644 index 0000000000..676c46dfd0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUTfYfuzoa/9f2RQTT/c6KssuRWkkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAUMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGDAWMBQGA1Ud +EQQNMAuCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAQEAYeN7Q1I0ihJhj2GG +o/0XZM/WuxPJ0JaJzEWMvf4ZGYeSaxp86tyMFNUOhGaDCvHCu9ZiruHUEC1J5Z7h +z4kSwG2h95SKLsOr5d3NDN3bGJJtzPARz8xeynFHI2f1AAiGM+ai714jNUgtVoXx +a1U5J+Ls+xbIzNiRPRzze8shnHrqTXmHL+R4G3F9MRsLUPQs4tVubi2J8+lVRrsK +QAFfnQp3VVGoWfDAj5OFDC9kCf6fVz9sVjTjHD2LuFCKvagOIxG62Y1qVhd5CLyJ +HUAzeorgZuUl7QXN2RT2w5itIcpzGRbNmd5CoN7Tbm7TyuS6BIBWyjjxlWM5Ue/j +ae8XOw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec new file mode 100644 index 0000000000..7662338470 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:127.0.0.1 +extension:subjectAlternativeName:127.0.0.1 diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem new file mode 100644 index 0000000000..3f373d09f7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIUGUp8qIucVUZ0D+cPoEILDVfteu8wDQYJKoZIhvcNAQEE +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoYDzIwMTMw +MTAxMDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IE1ENVNpZ25hdHVyZS1FeHBpcmVk +IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjYzBhMCsGA1UdEQQkMCKCIG1kNXNpZ25hdHVyZS1l +eHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW +aHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQQFAAOCAQEAYMtZZk0A +c3xvnK0PSwNxsWidAdOEY5uOKJTPT1LZFUQsNHw/2f7csfDneTeLNoCNKH7LPF3t +J+zwUMzq1Ut0vIRSs5r84P7LK7KaBRrSwWPSnTP90X4VX3IVIQ7dbwTkrlUaRzfs +B4Pqa/p2GVuvrLmbtmd2SDw+52GubJYVOF6u2s4KKgUGhHWtegzQOsVKTFEOoqBr +X3yDEJhK7M82NMiGtq3Fr5F0sLD6DuGL0Mm7ei9junSLS4sH0M+Hac2BVmXwYNTS +ekKzyjmZ1TYRlo2sCgYyYfCLcTOswG7uVHLU+ie0+Dbaik2NcolUgFNnC7Uk3E+t +DhSRNeOtKglSxw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec new file mode 100644 index 0000000000..e4c2b7008d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec @@ -0,0 +1,6 @@ +issuer:Test CA +subject:Test MD5Signature-Expired End-entity +validity:20110101-20130101 +signature:md5WithRSAEncryption +extension:subjectAlternativeName:md5signature-expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature.pem b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem new file mode 100644 index 0000000000..a2d46f868d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPbgiSgWOnRxOdlLj8dU/qbEhukQwDQYJKoZIhvcNAQEE +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAtMSswKQYDVQQDDCJUZXN0IEVuZC1lbnRpdHkgd2l0aCBNRDUg +c2lnbmF0dXJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAaghhtZDVzaWduYXR1cmUuZXhh +bXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9j +YWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBBAUAA4IBAQCFfTcMksF9oZhEnsAmGhLx +u7LvPXarRynLOia8+un6Lx33ZtvItBpLHtbbPkPvlsiv7oyKspzNbk5IpKdYEQbd +dYx6diFkEP8/xAnX8o1Jng1rbynLmVhnabRSnJfTOihGFlusN3UAVrmSZyZVAdEl +knnKqDL+U+CSVMdEeaqBECNQOFIUL7F+uutt6jfKNuN/fpDHEz9vCfUGiuZVC7Kd +2fVCwhDDOC7bN6rvQP3e+06uLoXGGleOM1aZjhNNdiYHvqq8veYiGLZckmkcF1a8 +XqCDuLoQDs0dVvsj4pNEyciXuk5wCuV6bgw4s4unPFMP9EBmgWQGFaW+iePqT6uS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec new file mode 100644 index 0000000000..02742d910e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test End-entity with MD5 signature +signature:md5WithRSAEncryption +extension:subjectAlternativeName:md5signature.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem new file mode 100644 index 0000000000..d5782da2cd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUXWNmi3NOMsq8iBKvohtG0kX2YFIwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjArMSkwJwYDVQQDDCBNaXNtYXRjaC1FeHBpcmVkIFRlc3QgRW5k +LWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXZG9lc250bWF0Y2guZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCt7JzZlMgD/ZHZobiGxcfE/EPQ +/V405Xu7DGdTJh5cTiFF1h3sQl06BfrCEAo0yhOrpPyMtmhTI+rMyF7PvFWZMQ89 +bk9y4cZ7jG1NEd6B+jlYfD4mFbLR3AbMEbf6QVjYDK29+XnjnhvczT5NPPl8g7rF +6y1FhFcFMTGiGZCOyhCz0nXbG/LpP/alH+WucXRdpMLUQbEXEDzWOq5WJ1ZPS556 +2Ouurfr1mkydAlXCGc5RYPVLRY48CwX2z+kfHRnF4TCb3ck5oOlqabP+bc+HD7EE +UgEEdnE6zpUs1D7s8C8Mp89LUcXx+s51/ZUQvGE4btBMML0lNImwwbqxbv02 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec new file mode 100644 index 0000000000..262f08d6be --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Mismatch-Expired Test End-entity +validity:20130101-20140101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem new file mode 100644 index 0000000000..b70a632693 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLzCCAhegAwIBAgIUcYUtGOYg2nrx/OAYr+cxTZVbv34wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMzMDEwMTAwMDAwMFoYDzIwMzQw +MTAxMDAwMDAwWjAxMS8wLQYDVQQDDCZNaXNtYXRjaC1Ob3QgWWV0IFZhbGlkIFRl +c3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXZG9lc250bWF0Y2gu +ZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8v +bG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCu5v5Saw0htF59xmKf +CQJ7YI4M/TvuNJjhVdwq5phvEw3k+qweEdpLHERGu4nrzyDTMKqN8kXO6tXUspnh +LpXCvmaDLNxx/UyYofWslqYqFwM4vQ4l5QEUriR1ndMN256ELRSx2cEpWCi9xHMb +1cqB12ulLMCpitmK+NXpflViZy7HliTQOCdwhLPDNWRKsRF85EHOuFzcx4uqfWdw +5zwA0zVOYG21fyY51bhy4oy7HjTWUOrGi/klwzz2TEDTUX6nRHYagrFxO7C1GMlg +pe32InUfLU0rR8G9lP/tSug8HawSH/TCE+63jo2BGWaIYGSd+k11QzU+CsT15+A2 +tbAC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec new file mode 100644 index 0000000000..947eb7d678 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Mismatch-Not Yet Valid Test End-entity +validity:20330101-20340101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem new file mode 100644 index 0000000000..4902855da5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOTCCAiGgAwIBAgIUO1bWrdrsbGfiDSe6i14vOA3vWsIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoY +DzIwMTMwMTAxMDAwMDAwWjA1MTMwMQYDVQQDDCpNaXNtYXRjaC1VbnRydXN0ZWQt +RXhwaXJlZCBUZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjWjBYMCIGA1UdEQQbMBmCF2Rv +ZXNudG1hdGNoLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAlTFY +rHGARngEHz3XEngdY1E3hf2GdITTHssgVRvpW3IvNmUJDhk3zVqvjb2hIVDmxFRv +ad7yCKK7FQum2A1MKZh/Pl7ylWv6vkdtB8HSg9F5qYifyUD/XEjYp3uSrfAXW7Pp +XHZHgBR6nlOB1EpAqrLtpEjxMX6F0fcXClOlWf0UsPLv1M6JvPNns/4tbHBnrhfm +e0DqBMfZIJV7x633eZhpLQmOIA27rZtpElWZsA6Gtenl3szr8mpOgy3hxuEs9oFn +cigHg2ECzaOKM5ayTP0dc2OVbVgUX/2doF8pGHiIKdsThYNLNEOioBZjJhQlreZE +K67bzkMDhLQmMBUMtw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec new file mode 100644 index 0000000000..adc8ebaf8b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Other test CA +subject:Mismatch-Untrusted-Expired Test End-entity +validity:20110101-20130101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem new file mode 100644 index 0000000000..708fdbe324 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMTCCAhmgAwIBAgIUIeL7ME9jR6UnL5tbkKtCbMzAstAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJNaXNtYXRjaC1VbnRydXN0ZWQg +VGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABo1owWDAiBgNVHREEGzAZghdkb2VzbnRtYXRj +aC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6 +Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBABPy72/P12xlsoLz +nImXr6gkVB84x2t32n9berLA5BuvB7XW3V5AnHM4cvEPw/SkWgkjb/CgKy/jE5mo +ExTyrtneG3PcX5KgIJedKgKYPjyji01SnsT4jlWlzRND2ISC5sv/0xQovrEsgkAP +pOLodr5WfjZhE0E0gA3TNwFW+/xDZeMwYeVuv1XwPtmto/r026VYhlQfhi7cZ0Rf +6/sW7zBKDhAgg2Puk32w8J7eP+KxkIbAPdfeLrWU4hl4U5Srnt7tFaTaIng5YAGC +6U3M8fEETS0YIgl1wRU77ywkIeSGX4jcRF3l5zwoexiDbSjSuJ/4lg6YItfW/Rd6 +xbzRon0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec new file mode 100644 index 0000000000..91c5f548b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec @@ -0,0 +1,4 @@ +issuer:Other test CA +subject:Mismatch-Untrusted Test End-entity +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem new file mode 100644 index 0000000000..2699b8196c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUU/pv4TGBlwPGJxIpKC/9rJ31RaUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhNaXNtYXRjaCBUZXN0IEVuZC1lbnRpdHkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjeTB3MEEGA1UdEQQ6MDiCF2RvZXNudG1hdGNoLmV4YW1wbGUuY29tgh0q +LmFsc29kb2VzbnRtYXRjaC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYI +KwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQAD +ggEBAIQ9iWQWypTHSxt73EdcGiorVJTczAisC4ar683CcwwcbonkG8c6Ca8OZZFz +QWYZYwKO6xouFMpKYoby933dKiEwQrtyckaBKHsGlgOQWKzY4BiaCULeYg24d6S0 +rWzKOAwZgmA5eaAqHxmoIz2qefNLOED1sYFzg85jeT6vL+SeEuHFh8GOGct2RHEA +I+EcdKgYT6/kFrHtxEkCu0QULVVk0g9PDlVeZZ8eOOMBYi1bsQq03QjKFTzUaQY2 +18iwDvWbIgh21MwTYGMDhCvEfXYXWKe+AqiMHNYDyfk2lmgxOHB48J7Akow4MiBX +zGuf1lvgdACSETNaPq5TXniBnMI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec new file mode 100644 index 0000000000..b93599fc88 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Mismatch Test End-entity +extension:subjectAlternativeName:doesntmatch.example.com,*.alsodoesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem new file mode 100644 index 0000000000..4c1e16b065 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAgIURUZJw9lGOsp7dEOmmehwl1FeaBwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdkb2VzbnRtYXRjaC5leGFtcGxlLmNvbTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAATANBgkqhkiG9w0BAQsFAAOCAQEABN5ha7Gn+zVm7AdnMKIIuDt5C5X3CfF7 +YKRgqPby5clFJybaYHz9msYoxgSFAyoA+nuD1KCCSbQA77rMFKVJ2mDQJh7a1tEI +RdSDZMhgKbuA8qG3knr0Q6eBjfwDI4Gx8SIxU9BdJ3NhY9a31TQfzuhKeV+hN8FR +9GGOO1121x29U4jih4vtt35blMZu4VLrvMAR+aapyBOTK2UzZeqYb8JTyWQrkdBT +03nvtThsVl1SMZuyKDwCBAbenDqCknuZ/1FED7njbl9VuoEz8ApMopn0XnliM4RU +AuyvWWF9oBY6+xLIZsDfK+shmlaH5hRUMQC25NVwOpE/VfIxdJPp6w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec new file mode 100644 index 0000000000..86ef45b7ce --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec @@ -0,0 +1,2 @@ +issuer:Test CA +subject:doesntmatch.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/mitm.pem b/security/manager/ssl/tests/unit/bad_certs/mitm.pem new file mode 100644 index 0000000000..37567fe10c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUS4dnYahNJmxk0T1Z0H+W8A+5tcgwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVGVzdCBNSVRNIFJvb3QwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowMDEuMCwGA1UEAwwlVGVzdCBlbmQtZW50aXR5IGlz +c3VlZCBmcm9tIE1JVE0gUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMfMB0wGwYDVR0RBBQwEoIQbWl0bS5l +eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAKNQhLbnyWK6cd8qvK8ZD/8cY +Je/PuuCew7E76VtbQFX3/d5foJJE2sKY/SHtfvFocAQbLp68/Pydfs2CmrvFlyFa +3rSUMJBSoFDOJ4az1Ht5iF374fnFCx61CXpxYl6b7SguWgZRd5qrstsTMw3cL+Er +/8f88N+aOX8P92eU20S4ZyCq0aO1yOBoOpmidPGqtNTuCQa32kyi96mCDGoBrWii +k9OQb8nrr/sORVGSIK377+/PdXyjPCPvDwYhhVEyIomYQrXXWrL6TTy5I5e1kpIs +9zi7T7XnQbcRaHSWOwYkRGAkuKlXbq7eS3LF+PSHSzcBr5r9vYCXBZMmtBToMg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec new file mode 100644 index 0000000000..1439391f1b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test MITM Root +subject:Test end-entity issued from MITM Root +extension:subjectAlternativeName:mitm.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/moz.build b/security/manager/ssl/tests/unit/bad_certs/moz.build new file mode 100644 index 0000000000..9390fd9c87 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/moz.build @@ -0,0 +1,71 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'badSubjectAltNames.pem', +# 'beforeEpoch.pem', +# 'beforeEpochINT.pem', +# 'beforeEpochIssuer.pem', +# 'ca-used-as-end-entity.pem', +# 'default-ee.pem', +# 'ee-from-missing-intermediate.pem', +# 'ee-imminently-distrusted.pem', +# 'eeIssuedByNonCA.pem', +# 'eeIssuedByV1Cert.pem', +# 'emptyIssuerName.pem', +# 'emptyNameCA.pem', +# 'ev-test-intermediate.pem', +# 'ev-test.pem', +# 'evroot.pem', +# 'expired-ee.pem', +# 'expiredINT.pem', +# 'expiredissuer.pem', +# 'idn-certificate.pem', +# 'inadequateKeySizeEE.pem', +# 'inadequatekeyusage-ee.pem', +# 'ipAddressAsDNSNameInSAN.pem', +# 'md5signature-expired.pem', +# 'md5signature.pem', +# 'mismatch-expired.pem', +# 'mismatch-notYetValid.pem', +# 'mismatch-untrusted-expired.pem', +# 'mismatch-untrusted.pem', +# 'mismatch.pem', +# 'mismatchCN.pem', +# 'mitm.pem', +# 'noValidNames.pem', +# 'notYetValid.pem', +# 'notYetValidINT.pem', +# 'notYetValidIssuer.pem', +# 'nsCertTypeCritical.pem', +# 'nsCertTypeCriticalWithExtKeyUsage.pem', +# 'nsCertTypeNotCritical.pem', +# 'other-issuer-ee.pem', +# 'other-test-ca.pem', +# 'self-signed-EE-with-cA-true.pem', +# 'selfsigned-inadequateEKU.pem', +# 'selfsigned.pem', +# 'test-ca.pem', +# 'test-int.pem', +# 'unknownissuer.pem', +# 'untrusted-expired.pem', +# 'untrustedissuer.pem', +# 'v1Cert.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'evroot.key', +# 'inadequateKeySizeEE.key', +# 'other-test-ca.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem new file mode 100644 index 0000000000..0086ff5310 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUc9BglcR5VS6X67v9lA6Nojd9gPUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjApMScwJQYDVQQDDB5FbmQtZW50aXR5IHdpdGggbm8gdmFsaWQg +bmFtZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjNjA0MDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0 +cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAbE3XcdHBwtBh +Kqy2B6BDvVnYn06/rx0T+6HrWPkn5BRWwhQW3K6OBf/Mfm+F9QI73YGWSalVZPs/ +pIpfM2qvjXztkEJ0ZfZTEjo6b0Jd5gJ72XFYC0CZbRS8C81ck4f4hjegT+Fbyp3f +hzNWHbdfo6yRIVtv3aGcfzn1K8RWy33620t+mNroaSNQoVVuO+TVGHWEp5g4vn8A +GxUc0gx0ePNtENLpEC071aPBO4OEU/SiT1bVCp9XNCP6GSyVAl1b/VguBWn+G9pD +m6kn0PjaNxLH9JQESIKrgHyj1s0vBizLdb4Yx+hmQVdHUESt99cmlkeJi6fBHwUU +ekQ1Wipf1Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec new file mode 100644 index 0000000000..87088e87e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:End-entity with no valid names +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem new file mode 100644 index 0000000000..79cc10aa68 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg6gAwIBAgIUH+AmYB0Pf6g+gBjtVqu94DStb3UwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMxMDEwMTAwMDAwMFoYDzIwMzIw +MTAxMDAwMDAwWjAoMSYwJAYDVQQDDB1Ob3QgWWV0IFZhbGlkIFRlc3QgRW5kLWVu +dGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXbm90eWV0dmFsaWQuZXhhbXBsZS5j +b20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0 +Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQB1xgChilLhS38NJG3FU3vyD8LN3uGV +wgzFB33egzO4s4GkPK5zjGpkyQG0ofYFmlbP8NpVrjKykbhbgusdvsZOknuPBBAJ +jgHDrt5fdT4ah7xlRr+o4KC8RpYOZ8pGy6eoheCZZdNvhV3cDVxYWrkFZbdbtvw9 +YqqgpgiFx/j85ZqFudq/ApdMwcueZWPjmc47Y2fsTtrqO7rVVtX9FrG4O3BWcrVH +5RJpwN5mBsC//zNhhuvaGNWZB3XGNH0wgxEweI+cpfufWHnshJFKoEESJBrdHywz ++kuH3ha9W3JwyorON9M7uduDBdUBsjwjwLpYLd+Saie6X+XjROrGYe8f +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec new file mode 100644 index 0000000000..5b60c29ebe --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Not Yet Valid Test End-entity +validity:20310101-20320101 +extension:subjectAlternativeName:notyetvalid.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem new file mode 100644 index 0000000000..0a111582bf --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUW7kXNYkW5OLObAOtdMQ9uL8FHUkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMxMDEwMTAwMDAwMFoYDzIwMzMw +MTAxMDAwMDAwWjAqMSgwJgYDVQQDDB9Ob3QgWWV0IFZhbGlkIFRlc3QgSW50ZXJt +ZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB +/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRx +CHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMC +OosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdm +Wqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGz +ey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUD +rNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq +hkiG9w0BAQsFAAOCAQEAJgm8BvVnIEy9uGjgTxLcNnIoOZeLgQ9CPrNir6RHzGIK +1hIHcNCDdC2mDc9DvyQ8MQPzJvAiMAOvo1v8yHDijC/mmYi6hTGuC6hDxF2YHKXu +8VZZOSMdaE9pkKUQ8sckzKMS+Oxw8EJOV7VeW/WZsSLKSpba0qAioae7wEBMg0QS +0Mp72+l4nMMUG5T/gzea6gy/nGTb0ghV97K1r5jekFNuy1pZZbKun9lLd9KJNmEs +XiJCn2M7Ce3nEhJfaJcDmz9sde4HOlJ/BVLV9ljkOL2cQ3TxdEkLT9/Unp9dmcLo +1sdvWkwimWiKT3XAs6Df64uM4GYl3PqPH5tQmUyPFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec new file mode 100644 index 0000000000..8a00f2ee23 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Not Yet Valid Test Intermediate +validity:20310101-20330101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem new file mode 100644 index 0000000000..07e38c01fd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjigAwIBAgIUWzSKPj2hWVPCNbbwxWOZDW3/ESwwDQYJKoZIhvcNAQEL +BQAwKjEoMCYGA1UEAwwfTm90IFlldCBWYWxpZCBUZXN0IEludGVybWVkaWF0ZTAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA0MTIwMAYDVQQDDClU +ZXN0IEVuZC1lbnRpdHkgd2l0aCBub3QgeWV0IHZhbGlkIGlzc3VlcjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNg +MF4wKAYDVR0RBCEwH4Idbm90eWV0dmFsaWRpc3N1ZXIuZXhhbXBsZS5jb20wMgYI +KwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgv +MA0GCSqGSIb3DQEBCwUAA4IBAQA6+mauWSqBTyI7KT2VVkNlmB0d0AZRnel1MMp8 +XkwBajtIMfwFiuQ5TZhIKbqPgV2tpUex4Uv5EPre2runpGWCBJNcWdQiTPPewHfK +vWwVvSEOcsNIzo5jaJLM14JDQUgTlqjVjiIxbIAdouck6is4oFCBLbpkE3pUQCC9 +l6dzuDwmMRNEp0HEv/lDl5slubTOVrRN1G5CLEGRI9BdWk4IsJiNcvSJeVF1PhlV +oE2/gcEcJo8gGzxwP07v6RAEf5quUCFDWbZwO9wba8vq1zVItMPHcxnM9n5vDzDa +lognzXkxApHHzP0TJMi6PV5899iJgk+4tOJq+VrW7aIY9piS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec new file mode 100644 index 0000000000..d8420898e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Not Yet Valid Test Intermediate +subject:Test End-entity with not yet valid issuer +extension:subjectAlternativeName:notyetvalidissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem new file mode 100644 index 0000000000..af14e9b6a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUO53hCvwCYNgrXfxkrdB945nRkCcwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNuc0NlcnRUeXBlIENyaXRpY2FsMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +oz0wOzAjBgNVHREEHDAagglsb2NhbGhvc3SCDSouZXhhbXBsZS5jb20wFAYJYIZI +AYb4QgEBAQH/BAQDAgZAMA0GCSqGSIb3DQEBCwUAA4IBAQAk0AOu1pTYiYQ4ojdG +1foeVBLBzCaC7jOK8FW/Ow04r5mli8saKVzC5YsPBRZreJp6nVnlBnjtmgHB4PW9 +XJcHzd46uzD7h/w8kFDpLsEgM3tTZ5oezNz82EFp9aoUvTXDrdMxBnC0S/lB2fek +9B5XTmmooU+DPYhTYYOVXXpjPCsRlKsAncu+vTGmagHGHCsRmrv6HkbSfLUEkdCl +dmyC9L9Fsr79RjtqPNQoLmc3zD78iH6fW2oSJnhYLGJrAJDIHuSLvVZ42puKxzMV +ZV01nNh3vXkxCFlNoQxlz8YTHr7dSku6+DGs9yMldhCgR+c3lrvhZk6d6tcM83iA +mqr3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec new file mode 100644 index 0000000000..b236bdea47 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:nsCertType Critical +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType[critical]:sslServer diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem new file mode 100644 index 0000000000..60664c7c8c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgIUO8zMxMDLlO213zx4ekxrMaUbPiowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRuc0NlcnRUeXBlIENyaXRpY2FsIFdpdGgg +ZXh0S2V5VXNhZ2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjXTBbMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5l +eGFtcGxlLmNvbTAUBglghkgBhvhCAQEBAf8EBAMCBkAwCQYDVR0TBAIwADATBgNV +HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAJFaCPufuePUQLh1a +TzJHqLoTZrAg+9L/NpGnFLpsyENIQOHiKf53KQ53oFT0lv7+g+s9qU/KKf7xu2IF +egggCwb5VD4KeU72EgmNwDT3i7oYuyU8nq+wo9XegChNdhMz3luyoVtwAp9I2oe9 +yOb/9JOWOH0+qzIExpqCOx0GSNHVk6H9QQKIDwfPiaqmUXQA/HruHeoLI6LSI6WF +CYyLzxoE8QKttN+1kL7e6GEWqvOExf1ZWRtvnPpt1qf5httvNq7aDZ0PID4hP4kP +SHlJu7PmrQe9AHJULTTSCJGTEwi/ll5HInMOFltxYNfDZ+H+cTnZb5ej+xwHLfdf +4uU4pQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..0ae63e20f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec @@ -0,0 +1,6 @@ +issuer:Test CA +subject:nsCertType Critical With extKeyUsage +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType[critical]:sslServer +extension:basicConstraints:, +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem new file mode 100644 index 0000000000..5a715769ad --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUZ/ocY0tl1j/n07vD7m9BRpTDAUUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBduc0NlcnRUeXBlIE5vdCBDcml0aWNhbDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaM6MDgwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMBEG +CWCGSAGG+EIBAQQEAwIGQDANBgkqhkiG9w0BAQsFAAOCAQEACDqdp7f3wMnxSwIE +GSzvCwSBjMkV1ELElEiSYuhXzh1jQ+ke+xLmLkjYJi3E8BmTmJ3g+9jUlMFL6n1y +b4OOdRXM3JJyCnv2EBURvonfk1hIzWqK6Fuiwfzs5YdRLeHPrUMw1trGvovQqZfY +9qCnkgmeJL8OO9AeicCDYRhl/KMid+rHNJePhfkURKs0ww9AzrBFepAorZ5UOmDe +8UfP4dJarEledosnoIZ6GSEwpLoQQ9ChzsdpaIAhKLIPz52l7Na/N/qUXKw2CMQv +RnifJXwS2/DhaEjGsXGHq7rmC2tGaVJci+zamUhJdyb5iJlbsAqXQ6Ufq9jhNUoB +4nnKNw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec new file mode 100644 index 0000000000..a44a1feeef --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:nsCertType Not Critical +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType:sslServer diff --git a/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem new file mode 100644 index 0000000000..580b682319 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIUbYx/Zvi5+U/zqP9O3mq26pzGgIAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAnMSUwIwYDVQQDDBxXcm9uZyBDQSBQaW4gVGVzdCBF +bmQtRW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJ +n3cIKmeR8bh2w39c5TiwbErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYCl +HDwSAkTFhKTESDMF5ROMAQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzS +pss8xwbrzTBw7JjM5AqlkdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2 +mZWGZiVHl+1CaQiICBFCIGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq +0n7wFvGHzdVOgys1uJMPdLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZV +Lx0eGR1xIWjTuwIDAQABo4GtMIGqMHQGA1UdEQRtMGuCKCouaW5jbHVkZS1zdWJk +b21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5z +LnBpbm5pbmcuZXhhbXBsZS5jb22CFSoucGlubmluZy5leGFtcGxlLmNvbTAyBggr +BgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8w +DQYJKoZIhvcNAQELBQADggEBAF95ssZxomk3Jj886Bqm8kDAHWR/njF15jNyLnVQ +JOTQcbOItFbgftUOuY4aN3MQ2q+LzuDwsalcsm7vvmOXf/tp4LWjGKrFOdIkO0XG +/yUZy5xBJgSnIKuDUtES3hrl2X6LllZBhLiKBiKuFqudYo8LG1JeyLdxDpCKoDZh +dyDK3XQ42oqJz9GOXBIZiwl4x8AmaLSE3o+CRYwNxwNOpdqRWeSwlETC46LEdtSo +0StD9MEu+onWbizWCsCB8p6ILvvPr1JJGI6GcR1sPtr2qTkT5veXWXBTZYuqW2Cl +gs288iz7Kbbq1ABu9ZCQ6SzpyA+LAIadtkHeDc4p87KcjQc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec new file mode 100644 index 0000000000..a905a66ac2 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec @@ -0,0 +1,6 @@ +issuer:Other test CA +subject:Wrong CA Pin Test End-Entity +issuerKey:alternate +subjectKey:alternate +extension:subjectAlternativeName:*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com,*.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key new file mode 100644 index 0000000000..abde350c28 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBdcZSZgmfdwgq +Z5HxuHbDf1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBIC +RMWEpMRIMwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzH +BuvNMHDsmMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZm +JUeX7UJpCIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW +8YfN1U6DKzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4Z +HXEhaNO7AgMBAAECggEAfj9tfLg572auXX3ZL/VBC7NB3BRyjTkDRXDho3B5DzDw +aBNV//QeKtTpqdn86/vRJ736uMAK/7Hzzqcyfq1HqhYh8qwe4UygLwSzsnhgF5gL +GBpEnQOwPmnRErg1ceVUNPASBWV10oMu1nMdznmeN8g/bVHFWrcetYAVrwXhrxXH +R2A+9/J9A6b/BJ2Wu/hUweTlDvWwWND7CBgOCsf3vo8v8Wc9l/yeVduoOAd7v4p8 +/ylihXeFJpzZ1brStXRp5K/NM8TKLS9pnxHnyPvc1ITwjY77ijy4qXLrJL7Zcu+q +5LtxIJPkj+lKRutimodQeMQCGposk8mnA5Dp0KVEAQKBgQDmP8clprp2klp/+MtZ +xPVt1+yD/oW/H1PhHKyagSWLz8CugZB3sPLRR3qvho3mqOy+r3uyKxlvKprYLTKG +8NDMKd5xnl8r6OUJtyhNWWPt02L5J4h6TEqJeZ00DVGzAax2AasnF5Ak/KrdOL9l +Iq9j6xZGHsAqfyewb+Cd3afAoQKBgQDXGLH+n4+Z8A6DKuH73G/iqyfzTgScSYAQ ++g63CEhSGCNGCDtclsPu5VksAUpBDGuTCxZcE7XCaqMurG58klqFUcJRNPL0pyxk +IfGacxSKDt+rpdOmiIs1y6GMAP047lqvC1RXMdcgdhu8ze50SlLKQV6Y5N4Bzf52 +TBlns+jK2wKBgAHlrKJmyUqI0i4TwrkuokcRbGV6B2gXvf0w20s6nTCVuaS2dJZH +4vhOenhPx4OLCMhZcc96A2+jDjuRw8TQ3yePgMG26FnYRWrbE33vqp8fCsW6yakY +T9TqJ51yLqYm8WDXiq17yDhFzLKd8RXIP2G3YiuZvUOcYJtXkKY8WVGBAoGBAIDM +RdENJITuDRKX/Ae/gLO+/0Yeon4fOPNxeJw69mtKDt0hksIneR208cd64ka/NC8x +hWsPVlgbWKlbETHAxTltsqjDxvOeouM2vCBa5qKgs2hp/KmMu6czzwExmm+bsmt8 +oj0wF/xVHNjaiv3Rf2+i4w00hoeYHNYjTVcekLffAoGAb3fAwfKuesFpVhzKSZxS +vfvgTN3M29wSrsWoVpHoWUt+4pkI8w57lqpiVLgO1K7sm5k3gr38ebadjVjGiHD6 +S+G8DDUnKIxcgrtK668V7f8RBAP8eOas5qgoJ79C8M+nUeUHZRxWONuTk90j3R9r +KVFR3kS3f+Vaew3yceGaZcA= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec new file mode 100644 index 0000000000..cbd5f309c0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec @@ -0,0 +1 @@ +alternate diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem new file mode 100644 index 0000000000..a2e264030a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIURym6o+VN9xgZXT/QLrvN/nv1ZN4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoY +DzIwMjUwMTAxMDAwMDAwWjAYMRYwFAYDVQQDDA1PdGhlciB0ZXN0IENBMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5Tiw +bErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROM +AQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5Aql +kdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFC +IGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMP +dLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAtXplrvls6HSbbibpzfGxOPmSuh2TH05bE4vQk+d7Kz6EOAFvgTiZbLwTxbrQ +gfrM05t+67C2nAeiwAtW34nUnu6S8MYA6mJjURWICbl7cAvCHuNjg1atVr6f1Y+9 +VFFG6aUibw3bzKneREmDEVcxlEWUaMvv/JjfyMA5veSyX6iTJYkIBrEiVV5Alzg5 +yVHBi6+tpuJDO/YLlG8kmfzkYeJkTyAGx1EJ2yQHim7R232638yb0KrhS4zKsfFU +egHhM4c+MpiCLc9q2EgblbYGx5GM+2leuzXunj1KPClHFrnmkRRm3rcESG2pK9RN +/48Nd38VNofRojEbzDSCdOFmow== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec new file mode 100644 index 0000000000..3bc975aa22 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec @@ -0,0 +1,7 @@ +issuer:Other test CA +subject:Other test CA +issuerKey:alternate +subjectKey:alternate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem new file mode 100644 index 0000000000..fdbb9a06db --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDeTCCAmGgAwIBAgIUXSAD8MMxkJHsAS4PFETbUKRZyQ0wDQYJKoZIhvcNAQEL +BQAwMzExMC8GA1UEAwwoVGVzdCBTZWxmLXNpZ25lZCBFbmQtZW50aXR5IHdpdGgg +Q0EgdHJ1ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAzMTEw +LwYDVQQDDChUZXN0IFNlbGYtc2lnbmVkIEVuZC1lbnRpdHkgd2l0aCBDQSB0cnVl +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABo4GAMH4wDAYDVR0TBAUwAwEB/zAyBggrBgEFBQcBAQQmMCQwIgYIKwYB +BQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wOgYDVR0RBDMwMYIvc2VsZi1z +aWduZWQtZW5kLWVudGl0eS13aXRoLWNBLXRydWUuZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAGSgc1erifMbfX4bRpm4+jylXmCnAnBbdxrQKtSDpMMGZV// +a66yGUEHRQ0SGNWo042NlLvQ52Z5OlS2eocrlny+eKCi7n4mVCjwKKRjZ9zfQU9r +wbKozCA75PTkdYI1GforX4dkWhCCIMRKPDQv/zoI9bikJuMd+fadAjbLUeEiwkOM +xmmDJ5wikGlj0U56+mu+8FN2A9NDDJHRAJd9YoD68cSb/IZSoOUVVsVGokLextDo +/IxkvhignOEko5NWQOu2m6TbiqWzMlvwZZ1FcshgGuilrHpXPPmsbpILtzx3pG8Y +E/PNSVRHKre5sPAEGPkt5q6l9WWUjgmXYnclKuY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec new file mode 100644 index 0000000000..0ca92d7fd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test Self-signed End-entity with CA true +subject:Test Self-signed End-entity with CA true +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:self-signed-end-entity-with-cA-true.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem new file mode 100644 index 0000000000..06924b41e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhzCCAm+gAwIBAgIUf+URCTKBiuOZl+FIY/BdYQHsrx8wDQYJKoZIhvcNAQEL +BQAwNTEzMDEGA1UEAwwqU2VsZi1zaWduZWQgSW5hZGVxdWF0ZSBFS1UgVGVzdCBF +bmQtZW50aXR5MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMDUx +MzAxBgNVBAMMKlNlbGYtc2lnbmVkIEluYWRlcXVhdGUgRUtVIFRlc3QgRW5kLWVu +dGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaOBijCBhzALBgNVHQ8EBAMCBDAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwLwYDVR0RBCgwJoIkc2VsZnNpZ25lZC1pbmFkZXF1YXRlRUtVLmV4YW1wbGUu +Y29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9z +dDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAeotRluVjBUDHNaKs8g5VCS5keHXt +nZMRxjAY0P6IqKdlfx3MUR8MbGHpHK1/f+3nzkKUTwemJXpUmsuPTTxOQwN5maSd +0ekOG/Ycdpy3QF6vT0SFlv3AZDmYIAo13qt3mmpFYkaeMbBqXURZzBsdxzNF5IJ9 +bN9BlQzGj7VKd7bAWXAo8HMeR83OzwANONXoMSolT6JN5NX/JRd79Iyl7Vc3WBRy +XDRlr74y5/YvETbQjDBOqi5+vWdceHmX3GekexXqtfnO/oX1hhupnMC+Mzjr3Awi +euQP2QHwdxy0TQg5h8elCLOcYkpAF1IASZ6VFqWpSa/Sobu9hc5laau5TA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec new file mode 100644 index 0000000000..477b90ce14 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec @@ -0,0 +1,6 @@ +issuer:Self-signed Inadequate EKU Test End-entity +subject:Self-signed Inadequate EKU Test End-entity +extension:keyUsage:keyEncipherment,dataEncipherment +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:selfsigned-inadequateEKU.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem new file mode 100644 index 0000000000..2743bd61a3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNzCCAh+gAwIBAgIUR1TNNr+Uv6ZR4ml0F8x6mwwA/lEwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbU2VsZi1zaWduZWQgVGVzdCBFbmQtZW50aXR5MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCYxJDAiBgNVBAMMG1NlbGYt +c2lnbmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNZMFcwIQYDVR0RBBowGIIWc2Vs +ZnNpZ25lZC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGG +Fmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBADbaX7tZ +XI5N3VzxZ3TUQ07croUVJj7DcduwDS1m2fc2w+Lub1odVm38RQGxvIROyfNdQA2q +Djb5QyKYTnQgfFNR+rOFdDT22pRWzHQ/jqtNUzaxwrO4vGKTlISRrZBRkxde6c8m +7Z5MDu6MyDkfJyFcm5oZX4L84wDTeALRAizR2c6dHT3CxVSqoCVK1hBLe7H5gy7R +nwL6OSFy0FCnibqJwoeSFQbbga9nYsmIm165+r/4qQRrdhrRVZXtZmMmrauua86r +nRqr5ZZWGV3kM3M5mlLiH7UYgYuC2i4XwxGoxuOX7ekX6ro3/grctareAzgsNWzv +8skVQ1O9v6l22b0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec new file mode 100644 index 0000000000..99a814be17 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec @@ -0,0 +1,4 @@ +issuer:Self-signed Test End-entity +subject:Self-signed Test End-entity +extension:subjectAlternativeName:selfsigned.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/test-ca.pem b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/test-int.pem b/security/manager/ssl/tests/unit/bad_certs/test-int.pem new file mode 100644 index 0000000000..08249b863e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec new file mode 100644 index 0000000000..33b42c2f41 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem new file mode 100644 index 0000000000..b2c5370f76 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUexjAmwfKg8l4RNHPND1Dh+75sXEwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbVGVzdCBJbnRlcm1lZGlhdGUgdG8gZGVsZXRlMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMC4xLDAqBgNVBAMMI1Rlc3Qg +RW5kLWVudGl0eSBmcm9tIHVua25vd24gaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HCMIG/MIGIBgNV +HREEgYAwfoIZdW5rbm93bmlzc3Vlci5leGFtcGxlLmNvbYI0dW5rbm93bmlzc3Vl +ci5pbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbYIrdW5rbm93 +bmlzc3Vlci50ZXN0LW1vZGUucGlubmluZy5leGFtcGxlLmNvbTAyBggrBgEFBQcB +AQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZI +hvcNAQELBQADggEBABITeIp7PtTCDIpSYqXqkf8cibmOkSHPDxBmHxR463rGXNiD +ZGT3ATksVoKh/HugKxb8FC6e2oEszN3bVARypjkMFEmqD2LkC5SIU5KmvU0+E4Eq +cjlvh7rDf0KED3aYXro3QUbmUKg12owyn0xzMqdwlvD6cWT2R6bBC0g6LN11BiLq +/BSMGU+p62LEjhqZjxzBNflGnj5lY9BCIelZ9rhO5WhIFURqZANXKw+MKAwTREl3 +AD1TmJztLABQukbGnYYplmn/COnzPDo//3mTCtYZlg158srgsDMNINfEvPcA2ZsS +Yg/nywbaXMCMyNiSUJJWf8Z/gDX8sfDbD7k/ets= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec new file mode 100644 index 0000000000..a735c730ca --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate to delete +subject:Test End-entity from unknown issuer +extension:subjectAlternativeName:unknownissuer.example.com,unknownissuer.include-subdomains.pinning.example.com,unknownissuer.test-mode.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem new file mode 100644 index 0000000000..921d14583f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIUGTh5myT/JfbNsso9a1ZhGr8B11gwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoY +DzIwMTMwMTAxMDAwMDAwWjAsMSowKAYDVQQDDCFVbnRydXN0ZWQtRXhwaXJlZCBU +ZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjYDBeMCgGA1UdEQQhMB+CHXVudHJ1c3RlZC1l +eHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW +aHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAMktkDNyd +MHFk4K4dcOfi0McOkxvdZW6/Nqts51scx8A3q8sT5pdW3ftBjvN7O+3c1cNGoThG +9SA6uLDV2NT2EQp65yxMZe8j1OHX3qybqZ/RVY5r7VHF4JDsPHHXsgew5+CRGraj +MTIFUqmgAYLMcv74vB0OLIt3JL4XnHVP7atULMLJrOP8QUmkUhZ49MDqyslN0i6w +X7KwhdM00+JKadqUFqOAfhacMHsH5ErsQ3LXrQRMJiFoaVbElMy9e/jJmY7rg4pw +0EMnkt+Vj650FkWsCnLndBia+6z+81L4EZ7uwBeeks2fYhXt85qqkuzmZq2T2diu +ArcEblKIbUYlVg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec new file mode 100644 index 0000000000..3efd1ce677 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Other test CA +subject:Untrusted-Expired Test End-entity +validity:20110101-20130101 +extension:subjectAlternativeName:untrusted-expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem new file mode 100644 index 0000000000..61cabc2522 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIUM0gXawDCbh+O00f2TLkI3uS0aRswDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVUZXN0IEVuZC1lbnRpdHkgd2l0 +aCB1bnRydXN0ZWQgaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo14wXDAmBgNVHREEHzAdght1bnRydXN0 +ZWRpc3N1ZXIuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAB +hhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCoqxjz +UdEXTpLlinCBiDl0BM5qRYcWRM7YKaUAVfX0Wn7Csuk67PQS0armkRUQYJqY8Q1a +/ChTD44Y9dtoe50gIIlWhXfOrVEWQHu36NQZx4uosrFXHmL96EmH4tznvWVydzh8 +4z7NQQ2rg9buiyY5zEyne2S2xDADvnYk/uszUv4AQ2+zQA2oARH3S9OO9VtFy1ZF +wfkt12IGRnv7kptP6YdAbZqCHfXWVc2Dg8lS0OwGxtpRU9bYJZt7ojlIOmUSJjQs +6iXqCUvax1KAWGNosVUlOgU0lEpyG94NkChiwgRgTpUEdnabnme0DYuhhm/suQEZ +/1Tb6W2ER3oiR1I+ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec new file mode 100644 index 0000000000..5ba0bc2535 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Other test CA +subject:Test End-entity with untrusted issuer +extension:subjectAlternativeName:untrustedissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem new file mode 100644 index 0000000000..ae4712fe05 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrzCCAZcCFAOC1GLXYEEbe03otHMT9P0Sz1UpMA0GCSqGSIb3DQEBCwUAMBIx +EDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHVjEgQ2VydDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAPfp2lSeHPS2M1Snc9ZMJ39bNbpLT3dJpbUFZ8lz3eh3NZEhDNig1ZgINC0Z4 +pwzAmt5Jurq6cHjr4akF+7I3LMmG6mdVrmcQY88ArkfC/PhYvh9eswhzq7C1y7nX +KLFP30U5h9R8Y4+6XEyz+yB9z3Yyf8Pq7a9qWDdPNE9faHU628h74FFu0y+EvSD+ +4CU0Zte8w2+OBracUPne52Gi196rcO0Ic+H0d0PCSgC+KqkTbQjynqpgkGif3W54 +yXflu6sBODd6Xil7qjlw9Bky5VNyLDuKOH+nz+15U3gMfPHm+mJjWXhBjqSyD743 +72mMwbtT7ze7kCeAER4p/a2JZg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec new file mode 100644 index 0000000000..7824630bbc --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:V1 Cert +version:1 diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js new file mode 100644 index 0000000000..cfec935e86 --- /dev/null +++ b/security/manager/ssl/tests/unit/head_psm.js @@ -0,0 +1,1231 @@ +/* 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"; + +const { AppConstants } = ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" +); +const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm"); +const { FileUtils } = ChromeUtils.import( + "resource://gre/modules/FileUtils.jsm" +); +const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Promise } = ChromeUtils.import("resource://gre/modules/Promise.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +const { X509 } = ChromeUtils.import("resource://gre/modules/psm/X509.jsm"); + +const isDebugBuild = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2) + .isDebugBuild; + +// The test EV roots are only enabled in debug builds as a security measure. +const gEVExpected = isDebugBuild; + +const CLIENT_AUTH_FILE_NAME = "ClientAuthRememberList.txt"; +const SSS_STATE_FILE_NAME = "SiteSecurityServiceState.txt"; +const PRELOAD_STATE_FILE_NAME = "SecurityPreloadState.txt"; + +const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE; +const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE; +const MOZILLA_PKIX_ERROR_BASE = Ci.nsINSSErrorsService.MOZILLA_PKIX_ERROR_BASE; + +// This isn't really a valid PRErrorCode, but is useful for signalling that +// a test is expected to succeed. +const PRErrorCodeSuccess = 0; + +// Sort in numerical order +const SEC_ERROR_INVALID_TIME = SEC_ERROR_BASE + 8; +const SEC_ERROR_BAD_DER = SEC_ERROR_BASE + 9; +const SEC_ERROR_BAD_SIGNATURE = SEC_ERROR_BASE + 10; +const SEC_ERROR_EXPIRED_CERTIFICATE = SEC_ERROR_BASE + 11; +const SEC_ERROR_REVOKED_CERTIFICATE = SEC_ERROR_BASE + 12; +const SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13; +const SEC_ERROR_UNTRUSTED_ISSUER = SEC_ERROR_BASE + 20; +const SEC_ERROR_UNTRUSTED_CERT = SEC_ERROR_BASE + 21; +const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = SEC_ERROR_BASE + 30; +const SEC_ERROR_CA_CERT_INVALID = SEC_ERROR_BASE + 36; +const SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = SEC_ERROR_BASE + 41; +const SEC_ERROR_PKCS7_BAD_SIGNATURE = SEC_ERROR_BASE + 47; +const SEC_ERROR_INADEQUATE_KEY_USAGE = SEC_ERROR_BASE + 90; +const SEC_ERROR_INADEQUATE_CERT_TYPE = SEC_ERROR_BASE + 91; +const SEC_ERROR_CERT_NOT_IN_NAME_SPACE = SEC_ERROR_BASE + 112; +const SEC_ERROR_CERT_BAD_ACCESS_LOCATION = SEC_ERROR_BASE + 117; +const SEC_ERROR_OCSP_MALFORMED_REQUEST = SEC_ERROR_BASE + 120; +const SEC_ERROR_OCSP_SERVER_ERROR = SEC_ERROR_BASE + 121; +const SEC_ERROR_OCSP_TRY_SERVER_LATER = SEC_ERROR_BASE + 122; +const SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = SEC_ERROR_BASE + 123; +const SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = SEC_ERROR_BASE + 124; +const SEC_ERROR_OCSP_UNKNOWN_CERT = SEC_ERROR_BASE + 126; +const SEC_ERROR_OCSP_MALFORMED_RESPONSE = SEC_ERROR_BASE + 129; +const SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = SEC_ERROR_BASE + 130; +const SEC_ERROR_OCSP_OLD_RESPONSE = SEC_ERROR_BASE + 132; +const SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE = SEC_ERROR_BASE + 141; +const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144; +const SEC_ERROR_POLICY_VALIDATION_FAILED = SEC_ERROR_BASE + 160; +const SEC_ERROR_OCSP_BAD_SIGNATURE = SEC_ERROR_BASE + 157; +const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176; + +const SSL_ERROR_NO_CYPHER_OVERLAP = SSL_ERROR_BASE + 2; +const SSL_ERROR_BAD_CERT_DOMAIN = SSL_ERROR_BASE + 12; +const SSL_ERROR_BAD_CERT_ALERT = SSL_ERROR_BASE + 17; +const SSL_ERROR_WEAK_SERVER_CERT_KEY = SSL_ERROR_BASE + 132; +const SSL_ERROR_DC_INVALID_KEY_USAGE = SSL_ERROR_BASE + 184; + +const SSL_ERROR_ECH_RETRY_WITH_ECH = SSL_ERROR_BASE + 188; +const SSL_ERROR_ECH_RETRY_WITHOUT_ECH = SSL_ERROR_BASE + 189; +const SSL_ERROR_ECH_FAILED = SSL_ERROR_BASE + 190; +const SSL_ERROR_ECH_REQUIRED_ALERT = SSL_ERROR_BASE + 191; + +const MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE = MOZILLA_PKIX_ERROR_BASE + 0; +const MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY = + MOZILLA_PKIX_ERROR_BASE + 1; +const MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE = MOZILLA_PKIX_ERROR_BASE + 2; +const MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA = MOZILLA_PKIX_ERROR_BASE + 3; +const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = + MOZILLA_PKIX_ERROR_BASE + 5; +const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = + MOZILLA_PKIX_ERROR_BASE + 6; +const MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = + MOZILLA_PKIX_ERROR_BASE + 8; +const MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING = + MOZILLA_PKIX_ERROR_BASE + 10; +const MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME = MOZILLA_PKIX_ERROR_BASE + 12; +const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = + MOZILLA_PKIX_ERROR_BASE + 13; +const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = MOZILLA_PKIX_ERROR_BASE + 14; +const MOZILLA_PKIX_ERROR_MITM_DETECTED = MOZILLA_PKIX_ERROR_BASE + 15; + +// Supported Certificate Usages +const certificateUsageSSLClient = 0x0001; +const certificateUsageSSLServer = 0x0002; +const certificateUsageSSLCA = 0x0008; +const certificateUsageEmailSigner = 0x0010; +const certificateUsageEmailRecipient = 0x0020; + +// A map from the name of a certificate usage to the value of the usage. +// Useful for printing debugging information and for enumerating all supported +// usages. +const allCertificateUsages = { + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageSSLCA, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, +}; + +const NO_FLAGS = 0; + +const CRLiteModeDisabledPrefValue = 0; +const CRLiteModeTelemetryOnlyPrefValue = 1; +const CRLiteModeEnforcePrefValue = 2; + +// Convert a string to an array of bytes consisting of the char code at each +// index. +function stringToArray(s) { + let a = []; + for (let i = 0; i < s.length; i++) { + a.push(s.charCodeAt(i)); + } + return a; +} + +// Converts an array of bytes to a JS string using fromCharCode on each byte. +function arrayToString(a) { + let s = ""; + for (let b of a) { + s += String.fromCharCode(b); + } + return s; +} + +// Commonly certificates are represented as PEM. The format is roughly as +// follows: +// +// -----BEGIN CERTIFICATE----- +// [some lines of base64, each typically 64 characters long] +// -----END CERTIFICATE----- +// +// However, nsIX509CertDB.constructX509FromBase64 and related functions do not +// handle input of this form. Instead, they require a single string of base64 +// with no newlines or BEGIN/END headers. This is a helper function to convert +// PEM to the format that nsIX509CertDB requires. +function pemToBase64(pem) { + return pem + .replace(/-----BEGIN CERTIFICATE-----/, "") + .replace(/-----END CERTIFICATE-----/, "") + .replace(/[\r\n]/g, ""); +} + +function build_cert_chain(certNames, testDirectory = "bad_certs") { + let certList = []; + certNames.forEach(function(certName) { + let cert = constructCertFromFile(`${testDirectory}/${certName}.pem`); + certList.push(cert); + }); + return certList; +} + +function areCertArraysEqual(certArrayA, certArrayB) { + if (certArrayA.length != certArrayB.length) { + return false; + } + + for (let i = 0; i < certArrayA.length; i++) { + const certA = certArrayA[i]; + const certB = certArrayB[i]; + if (!certA.equals(certB)) { + return false; + } + } + return true; +} + +function readFile(file) { + let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + fstream.init(file, -1, 0, 0); + let available = fstream.available(); + let data = + available > 0 ? NetUtil.readInputStreamToString(fstream, available) : ""; + fstream.close(); + return data; +} + +function addCertFromFile(certdb, filename, trustString) { + let certFile = do_get_file(filename, false); + let certBytes = readFile(certFile); + try { + return certdb.addCert(certBytes, trustString); + } catch (e) {} + // It might be PEM instead of DER. + return certdb.addCertFromBase64(pemToBase64(certBytes), trustString); +} + +function constructCertFromFile(filename) { + let certFile = do_get_file(filename, false); + let certBytes = readFile(certFile); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + try { + return certdb.constructX509(stringToArray(certBytes)); + } catch (e) {} + // It might be PEM instead of DER. + return certdb.constructX509FromBase64(pemToBase64(certBytes)); +} + +function setCertTrust(cert, trustString) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + certdb.setCertTrustFromString(cert, trustString); +} + +function getXPCOMStatusFromNSS(statusNSS) { + let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"].getService( + Ci.nsINSSErrorsService + ); + return nssErrorsService.getXPCOMFromNSSError(statusNSS); +} + +// Helper for checkCertErrorGenericAtTime +class CertVerificationExpectedErrorResult { + constructor(certName, expectedError, expectedEVStatus, resolve) { + this.certName = certName; + this.expectedError = expectedError; + this.expectedEVStatus = expectedEVStatus; + this.resolve = resolve; + } + + verifyCertFinished(aPRErrorCode, aVerifiedChain, aHasEVPolicy) { + equal( + aPRErrorCode, + this.expectedError, + `verifying ${this.certName}: should get error ${this.expectedError}` + ); + if (this.expectedEVStatus != undefined) { + equal( + aHasEVPolicy, + this.expectedEVStatus, + `verifying ${this.certName}: ` + + `should ${this.expectedEVStatus ? "be" : "not be"} EV` + ); + } + this.resolve(); + } +} + +// certdb implements nsIX509CertDB. See nsIX509CertDB.idl for documentation. +// In particular, hostname is optional. +function checkCertErrorGenericAtTime( + certdb, + cert, + expectedError, + usage, + time, + /* optional */ isEVExpected, + /* optional */ hostname, + /* optional */ flags = NO_FLAGS +) { + return new Promise((resolve, reject) => { + let result = new CertVerificationExpectedErrorResult( + cert.commonName, + expectedError, + isEVExpected, + resolve + ); + certdb.asyncVerifyCertAtTime(cert, usage, flags, hostname, time, result); + }); +} + +// certdb implements nsIX509CertDB. See nsIX509CertDB.idl for documentation. +// In particular, hostname is optional. +function checkCertErrorGeneric( + certdb, + cert, + expectedError, + usage, + /* optional */ isEVExpected, + /* optional */ hostname +) { + let now = new Date().getTime() / 1000; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedError, + usage, + now, + isEVExpected, + hostname + ); +} + +function checkEVStatus(certDB, cert, usage, isEVExpected) { + return checkCertErrorGeneric( + certDB, + cert, + PRErrorCodeSuccess, + usage, + isEVExpected + ); +} + +function _getLibraryFunctionWithNoArguments( + functionName, + libraryName, + returnType +) { + // Open the NSS library. copied from services/crypto/modules/WeaveCrypto.js + let path = ctypes.libraryName(libraryName); + + // XXX really want to be able to pass specific dlopen flags here. + let nsslib; + try { + nsslib = ctypes.open(path); + } catch (e) { + // In case opening the library without a full path fails, + // try again with a full path. + let file = Services.dirsvc.get("GreBinD", Ci.nsIFile); + file.append(path); + nsslib = ctypes.open(file.path); + } + + let SECStatus = ctypes.int; + let func = nsslib.declare( + functionName, + ctypes.default_abi, + returnType || SECStatus + ); + return func; +} + +function clearOCSPCache() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + certdb.clearOCSPCache(); +} + +function clearSessionCache() { + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + nssComponent.clearSSLExternalAndInternalSessionCache(); +} + +function getSSLStatistics() { + let SSL3Statistics = new ctypes.StructType("SSL3Statistics", [ + { sch_sid_cache_hits: ctypes.long }, + { sch_sid_cache_misses: ctypes.long }, + { sch_sid_cache_not_ok: ctypes.long }, + { hsh_sid_cache_hits: ctypes.long }, + { hsh_sid_cache_misses: ctypes.long }, + { hsh_sid_cache_not_ok: ctypes.long }, + { hch_sid_cache_hits: ctypes.long }, + { hch_sid_cache_misses: ctypes.long }, + { hch_sid_cache_not_ok: ctypes.long }, + { sch_sid_stateless_resumes: ctypes.long }, + { hsh_sid_stateless_resumes: ctypes.long }, + { hch_sid_stateless_resumes: ctypes.long }, + { hch_sid_ticket_parse_failures: ctypes.long }, + ]); + let SSL3StatisticsPtr = new ctypes.PointerType(SSL3Statistics); + let SSL_GetStatistics = null; + try { + SSL_GetStatistics = _getLibraryFunctionWithNoArguments( + "SSL_GetStatistics", + "ssl3", + SSL3StatisticsPtr + ); + } catch (e) { + // On Windows, this is actually in the nss3 library. + SSL_GetStatistics = _getLibraryFunctionWithNoArguments( + "SSL_GetStatistics", + "nss3", + SSL3StatisticsPtr + ); + } + if (!SSL_GetStatistics) { + throw new Error("Failed to get SSL statistics"); + } + return SSL_GetStatistics(); +} + +// Set up a TLS testing environment that has a TLS server running and +// ready to accept connections. This async function starts the server and +// waits for the server to indicate that it is ready. +// +// Each test should have its own subdomain of example.com, for example +// my-first-connection-test.example.com. The server can use the server +// name (passed through the SNI TLS extension) to determine what behavior +// the server side of the text should exhibit. See TLSServer.h for more +// information on how to write the server side of tests. +// +// Create a new source file for your new server executable in +// security/manager/ssl/tests/unit/tlsserver/cmd similar to the other ones in +// that directory, and add a reference to it to the sources variable in that +// directory's moz.build. +// +// Modify TEST_HARNESS_BINS in +// testing/mochitest/Makefile.in and NO_PKG_FILES in +// toolkit/mozapps/installer/packager.mk to make sure the new executable +// gets included in the packages used for shipping the tests to the test +// runners in our build/test farm. (Things will work fine locally without +// these changes but will break on TBPL.) +// +// Your test script should look something like this: +/* + +// -*- 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"; + +// <documentation on your test> + +function run_test() { + do_get_profile(); + add_tls_server_setup("<test-server-name>", "<path-to-certificate-directory>"); + + add_connection_test("<test-name-1>.example.com", + SEC_ERROR_xxx, + function() { ... }, + function(aTransportSecurityInfo) { ... }, + function(aTransport) { ... }); + [...] + add_connection_test("<test-name-n>.example.com", PRErrorCodeSuccess); + + run_next_test(); +} +*/ + +function add_tls_server_setup(serverBinName, certsPath, addDefaultRoot = true) { + add_test(function() { + _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot); + }); +} + +/** + * Add a TLS connection test case. + * + * @param {String} aHost + * The hostname to pass in the SNI TLS extension; this should unambiguously + * identify which test is being run. + * @param {PRErrorCode} aExpectedResult + * The expected result of the connection. If an error is not expected, pass + * in PRErrorCodeSuccess. + * @param {Function} aBeforeConnect + * A callback function that takes no arguments that will be called before the + * connection is attempted. + * @param {Function} aWithSecurityInfo + * A callback function that takes an nsITransportSecurityInfo, which is called + * after the TLS handshake succeeds. + * @param {Function} aAfterStreamOpen + * A callback function that is called with the nsISocketTransport once the + * output stream is ready. + * @param {OriginAttributes} aOriginAttributes (optional) + * The origin attributes that the socket transport will have. This parameter + * affects OCSP because OCSP cache is double-keyed by origin attributes' first + * party domain. + * + * @param {OriginAttributes} aEchConfig (optional) + * A Base64-encoded ECHConfig. If non-empty, it will be configured to the client + * socket resulting in an Encrypted Client Hello extension being sent. The client + * keypair is ephermeral and generated within NSS. + */ +function add_connection_test( + aHost, + aExpectedResult, + aBeforeConnect, + aWithSecurityInfo, + aAfterStreamOpen, + /* optional */ aOriginAttributes, + /* optional */ aEchConfig +) { + add_test(function() { + if (aBeforeConnect) { + aBeforeConnect(); + } + asyncConnectTo( + aHost, + aExpectedResult, + aWithSecurityInfo, + aAfterStreamOpen, + aOriginAttributes, + aEchConfig + ).then(run_next_test); + }); +} + +async function asyncConnectTo( + aHost, + aExpectedResult, + /* optional */ aWithSecurityInfo = undefined, + /* optional */ aAfterStreamOpen = undefined, + /* optional */ aOriginAttributes = undefined, + /* optional */ aEchConfig = undefined +) { + const REMOTE_PORT = 8443; + + function Connection(host) { + this.host = host; + this.thread = Services.tm.currentThread; + this.defer = Promise.defer(); + let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService( + Ci.nsISocketTransportService + ); + this.transport = sts.createTransport(["ssl"], host, REMOTE_PORT, null); + if (aEchConfig) { + this.transport.setEchConfig(atob(aEchConfig)); + } + // See bug 1129771 - attempting to connect to [::1] when the server is + // listening on 127.0.0.1 causes frequent failures on OS X 10.10. + this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6; + this.transport.setEventSink(this, this.thread); + if (aOriginAttributes) { + this.transport.originAttributes = aOriginAttributes; + } + this.inputStream = null; + this.outputStream = null; + this.connected = false; + } + + Connection.prototype = { + // nsITransportEventSink + onTransportStatus(aTransport, aStatus, aProgress, aProgressMax) { + if ( + !this.connected && + aStatus == Ci.nsISocketTransport.STATUS_CONNECTED_TO + ) { + this.connected = true; + this.outputStream.asyncWait(this, 0, 0, this.thread); + } + }, + + // nsIInputStreamCallback + onInputStreamReady(aStream) { + try { + // this will throw if the stream has been closed by an error + let str = NetUtil.readInputStreamToString(aStream, aStream.available()); + Assert.equal(str, "0", "Should have received ASCII '0' from server"); + this.inputStream.close(); + this.outputStream.close(); + this.result = Cr.NS_OK; + } catch (e) { + this.result = e.result; + } + this.defer.resolve(this); + }, + + // nsIOutputStreamCallback + onOutputStreamReady(aStream) { + if (aAfterStreamOpen) { + aAfterStreamOpen(this.transport); + } + this.outputStream.write("0", 1); + let inStream = this.transport + .openInputStream(0, 0, 0) + .QueryInterface(Ci.nsIAsyncInputStream); + this.inputStream = inStream; + this.inputStream.asyncWait(this, 0, 0, this.thread); + }, + + go() { + this.outputStream = this.transport + .openOutputStream(0, 0, 0) + .QueryInterface(Ci.nsIAsyncOutputStream); + return this.defer.promise; + }, + }; + + /* Returns a promise to connect to host that resolves to the result of that + * connection */ + function connectTo(host) { + Services.prefs.setCharPref("network.dns.localDomains", host); + let connection = new Connection(host); + return connection.go(); + } + + return connectTo(aHost).then(function(conn) { + info("handling " + aHost); + let expectedNSResult = + aExpectedResult == PRErrorCodeSuccess + ? Cr.NS_OK + : getXPCOMStatusFromNSS(aExpectedResult); + Assert.equal( + conn.result, + expectedNSResult, + "Actual and expected connection result should match" + ); + if (aWithSecurityInfo) { + aWithSecurityInfo( + conn.transport.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo) + ); + } + }); +} + +function _getBinaryUtil(binaryUtilName) { + let utilBin = Services.dirsvc.get("GreD", Ci.nsIFile); + // On macOS, GreD is .../Contents/Resources, and most binary utilities + // are located there, but certutil is in GreBinD (or .../Contents/MacOS), + // so we have to change the path accordingly. + if (binaryUtilName === "certutil") { + utilBin = Services.dirsvc.get("GreBinD", Ci.nsIFile); + } + utilBin.append(binaryUtilName + mozinfo.bin_suffix); + // If we're testing locally, the above works. If not, the server executable + // is in another location. + if (!utilBin.exists()) { + utilBin = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + while (utilBin.path.includes("xpcshell")) { + utilBin = utilBin.parent; + } + utilBin.append("bin"); + utilBin.append(binaryUtilName + mozinfo.bin_suffix); + } + // But maybe we're on Android, where binaries are in /data/local/xpcb. + if (!utilBin.exists()) { + utilBin.initWithPath("/data/local/xpcb/"); + utilBin.append(binaryUtilName); + } + Assert.ok(utilBin.exists(), `Binary util ${binaryUtilName} should exist`); + return utilBin; +} + +// Do not call this directly; use add_tls_server_setup +function _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot) { + asyncStartTLSTestServer(serverBinName, certsPath, addDefaultRoot).then( + run_next_test + ); +} + +async function asyncStartTLSTestServer( + serverBinName, + certsPath, + addDefaultRoot +) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + // The trusted CA that is typically used for "good" certificates. + if (addDefaultRoot) { + addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u"); + } + + const CALLBACK_PORT = 8444; + + let envSvc = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile); + envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path); + // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD" + // does not return this path on Android, so hard code it here. + envSvc.set("LD_LIBRARY_PATH", greBinDir.path + ":/data/local/xpcb"); + envSvc.set("MOZ_TLS_SERVER_DEBUG_LEVEL", "3"); + envSvc.set("MOZ_TLS_SERVER_CALLBACK_PORT", CALLBACK_PORT); + + let httpServer = new HttpServer(); + let serverReady = new Promise(resolve => { + httpServer.registerPathHandler("/", function handleServerCallback( + aRequest, + aResponse + ) { + aResponse.setStatusLine(aRequest.httpVersion, 200, "OK"); + aResponse.setHeader("Content-Type", "text/plain"); + let responseBody = "OK!"; + aResponse.bodyOutputStream.write(responseBody, responseBody.length); + executeSoon(function() { + httpServer.stop(resolve); + }); + }); + httpServer.start(CALLBACK_PORT); + }); + + let serverBin = _getBinaryUtil(serverBinName); + let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); + process.init(serverBin); + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append(`${certsPath}`); + Assert.ok(certDir.exists(), `certificate folder (${certsPath}) should exist`); + // Using "sql:" causes the SQL DB to be used so we can run tests on Android. + process.run(false, ["sql:" + certDir.path, Services.appinfo.processID], 2); + + registerCleanupFunction(function() { + process.kill(); + }); + + await serverReady; +} + +// Returns an Array of OCSP responses for a given ocspRespArray and a location +// for a nssDB where the certs and public keys are prepopulated. +// ocspRespArray is an array of arrays like: +// [ [typeOfResponse, certnick, extracertnick, thisUpdateSkew]...] +function generateOCSPResponses(ocspRespArray, nssDBlocation) { + let utilBinName = "GenerateOCSPResponse"; + let ocspGenBin = _getBinaryUtil(utilBinName); + let retArray = []; + + for (let i = 0; i < ocspRespArray.length; i++) { + let argArray = []; + let ocspFilepre = do_get_file(i.toString() + ".ocsp", true); + let filename = ocspFilepre.path; + // Using "sql:" causes the SQL DB to be used so we can run tests on Android. + argArray.push("sql:" + nssDBlocation); + argArray.push(ocspRespArray[i][0]); // ocsRespType; + argArray.push(ocspRespArray[i][1]); // nick; + argArray.push(ocspRespArray[i][2]); // extranickname + argArray.push(ocspRespArray[i][3]); // thisUpdate skew + argArray.push(filename); + info("argArray = " + argArray); + + let process = Cc["@mozilla.org/process/util;1"].createInstance( + Ci.nsIProcess + ); + process.init(ocspGenBin); + process.run(true, argArray, argArray.length); + Assert.equal(0, process.exitValue, "Process exit value should be 0"); + let ocspFile = do_get_file(i.toString() + ".ocsp", false); + retArray.push(readFile(ocspFile)); + ocspFile.remove(false); + } + return retArray; +} + +// Starts and returns an http responder that will cause a test failure if it is +// queried. The server identities are given by a non-empty array +// serverIdentities. +function getFailingHttpServer(serverPort, serverIdentities) { + let httpServer = new HttpServer(); + httpServer.registerPrefixHandler("/", function(request, response) { + Assert.ok(false, "HTTP responder should not have been queried"); + }); + httpServer.identity.setPrimary("http", serverIdentities.shift(), serverPort); + serverIdentities.forEach(function(identity) { + httpServer.identity.add("http", identity, serverPort); + }); + httpServer.start(serverPort); + return httpServer; +} + +// Starts an http OCSP responder that serves good OCSP responses and +// returns an object with a method stop that should be called to stop +// the http server. +// NB: Because generating OCSP responses inside the HTTP request +// handler can cause timeouts, the expected responses are pre-generated +// all at once before starting the server. This means that their producedAt +// times will all be the same. If a test depends on this not being the case, +// perhaps calling startOCSPResponder twice (at different times) will be +// necessary. +// +// serverPort is the port of the http OCSP responder +// identity is the http hostname that will answer the OCSP requests +// nssDBLocation is the location of the NSS database from where the OCSP +// responses will be generated (assumes appropiate keys are present) +// expectedCertNames is an array of nicks of the certs to be responsed +// expectedBasePaths is an optional array that is used to indicate +// what is the expected base path of the OCSP request. +// expectedMethods is an optional array of methods ("GET" or "POST") indicating +// by which HTTP method the server is expected to be queried. +// expectedResponseTypes is an optional array of OCSP response types to use (see +// GenerateOCSPResponse.cpp). +// responseHeaderPairs is an optional array of HTTP header (name, value) pairs +// to set in each response. +function startOCSPResponder( + serverPort, + identity, + nssDBLocation, + expectedCertNames, + expectedBasePaths, + expectedMethods, + expectedResponseTypes, + responseHeaderPairs = [] +) { + let ocspResponseGenerationArgs = expectedCertNames.map(function( + expectedNick + ) { + let responseType = "good"; + if (expectedResponseTypes && expectedResponseTypes.length >= 1) { + responseType = expectedResponseTypes.shift(); + } + return [responseType, expectedNick, "unused", 0]; + }); + let ocspResponses = generateOCSPResponses( + ocspResponseGenerationArgs, + nssDBLocation + ); + let httpServer = new HttpServer(); + httpServer.registerPrefixHandler("/", function handleServerCallback( + aRequest, + aResponse + ) { + info("got request for: " + aRequest.path); + let basePath = aRequest.path.slice(1).split("/")[0]; + if (expectedBasePaths.length >= 1) { + Assert.equal( + basePath, + expectedBasePaths.shift(), + "Actual and expected base path should match" + ); + } + Assert.ok( + expectedCertNames.length >= 1, + "expectedCertNames should contain >= 1 entries" + ); + if (expectedMethods && expectedMethods.length >= 1) { + Assert.equal( + aRequest.method, + expectedMethods.shift(), + "Actual and expected fetch method should match" + ); + } + aResponse.setStatusLine(aRequest.httpVersion, 200, "OK"); + aResponse.setHeader("Content-Type", "application/ocsp-response"); + for (let headerPair of responseHeaderPairs) { + aResponse.setHeader(headerPair[0], headerPair[1]); + } + aResponse.write(ocspResponses.shift()); + }); + httpServer.identity.setPrimary("http", identity, serverPort); + httpServer.start(serverPort); + return { + stop(callback) { + // make sure we consumed each expected response + Assert.equal( + ocspResponses.length, + 0, + "Should have 0 remaining expected OCSP responses" + ); + if (expectedMethods) { + Assert.equal( + expectedMethods.length, + 0, + "Should have 0 remaining expected fetch methods" + ); + } + if (expectedBasePaths) { + Assert.equal( + expectedBasePaths.length, + 0, + "Should have 0 remaining expected base paths" + ); + } + if (expectedResponseTypes) { + Assert.equal( + expectedResponseTypes.length, + 0, + "Should have 0 remaining expected response types" + ); + } + httpServer.stop(callback); + }, + }; +} + +// Given an OCSP responder (see startOCSPResponder), returns a promise that +// resolves when the responder has successfully stopped. +function stopOCSPResponder(responder) { + return new Promise((resolve, reject) => { + responder.stop(resolve); + }); +} + +// Utility functions for adding tests relating to certificate error overrides + +// Helper function for add_cert_override_test. Probably doesn't need to be +// called directly. +function add_cert_override(aHost, aExpectedBits, aSecurityInfo) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + true + ); +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and an +// expected error code, tests that an initial connection to the host fails +// with the expected errors and that adding an override results in a subsequent +// connection succeeding. +function add_cert_override_test( + aHost, + aExpectedBits, + aExpectedError, + aExpectedSecInfo = undefined +) { + add_connection_test( + aHost, + aExpectedError, + null, + add_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => { + Assert.ok( + aSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "Cert override flag should be set on the security state" + ); + if (aExpectedSecInfo) { + if (aExpectedSecInfo.failedCertChain) { + ok( + aExpectedSecInfo.failedCertChain.equals(aSecurityInfo.failedCertChain) + ); + } + } + }); +} + +// Helper function for add_prevented_cert_override_test. This is much like +// add_cert_override except it may not be the case that the connection has an +// SecInfo set on it. In this case, the error was not overridable anyway, so +// we consider it a success. +function attempt_adding_cert_override(aHost, aExpectedBits, aSecurityInfo) { + if (aSecurityInfo.serverCert) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + true + ); + } +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and +// an expected error code, tests that an initial connection to the host fails +// with the expected errors and that adding an override does not result in a +// subsequent connection succeeding (i.e. the same error code is encountered). +// The idea here is that for HSTS hosts or hosts with key pins, no error is +// overridable, even if an entry is added to the override service. +function add_prevented_cert_override_test( + aHost, + aExpectedBits, + aExpectedError +) { + add_connection_test( + aHost, + aExpectedError, + null, + attempt_adding_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, aExpectedError); +} + +// Helper for asyncTestCertificateUsages. +class CertVerificationResult { + constructor(certName, usageString, successExpected, resolve) { + this.certName = certName; + this.usageString = usageString; + this.successExpected = successExpected; + this.resolve = resolve; + } + + verifyCertFinished(aPRErrorCode, aVerifiedChain, aHasEVPolicy) { + if (this.successExpected) { + equal( + aPRErrorCode, + PRErrorCodeSuccess, + `verifying ${this.certName} for ${this.usageString} should succeed` + ); + } else { + notEqual( + aPRErrorCode, + PRErrorCodeSuccess, + `verifying ${this.certName} for ${this.usageString} should fail` + ); + } + this.resolve(); + } +} + +/** + * Asynchronously attempts to verify the given certificate for all supported + * usages (see allCertificateUsages). Verifies that the results match the + * expected successful usages. Returns a promise that will resolve when all + * verifications have been performed. + * Verification happens "now" with no specified flags or hostname. + * + * @param {nsIX509CertDB} certdb + * The certificate database to use to verify the certificate. + * @param {nsIX509Cert} cert + * The certificate to be verified. + * @param {Number[]} expectedUsages + * A list of usages (as their integer values) that are expected to verify + * successfully. + * @return {Promise} + * A promise that will resolve with no value when all asynchronous operations + * have completed. + */ +function asyncTestCertificateUsages(certdb, cert, expectedUsages) { + let now = new Date().getTime() / 1000; + let promises = []; + Object.keys(allCertificateUsages).forEach(usageString => { + let promise = new Promise((resolve, reject) => { + let usage = allCertificateUsages[usageString]; + let successExpected = expectedUsages.includes(usage); + let result = new CertVerificationResult( + cert.commonName, + usageString, + successExpected, + resolve + ); + let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY; + certdb.asyncVerifyCertAtTime(cert, usage, flags, null, now, result); + }); + promises.push(promise); + }); + return Promise.all(promises); +} + +/** + * Loads the pkcs11testmodule.cpp test PKCS #11 module, and registers a cleanup + * function that unloads it once the calling test completes. + * + * @param {nsIFile} libraryFile + * The dynamic library file that implements the module to + * load. + * @param {String} moduleName + * What to call the module. + * @param {Boolean} expectModuleUnloadToFail + * Should be set to true for tests that manually unload the + * test module, so the attempt to auto unload the test module + * doesn't cause a test failure. Should be set to false + * otherwise, so failure to automatically unload the test + * module gets reported. + */ +function loadPKCS11Module(libraryFile, moduleName, expectModuleUnloadToFail) { + ok(libraryFile.exists(), "The PKCS11 module file should exist"); + + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + registerCleanupFunction(() => { + try { + pkcs11ModuleDB.deleteModule(moduleName); + } catch (e) { + Assert.ok( + expectModuleUnloadToFail, + `Module unload should suceed only when expected: ${e}` + ); + } + }); + pkcs11ModuleDB.addModule(moduleName, libraryFile.path, 0, 0); +} + +/** + * @param {String} data + * @returns {String} + */ +function hexify(data) { + // |slice(-2)| chomps off the last two characters of a string. + // Therefore, if the Unicode value is < 0x10, we have a single-character hex + // string when we want one that's two characters, and unconditionally + // prepending a "0" solves the problem. + return Array.from(data, (c, i) => + ("0" + data.charCodeAt(i).toString(16)).slice(-2) + ).join(""); +} + +/** + * @param {String[]} lines + * Lines to write. Each line automatically has "\n" appended to it when + * being written. + * @param {nsIFileOutputStream} outputStream + */ +function writeLinesAndClose(lines, outputStream) { + for (let line of lines) { + line += "\n"; + outputStream.write(line, line.length); + } + outputStream.close(); +} + +/** + * @param {String} moduleName + * The name of the module that should not be loaded. + * @param {String} libraryName + * A unique substring of name of the dynamic library file of the module + * that should not be loaded. + */ +function checkPKCS11ModuleNotPresent(moduleName, libraryName) { + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let modules = moduleDB.listModules(); + ok( + modules.hasMoreElements(), + "One or more modules should be present with test module not present" + ); + for (let module of modules) { + notEqual( + module.name, + moduleName, + `Non-test module name shouldn't equal '${moduleName}'` + ); + ok( + !(module.libName && module.libName.includes(libraryName)), + `Non-test module lib name should not include '${libraryName}'` + ); + } +} + +/** + * Checks that the test module exists in the module list. + * Also checks various attributes of the test module for correctness. + * + * @param {String} moduleName + * The name of the module that should be present. + * @param {String} libraryName + * A unique substring of the name of the dynamic library file + * of the module that should be loaded. + * @returns {nsIPKCS11Module} + * The test module. + */ +function checkPKCS11ModuleExists(moduleName, libraryName) { + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let modules = moduleDB.listModules(); + ok( + modules.hasMoreElements(), + "One or more modules should be present with test module present" + ); + let testModule = null; + for (let module of modules) { + if (module.name == moduleName) { + testModule = module; + break; + } + } + notEqual(testModule, null, "Test module should have been found"); + notEqual(testModule.libName, null, "Test module lib name should not be null"); + ok( + testModule.libName.includes(ctypes.libraryName(libraryName)), + `Test module lib name should include lib name of '${libraryName}'` + ); + + return testModule; +} + +// Given an nsIX509Cert, return the bytes of its subject DN (as a JS string) and +// the sha-256 hash of its subject public key info, base64-encoded. +function getSubjectAndSPKIHash(nsCert) { + let certBytes = nsCert.getRawDER(); + let cert = new X509.Certificate(); + cert.parse(certBytes); + let subject = cert.tbsCertificate.subject._der._bytes; + let subjectString = arrayToString(subject); + let spkiHashString = nsCert.sha256SubjectPublicKeyInfoDigest; + return { subjectString, spkiHashString }; +} + +function run_certutil_on_directory(directory, args, expectSuccess = true) { + let envSvc = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile); + envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path); + // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD" + // does not return this path on Android, so hard code it here. + envSvc.set("LD_LIBRARY_PATH", greBinDir.path + ":/data/local/xpcb"); + let certutilBin = _getBinaryUtil("certutil"); + let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); + process.init(certutilBin); + args.push("-d"); + args.push(`sql:${directory}`); + process.run(true, args, args.length); + if (expectSuccess) { + Assert.equal(process.exitValue, 0, "certutil should succeed"); + } +} diff --git a/security/manager/ssl/tests/unit/moz.build b/security/manager/ssl/tests/unit/moz.build new file mode 100644 index 0000000000..212f14a22f --- /dev/null +++ b/security/manager/ssl/tests/unit/moz.build @@ -0,0 +1,42 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ["tlsserver"] + +if not CONFIG["MOZ_NO_SMART_CARDS"]: + DIRS += ["pkcs11testmodule"] + +TEST_DIRS += [ + "bad_certs", + "ocsp_certs", + "test_baseline_requirements", + "test_cert_eku", + "test_cert_embedded_null", + "test_cert_keyUsage", + "test_cert_sha1", + "test_cert_signatures", + "test_cert_trust", + "test_cert_utf8", + "test_cert_version", + "test_certDB_import", + "test_content_signing", + "test_ct", + "test_delegated_credentials", + "test_encrypted_client_hello", + "test_ev_certs", + "test_intermediate_basic_usage_constraints", + "test_intermediate_preloads", + "test_keysize", + "test_keysize_ev", + "test_missing_intermediate", + "test_name_constraints", + "test_ocsp_url", + "test_onecrl", + "test_sanctions", + "test_signed_apps", + "test_startcom_wosign", + "test_validity", +] diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem new file mode 100644 index 0000000000..3fffeaf56f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUF4tSVpnzLjrUBoa9WMfShlqrEjwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IEludGVybWVkaWF0ZSB1c2VkIGFz +IEVuZC1FbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjcjBwMAwGA1UdEwQFMAMBAf8wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMCwGA1UdEQQl +MCOCIWNhLXVzZWQtYXMtZW5kLWVudGl0eS5leGFtcGxlLmNvbTANBgkqhkiG9w0B +AQsFAAOCAQEAllsGy7B4yROdLH5rmLV6Q6AxUMKk/ixwfCnkt3ibKGtoypvAG6wn +vevqezN7BUeqIZd0QeoZBEtKwxv87oCiVDgSPXhkGqxryN9i8Zii07Sa27rCVZHd +F/AJv7qSgl2mYPYAAcyDX5F5ecbc3i9tc96mYSUJawhgPCwNB6PGB+HUr5fSskzx +j7Rg+0k9TEpk5bcTlsqH2hFvM9ZycEFC0/9trBVvnvh51WTHX/AzZDaaHPyOd2jD +RxqCMwde0EfpNQmpz39WnRJqs7bf2Cdc080m/apFL9yjZOuCfNaWdezfNjWoBKNC +S5tpZOoqNYzdV/8VAy74Nv+cXGNX4Ct7RA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec new file mode 100644 index 0000000000..8e16705b50 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate used as End-Entity +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:ca-used-as-end-entity.example.com diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem new file mode 100644 index 0000000000..8e6085c3e1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcugAwIBAgIUE031neMThT1B9azoKkIDscqx+88wDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAoMSYwJAYDVQQDDB1UZXN0IFNIQTEgRGVsZWdhdGVkIFJlc3Bv +bmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMF1xlJmCZ93CCpn +kfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJisSjs8H2FIf0G2mJQb2ApRw8EgJE +xYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF2YMTud+vN4NF2s5R1Nbc0qbLPMcG +680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElEWQvFo+pJ/ZOx11NAXxdzdpmVhmYl +R5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzSg3UTH5MrEozihvp9JRwGKtJ+8Bbx +h83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0YxMC4xo/DdIRXMkrX3obmVS8dHhkd +cSFo07sCAwEAAaMXMBUwEwYDVR0lBAwwCgYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAI2xNUwZgoTpe439ouS6dI/8JRgWKTq9pzZdW5v7a0Tlwx7KUmoZ6mlZ +xgvCVlk/6zIXT+eN0l79YDzWGzqjLpsFPuxPuczb1KraEFBteHwm/lrUpij2cnYD +yOUNgCpIpUfR0UO5AOzAs1yHeMb/5YkfFl+4xU6rY6QL0RaI5n9rFbaPbXE0cNGg +ORxg8K6/JwlwsfXg0pT/5KtcWEvdo2YVU5X26UROFBbwtWmcp6xpqnYVJY69mXGN +utLR039Nv6IO5F6m0looSt0p3SSCNgqyls3GY6c8xXqS0YOR04IvGDHqWg2QKPtQ +T1HiTliyNYNFzr2e84eTeqQm8aTUMYs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec new file mode 100644 index 0000000000..bdf3e2ee4d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test SHA1 Delegated Responder +subjectKey:alternate +signature:sha1WithRSAEncryption +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem new file mode 100644 index 0000000000..9c5ceb2af7 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3jCCAcagAwIBAgIUM8qmS5w0gb5569IOxnYzJV4lfV4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhUZXN0IERlbGVnYXRlZCBSZXNwb25kZXIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBdcZSZgmfdwgqZ5HxuHbD +f1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBICRMWEpMRI +MwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzHBuvNMHDs +mMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZmJUeX7UJp +CIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW8YfN1U6D +KzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4ZHXEhaNO7 +AgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IB +AQCeOJWvm8T7quyhSh8Yyu6/h7Yzi6h7YcVaK0azDuvWpWvJALZcYnKir6qOFbbD +x9pVEZ1r5DmwuC0UqBKo3KC8sDykT4fkjxKzW1OfOI0Iy6i76LHDGN7Ohg/U8I6x +V3rdTyVkNxFDKo4nK5WHNkMR5CBY7LcysV5sDFI79O3eM62UVSgP7+RaOV0cul0x +S8a1uad+azyE7EIM9qVkaO9456Z8ZT9P04fX5LRjrY/RVKXAUmpWGFmGes+matjw +2StNMW9jmbxc+eFoMUqUD9R4iJdElGj8ut4JbRvAHmtPv/Bj64WwIvsdvLRkCN06 +7vmqrN3x/8Bjga6uDx+zMHkr +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec new file mode 100644 index 0000000000..19971eeb4d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Delegated Responder +subjectKey:alternate +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem new file mode 100644 index 0000000000..7d22b7e3d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAjCCAeqgAwIBAgIUEePkwqVPaz9IVH+MGS7msFHPqyowDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowPTE7MDkGA1UEAwwyVGVzdCBJbnZhbGlkIERl +bGVnYXRlZCBSZXNwb25kZXIgRnJvbSBJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDBdcZSZgmfdwgqZ5HxuHbDf1zlOLBsSs0iscvU +b6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBICRMWEpMRIMwXlE4wBBs8IvpqG +J2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzHBuvNMHDsmMzkCqWR1ylaf3HF +vmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZmJUeX7UJpCIgIEUIgaZiKQ/7k +jOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW8YfN1U6DKzW4kw90upCqi8dh +ZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4ZHXEhaNO7AgMBAAGjFzAVMBMG +A1UdJQQMMAoGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IBAQBFmLHca/8lrjch +HtvuzERgSHeF8gsOjCKbkKmIJqAX7oAl+xoGV7sRzbk9Jcsl1be+xoffBCfuBPXI +a1Mr08nB7HV5h1fKu1Bt68i1rpKp0cDawfJeccovZQCbEpmwJ+sF5SCdA628KxoX +JclPsYODRqt6JSTb7WTRD7tIDO+CO9Q9Z2fis3zj6ZEN+mgnqj/SRFjkHnGKaRLN +1Aaj5Lbr6B1HZN5UbhAKySqkDAm/iWg8pFm6syJ3qMfjf65jecvbP6T0gXDueYG/ +qAcnddtqGmQQvU1WbmbtC4Vxg71yw62OhRtfUd5gVpRaVWE9Rcv09JHsu5Nox14p +sTEjoV/Q +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec new file mode 100644 index 0000000000..be0d3e9e5f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate +subject:Test Invalid Delegated Responder From Intermediate +subjectKey:alternate +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem new file mode 100644 index 0000000000..f44489f591 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUbf11GwRR/gsZC/ZdyZ4rphMYM9AwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA/MT0wOwYDVQQDDDRUZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBrZXlVc2FnZSBjcmxTaWduaW5nMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5TiwbErNIrHL1G+mWtoq3UHI +wkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROMAQbPCL6ahidguuai6PNv +I8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5AqlkdcpWn9xxb5maR0rLf7I +SURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFCIGmYikP+5Izmh4HdIram +nNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMPdLqQqovHYWckKrH9bWIU +DRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQABow8wDTALBgNVHQ8EBAMC +AQIwDQYJKoZIhvcNAQELBQADggEBADLwe7YTejSPwSk2T+oDdGunG96A7fTOadGo +/ygjd90S4ockZ+Bi/WgpEf/nPAhArYjKOdL0ND1lm2Zv5f5Ge/XrqX2rL4s7Owfq +sOounyEP2RMwX58I1bkrCsx7kKGDOIRXyhukaCdiircMiu/GT8tiBmxCJ5NfTsEi +k0R3+RaFQ0uhuryJWJ0IzjwPx7MaekSJuZ3rwSkm41zgCLU6cU9PkBW3jGW+M4Dg +cTvUzqryhFfdctaESk5OUT2XW7f4s1QlcbjyK5XDD97vC7zey/C8K+2xizaLDBVZ +iWdoE3WDmOHcYlLFeVg2l2sVAO1slQItVuQ1myy3VZo1r+SXEgs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec new file mode 100644 index 0000000000..2833ed9b52 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder keyUsage crlSigning +subjectKey:alternate +extension:keyUsage:cRLSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem new file mode 100644 index 0000000000..4d8de4e52d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3DCCAcSgAwIBAgIULfke5oAO5ZbtLXezjOOcrqEQIHwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA6MTgwNgYDVQQDDC9UZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBObyBleHRLZXlVc2FnZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMF1xlJmCZ93CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJisSj +s8H2FIf0G2mJQb2ApRw8EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF2YMT +ud+vN4NF2s5R1Nbc0qbLPMcG680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElEWQvF +o+pJ/ZOx11NAXxdzdpmVhmYlR5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzSg3UT +H5MrEozihvp9JRwGKtJ+8Bbxh83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0YxMC4 +xo/DdIRXMkrX3obmVS8dHhkdcSFo07sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Yco2Ah5HxHlmkSm1YhZ6AyuGv/FyXmMkJ+7Jr7NCXy/MuQAGj1QtKbhFCtt2iotU +D8V+sNPgUbtimTkstt3cdUsQhT61l+S9ZN1Be8Vza0S6RBA48RbkyDCx69DfjOWa +yJF0WB0eg5H2GMq2+i2LNU1qgFhld62miB1g7We80GYX/+bBEfTvjuojaeSWijN2 +6txGUC1udv4o2ELsuvma0nymBr3et9xVwuFfWoLbQAeyRHCScdSku0vB/kDQb6Pt +uCasUnBGiMPpf4w5DDNetLFh9FITYLCb4xWoPsj+6DSizVmD2/rOXhaNSwyHdWn9 +v2FW/J0cNFFuZLTSBA3z4w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..92444c94ad --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder No extKeyUsage +subjectKey:alternate diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem new file mode 100644 index 0000000000..ddc5ca01b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+DCCAeCgAwIBAgIUdw7kK4XEwM9Ipz41NlM1pF9VSEkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA9MTswOQYDVQQDDDJUZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBXcm9uZyBleHRLZXlVc2FnZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMF1xlJmCZ93CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJ +isSjs8H2FIf0G2mJQb2ApRw8EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF +2YMTud+vN4NF2s5R1Nbc0qbLPMcG680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElE +WQvFo+pJ/ZOx11NAXxdzdpmVhmYlR5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzS +g3UTH5MrEozihvp9JRwGKtJ+8Bbxh83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0Y +xMC4xo/DdIRXMkrX3obmVS8dHhkdcSFo07sCAwEAAaMXMBUwEwYDVR0lBAwwCgYI +KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBABdCK3EKY/6lwuCehtiHVJ6XcFBO +rTUmmRxkrRfXzn47Llofu/QC9OISWhfV/JefrNh44mYkkscsWV76eHsEqOp2F3Gz +Kv0bhlFt2ihCh1dzgz6tGWT5fwidow3nBSdssMZGqHD51kZXXGgB0xWopKDhnXgS +hUforJ1X4anMZzDgV52DSGB+dTo0atgq6ke2m+nOsW8CErYVGHs2ey4lugNPo+AO +XYaZqTclKGtrPjXt0P0E8ZaUs+Vxzx8jh0S096FDSPWMLdrfIETRB90legO8M2Qo +woGV4FsA48aPqqy6LPEke0NltJ/AlBwS5wz54TwWkhjjBV/dmBrFV2bFQzU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..bc704fbd41 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder Wrong extKeyUsage +subjectKey:alternate +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/moz.build b/security/manager/ssl/tests/unit/ocsp_certs/moz.build new file mode 100644 index 0000000000..212b3cad1d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/moz.build @@ -0,0 +1,42 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-used-as-end-entity.pem', +# 'default-ee.pem', +# 'delegatedSHA1Signer.pem', +# 'delegatedSigner.pem', +# 'invalidDelegatedSignerFromIntermediate.pem', +# 'invalidDelegatedSignerKeyUsageCrlSigning.pem', +# 'invalidDelegatedSignerNoExtKeyUsage.pem', +# 'invalidDelegatedSignerWrongExtKeyUsage.pem', +# 'multi-tls-feature-bad-ee.pem', +# 'multi-tls-feature-good-ee.pem', +# 'must-staple-ee.pem', +# 'must-staple-ee-with-must-staple-int.pem', +# 'must-staple-missing-ee.pem', +# 'ocspEEWithIntermediate.pem', +# 'ocspOtherEndEntity.pem', +# 'other-test-ca.pem', +# 'rsa-1016-keysizeDelegatedSigner.pem', +# 'test-ca.pem', +# 'test-int.pem', +# 'test-multi-tls-feature-int.pem', +# 'test-must-staple-int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'other-test-ca.key', +# 'rsa-1016-keysizeDelegatedSigner.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem new file mode 100644 index 0000000000..be14c630f8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJDCCAgygAwIBAgIUX5dBLWiffAZEKD2dHegBV9jFkhMwDQYJKoZIhvcNAQEL +BQAwNzE1MDMGA1UEAwwsVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdWx0aXBsZSBU +TFMgRmVhdHVyZXMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFow +LDEqMCgGA1UEAwwhTXVsdGkgVExTIEZlYXR1cmUgVGVzdCBFbmQtRW50aXR5MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABoy8wLTAYBgNVHREEETAPgg0qLmV4YW1wbGUuY29tMBEGCCsGAQUFBwEYBAUw +AwIBBTANBgkqhkiG9w0BAQsFAAOCAQEAoxlWVngbuVoxZdE2qM6gPpMbCR0vW99b +XWki1fUm9RwQ0XhobwDXJvpopSguoZ5gNsXoGHpLUTsQNVgdcNz9YJkjU05JhQQF +KRAufrkry4TLe+PmGmLCWkMJh2hemv8Ih5TUs2GPS4QsbAXKa3me6T3J4q4KBlH/ +RNN0cozoIbGdUmCmSFKgxnMuUN5E5/RpN06lgZIthtjcCvgbWHrOTPDJOs50KZSr +l4+fHiHxBoRvW0MJ3S/oixA6SQWrO86kv0iahn0kZA5cnqhrC8qI9HUnFT31k7AZ +XS4+EolIyjDrlse8fnehhW00dXjzH+zgvUNJFyafB3AYtJTco0gVqQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec new file mode 100644 index 0000000000..3fa2793b30 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Multiple TLS Features +subject:Multi TLS Feature Test End-Entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem new file mode 100644 index 0000000000..60a6c8b511 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJzCCAg+gAwIBAgIUNbatscZX2IBW2HGooNJW4304zyEwDQYJKoZIhvcNAQEL +BQAwNzE1MDMGA1UEAwwsVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdWx0aXBsZSBU +TFMgRmVhdHVyZXMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFow +LDEqMCgGA1UEAwwhTXVsdGkgVExTIEZlYXR1cmUgVGVzdCBFbmQtRW50aXR5MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABozIwMDAYBgNVHREEETAPgg0qLmV4YW1wbGUuY29tMBQGCCsGAQUFBwEYBAgw +BgIBBQIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKvmpaXwjW7///EBD0Qt6u4eYWxOf +kItU9yAiOjoKpSl803Jskqpt1WAYeOWv0+vjlFlkSR+Wb4bUiWFUG0ETXQPnpndy +zc0smDI+2ILQSRAUqF6UYvMqqkMQfTEfZN3CTSH48BdBw2G1brWnPBl/2qRZTFRy +/mdOZqJmE4UZhkf8ihtyQstqlVNqNAW6luS8u3tm5Uwk/ZVsH80yphF0OPQAFMGV +GxYbNYpmaUcJ4xGH1bwvxpUc7eVvu18GpZpl74VYThaizvXWTlIQGMxQU0OgBSAx +1uNpLNMo2eoGXPt7sC9v9fMq/KFN/VfCULlIwrALDfQdhJ4ctTQbHNCZtQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec new file mode 100644 index 0000000000..7a8dd223d0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Multiple TLS Features +subject:Multi TLS Feature Test End-Entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple,6 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem new file mode 100644 index 0000000000..f82cc96a06 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCDCCAfCgAwIBAgIUcXF8++LMW19oSQg8vdU5I0GGZWkwDQYJKoZIhvcNAQEL +BQAwLTErMCkGA1UEAwwiVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdXN0LVN0YXBs +ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQD +DA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAtMBgGA1UdEQQRMA+CDSouZXhhbXBs +ZS5jb20wEQYIKwYBBQUHARgEBTADAgEFMA0GCSqGSIb3DQEBCwUAA4IBAQArhytK +0cN71epgzB/5M26RujocEL8Puk5O04x1uEbU7j3y+mNTO7bLB5z76ZKEzU98blLq +V6Ds7PvmBHW/41KP8e7MwkOGprvUllfI8zmTvxXDV2iHGtmOvvEbfOf/QZS0e4Dj +eZCcew9p4/+Efe5lcto6QazTfFSJLxjkpKHU6S0ZgAu5mEZl5UW7VdR5LHzHp17t +dT4EWMt41CPoGxeJWYL5pOK14sD5GmUQ9OADzPBiN1M2v/9JY9IOWRabP1VafTYK +95PHA21eXqmA6SjCugaCMXW99pdStcBSCvQEAWfHBWloyALzG5Mh7H14tuM41ldF +abWEJfmtmGP2F2ru +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec new file mode 100644 index 0000000000..352a60675d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Must-Staple +subject:Test End-entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem new file mode 100644 index 0000000000..9453f79225 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUFdjcRo9oZDqo1b9UOWgfewuqbdwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjYzBh +MBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20wEQYIKwYBBQUHARgEBTADAgEFMDIG +CCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4 +LzANBgkqhkiG9w0BAQsFAAOCAQEAMkt3s3WLtDF364ZlSZ+WSei6kpk8XNmQ8PlM +SswAApahPrWlYlZ/V7Y18MHLHF26Rmoh2NdUczmLcOvvwRxq9/ekooDP4HkB7WFz +YnfDo5lWhqRUyTVmSVUS2SS7mmvt1fPbZrB8kjATqhvAmOu23XmxZzJu3ylGfBn2 +MJhLxt3VhOymRkiX3sPFboxCsipj5zD3jeqGbwJCnlr3kwqvTayUEke35mvkwCew +3L7akzbjXdJ8sFeLw/ZNpPbslRkVmV3lCv1Kl08U0POM6tKoow4sw4P0iVXGQqRT +H/4Stc8jzHop21H5chKAfMVQqIM3u05o022+rzrCQomyoVCLaA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec new file mode 100644 index 0000000000..43edfff0d9 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem new file mode 100644 index 0000000000..a436415f30 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9TCCAd2gAwIBAgIUL+F6WGk9sZuSuDMbhvPWt8PKv3owDQYJKoZIhvcNAQEL +BQAwLTErMCkGA1UEAwwiVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdXN0LVN0YXBs +ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQD +DA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHDAaMBgGA1UdEQQRMA+CDSouZXhhbXBs +ZS5jb20wDQYJKoZIhvcNAQELBQADggEBALem6GEzJyvZWTVaYg54X2qWTnFfHVyu +4F/UbGX54D+8hl/zumovWsAtPPfcls94uAMeVvAoRTBP8dUcubilzMwMig7QUPUs +2YeqeQZ+2+NFHwmMG9SnkSU+CK8lnD4JJClLUuS2rYh5q+tp7c+U7+jFuktqIAQg +PJijEhiFq0wlqjXg2ytvbdurEm/LAz+wu8sEJtWsWLCZt8QiQfYhX/epFRreO8tB +Ulu/FCh/1kWx7JAIudigMSQqsg2R7ohgHyOV5Bm9ad2OyTuBjQ8xGFba3Y4jtPvy +w6mpRAeFEJB7FVTdDQFAyEryoSuOE8MAve2Ld/+9YDddom4S5+ocXo8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec new file mode 100644 index 0000000000..8e4a6ac0c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate With Must-Staple +subject:Test End-entity +extension:subjectAlternativeName:*.example.com diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem new file mode 100644 index 0000000000..71459bdd6d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUc2xqnbHi4aDQ1Rj+6hXoSA+ut+8wDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhVGVzdCBFbmQtZW50aXR5 +IHdpdGggSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAagglsb2NhbGhv +c3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo +dHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCig/et41o2 +7hC3LJBIt5yh/eOgjZEUiuJlLAtrMssa5VjdxMDRyqBgn7FUMZMVnIpqRe9V0/a5 +E+yMZp+PvMWxexPlue7SOe7VYaDGvStdJ4ecsEqZzw151k6EuvyT2NJZPj92Mx+0 +gAAo2GysadZEn4E1juLZDCk+fTU1sq8Fek3XocrB/5on3UotDtglBIKW+O8N/vVh +0Fymnt8owdmt9anGJW9GSLf11b2qZ9XS+5Wlyn3ujDDaeL6+d70mKWo1AuxA7IQx +ODcsUb6lCGtyyJCLul6oW1ABJNGh1QGAPc3XSeONc2/w7UZcc5IzpmD46V1soJXl +yLUPGwF1W//L +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec new file mode 100644 index 0000000000..ae3a51565a --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate +subject:Test End-entity with Intermediate +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem new file mode 100644 index 0000000000..25036c7c21 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIUX1EMg6wBeHSbS/NgLV/M/PaxdWswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAVMRMwEQYDVQQDDApPdGhlciBDZXJ0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNV +HREEHDAagglsb2NhbGhvc3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAk +MCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEB +CwUAA4IBAQCvTyo5F7zhOPBd0LZJpC0ZQAktZtct7z9j0E+iUbo6tohRsvRMmbDs +lO/cwks/I2sNa3fzHEzE+oC/0kiCS9JUiHUSUrHQrPOraP1urmRdhzECbyFVQsdw +E9YEtfZemxBQd/pHj7VnYlZ9xNimGZ7rcSi0vif3QbB3BlJiFfAe+IrJ1tkfYOGY +3xwoCCWOIGj0xl79MXzlG6iI9678y0vUu45tM1JbnauekEjF65CqME035e3eFq/t +oqghb07JW7JSGmIz0JE+0qli2iT2QIML77Wk0OTE9niDPAbORFPRbNytycNQ8yHk +xDvo21FgYZFATLiYf4oUADqp23sTIhac +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec new file mode 100644 index 0000000000..5756f6ab5f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Other Cert +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key new file mode 100644 index 0000000000..abde350c28 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBdcZSZgmfdwgq +Z5HxuHbDf1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBIC +RMWEpMRIMwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzH +BuvNMHDsmMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZm +JUeX7UJpCIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW +8YfN1U6DKzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4Z +HXEhaNO7AgMBAAECggEAfj9tfLg572auXX3ZL/VBC7NB3BRyjTkDRXDho3B5DzDw +aBNV//QeKtTpqdn86/vRJ736uMAK/7Hzzqcyfq1HqhYh8qwe4UygLwSzsnhgF5gL +GBpEnQOwPmnRErg1ceVUNPASBWV10oMu1nMdznmeN8g/bVHFWrcetYAVrwXhrxXH +R2A+9/J9A6b/BJ2Wu/hUweTlDvWwWND7CBgOCsf3vo8v8Wc9l/yeVduoOAd7v4p8 +/ylihXeFJpzZ1brStXRp5K/NM8TKLS9pnxHnyPvc1ITwjY77ijy4qXLrJL7Zcu+q +5LtxIJPkj+lKRutimodQeMQCGposk8mnA5Dp0KVEAQKBgQDmP8clprp2klp/+MtZ +xPVt1+yD/oW/H1PhHKyagSWLz8CugZB3sPLRR3qvho3mqOy+r3uyKxlvKprYLTKG +8NDMKd5xnl8r6OUJtyhNWWPt02L5J4h6TEqJeZ00DVGzAax2AasnF5Ak/KrdOL9l +Iq9j6xZGHsAqfyewb+Cd3afAoQKBgQDXGLH+n4+Z8A6DKuH73G/iqyfzTgScSYAQ ++g63CEhSGCNGCDtclsPu5VksAUpBDGuTCxZcE7XCaqMurG58klqFUcJRNPL0pyxk +IfGacxSKDt+rpdOmiIs1y6GMAP047lqvC1RXMdcgdhu8ze50SlLKQV6Y5N4Bzf52 +TBlns+jK2wKBgAHlrKJmyUqI0i4TwrkuokcRbGV6B2gXvf0w20s6nTCVuaS2dJZH +4vhOenhPx4OLCMhZcc96A2+jDjuRw8TQ3yePgMG26FnYRWrbE33vqp8fCsW6yakY +T9TqJ51yLqYm8WDXiq17yDhFzLKd8RXIP2G3YiuZvUOcYJtXkKY8WVGBAoGBAIDM +RdENJITuDRKX/Ae/gLO+/0Yeon4fOPNxeJw69mtKDt0hksIneR208cd64ka/NC8x +hWsPVlgbWKlbETHAxTltsqjDxvOeouM2vCBa5qKgs2hp/KmMu6czzwExmm+bsmt8 +oj0wF/xVHNjaiv3Rf2+i4w00hoeYHNYjTVcekLffAoGAb3fAwfKuesFpVhzKSZxS +vfvgTN3M29wSrsWoVpHoWUt+4pkI8w57lqpiVLgO1K7sm5k3gr38ebadjVjGiHD6 +S+G8DDUnKIxcgrtK668V7f8RBAP8eOas5qgoJ79C8M+nUeUHZRxWONuTk90j3R9r +KVFR3kS3f+Vaew3yceGaZcA= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec new file mode 100644 index 0000000000..cbd5f309c0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec @@ -0,0 +1 @@ +alternate diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem new file mode 100644 index 0000000000..a2e264030a --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIURym6o+VN9xgZXT/QLrvN/nv1ZN4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoY +DzIwMjUwMTAxMDAwMDAwWjAYMRYwFAYDVQQDDA1PdGhlciB0ZXN0IENBMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5Tiw +bErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROM +AQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5Aql +kdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFC +IGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMP +dLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAtXplrvls6HSbbibpzfGxOPmSuh2TH05bE4vQk+d7Kz6EOAFvgTiZbLwTxbrQ +gfrM05t+67C2nAeiwAtW34nUnu6S8MYA6mJjURWICbl7cAvCHuNjg1atVr6f1Y+9 +VFFG6aUibw3bzKneREmDEVcxlEWUaMvv/JjfyMA5veSyX6iTJYkIBrEiVV5Alzg5 +yVHBi6+tpuJDO/YLlG8kmfzkYeJkTyAGx1EJ2yQHim7R232638yb0KrhS4zKsfFU +egHhM4c+MpiCLc9q2EgblbYGx5GM+2leuzXunj1KPClHFrnmkRRm3rcESG2pK9RN +/48Nd38VNofRojEbzDSCdOFmow== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec new file mode 100644 index 0000000000..3bc975aa22 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec @@ -0,0 +1,7 @@ +issuer:Other test CA +subject:Other test CA +issuerKey:alternate +subjectKey:alternate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key new file mode 100644 index 0000000000..d43495f851 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICcAIBADANBgkqhkiG9w0BAQEFAASCAlowggJWAgEAAoGAANKbsS+4T93NKbOl +GctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZ +BX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvmnZoIMTbh +WvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAQJ/PEllBwvzkMJR1aLFJ3xbX9C97oXK +1/4rJ5grsoURSlBwBANq4c+K5Usl5Ns5IVq9fpA/YYwtiy8IzGzRLbzNciBeSUW2 +s984nl5D3goUi7LITiQx/b5ZILBEuycvRez/ByG337YDl/xhOp6jXCIwBTDK6PkV +nFNN878JEJUZAQJAD58XWXyFuAUbnGmvtV71dsmW29CQR9DM3ludYOpcZ/5PrGe+ +gD9LasWj8FD3a5ZvsU9c8QV2HlrebdlgsYO6VQJADXtjcRLOYaVRaMD5yThvsnmr +QMug1Ukza7plJ3JjqseCYRosgdm2Nc94xAAYhZ4BjF6QBtEuPS7m80bnn6QzaQJA +Cf1smj6m6RrjIHD5/BwhD/k1L5e+XR7rlRuzloHp3FtnKlMiIbPYkAyanZm50KTh +AtxFDKG4ewsTid5lFsCuDQJAAUG4MkkbfdSoMwiSACTHnK5kvUR9+IO7TFZyqWur +SLcSOzTyYyRFLNzrF/IeVw40fL4v1MLY+ZEOrCy22JW4yQJABFjdau4YyIsvm4Hx +vDB1riDcH5lz0gck8gsGBD1hR8h4nUoHroi8gshDjIk+AXsTlH9i4LGJWKMetmSx +nmTT4A== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec new file mode 100644 index 0000000000..21ed73d60b --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec @@ -0,0 +1 @@ +rsa1016 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem new file mode 100644 index 0000000000..f16060beee --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICazCCAVOgAwIBAgIUYU3JfdG046x00L5zAkjGn4xjoZUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA1MTMwMQYDVQQDDCpSU0EgMTAxNiBLZXkgU2l6ZSBUZXN0IERl +bGVnYXRlZCBSZXNwb25kZXIwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAANKb +sS+4T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJ +aj7SBxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyv +bXvmnZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAaMXMBUwEwYDVR0lBAww +CgYIKwYBBQUHAwkwDQYJKoZIhvcNAQELBQADggEBAHkGbdeUVBJCqfgXfmU4Acl1 +ZNunakiEmkZA2oOKvvksDaDg3rKbfZU6WwXhploKPtoWbCIyEkP3BTRJ6SqxNdq0 +S9yE3jR4CmfRy6+4f+cUIexihlI8l8PYC6ccXcZ5gvawCuMZ1YcVlq3LZS1WuNbV +qBhLURgwzXjpKMIzmsz0e6zIHNBskGX/vXLJjjUJSwnxxdTuCOZ0BUNpz26jMfdl +fEfYkPIEW0jvGSmg52NM6Uu20JUGM13lxp7WSrBPNqDnnV0Ivpvyiy1O7eOYBDRL +9LpnghoviPlE04OgvWtiEETNYkDxs606xOGd3eb/1HYLEdJtWdR7F2/KweJBqe8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec new file mode 100644 index 0000000000..05f73368a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:RSA 1016 Key Size Test Delegated Responder +subjectKey:rsa1016 +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem new file mode 100644 index 0000000000..08249b863e --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec new file mode 100644 index 0000000000..33b42c2f41 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem new file mode 100644 index 0000000000..63e94388af --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIUZVYCAllpNYOv9692qhipPYQMx/4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA3MTUwMwYDVQQDDCxUZXN0IEludGVybWVkaWF0ZSBXaXRoIE11 +bHRpcGxlIFRMUyBGZWF0dXJlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMzMDEwDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwFAYIKwYBBQUHARgECDAGAgEFAgEGMA0GCSqGSIb3DQEBCwUAA4IB +AQAdkLVuX3A0Q9pzWuUV0XADf/nao4Wo5tlpQgsPFNmtrZSeeMJhue7JczJpeuKj +0b176lb9VSKh8gdU7r1yvEYadl146UZnUvjbKGKQUlU9TLZBdgLnLIs845zRT8+T +6fQcWzapnhXVt7YSaNCri/iWXyWbOU/PdYjTZejU0lcCEml+t3J7KaKmrZqWZQT/ +CJa7hphC6qEmgE4zoWdmur3nhRFq7JkPGl1JeVEK4M4coec7gTqM/Z1gCkKLmBW9 +fHsYVtf+viYfL6I6xxQtTa7WdgGFKKJyJJ70A6om6TFiD5RHZDZ90wuwtjg1y25x +4rfoP1xZ9+2So4/8fNiX6PuD +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec new file mode 100644 index 0000000000..3f0e925aae --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate With Multiple TLS Features +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:TLSFeature:OCSPMustStaple,6 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem new file mode 100644 index 0000000000..ecdd4a9261 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDATCCAemgAwIBAgIUV+gXM8WzfHTQR4sK51eSBZrYF9IwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAtMSswKQYDVQQDDCJUZXN0IEludGVybWVkaWF0ZSBXaXRoIE11 +c3QtU3RhcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABozAwLjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAR +BggrBgEFBQcBGAQFMAMCAQUwDQYJKoZIhvcNAQELBQADggEBAJ3n7RFMk6L0VPZi +1inbBkR3qLljszxJIkBQiYEV+leqxMXzn3S1CyTD1Pgnc59TCcf2W6upn58duyFN +NQWj9o5BDGNoq4vs8LZAxs7KivhtDsrGAsr049nVG9VbbpxvCjsEA+oygqquPbhF +N+775DpAYL/ZDdl/M3/R3XjLgK4FwIu9MDCc45HuYCPTIAp9ASNH65fBfV0be3FM +2k1/luQygte7VkXKRLxA0/+q498Q3awyWdkFin1/0sTIcMpr2MAuFUMO9j1/BdD+ +2xRUpuHc5sEMHdCNEDZylCLrEMa6tqz9FzUclxAVL7y1irrlGxOfjm4tYzO3P2rr +bT6iDxk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec new file mode 100644 index 0000000000..7c29aa0ad1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate With Must-Staple +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build b/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build new file mode 100644 index 0000000000..0eef91b076 --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +FINAL_TARGET = "_tests/xpcshell/security/manager/ssl/tests/unit/pkcs11testmodule" + +UNIFIED_SOURCES += [ + "pkcs11testmodule.cpp", +] + +SharedLibrary("pkcs11testmodule") + +# C_GetFunctionList needs to be exported. As it turns out, it's much easier to +# just export all the symbols. +NoVisibilityFlags() +SYMBOLS_FILE = "pkcs11testmodule.symbols" + +NO_PGO = True diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp new file mode 100644 index 0000000000..fcc332bc40 --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp @@ -0,0 +1,577 @@ +/* -*- Mode: C++; tab-width: 8; 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/. */ + +// This is a testing PKCS #11 module that simulates a token being inserted and +// removed from a slot every 50ms. This is achieved mainly in +// Test_C_WaitForSlotEvent. If the application that loaded this module calls +// C_WaitForSlotEvent, this module waits for 50ms and returns, having changed +// its internal state to report that the token has either been inserted or +// removed, as appropriate. +// This module also provides an alternate token that is always present for tests +// that don't want the cyclic behavior described above. + +#include <assert.h> +#include <string.h> + +#if defined(WIN32) +# include <windows.h> // for Sleep +#else +# include <unistd.h> // for usleep +#endif + +#include "pkcs11.h" + +CK_RV Test_C_Initialize(CK_VOID_PTR) { return CKR_OK; } + +CK_RV Test_C_Finalize(CK_VOID_PTR) { return CKR_OK; } + +static const CK_VERSION CryptokiVersion = {2, 2}; +static const CK_VERSION TestLibraryVersion = {0, 0}; +static const char TestLibraryDescription[] = "Test PKCS11 Library"; +static const char TestManufacturerID[] = "Test PKCS11 Manufacturer ID"; + +/* The dest buffer is one in the CK_INFO or CK_TOKEN_INFO structs. + * Those buffers are padded with spaces. DestSize corresponds to the declared + * size for those buffers (e.g. 32 for `char foo[32]`). + * The src buffer is a string literal. SrcSize includes the string + * termination character (e.g. 4 for `const char foo[] = "foo"` */ +template <size_t DestSize, size_t SrcSize> +void CopyString(unsigned char (&dest)[DestSize], const char (&src)[SrcSize]) { + static_assert(DestSize >= SrcSize - 1, "DestSize >= SrcSize - 1"); + memcpy(dest, src, SrcSize - 1); + memset(dest + SrcSize - 1, ' ', DestSize - SrcSize + 1); +} + +CK_RV Test_C_GetInfo(CK_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + pInfo->cryptokiVersion = CryptokiVersion; + CopyString(pInfo->manufacturerID, TestManufacturerID); + pInfo->flags = 0; // must be 0 + CopyString(pInfo->libraryDescription, TestLibraryDescription); + pInfo->libraryVersion = TestLibraryVersion; + return CKR_OK; +} + +CK_RV Test_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR) { return CKR_OK; } + +static int tokenPresent = 0; + +CK_RV Test_C_GetSlotList(CK_BBOOL limitToTokensPresent, + CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { + if (!pulCount) { + return CKR_ARGUMENTS_BAD; + } + + // We always return slot 2 + CK_ULONG slotCount = 1; + if (!limitToTokensPresent) { + // If we want empty slots, we also return slots 1 and 3 + slotCount += 2; + } else if (tokenPresent) { + // If we don't want empty slots, but token 1 is present, return that (but + // not slot 3) + slotCount++; + } + + if (pSlotList) { + if (*pulCount < slotCount) { + return CKR_BUFFER_TOO_SMALL; + } + // apparently CK_SLOT_IDs are integers [1,N] because + // who likes counting from 0 all the time? + switch (slotCount) { + case 1: + pSlotList[0] = 2; + break; + case 2: + if (tokenPresent) { + pSlotList[0] = 1; + pSlotList[1] = 2; + } else { + pSlotList[0] = 2; + pSlotList[1] = 3; + } + break; + case 3: + pSlotList[0] = 1; + pSlotList[1] = 2; + pSlotList[2] = 3; + break; + default: + assert("Unexpected slot count in Test_C_GetSlotList" == NULL); + return CKR_GENERAL_ERROR; + } + } + + *pulCount = slotCount; + return CKR_OK; +} + +static const char TestSlotDescription[] = "Test PKCS11 Slot"; +static const char TestSlot2Description[] = "Test PKCS11 Slot 二"; +static const char TestSlot3Description[] = "Empty PKCS11 Slot"; + +CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (slotID) { + case 1: + CopyString(pInfo->slotDescription, TestSlotDescription); + pInfo->flags = + (tokenPresent ? CKF_TOKEN_PRESENT : 0) | CKF_REMOVABLE_DEVICE; + break; + case 2: + CopyString(pInfo->slotDescription, TestSlot2Description); + pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE; + break; + case 3: + CopyString(pInfo->slotDescription, TestSlot3Description); + pInfo->flags = CKF_REMOVABLE_DEVICE; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + CopyString(pInfo->manufacturerID, TestManufacturerID); + pInfo->hardwareVersion = TestLibraryVersion; + pInfo->firmwareVersion = TestLibraryVersion; + return CKR_OK; +} + +// Deliberately include énye to ensure we're handling encoding correctly. +// The PKCS #11 base specification v2.20 specifies that strings be encoded +// as UTF-8. +static const char TestTokenLabel[] = "Test PKCS11 Tokeñ Label"; +static const char TestToken2Label[] = "Test PKCS11 Tokeñ 2 Label"; +static const char TestTokenModel[] = "Test Model"; + +CK_RV Test_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (slotID) { + case 1: + CopyString(pInfo->label, TestTokenLabel); + break; + case 2: + CopyString(pInfo->label, TestToken2Label); + break; + default: + return CKR_ARGUMENTS_BAD; + } + + CopyString(pInfo->manufacturerID, TestManufacturerID); + CopyString(pInfo->model, TestTokenModel); + memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber)); + pInfo->flags = CKF_TOKEN_INITIALIZED; + pInfo->ulMaxSessionCount = 1; + pInfo->ulSessionCount = 0; + pInfo->ulMaxRwSessionCount = 1; + pInfo->ulRwSessionCount = 0; + pInfo->ulMaxPinLen = 4; + pInfo->ulMinPinLen = 4; + pInfo->ulTotalPublicMemory = 1024; + pInfo->ulFreePublicMemory = 1024; + pInfo->ulTotalPrivateMemory = 1024; + pInfo->ulFreePrivateMemory = 1024; + pInfo->hardwareVersion = TestLibraryVersion; + pInfo->firmwareVersion = TestLibraryVersion; + memset(pInfo->utcTime, 0, sizeof(pInfo->utcTime)); + return CKR_OK; +} + +CK_RV Test_C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, + CK_ULONG_PTR pulCount) { + if (!pulCount) { + return CKR_ARGUMENTS_BAD; + } + + *pulCount = 0; + return CKR_OK; +} + +CK_RV Test_C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO_PTR) { + return CKR_OK; +} + +CK_RV Test_C_InitToken(CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR) { + return CKR_OK; +} + +CK_RV Test_C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, + CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, + CK_SESSION_HANDLE_PTR phSession) { + switch (slotID) { + case 1: + *phSession = 1; + break; + case 2: + *phSession = 2; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + return CKR_OK; +} + +CK_RV Test_C_CloseSession(CK_SESSION_HANDLE) { return CKR_OK; } + +CK_RV Test_C_CloseAllSessions(CK_SLOT_ID) { return CKR_OK; } + +CK_RV Test_C_GetSessionInfo(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (hSession) { + case 1: + pInfo->slotID = 1; + break; + case 2: + pInfo->slotID = 2; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + pInfo->state = CKS_RO_PUBLIC_SESSION; + pInfo->flags = CKF_SERIAL_SESSION; + return CKR_OK; +} + +CK_RV Test_C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Logout(CK_SESSION_HANDLE) { return CKR_FUNCTION_NOT_SUPPORTED; } + +CK_RV Test_C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_OK; +} + +CK_RV Test_C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG, + CK_ULONG_PTR pulObjectCount) { + *pulObjectCount = 0; + return CKR_OK; +} + +CK_RV Test_C_FindObjectsFinal(CK_SESSION_HANDLE) { return CKR_OK; } + +CK_RV Test_C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Encrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Decrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Digest(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Sign(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Verify(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetFunctionStatus(CK_SESSION_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_CancelFunction(CK_SESSION_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR) { +#ifdef WIN32 + Sleep(50); // Sleep takes the duration argument as milliseconds +#else + usleep(50000); // usleep takes the duration argument as microseconds +#endif + *pSlot = 1; + tokenPresent = !tokenPresent; + return CKR_OK; +} + +static CK_FUNCTION_LIST FunctionList = {{2, 2}, + Test_C_Initialize, + Test_C_Finalize, + Test_C_GetInfo, + Test_C_GetFunctionList, + Test_C_GetSlotList, + Test_C_GetSlotInfo, + Test_C_GetTokenInfo, + Test_C_GetMechanismList, + Test_C_GetMechanismInfo, + Test_C_InitToken, + Test_C_InitPIN, + Test_C_SetPIN, + Test_C_OpenSession, + Test_C_CloseSession, + Test_C_CloseAllSessions, + Test_C_GetSessionInfo, + Test_C_GetOperationState, + Test_C_SetOperationState, + Test_C_Login, + Test_C_Logout, + Test_C_CreateObject, + Test_C_CopyObject, + Test_C_DestroyObject, + Test_C_GetObjectSize, + Test_C_GetAttributeValue, + Test_C_SetAttributeValue, + Test_C_FindObjectsInit, + Test_C_FindObjects, + Test_C_FindObjectsFinal, + Test_C_EncryptInit, + Test_C_Encrypt, + Test_C_EncryptUpdate, + Test_C_EncryptFinal, + Test_C_DecryptInit, + Test_C_Decrypt, + Test_C_DecryptUpdate, + Test_C_DecryptFinal, + Test_C_DigestInit, + Test_C_Digest, + Test_C_DigestUpdate, + Test_C_DigestKey, + Test_C_DigestFinal, + Test_C_SignInit, + Test_C_Sign, + Test_C_SignUpdate, + Test_C_SignFinal, + Test_C_SignRecoverInit, + Test_C_SignRecover, + Test_C_VerifyInit, + Test_C_Verify, + Test_C_VerifyUpdate, + Test_C_VerifyFinal, + Test_C_VerifyRecoverInit, + Test_C_VerifyRecover, + Test_C_DigestEncryptUpdate, + Test_C_DecryptDigestUpdate, + Test_C_SignEncryptUpdate, + Test_C_DecryptVerifyUpdate, + Test_C_GenerateKey, + Test_C_GenerateKeyPair, + Test_C_WrapKey, + Test_C_UnwrapKey, + Test_C_DeriveKey, + Test_C_SeedRandom, + Test_C_GenerateRandom, + Test_C_GetFunctionStatus, + Test_C_CancelFunction, + Test_C_WaitForSlotEvent}; + +CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { + *ppFunctionList = &FunctionList; + return CKR_OK; +} diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols new file mode 100644 index 0000000000..562ecea21d --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols @@ -0,0 +1 @@ +C_GetFunctionList diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py new file mode 100755 index 0000000000..627f7b6ad1 --- /dev/null +++ b/security/manager/ssl/tests/unit/pycert.py @@ -0,0 +1,815 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a certificate specification from stdin or a file and outputs a +signed x509 certificate with the desired properties. + +The input format is as follows: + +issuer:<issuer distinguished name specification> +subject:<subject distinguished name specification> +[version:{1,2,3,4}] +[validity:<YYYYMMDD-YYYYMMDD|duration in days>] +[issuerKey:<key specification>] +[subjectKey:<key specification>] +[signature:{sha256WithRSAEncryption,sha1WithRSAEncryption, + md5WithRSAEncryption,ecdsaWithSHA256,ecdsaWithSHA384, + ecdsaWithSHA512}] +[serialNumber:<integer in the interval [1, 127]>] +[extension:<extension name:<extension-specific data>>] +[...] + +Known extensions are: +basicConstraints:[cA],[pathLenConstraint] +keyUsage:[digitalSignature,nonRepudiation,keyEncipherment, + dataEncipherment,keyAgreement,keyCertSign,cRLSign] +extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection + nsSGC, # Netscape Server Gated Crypto + OCSPSigning,timeStamping] +subjectAlternativeName:[<dNSName|directoryName|"ip4:"iPV4Address>,...] +authorityInformationAccess:<OCSP URI> +certificatePolicies:[<policy OID>,...] +nameConstraints:{permitted,excluded}:[<dNSName|directoryName>,...] +nsCertType:sslServer +TLSFeature:[<TLSFeature>,...] +embeddedSCTList:[<key specification>:<YYYYMMDD>,...] +delegationUsage: + +Where: + [] indicates an optional field or component of a field + <> indicates a required component of a field + {} indicates a choice of exactly one value among a set of values + [a,b,c] indicates a list of potential values, of which zero or more + may be used + +For instance, the version field is optional. However, if it is +specified, it must have exactly one value from the set {1,2,3,4}. + +Most fields have reasonable default values. By default one shared RSA +key is used for all signatures and subject public key information +fields. Using "issuerKey:<key specification>" or +"subjectKey:<key specification>" causes a different key be used for +signing or as the subject public key information field, respectively. +See pykey.py for the list of available specifications. +The signature algorithm is sha256WithRSAEncryption by default. + +The validity period may be specified as either concrete notBefore and +notAfter values or as a validity period centered around 'now'. For the +latter, this will result in a notBefore of 'now' - duration/2 and a +notAfter of 'now' + duration/2. + +Issuer and subject distinguished name specifications are of the form +'[stringEncoding]/C=XX/O=Example/CN=example.com'. C (country name), ST +(state or province name), L (locality name), O (organization name), OU +(organizational unit name), CN (common name) and emailAddress (email +address) are currently supported. The optional stringEncoding field may +be 'utf8String' or 'printableString'. If the given string does not +contain a '/', it is assumed to represent a common name. If an empty +string is provided, then an empty distinguished name is returned. +DirectoryNames also use this format. When specifying a directoryName in +a nameConstraints extension, the implicit form may not be used. + +If an extension name has '[critical]' after it, it will be marked as +critical. Otherwise (by default), it will not be marked as critical. + +TLSFeature values can either consist of a named value (currently only +'OCSPMustStaple' which corresponds to status_request) or a numeric TLS +feature value (see rfc7633 for more information). + +If a serial number is not explicitly specified, it is automatically +generated based on the contents of the certificate. +""" + +from pyasn1.codec.der import decoder +from pyasn1.codec.der import encoder +from pyasn1.type import constraint, tag, univ, useful +from pyasn1_modules import rfc2459 +from struct import pack +import base64 +import datetime +import hashlib +import re +import socket +import six +import sys + +import pyct +import pykey + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownBaseError(Error): + """Base class for handling unexpected input in this module.""" + + def __init__(self, value): + super(UnknownBaseError, self).__init__() + self.value = value + self.category = "input" + + def __str__(self): + return 'Unknown %s type "%s"' % (self.category, repr(self.value)) + + +class UnknownAlgorithmTypeError(UnknownBaseError): + """Helper exception type to handle unknown algorithm types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "algorithm" + + +class UnknownParameterTypeError(UnknownBaseError): + """Helper exception type to handle unknown input parameters.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "parameter" + + +class UnknownExtensionTypeError(UnknownBaseError): + """Helper exception type to handle unknown input extensions.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "extension" + + +class UnknownKeyPurposeTypeError(UnknownBaseError): + """Helper exception type to handle unknown key purposes.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "keyPurpose" + + +class UnknownKeyTargetError(UnknownBaseError): + """Helper exception type to handle unknown key targets.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "key target" + + +class UnknownVersionError(UnknownBaseError): + """Helper exception type to handle unknown specified versions.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "version" + + +class UnknownNameConstraintsSpecificationError(UnknownBaseError): + """Helper exception type to handle unknown specified + nameConstraints.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "nameConstraints specification" + + +class UnknownDNTypeError(UnknownBaseError): + """Helper exception type to handle unknown DN types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "DN" + + +class UnknownNSCertTypeError(UnknownBaseError): + """Helper exception type to handle unknown nsCertType types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "nsCertType" + + +class UnknownTLSFeature(UnknownBaseError): + """Helper exception type to handle unknown TLS Features.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "TLSFeature" + + +class UnknownDelegatedCredentialError(UnknownBaseError): + """Helper exception type to handle unknown Delegated Credential args.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "delegatedCredential" + + +class InvalidSCTSpecification(Error): + """Helper exception type to handle invalid SCT specifications.""" + + def __init__(self, value): + super(InvalidSCTSpecification, self).__init__() + self.value = value + + def __str__(self): + return repr('invalid SCT specification "{}"' % self.value) + + +class InvalidSerialNumber(Error): + """Exception type to handle invalid serial numbers.""" + + def __init__(self, value): + super(InvalidSerialNumber, self).__init__() + self.value = value + + def __str__(self): + return repr(self.value) + + +def getASN1Tag(asn1Type): + """Helper function for returning the base tag value of a given + type from the pyasn1 package""" + return asn1Type.tagSet.baseTag.tagId + + +def stringToAccessDescription(string): + """Helper function that takes a string representing a URI + presumably identifying an OCSP authority information access + location. Returns an AccessDescription usable by pyasn1.""" + accessMethod = rfc2459.id_ad_ocsp + accessLocation = rfc2459.GeneralName() + accessLocation["uniformResourceIdentifier"] = string + sequence = univ.Sequence() + sequence.setComponentByPosition(0, accessMethod) + sequence.setComponentByPosition(1, accessLocation) + return sequence + + +def stringToDN(string, tag=None): + """Takes a string representing a distinguished name or directory + name and returns a Name for use by pyasn1. See the documentation + for the issuer and subject fields for more details. Takes an + optional implicit tag in cases where the Name needs to be tagged + differently.""" + if string and "/" not in string: + string = "/CN=%s" % string + rdns = rfc2459.RDNSequence() + pattern = "/(C|ST|L|O|OU|CN|emailAddress)=" + split = re.split(pattern, string) + # split should now be [[encoding], <type>, <value>, <type>, <value>, ...] + if split[0]: + encoding = split[0] + else: + encoding = "utf8String" + for pos, (nameType, value) in enumerate(zip(split[1::2], split[2::2])): + ava = rfc2459.AttributeTypeAndValue() + if nameType == "C": + ava["type"] = rfc2459.id_at_countryName + nameComponent = rfc2459.X520countryName(value) + elif nameType == "ST": + ava["type"] = rfc2459.id_at_stateOrProvinceName + nameComponent = rfc2459.X520StateOrProvinceName() + elif nameType == "L": + ava["type"] = rfc2459.id_at_localityName + nameComponent = rfc2459.X520LocalityName() + elif nameType == "O": + ava["type"] = rfc2459.id_at_organizationName + nameComponent = rfc2459.X520OrganizationName() + elif nameType == "OU": + ava["type"] = rfc2459.id_at_organizationalUnitName + nameComponent = rfc2459.X520OrganizationalUnitName() + elif nameType == "CN": + ava["type"] = rfc2459.id_at_commonName + nameComponent = rfc2459.X520CommonName() + elif nameType == "emailAddress": + ava["type"] = rfc2459.emailAddress + nameComponent = rfc2459.Pkcs9email(value) + else: + raise UnknownDNTypeError(nameType) + if not nameType == "C" and not nameType == "emailAddress": + # The value may have things like '\0' (i.e. a slash followed by + # the number zero) that have to be decoded into the resulting + # '\x00' (i.e. a byte with value zero). + nameComponent[encoding] = six.ensure_binary(value).decode( + encoding="unicode_escape" + ) + ava["value"] = nameComponent + rdn = rfc2459.RelativeDistinguishedName() + rdn.setComponentByPosition(0, ava) + rdns.setComponentByPosition(pos, rdn) + if tag: + name = rfc2459.Name().subtype(implicitTag=tag) + else: + name = rfc2459.Name() + name.setComponentByPosition(0, rdns) + return name + + +def stringToAlgorithmIdentifiers(string): + """Helper function that converts a description of an algorithm + to a representation usable by the pyasn1 package and a hash + algorithm constant for use by pykey.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmType = None + algorithm = None + # We add Null parameters for RSA only + addParameters = False + if string == "sha1WithRSAEncryption": + algorithmType = pykey.HASH_SHA1 + algorithm = rfc2459.sha1WithRSAEncryption + addParameters = True + elif string == "sha256WithRSAEncryption": + algorithmType = pykey.HASH_SHA256 + algorithm = univ.ObjectIdentifier("1.2.840.113549.1.1.11") + addParameters = True + elif string == "md5WithRSAEncryption": + algorithmType = pykey.HASH_MD5 + algorithm = rfc2459.md5WithRSAEncryption + addParameters = True + elif string == "ecdsaWithSHA256": + algorithmType = pykey.HASH_SHA256 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.2") + elif string == "ecdsaWithSHA384": + algorithmType = pykey.HASH_SHA384 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.3") + elif string == "ecdsaWithSHA512": + algorithmType = pykey.HASH_SHA512 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.4") + else: + raise UnknownAlgorithmTypeError(string) + algorithmIdentifier["algorithm"] = algorithm + if addParameters: + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + return (algorithmIdentifier, algorithmType) + + +def datetimeToTime(dt): + """Takes a datetime object and returns an rfc2459.Time object with + that time as its value as a GeneralizedTime""" + time = rfc2459.Time() + time["generalTime"] = useful.GeneralizedTime(dt.strftime("%Y%m%d%H%M%SZ")) + return time + + +def serialBytesToString(serialBytes): + """Takes a list of integers in the interval [0, 255] and returns + the corresponding serial number string.""" + serialBytesLen = len(serialBytes) + if serialBytesLen > 127: + raise InvalidSerialNumber("{} bytes is too long".format(serialBytesLen)) + # Prepend the ASN.1 INTEGER tag and length bytes. + stringBytes = [getASN1Tag(univ.Integer), serialBytesLen] + serialBytes + return bytes(stringBytes) + + +class Certificate(object): + """Utility class for reading a certificate specification and + generating a signed x509 certificate""" + + def __init__(self, paramStream): + self.versionValue = 2 # a value of 2 is X509v3 + self.signature = "sha256WithRSAEncryption" + self.issuer = "Default Issuer" + actualNow = datetime.datetime.utcnow() + self.now = datetime.datetime.strptime(str(actualNow.year), "%Y") + aYearAndAWhile = datetime.timedelta(days=400) + self.notBefore = self.now - aYearAndAWhile + self.notAfter = self.now + aYearAndAWhile + self.subject = "Default Subject" + self.extensions = None + # The serial number can be automatically generated from the + # certificate specification. We need this value to depend in + # part of what extensions are present. self.extensions are + # pyasn1 objects. Depending on the string representation of + # these objects can cause the resulting serial number to change + # unexpectedly, so instead we depend on the original string + # representation of the extensions as specified. + self.extensionLines = None + self.savedEmbeddedSCTListData = None + self.subjectKey = pykey.keyFromSpecification("default") + self.issuerKey = pykey.keyFromSpecification("default") + self.serialNumber = None + self.decodeParams(paramStream) + # If a serial number wasn't specified, generate one based on + # the certificate contents. + if not self.serialNumber: + self.serialNumber = self.generateSerialNumber() + # This has to be last because the SCT signature depends on the + # contents of the certificate. + if self.savedEmbeddedSCTListData: + self.addEmbeddedSCTListData() + + def generateSerialNumber(self): + """Generates a serial number for this certificate based on its + contents. Intended to be reproducible for compatibility with + the build system on OS X (see the comment above main, later in + this file).""" + hasher = hashlib.sha256() + hasher.update(six.ensure_binary(str(self.versionValue))) + hasher.update(six.ensure_binary(self.signature)) + hasher.update(six.ensure_binary(self.issuer)) + hasher.update(six.ensure_binary(str(self.notBefore))) + hasher.update(six.ensure_binary(str(self.notAfter))) + hasher.update(six.ensure_binary(self.subject)) + if self.extensionLines: + for extensionLine in self.extensionLines: + hasher.update(six.ensure_binary(extensionLine)) + if self.savedEmbeddedSCTListData: + # savedEmbeddedSCTListData is + # (embeddedSCTListSpecification, critical), where |critical| + # may be None + hasher.update(six.ensure_binary(self.savedEmbeddedSCTListData[0])) + if self.savedEmbeddedSCTListData[1]: + hasher.update(six.ensure_binary(self.savedEmbeddedSCTListData[1])) + serialBytes = [c for c in hasher.digest()[:20]] + # Ensure that the most significant bit isn't set (which would + # indicate a negative number, which isn't valid for serial + # numbers). + serialBytes[0] &= 0x7F + # Also ensure that the least significant bit on the most + # significant byte is set (to prevent a leading zero byte, + # which also wouldn't be valid). + serialBytes[0] |= 0x01 + return serialBytesToString(serialBytes) + + def decodeParams(self, paramStream): + for line in paramStream.readlines(): + self.decodeParam(line.strip()) + + def decodeParam(self, line): + param = line.split(":")[0] + value = ":".join(line.split(":")[1:]) + if param == "version": + self.setVersion(value) + elif param == "subject": + self.subject = value + elif param == "issuer": + self.issuer = value + elif param == "validity": + self.decodeValidity(value) + elif param == "extension": + self.decodeExtension(value) + elif param == "issuerKey": + self.setupKey("issuer", value) + elif param == "subjectKey": + self.setupKey("subject", value) + elif param == "signature": + self.signature = value + elif param == "serialNumber": + serialNumber = int(value) + # Ensure only serial numbers that conform to the rules listed in + # generateSerialNumber() are permitted. + if serialNumber < 1 or serialNumber > 127: + raise InvalidSerialNumber(value) + self.serialNumber = serialBytesToString([serialNumber]) + else: + raise UnknownParameterTypeError(param) + + def setVersion(self, version): + intVersion = int(version) + if intVersion >= 1 and intVersion <= 4: + self.versionValue = intVersion - 1 + else: + raise UnknownVersionError(version) + + def decodeValidity(self, duration): + match = re.search("([0-9]{8})-([0-9]{8})", duration) + if match: + self.notBefore = datetime.datetime.strptime(match.group(1), "%Y%m%d") + self.notAfter = datetime.datetime.strptime(match.group(2), "%Y%m%d") + else: + delta = datetime.timedelta(days=(int(duration) / 2)) + self.notBefore = self.now - delta + self.notAfter = self.now + delta + + def decodeExtension(self, extension): + match = re.search(r"([a-zA-Z]+)(\[critical\])?:(.*)", extension) + if not match: + raise UnknownExtensionTypeError(extension) + extensionType = match.group(1) + critical = match.group(2) + value = match.group(3) + if extensionType == "basicConstraints": + self.addBasicConstraints(value, critical) + elif extensionType == "keyUsage": + self.addKeyUsage(value, critical) + elif extensionType == "extKeyUsage": + self.addExtKeyUsage(value, critical) + elif extensionType == "subjectAlternativeName": + self.addSubjectAlternativeName(value, critical) + elif extensionType == "authorityInformationAccess": + self.addAuthorityInformationAccess(value, critical) + elif extensionType == "certificatePolicies": + self.addCertificatePolicies(value, critical) + elif extensionType == "nameConstraints": + self.addNameConstraints(value, critical) + elif extensionType == "nsCertType": + self.addNSCertType(value, critical) + elif extensionType == "TLSFeature": + self.addTLSFeature(value, critical) + elif extensionType == "embeddedSCTList": + self.savedEmbeddedSCTListData = (value, critical) + elif extensionType == "delegationUsage": + self.addDelegationUsage(critical) + else: + raise UnknownExtensionTypeError(extensionType) + + if extensionType != "embeddedSCTList": + if not self.extensionLines: + self.extensionLines = [] + self.extensionLines.append(extension) + + def setupKey(self, subjectOrIssuer, value): + if subjectOrIssuer == "subject": + self.subjectKey = pykey.keyFromSpecification(value) + elif subjectOrIssuer == "issuer": + self.issuerKey = pykey.keyFromSpecification(value) + else: + raise UnknownKeyTargetError(subjectOrIssuer) + + def addExtension(self, extensionType, extensionValue, critical): + if not self.extensions: + self.extensions = [] + encapsulated = univ.OctetString(encoder.encode(extensionValue)) + extension = rfc2459.Extension() + extension["extnID"] = extensionType + # critical is either the string '[critical]' or None. + # We only care whether or not it is truthy. + if critical: + extension["critical"] = True + extension["extnValue"] = encapsulated + self.extensions.append(extension) + + def addBasicConstraints(self, basicConstraints, critical): + cA = basicConstraints.split(",")[0] + pathLenConstraint = basicConstraints.split(",")[1] + basicConstraintsExtension = rfc2459.BasicConstraints() + basicConstraintsExtension["cA"] = cA == "cA" + if pathLenConstraint: + pathLenConstraintValue = univ.Integer(int(pathLenConstraint)).subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, float("inf")) + ) + basicConstraintsExtension["pathLenConstraint"] = pathLenConstraintValue + self.addExtension( + rfc2459.id_ce_basicConstraints, basicConstraintsExtension, critical + ) + + def addKeyUsage(self, keyUsage, critical): + keyUsageExtension = rfc2459.KeyUsage(keyUsage) + self.addExtension(rfc2459.id_ce_keyUsage, keyUsageExtension, critical) + + def keyPurposeToOID(self, keyPurpose): + if keyPurpose == "serverAuth": + return rfc2459.id_kp_serverAuth + if keyPurpose == "clientAuth": + return rfc2459.id_kp_clientAuth + if keyPurpose == "codeSigning": + return rfc2459.id_kp_codeSigning + if keyPurpose == "emailProtection": + return rfc2459.id_kp_emailProtection + if keyPurpose == "nsSGC": + return univ.ObjectIdentifier("2.16.840.1.113730.4.1") + if keyPurpose == "OCSPSigning": + return univ.ObjectIdentifier("1.3.6.1.5.5.7.3.9") + if keyPurpose == "timeStamping": + return rfc2459.id_kp_timeStamping + raise UnknownKeyPurposeTypeError(keyPurpose) + + def addExtKeyUsage(self, extKeyUsage, critical): + extKeyUsageExtension = rfc2459.ExtKeyUsageSyntax() + for count, keyPurpose in enumerate(extKeyUsage.split(",")): + extKeyUsageExtension.setComponentByPosition( + count, self.keyPurposeToOID(keyPurpose) + ) + self.addExtension(rfc2459.id_ce_extKeyUsage, extKeyUsageExtension, critical) + + def addSubjectAlternativeName(self, names, critical): + IPV4_PREFIX = "ip4:" + + subjectAlternativeName = rfc2459.SubjectAltName() + for count, name in enumerate(names.split(",")): + generalName = rfc2459.GeneralName() + if "/" in name: + directoryName = stringToDN( + name, tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + generalName["directoryName"] = directoryName + elif "@" in name: + generalName["rfc822Name"] = name + elif name.startswith(IPV4_PREFIX): + generalName["iPAddress"] = socket.inet_pton( + socket.AF_INET, name[len(IPV4_PREFIX) :] + ) + else: + # The string may have things like '\0' (i.e. a slash + # followed by the number zero) that have to be decoded into + # the resulting '\x00' (i.e. a byte with value zero). + generalName["dNSName"] = six.ensure_binary(name).decode( + "unicode_escape" + ) + subjectAlternativeName.setComponentByPosition(count, generalName) + self.addExtension( + rfc2459.id_ce_subjectAltName, subjectAlternativeName, critical + ) + + def addAuthorityInformationAccess(self, ocspURI, critical): + sequence = univ.Sequence() + accessDescription = stringToAccessDescription(ocspURI) + sequence.setComponentByPosition(0, accessDescription) + self.addExtension(rfc2459.id_pe_authorityInfoAccess, sequence, critical) + + def addCertificatePolicies(self, policyOIDs, critical): + policies = rfc2459.CertificatePolicies() + for pos, policyOID in enumerate(policyOIDs.split(",")): + if policyOID == "any": + policyOID = "2.5.29.32.0" + policy = rfc2459.PolicyInformation() + policyIdentifier = rfc2459.CertPolicyId(policyOID) + policy["policyIdentifier"] = policyIdentifier + policies.setComponentByPosition(pos, policy) + self.addExtension(rfc2459.id_ce_certificatePolicies, policies, critical) + + def addNameConstraints(self, constraints, critical): + nameConstraints = rfc2459.NameConstraints() + if constraints.startswith("permitted:"): + (subtreesType, subtreesTag) = ("permittedSubtrees", 0) + elif constraints.startswith("excluded:"): + (subtreesType, subtreesTag) = ("excludedSubtrees", 1) + else: + raise UnknownNameConstraintsSpecificationError(constraints) + generalSubtrees = rfc2459.GeneralSubtrees().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatConstructed, subtreesTag + ) + ) + subtrees = constraints[(constraints.find(":") + 1) :] + for pos, name in enumerate(subtrees.split(",")): + generalName = rfc2459.GeneralName() + if "/" in name: + directoryName = stringToDN( + name, tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + generalName["directoryName"] = directoryName + else: + generalName["dNSName"] = name + generalSubtree = rfc2459.GeneralSubtree() + generalSubtree["base"] = generalName + generalSubtrees.setComponentByPosition(pos, generalSubtree) + nameConstraints[subtreesType] = generalSubtrees + self.addExtension(rfc2459.id_ce_nameConstraints, nameConstraints, critical) + + def addNSCertType(self, certType, critical): + if certType != "sslServer": + raise UnknownNSCertTypeError(certType) + self.addExtension( + univ.ObjectIdentifier("2.16.840.1.113730.1.1"), + univ.BitString("'01'B"), + critical, + ) + + def addDelegationUsage(self, critical): + if critical: + raise UnknownDelegatedCredentialError(critical) + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.4.1.44363.44"), univ.Null(), critical + ) + + def addTLSFeature(self, features, critical): + namedFeatures = {"OCSPMustStaple": 5} + featureList = [f.strip() for f in features.split(",")] + sequence = univ.Sequence() + for pos, feature in enumerate(featureList): + featureValue = 0 + try: + featureValue = int(feature) + except ValueError: + try: + featureValue = namedFeatures[feature] + except Exception: + raise UnknownTLSFeature(feature) + sequence.setComponentByPosition(pos, univ.Integer(featureValue)) + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.5.5.7.1.24"), sequence, critical + ) + + def addEmbeddedSCTListData(self): + (scts, critical) = self.savedEmbeddedSCTListData + encodedSCTs = [] + for sctSpec in scts.split(","): + match = re.search("(\w+):(\d{8})", sctSpec) + if not match: + raise InvalidSCTSpecification(sctSpec) + keySpec = match.group(1) + key = pykey.keyFromSpecification(keySpec) + time = datetime.datetime.strptime(match.group(2), "%Y%m%d") + tbsCertificate = self.getTBSCertificate() + tbsDER = encoder.encode(tbsCertificate) + sct = pyct.SCT(key, time, tbsDER, self.issuerKey) + signed = sct.signAndEncode() + lengthPrefix = pack("!H", len(signed)) + encodedSCTs.append(lengthPrefix + signed) + encodedSCTBytes = b"".join(encodedSCTs) + lengthPrefix = pack("!H", len(encodedSCTBytes)) + extensionBytes = lengthPrefix + encodedSCTBytes + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.4.1.11129.2.4.2"), + univ.OctetString(extensionBytes), + critical, + ) + + def getVersion(self): + return rfc2459.Version(self.versionValue).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0) + ) + + def getSerialNumber(self): + return decoder.decode(self.serialNumber)[0] + + def getIssuer(self): + return stringToDN(self.issuer) + + def getValidity(self): + validity = rfc2459.Validity() + validity["notBefore"] = self.getNotBefore() + validity["notAfter"] = self.getNotAfter() + return validity + + def getNotBefore(self): + return datetimeToTime(self.notBefore) + + def getNotAfter(self): + return datetimeToTime(self.notAfter) + + def getSubject(self): + return stringToDN(self.subject) + + def getTBSCertificate(self): + (signatureOID, _) = stringToAlgorithmIdentifiers(self.signature) + tbsCertificate = rfc2459.TBSCertificate() + tbsCertificate["version"] = self.getVersion() + tbsCertificate["serialNumber"] = self.getSerialNumber() + tbsCertificate["signature"] = signatureOID + tbsCertificate["issuer"] = self.getIssuer() + tbsCertificate["validity"] = self.getValidity() + tbsCertificate["subject"] = self.getSubject() + tbsCertificate[ + "subjectPublicKeyInfo" + ] = self.subjectKey.asSubjectPublicKeyInfo() + if self.extensions: + extensions = rfc2459.Extensions().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3) + ) + for count, extension in enumerate(self.extensions): + extensions.setComponentByPosition(count, extension) + tbsCertificate["extensions"] = extensions + return tbsCertificate + + def toDER(self): + (signatureOID, hashAlgorithm) = stringToAlgorithmIdentifiers(self.signature) + certificate = rfc2459.Certificate() + tbsCertificate = self.getTBSCertificate() + certificate["tbsCertificate"] = tbsCertificate + certificate["signatureAlgorithm"] = signatureOID + tbsDER = encoder.encode(tbsCertificate) + certificate["signatureValue"] = self.issuerKey.sign(tbsDER, hashAlgorithm) + return encoder.encode(certificate) + + def toPEM(self): + output = "-----BEGIN CERTIFICATE-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END CERTIFICATE-----" + return output + + +# The build harness will call this function with an output +# file-like object and a path to a file containing a +# specification. This will read the specification and output +# the certificate as PEM. +# This utility tries as hard as possible to ensure that two +# runs with the same input will have the same output. This is +# particularly important when building on OS X, where we +# generate everything twice for unified builds. During the +# unification step, if any pair of input files differ, the build +# system throws an error. +# The one concrete failure mode is if one run happens before +# midnight on New Year's Eve and the next run happens after +# midnight. +def main(output, inputPath): + with open(inputPath) as configStream: + output.write(Certificate(configStream).toPEM() + "\n") + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(Certificate(sys.stdin).toPEM()) diff --git a/security/manager/ssl/tests/unit/pycms.py b/security/manager/ssl/tests/unit/pycms.py new file mode 100755 index 0000000000..befe68e346 --- /dev/null +++ b/security/manager/ssl/tests/unit/pycms.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a specification from stdin and outputs a PKCS7 (CMS) message with +the desired properties. + +The specification format is as follows: + +sha1:<hex string> +sha256:<hex string> +signer: +<pycert specification> + +Eith or both of sha1 and sha256 may be specified. The value of +each hash directive is what will be put in the messageDigest +attribute of the SignerInfo that corresponds to the signature +algorithm defined by the hash algorithm and key type of the +default key. Together, these comprise the signerInfos field of +the SignedData. If neither hash is specified, the signerInfos +will be an empty SET (i.e. there will be no actual signature +information). +The certificate specification must come last. +""" + +from pyasn1.codec.der import decoder +from pyasn1.codec.der import encoder +from pyasn1.type import tag, univ +from pyasn1_modules import rfc2315, rfc2459 +import base64 +from io import StringIO +import pycert +import pykey +import sys + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownDirectiveError(Error): + """Helper exception type to handle unknown specification + directives.""" + + def __init__(self, directive): + super(UnknownDirectiveError, self).__init__() + self.directive = directive + + def __str__(self): + return "Unknown directive %s" % repr(self.directive) + + +class CMS(object): + """Utility class for reading a CMS specification and + generating a CMS message""" + + def __init__(self, paramStream): + self.sha1 = "" + self.sha256 = "" + signerSpecification = StringIO() + readingSignerSpecification = False + for line in paramStream.readlines(): + if readingSignerSpecification: + print(line.strip(), file=signerSpecification) + elif line.strip() == "signer:": + readingSignerSpecification = True + elif line.startswith("sha1:"): + self.sha1 = line.strip()[len("sha1:") :] + elif line.startswith("sha256:"): + self.sha256 = line.strip()[len("sha256:") :] + else: + raise UnknownDirectiveError(line.strip()) + signerSpecification.seek(0) + self.signer = pycert.Certificate(signerSpecification) + self.signingKey = pykey.keyFromSpecification("default") + + def buildAuthenticatedAttributes(self, value, implicitTag=None): + """Utility function to build a pyasn1 AuthenticatedAttributes + object. Useful because when building a SignerInfo, the + authenticatedAttributes needs to be tagged implicitly, but when + signing an AuthenticatedAttributes, it needs the explicit SET + tag.""" + if implicitTag: + authenticatedAttributes = rfc2315.Attributes().subtype( + implicitTag=implicitTag + ) + else: + authenticatedAttributes = rfc2315.Attributes() + contentTypeAttribute = rfc2315.Attribute() + # PKCS#9 contentType + contentTypeAttribute["type"] = univ.ObjectIdentifier("1.2.840.113549.1.9.3") + contentTypeAttribute["values"] = univ.SetOf(rfc2459.AttributeValue()) + # PKCS#7 data + contentTypeAttribute["values"][0] = univ.ObjectIdentifier( + "1.2.840.113549.1.7.1" + ) + authenticatedAttributes[0] = contentTypeAttribute + hashAttribute = rfc2315.Attribute() + # PKCS#9 messageDigest + hashAttribute["type"] = univ.ObjectIdentifier("1.2.840.113549.1.9.4") + hashAttribute["values"] = univ.SetOf(rfc2459.AttributeValue()) + hashAttribute["values"][0] = univ.OctetString(hexValue=value) + authenticatedAttributes[1] = hashAttribute + return authenticatedAttributes + + def pykeyHashToDigestAlgorithm(self, pykeyHash): + """Given a pykey hash algorithm identifier, builds an + AlgorithmIdentifier for use with pyasn1.""" + if pykeyHash == pykey.HASH_SHA1: + oidString = "1.3.14.3.2.26" + elif pykeyHash == pykey.HASH_SHA256: + oidString = "2.16.840.1.101.3.4.2.1" + else: + raise pykey.UnknownHashAlgorithmError(pykeyHash) + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = univ.ObjectIdentifier(oidString) + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + return algorithmIdentifier + + def buildSignerInfo(self, certificate, pykeyHash, digestValue): + """Given a pyasn1 certificate, a pykey hash identifier + and a hash value, creates a SignerInfo with the + appropriate values.""" + signerInfo = rfc2315.SignerInfo() + signerInfo["version"] = 1 + issuerAndSerialNumber = rfc2315.IssuerAndSerialNumber() + issuerAndSerialNumber["issuer"] = self.signer.getIssuer() + issuerAndSerialNumber["serialNumber"] = certificate["tbsCertificate"][ + "serialNumber" + ] + signerInfo["issuerAndSerialNumber"] = issuerAndSerialNumber + signerInfo["digestAlgorithm"] = self.pykeyHashToDigestAlgorithm(pykeyHash) + rsa = rfc2459.AlgorithmIdentifier() + rsa["algorithm"] = rfc2459.rsaEncryption + rsa["parameters"] = univ.Null() + authenticatedAttributes = self.buildAuthenticatedAttributes( + digestValue, + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), + ) + authenticatedAttributesTBS = self.buildAuthenticatedAttributes(digestValue) + signerInfo["authenticatedAttributes"] = authenticatedAttributes + signerInfo["digestEncryptionAlgorithm"] = rsa + authenticatedAttributesEncoded = encoder.encode(authenticatedAttributesTBS) + signature = self.signingKey.sign(authenticatedAttributesEncoded, pykeyHash) + # signature will be a hexified bit string of the form + # "'<hex bytes>'H". For some reason that's what BitString wants, + # but since this is an OCTET STRING, we have to strip off the + # quotation marks and trailing "H". + signerInfo["encryptedDigest"] = univ.OctetString(hexValue=signature[1:-2]) + return signerInfo + + def toDER(self): + contentInfo = rfc2315.ContentInfo() + contentInfo["contentType"] = rfc2315.signedData + + signedData = rfc2315.SignedData() + signedData["version"] = rfc2315.Version(1) + + digestAlgorithms = rfc2315.DigestAlgorithmIdentifiers() + digestAlgorithms[0] = self.pykeyHashToDigestAlgorithm(pykey.HASH_SHA1) + signedData["digestAlgorithms"] = digestAlgorithms + + dataContentInfo = rfc2315.ContentInfo() + dataContentInfo["contentType"] = rfc2315.data + signedData["contentInfo"] = dataContentInfo + + certificates = rfc2315.ExtendedCertificatesAndCertificates().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0) + ) + extendedCertificateOrCertificate = rfc2315.ExtendedCertificateOrCertificate() + certificate = decoder.decode( + self.signer.toDER(), asn1Spec=rfc2459.Certificate() + )[0] + extendedCertificateOrCertificate["certificate"] = certificate + certificates[0] = extendedCertificateOrCertificate + signedData["certificates"] = certificates + + signerInfos = rfc2315.SignerInfos() + + if len(self.sha1) > 0: + signerInfos[len(signerInfos)] = self.buildSignerInfo( + certificate, pykey.HASH_SHA1, self.sha1 + ) + if len(self.sha256) > 0: + signerInfos[len(signerInfos)] = self.buildSignerInfo( + certificate, pykey.HASH_SHA256, self.sha256 + ) + signedData["signerInfos"] = signerInfos + + encoded = encoder.encode(signedData) + anyTag = univ.Any(encoded).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0) + ) + + contentInfo["content"] = anyTag + return encoder.encode(contentInfo) + + def toPEM(self): + output = "-----BEGIN PKCS7-----" + der = self.toDER() + b64 = base64.b64encode(der) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END PKCS7-----\n" + return output + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(CMS(sys.stdin).toPEM()) diff --git a/security/manager/ssl/tests/unit/pyct.py b/security/manager/ssl/tests/unit/pyct.py new file mode 100644 index 0000000000..125b626fc2 --- /dev/null +++ b/security/manager/ssl/tests/unit/pyct.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Helper library for creating a Signed Certificate Timestamp given the +details of a signing key, when to sign, and the certificate data to +sign. Currently only supports precert_entry types. See RFC 6962. +""" + +from pyasn1.codec.der import encoder +from struct import pack +import binascii +import calendar +import hashlib + +import pykey + + +class InvalidKeyError(Exception): + """Helper exception to handle unknown key types.""" + + def __init__(self, key): + self.key = key + + def __str__(self): + return 'Invalid key: "%s"' % str(self.key) + + +class SCT(object): + """SCT represents a Signed Certificate Timestamp.""" + + def __init__(self, key, date, tbsCertificate, issuerKey): + self.key = key + self.timestamp = calendar.timegm(date.timetuple()) * 1000 + self.tbsCertificate = tbsCertificate + self.issuerKey = issuerKey + + def signAndEncode(self): + """Returns a signed and encoded representation of the SCT as a + string.""" + # The signature is over the following data: + # sct_version (one 0 byte) + # signature_type (one 0 byte) + # timestamp (8 bytes, milliseconds since the epoch) + # entry_type (two bytes [0, 1] - currently only precert_entry is + # supported) + # signed_entry (bytes of PreCert) + # extensions (2-byte-length-prefixed, currently empty (so two 0 + # bytes)) + # A PreCert is: + # issuer_key_hash (32 bytes of SHA-256 hash of the issuing + # public key, as DER-encoded SPKI) + # tbs_certificate (3-byte-length-prefixed data) + timestamp = pack("!Q", self.timestamp) + hasher = hashlib.sha256() + hasher.update(encoder.encode(self.issuerKey.asSubjectPublicKeyInfo())) + issuer_key_hash = hasher.digest() + len_prefix = pack("!L", len(self.tbsCertificate))[1:] + data = ( + b"\0\0" + + timestamp + + b"\0\1" + + issuer_key_hash + + len_prefix + + self.tbsCertificate + + b"\0\0" + ) + if isinstance(self.key, pykey.ECCKey): + signatureByte = b"\3" + elif isinstance(self.key, pykey.RSAKey): + signatureByte = b"\1" + else: + raise InvalidKeyError(self.key) + # sign returns a hex string like "'<hex bytes>'H", but we want + # bytes here + hexSignature = self.key.sign(data, pykey.HASH_SHA256) + signature = binascii.unhexlify(hexSignature[1:-2]) + # The actual data returned is the following: + # sct_version (one 0 byte) + # id (32 bytes of SHA-256 hash of the signing key, as + # DER-encoded SPKI) + # timestamp (8 bytes, milliseconds since the epoch) + # extensions (2-byte-length-prefixed data, currently + # empty) + # hash (one 4 byte representing sha256) + # signature (one byte - 1 for RSA and 3 for ECDSA) + # signature (2-byte-length-prefixed data) + hasher = hashlib.sha256() + hasher.update(encoder.encode(self.key.asSubjectPublicKeyInfo())) + key_id = hasher.digest() + signature_len_prefix = pack("!H", len(signature)) + return ( + b"\0" + + key_id + + timestamp + + b"\0\0\4" + + signatureByte + + signature_len_prefix + + signature + ) diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py new file mode 100755 index 0000000000..05163adc36 --- /dev/null +++ b/security/manager/ssl/tests/unit/pykey.py @@ -0,0 +1,958 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a key specification from stdin or a file and outputs a +PKCS #8 file representing the (private) key. Also provides +methods for signing data and representing the key as a subject +public key info for use with pyasn1. + +The key specification format is as follows: + +default: a 2048-bit RSA key +alternate: a different 2048-bit RSA key +ev: a 2048-bit RSA key that, when combined with the right pycert + specification, results in a certificate that is enabled for + extended validation in debug Firefox (see ExtendedValidation.cpp). +evRSA2040: a 2040-bit RSA key that, when combined with the right pycert + specification, results in a certificate that is enabled for + extended validation in debug Firefox. +rsa2040: a 2040-bit RSA key +rsa1024: a 1024-bit RSA key +rsa1016: a 1016-bit RSA key +secp256k1: an ECC key on the curve secp256k1 +secp244r1: an ECC key on the curve secp244r1 +secp256r1: an ECC key on the curve secp256r1 +secp384r1: an ECC key on the curve secp384r1 +secp521r1: an ECC key on the curve secp521r1 +""" + +from pyasn1.codec.der import encoder +from pyasn1.type import univ, namedtype, tag +from pyasn1_modules import rfc2459 +import base64 +import binascii +import ecdsa +import hashlib +import math +import rsa +import six +import sys + +# "constants" to make it easier for consumers to specify hash algorithms +HASH_MD5 = "hash:md5" +HASH_SHA1 = "hash:sha1" +HASH_SHA256 = "hash:sha256" +HASH_SHA384 = "hash:sha384" +HASH_SHA512 = "hash:sha512" + + +# NOTE: With bug 1621441 we migrated from one library for ecdsa to another. +# These libraries differ somewhat in terms of functionality and interface. In +# order to ensure there are no diffs and that the generated signatures are +# exactly the same between the two libraries, we need to patch some stuff in. + + +def _gen_k(curve): + # This calculation is arbitrary, but it matches what we were doing pre- + # bug 1621441 (see the above NOTE). Crucially, this generation of k is + # non-random; the ecdsa library exposes an option to deterministically + # generate a value of k for us, but it doesn't match up to what we were + # doing before so we have to inject a custom value. + num_bytes = int(math.log(curve.order - 1, 2) + 1) // 8 + 8 + entropy = int.from_bytes(b"\04" * num_bytes, byteorder="big") + p = curve.curve.p() + return (entropy % (p - 1)) + 1 + + +# As above, the library has built-in logic for truncating digests that are too +# large, but they use a slightly different technique than our previous library. +# Re-implement that logic here. +def _truncate_digest(digest, curve): + i = int.from_bytes(digest, byteorder="big") + p = curve.curve.p() + while i > p: + i >>= 1 + return i.to_bytes(math.ceil(i.bit_length() / 8), byteorder="big") + + +def byteStringToHexifiedBitString(string): + """Takes a string of bytes and returns a hex string representing + those bytes for use with pyasn1.type.univ.BitString. It must be of + the form "'<hex bytes>'H", where the trailing 'H' indicates to + pyasn1 that the input is a hex string.""" + return "'%s'H" % six.ensure_binary(string).hex() + + +class UnknownBaseError(Exception): + """Base class for handling unexpected input in this module.""" + + def __init__(self, value): + super(UnknownBaseError, self).__init__() + self.value = value + self.category = "input" + + def __str__(self): + return 'Unknown %s type "%s"' % (self.category, repr(self.value)) + + +class UnknownKeySpecificationError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "key specification" + + +class UnknownHashAlgorithmError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "hash algorithm" + + +class UnsupportedHashAlgorithmError(Exception): + """Helper exception type for unsupported hash algorithms.""" + + def __init__(self, value): + super(UnsupportedHashAlgorithmError, self).__init__() + self.value = value + + def __str__(self): + return 'Unsupported hash algorithm "%s"' % repr(self.value) + + +class RSAPublicKey(univ.Sequence): + """Helper type for encoding an RSA public key""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("N", univ.Integer()), + namedtype.NamedType("E", univ.Integer()), + ) + + +class RSAPrivateKey(univ.Sequence): + """Helper type for encoding an RSA private key""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("modulus", univ.Integer()), + namedtype.NamedType("publicExponent", univ.Integer()), + namedtype.NamedType("privateExponent", univ.Integer()), + namedtype.NamedType("prime1", univ.Integer()), + namedtype.NamedType("prime2", univ.Integer()), + namedtype.NamedType("exponent1", univ.Integer()), + namedtype.NamedType("exponent2", univ.Integer()), + namedtype.NamedType("coefficient", univ.Integer()), + ) + + +class ECPrivateKey(univ.Sequence): + """Helper type for encoding an EC private key + ECPrivateKey ::= SEQUENCE { + version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + privateKey OCTET STRING, + parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + (NOTE: parameters field is not supported) + publicKey [1] BIT STRING OPTIONAL + }""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("privateKey", univ.OctetString()), + namedtype.OptionalNamedType( + "publicKey", + univ.BitString().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1) + ), + ), + ) + + +class ECPoint(univ.Sequence): + """Helper type for encoding a EC point""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("x", univ.Integer()), + namedtype.NamedType("y", univ.Integer()), + ) + + +class PrivateKeyInfo(univ.Sequence): + """Helper type for encoding a PKCS #8 private key info""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("privateKeyAlgorithm", rfc2459.AlgorithmIdentifier()), + namedtype.NamedType("privateKey", univ.OctetString()), + ) + + +class RSAKey(object): + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= + sharedRSA_N = int( + "00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857" + "6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a" + "a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c" + "c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b" + "2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716" + "d855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075" + "31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a" + "95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3" + "fe4923fa7251c431d503acda180a35ed8d", + 16, + ) + sharedRSA_E = 65537 + sharedRSA_D = int( + "009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da" + "a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46" + "3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2" + "39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c" + "7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa" + "79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3" + "6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c" + "f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931" + "5b62b30e6011f224725946eec57c6d9441", + 16, + ) + sharedRSA_P = int( + "00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb" + "a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f" + "8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d" + "d5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177" + "3ca5d19301f48c742b", + 16, + ) + sharedRSA_Q = int( + "00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47" + "8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d" + "1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833" + "28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16" + "5810a77b9845bc3127", + 16, + ) + sharedRSA_exp1 = int( + "0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35" + "81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc" + "f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66" + "21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765" + "5315be9c24d191992d", + 16, + ) + sharedRSA_exp2 = int( + "28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26" + "ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1" + "b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0" + "aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a" + "5a4a6287c151de2d", + 16, + ) + sharedRSA_coef = int( + "28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b" + "e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab" + "cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf" + "8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf" + "7402af6c43247f43", + 16, + ) + + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= + alternateRSA_N = int( + "00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f" + "a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244" + "c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313" + "b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7" + "295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773" + "7699958666254797ed426908880811422069988a43fee48ce68781dd22b6" + "a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b" + "35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457" + "324ad7de86e6552f1d1e191d712168d3bb", + 16, + ) + alternateRSA_E = 65537 + alternateRSA_D = int( + "7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079" + "0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732" + "7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1" + "12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e" + "b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0" + "58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962" + "857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0" + "8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750" + "78c4021a9a2c93c9a70390e9d0a54401", + 16, + ) + alternateRSA_P = int( + "00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81" + "258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d" + "3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979" + "9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f" + "27b06fe09ddda7c0a1", + 16, + ) + alternateRSA_Q = int( + "00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708" + "4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac" + "6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb" + "a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd" + "fe764c1967b3e8cadb", + 16, + ) + alternateRSA_exp1 = int( + "01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d" + "3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3" + "c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27" + "9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60" + "9b5790a63c595181", + 16, + ) + alternateRSA_exp2 = int( + "0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a" + "f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b" + "1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733" + "cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798" + "1cd6234d571e90b7df", + 16, + ) + alternateRSA_coef = int( + "6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8" + "594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6" + "8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828" + "27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a" + "7b0df271e19a65c0", + 16, + ) + + evRSA_N = int( + "00b549895c9d00108d11a1f99f87a9e3d1a5db5dfaecf188da57bf641368" + "8f2ce4722cff109038c17402c93a2a473dbd286aed3fdcd363cf5a291477" + "01bdd818d7615bf9356bd5d3c8336aaa8c0971368a06c3cd4461b93e5142" + "4e1744bb2eaad46aab38ce196821961f87714a1663693f09761cdf4d6ba1" + "25eacec7be270d388f789f6cdf78ae3144ed28c45e79293863a7a22a4898" + "0a36a40e72d579c9b925dff8c793362ffd6897a7c1754c5e97c967c3eadd" + "1aae8aa2ccce348a0169b80e28a2d70c1a960c6f335f2da09b9b643f5abf" + "ba49e8aaa981e960e27d87480bdd55dd9417fa18509fbb554ccf81a4397e" + "8ba8128a34bdf27865c189e5734fb22905", + 16, + ) + evRSA_E = 65537 + evRSA_D = int( + "00983d54f94d6f4c76eb23d6f93d78523530cf73b0d16254c6e781768d45" + "f55681d1d02fb2bd2aac6abc1c389860935c52a0d8f41482010394778314" + "1d864bff30803638a5c0152570ae9d18f3d8ca163efb475b0dddf32e7e16" + "ec7565e6bb5e025c41c5c66e57a03cede554221f83045347a2c4c451c3dc" + "e476b787ce0c057244be9e04ef13118dbbb3d5e0a6cc87029eafd4a69ed9" + "b14759b15e39d8a9884e56f54d2f9ab013f0d15f318a9ab6b2f73d1ec3c9" + "fe274ae89431a10640be7899b0011c5e5093a1834708689de100634dabde" + "60fbd6aaefa3a33df34a1f36f60c043036b748d1c9ee98c4031a0afec60e" + "fda0a990be524f5614eac4fdb34a52f951", + 16, + ) + evRSA_P = int( + "00eadc2cb33e5ff1ca376bbd95bd6a1777d2cf4fac47545e92d11a6209b9" + "d5e4ded47834581c169b3c884742a09ea187505c1ca55414d8d25b497632" + "d5ec2aaa05233430fad49892777a7d68e038f561a3b8969e60b0a263defb" + "fda48a9b0ff39d95bc88b15267c8ade97b5107948e41e433249d87f7db10" + "9d5d74584d86bcc1d7", + 16, + ) + evRSA_Q = int( + "00c59ae576a216470248d944a55b9e9bf93299da341ec56e558eba821abc" + "e1bf57b79cf411d2904c774f9dba1f15185f607b0574a08205d6ec28b66a" + "36d634232eaaf2fea37561abaf9d644b68db38c9964cb8c96ec0ac61eba6" + "4d05b446542f423976f5acde4ecc95536d2df578954f93f0cfd9c58fb78b" + "a2a76dd5ac284dc883", + 16, + ) + evRSA_exp1 = int( + "00c1d2ef3906331c52aca64811f9fe425beb2898322fb3db51032ce8d7e9" + "fc32240be92019cf2480fcd5e329837127118b2a59a1bfe06c883e3a4447" + "f3f031cd9aebd0b8d368fc79740d2cce8eadb324df7f091eafe1564361d5" + "4920b01b0471230e5e47d93f8ed33963c517bc4fc78f6d8b1f9eba85bcce" + "db7033026508db6285", + 16, + ) + evRSA_exp2 = int( + "008521b8db5694dfbe804a315f9efc9b65275c5490acf2a3456d65e6e610" + "bf9f647fc67501d4f5772f232ac70ccdef9fc2a6dfa415c7c41b6afc7af9" + "d07c3ca03f7ed93c09f0b99f2c304434322f1071709bbc1baa4c91575fa6" + "a959e07d4996956d95e22b57938b6e47c8d51ffedfc9bf888ce0d1a3e42b" + "65a89bed4b91d3e5f5", + 16, + ) + evRSA_coef = int( + "00dc497b06b920c8be0b0077b798e977eef744a90ec2c5d7e6cbb22448fa" + "c72da81a33180e0d8a02e831460c7fc7fd3a612f7b9930b61b799f8e908e" + "632e9ba0409b6aa70b03a3ba787426263b5bd5843df8476edb5d14f6a861" + "3ebaf5b9cd5ca42f5fbd2802e08e4e49e5709f5151510caa5ab2c1c6eb3e" + "fe9295d16e8c25c916", + 16, + ) + + evRSA2040_N = int( + "00ca7020dc215f57914d343fae4a015111697af997a5ece91866499fc23f" + "1b88a118cbd30b10d91c7b9a0d4ee8972fcae56caf57f25fc1275a2a4dbc" + "b982428c32ef587bf2387410330a0ffb16b8029bd783969ef675f6de38c1" + "8f67193cb6c072f8b23d0b3374112627a57b90055771d9e62603f53788d7" + "f63afa724f5d108096df31f89f26b1eb5f7c4357980e008fcd55d827dd26" + "2395ca2f526a07897cc40c593b38716ebc0caa596719c6f29ac9b73a7a94" + "4748a3aa3e09e9eb4d461ea0027e540926614728b9d243975cf9a0541bef" + "d25e76b51f951110b0e7644fc7e38441791b6d2227384cb8004e23342372" + "b1cf5cc3e73e31b7bbefa160e6862ebb", + 16, + ) + evRSA2040_E = 65537 + evRSA2040_D = int( + "00b2db74bce92362abf72955a638ae8720ba3033bb7f971caf39188d7542" + "eaa1c1abb5d205b1e2111f4791c08911a2e141e8cfd7054702d23100b564" + "2c06e1a31b118afd1f9a2f396cced425c501d91435ca8656766ced2b93bb" + "b8669fce9bacd727d1dacb3dafabc3293e35389eef8ea0b58e1aeb1a20e6" + "a61f9fcd453f7567fe31d123b616a26fef4df1d6c9f7490111d028eefd1d" + "972045b1a242273dd7a67ebf111db2741a5a93c7b2289cc4a236f5a99a6e" + "c7a8206fdae1c1d04bdbb1980d4a298c5a17dae4186474a5f7835d882bce" + "f24aef4ed6f149f94d96c9f7d78e647fc778a9017ff208d3b4a1768b1821" + "62102cdab032fabbab38d5200a324649", + 16, + ) + evRSA2040_P = int( + "0f3844d0d4d4d6a21acd76a6fc370b8550e1d7ec5a6234172e790f0029ae" + "651f6d5c59330ab19802b9d7a207de7a1fb778e3774fdbdc411750633d8d" + "1b3fe075006ffcfd1d10e763c7a9227d2d5f0c2dade1c9e659c350a159d3" + "6bb986f12636d4f9942b288bc0fe21da8799477173144249ca2e389e6c5c" + "25aa78c8cad7d4df", + 16, + ) + evRSA2040_Q = int( + "0d4d0bedd1962f07a1ead6b23a4ed67aeaf1270f052a6d29ba074945c636" + "1a5c4f8f07bf859e067aed3f4e6e323ef2aa8a6acd340b0bdc7cfe4fd329" + "e3c97f870c7f7735792c6aa9d0f7e7542a28ed6f01b0e55a2b8d9c24a65c" + "6da314c95484f5c7c3954a81bb016b07ed17ee9b06039695bca059a79f8d" + "c2423d328d5265a5", + 16, + ) + evRSA2040_exp1 = int( + "09f29a2ff05be8a96d614ba31b08935420a86c6bc42b99a6692ea0da5763" + "f01e596959b7ddce73ef9c2e4f6e5b40710887500d44ba0c3cd3132cba27" + "475f39c2df7552e2d123a2497a4f97064028769a48a3624657f72bf539f3" + "d0de234feccd3be8a0aa90c6bf6e9b0bed43070a24d061ff3ed1751a3ef2" + "ff7f6b90b9dbd5fb", + 16, + ) + evRSA2040_exp2 = int( + "01a659e170cac120a03be1cf8f9df1caa353b03593bd7476e5853bd874c2" + "87388601c6c341ce9d1d284a5eef1a3a669d32b816a5eaecd8b7844fe070" + "64b9bca0c2b318d540277b3f7f1510d386bb36e03b04771e5d229e88893e" + "13b753bfb94518bb638e2404bd6e6a993c1668d93fc0b82ff08aaf34347d" + "3fe8397108c87ca5", + 16, + ) + evRSA2040_coef = int( + "040257c0d4a21c0b9843297c65652db66304fb263773d728b6abfa06d37a" + "c0ca62c628023e09e37dc0a901e4ce1224180e2582a3aa4b6a1a7b98e2bd" + "70077aec14ac8ab66a755c71e0fc102471f9bbc1b46a95aa0b645f2c38e7" + "6450289619ea3f5e8ae61037bffcf8249f22aa4e76e2a01909f3feb290ce" + "93edf57b10ebe796", + 16, + ) + + rsa2040_N = int( + "00bac0652fdfbc0055882ffbaeaceec88fa2d083c297dd5d40664dd3d90f" + "52f9aa02bd8a50fba16e0fd991878ef475f9b350d9f8e3eb2abd717ce327" + "b09788531f13df8e3e4e3b9d616bb8a41e5306eed2472163161051180127" + "6a4eb66f07331b5cbc8bcae7016a8f9b3d4f2ac4553c624cf5263bcb348e" + "8840de6612870960a792191b138fb217f765cec7bff8e94f16b39419bf75" + "04c59a7e4f79bd6d173e9c7bf3d9d2a4e73cc180b0590a73d584fb7fc9b5" + "4fa544607e53fc685c7a55fd44a81d4142b6af51ea6fa6cea52965a2e8c5" + "d84f3ca024d6fbb9b005b9651ce5d9f2ecf40ed404981a9ffc02636e311b" + "095c6332a0c87dc39271b5551481774b", + 16, + ) + rsa2040_E = 65537 + rsa2040_D = int( + "603db267df97555cbed86b8df355034af28f1eb7f3e7829d239bcc273a7c" + "7a69a10be8f21f1b6c4b02c6bae3731c3158b5bbff4605f57ab7b7b2a0cb" + "a2ec005a2db5b1ea6e0aceea5bc745dcd2d0e9d6b80d7eb0ea2bc08127bc" + "e35fa50c42cc411871ba591e23ba6a38484a33eff1347f907ee9a5a92a23" + "11bb0b435510020f78e3bb00099db4d1182928096505fcba84f3ca1238fd" + "1eba5eea1f391bbbcc5424b168063fc17e1ca6e1912ccba44f9d0292308a" + "1fedb80612529b39f59d0a3f8180b5ba201132197f93a5815ded938df8e7" + "d93c9b15766588f339bb59100afda494a7e452d7dd4c9a19ce2ec3a33a18" + "b20f0b4dade172bee19f26f0dcbe41", + 16, + ) + rsa2040_P = int( + "0ec3869cb92d406caddf7a319ab29448bc505a05913707873361fc5b986a" + "499fb65eeb815a7e37687d19f128087289d9bb8818e7bcca502c4900ad9a" + "ece1179be12ff3e467d606fc820ea8f07ac9ebffe2236e38168412028822" + "3e42dbe68dfd972a85a6447e51695f234da7911c67c9ab9531f33df3b994" + "32d4ee88c9a4efbb", + 16, + ) + rsa2040_Q = int( + "0ca63934549e85feac8e0f5604303fd1849fe88af4b7f7e1213283bbc7a2" + "c2a509f9273c428c68de3db93e6145f1b400bd6d4a262614e9043ad362d4" + "eba4a6b995399c8934a399912199e841d8e8dbff0489f69e663796730b29" + "80530b31cb70695a21625ea2adccc09d930516fa872211a91e22dd89fd9e" + "b7da8574b72235b1", + 16, + ) + rsa2040_exp1 = int( + "0d7d3a75e17f65f8a658a485c4095c10a4f66979e2b73bca9cf8ef21253e" + "1facac6d4791f58392ce8656f88f1240cc90c29653e3100c6d7a38ed44b1" + "63b339e5f3b6e38912126c69b3ceff2e5192426d9649b6ffca1abb75d2ba" + "2ed6d9a26aa383c5973d56216ff2edb90ccf887742a0f183ac92c94cf187" + "657645c7772d9ad7", + 16, + ) + rsa2040_exp2 = int( + "03f550194c117f24bea285b209058032f42985ff55acebe88b16df9a3752" + "7b4e61dc91a68dbc9a645134528ce5f248bda2893c96cb7be79ee73996c7" + "c22577f6c2f790406f3472adb3b211b7e94494f32c5c6fcc0978839fe472" + "4c31b06318a2489567b4fca0337acb1b841227aaa5f6c74800a2306929f0" + "2ce038bad943df41", + 16, + ) + rsa2040_coef = int( + "080a7dbfa8c2584814c71664c56eb62ce4caf16afe88d4499159d674774a" + "3a3ecddf1256c02fc91525c527692422d0aba94e5c41ee12dc71bb66f867" + "9fa17e096f28080851ba046eb31885c1414e8985ade599d907af17453d1c" + "caea2c0d06443f8367a6be154b125e390ee0d90f746f08801dd3f5367f59" + "fba2e5a67c05f375", + 16, + ) + + rsa1024_N = int( + "00d3a97440101eba8c5df9503e6f935eb52ffeb3ebe9d0dc5cace26f973c" + "a94cbc0d9c31d66c0c013bce9c82d0d480328df05fb6bcd7990a5312ddae" + "6152ad6ee61c8c1bdd8663c68bd36224a9882ae78e89f556dfdbe6f51da6" + "112cbfc27c8a49336b41afdb75321b52b24a7344d1348e646351a551c757" + "1ccda0b8fe35f61a75", + 16, + ) + rsa1024_E = 65537 + rsa1024_D = int( + "5b6708e185548fc07ff062dba3792363e106ff9177d60ee3227162391024" + "1813f958a318f26db8b6a801646863ebbc69190d6c2f5e7723433e99666d" + "76b3987892cd568f1f18451e8dc05477c0607ee348380ebb7f4c98d0c036" + "a0260bc67b2dab46cbaa4ce87636d839d8fddcbae2da3e02e8009a21225d" + "d7e47aff2f82699d", + 16, + ) + rsa1024_P = int( + "00fcdee570323e8fc399dbfc63d8c1569546fb3cd6886c628668ab1e1d0f" + "ca71058febdf76d702970ad6579d80ac2f9521075e40ef8f3f39983bd819" + "07e898bad3", + 16, + ) + rsa1024_Q = int( + "00d64801c955b4eb75fbae230faa8b28c9cc5e258be63747ff5ac8d2af25" + "3e9f6d6ce03ea2eb13ae0eb32572feb848c32ca00743635374338fedacd8" + "c5885f7897", + 16, + ) + rsa1024_exp1 = int( + "76c0526d5b1b28368a75d5d42a01b9a086e20b9310241e2cd2d0b166a278" + "c694ff1e9d25d9193d47789b52bb0fa194de1af0b77c09007f12afdfeef9" + "58d108c3", + 16, + ) + rsa1024_exp2 = int( + "008a41898d8b14217c4d782cbd15ef95d0a660f45ed09a4884f4e170367b" + "946d2f20398b907896890e88fe17b54bd7febe133ebc7720c86fe0649cca" + "7ca121e05f", + 16, + ) + rsa1024_coef = int( + "22db133445f7442ea2a0f582031ee214ff5f661972986f172651d8d6b4ec" + "3163e99bff1c82fe58ec3d075c6d8f26f277020edb77c3ba821b9ba3ae18" + "ff8cb2cb", + 16, + ) + + rsa1016_N = int( + "00d29bb12fb84fddcd29b3a519cb66c43b8d8f8be545ba79384ce663ed03" + "df75991600eb920790d2530cece544db99a71f05896a3ed207165534aa99" + "057e47c47e3bc81ada6fa1e12e37268b5046a55268f9dad7ccb485d81a2e" + "19d50d4f0b6854acaf6d7be69d9a083136e15afa8f53c1c8c84fc6077279" + "dd0e55d7369a5bdd", + 16, + ) + rsa1016_E = 65537 + rsa1016_D = int( + "3c4965070bf390c251d5a2c5277c5b5fd0bdee85cad7fe2b27982bb28511" + "4a507004036ae1cf8ae54b25e4db39215abd7e903f618c2d8b2f08cc6cd1" + "2dbccd72205e4945b6b3df389e5e43de0a148bb2c84e2431fdbe5920b044" + "bb272f45ecff0721b7dfb60397fc613a9ea35c22300530cae8f9159c534d" + "f3bf0910951901", + 16, + ) + rsa1016_P = int( + "0f9f17597c85b8051b9c69afb55ef576c996dbd09047d0ccde5b9d60ea5c" + "67fe4fac67be803f4b6ac5a3f050f76b966fb14f5cf105761e5ade6dd960" + "b183ba55", + 16, + ) + rsa1016_Q = int( + "0d7b637112ce61a55168c0f9c9386fb279ab40cba0d549336bba65277263" + "aac782611a2c81d9b635cf78c40018859e018c5e9006d12e3d2ee6f346e7" + "9fa43369", + 16, + ) + rsa1016_exp1 = int( + "09fd6c9a3ea6e91ae32070f9fc1c210ff9352f97be5d1eeb951bb39681e9" + "dc5b672a532221b3d8900c9a9d99b9d0a4e102dc450ca1b87b0b1389de65" + "16c0ae0d", + 16, + ) + rsa1016_exp2 = int( + "0141b832491b7dd4a83308920024c79cae64bd447df883bb4c5672a96bab" + "48b7123b34f26324452cdceb17f21e570e347cbe2fd4c2d8f9910eac2cb6" + "d895b8c9", + 16, + ) + rsa1016_coef = int( + "0458dd6aee18c88b2f9b81f1bc3075ae20dc1f9973d20724f20b06043d61" + "47c8789d4a07ae88bc82c8438c893e017b13947f62e0b18958a31eb664b1" + "9e64d3e0", + 16, + ) + + def __init__(self, specification): + if specification == "default": + self.RSA_N = self.sharedRSA_N + self.RSA_E = self.sharedRSA_E + self.RSA_D = self.sharedRSA_D + self.RSA_P = self.sharedRSA_P + self.RSA_Q = self.sharedRSA_Q + self.RSA_exp1 = self.sharedRSA_exp1 + self.RSA_exp2 = self.sharedRSA_exp2 + self.RSA_coef = self.sharedRSA_coef + elif specification == "alternate": + self.RSA_N = self.alternateRSA_N + self.RSA_E = self.alternateRSA_E + self.RSA_D = self.alternateRSA_D + self.RSA_P = self.alternateRSA_P + self.RSA_Q = self.alternateRSA_Q + self.RSA_exp1 = self.alternateRSA_exp1 + self.RSA_exp2 = self.alternateRSA_exp2 + self.RSA_coef = self.alternateRSA_coef + elif specification == "ev": + self.RSA_N = self.evRSA_N + self.RSA_E = self.evRSA_E + self.RSA_D = self.evRSA_D + self.RSA_P = self.evRSA_P + self.RSA_Q = self.evRSA_Q + self.RSA_exp1 = self.evRSA_exp1 + self.RSA_exp2 = self.evRSA_exp2 + self.RSA_coef = self.evRSA_coef + elif specification == "evRSA2040": + self.RSA_N = self.evRSA2040_N + self.RSA_E = self.evRSA2040_E + self.RSA_D = self.evRSA2040_D + self.RSA_P = self.evRSA2040_P + self.RSA_Q = self.evRSA2040_Q + self.RSA_exp1 = self.evRSA2040_exp1 + self.RSA_exp2 = self.evRSA2040_exp2 + self.RSA_coef = self.evRSA2040_coef + elif specification == "rsa2040": + self.RSA_N = self.rsa2040_N + self.RSA_E = self.rsa2040_E + self.RSA_D = self.rsa2040_D + self.RSA_P = self.rsa2040_P + self.RSA_Q = self.rsa2040_Q + self.RSA_exp1 = self.rsa2040_exp1 + self.RSA_exp2 = self.rsa2040_exp2 + self.RSA_coef = self.rsa2040_coef + elif specification == "rsa1024": + self.RSA_N = self.rsa1024_N + self.RSA_E = self.rsa1024_E + self.RSA_D = self.rsa1024_D + self.RSA_P = self.rsa1024_P + self.RSA_Q = self.rsa1024_Q + self.RSA_exp1 = self.rsa1024_exp1 + self.RSA_exp2 = self.rsa1024_exp2 + self.RSA_coef = self.rsa1024_coef + elif specification == "rsa1016": + self.RSA_N = self.rsa1016_N + self.RSA_E = self.rsa1016_E + self.RSA_D = self.rsa1016_D + self.RSA_P = self.rsa1016_P + self.RSA_Q = self.rsa1016_Q + self.RSA_exp1 = self.rsa1016_exp1 + self.RSA_exp2 = self.rsa1016_exp2 + self.RSA_coef = self.rsa1016_coef + else: + raise UnknownKeySpecificationError(specification) + + def toDER(self): + privateKeyInfo = PrivateKeyInfo() + privateKeyInfo["version"] = 0 + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier + rsaPrivateKey = RSAPrivateKey() + rsaPrivateKey["version"] = 0 + rsaPrivateKey["modulus"] = self.RSA_N + rsaPrivateKey["publicExponent"] = self.RSA_E + rsaPrivateKey["privateExponent"] = self.RSA_D + rsaPrivateKey["prime1"] = self.RSA_P + rsaPrivateKey["prime2"] = self.RSA_Q + rsaPrivateKey["exponent1"] = self.RSA_exp1 + rsaPrivateKey["exponent2"] = self.RSA_exp2 + rsaPrivateKey["coefficient"] = self.RSA_coef + rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) + privateKeyInfo["privateKey"] = univ.OctetString(rsaPrivateKeyEncoded) + return encoder.encode(privateKeyInfo) + + def toPEM(self): + output = "-----BEGIN PRIVATE KEY-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END PRIVATE KEY-----" + return output + + def asSubjectPublicKeyInfo(self): + """Returns a subject public key info representing + this key for use by pyasn1.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + spki = rfc2459.SubjectPublicKeyInfo() + spki["algorithm"] = algorithmIdentifier + rsaKey = RSAPublicKey() + rsaKey["N"] = univ.Integer(self.RSA_N) + rsaKey["E"] = univ.Integer(self.RSA_E) + subjectPublicKey = univ.BitString( + byteStringToHexifiedBitString(encoder.encode(rsaKey)) + ) + spki["subjectPublicKey"] = subjectPublicKey + return spki + + def sign(self, data, hashAlgorithm): + """Returns a hexified bit string representing a + signature by this key over the specified data. + Intended for use with pyasn1.type.univ.BitString""" + hashAlgorithmName = None + if hashAlgorithm == HASH_MD5: + hashAlgorithmName = "MD5" + elif hashAlgorithm == HASH_SHA1: + hashAlgorithmName = "SHA-1" + elif hashAlgorithm == HASH_SHA256: + hashAlgorithmName = "SHA-256" + elif hashAlgorithm == HASH_SHA384: + hashAlgorithmName = "SHA-384" + elif hashAlgorithm == HASH_SHA512: + hashAlgorithmName = "SHA-512" + else: + raise UnknownHashAlgorithmError(hashAlgorithm) + rsaPrivateKey = rsa.PrivateKey( + self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q + ) + signature = rsa.sign(data, rsaPrivateKey, hashAlgorithmName) + return byteStringToHexifiedBitString(signature) + + +ecPublicKey = univ.ObjectIdentifier("1.2.840.10045.2.1") +secp256k1 = univ.ObjectIdentifier("1.3.132.0.10") +secp224r1 = univ.ObjectIdentifier("1.3.132.0.33") +secp256r1 = univ.ObjectIdentifier("1.2.840.10045.3.1.7") +secp384r1 = univ.ObjectIdentifier("1.3.132.0.34") +secp521r1 = univ.ObjectIdentifier("1.3.132.0.35") + + +def longToEvenLengthHexString(val): + h = format(val, "x") + if not len(h) % 2 == 0: + h = "0" + h + return h + + +class ECCKey(object): + secp256k1KeyPair = ( + "35ee7c7289d8fef7a86afe5da66d8bc2ebb6a8543fd2fead089f45ce7acd0fa6" + + "4382a9500c41dad770ffd4b511bf4b492eb1238800c32c4f76c73a3f3294e7c5", + "67cebc208a5fa3df16ec2bb34acc59a42ab4abb0538575ca99b92b6a2149a04f", + ) + + secp224r1KeyPair = ( + "668d72cca6fd6a1b3557b5366104d84408ecb637f08e8c86bbff82cc" + + "00e88f0066d7af63c3298ba377348a1202b03b37fd6b1ff415aa311e", + "04389459926c3296c242b83e10a6cd2011c8fe2dae1b772ea5b21067", + ) + + secp256r1KeyPair = ( + "4fbfbbbb61e0f8f9b1a60a59ac8704e2ec050b423e3cf72e923f2c4f794b455c" + + "2a69d233456c36c4119d0706e00eedc8d19390d7991b7b2d07a304eaa04aa6c0", + "2191403d5710bf15a265818cd42ed6fedf09add92d78b18e7a1e9feb95524702", + ) + + secp384r1KeyPair = ( + "a1687243362b5c7b1889f379154615a1c73fb48dee863e022915db608e252de4b71" + + "32da8ce98e831534e6a9c0c0b09c8d639ade83206e5ba813473a11fa330e05da8c9" + + "6e4383fe27873da97103be2888cff002f05af71a1fddcc8374aa6ea9ce", + "035c7a1b10d9fafe837b64ad92f22f5ced0789186538669b5c6d872cec3d926122b" + + "393772b57602ff31365efe1393246", + ) + + secp521r1KeyPair = ( + "014cdc9cacc47941096bc9cc66752ec27f597734fa66c62b792f88c519d6d37f0d1" + + "6ea1c483a1827a010b9128e3a08070ca33ef5f57835b7c1ba251f6cc3521dc42b01" + + "0653451981b445d343eed3782a35d6cff0ff484f5a883d209f1b9042b726703568b" + + "2f326e18b833bdd8aa0734392bcd19501e10d698a79f53e11e0a22bdd2aad90", + "014f3284fa698dd9fe1118dd331851cdfaac5a3829278eb8994839de9471c940b85" + + "8c69d2d05e8c01788a7d0b6e235aa5e783fc1bee807dcc3865f920e12cf8f2d29", + ) + + def __init__(self, specification): + if specification == "secp256k1": + key_pair = self.secp256k1KeyPair + self.keyOID = secp256k1 + self.curve = ecdsa.SECP256k1 + elif specification == "secp224r1": + key_pair = self.secp224r1KeyPair + self.keyOID = secp224r1 + self.curve = ecdsa.NIST224p + elif specification == "secp256r1": + key_pair = self.secp256r1KeyPair + self.keyOID = secp256r1 + self.curve = ecdsa.NIST256p + elif specification == "secp384r1": + key_pair = self.secp384r1KeyPair + self.keyOID = secp384r1 + self.curve = ecdsa.NIST384p + elif specification == "secp521r1": + key_pair = self.secp521r1KeyPair + self.keyOID = secp521r1 + self.curve = ecdsa.NIST521p + else: + raise UnknownKeySpecificationError(specification) + + self.public_key, self.private_key = ( + binascii.unhexlify(key_pair[0]), + binascii.unhexlify(key_pair[1]), + ) + self.key = ecdsa.SigningKey.from_string(self.private_key, curve=self.curve) + + def getPublicKeyHexifiedString(self): + """Returns the EC public key as a hex string using the uncompressed + point representation. This is intended to be used in the encoder + functions, as it surrounds the value with ''H to indicate its type.""" + p1, p2 = ( + self.public_key[: len(self.public_key) // 2], + self.public_key[len(self.public_key) // 2 :], + ) + # We don't want leading zeroes. + p1, p2 = (p1.lstrip(b"\0"), p2.lstrip(b"\0")) + # '04' indicates that the points are in uncompressed form. + return byteStringToHexifiedBitString(b"\04" + p1 + p2) + + def toPEM(self): + """Return the EC private key in PEM-encoded form.""" + output = "-----BEGIN EC PRIVATE KEY-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END EC PRIVATE KEY-----" + return output + + def toDER(self): + """Return the EC private key in DER-encoded form, encoded per SEC 1 + section C.4 format.""" + privateKeyInfo = PrivateKeyInfo() + privateKeyInfo["version"] = 0 + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = ecPublicKey + algorithmIdentifier["parameters"] = self.keyOID + privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier + ecPrivateKey = ECPrivateKey() + ecPrivateKey["version"] = 1 + ecPrivateKey["privateKey"] = self.private_key + ecPrivateKey["publicKey"] = univ.BitString( + self.getPublicKeyHexifiedString() + ).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) + ecPrivateKeyEncoded = encoder.encode(ecPrivateKey) + privateKeyInfo["privateKey"] = univ.OctetString(ecPrivateKeyEncoded) + return encoder.encode(privateKeyInfo) + + def asSubjectPublicKeyInfo(self): + """Returns a subject public key info representing + this key for use by pyasn1.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = ecPublicKey + algorithmIdentifier["parameters"] = self.keyOID + spki = rfc2459.SubjectPublicKeyInfo() + spki["algorithm"] = algorithmIdentifier + spki["subjectPublicKey"] = univ.BitString(self.getPublicKeyHexifiedString()) + return spki + + def signRaw(self, data, hashAlgorithm): + """Performs the ECDSA signature algorithm over the given data. + The returned value is a string representing the bytes of the + resulting point when encoded by left-padding each of (r, s) to + the key size and concatenating them. + """ + assert hashAlgorithm.startswith("hash:") + hashAlgorithm = hashAlgorithm[len("hash:") :] + k = _gen_k(self.curve) + digest = hashlib.new(hashAlgorithm, six.ensure_binary(data)).digest() + digest = _truncate_digest(digest, self.curve) + # NOTE: Under normal circumstances it's advisable to use + # sign_digest_deterministic. In this case we don't want the library's + # default generation of k, so we call the normal "sign" method and + # inject it here. + return self.key.sign_digest(digest, sigencode=ecdsa.util.sigencode_string, k=k) + + def sign(self, data, hashAlgorithm): + """Returns a hexified bit string representing a + signature by this key over the specified data. + Intended for use with pyasn1.type.univ.BitString""" + # signRaw returns an encoded point, which is useful in some situations. + # However, for signatures on X509 certificates, we need to decode it so + # we can encode it as a BITSTRING consisting of a SEQUENCE of two + # INTEGERs. + raw = self.signRaw(data, hashAlgorithm) + point = ECPoint() + point["x"] = int.from_bytes(raw[: len(raw) // 2], byteorder="big") + point["y"] = int.from_bytes(raw[len(raw) // 2 :], byteorder="big") + return byteStringToHexifiedBitString(encoder.encode(point)) + + +def keyFromSpecification(specification): + """Pass in a specification, get the appropriate key back.""" + if specification.startswith("secp"): + return ECCKey(specification) + return RSAKey(specification) + + +# The build harness will call this function with an output file-like +# object and a path to a file containing a specification. This will +# read the specification and output the key as ASCII-encoded PKCS #8. + + +def main(output, inputPath): + with open(inputPath) as configStream: + output.write(keyFromSpecification(configStream.read().strip()).toPEM() + "\n") + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(keyFromSpecification(sys.stdin.read().strip()).toPEM()) diff --git a/security/manager/ssl/tests/unit/requirements.txt b/security/manager/ssl/tests/unit/requirements.txt new file mode 100644 index 0000000000..095fcb04fc --- /dev/null +++ b/security/manager/ssl/tests/unit/requirements.txt @@ -0,0 +1,6 @@ +lxml +pyasn1 == 0.3.7 +pyasn1_modules == 0.1.5 +ecc +mock +rsa diff --git a/security/manager/ssl/tests/unit/sign_app.py b/security/manager/ssl/tests/unit/sign_app.py new file mode 100755 index 0000000000..8c90376581 --- /dev/null +++ b/security/manager/ssl/tests/unit/sign_app.py @@ -0,0 +1,399 @@ +#!/usr/bin/env python3 +# +# 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/. + +""" +Given a directory of files, packages them up and signs the +resulting zip file. Mainly for creating test inputs to the +nsIX509CertDB.openSignedAppFileAsync API. +""" +from base64 import b64encode +from cbor2 import dumps +from cbor2.types import CBORTag +from hashlib import sha1, sha256 +import argparse +from io import StringIO +import os +import pycert +import pycms +import pykey +import re +import six +import zipfile + + +ES256 = -7 +ES384 = -35 +ES512 = -36 +KID = 4 +ALG = 1 +COSE_Sign = 98 + + +def coseAlgorithmToPykeyHash(algorithm): + """Helper function that takes one of (ES256, ES384, ES512) + and returns the corresponding pykey.HASH_* identifier.""" + if algorithm == ES256: + return pykey.HASH_SHA256 + if algorithm == ES384: + return pykey.HASH_SHA384 + if algorithm == ES512: + return pykey.HASH_SHA512 + raise UnknownCOSEAlgorithmError(algorithm) + + +# COSE_Signature = [ +# protected : serialized_map, +# unprotected : {}, +# signature : bstr +# ] + + +def coseSignature(payload, algorithm, signingKey, signingCertificate, bodyProtected): + """Returns a COSE_Signature structure. + payload is a string representing the data to be signed + algorithm is one of (ES256, ES384, ES512) + signingKey is a pykey.ECKey to sign the data with + signingCertificate is a byte string + bodyProtected is the serialized byte string of the protected body header + """ + protected = {ALG: algorithm, KID: signingCertificate} + protectedEncoded = dumps(protected) + # Sig_structure = [ + # context : "Signature" + # body_protected : bodyProtected + # sign_protected : protectedEncoded + # external_aad : nil + # payload : bstr + # ] + sigStructure = [u"Signature", bodyProtected, protectedEncoded, None, payload] + sigStructureEncoded = dumps(sigStructure) + pykeyHash = coseAlgorithmToPykeyHash(algorithm) + signature = signingKey.signRaw(sigStructureEncoded, pykeyHash) + return [protectedEncoded, {}, signature] + + +# COSE_Sign = [ +# protected : serialized_map, +# unprotected : {}, +# payload : nil, +# signatures : [+ COSE_Signature] +# ] + + +def coseSig(payload, intermediates, signatures): + """Returns the entire (tagged) COSE_Sign structure. + payload is a string representing the data to be signed + intermediates is an array of byte strings + signatures is an array of (algorithm, signingKey, + signingCertificate) triplets to be passed to + coseSignature + """ + protected = {KID: intermediates} + protectedEncoded = dumps(protected) + coseSignatures = [] + for (algorithm, signingKey, signingCertificate) in signatures: + coseSignatures.append( + coseSignature( + payload, algorithm, signingKey, signingCertificate, protectedEncoded + ) + ) + tagged = CBORTag(COSE_Sign, [protectedEncoded, {}, None, coseSignatures]) + return dumps(tagged) + + +def walkDirectory(directory): + """Given a relative path to a directory, enumerates the + files in the tree rooted at that location. Returns a list + of pairs of paths to those files. The first in each pair + is the full path to the file. The second in each pair is + the path to the file relative to the directory itself.""" + paths = [] + for path, _dirs, files in os.walk(directory): + for f in files: + fullPath = os.path.join(path, f) + internalPath = re.sub(r"^/", "", fullPath.replace(directory, "")) + paths.append((fullPath, internalPath)) + return paths + + +def addManifestEntry(filename, hashes, contents, entries): + """Helper function to fill out a manifest entry. + Takes the filename, a list of (hash function, hash function name) + pairs to use, the contents of the file, and the current list + of manifest entries.""" + entry = "Name: %s\n" % filename + for (hashFunc, name) in hashes: + base64hash = b64encode(hashFunc(contents).digest()).decode("ascii") + entry += "%s-Digest: %s\n" % (name, base64hash) + entries.append(entry) + + +def getCert(subject, keyName, issuerName, ee, issuerKey=""): + """Helper function to create an X509 cert from a specification. + Takes the subject, the subject key name to use, the issuer name, + a bool whether this is an EE cert or not, and optionally an issuer key + name.""" + certSpecification = ( + "issuer:%s\n" % issuerName + + "subject:" + + subject + + "\n" + + "subjectKey:%s\n" % keyName + ) + if ee: + certSpecification += "extension:keyUsage:digitalSignature" + else: + certSpecification += ( + "extension:basicConstraints:cA,\n" + + "extension:keyUsage:cRLSign,keyCertSign" + ) + if issuerKey: + certSpecification += "\nissuerKey:%s" % issuerKey + certSpecificationStream = StringIO() + print(certSpecification, file=certSpecificationStream) + certSpecificationStream.seek(0) + return pycert.Certificate(certSpecificationStream) + + +def coseAlgorithmToSignatureParams(coseAlgorithm, issuerName): + """Given a COSE algorithm ('ES256', 'ES384', 'ES512') and an issuer + name, returns a (algorithm id, pykey.ECCKey, encoded certificate) + triplet for use with coseSig. + """ + if coseAlgorithm == "ES256": + keyName = "secp256r1" + algId = ES256 + elif coseAlgorithm == "ES384": + keyName = "secp384r1" + algId = ES384 + elif coseAlgorithm == "ES512": + keyName = "secp521r1" # COSE uses the hash algorithm; this is the curve + algId = ES512 + else: + raise UnknownCOSEAlgorithmError(coseAlgorithm) + key = pykey.ECCKey(keyName) + # The subject must differ to avoid errors when importing into NSS later. + ee = getCert( + "xpcshell signed app test signer " + keyName, + keyName, + issuerName, + True, + "default", + ) + return (algId, key, ee.toDER()) + + +def signZip( + appDirectory, + outputFile, + issuerName, + rootName, + manifestHashes, + signatureHashes, + pkcs7Hashes, + coseAlgorithms, + emptySignerInfos, + headerPaddingFactor, +): + """Given a directory containing the files to package up, + an output filename to write to, the name of the issuer of + the signing certificate, the name of trust anchor, a list of hash algorithms + to use in the manifest file, a similar list for the signature file, + a similar list for the pkcs#7 signature, a list of COSE signature algorithms + to include, whether the pkcs#7 signer info should be kept empty, and how + many MB to pad the manifests by (to test handling large manifest files), + packages up the files in the directory and creates the output as + appropriate.""" + # The header of each manifest starts with the magic string + # 'Manifest-Version: 1.0' and ends with a blank line. There can be + # essentially anything after the first line before the blank line. + mfEntries = ["Manifest-Version: 1.0"] + if headerPaddingFactor > 0: + # In this format, each line can only be 72 bytes long. We make + # our padding 50 bytes per line (49 of content and one newline) + # so the math is easy. + singleLinePadding = "a" * 49 + # 1000000 / 50 = 20000 + allPadding = [singleLinePadding] * (headerPaddingFactor * 20000) + mfEntries.extend(allPadding) + # Append the blank line. + mfEntries.append("") + + with zipfile.ZipFile(outputFile, "w", zipfile.ZIP_DEFLATED) as outZip: + for (fullPath, internalPath) in walkDirectory(appDirectory): + with open(fullPath, "rb") as inputFile: + contents = inputFile.read() + outZip.writestr(internalPath, contents) + + # Add the entry to the manifest we're building + addManifestEntry(internalPath, manifestHashes, contents, mfEntries) + + if len(coseAlgorithms) > 0: + coseManifest = "\n".join(mfEntries) + outZip.writestr("META-INF/cose.manifest", coseManifest) + coseManifest = six.ensure_binary(coseManifest) + addManifestEntry( + "META-INF/cose.manifest", manifestHashes, coseManifest, mfEntries + ) + intermediates = [] + coseIssuerName = issuerName + if rootName: + coseIssuerName = "xpcshell signed app test issuer" + intermediate = getCert(coseIssuerName, "default", rootName, False) + intermediate = intermediate.toDER() + intermediates.append(intermediate) + signatures = [ + coseAlgorithmToSignatureParams(coseAlgorithm, coseIssuerName) + for coseAlgorithm in coseAlgorithms + ] + coseSignatureBytes = coseSig(coseManifest, intermediates, signatures) + outZip.writestr("META-INF/cose.sig", coseSignatureBytes) + addManifestEntry( + "META-INF/cose.sig", manifestHashes, coseSignatureBytes, mfEntries + ) + + if len(pkcs7Hashes) != 0 or emptySignerInfos: + mfContents = "\n".join(mfEntries) + sfContents = "Signature-Version: 1.0\n" + for (hashFunc, name) in signatureHashes: + hashed = hashFunc(six.ensure_binary(mfContents)).digest() + base64hash = b64encode(hashed).decode("ascii") + sfContents += "%s-Digest-Manifest: %s\n" % (name, base64hash) + + cmsSpecification = "" + for name in pkcs7Hashes: + hashFunc, _ = hashNameToFunctionAndIdentifier(name) + cmsSpecification += "%s:%s\n" % ( + name, + hashFunc(six.ensure_binary(sfContents)).hexdigest(), + ) + cmsSpecification += ( + "signer:\n" + + "issuer:%s\n" % issuerName + + "subject:xpcshell signed app test signer\n" + + "extension:keyUsage:digitalSignature" + ) + cmsSpecificationStream = StringIO() + print(cmsSpecification, file=cmsSpecificationStream) + cmsSpecificationStream.seek(0) + cms = pycms.CMS(cmsSpecificationStream) + p7 = cms.toDER() + outZip.writestr("META-INF/A.RSA", p7) + outZip.writestr("META-INF/A.SF", sfContents) + outZip.writestr("META-INF/MANIFEST.MF", mfContents) + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownHashAlgorithmError(Error): + """Helper exception type to handle unknown hash algorithms.""" + + def __init__(self, name): + super(UnknownHashAlgorithmError, self).__init__() + self.name = name + + def __str__(self): + return "Unknown hash algorithm %s" % repr(self.name) + + +class UnknownCOSEAlgorithmError(Error): + """Helper exception type to handle unknown COSE algorithms.""" + + def __init__(self, name): + super(UnknownCOSEAlgorithmError, self).__init__() + self.name = name + + def __str__(self): + return "Unknown COSE algorithm %s" % repr(self.name) + + +def hashNameToFunctionAndIdentifier(name): + if name == "sha1": + return (sha1, "SHA1") + if name == "sha256": + return (sha256, "SHA256") + raise UnknownHashAlgorithmError(name) + + +def main(outputFile, appPath, *args): + """Main entrypoint. Given an already-opened file-like + object, a path to the app directory to sign, and some + optional arguments, signs the contents of the directory and + writes the resulting package to the 'file'.""" + parser = argparse.ArgumentParser(description="Sign an app.") + parser.add_argument( + "-i", + "--issuer", + action="store", + help="Issuer name", + default="xpcshell signed apps test root", + ) + parser.add_argument("-r", "--root", action="store", help="Root name", default="") + parser.add_argument( + "-m", + "--manifest-hash", + action="append", + help="Hash algorithms to use in manifest", + default=[], + ) + parser.add_argument( + "-s", + "--signature-hash", + action="append", + help="Hash algorithms to use in signature file", + default=[], + ) + parser.add_argument( + "-c", + "--cose-sign", + action="append", + help="Append a COSE signature with the given " + + "algorithms (out of ES256, ES384, and ES512)", + default=[], + ) + parser.add_argument( + "-z", + "--pad-headers", + action="store", + default=0, + help="Pad the header sections of the manifests " + + "with X MB of repetitive data", + ) + group = parser.add_mutually_exclusive_group() + group.add_argument( + "-p", + "--pkcs7-hash", + action="append", + help="Hash algorithms to use in PKCS#7 signature", + default=[], + ) + group.add_argument( + "-e", + "--empty-signerInfos", + action="store_true", + help="Emit pkcs#7 SignedData with empty signerInfos", + ) + parsed = parser.parse_args(args) + if len(parsed.manifest_hash) == 0: + parsed.manifest_hash.append("sha256") + if len(parsed.signature_hash) == 0: + parsed.signature_hash.append("sha256") + signZip( + appPath, + outputFile, + parsed.issuer, + parsed.root, + [hashNameToFunctionAndIdentifier(h) for h in parsed.manifest_hash], + [hashNameToFunctionAndIdentifier(h) for h in parsed.signature_hash], + parsed.pkcs7_hash, + parsed.cose_sign, + parsed.empty_signerInfos, + int(parsed.pad_headers), + ) diff --git a/security/manager/ssl/tests/unit/sss_readstate_child_worker.js b/security/manager/ssl/tests/unit/sss_readstate_child_worker.js new file mode 100644 index 0000000000..851a4e26ce --- /dev/null +++ b/security/manager/ssl/tests/unit/sss_readstate_child_worker.js @@ -0,0 +1,66 @@ +/* import-globals-from head_psm.js */ +"use strict"; + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + do_test_finished(); +} diff --git a/security/manager/ssl/tests/unit/test_add_preexisting_cert.js b/security/manager/ssl/tests/unit/test_add_preexisting_cert.js new file mode 100644 index 0000000000..1f1a7825f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_add_preexisting_cert.js @@ -0,0 +1,46 @@ +/* -*- 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 adding a certificate already present in the certificate database +// with different trust bits than those stored in the database does not result +// in the new trust bits being ignored. + +do_get_profile(); +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert, trust) { + let file = "test_intermediate_basic_usage_constraints/" + cert + ".pem"; + return addCertFromFile(certDB, file, trust); +} + +add_task(async function() { + load_cert("ca", "CTu,CTu,CTu"); + let int_cert = load_cert("int-limited-depth", "CTu,CTu,CTu"); + let file = + "test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem"; + let cert_pem = readFile(do_get_file(file)); + let ee = certDB.constructX509FromBase64(pemToBase64(cert_pem)); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + // Change the already existing intermediate certificate's trust using + // addCertFromBase64(). + notEqual(int_cert, null, "Intermediate cert should be in the cert DB"); + let base64_cert = int_cert.getBase64DERString(); + let returnedEE = certDB.addCertFromBase64(base64_cert, "p,p,p"); + notEqual(returnedEE, null, "addCertFromBase64 should return a certificate"); + await checkCertErrorGeneric( + certDB, + ee, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); +}); diff --git a/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js b/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js new file mode 100644 index 0000000000..e9f1b6c9db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js @@ -0,0 +1,25 @@ +/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +function run_test() { + do_get_profile(); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + true + ); + + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_connection_test("expired.example.com", PRErrorCodeSuccess); + add_test(function() { + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + false + ); + run_next_test(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem new file mode 100644 index 0000000000..161ce88377 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUXwklABFZn09Yj1azSdQ4kpuizxYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCdpP06UqpAnAAak/i4+LShrIG/ +DdjHLQ8qLChBdPkT6Gxx1XVoNfG3GJsIGCoOf6isORMfBlBXiR5kmLFTE3kJhA/I +pDxDGYDqt9DNb0fxeMpOJxwQ+mBMZIKLPu+nk4jTqUrOX8bLwDMiXTbFeY91SUr8 +4b43YzXVorVQSlYOfcsmrnEfmfJNauHBrzak5BQhsEXHqAI7qV9TCQA1+cGwH8jb +Aw2SyVu1usAyHkM2wCisHXeidf3qR6PxmfLMAgHKXBLz3DsXY30xDI4jJS9MySu9 +lhrs1IJf5PdJk5z5viYqZQemuv0R+R7ItbpCHpreUXh2GutiAY4Xsgrhfcer +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec new file mode 100644 index 0000000000..9c21e7adcf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build b/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build new file mode 100644 index 0000000000..df0cef67d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'no-san-old.pem', +# 'no-san-older.pem', +# 'no-san-recent.pem', +# 'san-contains-no-hostnames-old.pem', +# 'san-contains-no-hostnames-older.pem', +# 'san-contains-no-hostnames-recent.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem new file mode 100644 index 0000000000..a13b0cbcd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUS00fexo4Y4FagP1oiKQiGCJKd/swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAGjMx1NAs2guKp3wRRAWdiAw9NCeX+qCsxxkr4jUdgQ14wZwU2fZ/2rK +7Z/StpwlWN+G4dWwCRCjibKvjauQs+XLT9wMO3U/1VBcQda36duX70ss2SAF9crs +dmZdISevFItTn+W6JNyr1Wt2sSiD4buXpW1UzNwuxnWGpo/a++bMEYaM8KDdz73t +KA9VShYNbcrUZgf70bvCbc8BR3vYUwyIp3fP7TngD/dRLYJyv5ayo9VXVJxOzYU7 +/aRrBvAdAL2w8eQzzYm6uyHlOE+imWYix2QOGNFJIiRXFRTii9Rr0o4geW7x2wZJ ++TzO4XPVlax1h6KDPRLsmwhbJDAMuUU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec new file mode 100644 index 0000000000..7a34d0758f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem new file mode 100644 index 0000000000..f2bb8c97d9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUZ3gdKZRvWFYArMRStT2zAGE6JDQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBABERZmWOEZAI2dQHbpXo7BJFw8eigDs8xWGtnu5UbNFs7zGnXzta0L8T +RBoaWeEbsaVpuGQ648eorgQRGwNdL3JkJb0qHtaSl5/raAOvv+YqmGzZhFWcj3ib +WUOWODdFlY3oUzpPjA+IeRzULya6//s8DhEKfVi2mJXc/sS6fE9J234IhKBysyr1 +cRIApw6OCr0V78TbHzEPh1z0QuMKY8hH0lz3JvQqGD59oTEdSJ5VVbmDLxqqmVtA +/i4j2lYkDos2HvHGP7a/LC20FI0lOcSqazSeKc+y2Mand9tDXCU/dEEYMj1IW5rM +z2+96XzCbJBesYFEEfWXG6XysP3UtE0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec new file mode 100644 index 0000000000..aa682a7afd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem new file mode 100644 index 0000000000..7ac56a0689 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUWxGwhSb8roUQoLNpJajl0X8jk10wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAKxEoWUrHht8zENUlC/3tj/KbDSeaIy5nVE49aJRqHwuSczG5PTDn7sD +rjl6Qq2rx3Z3ftZxJNIdpS3BUeUJ+FsQ2fK3ckDyeWkzxADlWp2l2bgKDtnW5Xjw +lfzFt1Z/4PUmz0JyNGqijvpT/YYM9uM5OOKmKvy6C/6HiIMI2f5pVHM2bFWLuHLI +p9yqp056EKPWCEQbkqseXLS0O8ZyxAyW4kHezUQzn1KFq9IGZu5sBZ8Imop0xnal +2wXCuEisuAIOQNb1l9t+hf/P53+oRLjPbJzuzLZGSNA5PzoTbmZOqOdJS+kCNGCX +IahLlU3dPILDlvl8DLFhk+lz9mA8x90= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec new file mode 100644 index 0000000000..e38478165c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20160824-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem new file mode 100644 index 0000000000..ba11dcc152 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUOWkKeR6blD0zzhElEnCm4eSqLTAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEACPZ4Ed3iONrIIKtg3865taT5TUj4Ts3tnYn4riFqojr6h/CHEDPR +LStAJ4yYGQoTTzQzaxYjEZXHIEI/bCZ1VpGNpZt8DXWsJWwJgt8QUNeYT0eFFE2M +CjrLJC1OIQRvlR89WEbk/q45KBQC0faeizqkAn+YUSG8mjHHbmSO8PWbh4z0YYlg +BjwhTRFWUmWfQKC+mHyWblbYyFKlsFWf6cGOd4qE8N/hIz7oPzI4IPN1EQ/IfaQy +WOOyxPZeu+J5VPlPE10nV5afoRcPLh/6vTwH85tPGzxWU4Jo4NDtFOtZAZR/S7sO +OB/ST8Dbvs7qQFfRtgCtpEMicG7kxO1F+Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec new file mode 100644 index 0000000000..41817bde75 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20160724-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem new file mode 100644 index 0000000000..6882ba0554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUG1q3+RCKIizPHadkamCYLL7cp2swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEAqa/ayP8zXODUJJmuZLTJsdT2VaqbOh2WWk2bC2A82feGvCevLuL0 +0gPk+001Zx49Y1erMmt2M1cKtf2Lob8SGLNGUlJf2K7SNJTk7nyog+4UIlK4Hsxo +CQ9sqKGJjkwHTDK1rB9gSW4e27Taj6tudnsUfgKWVzERxipebtLsCvz8Jfa0YLRI +bGr6L4LoWiN2RNiK7/IOycfJ8VLDlBRouHD2Xfu0pFcvymMvfOC7GG4oBAacCKGn +muUfoODgKw2yCIOSe7jsJOQ9yOp03sRipISfO0TALFzJX0V5+7CYDLZYR8vs/F/4 +0cIqkhwyCfUWYsGI4gPPR/nVxNvTRZhiFw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec new file mode 100644 index 0000000000..65acf0b024 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20150724-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem new file mode 100644 index 0000000000..cd87acfe48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUD1kNqQ0aKQ2TJjGUYztUh8I7j4AwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEAU9n5I/Hdfod2fPBYWHZA/5/SabHkOBUHfrg6UUQYeHagVbqmoTQD +M5F/DcDna+w6nHagIC/GRHBHkgY3Syh8QK5LnL3zi5tC0u4dzysDUjWtEAEgIcWA +/pYtp6qZwJzxvn68PTnYnFDL61+LDLxlUBa2iRieRkCUOokCLL4ce3jsSTuJ+mGk +XoaRrRREgtG5loYK8hFXM1RDkzyCa82DF/qD+iYgUJS9LMXrsksIRHP7Lqzhnwba +Q4N8rgsBDFkNTEAmGcnTLMTlfO+SyKdHZI4n9VHdUQ1n38qFn70jj1YjcqEOFKXb +wldSrYMedEOFVWyXaVWmxMwMTiDIKWMoxg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec new file mode 100644 index 0000000000..140c201434 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20160824-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js new file mode 100644 index 0000000000..56de79ae7c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js @@ -0,0 +1,295 @@ +// -*- 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/. + +// The preference security.pki.name_matching_mode controls whether or not +// mozilla::pkix will fall back to using a certificate's subject common name +// during name matching. If the Baseline Requirements are followed, fallback +// should not be necessary (because any name information in the subject common +// name should be present in the subject alternative name extension). Due to +// compatibility concerns, the platform can be configured to fall back for +// certificates that are valid before 23 August 2016. Note that for certificates +// issued by an imported root, the platform will fall back if necessary, +// regardless of the value of the preference. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile(`test_baseline_requirements/${certName}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + gCertDB, + `test_baseline_requirements/${certName}.pem`, + trustString + ); +} + +function checkCertOn25August2016(cert, expectedResult) { + // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000 + const VALIDATION_TIME = 1472083200; + return checkCertErrorGenericAtTime( + gCertDB, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME, + false, + "example.com" + ); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.pki.name_matching_mode"); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); + }); + + Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false); + + loadCertWithTrust("ca", "CTu,,"); + + // When verifying a certificate, if the trust anchor is not a built-in root, + // name matching will fall back to using the subject common name if necessary + // (i.e. if there is no subject alternative name extension or it does not + // contain any dNSName or iPAddress entries). Thus, since imported roots are + // not in general treated as built-ins, these should all successfully verify + // regardless of the value of the pref. + Services.prefs.setIntPref("security.pki.name_matching_mode", 0); + info("current mode: always fall back, root not built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 1); + info( + "current mode: fall back for notBefore < August 23, 2016, root " + + "not built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 2); + info( + "current mode: fall back for notBefore < August 23, 2015, root " + + "not built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 3); + info("current mode: never fall back, root not built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // In debug builds, we can treat an imported root as a built-in, and thus we + // can actually test the different values of the pref. + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + + // Always fall back if necessary. + Services.prefs.setIntPref("security.pki.name_matching_mode", 0); + info("current mode: always fall back, root built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Only fall back if notBefore < 23 August 2016 + Services.prefs.setIntPref("security.pki.name_matching_mode", 1); + info( + "current mode: fall back for notBefore < August 23, 2016, root " + + "built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Only fall back if notBefore < 23 August 2015 + Services.prefs.setIntPref("security.pki.name_matching_mode", 2); + info( + "current mode: fall back for notBefore < August 23, 2015, root " + + "built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Never fall back. + Services.prefs.setIntPref("security.pki.name_matching_mode", 3); + info("current mode: never fall back, root built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + } +}); diff --git a/security/manager/ssl/tests/unit/test_blocklist_onecrl.js b/security/manager/ssl/tests/unit/test_blocklist_onecrl.js new file mode 100644 index 0000000000..388816417a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_blocklist_onecrl.js @@ -0,0 +1,75 @@ +"use strict"; + +do_get_profile(); + +const { Utils } = ChromeUtils.import("resource://services-settings/Utils.jsm"); +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { OneCRLBlocklistClient } = RemoteSecuritySettings.init(); + +const global = this; + +add_task(async function test_uses_a_custom_signer() { + Assert.notEqual( + OneCRLBlocklistClient.signerName, + RemoteSettings("not-specified").signerName + ); +}); + +add_task(async function test_has_initial_dump() { + Assert.ok( + await Utils.hasLocalDump( + OneCRLBlocklistClient.bucketName, + OneCRLBlocklistClient.collectionName + ) + ); +}); + +add_task(async function test_default_jexl_filter_is_used() { + Assert.deepEqual( + OneCRLBlocklistClient.filterFunc, + RemoteSettings("not-specified").filterFunc + ); +}); + +add_task( + async function test_revocations_are_updated_on_sync_with_cert_storage() { + const certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + const has_revocations = () => + new Promise(resolve => { + certList.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_REVOCATION, + (rv, hasPriorData) => { + if (rv == Cr.NS_OK) { + return resolve(hasPriorData); + } + return resolve(false); + } + ); + }); + + Assert.ok(!(await has_revocations())); + + await OneCRLBlocklistClient.emit("sync", { + data: { + current: [], + created: [ + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "a0X7/7DlTaedpgrIJg25iBPOkIM=", + }, + ], + updated: [], + deleted: [], + }, + }); + + Assert.ok(await has_revocations()); + } +); diff --git a/security/manager/ssl/tests/unit/test_blocklist_pinning.js b/security/manager/ssl/tests/unit/test_blocklist_pinning.js new file mode 100644 index 0000000000..87fd836f45 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_blocklist_pinning.js @@ -0,0 +1,127 @@ +"use strict"; + +const { Utils } = ChromeUtils.import("resource://services-settings/Utils.jsm"); +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); + +const sss = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +const { PinningBlocklistClient } = RemoteSecuritySettings.init(); + +add_task(async function test_uses_a_custom_signer() { + Assert.notEqual( + PinningBlocklistClient.signerName, + RemoteSettings("not-specified").signerName + ); +}); + +add_task(async function test_pinning_has_initial_dump() { + if (AppConstants.platform == "android") { + // Skip test: we don't ship pinning dumps on Android (see package-manifest). + return; + } + Assert.ok( + await Utils.hasLocalDump( + PinningBlocklistClient.bucketName, + PinningBlocklistClient.collectionName + ) + ); +}); + +add_task(async function test_default_jexl_filter_is_used() { + Assert.deepEqual( + PinningBlocklistClient.filterFunc, + RemoteSettings("not-specified").filterFunc + ); +}); + +add_task(async function test_no_pins_by_default() { + // ensure our pins are all missing before we start + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://four.example.com"), + 0 + ) + ); + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); +}); + +add_task(async function test_multiple_entries() { + const current = [ + { + pinType: "STSPin", + hostName: "five.example.com", + includeSubdomains: false, + expires: new Date().getTime() + 1000000, + versions: [Services.appinfo.version, "some version that won't match"], + }, + ]; + await PinningBlocklistClient.emit("sync", { data: { current } }); + + // Check that the HSTS preload added to the collection works... + ok( + sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); + // // ...and that includeSubdomains is honored + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://subdomain.five.example.com"), + 0 + ) + ); + + // Overwrite existing entries. + current[current.length - 1].includeSubdomains = true; + await PinningBlocklistClient.emit("sync", { data: { current } }); + // The STS entry for five.example.com now has includeSubdomains set; + // ensure that the new includeSubdomains value is honored. + ok( + sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://subdomain.five.example.com"), + 0 + ) + ); +}); + +add_task(async function test_bad_entries() { + const current = [ + { + pinType: "STSPin", + hostName: "five.example.com", + includeSubdomains: true, + expires: new Date().getTime() + 1000000, + }, // missing versions. + ]; + // The event listener will catch any error, and won't throw. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1554939 + await PinningBlocklistClient.emit("sync", { data: { current } }); + + // Check that the HSTS preload overwrites existing entries... + // Version field is missing. + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); +}); diff --git a/security/manager/ssl/tests/unit/test_broken_fips.js b/security/manager/ssl/tests/unit/test_broken_fips.js new file mode 100644 index 0000000000..964092e2db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_broken_fips.js @@ -0,0 +1,64 @@ +// -*- 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 if Firefox attempts and fails to load a PKCS#11 module DB that was +// in FIPS mode, Firefox can still make use of keys in the key database. +// secomd.db can be created via `certutil -N -d <dir>`. Putting it in FIPS mode +// involves running `modutil -fips true -dbdir <dir>`. key4.db is from +// test_sdr_preexisting/key4.db. + +function run_test() { + // Append a single quote and non-ASCII characters to the profile path. + let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + file.initWithPath(profd); + file.append("'÷1"); + env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + + let profile = do_get_profile(); // must be called before getting nsIX509CertDB + Assert.ok( + /[^\x20-\x7f]/.test(profile.path), + "the profile path should contain a non-ASCII character" + ); + + let keyDBName = "key4.db"; + let keyDBFile = do_get_file(`test_broken_fips/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let pkcs11modDBName = "pkcs11.txt"; + let pkcs11modDBFile = do_get_file(`test_broken_fips/${pkcs11modDBName}`); + pkcs11modDBFile.copyTo(profile, pkcs11modDBName); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + ok(!moduleDB.isFIPSEnabled, "FIPS should not be enabled"); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + const encrypted = + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d"; + const expectedResult = "password"; + let decrypted = sdr.decryptString(encrypted); + equal( + decrypted, + expectedResult, + "decrypted ciphertext should match expected plaintext" + ); + + let pkcs11modDBFileFIPS = do_get_profile(); + pkcs11modDBFileFIPS.append(`${pkcs11modDBName}.fips`); + ok( + pkcs11modDBFileFIPS.exists(), + "backed-up PKCS#11 module db should now exist" + ); +} diff --git a/security/manager/ssl/tests/unit/test_broken_fips/key4.db b/security/manager/ssl/tests/unit/test_broken_fips/key4.db Binary files differnew file mode 100644 index 0000000000..8f320dfdbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_broken_fips/key4.db diff --git a/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt b/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt new file mode 100644 index 0000000000..78a11f5fa7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt @@ -0,0 +1,5 @@ +library= +name=NSS Internal FIPS PKCS #11 Module +parameters=configdir='.' certPrefix='' keyPrefix='' secmod='' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' +NSS=slotParams={0x00000003=[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,SHA256,SHA512,Camellia,SEED,RANDOM ] } Flags=internal,FIPS,critical + diff --git a/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js new file mode 100644 index 0000000000..3bcbc52f2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js @@ -0,0 +1,57 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests exporting a certificate and key as a PKCS#12 blob and importing it +// again with a new password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "黒い"; +const TEST_OUTPUT_PASSWORD = "other password"; + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + // Import the certificate and key so we have something to export. + let cert = findCertByCommonName(CERT_COMMON_NAME); + equal(cert, null, "cert should not be found before import"); + let certFile = do_get_file(PKCS12_FILE); + ok(certFile, `${PKCS12_FILE} should exist`); + let errorCode = gCertDB.importPKCS12File(certFile, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be imported"); + cert = findCertByCommonName(CERT_COMMON_NAME); + notEqual(cert, null, "cert should be found now"); + + // Export the certificate and key. + let output = do_get_tempdir(); + output.append("output.p12"); + ok(!output.exists(), "output shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be exported"); + ok(output.exists(), "output should exist after exporting PKCS12 file"); + + // We should be able to import the exported blob again using the new password. + errorCode = gCertDB.importPKCS12File(output, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be imported"); + output.remove(false /* not a directory; recursive doesn't apply */); + + // Ideally there would be some way to confirm that this actually did anything. + // Unfortunately, since deleting a certificate currently doesn't actually do + // anything until the platform is restarted, we can't confirm that we + // successfully re-imported the certificate. +} diff --git a/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js new file mode 100644 index 0000000000..598d159c95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests exporting a certificate and key as a PKCS#12 blob if the user has a +// master password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "黒い"; + +var gPrompt = { + password: "password", + clickOk: true, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gPrompt| due to + // how objects get wrapped when going across xpcom boundaries. + alert(title, text) { + info(`alert('${text}')`); + ok(false, "not expecting alert() to be called"); + }, + + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + password.value = this.password; + return this.clickOk; + }, +}; + +const gPromptFactory = { + QueryInterface: ChromeUtils.generateQI(["nsIPromptFactory"]), + getPrompt: (aWindow, aIID) => gPrompt, +}; + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + let promptFactoryCID = MockRegistrar.register( + "@mozilla.org/prompter;1", + gPromptFactory + ); + + registerCleanupFunction(() => { + MockRegistrar.unregister(promptFactoryCID); + }); + + // Set a master password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + // Import the certificate and key so we have something to export. + let cert = findCertByCommonName(CERT_COMMON_NAME); + equal(cert, null, "cert should not be found before import"); + let certFile = do_get_file(PKCS12_FILE); + ok(certFile, `${PKCS12_FILE} should exist`); + let errorCode = gCertDB.importPKCS12File(certFile, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should import"); + cert = findCertByCommonName(CERT_COMMON_NAME); + notEqual(cert, null, "cert should be found now"); + + // Log out so we're prompted for the password. + token.logoutSimple(); + + // Export the certificate and key (and don't cancel the password request + // dialog). + let output = do_get_tempdir(); + output.append("output.p12"); + ok(!output.exists(), "output shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should export"); + ok(output.exists(), "output should exist after exporting PKCS12 file"); + output.remove(false /* not a directory; recursive doesn't apply */); + + // Log out again so we're prompted for the password. + token.logoutSimple(); + + // Attempt to export the certificate and key, but this time cancel the + // password request dialog. The export operation should also be canceled. + gPrompt.clickOk = false; + let output2 = do_get_tempdir(); + output2.append("output2.p12"); + ok(!output2.exists(), "output2 shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal( + errorCode, + Ci.nsIX509CertDB.ERROR_PKCS12_BACKUP_FAILED, + "cert should not export" + ); + + ok(!output2.exists(), "output2 shouldn't exist after failing to export"); +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import.js b/security/manager/ssl/tests/unit/test_certDB_import.js new file mode 100644 index 0000000000..76bf968970 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import.js @@ -0,0 +1,217 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the various nsIX509CertDB import methods. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const CA_CERT_COMMON_NAME = "importedCA"; +const TEST_EMAIL_ADDRESS = "test@example.com"; + +let gCACertImportDialogCount = 0; + +// Mock implementation of nsICertificateDialogs. +const gCertificateDialogs = { + confirmDownloadCACert: (ctx, cert, trust) => { + gCACertImportDialogCount++; + equal( + cert.commonName, + CA_CERT_COMMON_NAME, + "CA cert to import should have the correct CN" + ); + trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL; + return true; + }, + setPKCS12FilePassword: (ctx, password) => { + // This is only relevant to exporting. + ok(false, "setPKCS12FilePassword() should not have been called"); + }, + getPKCS12FilePassword: (ctx, password) => { + // We don't test anything that calls this method yet. + ok(false, "getPKCS12FilePassword() should not have been called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]), +}; + +// Implements nsIInterfaceRequestor. Mostly serves to mock nsIPrompt. +const gInterfaceRequestor = { + alert: (title, text) => { + // We don't test anything that calls this method yet. + ok(false, `alert() should not have been called: ${text}`); + }, + + getInterface: iid => { + if (iid.equals(Ci.nsIPrompt)) { + return this; + } + + throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); + }, +}; + +function getCertAsByteArray(certPath) { + let certFile = do_get_file(certPath, false); + let certBytes = readFile(certFile); + + let byteArray = []; + for (let i = 0; i < certBytes.length; i++) { + byteArray.push(certBytes.charCodeAt(i)); + } + + return byteArray; +} + +function commonFindCertBy(propertyName, value) { + for (let cert of gCertDB.getCerts()) { + if (cert[propertyName] == value) { + return cert; + } + } + return null; +} + +function findCertByCommonName(commonName) { + return commonFindCertBy("commonName", commonName); +} + +function findCertByEmailAddress(emailAddress) { + return commonFindCertBy("emailAddress", emailAddress); +} + +function testImportCACert() { + // Sanity check the CA cert is missing. + equal( + findCertByCommonName(CA_CERT_COMMON_NAME), + null, + "CA cert should not be in the database before import" + ); + + // Import and check for success. + let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem"); + gCertDB.importCertificates( + caArray, + caArray.length, + Ci.nsIX509Cert.CA_CERT, + gInterfaceRequestor + ); + equal( + gCACertImportDialogCount, + 1, + "Confirmation dialog for the CA cert should only be shown once" + ); + + let caCert = findCertByCommonName(CA_CERT_COMMON_NAME); + notEqual(caCert, null, "CA cert should now be found in the database"); + ok( + gCertDB.isCertTrusted( + caCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "CA cert should be trusted for e-mail" + ); +} + +function testImportEmptyCertPackage() { + // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. + let byteArray = [ + 0x30, + 0x0f, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + 0x05, + 0xa0, + 0x02, + 0x30, + 0x00, + ]; + gCertDB.importCertificates( + byteArray, + byteArray.length, + Ci.nsIX509Cert.CA_CERT, + gInterfaceRequestor + ); +} + +function testImportEmptyUserCert() { + // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. + let byteArray = [ + 0x30, + 0x0f, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + 0x05, + 0xa0, + 0x02, + 0x30, + 0x00, + ]; + gCertDB.importUserCertificate( + byteArray, + byteArray.length, + gInterfaceRequestor + ); +} + +function run_test() { + let certificateDialogsCID = MockRegistrar.register( + "@mozilla.org/nsCertificateDialogs;1", + gCertificateDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(certificateDialogsCID); + }); + + // Sanity check the e-mail cert is missing. + equal( + findCertByEmailAddress(TEST_EMAIL_ADDRESS), + null, + "E-mail cert should not be in the database before import" + ); + + // Import the CA cert so that the e-mail import succeeds. + testImportCACert(); + testImportEmptyCertPackage(); + testImportEmptyUserCert(); + + // Import the e-mail cert and check for success. + let emailArray = getCertAsByteArray("test_certDB_import/emailEE.pem"); + gCertDB.importEmailCertificate( + emailArray, + emailArray.length, + gInterfaceRequestor + ); + let emailCert = findCertByEmailAddress(TEST_EMAIL_ADDRESS); + notEqual(emailCert, null, "E-mail cert should now be found in the database"); + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + equal( + emailCert.tokenName, + bundle.GetStringFromName("PrivateTokenDescription"), + "cert's tokenName should be the expected localized value" + ); +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx Binary files differnew file mode 100644 index 0000000000..e969d672d7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx Binary files differnew file mode 100644 index 0000000000..879d424b85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx Binary files differnew file mode 100644 index 0000000000..7dcd668121 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx diff --git a/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem new file mode 100644 index 0000000000..136356c362 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUZ0427vGPMGf5dB3ZIhW8mkoNr04wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKaW1wb3J0ZWRDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29t +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBi4qlU7QLKNNAFYso7DWFZzptHNiR5 +5oOGSbUPu8pvi8YoJbyzefH7A9kiIyvdZNkBKPUZTwwFWKM+QwmZVrH8e7G3zI/G +447HiUQ4VNeeAYkT3K126nxEhVsk/gWPfv7qv3jUQcii/3PlUhHNqVRZNcEe/u4D +zwWp/j56ydzmQoWwBN/pal//uQOjum9PPpk+V1RYCDtekOHwOHQsuhKXTscMcamy +SJmG06/O3JF8yhjq03X1cHtj3YF2PH0fTCcgZMv/3GY34kZ61A4VJWUWRZFoCujy +Fx8jMEoMvJt/oIBggNJsDCBP9ksesfA5ImOqI5hziqo52oHG0Z9+0f1D +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec new file mode 100644 index 0000000000..0528bc624a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec @@ -0,0 +1,2 @@ +issuer:importedCA +subject:/emailAddress=test@example.com diff --git a/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem new file mode 100644 index 0000000000..6c8ab901ae --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICzDCCAbSgAwIBAgIUUQGnWi0czVZBST5XDA1wp0G74kowDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKaW1wb3J0ZWRDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDAppbXBvcnRlZENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAM +BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCkMue2IDPldrL6f/ox5CoU +RPLnEPQyUDYIz4eFdAS/PX2A1/KEvYthVuVNbGZ1r5/3htt4cOKJCUYI/LWKc4eB +6gC9uhcC6JBqRfsQB4zK9RZu860shuNPGuEWA1KYgy1bzi8iJ2kTaHO0y3yXL+ow +guKrFJTK5NWPnxWQsdLE5lA9p67bNHjWxDzRHkDqeyIPiG/zmrudprxWXHk+EQgx +1hKN0rTaSAZnCyeik11i7MCyAnvrAk0mr9j8jX1+yf5mbFeKk0XcjSRmzoAQZBSA +9br5LUP1CvN2DbphDK1jkgP2Dx0dBuQH4HZBbY6lcKGfi4mdiJUkwiwqp346q7vo +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec new file mode 100644 index 0000000000..b168253544 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec @@ -0,0 +1,3 @@ +issuer:importedCA +subject:importedCA +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_certDB_import/moz.build b/security/manager/ssl/tests/unit/test_certDB_import/moz.build new file mode 100644 index 0000000000..dfc75de914 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See Bug 1256495. +# test_certificates = ( +# 'emailEE.pem', +# 'importedCA.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js b/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js new file mode 100644 index 0000000000..a295d424ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests import PKCS12 file by nsIX509CertDB. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const PKCS12_FILE_EMPTY_PASS = + "test_certDB_import/cert_from_windows_emptypass.pfx"; +const PKCS12_FILE_NO_PASS = "test_certDB_import/cert_from_windows_nopass.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "黒い"; + +// Has getPKCS12FilePassword been called since we last reset this? +let gGetPKCS12FilePasswordCalled = false; +let gCurrentTestcase = null; + +let gTestcases = [ + // Test that importing a PKCS12 file with the wrong password fails. + { + name: "import using incorrect password", + filename: PKCS12_FILE, + passwordToUse: "this is the wrong password", + successExpected: false, + errorCode: Ci.nsIX509CertDB.ERROR_BAD_PASSWORD, + checkCertExist: true, + }, + // Test that importing something that isn't a PKCS12 file fails. + { + name: "import non-PKCS12 file", + filename: "test_certDB_import_pkcs12.js", + passwordToUse: TEST_CERT_PASSWORD, + successExpected: false, + errorCode: Ci.nsIX509CertDB.ERROR_DECODE_ERROR, + checkCertExist: true, + }, + // Test that importing a PKCS12 file with the correct password succeeds. + // This needs to be last because currently there isn't a way to delete the + // imported certificate (and thus reset the test state) that doesn't depend on + // the garbage collector running. + { + name: "import PKCS12 file", + filename: PKCS12_FILE, + passwordToUse: TEST_CERT_PASSWORD, + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: true, + }, + // Same cert file protected with empty string password + { + name: "import PKCS12 file empty password", + filename: PKCS12_FILE_EMPTY_PASS, + passwordToUse: "", + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: false, + }, + // Same cert file protected with no password + { + name: "import PKCS12 file no password", + filename: PKCS12_FILE_NO_PASS, + passwordToUse: null, + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: false, + }, +]; + +function doesCertExist(commonName) { + let allCerts = gCertDB.getCerts(); + for (let cert of allCerts) { + if (cert.isBuiltInRoot) { + continue; + } + if (cert.commonName == commonName) { + return true; + } + } + + return false; +} + +function runOneTestcase(testcase) { + info(`running ${testcase.name}`); + if (testcase.checkCertExist) { + ok( + !doesCertExist(CERT_COMMON_NAME), + "cert should not be in the database before import" + ); + } + + // Import and check for failure. + let certFile = do_get_file(testcase.filename); + ok(certFile, `${testcase.filename} should exist`); + gGetPKCS12FilePasswordCalled = false; + gCurrentTestcase = testcase; + let errorCode = gCertDB.importPKCS12File(certFile, testcase.passwordToUse); + equal(errorCode, testcase.errorCode, `verifying error code`); + equal( + doesCertExist(CERT_COMMON_NAME), + testcase.successExpected, + `cert should${testcase.successExpected ? "" : " not"} be found now` + ); +} + +function run_test() { + for (let testcase of gTestcases) { + runOneTestcase(testcase); + } +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js b/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js new file mode 100644 index 0000000000..e31dc605b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js @@ -0,0 +1,148 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that a CA certificate can still be imported if the user has a master +// password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const CA_CERT_COMMON_NAME = "importedCA"; + +let gCACertImportDialogCount = 0; + +// Mock implementation of nsICertificateDialogs. +const gCertificateDialogs = { + confirmDownloadCACert: (ctx, cert, trust) => { + gCACertImportDialogCount++; + equal( + cert.commonName, + CA_CERT_COMMON_NAME, + "CA cert to import should have the correct CN" + ); + trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL; + return true; + }, + setPKCS12FilePassword: (ctx, password) => { + // This is only relevant to exporting. + ok(false, "setPKCS12FilePassword() should not have been called"); + }, + getPKCS12FilePassword: (ctx, password) => { + // We don't test anything that calls this method yet. + ok(false, "getPKCS12FilePassword() should not have been called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]), +}; + +var gMockPrompter = { + passwordToTry: "password", + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), + + // Again with the arrow function issue. + getInterface(iid) { + if (iid.equals(Ci.nsIPrompt)) { + return this; + } + + throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); + }, +}; + +function getCertAsByteArray(certPath) { + let certFile = do_get_file(certPath, false); + let certBytes = readFile(certFile); + + let byteArray = []; + for (let i = 0; i < certBytes.length; i++) { + byteArray.push(certBytes.charCodeAt(i)); + } + + return byteArray; +} + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + let certificateDialogsCID = MockRegistrar.register( + "@mozilla.org/nsCertificateDialogs;1", + gCertificateDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(certificateDialogsCID); + }); + + // Set a master password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + // Sanity check the CA cert is missing. + equal( + findCertByCommonName(CA_CERT_COMMON_NAME), + null, + "CA cert should not be in the database before import" + ); + + // Import and check for success. + let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem"); + gCertDB.importCertificates( + caArray, + caArray.length, + Ci.nsIX509Cert.CA_CERT, + gMockPrompter + ); + equal( + gCACertImportDialogCount, + 1, + "Confirmation dialog for the CA cert should only be shown once" + ); + + let caCert = findCertByCommonName(CA_CERT_COMMON_NAME); + notEqual(caCert, null, "CA cert should now be found in the database"); + ok( + gCertDB.isCertTrusted( + caCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "CA cert should be trusted for e-mail" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_chains.js b/security/manager/ssl/tests/unit/test_cert_chains.js new file mode 100644 index 0000000000..56c68a049a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_chains.js @@ -0,0 +1,814 @@ +// -*- 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 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" + ); +} + +// We hard-code the following certificates for the pkcs7 export tests so that we +// don't have to change the test data when the certificates change each year. +// Luckily these tests don't depend on the certificates being valid, so it's ok +// to let them expire. +const gDefaultEEPEM = `-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaob +K2YRb4OGMxySIKuQ80N0XlO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4s +v0swx/+oUxCfLb0VIl/kdUqLkbGYrAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU ++aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGMyG/pwas+JXehbReUf4n1ewk84ADtb ++ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41sQnNqPg12x4+WGWiAsWCpR +/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16IjWEukvJuU1W +-----END CERTIFICATE-----`; + +const gExpiredEEPEM = `-----BEGIN CERTIFICATE----- +MIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyBggrBgEF +BQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ +KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzf +T+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5h +mu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3 +L9zJ2JqNc60+hB8l297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74V +kQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZ +gBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7I= +-----END CERTIFICATE-----`; + +const gTestCAPEM = `-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUKaFwIwCwHXUgKRuOhAX4pjYsmbgwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIMgnywHFbPzJ +BEcbpx/aWQOI2tUFlo7MUoPSoACHzoI/HOUTx25eKHlpNK2jSljLufhUd//eCCXg ++OQt4f2N/tRw8gumbs3YDF7+t3ZNGt+iQxZTwN7MKsGIZy+6R523XHw8lpzFX5iz +XgIS+0APlX+XyZk7MRCcBWh6PSaSqEOOvUXVp6Omh3it034kBWnm809TEWmwiVw3 +ssPDmpUCArdDNMMdvQehzaH96cdjcSsguqpX9NcMDUmmiG7HLQ2iy+WSzek9S46S +bKKDLw8Ebevfkl6PEpg+GDulq+EPXayN3AsFXkF8MaFLgfeprkENjN1g4jM+WSyN +6DC7vCkj7A== +-----END CERTIFICATE-----`; + +const gUnknownIssuerPEM = ` +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUMRiJ9TrwqTOoVFU+j5FDWDWS1X8wDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbVGVzdCBJbnRlcm1lZGlhdGUgdG8gZGVsZXRlMCIYDzIw +MTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMC4xLDAqBgNVBAMMI1Rlc3Qg +RW5kLWVudGl0eSBmcm9tIHVua25vd24gaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HCMIG/MIGIBgNV +HREEgYAwfoIZdW5rbm93bmlzc3Vlci5leGFtcGxlLmNvbYI0dW5rbm93bmlzc3Vl +ci5pbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbYIrdW5rbm93 +bmlzc3Vlci50ZXN0LW1vZGUucGlubmluZy5leGFtcGxlLmNvbTAyBggrBgEFBQcB +AQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZI +hvcNAQELBQADggEBALAnJjBJ+MOc7kMRzmESYZRSxKak7A1K67xBXWzWmK3t3WXv +e/RLjV/RhbyTN20h2ZjSVcuDzgNYC/RJ/z3Xd5Q9QEGoi1ly84HeaeHw/3kUSHxv +J3JnbPu2lk96U5y7tXEVfbEVZYpx4Us72fuURPWriVldILH2lgrEg+iKZWbY/wcT +vfu1j/flMkGEOpc1HytlmR9fkCDnqzFfcmv7Eh3X1BiSBOIemGnUHxONwlthSE68 +IItE5l3c82G8oQGmve6r0N9h7t6opIjH1koFWMck/pzDA01FmWey4ASdlmjE8NSJ +Al1zsF8EiLOZeI1rvurcXwVOd0Olk9/QT5hwTkk= +-----END CERTIFICATE-----`; + +const gOCSPEEWithIntermediatePEM = ` +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUZ67hS7lHVnCQtXx7oXFlzihqh0cwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxNzExMjcwMDAw +MDBaGA8yMDIwMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhVGVzdCBFbmQtZW50aXR5 +IHdpdGggSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAagglsb2NhbGhv +c3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo +dHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQAo043hM4Gi +UtoXKOQB2v0C8nF4Yyzpf+i0LlxQCFZkiLYu9pIuQu16I3TbLQRBwhCC0ml7TqJB +AbryzILTorCQP8A1WQa1kt6cb30jCyXLcWnDA/ULPexn9cYm6I0YyLFlnkcVzMGL +Fc+LyWTAPEW5rMauu5iOOp/6L5rBF0M9bg5yXSGNDv8gk3Jc+opJbBDTrAuKDNLp +JSEp4rqovNFnirzlJWDS+ScAsWHtoLcrH6gnQRPsEV1WFQnYr3HkAakYQok9xs5A +ikBS6mgz4/cFBts8bSGSuXxctkN2Ss7Y5l3YmTYKCxPz6retVfrhi/islH4W3z9H +pu3ZqyACO6Lb +-----END CERTIFICATE-----`; + +const gTestIntPEM = ` +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE-----`; + +function build_cert_list_from_pem_list(pemList) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let certList = []; + for (let pem of pemList) { + let cert = certdb.constructX509FromBase64(pemToBase64(pem)); + certList.push(cert); + } + return certList; +} + +function test_cert_pkcs7_export() { + // This was generated by running BadCertAndPinningServer locally on the bad_certs + // directory and visiting: + // https://good.include-subdomains.pinning.example.com:8443/ + // and then viewing the certificate chain presented (in the page info dialog) + // and exporting it. + // (NB: test-ca must be imported and trusted for the connection to succeed) + const expectedPKCS7ForDefaultEE = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCBmQwggLTMIIBu6ADAgE" + + "CAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZX" + + "N0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB" + + "1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI" + + "BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xz" + + "VJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCy" + + "uwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW" + + "7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE" + + "LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8" + + "wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1Q" + + "WWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMX" + + "v63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKo" + + "Q469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf" + + "01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoU" + + "uB96muQQ2M3WDiMz5ZLI3oMLu8KSPsMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6T" + + "IyPRSIwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAw" + + "MDAwMFoYDzIwMjAwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggE" + + "iMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNU" + + "q07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0" + + "DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ" + + "sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJH" + + "dtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFz" + + "G4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob" + + "3N0gg0qLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1z" + + "dWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnB" + + "pbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi" + + "8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvl" + + "aobK2YRb4OGMxySIKuQ80N0XlO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0sw" + + "x/+oUxCfLb0VIl/kdUqLkbGYrAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j" + + "3rXoimcdo6X3TK1SN2/64fGMyG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t" + + "/UgqDsnTWq5wUc5IJKwoHT41sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9W" + + "tZYAvwT78a2xpHp5XNglj16IjWEukvJuU1WMQAAAAAAAAA="; + let certListDefaultEE = build_cert_list_from_pem_list([ + gDefaultEEPEM, + gTestCAPEM, + ]); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let pkcs7DefaultEE = certdb.asPKCS7Blob(certListDefaultEE); + + equal( + btoa(pkcs7DefaultEE), + expectedPKCS7ForDefaultEE, + "PKCS7 export should work as expected for default-ee chain" + ); + + // This was generated by running BadCertAndPinningServer locally on the bad_certs + // directory and visiting: + // https://unknownissuer.example.com:8443/ + // and then viewing the certificate presented (in the add certificate + // exception dialog) and exporting it. + const expectedPKCS7ForUnknownIssuer = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCA60wggOpMIICkaADAgE" + + "CAhQxGIn1OvCpM6hUVT6PkUNYNZLVfzANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtUZX" + + "N0IEludGVybWVkaWF0ZSB0byBkZWxldGUwIhgPMjAxNzExMjcwMDAwMDBaGA8yMDIwMDIwN" + + "TAwMDAwMFowLjEsMCoGA1UEAwwjVGVzdCBFbmQtZW50aXR5IGZyb20gdW5rbm93biBpc3N1" + + "ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTw" + + "T2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs" + + "1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkf" + + "bmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA" + + "dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/" + + "l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcIwgb8wgYgGA1UdEQSBgDB+ghl1bm" + + "tub3duaXNzdWVyLmV4YW1wbGUuY29tgjR1bmtub3duaXNzdWVyLmluY2x1ZGUtc3ViZG9tY" + + "Wlucy5waW5uaW5nLmV4YW1wbGUuY29tgit1bmtub3duaXNzdWVyLnRlc3QtbW9kZS5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAsCcmMEn4w5zuQxHOYRJhlFLEpq" + + "TsDUrrvEFdbNaYre3dZe979EuNX9GFvJM3bSHZmNJVy4POA1gL9En/Pdd3lD1AQaiLWXLzg" + + "d5p4fD/eRRIfG8ncmds+7aWT3pTnLu1cRV9sRVlinHhSzvZ+5RE9auJWV0gsfaWCsSD6Ipl" + + "Ztj/BxO9+7WP9+UyQYQ6lzUfK2WZH1+QIOerMV9ya/sSHdfUGJIE4h6YadQfE43CW2FITrw" + + "gi0TmXdzzYbyhAaa97qvQ32Hu3qikiMfWSgVYxyT+nMMDTUWZZ7LgBJ2WaMTw1IkCXXOwXw" + + "SIs5l4jWu+6txfBU53Q6WT39BPmHBOSTEAAAAAAAAA"; + let certListUnknownIssuer = build_cert_list_from_pem_list([ + gUnknownIssuerPEM, + ]); + let pkcs7UnknownIssuer = certdb.asPKCS7Blob(certListUnknownIssuer); + equal( + btoa(pkcs7UnknownIssuer), + expectedPKCS7ForUnknownIssuer, + "PKCS7 export should work as expected for unknown issuer" + ); + + // This was generated by running OCSPStaplingServer locally on the ocsp_certs + // directory and visiting: + // https://ocsp-stapling-with-intermediate.example.com:8443/ + // and then viewing the certificate chain presented (in the page info dialog) + // and exporting it. + // (NB: test-ca must be imported and trusted for the connection to succeed) + const expectedPKCS7WithIntermediate = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCCPEwggLTMIIBu6ADAgE" + + "CAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZX" + + "N0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB" + + "1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI" + + "BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xz" + + "VJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCy" + + "uwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW" + + "7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE" + + "LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8" + + "wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1Q" + + "WWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMX" + + "v63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKo" + + "Q469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf" + + "01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoU" + + "uB96muQQ2M3WDiMz5ZLI3oMLu8KSPsMIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25i" + + "BPOkIMwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAw" + + "MDAwMFoYDzIwMjUwMTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTC" + + "CASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6u" + + "Q1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8H" + + "mnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh" + + "eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaM" + + "Mkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5" + + "kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EB" + + "AMCAQYwDQYJKoZIhvcNAQELBQADggEBAILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC" + + "2BQF0kMEEB547p+Ms8zdJY00Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77Tk" + + "fmnSnxvPi+0nlA+eM8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22" + + "+AIU7w6wyAIbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubji" + + "Mr3B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpykrGFL" + + "vocT/kym6r8galxCJUowggM1MIICHaADAgECAhRnruFLuUdWcJC1fHuhcWXOKGqHRzANBgk" + + "qhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTAiGA8yMDE3MTEyNz" + + "AwMDAwMFoYDzIwMjAwMjA1MDAwMDAwWjAsMSowKAYDVQQDDCFUZXN0IEVuZC1lbnRpdHkgd" + + "2l0aCBJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo" + + "RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHE" + + "IeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7q" + + "dw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCAB" + + "iTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjWzBZMCMGA1U" + + "dEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKw" + + "YBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBACjTj" + + "eEzgaJS2hco5AHa/QLycXhjLOl/6LQuXFAIVmSIti72ki5C7XojdNstBEHCEILSaXtOokEB" + + "uvLMgtOisJA/wDVZBrWS3pxvfSMLJctxacMD9Qs97Gf1xibojRjIsWWeRxXMwYsVz4vJZMA" + + "8Rbmsxq67mI46n/ovmsEXQz1uDnJdIY0O/yCTclz6iklsENOsC4oM0uklISniuqi80WeKvO" + + "UlYNL5JwCxYe2gtysfqCdBE+wRXVYVCdivceQBqRhCiT3GzkCKQFLqaDPj9wUG2zxtIZK5f" + + "Fy2Q3ZKztjmXdiZNgoLE/Pqt61V+uGL+KyUfhbfP0em7dmrIAI7otsxAAAAAAAAAA=="; + let certListWithIntermediate = build_cert_list_from_pem_list([ + gOCSPEEWithIntermediatePEM, + gTestIntPEM, + gTestCAPEM, + ]); + let pkcs7WithIntermediate = certdb.asPKCS7Blob(certListWithIntermediate); + equal( + btoa(pkcs7WithIntermediate), + expectedPKCS7WithIntermediate, + "PKCS7 export should work as expected for chain with intermediate" + ); +} + +function test_cert_pkcs7_empty_array() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + throws( + () => certdb.asPKCS7Blob([]), + /NS_ERROR_ILLEGAL_VALUE/, + "trying to convert an empty array to pkcs7 should throw" + ); +} + +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" + ); +} + +// In Bug 1580315, nsNSSCertList/nsIX509CertList was replaced by +// Array<nsIX509Cert>, so the serialization of the certList changed. This +// test is used to make sure we can still deserialize the transportSecurityInfo +// binary string which has the old certList binary. +function test_old_succeeded_certlist_deseralization_v1() { + // This was the serialized output of test "good.include-subdomains.pinning.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + // The serialized output was generated before we replace nsIX509CertList with + // Array<nsIX509Cert>, so it had the old version of transportSecurityInfo. + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAAAgA" + + "AAAAAAAAAAAAAAAAAAAEAMQFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAONMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAwMjA1MDAw" + + "MDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4I" + + "BDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZ" + + "wGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tF" + + "YIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n" + + "FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN" + + "7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe" + + "2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tg" + + "hUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu" + + "ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20" + + "wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA" + + "0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaobK2YRb4OGMxySIKuQ80N0X" + + "lO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0swx/+oUxCfLb0VIl/kdUqLkbGY" + + "rAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGM" + + "yG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41" + + "sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16I" + + "jWEukvJuU1WwC8AAwAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+x" + + "ZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgAAAACZgoyJpFcT/u7IImFpjLfBb3Dl5p" + + "UIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFA1KP/RtK8+3yYlk8NIWOkyMj0" + + "UiMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNzExMjcwMDAwM" + + "DBaGA8yMDIwMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjAN" + + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz" + + "1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4IC" + + "mTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXk" + + "D3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK" + + "9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP" + + "+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdI" + + "INKi5leGFtcGxlLmNvbYIVKi5waW5uaW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZ" + + "G9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEApILjYTMlQmIcmF3xNtsDb5WqGy" + + "tmEW+DhjMckiCrkPNDdF5TvsaSyU7PWMxVWNfiUxzXs9UH8D/SiXmc5081cy4eLL9LMMf/q" + + "FMQny29FSJf5HVKi5GxmKwJrY3jimS2qlbUR9AZ5mz6MC2pNaYup0GDlPmi/UDrr0/49616" + + "IpnHaOl90ytUjdv+uHxjMhv6cGrPiV3oW0XlH+J9XsJPOAA7W/nsPLUQCn/7scylI+bf1IK" + + "g7J01qucFHOSCSsKB0+NbEJzaj4NdsePlhlogLFgqUf4SmBxRq+62+CUxhDwCaVnL/VrWWA" + + "L8E+/GtsaR6eVzYJY9eiI1hLpLyblNVmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtul" + + "uqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG" + + "9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDA" + + "yMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDw" + + "AwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm" + + "24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP" + + "8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFth" + + "Vt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7Ly" + + "JvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NA" + + "gMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB" + + "AQAgyCfLAcVs/MkERxunH9pZA4ja1QWWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR" + + "3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmL" + + "NeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8Oal" + + "QICt0M0wx29B6HNof3px2NxKyC6qlf01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+S" + + "Xo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB96muQQ2M3WDiMz5ZLI3oMLu8KSPsAA=="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.failedCertChain.length, + 0, + "failedCertChain for a successful connection should be empty" + ); + let certChain = build_cert_list_from_pem_list([gDefaultEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.succeededCertChain), + "succeededCertChain should be deserialized correctly" + ); +} + +// Same as the above test, however, this is the v2 version of the +// serialization. +function test_old_succeeded_certlist_deseralization_v2() { + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAAAgA" + + "AAAAAAAAAAAAAAAAAAAEAMgFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAONMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAwMjA1MDAw" + + "MDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4I" + + "BDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZ" + + "wGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tF" + + "YIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n" + + "FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN" + + "7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe" + + "2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tg" + + "hUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu" + + "ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20" + + "wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA" + + "0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaobK2YRb4OGMxySIKuQ80N0X" + + "lO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0swx/+oUxCfLb0VIl/kdUqLkbGY" + + "rAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGM" + + "yG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41" + + "sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16I" + + "jWEukvJuU1WEwEABAAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+x" + + "ZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgAAAACZgoyJpFcT/u7IImFpjLfBb3Dl5p" + + "UIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFA1KP/RtK8+3yYlk8NIWOkyMj0" + + "UiMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNzExMjcwMDAwM" + + "DBaGA8yMDIwMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjAN" + + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz" + + "1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4IC" + + "mTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXk" + + "D3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK" + + "9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP" + + "+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdI" + + "INKi5leGFtcGxlLmNvbYIVKi5waW5uaW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZ" + + "G9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEApILjYTMlQmIcmF3xNtsDb5WqGy" + + "tmEW+DhjMckiCrkPNDdF5TvsaSyU7PWMxVWNfiUxzXs9UH8D/SiXmc5081cy4eLL9LMMf/q" + + "FMQny29FSJf5HVKi5GxmKwJrY3jimS2qlbUR9AZ5mz6MC2pNaYup0GDlPmi/UDrr0/49616" + + "IpnHaOl90ytUjdv+uHxjMhv6cGrPiV3oW0XlH+J9XsJPOAA7W/nsPLUQCn/7scylI+bf1IK" + + "g7J01qucFHOSCSsKB0+NbEJzaj4NdsePlhlogLFgqUf4SmBxRq+62+CUxhDwCaVnL/VrWWA" + + "L8E+/GtsaR6eVzYJY9eiI1hLpLyblNVmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtul" + + "uqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG" + + "9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDA" + + "yMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDw" + + "AwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm" + + "24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP" + + "8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFth" + + "Vt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7Ly" + + "JvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NA" + + "gMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB" + + "AQAgyCfLAcVs/MkERxunH9pZA4ja1QWWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR" + + "3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmL" + + "NeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8Oal" + + "QICt0M0wx29B6HNof3px2NxKyC6qlf01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+S" + + "Xo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB96muQQ2M3WDiMz5ZLI3oMLu8KSPsAAA="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.failedCertChain.length, + [], + "failedCertChain for a successful connection should be empty" + ); + let certChain = build_cert_list_from_pem_list([gDefaultEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.succeededCertChain), + "succeededCertChain should be deserialized correctly" + ); +} + +// In Bug 1580315, nsNSSCertList/nsIX509CertList was replaced by +// Array<nsIX509Cert>, so the serialization of the certList changed. This +// test is used to make sure we can still deserialize the TransportSecurityInfo +// binary string which has the old certList binary. +function test_old_failed_certlist_deseralization_v1() { + // This was the serialized output of test "expired.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + // The serialized output was generated before we replace nsIX509CertList with + // Array<nsIX509Cert>, so it had the old version of transportSecurityInfo. + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAA" + + "AAAAAAAAA///gCwAAAAEAMQFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAMgMIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQwMTAxMDAw" + + "MDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvc" + + "NAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wc" + + "clqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk2" + + "7lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI" + + "H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wn" + + "vuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxD" + + "HVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyB" + + "ggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ" + + "KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WV" + + "sxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQ" + + "DWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l297Za" + + "Sl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYn" + + "q8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFw" + + "WwtnoK7IAAAAAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vYkTvlMZeudM2lzS9HP5" + + "b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwg" + + "gMcMIICBKADAgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAw" + + "DgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAxMDEwMDAwMDBaMCI" + + "xIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAA" + + "OCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngfv" + + "bGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO" + + "7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEP" + + "vJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naO" + + "Gzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYC" + + "jXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUF" + + "BwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0" + + "BAQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF" + + "0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrK" + + "f/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSdsp99" + + "vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag" + + "7gO5iubzT+npsw7qVoHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsm" + + "YKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECA" + + "hQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0" + + "IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1R" + + "lc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBj" + + "YQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJ" + + "JwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw" + + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7f" + + "ilhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL" + + "8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wC" + + "wYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1QWW" + + "jsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv6" + + "3dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ4" + + "69RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf01" + + "wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB" + + "96muQQ2M3WDiMz5ZLI3oMLu8KSPs"; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.succeededCertChain.length, + 0, + "succeededCertChain should be empty" + ); + let certChain = build_cert_list_from_pem_list([gExpiredEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.failedCertChain), + "failedCertChain should be deserialized correctly" + ); +} + +// Same as the above test, however, this is the v2 version of the +// serialization. +function test_old_failed_certlist_deseralization_v2() { + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAA" + + "AAAAAAAAA///gCwAAAAEAMgFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAMgMIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQwMTAxMDAw" + + "MDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvc" + + "NAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wc" + + "clqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk2" + + "7lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI" + + "H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wn" + + "vuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxD" + + "HVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyB" + + "ggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ" + + "KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WV" + + "sxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQ" + + "DWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l297Za" + + "Sl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYn" + + "q8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFw" + + "WwtnoK7IAAAAAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vYkTvlMZeudM2lzS9HP5" + + "b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwg" + + "gMcMIICBKADAgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAw" + + "DgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAxMDEwMDAwMDBaMCI" + + "xIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAA" + + "OCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngfv" + + "bGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO" + + "7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEP" + + "vJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naO" + + "Gzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYC" + + "jXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUF" + + "BwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0" + + "BAQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF" + + "0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrK" + + "f/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSdsp99" + + "vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag" + + "7gO5iubzT+npsw7qVoHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsm" + + "YKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECA" + + "hQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0" + + "IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1R" + + "lc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBj" + + "YQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJ" + + "JwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw" + + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7f" + + "ilhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL" + + "8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wC" + + "wYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1QWW" + + "jsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv6" + + "3dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ4" + + "69RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf01" + + "wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB" + + "96muQQ2M3WDiMz5ZLI3oMLu8KSPsAA=="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + let certChain = build_cert_list_from_pem_list([gExpiredEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.failedCertChain), + "failedCertChain should be deserialized correctly" + ); +} +function run_test() { + do_get_profile(); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + // Test nsIX509Cert.equals + add_test(function() { + test_cert_equals(); + run_next_test(); + }); + + add_test(function() { + test_cert_pkcs7_export(); + run_next_test(); + }); + + add_test(function() { + test_cert_pkcs7_empty_array(); + run_next_test(); + }); + + add_test(function() { + test_old_succeeded_certlist_deseralization_v2(); + run_next_test(); + }); + + add_test(function() { + test_old_failed_certlist_deseralization_v2(); + run_next_test(); + }); + + add_test(function() { + test_old_succeeded_certlist_deseralization_v1(); + run_next_test(); + }); + + add_test(function() { + test_old_failed_certlist_deseralization_v1(); + 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.length, + 0, + "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( + areCertArraysEqual(originalCertChain, securityInfo.failedCertChain), + "failedCertChain should equal the original cert chain for an" + + " overrideable connection failure" + ); + } + ); + + // Test overrideable connection failure (failedCertChain should be non-null) + add_connection_test( + "unknownissuer.example.com", + SEC_ERROR_UNKNOWN_ISSUER, + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + test_security_info_serialization(securityInfo, SEC_ERROR_UNKNOWN_ISSUER); + notEqual( + securityInfo.failedCertChain, + null, + "failedCertChain should not be null for an overrideable" + + " connection failure" + ); + let originalCertChain = build_cert_chain(["unknownissuer"]); + ok( + areCertArraysEqual(originalCertChain, 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( + areCertArraysEqual(originalCertChain, securityInfo.failedCertChain), + "failedCertChain should equal the original cert chain for a" + + " non-overrideable connection failure" + ); + } + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_dbKey.js b/security/manager/ssl/tests/unit/test_cert_dbKey.js new file mode 100644 index 0000000000..a45b638b8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_dbKey.js @@ -0,0 +1,263 @@ +// -*- 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"; + +// This test tests that the nsIX509Cert.dbKey and nsIX509CertDB.findCertByDBKey +// APIs work as expected. That is, getting a certificate's dbKey and using it +// in findCertByDBKey should return the same certificate. Also, for backwards +// compatibility, findCertByDBKey should ignore any whitespace in its input +// (even though now nsIX509Cert.dbKey will never have whitespace in it). + +function hexStringToBytes(hex) { + let bytes = []; + for (let hexByteStr of hex.split(":")) { + bytes.push(parseInt(hexByteStr, 16)); + } + return bytes; +} + +function encodeCommonNameAsBytes(commonName) { + // The encoding will look something like this (in hex): + // 30 (SEQUENCE) <length of contents> + // 31 (SET) <length of contents> + // 30 (SEQUENCE) <length of contents> + // 06 (OID) 03 (length) + // 55 04 03 (id-at-commonName) + // 0C (UTF8String) <length of common name> + // <common name bytes> + // To make things simple, it would be nice to have the length of each + // component be less than 128 bytes (so we can have single-byte lengths). + // For this to hold, the maximum length of the contents of the outermost + // SEQUENCE must be 127. Everything not in the contents of the common name + // will take up 11 bytes, so the value of the common name itself can be at + // most 116 bytes. + ok( + commonName.length <= 116, + "test assumption: common name can't be longer than 116 bytes (makes " + + "DER encoding easier)" + ); + let commonNameOIDBytes = [0x06, 0x03, 0x55, 0x04, 0x03]; + let commonNameBytes = [0x0c, commonName.length]; + for (let i = 0; i < commonName.length; i++) { + commonNameBytes.push(commonName.charCodeAt(i)); + } + let bytes = commonNameOIDBytes.concat(commonNameBytes); + bytes.unshift(bytes.length); + bytes.unshift(0x30); // SEQUENCE + bytes.unshift(bytes.length); + bytes.unshift(0x31); // SET + bytes.unshift(bytes.length); + bytes.unshift(0x30); // SEQUENCE + return bytes; +} + +function testInvalidDBKey(certDB, dbKey) { + throws( + () => certDB.findCertByDBKey(dbKey), + /NS_ERROR_ILLEGAL_INPUT/, + `findCertByDBKey(${dbKey}) should raise NS_ERROR_ILLEGAL_INPUT` + ); +} + +function testDBKeyForNonexistentCert(certDB, dbKey) { + let cert = certDB.findCertByDBKey(dbKey); + ok(!cert, "shouldn't find cert for given dbKey"); +} + +function byteArrayToByteString(bytes) { + let byteString = ""; + for (let b of bytes) { + byteString += String.fromCharCode(b); + } + return byteString; +} + +function run_test() { + do_get_profile(); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let cert = constructCertFromFile("bad_certs/test-ca.pem"); + equal( + cert.issuerName, + "CN=" + cert.issuerCommonName, + "test assumption: this certificate's issuer distinguished name " + + "consists only of a common name" + ); + let issuerBytes = encodeCommonNameAsBytes(cert.issuerCommonName); + ok( + issuerBytes.length < 256, + "test assumption: length of encoded issuer is less than 256 bytes" + ); + let serialNumberBytes = hexStringToBytes(cert.serialNumber); + ok( + serialNumberBytes.length < 256, + "test assumption: length of encoded serial number is less than 256 bytes" + ); + let dbKeyHeader = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + serialNumberBytes.length, + 0, + 0, + 0, + issuerBytes.length, + ]; + let expectedDbKeyBytes = dbKeyHeader.concat(serialNumberBytes, issuerBytes); + let expectedDbKey = btoa(byteArrayToByteString(expectedDbKeyBytes)); + equal( + cert.dbKey, + expectedDbKey, + "actual and expected dbKey values should match" + ); + + let certFromDbKey = certDB.findCertByDBKey(expectedDbKey); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should find the right certificate" + ); + + ok( + expectedDbKey.length > 64, + "test assumption: dbKey should be longer than 64 characters" + ); + let expectedDbKeyWithCRLF = expectedDbKey.replace(/(.{64})/, "$1\r\n"); + ok( + expectedDbKeyWithCRLF.indexOf("\r\n") == 64, + "test self-check: adding CRLF to dbKey should succeed" + ); + certFromDbKey = certDB.findCertByDBKey(expectedDbKeyWithCRLF); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should work with dbKey with CRLF" + ); + + let expectedDbKeyWithSpaces = expectedDbKey.replace(/(.{64})/, "$1 "); + ok( + expectedDbKeyWithSpaces.indexOf(" ") == 64, + "test self-check: adding spaces to dbKey should succeed" + ); + certFromDbKey = certDB.findCertByDBKey(expectedDbKeyWithSpaces); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should work with dbKey with spaces" + ); + + // Test some invalid dbKey values. + testInvalidDBKey(certDB, "AAAA"); // Not long enough. + // No header. + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString( + [0, 0, 0, serialNumberBytes.length, 0, 0, 0, issuerBytes.length].concat( + serialNumberBytes, + issuerBytes + ) + ) + ) + ); + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, // serial number length is way too long + 255, + 255, + 255, + 255, // issuer length is way too long + 0, + 0, + 0, + 0, + ]) + ) + ); + // Truncated issuer. + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 10, + 1, + 1, + 2, + 3, + ]) + ) + ); + // Issuer doesn't decode to valid common name. + testDBKeyForNonexistentCert( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 3, + 1, + 1, + 2, + 3, + ]) + ) + ); + + // zero-length serial number and issuer -> no such certificate + testDBKeyForNonexistentCert( + certDB, + btoa( + byteArrayToByteString([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_eku.js b/security/manager/ssl/tests/unit/test_cert_eku.js new file mode 100644 index 0000000000..d185407243 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku.js @@ -0,0 +1,189 @@ +// -*- 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/. + +// Tests that the extended key usage extension is properly processed by the +// platform when verifying certificates. There are already comprehensive tests +// in mozilla::pkix itself, but these tests serve as integration tests to ensure +// that the cases we're particularly concerned about are correctly handled. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile(`test_cert_eku/${certName}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, `test_cert_eku/${certName}.pem`, trustString); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLServer + ); +} + +function checkCertOn25August2016(cert, expectedResult) { + // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000 + const VALIDATION_TIME = 1472083200; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); + }); + Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false); + + loadCertWithTrust("ca", "CTu,,"); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA"), PRErrorCodeSuccess); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA-CA"), PRErrorCodeSuccess); + // end-entity has extended key usage, but id-kp-serverAuth is not present => + // failure + await checkEndEntity(certFromFile("ee-CA"), SEC_ERROR_INADEQUATE_CERT_TYPE); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA-nsSGC"), PRErrorCodeSuccess); + + // end-entity has extended key usage, but id-kp-serverAuth is not present => + // failure (in particular, Netscape Server Gated Crypto (also known as + // Netscape Step Up) is not an acceptable substitute for end-entity + // certificates). + // Verify this for all Netscape Step Up policy configurations. + // 0 = "always accept nsSGC in place of serverAuth for CA certificates" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 1 = "accept nsSGC before 23 August 2016" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 2 = "accept nsSGC before 23 August 2015" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 3 = "never accept nsSGC" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // end-entity has id-kp-OCSPSigning, which is not acceptable for end-entity + // certificates being verified as TLS server certificates => failure + await checkEndEntity( + certFromFile("ee-SA-OCSP"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA", ",,"); + await checkEndEntity(certFromFile("ee-int-SA"), PRErrorCodeSuccess); + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA-CA", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-CA"), PRErrorCodeSuccess); + // intermediate has extended key usage, but id-kp-serverAuth is not present + // => failure + loadCertWithTrust("int-CA", ",,"); + await checkEndEntity( + certFromFile("ee-int-CA"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA-nsSGC", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-nsSGC"), PRErrorCodeSuccess); + + // Intermediate has Netscape Server Gated Crypto. Success will depend on the + // Netscape Step Up policy configuration and the notBefore property of the + // intermediate. + loadCertWithTrust("int-nsSGC-recent", ",,"); + loadCertWithTrust("int-nsSGC-old", ",,"); + loadCertWithTrust("int-nsSGC-older", ",,"); + // 0 = "always accept nsSGC in place of serverAuth for CA certificates" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0); + info("Netscape Step Up policy: always accept"); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 1 = "accept nsSGC before 23 August 2016" + info("Netscape Step Up policy: accept before 23 August 2016"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 2 = "accept nsSGC before 23 August 2015" + info("Netscape Step Up policy: accept before 23 August 2015"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 3 = "never accept nsSGC" + info("Netscape Step Up policy: never accept"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // intermediate has id-kp-OCSPSigning, which is acceptable for CA + // certificates => success + loadCertWithTrust("int-SA-OCSP", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-OCSP"), PRErrorCodeSuccess); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ca.pem b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem new file mode 100644 index 0000000000..790e942fbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvDCCAaSgAwIBAgIUbYeck7JVOWdVm1AGwsw/DzdRnaYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTAxMDEwMDAwMDBaGA8yMDM1MDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBAI0AO+ZBY1oImSrpifcmQZTE/C4xIu7Uu5GX/A7ApQU7 +8UAXivMgRDbtrjOie1HNH9DIxHBCFY/Y7f0VRXxWmPEmT+5LpHrLoi+YF0h2wh/1 +RuiJV1AfaEdVJyNCVDSQrS8BQG5O3LebBq00gjSJSQ4+DHu7YHWkyMIZk+lbBiO1 +GsD0FWBDlOtiMpL/CQWjyiskiqQjrDCs5m0NayqgzYAMtdlEd+pAKEMNO8Fr8xSI +tAlcG4frvH0kLJ2scX9ayvKTZrAiAxJz9CjmmnXOyL78yyr/hkJbzYTvk0+1cClg +J2aGnsFIHgUxEx7sApOqlmG8g1lqL7UPqpi8ItVNl48= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec new file mode 100644 index 0000000000..c6e443f5d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +validity:20150101-20350101 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem new file mode 100644 index 0000000000..b947abe69f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUC5X2jRE2ClirTUZa/5o/butQdrgwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEDEOMAwGA1UEAwwFZWUtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG +AQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCaHEnFif4rqZGKOtXrnXTCvFvkxr7i +hBU/zInfRn+9Q1+k4/yyjdThNNLCuTVu3sMlWjIbZGvF/iudIN/m2ZkT4qOmi+LX +fy7a+QEEFLPZy+CCAQ3KHX2p+LEf9rnuUVOiqub9/lxD/KJOBV6SOwVGU+D7bxq4 +/+Y1mVFpxlGqQgHgSroZCPDAquRVYJC43x+lrlPNnX5fOetd3ipbZDcEdLf6Vy1A +RsWVyFgJhVR8Uw267iI9/j9rIbChLY4aQNxTmH6/Knz+KYussltkcotgEu5YAQSs +y7VL3y2JzlLQaq/0WorvkjHjZ8F4eILSS1fGAHrK6HT1eJsDxJzYVayO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec new file mode 100644 index 0000000000..d49cabaa2f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-CA +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem new file mode 100644 index 0000000000..a9fc97c5b0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUFZM7fDUSi2PQ/ZLQ1JsWSrDyX7kwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZWUtU0EtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjITAfMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAd6LFItpHZW0s +kKR7utmFTcQmuSXg6OJF7DSbF0bJkVfE9L0ZrYc4ATp3M9zTxlZAVKJIFX8RPMp4 +tNPQrfsa3jQGWzRdIv6dtsHau3EUVrNQwdsErtko3LUr/W6anHy9VTOJuXWQ//qf +eBiZHOfxf2WAZCjDcOP8k6/rttbrpka0Y1VjPzNNXJR83lLk0ADxt2R9R6/PYsq1 +uxuYbBbkmB3vlLrfpYw3yCEXkaAByTCvCALaEXzC9vS1gDxhPvucS122A9GdCe8j +8wkHMNFpfeCafqTypD6KDS/6yl+GEiB1ErHM2pkwn9oromh9R9M1ILkBtICy+w/W +4FqGVfffaQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec new file mode 100644 index 0000000000..5250cc4a84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-CA +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem new file mode 100644 index 0000000000..de6b780718 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUO/5lR94sxaHEzsErl8RFZ8quniAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtU0EtT0NTUDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMhMB8wHQYDVR0lBBYw +FAYIKwYBBQUHAwEGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IBAQB+jNOQ3Nti +BB0Vi9y2+E/TMcrR+A0YNJpGQfxbH2bPs1RONwq+b8/RXzTb5OXkh02gb94inOn6 +E8uvxwZeFNp6hRdJWrUMP/Fw0H5zn7F/X7h9yRGDV3aICULFK9G/c26jgiQY4+P8 +j61EnAaEI68KDXZ/QFSrH/nxlb+xOl+MZQfnD4jEbyGWknL6RX2uhOuc3c6mzaEI +FkKRXtLuAnGaaBwnjPenNKO7wPKaaF5wo1JcO5uZqaEI/hkw3WXUF25HBhq8ntx4 +VYKQaKQwzwLvptLDxUsf4nhbyQYNSxUJq/L2hnZDuiLFQzWiK4cFnOiBeojZDoq4 +gVp7BdWxFL7A +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..3b3eff9ae4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-OCSP +extension:extKeyUsage:serverAuth,OCSPSigning diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem new file mode 100644 index 0000000000..70f5bd54b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1zCCAb+gAwIBAgIUD6t9UhitEOD4JaK87FphFLXfkgowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtU0EtbnNTR0MwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjIjAgMB4GA1UdJQQX +MBUGCCsGAQUFBwMBBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQADggEBAIveO3ip +QuHtl08d57tWw4yCLEvkm00QHiW45hvkB7sAc/yc5oQ6Ctas8kFeiQlFov0oc855 +H/m1/+q69AhjloTCRP56ETxQD8XOYpJ65Z+h7xLJ0ePb16KzFdP4D/RrrP88Q+IW +P8y80sk79ZYFpXw/pQVWmeYlZ/2B+0lRG2Qr14Y87oJq58e2v3D8JVTYIaqvcUUV +KL+vvz2VD2oIRVcHkPKRDziC71au/uGZNpaRFiJLrqMXp5tbSTnTfvEU8UQNvWsD +up7hx5Sjnm1hih9NxNNYC0JqjqAe09fPLuKEpmhkMs+cQBhQkgGum82WOu/BVgTA +bOzdhBReGuu6di4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..4c51425ce7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-nsSGC +extension:extKeyUsage:serverAuth,nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem new file mode 100644 index 0000000000..72fdae0143 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUO1FsmRgdyx0D0iMZXEesXr+RpxswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEDEOMAwGA1UEAwwFZWUtU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBHY3Yp7JCSy1kJOdflxPplNuPlU5i/ +WTQbM3LKjibHKefWe22GAKIArymZWtE5/1OLUOyicB2bd4AdLA2dflTN2kZ0isVd +K4Gk5z7o+i3rSULI5DeAhlAHPDMP9+NV1os+j/c5eK+CKAaWEJtcH+khDeb6kH83 +1IQDAgvYOpXrZTnoC+dKc/9esdmAzEWeP05F5PgfFCTAjKX2voMmnJOjGtSoV/UM +76RHmB3Z4tLeJ85eXU2k6E+RwMrb6JLZe+xfeInN3EE/g4dfnh+/KAHhgLl7MTyn +GRIlTXisaOYe27wGK4/O9vuvoaQu4A5QrZcUp9lFv7cD1Fz1E8zBC8oY +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec new file mode 100644 index 0000000000..690f579afa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem new file mode 100644 index 0000000000..cc1e10404d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUZaXG7JEsTaOaPw87/nUy+/eUmqYwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLWludC1DQTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAigF8fmjv72/13vJXo6IeNjrY7B7Vo4ojlCP+3MjGBCgCXy1Bm34p +X8t4DcJMZ9e4QPkGpA30jl/TymxaFUA/Hr2zezdJ+uU66qPWzzsiQCYZVXpkHgDL +yd2MpiQZeIoX7t71BdxZbikajedXutn36U/ZIehZcSeNeaz/Fd8MqABVcvvjuTsn +0Lbt8eubJml/x6WtQbDjPspI25oQwbQz3stXOGv4uBfuALKzO9AtlAXWpS/JFhhs +4rqa8VEqHKGtP8fSieSsqhy4R98gR/PfYS/XvnRo71U+/m2iGxMizz7/FIuO13X+ +Xq1+S2fKey7Z3ZbA8+zdfHwlZpBydKAkMA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec new file mode 100644 index 0000000000..670973930d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-CA +subject:ee-int-CA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem new file mode 100644 index 0000000000..759812ff9f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIUY8AAXoT/5+XKoZB/qHd8n2QKXn0wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJaW50LVNBLUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLWludC1TQS1DQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEAongard/cqAypTPlDgt8nFQQxFkNgZ0L0izzNhbZ2VuYM +8+gxKgT76VhixF5fM4aojpTKpvfBjMMVfBeYc9zLjad4jIvroYEzRTuOVeHhsVyf +sre2adRS1Z1rj45x5G4N6KriZimKJGgaZeBeTNA4rVO6Tf9mUzllaHG9e3VhPXCR +Pzqhb29lpdIkqn3TZR+RU/gRHLgk5uAL5d3izvI2xmH16zWdtEULjPA6fATiLPDi +36dmkUFNBQBQ74xZBBmj98R0FpVGCEPj3yX8/hjYT4R2ixhLLZXrybLwSbVD7MVq +GOnF+ezXULHmbUkNUO1expuWLFnrOTqsNMFOse453A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec new file mode 100644 index 0000000000..bd012ab712 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-CA +subject:ee-int-SA-CA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem new file mode 100644 index 0000000000..0b442fb3ce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvzCCAaegAwIBAgIUG6TTZ+C/RpJ/4TcDy/SngGYRzAkwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LVNBLU9DU1AwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowGTEXMBUGA1UEAwwOZWUtaW50LVNBLU9DU1AwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAFPckRG2h/ZdBJmtCRQ0sLB76hwRRHxm6WMyCzUM +V5kOmpgcIRIlbSJmYCVBzgcmVgT0q/6eK6qg+vCnrhBthv+lx+ZI42x0QEatyL0X +FTqwEe5x0nnw6wqhDuFBQ5KGOyGfb5fRk3cT7m6Fya00X/87uPs/HuoYBJsnschJ +2zCyP3yGQRiiQ8moBvQZvJBJ1wwlNPduMLF9WhQRxW6ijxZGiNctHmZU452ol+3/ +jOK2N7FvkK19f+fzMa0y1bWE8M68fIIIylWEpiYSrzCO04nf6TD6HK2Ss25qCoKS +dzowS1bL9TdUmwbCXnL/CyXSDWHMaAhNWD/DEwL6t3altBc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..2374d248f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-OCSP +subject:ee-int-SA-OCSP diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem new file mode 100644 index 0000000000..ed4d21e745 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAamgAwIBAgIUQ+NMzLj5C9j8fDWZOGMQ0w7huRcwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LVNBLW5zU0dDMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD2VlLWludC1TQS1uc1NHQzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +ATANBgkqhkiG9w0BAQsFAAOCAQEAMQ6PCkVUC9IQH/ZQippzUv5UWQo+YagnX13p +10m5+Qt4OT/qxaj1hKbSnZrgZfphDoQ/8DKmHKFuRH8sCNXloc1XNrgXDb959BH8 +1R/BreULnXn7avmSycVTW06XuctRfozB15YjG9V6EUQgPOyzWeK7qmtJWJSxlsMw +JxRtbD8M+UOXHO8mmneRjz0N7kzEEOhr97sr/XCbcRuc81PU9n8X3gqITEyvBRld +MqXNuVF/cvN8DJG9A7gKQ6NWlpks2k2U2k93je5lsofLmdQFQjc8AQ63aW8i9Fa8 +kBOWlHNVMK838BSR8DPT05Pc6f6kAT9biLMx8Z7z3/5AmbJXlQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..6c3cb64730 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-nsSGC +subject:ee-int-SA-nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem new file mode 100644 index 0000000000..31833bde84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUWSf0ySmH86e0yX7mdf5oq7s682cwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LVNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLWludC1TQTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAfaFAdO8ATfh6LHVfh/R9TVdi+khwSItsGLXJO3XEJd5luGSb2bkH +HM+9TWZmBC/LHhtnm5RDcQ9qSPSDoj7KRHPXccN0mLjTwr/nMnZaqG8P/khxsb1V +8vQvHVz3XrNXbothv8TCidYPSain7Zr3j8iB8bArzwOL5gf0z7xyDtpnsRMkTd48 +/cOhY+YA5vx+mNE7NUVUSMk1jtfg7Q8FVSGVOzZlRFoZ7IxlDN7nt2fTepPjuYDM +NTiJ1qLwkve2mig0ZPzov4eTH+i/gkFC08Kqc9IKI14VmFT72Lxu6pDTAeO4bEQm +Jm5i9Z4ffgJmbL8nUC4IDTOau4eGoTjhig== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec new file mode 100644 index 0000000000..72ddb78dfd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA +subject:ee-int-SA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem new file mode 100644 index 0000000000..8e8d4c2c04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAaugAwIBAgIUB/nCi+kTmIkobMVqQFtJnevhGwEwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNaW50LW5zU0dDLW9sZDAiGA8yMDE2MDcyNDAwMDAwMFoY +DzIwMTYwOTI0MDAwMDAwWjAbMRkwFwYDVQQDDBBlZS1pbnQtbnNTR0Mtb2xkMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABMA0GCSqGSIb3DQEBCwUAA4IBAQBcxzg5hx9tQ57Jv3wibAhPktjmqapB2suH +eGE253Xn5haGq+0E3Qkmn7oF1ou6QyLvP+qbElhkx7+eEvhMhzRZFU8XmxzHRqbb +dZ0/MQw+aLEOc4Utl+1n3pDbVhBjoG3yVxyErndHfyXg+hNPMBEPvtfMYnSkKHX1 +3w3pJSs8HtUNMG3jecwXOJic0kUu6V5npNC0KTeZq4OOzp48WCpEfsQ6W5MzR4PN +mrCVU2t1GzCKRNA8E8a9unOcxnukz8FaY9RCkeW3cTwRNt0VaFprX32d1C4mz5rV +vNz/TGA0jy2b4Mg/dpGXrxqyRy1mG3zfs7sDhEoCxLsd/7ytu/bs +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec new file mode 100644 index 0000000000..a21b49b783 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-old +subject:ee-int-nsSGC-old +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem new file mode 100644 index 0000000000..4acdf7b59d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxzCCAa+gAwIBAgIUYfx/2lyIWKMRlK/zS6/kmkp+t/MwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPaW50LW5zU0dDLW9sZGVyMCIYDzIwMTUwNzI0MDAwMDAw +WhgPMjAxNjA5MjQwMDAwMDBaMB0xGzAZBgNVBAMMEmVlLWludC1uc1NHQy1vbGRl +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAbCqK5OcHMj28V1PKiL4CHeN2oTCj +pObUJrAUqsHJbqS2Q+huzzoSsL+yT4uKeiuDMZnKOm8OIZMtM7M4zQb6b5H1Wqm+ +fM5384kUubmSG+CzUd4adK8NjSwgYhgdvAecbzhPS1GUlai9qDJU+elQVIrNZCL4 +6B634koCQkarYybibdXgoum9zzcla0TRXe9rHjb8VYe+BH7tLAnWGpUqw4x36Buz +gv605ApVb+QDAB9NH4/EZ1TXuKby6I9I19EkfADHL5XUKHGFH2EE+6Fsqihgu3QG +NRYMU2GL79bZcwOm2t2v+ZB2fp+UlEs8nykWY7PgwbJ+ObgSauNHhKi5DA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec new file mode 100644 index 0000000000..93e1831a32 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-older +subject:ee-int-nsSGC-older +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem new file mode 100644 index 0000000000..557c8276e8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUE/PT07mikR8SeEYcqdLT8IL5vMIwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LW5zU0dDLXJlY2VudDAiGA8yMDE2MDgyNDAwMDAw +MFoYDzIwMTcwODI0MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1pbnQtbnNTR0MtcmVj +ZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAKnYtenyuUSykB8EP4IkEeeVPo +PeZpLKEHHr9CnjIC8b0lHhTsFQhIiNsCWt8xh+JS273QJi/A2rdo1M4KiMZyURne +RZvTBpFu5F8E+VixDP9xmpAffrgqPqgNRyN+co7tUQZgsJHhb8LSKKMHQTMTBOgW +nrVlMR+MwXBBQx7Yc7KkVob8DMWmIAAXlv0JY6ID2lRb4haBVS1gsPIj24mVF8XG +dRJIgtVUvey49/PvErG6FNA32QPDCyv9UOkX9mtpnu9dT+v6mAkbRcSDYAsTTWh2 +seog8fOBA8WoqO+EtTIY2VLiO2G8pTp8MftYVc1Mhd5Kh/ZT+PtdngloPnDM +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec new file mode 100644 index 0000000000..4a3ad8ec05 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-recent +subject:ee-int-nsSGC-recent +validity:20160824-20170824 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem new file mode 100644 index 0000000000..46f729df5c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUOcdHr2fMC/woQI+w/G6U646FIE0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZWUtbnNTR0MwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGDAWMBQGA1UdJQQNMAsG +CWCGSAGG+EIEATANBgkqhkiG9w0BAQsFAAOCAQEATjPFb+Y7HWDeWq02niJ4Puxu +T68/Q/P1M9BCeLMCaZAybxCJ1FDR/aOGfZMF8TQlx77wYz63j5s4BVjM1gLwl59w +EQK1xaav37Jt5IxfTFVBkJovOnDZFkDa3s+ebZfFpXl5pUFCZc8XOzkV/dy5mbE+ +baYZUikhVIDrvRmWcbXwzhEJhl5qfzgFkiWP9vA0vkVt3NAMuPclh/6L9844d4TN +uVo0C6X6I9jK3X7x2skLk00RT1MeigOE9o6Xuu0SYujDOXBAeOcjCE3mFJZQUr71 +FkD3Exrxo/UjbgIpLdBNLp2TEDR5bbwUIkk6bZy37vDa2xYCxe+Ret3ykpxshw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec new file mode 100644 index 0000000000..43d58ab6d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-nsSGC +extension:extKeyUsage:nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem new file mode 100644 index 0000000000..ec83db25ec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIULaosvYiVvbvMj07BsP9K65Ea2yMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBRB7aEaMyA +kIN82mO+ZICrTUqFqe/0LHF4N3c5hR/JqjHGnrYcyNnewYccQXMQhZhZu1aRfZ8o +bs5Hz52teZsxjL8udA0c75bF48Dd2BHT++lHV4AHO8EZsW6SwF5NDGGJH6B8bRq9 +5FoiuOtWHan8MFTqC5FxHeaXsDiqS8MlEojSTvkh5Huq9HQAEAziJFfUyRZ1W8qw +m0GNX+/iXvqj0g0vrIBkVnPnUgHuglQITcH8luYhBJlv7I9YE55wNMCIf/xcHJro +htKzXzaJvdXeZrNlOLTzhEt8scv0sOF/tgiqVYpIHB7ku5x0Qnw7NRf6j9zDdzqm +SlKm9uRBg4LX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec new file mode 100644 index 0000000000..e5bc18198c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-CA +extension:basicConstraints:cA, +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem new file mode 100644 index 0000000000..9ebd34f0df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUU53rn1mYUmAkdWEYl4H8CjVjAqUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFDESMBAGA1UEAwwJaW50LVNBLUNBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoy8wLTAMBgNVHRMEBTAD +AQH/MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsF +AAOCAQEANp5URW6l61bXiiNt7GQU/Q5bXrlHO31ipGzyo1t936xejdsnEZuRqc7i +QCKsCDynX7z6+hqyjFiOx7hTxh3tek/LICciZfigatB0mGqK0SsqaDMPbPvJgPCT +PDJUskEI92R4Qzelvol46F/4mZUQTOvoCASZRcr4RefqF/ClcE167XqZDn2DYxn/ +jpNY+Bs+VINWEgaqPbznEh3sQHksmweUWW49deIidAZGCwIHJFfFOegT0xBSRRdp +BN2WV78zIr4LFsrpwSKD82LJ2jdeq86hrc9UXJ55+JffNXtsWxXr/vXxiNEW+qJ0 +g4OGIAY9XAF/sJ2iPJd5ynaCmpEqVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec new file mode 100644 index 0000000000..94e9a42d48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-CA +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem new file mode 100644 index 0000000000..e37d294074 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIULf8za+LuAorq+vV7GCo4dV9SG8MwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LVNBLU9DU1AwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAtMAwGA1UdEwQF +MAMBAf8wHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMJMA0GCSqGSIb3DQEB +CwUAA4IBAQBuugyWnIWv5eql67JO/rdh5JswvOfsmDql24twefbVILsHDMKHNMm7 +Xzq7N2lQ0Ye5hy1G0Tmpgd6GV8Yyi1lWwRmI0zZCsRWDYeodbXgDYbDoBBdzNUeH +KpPqV7PCkdMgoJp8AAlYOJnNKw9ARAQBe6ut5mq1fNgpzRGEeHpl0WVFKF0c1pSd +snNLv8LgtCOXdbpc+gHEZ4CLHffVic1cVWg2M+EivuZsFZRPUMFlfevlC5Uh9ea9 +UWvp3Ta3ipZX+XuCTkmzDMLRNm6pM/Je6yKo8zywxLgGt+kpK6itSLEMmQFql49A +NWS74xUiOXJWsE0+YeZ0aaNSPe0tFyLX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..c38a640b9b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-OCSP +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,OCSPSigning diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem new file mode 100644 index 0000000000..c149580a8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUVWq3GjxxzfgGFcE6ypKcX3YnKZEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LVNBLW5zU0dDMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozAwLjAMBgNVHRME +BTADAQH/MB4GA1UdJQQXMBUGCCsGAQUFBwMBBglghkgBhvhCBAEwDQYJKoZIhvcN +AQELBQADggEBAFUF48SjYDpRRNNlGynD/g4jHOW5TTdUueiEWNCYEayldMMe6Rhq +kkEhY+3yC5Ys94YZFoiWaPmlR9FGFNdvjYV+abyElqYoSWO99qOJUldvm4xFwGQr +TwalO2jqwy4qtos/qbw6M/dflrRQzEZ5Cf5yYLwm9E18ALbuiU+B2Jp3n5LQ6T1Q +dDt+FkP3LlCWde+Y3aFOY+aLCkXgLwCOVCluwet8/IsKTGD6qzJhd3R2f1fnX8EU +EBfhaw850FpB8Xn4OvDYd+rEHSURNsNGxLzMVxhoBZKTzbwim5Cwem/5n8epRheW +L3eKTia8yBvTtvxDE3+iKkR+Oz9ozOGp6Ys= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..c84201d874 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-nsSGC +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem new file mode 100644 index 0000000000..5dac5b5c24 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUV3pjDiG/4yqDPtPjv5HyVpDHrncwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LVNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQABgZe7+5NE +2Ui9SdwymCBbH8KrZcPKWRCBb/iCxVMbt39k+MQPaQQgxEKqGiYYCE79yJo0HznF ++gN/Jc62tuY+oBUc+E3MvULqR6AMB1qjSs48uq57aunoE5gDgwoGU/gMA1Mfd22s +X08jcbpWfsyDVglzeK9J/Ihc7QPnBk3iMnv10TuFq+8/C6E+2ZQmTYd9CjVAPyS0 +C1DVIBoPsRrcWlh5cKVXQIVBECGLNAIIXbPGcO6tirxOtNG6ehnROfQn6hBqZQrs +LIrrRHHGuF+eT9PV3Eld4puoHQ2FYPo8lK41xqqbZJYW7a9kP0EEJVQYLrwcM/0i +haT6qq3JwqKA +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec new file mode 100644 index 0000000000..74bec2b21c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem new file mode 100644 index 0000000000..e0deef7c3f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUbXK8dZ2kTHVUtKZ1Uamdr5h27tQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowGDEWMBQGA1UEAwwNaW50LW5zU0dDLW9sZDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYDVR0T +BAUwAwEB/zAUBgNVHSUEDTALBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQADggEB +AK/99QYaWy5/SG7iKiGwSgJ49hobsVUf4DTN9+4FIesvXNUtXc+vmPVNwgy8S4Kn +23zOUmp2LaRBQ3VxaiQ0o/RN3ZjULhPhGi3cHsjDTKXH3U0snAloUYONx1JCFOif +RWwLeiyps1oW9ARfUQrbQRtw87ospU5aJ7JSPoVgbCMXubmEpRSeTMv0SHdOs6g7 +ahSaoT7BBRuHDnCb8+ZR509H9Dc4M2Dv4lQ9vlWGZjXnfM1ImIeUBTWQ0fngyoZW +neTStGeL5MmCjjMMupJYbjNsenQXd9doD08+voOfmKgaMQDH0fgEACJHjmmt+eQ4 +j8WZP3lRZHZm/s23xNl+6S4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec new file mode 100644 index 0000000000..35f61671ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-old +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem new file mode 100644 index 0000000000..dd709c343d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUITNR+z5zrXNAq+3y9u3et1fNp6YwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowGjEYMBYGA1UEAwwPaW50LW5zU0dDLW9sZGVyMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyYwJDAMBgNV +HRMEBTADAQH/MBQGA1UdJQQNMAsGCWCGSAGG+EIEATANBgkqhkiG9w0BAQsFAAOC +AQEAtkFQHiG8UeleNMgvJVneYQzIQt8wiZwudAH2FdiyeCtYUp95z19IzPlZeYq0 +FXlMJJ+SOn2wSZ9jHshV5VF8S4Rb3ou0EVJcu+X7cs3jOuLtV/KwFDKXrncWpF7L +sH1yGVkAUNMQlE52MgPxg7P6yd+lbU9MlqD5rpifsAecrXzctzi8l3qb2UJvkHku +BLE+ViTnn9RFDQFQ/1AAF9cbSJaUF0rwWznXpB0PAu+v9lBpn9a83/GXZc1SO2mE +MIdgRpuB1Lr+wZq5ulXHAeBJ+kH8lrG2CIXSQPFQjPfiS2D5hM1cdd7GSEh4BoZv +AbTKG12NXN9AG7RpG7upSBG4mQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec new file mode 100644 index 0000000000..f7a870c0f1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-older +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem new file mode 100644 index 0000000000..c5c8e724c2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUec5AldPAXDY+y1Q7RfO4SfvteiEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE3MDgyNDAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LW5zU0dDLXJlY2VudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYD +VR0TBAUwAwEB/zAUBgNVHSUEDTALBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQAD +ggEBAJO1C5eYEk2/+xvgWsCsUZi7PMoZLhb5Jb2V61JMWREfCozmYepqlamR6IZV +fn5Q9OClLtAzSybeia40nsW/xb/o+5zJn0rPzk6JIsMToJk07fqp+uG9LbAM82IV +RnHzmCS4/3n4fl1k1GGL0A/NYBUsilY9oKhVl1zukB/z3ALp9LyProNLsEZmWkl7 +F07+lR9PPMOqA1SuDJmZMyZ4cKDyYYF7NYKGi57xpgpUXGq8IPOKKGq4XlYqQhOQ +sVSuc+16A+NlPwMogczcgTgy7QD6DF4WNOCDGwuF0YB7uROEbYvh4lkKJfhnAtb7 +1/xnmTVssnCTsbppIiXtKs8zzu0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec new file mode 100644 index 0000000000..f421ddc1a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-recent +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20160824-20170824 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/moz.build b/security/manager/ssl/tests/unit/test_cert_eku/moz.build new file mode 100644 index 0000000000..ede7f4b548 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/moz.build @@ -0,0 +1,35 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee-CA.pem', +# 'ee-SA-CA.pem', +# 'ee-SA-OCSP.pem', +# 'ee-SA-nsSGC.pem', +# 'ee-SA.pem', +# 'ee-int-CA.pem', +# 'ee-int-SA-CA.pem', +# 'ee-int-SA-OCSP.pem', +# 'ee-int-SA-nsSGC.pem', +# 'ee-int-SA.pem', +# 'ee-int-nsSGC-old.pem', +# 'ee-int-nsSGC-older.pem', +# 'ee-int-nsSGC-recent.pem', +# 'ee-nsSGC.pem', +# 'int-CA.pem', +# 'int-SA-CA.pem', +# 'int-SA-OCSP.pem', +# 'int-SA-nsSGC.pem', +# 'int-SA.pem', +# 'int-nsSGC-old.pem', +# 'int-nsSGC-older.pem', +# 'int-nsSGC-recent.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null.js b/security/manager/ssl/tests/unit/test_cert_embedded_null.js new file mode 100644 index 0000000000..c1b20c1664 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null.js @@ -0,0 +1,54 @@ +// -*- 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/. + +// Tests that a certificate with a clever subject common name like +// 'www.bank1.com[NUL]www.bad-guy.com' (where [NUL] is a single byte with +// value 0) will not be treated as valid for www.bank1.com. +// Includes a similar test case but for the subject alternative name extension. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +async function do_testcase(certname, checkCommonName) { + let cert = constructCertFromFile(`test_cert_embedded_null/${certname}.pem`); + // Where applicable, check that the testcase is meaningful (i.e. that the + // certificate's subject common name has an embedded NUL in it). + if (checkCommonName) { + equal( + cert.commonName, + "www.bank1.com\\00www.bad-guy.com", + "certificate subject common name should have an embedded NUL byte" + ); + } + await checkCertErrorGeneric( + certdb, + cert, + SSL_ERROR_BAD_CERT_DOMAIN, + certificateUsageSSLServer, + undefined, + "www.bank1.com" + ); + await checkCertErrorGeneric( + certdb, + cert, + SSL_ERROR_BAD_CERT_DOMAIN, + certificateUsageSSLServer, + undefined, + "www.bad-guy.com" + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_cert_embedded_null/ca.pem", "CTu,,"); + + await do_testcase("embeddedNull", true); + await do_testcase("embeddedNullSAN", false); + await do_testcase("embeddedNullCNAndSAN", true); + await do_testcase("embeddedNullSAN2", false); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem new file mode 100644 index 0000000000..48031d478c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUb2Np/S2xMtQR+BvitAuzKtjWxMswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBPEDwwrdd6h+SHkc0J+p4Ik/yc +aoLWNdGsVD4hJYa0IOgNh6Z/GyhTXM9hr/q0f7fewjfNhXi/nrXNcW5w4FJERhHp +HvZO6Z08i8CrVYSiijFcLf6ClK4e163j0LXUutBWY2PCf4TDS+fnF9PJmle0kPLU +IxqptfSSoCjLuWyYyRmjZIdNCtrNCU9g85SDaUO6l79vBm0TYOLhOiPBN0F7DWXo +JlOZKWEco6qqS22yIM1r/5KNc5ekPTD+UJFh7qprAq0riEfR38DYJmUq3w07q5Tb +HQdG8JHEtemi7dHr/WoJY18MLZaF7BSLAwBWmBWzx8Lj2V+/4TP4NtRWkL7y +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec new file mode 100644 index 0000000000..6660f5d478 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem new file mode 100644 index 0000000000..3ec195d7ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAgIUN3cis45zT7JXRJUjglyGLKsRNY4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKDEmMCQGA1UEAwwdd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEH79W5n+TiJob4LWvypQNMj4Fi44pwh +L/Pcpe+vXd19sN/UyY4WAH4S6U+Fu+wNlItMWWFQnlkibutTQQLpJhXTSR2q/ttU +CWo9MdCJ8JGFwTReHDoajxdD2NJ/C8vK/dJeFNtCUXLAnwR2bk+F+StDQt6I6iS4 +EXL/A+y1L3jw9j/qVO8ewNp8QJvA8jOe3AQyI3q8fHENExUk0opo1Nvorrlj4xWg +MP+NTIHZeJMGUfBw9vRwIZvfsx5BVQ5aqWpzVR9wxv7UCbO5NKeva57P6s+UeqX5 +rNxjzk0t7MV/3TZSTkMSVCUDc//sGUHMGk0F5fFsZ4/7SM+dO9+PaFM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec new file mode 100644 index 0000000000..d1a32349a2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem new file mode 100644 index 0000000000..6a1dd23bbf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUP8GnOjltE+C0ll5IYA6asvsZ+/MwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKDEmMCQGA1UEAwwdd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjLDAqMCgGA1UdEQQhMB+CHXd3dy5iYW5rMS5jb20Ad3d3LmJhZC1ndXku +Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQAF6YEQrh2rMu+HEcySofn4x3MStqoXrqwc +mn4r4cm4Qvrlubg+vewRan9b8pMryixRG8obsiEp+KGEB74XoSJmwumv8Ov3WL8V +njKT2vAfVLgyZp4p+ZD3firGJMdzZcRDAU8Sg+yM0Vru3fx40piusBqeMbc7lOga +AF+JCMtHPEJc32C4Y+itY0bedXUcBALljTHkam5nQ6+ShPk8X7wazKs8gn3wIBSB +XmLZtmqEjzeI1UuUoyP3/AymCgo90Xi27aA8GGsxsmaUk5Am07Sw9WobLpeRoNgp +c4dV4+2tcDqVM7nK2V4LKNlH9/2oRXoWnQNoDBzRZis9C6SeNV29 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec new file mode 100644 index 0000000000..1029d6cdd0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:www.bank1.com\0www.bad-guy.com +extension:subjectAlternativeName:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem new file mode 100644 index 0000000000..7a9140f31b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUAy5rhhLOHnC6Vr7TTF+tKn9VA+UwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHjEcMBoGA1UEAwwTZW1iZWRkZWQgTlVMIGluIFNBTjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMsMCow +KAYDVR0RBCEwH4Idd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20wDQYJKoZI +hvcNAQELBQADggEBAEmpR9Bldw/m1N5yODTW8J5E1vIy8UbxtcNJnGZaQNCeCbXO +r5d1EwqhGIsrVrYk4kjPD3gLPJuwAGh4yRVTiHWM+dCGf0EyzY5Ytlw42J0ny0PW +15dRoEf07hKxnloqwXy3pAQqtoRyKgIY38xrSYcIAaGlt/wbuO469nzyD7QoamxR +VcSosi0YxSlD8yye+E8fiZyBzB+fiD9W+JHX6mhYEznvtdW3J6zTG7aCOBEswh9C +kVBpMu7gAvGrIviIrtw7EFYxqwmNQg8/KMfeitOoBH7aznq0qsVajkXLo2QrX4CE +VzOabf4X7rLlcdqGN3fl4aDcZNuGR8goj4dgRkY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec new file mode 100644 index 0000000000..f224888eee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:embedded NUL in SAN +extension:subjectAlternativeName:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem new file mode 100644 index 0000000000..e08110f6bc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7jCCAdagAwIBAgIUQx7QA9Wf1gacnL1geoQjuSqMSx4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLYmFkLWd1eS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOTA3MDUGA1UdEQQu +MCyCC2JhZC1ndXkuY29tgh13d3cuYmFuazEuY29tAHd3dy5iYWQtZ3V5LmNvbTAN +BgkqhkiG9w0BAQsFAAOCAQEAWyk3hxMIPXpSeKlePbth7wYv0kUF0RmT6eERgDtz +h/0GIVYx7kaCNQLuBAaRCP/50Tj17R/gYWiPN7YXa1kGfgUYy25mOsrccMR1wvYy +KDzCv4Fip0dDkYAVFRmpTHzy1JQ64dnVlgOkCWuhSb93XOcOJ651BAgPjRwzjDZ4 +vHYidUF61uOU3i/UsLrJJXHdojIgYsyfHv2B7aCkuO4ea1WcmwrS2YYW7DoDBft1 +/X4vRkWhJRKBrertLXCzpC/0ERO0pvGAQp1CJJIddIoO+XwCKnvvgsQI0ao34pJp +Bsk3ZkIyNeYL5o9MAEAr8R4KkpZqACFWoyGqlwP9GPkqOw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec new file mode 100644 index 0000000000..d352d034b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:bad-guy.com +extension:subjectAlternativeName:bad-guy.com,www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build b/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build new file mode 100644 index 0000000000..57c9013ddc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'embeddedNull.pem', +# 'embeddedNullCNAndSAN.pem', +# 'embeddedNullSAN.pem', +# 'embeddedNullSAN2.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_expiration_canary.js b/security/manager/ssl/tests/unit/test_cert_expiration_canary.js new file mode 100644 index 0000000000..4519dd3935 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_expiration_canary.js @@ -0,0 +1,40 @@ +// -*- 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"; + +// Attempts to verify a certificate for a time a few weeks into the future in +// the hopes of avoiding mass test failures when the certificates all expire. +// If this test fails, the certificates probably need to be regenerated. +// See bug 1525191. + +// If this test and only this test fails, do the following: +// 1. Create a bug for the issue in "Core :: Security: PSM". +// 2. Write a patch to temporarily disable the test. +// 3. Land the patch. +// 4. Write a patch to reenable the test but don't land it. +// 5. Needinfo the triage owner of Bugzilla's "Core :: Security: PSM" component +// in the bug. +// 6. Patches to update certificates get created. +// 7. Test the patches with a Try push. +// 8. Land the patches on all trees whose code will still be used when the +// certificates expire in 3 weeks. +add_task(async function() { + do_get_profile(); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + addCertFromFile(certDB, "bad_certs/test-ca.pem", "CTu,,"); + let threeWeeksFromNowInSeconds = Date.now() / 1000 + 3 * 7 * 24 * 60 * 60; + let ee = constructCertFromFile("bad_certs/default-ee.pem"); + await checkCertErrorGenericAtTime( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLServer, + threeWeeksFromNowInSeconds, + false, + "test.example.com" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js new file mode 100644 index 0000000000..d69ea5105c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js @@ -0,0 +1,73 @@ +// -*- 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/. + +// Tests that nsIX509Cert.isBuiltInRoot works as expected. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// This is a certificate that (currently) ships with the platform. +// It should be considered a built-in root. +const sGeoTrustBase64 = + "" + + "MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL" + + "MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj" + + "KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2" + + "MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0" + + "eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV" + + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw" + + "NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV" + + "BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH" + + "MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL" + + "So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal" + + "tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO" + + "BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG" + + "CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT" + + "qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz" + + "rD6ogRLQy7rQkgu2npaqBA+K"; + +// This is a certificate that does not ship with the platform. +// It should not be considered a built-in root. +const sLetsEncryptBase64 = + "" + + "MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw" + + "PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD" + + "Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa" + + "MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD" + + "ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD" + + "ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB" + + "BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg" + + "PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG" + + "dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1" + + "gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4" + + "4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud" + + "EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy" + + "BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j" + + "b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv" + + "ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ" + + "MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH" + + "AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw" + + "MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM" + + "LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3" + + "pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd" + + "v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd" + + "ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW" + + "ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk" + + "6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj" + + "f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk="; + +function run_test() { + let builtInCert = certdb.constructX509FromBase64(sGeoTrustBase64); + ok(builtInCert, "should be able to decode base-64 of built-in cert"); + ok(builtInCert.isBuiltInRoot, "cert should be considered built-in"); + + let notBuiltInCert = certdb.constructX509FromBase64(sLetsEncryptBase64); + ok(notBuiltInCert, "should be able to decode base-64 of built-in cert"); + ok(!notBuiltInCert.isBuiltInRoot, "cert should not be considered built-in"); +} diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js new file mode 100644 index 0000000000..a8c6d09f2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js @@ -0,0 +1,124 @@ +// -*- 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/. + +// Tests that nsIX509Cert.isBuiltInRoot works as expected. Differs from +// test_cert_isBuiltInRoot.js in that this test uses a preexisting NSS +// certificate DB that already contains some of the certificates in question. +// +// To create the necessary preexisting files, obtain the "GeoTrust Primary +// Certification Authority - G2" certificate and the "Let's Encrypt Authority +// X1" certificate (copied below for reference) and perform the following steps: +// +// `certutil -d . -N` (use an empty password) +// `certutil -d . -A -n "GeoTrust Primary Certification Authority - G2" -t ,, \ +// -a -i GeoTrust.pem` +// `certutil -d . -A -n "Let's Encrypt Authority X1" -t ,, -a \ +// -i LetsEncrypt.pem` +// +// This should create the cert9.db and key4.db files. +// +// (The crucial property of the first certificate is that it is a built-in trust +// anchor, so any replacement must also have this property. The second +// certificate is not a built-in trust anchor, so any replacement must not be a +// built-in trust anchor.) +// +// GeoTrust Primary Certification Authority - G2: +// -----BEGIN CERTIFICATE----- +// MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +// MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +// KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +// MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +// eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +// BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +// NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +// BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +// MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +// So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +// tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +// BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +// CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +// qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +// rD6ogRLQy7rQkgu2npaqBA+K +// -----END CERTIFICATE----- +// +// Let's Encrypt Authority X1: +// -----BEGIN CERTIFICATE----- +// MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw +// PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +// Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa +// MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD +// ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD +// ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB +// BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg +// PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG +// dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1 +// gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4 +// 4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud +// EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy +// BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j +// b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv +// ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ +// MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH +// AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw +// MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM +// LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3 +// pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd +// v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd +// ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW +// ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk +// 6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj +// f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk= +// -----END CERTIFICATE----- + +"use strict"; + +function run_test() { + const certDBName = "cert9.db"; + const keyDBName = "key4.db"; + let profile = do_get_profile(); + let certDBFile = do_get_file(`test_cert_isBuiltInRoot_reload/${certDBName}`); + certDBFile.copyTo(profile, certDBName); + let keyDBFile = do_get_file(`test_cert_isBuiltInRoot_reload/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // This is a built-in root, but not one that was added to the preexisting + // certificate DB. + // Verisign Class 1 Public Primary Certification Authority - G3 + // Certificate fingerprint (SHA1): 204285DCF7EB764195578E136BD4B7D1E98E46A5 + // https://crt.sh/?id=8984570 + const veriSignCertDBKey = `AAAAAAAAAAAAAAARAAAAzQCLW3VWhFSFCwDPrzhI + zrGkMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdB + gNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IF + ZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAM + TPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB + dXRob3JpdHkgLSBHMw==`; + let veriSignCert = certdb.findCertByDBKey(veriSignCertDBKey); + ok(veriSignCert, "Should be able to find VeriSign root"); + ok(veriSignCert.isBuiltInRoot, "VeriSign root is a built-in"); + + // This is a built-in root. It was added to the preexisting certificate DB. It + // should still be considered a built-in. + const geoTrustCertDBKey = `AAAAAAAAAAAAAAAQAAAAmzyy9EgK + AOL+6yQ7XmA+w2swgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ + bmMuMTkwNwYDVQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhv + cml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlm + aWNhdGlvbiBBdXRob3JpdHkgLSBHMg==`; + let geoTrustCert = certdb.findCertByDBKey(geoTrustCertDBKey); + ok(geoTrustCert, "Should be able to find GeoTrust root"); + ok(geoTrustCert.isBuiltInRoot, "GeoTrust root is a built-in"); + + // This is not a built-in root. It was added to the preexisting certificate + // DB. It should not be considered a built-in root. + const letsEncryptCertDBKey = `AAAAAAAAAAAAAAARAAAAQQCYE + /R1E+V1C0PnQx6XHkS9MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRyd + XN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=`; + let letsEncryptCert = certdb.findCertByDBKey(letsEncryptCertDBKey); + ok(letsEncryptCert, "Should be able to find LetsEncrypt root"); + ok(!letsEncryptCert.isBuiltInRoot, "LetsEncrypt root is not a built-in"); +} diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db Binary files differnew file mode 100644 index 0000000000..b4567566d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db Binary files differnew file mode 100644 index 0000000000..ed8747112d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage.js b/security/manager/ssl/tests/unit/test_cert_keyUsage.js new file mode 100644 index 0000000000..a32be6152d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage.js @@ -0,0 +1,76 @@ +/* -*- 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"; + +do_get_profile(); // must be called before getting nsIX509CertDB +var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const caList = [ + "ca-no-keyUsage-extension", + "ca-missing-keyCertSign", + "ca-all-usages", +]; +const eeList = [ + "ee-no-keyUsage-extension", + "ee-keyCertSign-only", + "ee-keyEncipherment-only", + "ee-keyCertSign-and-keyEncipherment", +]; + +const caUsage = [certificateUsageSSLCA]; +const allEEUsages = [ + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, +]; +const serverEEUsages = [ + certificateUsageSSLServer, + certificateUsageEmailRecipient, +]; + +const expectedUsagesMap = { + "ca-no-keyUsage-extension": caUsage, + "ca-missing-keyCertSign": [], + "ca-all-usages": caUsage, + + "ee-no-keyUsage-extension-ca-no-keyUsage-extension": allEEUsages, + "ee-no-keyUsage-extension-ca-missing-keyCertSign": [], + "ee-no-keyUsage-extension-ca-all-usages": allEEUsages, + + "ee-keyCertSign-only-ca-no-keyUsage-extension": [], + "ee-keyCertSign-only-ca-missing-keyCertSign": [], + "ee-keyCertSign-only-ca-all-usages": [], + + "ee-keyEncipherment-only-ca-no-keyUsage-extension": serverEEUsages, + "ee-keyEncipherment-only-ca-missing-keyCertSign": [], + "ee-keyEncipherment-only-ca-all-usages": serverEEUsages, + + "ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension": serverEEUsages, + "ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign": [], + "ee-keyCertSign-and-keyEncipherment-ca-all-usages": serverEEUsages, +}; + +add_task(async function() { + for (let ca of caList) { + addCertFromFile(certdb, "test_cert_keyUsage/" + ca + ".pem", "CTu,CTu,CTu"); + let caCert = constructCertFromFile("test_cert_keyUsage/" + ca + ".pem"); + await asyncTestCertificateUsages(certdb, caCert, expectedUsagesMap[ca]); + for (let ee of eeList) { + let eeFullName = ee + "-" + ca; + let eeCert = constructCertFromFile( + "test_cert_keyUsage/" + eeFullName + ".pem" + ); + await asyncTestCertificateUsages( + certdb, + eeCert, + expectedUsagesMap[eeFullName] + ); + } + } +}); diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem new file mode 100644 index 0000000000..f59173e4d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUJUeujAg8AwYGhKxQTX/25wMUlcUwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1jYS1hbGwtdXNhZ2VzMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jANBgkqhkiG9w0BAQsFAAOC +AQEAG8zr2oIAMopI4FXUoIcqnnqRafTg/URYGcBcuqpXQiCFufslaqIY2c1iQExS +S6TcNM2BD2+XjudfRO4R3qSNWNHcq7MFGaiZEOIzIF4bSozXg4HWLkhhZFxPO6Sp +zWd1wr3sHs+LpympZAB4Hs3BCkrYBPACKwTXSP8iqmZ5gN/vRMhyyZMNPSBE9YYO +H7hl+eDeShTQZ8wrhMj2C1QRP8bLtANMpR1yzHNYBVaGFEGJi3ojgSlkZjt1OBu+ +AXOkTU72YycuV0Pin+5RPWGTpbQCBKKkDT4dWEKe9Ur04JdrVuFPHY1AA422Bg1k +WpRsoqRh9fqXtwntrf3gRm/jIw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec new file mode 100644 index 0000000000..2ca523c74e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-all-usages +subject:ca-all-usages +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..49b7d2b962 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUb5GhjzP0jcrSceWaX1M31KkwYIgwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZjYS1taXNzaW5n +LWtleUNlcnRTaWduMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB ++jANBgkqhkiG9w0BAQsFAAOCAQEAGWOD5t5lqzj8nk4TXD4wNPTlZYYpGqRNkQJ4 +LAgt8LhtH656c1OPKCxwJDQXF9XapnkqnPzpT4M3wiRfVBVZgEoO0TN0Fh4CWNJM +Dkq+kNC+rCvb9bddoF9Kzw1MoGa8A5y/JLqAQHi7TL+GwkksdgMvjBkmbEUqc0bc +JdZ5USOBJPEWcsyfxNleyLHtcvI0JcngAeHfb6mK+Tr3wHUeRq1o6llfHOz1nzwE +Lf1rhl6+hY458nxJjIv4p7YzON6dmzkkbKn4Rq4PPppMy44w2jxNqqtbev2TGJBh +lnEibCTgzwFs0xJaQpKqKpHy4lBgjAMwjTzS76UsI30sYV9QjQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..26e0158ebe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-missing-keyCertSign +subject:ca-missing-keyCertSign +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..e79801f9dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6DCCAdCgAwIBAgIUd46cj+Dhtp73GVJRwiYAMXpO09EwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGNhLW5vLWtl +eVVzYWdlLWV4dGVuc2lvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAQEAfo7G469It6DM1PTLY0lfxGdV+4uCJPAWNKKjDk4swLsNy1yz +4zxv5HUwQPnZZqm5dZT22EPUHmycWzt/N/cnjfn10pxDvB41h+XmWgmLPltVXD6E +66N+9sNHb+XIwZdFdGa+oHJI0MLLH+/Uym4t46HuSsjAjvSth40yf7D76WXRmPUn +2bTuxqK+T2Ioq3z8DXx47fNPSqmFiFsj7wUdfQfxugjTbwDNlZ9quxEicYChnl4O +mScxJ/cDoBgB2ZV3FdcSeIc+0aVd7Nxx5sNOifS12/O8m0pflK5dVUtoNXLFoa78 +udnWXJ0J9224khw25u5vabj/gWJGe8TaI61tNw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..d32e6a6496 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ca-no-keyUsage-extension +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem new file mode 100644 index 0000000000..0b391b9b35 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUIQJpgukzHUBKie2RdSdPXFoY4LwwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJlZS1rZXlDZXJ0U2lnbi1hbmQt +a2V5RW5jaXBoZXJtZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAiQwDQYJKoZIhvcN +AQELBQADggEBAA69Kh2Wk+QjEnMqyClxxpodQa37MQqGkXAVgSKgWHYQSagQ0EEJ +SD8oDeNdgeh2mb7lvBysQCw29jgoRj8f/9Pi1+8xkCGBocitM2Um8nYWJ70nHMgt +YOY1io2vQnQmI/dTIrSn330Gf5aCByqIEczEB7Erv/wuZY4l3RPG/HI6e94DXLOt +rSBW/bFM61PU8C/q31VLZ8IHebdaaRO3OL7T0BM4bzQafc3lPfMbqiVy9GzBfQ/a +nRrJirwqNGrKRyAWQ3gfvC60eNTjryH+NSA2N7gPawr2HxMkBqbUXhQwRMRatNKx +JwmoBQTlPI3GVL42qeWGO/ozgwQoRqwHqBs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..0bb2721a31 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..45427ccd17 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUG6KKRn9QfADWZAOAYBt7T0HRwxUwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJlZS1rZXlDZXJ0 +U2lnbi1hbmQta2V5RW5jaXBoZXJtZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAiQw +DQYJKoZIhvcNAQELBQADggEBAA3HxmNPBMOe9i3095PKNQU3OPoJ+iRM6cQLM6KQ +PnfTAXPJFK4gdiY/xH3A69fq8h44F7VoHmxBf2VNurgI8GYiG2U6rLtTshPvDyHe +4KKTIz7rqiCAjdU5jslTS56HYvf0NguwdnFumXybWMAq0ThKCbQMXK16umegtoVE +RgtupUHDwdx8FA+GdcEYYqe7n+yO5ZuzoMlOdAaCl4sO/2XjpTcTNOauUVfrgJ9k +WlKTF6kzL7jhQVYosbGNpE/NblUjRt2/gDbz9tbi/OOcRqq0bQ3l7g6k+lpX7yYf +TKBnXzLhUoP+TNRF/MnO/Hj+HefiGXDtugH2e1CoXJOXluM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..567ab0ce2d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..54b5156753 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUKX6X2shljk68mAen0V5Rvu+OMJgwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMC0xKzApBgNVBAMMImVlLWtleUNl +cnRTaWduLWFuZC1rZXlFbmNpcGhlcm1lbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwIC +JDANBgkqhkiG9w0BAQsFAAOCAQEAW4N1dHXHynllzRvDdokzMD8vKAFcXyOSXP5N +lFqigC5B7Gmt19WFwui/y+qGws1H1PeJPdt73ht/R0tRFMfptuswGlyPufT7t+yP +bVH3JEPuBYBBNragxVsXtqkYIxJGNH96xGBhAbovL7Ie4iIhY+6tsn0j/DATn301 +9Sv+Q3aUTjmpAYo+X7G/TkxOM37vtJbCvZhEYy3NnFQliIdyneJoXRX7V7Yxu+Yv +vAnoDbiuiaT4N/XnP2OTdiwi/Obm7ITujbhwf2QOJvB8gGBIcGQ864opOmqIOn6i +gx6ZpIB0bXeRun3j7qQdm/NeunBBG/EGlK1bcobxYB0lEthxUg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..c48ef66126 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem new file mode 100644 index 0000000000..649c6b2744 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1zCCAb+gAwIBAgIUS7/18rlCU549DxhuSleCZnLydSUwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1rZXlDZXJ0U2lnbi1vbmx5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABow8wDTALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAHGZLv0V +Jx+wMdx0BJkZWUpJq2rKTepW7b9zsGKO1OFo3Y9S+jCHobanWqmz2bwiEThQ4Ebx +wy6eXK9/ex46HNMU/R2OmqjNRJ+fn8NIbSLRK1UTGBnUNFMJgwFqoDGKCHmSGIA/ +DPR0dCFn9VFSVet7vSLSLbUurvTgfSR9GlyXw3abJ1BWsxP+3iCXr5NBNRVepZte +NGIajiG8gnm+JVhAAG1XSnd+/Q99IcLwkJK6QQ8rYQgsg86yF7f1PF/+1jMWo/3E +irkb0oBiyx3aitcPcci3yHcBAHqB/BIooJiQmt9EhvnVOKxFycw1yh3bpbzp0sIr +MBu/rdb+5QSUqCc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..c495ca6d0e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..a818a38d1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUW6rkcglhshQOePFgTRd3FZiywHgwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1rZXlDZXJ0 +U2lnbi1vbmx5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQAD +ggEBAAkfffPLkCJ7QwlVv19U2I69EEG7R8dfPcckXdxRQvRBSrnvFpq4xP+mS+b/ +cPzkCF7XK2JbKILWdpLl1Gl0fqIMdqAo3CUgAh2EgFXb+dDaTNF50vIKhIEnnVBt +xWVQDOxNtFRrwtoUleeV7gOdY8oII+ehCIAqWSSN0tIHdYaoD84ngoIOYD7qGytK +KN7AIIsZ9Ka+2WVGaWloE81ubJK68VThgrjW4eOHGjiHt38cEqge5zco2xj1rSE5 +G7Szdi+gcIOMoqJon3mXq/bkqaUZyTJs7BSm/tic/qID9cIeX2ZpuKCu1HWJqhSF +Jdx3G8WPh5xnKwwKtDmdZoS5NgE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..23ddd0eb8a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..f95886bfb5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUHwJqP3oKeHdRO4h+n18uLiTGuvswDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB4xHDAaBgNVBAMME2VlLWtleUNl +cnRTaWduLW9ubHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwICBDANBgkqhkiG9w0BAQsF +AAOCAQEAGT9yKiHNhaNqa+QCuBKgMYN6cthRl7cXmB6rbgSl6x4+LGLFC/mpVx2n +2ON9I9weQOcdqdA/s6LaT4sdk3V+BR7NDUBN0mHehxxYvMdOKWirMBGQsU/yspEh +asD9RVHBBiX4AaCBfz+k+a0xGg1WNX+XQr7OGARPBclvN4gK/C3EnqWvcInd6dKh +L11X5V8+O76coeii1pRTuEJTgJhttlFurr10YQM59xcJCvbNnDF4NP0ithumm3TX +iH6h29vnr9Xuyhz6yBo8Izvw2mSKtn619U4nxqD0kT11ovfOLbBfS+0D67i7uGUe +9xnFnXmaC7x/UPZ40Ba2bpm5KIo22w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..a5a2d62a7d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem new file mode 100644 index 0000000000..94d5b8376d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2zCCAcOgAwIBAgIUD4en2K6uMB5YpGMfwGgTtM+cZMMwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdlZS1rZXlFbmNpcGhlcm1lbnQt +b25seTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBCwUAA4IBAQCD +FhkKA16rSKyeeyWbKV0GLm0leHDTHD1lLq9OMFJTnM8oIV4wTxkNlM8GBvmXrbJ9 +bR2XBZADefQ2/hYBWCQJHBONOss+G3OF4xYYYQT0gDnhZuABWpT97FLMOsajPaAJ +GcCy4CXFiWmBR3Z70duV7B7AbYM18SOstghaOHCT6dLzA00C/MkeuSwwmylJ0jjX +VE5kmrh8RMy4o9BT2RGLNCAyJehCik0DqHyQjq61Q2pE/eVwSaDIFH29Q57ianyB +fsVGxWjebixLkFm+GWqTbTsGyACwL2tDgE9zA7FcuQ+bUsmNt14+9Sf9j+DGcMXn +wroXpu9cJ2hUBGH/1kya +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..08154a53ee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..413eec8073 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIUR9LRIE9OxiebeLBW62zXCGMQD/4wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdlZS1rZXlFbmNp +cGhlcm1lbnQtb25seTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEB +CwUAA4IBAQAgn7t4QKh0bvoLuwFaZMhTEG1aeC/UH8CAi9InsjNFFKsrqKNMFXIB +BHMwsNX0pd92UVQmcxOelJGKh4Ssebqwi3CegvUxjkoc0XJmJIsmGnta7aliFgYq +8yS9CzxQAsQBS8L/NgJx+kYL5OyyYcOdKkDH2MnHvMl66JwSKoerp0xxK+senJmM +UjvR5bZgR+4L/IZ9G1J70u5EIKOKusrHHnD95y9OtwJSXriErMDaeTMK7C+HSqdK +6+d7OSj/l7sBWgvvIRBAOqIOe3WBnNw5HVAfEf+RkzL9ry0llF93z429BxnV17r0 +DecPXRH8iTA11aPezhblHImD9I+LnEnx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..9bdcf4b7b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..42d173b89a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUUb8T3+6DgXwOgUnl93BH2znvH7swDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCIxIDAeBgNVBAMMF2VlLWtleUVu +Y2lwaGVybWVudC1vbmx5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCBSAwDQYJKoZIhvcN +AQELBQADggEBADPdx2NPP/lnfhFONgim1PT1z9715fnVBUOovdbOFrX4o5bAW9A4 +5EL+4jWXFEgSDCWbaVZIunaExT0clbrdP+96KSu0eCmO8UtWuEmLvWBpwnLNSJmV +V07kpv4cF3ju7m6FMVn2yAWC3MwUVwtG3rc1cTEaQb8mRSP168L+c4bgbDfjT3SH +cjc0Xku8+0qEF8mvDkEjEQ6DXciMQMEA+mdnhjLY7pCxEeMeYn3wbc02j0sDg9mc +P5r7KFALon3lvNNvfgX8ksqs/FxvtkMJuJfxuqqw0JKbTUnCSWDUQLLpH5vTSNwS +J6HaMBk4cBmm7RiMSNHb4q4DD2KPQaR3ia0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..a2383ecfdd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem new file mode 100644 index 0000000000..f9c0e98abf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyzCCAbOgAwIBAgIUdb+6dAvNPrDSi4t1Mh0VWTH9+PwwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhlZS1uby1rZXlVc2FnZS1leHRl +bnNpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAOmZY9qkWrF1fxh37r8uzeI +DIliysuC/r8Zv2PH1uXNQ/Xc2/YRevoLlXYFjPSv+dDLBTLU8gaKoc4A8VbScMXj +RD/4Dgg5P8zp8tYhC6IC6lJU+BsYdE4bVEfxYIuFsj9t3IWaV6dfBGV6tZr5+hma +fd132i0EB6j9tHdWxyjRjbLlpS+Ebws1YxpxhFthtDXia8g4jowh1SRYpK3a+Feh +f/uZAVVDUia9iLK17JwQCWSvIAoMz5A1GyYzfjL6CnhIpXO77G1crCGoUeWbJ94j +5IX1zQfT0YQhdiIQEoD11478aok3BhIIE1KO6iCSXj4o+OVAlFWZexPcutqnTFA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..6d2e672961 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-all-usages +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..4fd1085a57 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUQSQmSr1VH8nomKY2NVNJ+HN8y+0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhlZS1uby1rZXlV +c2FnZS1leHRlbnNpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA36Vps+r3Ao +jobxXMLVlFswo/qOC6/G1BtF8l0UPuOuSf7xpKDWVsorWY/FmsHAdcauHm0m5MUP +nCVhPfH8xYP6TBQw2wWrGk/RBnWDNLewrdEIlWSTFUALY6SKcvRO1adWGJ/uJZr3 +O6KCvrg22O4ZlOFLpb5B8XhUVcCPiH30vdo2MeiaA/IOs0dqMZAfzH5s25WRjwnJ +byYST/yVutDdexECWVibIFwi1N+APduacEyDXvao5y3VXz96kblSLtZaSX/2mHDc +fhKTLWw4ykHqBIWmDYs2RJrSqFM45bNShLYGCqTPmYFmCU5SY9e+elcfReLcbJzv +FNK2ofnYhm4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..3cba2f0d81 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-missing-keyCertSign +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..4bf7250fee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1jCCAb6gAwIBAgIUOXIHlX23XCDj+TpQN+GOUIa0wl0wDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGVlLW5vLWtl +eVVzYWdlLWV4dGVuc2lvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAkKUtc+iJ +0yBV2Y3xKmTIDe3he3Cy3VSembzQTpc+FBfQ4n9gXZSw5O8PllaWD4pjz7ovDYNp +rl422x6vkfmm7ebZb1PqVXZDkONXYn22a/76j7EFl+LlG6EMUw8OJ+iMTiCrDS2j +MbTpyRKLbgPMcT7GxZZDmqRJKva/VFVJ92XuIndZrltQ/RAr5QAg1+ijo2VpowWn +etUhR/GZ6WbDS85KQLEOFeWHS9ez02asCjQcanWgMYPqZXG1wQQbEAgfJLT1Bqar +k+TRt7NRlJPbxI8R5UfXJfCdXYrT17jhO52b7UZcCmCe/kyQPwtir5axOupFy17i +NHOBFw1PVX4KfQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..c850725a63 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-no-keyUsage-extension +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build b/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build new file mode 100644 index 0000000000..a16fff4b94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build @@ -0,0 +1,27 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-all-usages.pem', +# 'ca-missing-keyCertSign.pem', +# 'ca-no-keyUsage-extension.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem', +# 'ee-keyCertSign-only-ca-all-usages.pem', +# 'ee-keyCertSign-only-ca-missing-keyCertSign.pem', +# 'ee-keyCertSign-only-ca-no-keyUsage-extension.pem', +# 'ee-keyEncipherment-only-ca-all-usages.pem', +# 'ee-keyEncipherment-only-ca-missing-keyCertSign.pem', +# 'ee-keyEncipherment-only-ca-no-keyUsage-extension.pem', +# 'ee-no-keyUsage-extension-ca-all-usages.pem', +# 'ee-no-keyUsage-extension-ca-missing-keyCertSign.pem', +# 'ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js b/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js new file mode 100644 index 0000000000..4ac8820515 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js @@ -0,0 +1,116 @@ +// -*- 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"; + +// Test that when an override exists for a (host, certificate) pair, +// connections will succeed only if the set of error bits in the override +// contains each bit in the set of encountered error bits. +// Strangely, it is possible to store an override with an empty set of error +// bits, so this tests that too. + +do_get_profile(); + +function add_override_bits_mismatch_test( + host, + certPath, + expectedBits, + expectedError +) { + const MAX_BITS = + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME; + let cert = constructCertFromFile(certPath); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + for (let overrideBits = 0; overrideBits <= MAX_BITS; overrideBits++) { + add_test(function() { + certOverrideService.clearValidityOverride(host, 8443); + certOverrideService.rememberValidityOverride( + host, + 8443, + cert, + overrideBits, + true + ); + run_next_test(); + }); + // The override will succeed only if the set of error bits in the override + // contains each bit in the set of expected error bits. + let successExpected = (overrideBits | expectedBits) == overrideBits; + add_connection_test( + host, + successExpected ? PRErrorCodeSuccess : expectedError + ); + } +} + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + add_override_bits_mismatch_test( + "unknownissuer.example.com", + "bad_certs/unknownissuer.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "mismatch.example.com", + "bad_certs/mismatch.pem", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_override_bits_mismatch_test( + "expired.example.com", + "bad_certs/expired-ee.pem", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + + add_override_bits_mismatch_test( + "mismatch-untrusted.example.com", + "bad_certs/mismatch-untrusted.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "untrusted-expired.example.com", + "bad_certs/untrusted-expired.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "mismatch-expired.example.com", + "bad_certs/mismatch-expired.pem", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + add_override_bits_mismatch_test( + "mismatch-untrusted-expired.example.com", + "bad_certs/mismatch-untrusted-expired.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides.js b/security/manager/ssl/tests/unit/test_cert_overrides.js new file mode 100644 index 0000000000..f160f00562 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides.js @@ -0,0 +1,718 @@ +// -*- 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 the certificate overrides we allow. +// add_cert_override_test will queue a test that does the following: +// 1. Attempt to connect to the given host. This should fail with the +// given error and override bits. +// 2. Add an override for that host/port/certificate/override bits. +// 3. Connect again. This should succeed. + +do_get_profile(); + +function check_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_CERT_ERROR_OVERRIDES") + .snapshot(); + equal(histogram.values[0], 0, "Should have 0 unclassified values"); + equal( + histogram.values[2], + 9, + "Actual and expected SEC_ERROR_UNKNOWN_ISSUER values should match" + ); + equal( + histogram.values[3], + 1, + "Actual and expected SEC_ERROR_CA_CERT_INVALID values should match" + ); + equal( + histogram.values[4] || 0, + 0, + "Actual and expected SEC_ERROR_UNTRUSTED_ISSUER values should match" + ); + equal( + histogram.values[5], + 1, + "Actual and expected SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE values should match" + ); + equal( + histogram.values[6] || 0, + 0, + "Actual and expected SEC_ERROR_UNTRUSTED_CERT values should match" + ); + equal( + histogram.values[7] || 0, + 0, + "Actual and expected SEC_ERROR_INADEQUATE_KEY_USAGE values should match" + ); + equal( + histogram.values[8], + 2, + "Actual and expected SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED values should match" + ); + equal( + histogram.values[9], + 13, + "Actual and expected SSL_ERROR_BAD_CERT_DOMAIN values should match" + ); + equal( + histogram.values[10], + 5, + "Actual and expected SEC_ERROR_EXPIRED_CERTIFICATE values should match" + ); + equal( + histogram.values[11], + 2, + "Actual and expected MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY values should match" + ); + equal( + histogram.values[12], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA values should match" + ); + equal( + histogram.values[13], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE values should match" + ); + equal( + histogram.values[14], + 2, + "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE values should match" + ); + equal( + histogram.values[15], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE values should match" + ); + equal( + histogram.values[16], + 2, + "Actual and expected SEC_ERROR_INVALID_TIME values should match" + ); + equal( + histogram.values[17], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME values should match" + ); + equal( + histogram.values[19], + 3, + "Actual and expected MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT values should match" + ); + equal( + histogram.values[20], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_MITM_DETECTED values should match" + ); + + let keySizeHistogram = Services.telemetry + .getHistogramById("CERT_CHAIN_KEY_SIZE_STATUS") + .snapshot(); + equal( + keySizeHistogram.values[0], + 0, + "Actual and expected unchecked key size values should match" + ); + equal( + keySizeHistogram.values[1], + 16, + "Actual and expected successful verifications of 2048-bit keys should match" + ); + equal( + keySizeHistogram.values[2] || 0, + 0, + "Actual and expected successful verifications of 1024-bit keys should match" + ); + equal( + keySizeHistogram.values[3], + 68, + "Actual and expected verification failures unrelated to key size should match" + ); + + run_next_test(); +} + +// Internally, specifying "port" -1 is the same as port 443. This tests that. +function run_port_equivalency_test(inPort, outPort) { + Assert.ok( + (inPort == 443 && outPort == -1) || (inPort == -1 && outPort == 443), + "The two specified ports must be -1 and 443 (in any order)" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let cert = constructCertFromFile("bad_certs/default-ee.pem"); + let expectedBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED; + let expectedTemporary = true; + certOverrideService.rememberValidityOverride( + "example.com", + inPort, + cert, + expectedBits, + expectedTemporary + ); + let actualBits = {}; + let actualTemporary = {}; + Assert.ok( + certOverrideService.hasMatchingOverride( + "example.com", + outPort, + cert, + actualBits, + actualTemporary + ), + `override set on port ${inPort} should match port ${outPort}` + ); + equal( + actualBits.value, + expectedBits, + "input override bits should match output bits" + ); + equal( + actualTemporary.value, + expectedTemporary, + "input override temporary value should match output temporary value" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.com", 563, cert, {}, {}), + `override set on port ${inPort} should not match port 563` + ); + certOverrideService.clearValidityOverride("example.com", inPort); + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.com", + outPort, + cert, + actualBits, + {} + ), + `override cleared on port ${inPort} should match port ${outPort}` + ); + equal(actualBits.value, 0, "should have no bits set if there is no override"); +} + +function run_test() { + run_port_equivalency_test(-1, 443); + run_port_equivalency_test(443, -1); + + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + add_simple_tests(); + add_localhost_tests(); + add_combo_tests(); + add_distrust_tests(); + + add_test(function() { + fakeOCSPResponder.stop(check_telemetry); + }); + + run_next_test(); +} + +function add_simple_tests() { + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + add_cert_override_test( + "notyetvalid.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE + ); + add_cert_override_test( + "before-epoch.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_INVALID_TIME + ); + add_cert_override_test( + "selfsigned.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + add_cert_override_test( + "unknownissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "expiredissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE + ); + add_cert_override_test( + "notyetvalidissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE + ); + add_cert_override_test( + "before-epoch-issuer.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_INVALID_TIME + ); + add_cert_override_test( + "md5signature.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + add_cert_override_test( + "emptyissuername.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME + ); + // This has name information in the subject alternative names extension, + // but not the subject common name. + add_cert_override_test( + "mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + // This has name information in the subject common name but not the subject + // alternative names extension. + add_cert_override_test( + "mismatch-CN.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + // A Microsoft IIS utility generates self-signed certificates with + // properties similar to the one this "host" will present. + add_cert_override_test( + "selfsigned-inadequateEKU.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + + add_prevented_cert_override_test( + "inadequatekeyusage.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_INADEQUATE_KEY_USAGE + ); + + // Test triggering the MitM detection. We don't set-up a proxy here. Just + // set the pref. Without the pref set we expect an unkown issuer error. + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + Services.prefs.setStringPref( + "security.pki.mitm_canary_issuer", + "CN=Test MITM Root" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_MITM_DETECTED + ); + add_test(function() { + Services.prefs.setStringPref( + "security.pki.mitm_canary_issuer", + "CN=Other MITM Root" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + // If the canary issuer doesn't match the one we see, we exepct and unknown + // issuer error. + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + // If security.pki.mitm_canary_issuer.enabled is false, there should always + // be an unknown issuer error. + add_test(function() { + Services.prefs.setBoolPref( + "security.pki.mitm_canary_issuer.enabled", + false + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + Services.prefs.clearUserPref("security.pki.mitm_canary_issuer"); + run_next_test(); + }); + + // This is intended to test the case where a verification has failed for one + // overridable reason (e.g. unknown issuer) but then, in the process of + // reporting that error, a non-overridable error is encountered. The + // non-overridable error should be prioritized. + add_test(function() { + let rootCert = constructCertFromFile("bad_certs/test-ca.pem"); + setCertTrust(rootCert, ",,"); + run_next_test(); + }); + add_prevented_cert_override_test( + "nsCertTypeCritical.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION + ); + add_test(function() { + let rootCert = constructCertFromFile("bad_certs/test-ca.pem"); + setCertTrust(rootCert, "CTu,,"); + run_next_test(); + }); + + // Bug 990603: Apache documentation has recommended generating a self-signed + // test certificate with basic constraints: CA:true. For compatibility, this + // is a scenario in which an override is allowed. + add_cert_override_test( + "self-signed-end-entity-with-cA-true.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + + add_cert_override_test( + "ca-used-as-end-entity.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + + // If an X.509 version 1 certificate is not a trust anchor, we will + // encounter an overridable error. + add_cert_override_test( + "end-entity-issued-by-v1-cert.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + // If we make that certificate a trust anchor, the connection will succeed. + add_test(function() { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride( + "end-entity-issued-by-v1-cert.example.com", + 8443 + ); + let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem"); + setCertTrust(v1Cert, "CTu,,"); + clearSessionCache(); + run_next_test(); + }); + add_connection_test( + "end-entity-issued-by-v1-cert.example.com", + PRErrorCodeSuccess + ); + // Reset the trust for that certificate. + add_test(function() { + let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem"); + setCertTrust(v1Cert, ",,"); + clearSessionCache(); + run_next_test(); + }); + + // Due to compatibility issues, we allow overrides for certificates issued by + // certificates that are not valid CAs. + add_cert_override_test( + "end-entity-issued-by-non-CA.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_CA_CERT_INVALID + ); + + // This host presents a 1016-bit RSA key. + add_cert_override_test( + "inadequate-key-size-ee.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + add_cert_override_test( + "ipAddressAsDNSNameInSAN.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "noValidNames.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "badSubjectAltNames.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + add_cert_override_test( + "bug413909.xn--hxajbheg2az3al.xn--jxalpdlp", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + // At this point, the override for bug413909.xn--hxajbheg2az3al.xn--jxalpdlp + // is still valid. Do some additional tests relating to IDN handling. + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let uri = Services.io.newURI( + "https://bug413909.xn--hxajbheg2az3al.xn--jxalpdlp" + ); + let cert = constructCertFromFile("bad_certs/idn-certificate.pem"); + Assert.ok( + certOverrideService.hasMatchingOverride( + uri.asciiHost, + 8443, + cert, + {}, + {} + ), + "IDN certificate should have matching override using ascii host" + ); + Assert.throws( + () => + !certOverrideService.hasMatchingOverride( + uri.displayHost, + 8443, + cert, + {}, + {} + ), + /NS_ERROR_ILLEGAL_VALUE/, + "IDN certificate should not have matching override using (non-ascii) host" + ); + let invalidHost = uri.asciiHost.replace(/./g, c => + String.fromCharCode(c.charCodeAt(0) | 0x100) + ); + Assert.throws( + () => + !certOverrideService.hasMatchingOverride( + invalidHost, + 8443, + cert, + {}, + {} + ), + /NS_ERROR_ILLEGAL_VALUE/, + "hasMatchingOverride should not truncate high-bytes" + ); + run_next_test(); + }); + + add_test(function() { + // Add a bunch of overrides... + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let cert = constructCertFromFile("bad_certs/default-ee.pem"); + let expectedBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED; + certOverrideService.rememberValidityOverride( + "example.com", + 443, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.com", 443, cert, {}, {}), + "Should have added override for example.com:443" + ); + certOverrideService.rememberValidityOverride( + "example.com", + 80, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.com", 80, cert, {}, {}), + "Should have added override for example.com:80" + ); + certOverrideService.rememberValidityOverride( + "example.org", + 443, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.org", 443, cert, {}, {}), + "Should have added override for example.org:443" + ); + certOverrideService.rememberValidityOverride( + "example.org", + 80, + cert, + expectedBits, + true + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.org", 80, cert, {}, {}), + "Should have added override for example.org:80" + ); + + // Clear them all... + certOverrideService.clearAllOverrides(); + + // And ensure they're all gone. + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.com", + 443, + cert, + {}, + {} + ), + "Should have removed override for example.com:443" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.com", 80, cert, {}, {}), + "Should have removed override for example.com:80" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.org", + 443, + cert, + {}, + {} + ), + "Should have removed override for example.org:443" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.org", 80, cert, {}, {}), + "Should have removed override for example.org:80" + ); + + run_next_test(); + }); +} + +function add_localhost_tests() { + add_cert_override_test( + "localhost", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "127.0.0.1", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "::1", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); +} + +function add_combo_tests() { + add_cert_override_test( + "mismatch-expired.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "mismatch-notYetValid.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "mismatch-untrusted.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "untrusted-expired.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "mismatch-untrusted-expired.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_cert_override_test( + "md5signature-expired.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + add_cert_override_test( + "ca-used-as-end-entity-name-mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); +} + +function add_distrust_tests() { + // Before we specifically distrust this certificate, it should be trusted. + add_connection_test("untrusted.example.com", PRErrorCodeSuccess); + + add_distrust_test( + "bad_certs/default-ee.pem", + "untrusted.example.com", + SEC_ERROR_UNTRUSTED_CERT + ); + + add_distrust_test( + "bad_certs/other-test-ca.pem", + "untrustedissuer.example.com", + SEC_ERROR_UNTRUSTED_ISSUER + ); + + add_distrust_test( + "bad_certs/test-ca.pem", + "ca-used-as-end-entity.example.com", + SEC_ERROR_UNTRUSTED_ISSUER + ); +} + +function add_distrust_test(certFileName, hostName, expectedResult) { + let certToDistrust = constructCertFromFile(certFileName); + + add_test(function() { + // Add an entry to the NSS certDB that says to distrust the cert + setCertTrust(certToDistrust, "pu,,"); + clearSessionCache(); + run_next_test(); + }); + add_prevented_cert_override_test( + hostName, + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + expectedResult + ); + add_test(function() { + setCertTrust(certToDistrust, "u,,"); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js new file mode 100644 index 0000000000..bf7104eaaa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js @@ -0,0 +1,126 @@ +// -*- 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 permanent certificate error overrides can be added even if the +// certificate/key databases are in read-only mode. + +// Helper function for add_read_only_cert_override_test. Probably doesn't need +// to be called directly. +function add_read_only_cert_override(aHost, aExpectedBits, aSecurityInfo) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + // Setting the last argument to false here ensures that we attempt to store a + // permanent override (which is what was failing in bug 1427273). + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + false + ); +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and an +// expected error code, tests that an initial connection to the host fails with +// the expected errors and that adding an override results in a subsequent +// connection succeeding. +function add_read_only_cert_override_test( + aHost, + aExpectedBits, + aExpectedError +) { + add_connection_test( + aHost, + aExpectedError, + null, + add_read_only_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => { + Assert.ok( + aSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "Cert override flag should be set on the security state" + ); + }); +} + +function run_test() { + let profile = do_get_profile(); + const KEY_DB_NAME = "key4.db"; + const CERT_DB_NAME = "cert9.db"; + let srcKeyDBFile = do_get_file( + `test_cert_overrides_read_only/${KEY_DB_NAME}` + ); + srcKeyDBFile.copyTo(profile, KEY_DB_NAME); + let srcCertDBFile = do_get_file( + `test_cert_overrides_read_only/${CERT_DB_NAME}` + ); + srcCertDBFile.copyTo(profile, CERT_DB_NAME); + + // set the databases to read-only + let keyDBFile = do_get_profile(); + keyDBFile.append(KEY_DB_NAME); + keyDBFile.permissions = 0o400; + let certDBFile = do_get_profile(); + certDBFile.append(CERT_DB_NAME); + certDBFile.permissions = 0o400; + + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // Specifying false as the last argument means we don't try to add the default + // test root CA (which would fail). + add_tls_server_setup("BadCertAndPinningServer", "bad_certs", false); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + // Since we can't add the root CA to the (read-only) trust db, all of these + // will result in an "unknown issuer error" and need the "untrusted" error bit + // set in addition to whatever other specific error bits are necessary. + add_read_only_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_read_only_cert_override_test( + "selfsigned.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + add_read_only_cert_override_test( + "mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db Binary files differnew file mode 100644 index 0000000000..3d452f335c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db Binary files differnew file mode 100644 index 0000000000..44d0cb1728 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db diff --git a/security/manager/ssl/tests/unit/test_cert_sha1.js b/security/manager/ssl/tests/unit/test_cert_sha1.js new file mode 100644 index 0000000000..371945bf85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1.js @@ -0,0 +1,187 @@ +// -*- 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/. + +// Tests the rejection of SHA-1 certificates based on the preference +// security.pki.sha1_enforcement_level. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// We need to test as if we are at a fixed time, so that we are testing the +// 2016 checks on SHA-1, not the notBefore checks. +// +// (new Date("2016-03-01")).getTime() / 1000 +const VALIDATION_TIME = 1456790400; + +function certFromFile(certName) { + return constructCertFromFile("test_cert_sha1/" + certName + ".pem"); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, "test_cert_sha1/" + certName + ".pem", trustString); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + loadCertWithTrust("int-pre", ",,"); + loadCertWithTrust("int-post", ",,"); + + // Test cases per pref setting + // + // root intermed. end entity + // =========================== + // root + // | + // +--- pre-2016 + // | | + // | +----- pre-2016 <--- (a) + // | +----- post-2016 <--- (b) + // | + // +--- post-2016 + // | + // +----- post-2016 <--- (c) + // + // Expected outcomes (accept / reject): + // + // a b c + // Allowed (0) Accept Accept Accept + // Forbidden (1) Reject Reject Reject + // (2) is no longer available and is treated as Forbidden (1) internally. + // ImportedRoot (3) Reject Reject Reject (for built-in roots) + // ImportedRoot Accept Accept Accept (for non-built-in roots) + // ImportedRootOrBefore2016 (4) Accept Reject Reject (for built-in roots) + // ImportedRootOrBefore2016 Accept Accept Accept (for non-built-in roots) + // + // The pref setting of ImportedRoot accepts usage of SHA-1 only for + // certificates issued by non-built-in roots. By default, the testing + // certificates are all considered issued by a non-built-in root. However, we + // have the ability to treat a given non-built-in root as built-in. We test + // both of these situations below. + // + // As a historical note, a policy option (Before2016) was previously available + // that only allowed SHA-1 for certificates with a notBefore before 2016. + // However, to enable the policy of only allowing SHA-1 from non-built-in + // roots in the most straightforward way (while still having a time-based + // policy that users could enable if this new policy were problematic), + // Before2016 was shifted to also allow SHA-1 from non-built-in roots, hence + // ImportedRootOrBefore2016. + // + // A note about intermediate certificates: the certificate verifier has the + // ability to directly verify a given certificate for the purpose of issuing + // TLS web server certificates. However, when asked to do so, the certificate + // verifier does not take into account the currently configured SHA-1 policy. + // This is in part due to implementation complexity and because this isn't + // actually how TLS web server certificates are verified in the TLS handshake + // (which makes a full implementation that supports heeding the SHA-1 policy + // unnecessary). + + // SHA-1 allowed + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 0); + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); + + // SHA-1 forbidden + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 1); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + // SHA-1 forbidden (test the case where the pref has been set to 2) + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 2); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + // SHA-1 allowed only when issued by an imported root. First test with the + // test root considered a built-in (on debug only - this functionality is + // disabled on non-debug builds). + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3); + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + } + + // SHA-1 still allowed only when issued by an imported root. + // Now test with the test root considered a non-built-in. + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); + + // SHA-1 allowed before 2016 or when issued by an imported root. First test + // with the test root considered a built-in. + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + } + + // SHA-1 still only allowed before 2016 or when issued by an imported root. + // Now test with the test root considered a non-built-in. + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem new file mode 100644 index 0000000000..60140056de --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUUbC4F7yPobFDd+B73iWKejQ3THkwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCU+Y0AeMXFIfX4/L2aX37uSR70 +pGpPrh0FPOwBO2ETUc4j7Whol9wOSPnUwuPIpiDhar5qRuhY6aCPGTIJbRZrVeXv +T5uFQXq+3CQdIyI55AkFDh9tO7wX7p3pRgzma47mBxIH082Uwy7+eEeQfhuJ5cU4 +e/zyHf6FEdkSrDjgwDip+dn8Q7tnjdaN3WYQjOFRXkHyYCIFkORDPTbYSYZ6DAqq +Q/loKTdrcbyeEwFVBZxQu4Nb6mjhkfk8U+8TIGMCTQXhoQhgMWMeMo2E0kWvYbjc +YDiRzmnsdvPu2LKnTvH28M9ODi3ZzcOuLs6jAKAiXISq0CbmwaddV/oAMoF2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec new file mode 100644 index 0000000000..7e65e9ee30 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem new file mode 100644 index 0000000000..8fb93e69e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUJWQl8gkrLL7gPn47YYMdN7qBP5wwDQYJKoZIhvcNAQEF +BQAwEzERMA8GA1UEAwwIaW50LXBvc3QwIhgPMjAxNjAxMDIwMDAwMDBaGA8yMDE3 +MDIwMTAwMDAwMFowEjEQMA4GA1UEAwwHZWUtcG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQUFAAOCAQEAVOPvLS8zwos/RdClnabdxMh5g1WN5T1BsIMExE6oU6sJ7n4HyIXt +RnFTFe0t2CdXBCQPK6qG8ymeLQFNKykYlQxVZb8m5YgUK3k4IeMS/EoX4g7taREI +IwK9/n7+oKZYlz2Q/ro/R2HFmLXsCIUrsxV3vAWQCm8rSeCKzEVNlDaQ5FEMVAM7 +VlNhNNKtUnXkzZ3SRj6O4eOq3G4azr5DNo5kAQPaIbAI3k/3AHyPqIjHcoSiG1Ug +aqzIK6fNNCIAxIKAY2ERJfxA4fPlBZXono2sCOgCdFfF7QAo+o9SO8v3B+djuHgb +flbfdyEnN+y32UpYe3qV8LnFmRqGAe/vbQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec new file mode 100644 index 0000000000..76834f8447 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-post +subject:ee-post +validity:20160102-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem new file mode 100644 index 0000000000..2385322a64 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUIVsTCuql4BDO2r4O5zePBEoHg3QwDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHaW50LXByZTAiGA8yMDE2MDEwMTAwMDAwMFoYDzIwMTcw +MjAxMDAwMDAwWjASMRAwDgYDVQQDDAdlZS1wb3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +BQUAA4IBAQCW5zeJg+LzGn07GtdBprRLarL7aLNFSr+s+3yzphq9kN43prElX6eD +gdggPWicZozTm3IFLfJfsuhiodBZjWmkF/dsvvT3W77AcKzNWjShCnnA/Vf5IF6k +U01ROfjmgcX0mMuhVUB7b9Fl6G5DFxJgny2jYehZcJIzWUBLiwu41TIxj5Cv5F9p ++XIHEyygqm8rYzbW8F49FRbsDD9nvhmdVqXsoTaKxY8bsKKu1EpBSBXozRbLKcAn +/zrLy0HHS4qfXTHm0UKt+RCYVylL5I5YGR6rapXHChkBTBHFXdkPVsW5uHKBdBqY +98zoAAMWRvJ3xOuqAbtKG6DKadiOpz6l +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec new file mode 100644 index 0000000000..1e8bb35b34 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-pre +subject:ee-post +validity:20160101-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem new file mode 100644 index 0000000000..11a5e41e99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUOU+CyYnf3GRRgGHvbeJB8HTUvJ4wDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHaW50LXByZTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMTcw +MjAxMDAwMDAwWjARMQ8wDQYDVQQDDAZlZS1wcmUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEF +BQADggEBACWLcVnT0nNyU/qFZNDZPGDFPuZCXuodBf3sgz1XDmcp5wlH+IjW3J8H +3HH6ZwIUpTtppqVxuvo2y9GP+GNyeXhxmokHTVdKDj8HqYl5lV+reO1UmzEH0AU8 +x3hd2Fkzv/h3N3EPVETWuPiFSB0oAN/xwsXC/7Yi4AY0s/I/4q/vkS76Oa2RyL3f +gbaa80+nR73BX+0wRqyg+Sgo2hOzjkCQchtZPUFYsRLhsHHBnokD8GJlT7NBKSN1 +TFt6uXpfEmqDICoyZoAw6rtnFfdEsZNo+PU6NDN3T0fkolBQPvuzfqcqAl85dpJK +ow8mFKkb2t6qQH98yabi/172l03/P34= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec new file mode 100644 index 0000000000..0f4a6ec257 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-pre +subject:ee-pre +validity:20150101-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem new file mode 100644 index 0000000000..94ab4f5b15 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzzCCAbegAwIBAgIUYQ6xulHM0FrQ0sKMdbPI2ecC3PcwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjAxMDEwMDAwMDBaGA8yMDI2MDEwMTAw +MDAwMFowEzERMA8GA1UEAwwIaW50LXBvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIB +BjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCJN8/XexXMusXYbhVW +uYA1YpaSTrz96CXlckIuABnzCrGD5iHkfFoB0LPKd+EZ80fdHIvS1zQTYohy6O95 +JageOaTY9HsOEqsgr1BA9VKZW4QlGp7csQzNMa52WRetimv6XY/lrfPf4qAhomWG +/ImmLJpGTVPhEdz6Pl4Kvmf9zNf/BcXtBTWLSGWUC5UItC58WTopqcr5kLg3DmXB +Qr7DjqA7DT92N6qefFkTYspDZJzv0nL9OfqkdCj/s6bm3iisTQq3aek6IP6OEkXF +4TWUF3RDBsyRpG8jt/XsOsrwJDOGZGFPmMTz2uZPsZkeZhU+sfFDWL7wojl7kHV1 +c7f5 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec new file mode 100644 index 0000000000..50156c9f6e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:int-post +validity:20160101-20260101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem new file mode 100644 index 0000000000..0b916d5755 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUYW27TGzVOIbjpG1ADx7m7mZnrNQwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDIwMDEwMTAw +MDAwMFowEjEQMA4GA1UEAwwHaW50LXByZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQDAgEG +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAESNgcKkxBwkaBykKo2Q +GzgimnI3eNw8O8GrhefL+r3Ek/CH4/oBHGvfvrz6D19uemdOyHxo5QNW2iWEq0No +pE6Hhm504P1fdkfQvjqjIhu/h3y5QjO3zdMGeVE/39TWAGrGsNFKE+jSxm8IbycF +Ue6165agasf+PhQdorjFca48iLcowKYs5Df0SAhY7zbw1fM1HTr1YGAXc1K9aCA5 +fTmu8Nd0fNKc1NcbNDpdCG2YEj1nox1iMN5A4nY1ve88zJsnlpfsoJkHJqo2Cy+M +mpQSnkTlf3Gfpl8NO3UW9FTcnK8L4Ix2DSNBDe8Yg2YL5w/VIxecFwlmwV0wWdg6 +vl0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec new file mode 100644 index 0000000000..9f0a59ee99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:int-pre +validity:20100101-20200101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/moz.build b/security/manager/ssl/tests/unit/test_cert_sha1/moz.build new file mode 100644 index 0000000000..93cba24554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'int-pre.pem', +# 'ee-pre_int-pre.pem', +# 'ee-post_int-pre.pem', +# 'int-post.pem', +# 'ee-post_int-post.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_signatures.js b/security/manager/ssl/tests/unit/test_cert_signatures.js new file mode 100644 index 0000000000..e92b5a4ab8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures.js @@ -0,0 +1,140 @@ +// -*- 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 certificates cannot be tampered with without being detected. +// Tests a combination of cases: RSA signatures, ECDSA signatures, certificate +// chains where the intermediate has been tampered with, chains where the +// end-entity has been tampered, tampering of the signature, and tampering in +// the rest of the certificate. + +do_get_profile(); // must be called before getting nsIX509CertDB +var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// Reads a PEM-encoded certificate, modifies the nth byte (0-indexed), and +// returns the base64-encoded bytes of the certificate. Negative indices may be +// specified to modify a byte from the end of the certificate. +function readAndTamperWithNthByte(certificatePath, n) { + let pem = readFile(do_get_file(certificatePath, false)); + let der = atob(pemToBase64(pem)); + if (n < 0) { + // remember, n is negative at this point + n = der.length + n; + } + let replacement = "\x22"; + if (der.charCodeAt(n) == replacement) { + replacement = "\x23"; + } + der = der.substring(0, n) + replacement + der.substring(n + 1); + return btoa(der); +} + +// The signature on certificates appears last. This should modify the contents +// of the signature such that it no longer validates correctly while still +// resulting in a structurally valid certificate. +const BYTE_IN_SIGNATURE = -8; +function addSignatureTamperedCertificate(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SIGNATURE); + certdb.addCertFromBase64(base64, ",,"); +} + +function ensureSignatureVerificationFailure(certificatePath) { + let cert = constructCertFromFile(certificatePath); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +function tamperWithSignatureAndEnsureVerificationFailure(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SIGNATURE); + let cert = certdb.constructX509FromBase64(base64); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +// The beginning of a certificate looks like this (in hex, using DER): +// 30 XX XX XX [the XX encode length - there are probably 3 bytes here] +// 30 XX XX XX [length again] +// A0 03 +// 02 01 +// 02 +// 02 XX [length again - 1 byte as long as we're using pycert] +// XX XX ... [serial number - 20 bytes as long as we're using pycert] +// Since we want to modify the serial number, we need to change something from +// byte 15 to byte 34 (0-indexed). If it turns out that the two length sections +// we assumed were 3 bytes are shorter (they can't be longer), modifying +// something from byte 15 to byte 30 will still get us what we want. Since the +// serial number is a DER INTEGER and because it must be positive, it's best to +// skip the first two bytes of the serial number so as to not run into any +// issues there. Thus byte 17 is a good byte to modify. +const BYTE_IN_SERIAL_NUMBER = 17; +function addSerialNumberTamperedCertificate(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SERIAL_NUMBER); + certdb.addCertFromBase64(base64, ",,"); +} + +function tamperWithSerialNumberAndEnsureVerificationFailure(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SERIAL_NUMBER); + let cert = certdb.constructX509FromBase64(base64); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_cert_signatures/ca-rsa.pem", "CTu,,"); + addCertFromFile(certdb, "test_cert_signatures/ca-secp384r1.pem", "CTu,,"); + + // Tamper with the signatures on intermediate certificates and ensure that + // end-entity certificates issued by those intermediates do not validate + // successfully. + addSignatureTamperedCertificate("test_cert_signatures/int-rsa.pem"); + addSignatureTamperedCertificate("test_cert_signatures/int-secp384r1.pem"); + await ensureSignatureVerificationFailure("test_cert_signatures/ee-rsa.pem"); + await ensureSignatureVerificationFailure( + "test_cert_signatures/ee-secp384r1.pem" + ); + + // Tamper with the signatures on end-entity certificates and ensure that they + // do not validate successfully. + await tamperWithSignatureAndEnsureVerificationFailure( + "test_cert_signatures/ee-rsa-direct.pem" + ); + await tamperWithSignatureAndEnsureVerificationFailure( + "test_cert_signatures/ee-secp384r1-direct.pem" + ); + + // Tamper with the serial numbers of intermediate certificates and ensure + // that end-entity certificates issued by those intermediates do not validate + // successfully. + addSerialNumberTamperedCertificate("test_cert_signatures/int-rsa.pem"); + addSerialNumberTamperedCertificate("test_cert_signatures/int-secp384r1.pem"); + await ensureSignatureVerificationFailure("test_cert_signatures/ee-rsa.pem"); + await ensureSignatureVerificationFailure( + "test_cert_signatures/ee-secp384r1.pem" + ); + + // Tamper with the serial numbers of end-entity certificates and ensure that + // they do not validate successfully. + await tamperWithSerialNumberAndEnsureVerificationFailure( + "test_cert_signatures/ee-rsa-direct.pem" + ); + await tamperWithSerialNumberAndEnsureVerificationFailure( + "test_cert_signatures/ee-secp384r1-direct.pem" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem new file mode 100644 index 0000000000..290b01e0b2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUJaZFyIe9qjfQ+Uofk9CZqYEHlTgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmNhLXJzYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBALa6fRuvA3KLtAMN +jeo0kNekw4UJ4eZK2m1XPHOEbrPXIZ9tTRAPPioOuNCLHYsj0038iu2tjpHmorgs +sCYSjvVxVxu9jWu2Ka99X/o8j1bH137Rrr9JpD1/Ur5/TvqjS4YmL+vhmogb9fr6 +1Duw6H9/L0E+KROhAQcxjAxe3kGHhBeIMLPFo4jtpTQo5rFUA2N1z9BHd7J3/zAv +T72inci5G739Uo2l2EeAWB3VtqrMCZeSLw4WbBJiRS9sO7Q3weIRH+k5qqBlKcB9 +hQnP+MXADWkphfe5AucI8aKY5fK5vCn2SlWQ+/6J3rnPkNUYVHkjKTnqkPBeoCeq +S3FICGE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec new file mode 100644 index 0000000000..5890d2db60 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-rsa +subject:ca-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem new file mode 100644 index 0000000000..fd92a46fef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjjCCARSgAwIBAgIUOyTEDH+eecqyzh2AucmMGj9fTLAwCgYIKoZIzj0EAwIw +FzEVMBMGA1UEAwwMY2Etc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGNhLXNlY3AzODRyMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMt +qM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC +8Fr3Gh/dzIN0qm6pzqMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYI +KoZIzj0EAwIDaAAwZQIxAO0GJz6haDpUtNgaQ3SESJY85j6+gRcD7Nc9cvCiVAZZ +1OxFRuhW515lVbeTqfcA8wIwEy0o836FaKqjhXZB1FUAVV+3Qr3iStR9Be83+S6N +9SZg7pExVwePnv4bYkrcja5s +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec new file mode 100644 index 0000000000..0701c23c1e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec @@ -0,0 +1,7 @@ +issuer:ca-secp384r1 +subject:ca-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem new file mode 100644 index 0000000000..3e1eef7d68 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuTCCAaGgAwIBAgIUfab+E3B6QwSzRFe7us5sNYBJa10wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBgxFjAUBgNVBAMMDWVlLXJzYS1kaXJlY3QwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAJMWIw3o4w2U4Nvw2R0QZ41JZDGMSRSj88Jc3rqU9R0RrmuJ +xWj1/PidCJGo0ZhKsBxgleezXqyxPrnm/2nIK6GValEbHQh5lybnGugnu8sjjHv0 +XRifYbr+Hw1IIs6ZCZbqt6X4BsbinS8Kj/SArptw45dnXYO+xQVkcZVXRj8tRuWo +9H3uWpnspur3Jod2fhhyEWTYYHiH/B7XtD81slgWrNwPFvsdDiiLqBgsZ7O/vDAO +zE7VowW8qcs7R3sNOZrPx5bW+uAp2LSpZVToLdInMzLuLA9DdUqppyE5uBQ+MgEy +s052+WQ549Z8LN0l8iLYs9Ir9p437jNw9sty12k= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec new file mode 100644 index 0000000000..4e25ddcf94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-rsa +subject:ee-rsa-direct diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem new file mode 100644 index 0000000000..7b368c2554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUG5+/xrLNQFse7iMoGWpBJsrHx84wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHaW50LXJzYTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjARMQ8wDQYDVQQDDAZlZS1yc2EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAFuOB6tFv6DrMoDrZcBwqptvrUE152IoCVT7M+p3VPIgTA4jyAm3tgog +ID3CZJmoYJrd+7HNDhFsjudGOF21k8z8snqSCCYBDETlLz5EKq5XmVGLw+hdKyZB +MtCmXXDr4qBFupN4D7x/1boqiB7L/AvDPOTk3H+UOF4xPLRFFSCZda0pAcbuPkAn +M07E1P9/qN6qBNp0/AT8tOHvcw5L2oSnfSJyYDCB+fStuh3MGj8crwq5sOprEWXp +5xxFiGM+0RyVTj6CqkJxb7UuY1g+rqKHxQo0CauF3g6pWFYz68NfHdOxiq17T5Ze +cc/o2Bl0HfldhPykzcdafPe4sEF0gxQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec new file mode 100644 index 0000000000..b974a0a0a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-rsa +subject:ee-rsa diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem new file mode 100644 index 0000000000..9a09340159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCB/KADAgECAhRfE+Et8NOs0+Akxjdd6jKTDpPw6jAKBggqhkjOPQQDAjAX +MRUwEwYDVQQDDAxjYS1zZWNwMzg0cjEwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIy +MDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTZWUtc2VjcDM4NHIxLWRpcmVjdDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22CO +JS3ktxMtqM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXED +viiIz/AC8Fr3Gh/dzIN0qm6pzjAKBggqhkjOPQQDAgNoADBlAjEA7QYnPqFoOlS0 +2BpDdIRIljzmPr6BFwPs1z1y8KJUBlnU7EVG6FbnXmVVt5Op9wDzAjAYYo+yN543 +lFkKtNGxnw22Jtgv0oA8co0+1n9dOxz8zTR0msc+9jzshYa7VZQ0hNA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec new file mode 100644 index 0000000000..386ab95f78 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-secp384r1 +subject:ee-secp384r1-direct +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem new file mode 100644 index 0000000000..1baaad5156 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcDCB9qADAgECAhRPYP/LpKATb8Eee6XdLyXiGnwgJzAKBggqhkjOPQQDAjAY +MRYwFAYDVQQDDA1pbnQtc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLXNlY3AzODRyMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMt +qM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC +8Fr3Gh/dzIN0qm6pzjAKBggqhkjOPQQDAgNpADBmAjEA7QYnPqFoOlS02BpDdIRI +ljzmPr6BFwPs1z1y8KJUBlnU7EVG6FbnXmVVt5Op9wDzAjEAx9LL4IWV8HF8MrGQ +ZdFqG+sVSQ3QCUcEsVjGG/gZ6RcMlEnjW21iGqxnIZpKtiTN +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec new file mode 100644 index 0000000000..b8f7993be8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-secp384r1 +subject:ee-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem new file mode 100644 index 0000000000..49f8879ed2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0jCCAbqgAwIBAgIURzatuu7JX78XkY/w99jKWmox0howDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBIxEDAOBgNVBAMMB2ludC1yc2EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQF +MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAQ64v/9Z3EylV0 +lsRQI0PevDlAIEL8YHGBJWToq++WJGC3eemcoxyvvw1b9rvZgdkrrjx/+bjtOJci +7kloRJ2xiZOYQlqvnpwFcNqTlMDZnuWkPX50ZBUelqk4R6cwm0HB1VFIN+GOwCMD +zCC7t4a66HhAiqaejMDVcWMzw9VqytWgwm/isui/uBYQW84NGI1GKy1cIk770S6Q +J6HTKE6LM526ytMjIlGBtN9D7hl7K8AMuupKySA2QASodOrAJqoT5U2hlCl5OviF +OjmxnbgvveU6kdKN8a7z7y3uTkjhZpef81ImbF1jj8E1KtkC+b7Lm/CbK+IiEXxL +u9pvfao3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec new file mode 100644 index 0000000000..a86d28b44a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-rsa +subject:int-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem new file mode 100644 index 0000000000..ab896dbead --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjzCCARWgAwIBAgIUMSRDv+0O5jNq1Obl2F8M+xzDNGUwCgYIKoZIzj0EAwIw +FzEVMBMGA1UEAwwMY2Etc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBgxFjAUBgNVBAMMDWludC1zZWNwMzg0cjEwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcT +LajOmOgxU05qnAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/w +AvBa9xof3cyDdKpuqc6jHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA2gAMGUCMQDtBic+oWg6VLTYGkN0hEiWPOY+voEXA+zXPXLwolQG +WdTsRUboVudeZVW3k6n3APMCMCNZB4rLFK+Njz93hs7gAv/HPo9isW3PSdPN7Dt6 +5lZVYZzti2Ram/Fr4ki+/pP+/g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec new file mode 100644 index 0000000000..e002a1569a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec @@ -0,0 +1,7 @@ +issuer:ca-secp384r1 +subject:int-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/moz.build b/security/manager/ssl/tests/unit/test_cert_signatures/moz.build new file mode 100644 index 0000000000..f2bbe7a375 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-rsa.pem', +# 'ca-secp384r1.pem', +# 'ee-rsa-direct.pem', +# 'ee-rsa.pem', +# 'ee-secp384r1-direct.pem', +# 'ee-secp384r1.pem', +# 'int-rsa.pem', +# 'int-secp384r1.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_storage.js b/security/manager/ssl/tests/unit/test_cert_storage.js new file mode 100644 index 0000000000..ff0d1f24c8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage.js @@ -0,0 +1,286 @@ +/* -*- 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"; + +// This test checks a number of things: +// * it ensures that data loaded from revocations.txt on startup is present +// * it ensures that data served from OneCRL are persisted correctly +// * it ensures that items in the CertBlocklist are seen as revoked by the +// cert verifier +// * it does a sanity check to ensure other cert verifier behavior is +// unmodified + +const { setTimeout } = ChromeUtils.import( + "resource://gre/modules/Timer.jsm", + {} +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); + +// First, we need to setup appInfo for the blocklist service to work +var id = "xpcshell@tests.mozilla.org"; +var appName = "XPCShell"; +var version = "1"; +var platformVersion = "1.9.2"; +ChromeUtils.import("resource://testing-common/AppInfo.jsm", this); // Imported via AppInfo.jsm. +/* global updateAppInfo:false */ updateAppInfo({ + name: appName, + ID: id, + version, + platformVersion: platformVersion ? platformVersion : "1.0", + crashReporter: true, +}); + +// we need to ensure we setup revocation data before certDB, or we'll start with +// no revocation.txt in the profile +var gProfile = do_get_profile(); + +var gRevocations = gProfile.clone(); +gRevocations.append("revocations.txt"); +if (!gRevocations.exists()) { + let existing = do_get_file("test_onecrl/sample_revocations.txt", false); + existing.copyTo(gProfile, "revocations.txt"); +} + +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const certBlocklist = [ + // test with some bad data ... + { + issuerName: "Some nonsense in issuer", + serialNumber: "AkHVNA==", + }, + { + issuerName: "MA0xCzAJBgNVBAMMAmNh", + serialNumber: "some nonsense in serial", + }, + { + issuerName: "and serial", + serialNumber: "some nonsense in both issuer", + }, + // some mixed + // In these case, the issuer name and the valid serialNumber correspond + // to test-int.pem in bad_certs/ + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "oops! more nonsense.", + }, + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "a0X7/7DlTaedpgrIJg25iBPOkIM=", + }, + // ... and some good + // In this case, the issuer name and the valid serialNumber correspond + // to other-test-ca.pem in bad_certs/ (for testing root revocation) + { + issuerName: "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=", + serialNumber: "Rym6o+VN9xgZXT/QLrvN/nv1ZN4=", + }, + // These items correspond to an entry in sample_revocations.txt where: + // isser name is the base-64 encoded subject DN for the shared Test + // Intermediate and the serialNumbers are base-64 encoded 78 and 31, + // respectively. + // We need this to ensure that existing items are retained if they're + // also in the blocklist + { + issuerName: "MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl", + serialNumber: "Tg==", + }, + { + issuerName: "MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl", + serialNumber: "Hw==", + }, + // This item revokes same-issuer-ee.pem by subject and pubKeyHash. + { + subject: "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5", + pubKeyHash: "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=", + }, +]; + +function verify_cert(file, expectedError) { + let ee = constructCertFromFile(file); + return checkCertErrorGeneric( + certDB, + ee, + expectedError, + certificateUsageSSLServer + ); +} + +// The certificate blocklist currently only applies to TLS server certificates. +async function verify_non_tls_usage_succeeds(file) { + let ee = constructCertFromFile(file); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +} + +function load_cert(cert, trust) { + let file = "bad_certs/" + cert + ".pem"; + addCertFromFile(certDB, file, trust); +} + +async function update_blocklist() { + const { OneCRLBlocklistClient } = RemoteSecuritySettings.init(); + + const fakeEvent = { + current: certBlocklist, // with old .txt revocations. + deleted: [], + created: certBlocklist, // with new cert storage. + updated: [], + }; + await OneCRLBlocklistClient.emit("sync", { data: fakeEvent }); + // Save the last check timestamp, used by cert_storage to assert + // if the blocklist is «fresh». + Services.prefs.setIntPref( + OneCRLBlocklistClient.lastCheckTimePref, + Math.floor(Date.now() / 1000) + ); +} + +function* generate_revocations_txt_lines() { + let profile = do_get_profile(); + let revocations = profile.clone(); + revocations.append("revocations.txt"); + ok(revocations.exists(), "the revocations file should exist"); + let inputStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + inputStream.init(revocations, -1, -1, 0); + inputStream.QueryInterface(Ci.nsILineInputStream); + let hasmore = false; + do { + let line = {}; + hasmore = inputStream.readLine(line); + yield line.value; + } while (hasmore); +} + +function run_test() { + // import the certificates we need + load_cert("test-ca", "CTu,CTu,CTu"); + load_cert("test-int", ",,"); + load_cert("other-test-ca", "CTu,CTu,CTu"); + + let certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + + add_task(async function() { + // check some existing items in revocations.txt are blocked. + // This test corresponds to: + // issuer: MBIxEDAOBgNVBAMMB1Rlc3QgQ0E= (CN=Test CA) + // serial: Kg== (42) + let file = "test_onecrl/ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // This test corresponds to: + // issuer: MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl (CN=Test Intermediate) + // serial: Tg== (78) + file = "test_onecrl/another-ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // And this test corresponds to: + // issuer: MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl (CN=Test Intermediate) + // serial: Hw== (31) + // (we test this issuer twice to ensure we can read multiple serials) + file = "test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Test that a certificate revoked by subject and public key hash in + // revocations.txt is revoked + // subject: MCsxKTAnBgNVBAMMIEVFIFJldm9rZWQgQnkgU3ViamVjdCBhbmQgUHViS2V5 + // (CN=EE Revoked By Subject and PubKey) + // pubkeyhash: VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8 (this is the + // shared RSA SPKI) + file = "test_onecrl/ee-revoked-by-subject-and-pubkey.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Soon we'll load a blocklist which revokes test-int.pem, which issued + // test-int-ee.pem. + // Check the cert validates before we load the blocklist + file = "test_onecrl/test-int-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // The blocklist also revokes other-test-ca.pem, which issued + // other-ca-ee.pem. Check the cert validates before we load the blocklist + file = "bad_certs/other-issuer-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // The blocklist will revoke same-issuer-ee.pem via subject / pubKeyHash. + // Check the cert validates before we load the blocklist + file = "test_onecrl/same-issuer-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + }); + + // blocklist load is async so we must use add_test from here + add_task(update_blocklist); + + add_task(async function() { + // The blocklist will be loaded now. Let's check the data is sane. + // In particular, we should still have the revoked issuer / serial pair + // that was in revocations.txt but not the blocklist. + let file = "test_onecrl/ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // We should also still have the revoked issuer / serial pairs that were in + // revocations.txt and are also in the blocklist. + file = "test_onecrl/another-ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + file = "test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // The cert revoked by subject and pubkeyhash should still be revoked. + file = "test_onecrl/ee-revoked-by-subject-and-pubkey.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Check the blocklisted intermediate now causes a failure + file = "test_onecrl/test-int-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check the ee with the blocklisted root also causes a failure + file = "bad_certs/other-issuer-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check the ee blocked by subject / pubKey causes a failure + file = "test_onecrl/same-issuer-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check a non-blocklisted chain still validates OK + file = "bad_certs/default-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // Check a bad cert is still bad (unknown issuer) + file = "bad_certs/unknownissuer.pem"; + await verify_cert(file, SEC_ERROR_UNKNOWN_ISSUER); + }); + + add_task(async function() { + ok(certList.isBlocklistFresh(), "Blocklist should be fresh."); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js b/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js new file mode 100644 index 0000000000..070482f236 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js @@ -0,0 +1,95 @@ +/* -*- 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"; + +// This file tests cert_storage's automatic database recreation mechanism. If +// opening the database for the first time fails, cert_storage will re-create +// it. + +function call_has_prior_data(certStorage, type) { + return new Promise(resolve => { + certStorage.hasPriorData(type, (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + }); + }); +} + +async function check_has_prior_revocation_data(certStorage, expectedResult) { + let hasPriorRevocationData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_REVOCATION + ); + Assert.equal( + hasPriorRevocationData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior revocation data` + ); +} + +async function check_has_prior_cert_data(certStorage, expectedResult) { + let hasPriorCertData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_CERTIFICATE + ); + Assert.equal( + hasPriorCertData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior cert data` + ); +} + +async function check_has_prior_crlite_data(certStorage, expectedResult) { + let hasPriorCRLiteData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_CRLITE + ); + Assert.equal( + hasPriorCRLiteData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior CRLite data` + ); +} + +add_task(async function() { + // Create an invalid database. + let fileToCopy = do_get_file("test_cert_storage_broken_db.js"); + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + fileToCopy.copyTo(dbDirectory, "data.mdb"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + check_has_prior_revocation_data(certStorage, false); + check_has_prior_cert_data(certStorage, false); + check_has_prior_crlite_data(certStorage, false); + + let result = await new Promise(resolve => { + certStorage.setRevocations([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "setRevocations should succeed"); + + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, false); + check_has_prior_crlite_data(certStorage, false); + + result = await new Promise(resolve => { + certStorage.addCerts([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "addCerts should succeed"); + + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, true); + check_has_prior_crlite_data(certStorage, false); + + result = await new Promise(resolve => { + certStorage.setCRLiteState([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "setCRLiteState should succeed"); + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, true); + check_has_prior_crlite_data(certStorage, true); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct.js b/security/manager/ssl/tests/unit/test_cert_storage_direct.js new file mode 100644 index 0000000000..09d8a5bd17 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct.js @@ -0,0 +1,533 @@ +/* -*- 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"; + +// This file consists of unit tests for cert_storage (whereas test_cert_storage.js is more of an +// integration test). + +do_get_profile(); + +this.certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage +); + +async function addCerts(certInfos) { + let result = await new Promise(resolve => { + certStorage.addCerts(certInfos, resolve); + }); + Assert.equal(result, Cr.NS_OK, "addCerts should succeed"); +} + +async function removeCertsByHashes(hashesBase64) { + let result = await new Promise(resolve => { + certStorage.removeCertsByHashes(hashesBase64, resolve); + }); + Assert.equal(result, Cr.NS_OK, "removeCertsByHashes should succeed"); +} + +function getLongString(uniquePart, length) { + return String(uniquePart).padStart(length, "0"); +} + +class CertInfo { + constructor(cert, subject) { + this.cert = btoa(cert); + this.subject = btoa(subject); + this.trust = Ci.nsICertStorage.TRUST_INHERIT; + } +} +CertInfo.prototype.QueryInterface = ChromeUtils.generateQI(["nsICertInfo"]); + +add_task(async function test_common_subject() { + let someCert1 = new CertInfo( + "some certificate bytes 1", + "some common subject" + ); + let someCert2 = new CertInfo( + "some certificate bytes 2", + "some common subject" + ); + let someCert3 = new CertInfo( + "some certificate bytes 3", + "some common subject" + ); + await addCerts([someCert1, someCert2, someCert3]); + let storedCerts = certStorage.findCertsBySubject( + stringToArray("some common subject") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "some certificate bytes 1", + "some certificate bytes 2", + "some certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs" + ); + + await addCerts([ + new CertInfo("some other certificate bytes", "some other subject"), + ]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("some common subject") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should still find expected certs" + ); + + let storedOtherCerts = certStorage.findCertsBySubject( + stringToArray("some other subject") + ); + let storedOtherCertsAsStrings = storedOtherCerts.map(arrayToString); + let expectedOtherCerts = ["some other certificate bytes"]; + Assert.deepEqual( + storedOtherCertsAsStrings, + expectedOtherCerts, + "should have other certificate" + ); +}); + +add_task(async function test_many_entries() { + const NUM_CERTS = 500; + const CERT_LENGTH = 3000; + const SUBJECT_LENGTH = 40; + let certs = []; + for (let i = 0; i < NUM_CERTS; i++) { + certs.push( + new CertInfo( + getLongString(i, CERT_LENGTH), + getLongString(i, SUBJECT_LENGTH) + ) + ); + } + await addCerts(certs); + for (let i = 0; i < NUM_CERTS; i++) { + let subject = stringToArray(getLongString(i, SUBJECT_LENGTH)); + let storedCerts = certStorage.findCertsBySubject(subject); + Assert.equal( + storedCerts.length, + 1, + "should have 1 certificate (lots of data test)" + ); + let storedCertAsString = arrayToString(storedCerts[0]); + Assert.equal( + storedCertAsString, + getLongString(i, CERT_LENGTH), + "certificate should be as expected (lots of data test)" + ); + } +}); + +add_task(async function test_removal() { + // As long as cert_storage is given valid base64, attempting to delete some nonexistent + // certificate will "succeed" (it'll do nothing). + await removeCertsByHashes([btoa("thishashisthewrongsize")]); + + let removalCert1 = new CertInfo( + "removal certificate bytes 1", + "common subject to remove" + ); + let removalCert2 = new CertInfo( + "removal certificate bytes 2", + "common subject to remove" + ); + let removalCert3 = new CertInfo( + "removal certificate bytes 3", + "common subject to remove" + ); + await addCerts([removalCert1, removalCert2, removalCert3]); + + let storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "removal certificate bytes 1", + "removal certificate bytes 2", + "removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs before removing them" + ); + + // echo -n "removal certificate bytes 2" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["2nUPHwl5TVr1mAD1FU9FivLTlTb0BAdnVUhsYgBccN4="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + expectedCerts = [ + "removal certificate bytes 1", + "removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should only have first and third certificates now" + ); + + // echo -n "removal certificate bytes 1" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["8zoRqHYrklr7Zx6UWpzrPuL+ol8KL1Ml6XHBQmXiaTY="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + expectedCerts = ["removal certificate bytes 3"]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should only have third certificate now" + ); + + // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); + + // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + // Again, removing a nonexistent certificate should "succeed". + await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); +}); + +add_task(async function test_batched_removal() { + let removalCert1 = new CertInfo( + "batch removal certificate bytes 1", + "batch subject to remove" + ); + let removalCert2 = new CertInfo( + "batch removal certificate bytes 2", + "batch subject to remove" + ); + let removalCert3 = new CertInfo( + "batch removal certificate bytes 3", + "batch subject to remove" + ); + await addCerts([removalCert1, removalCert2, removalCert3]); + let storedCerts = certStorage.findCertsBySubject( + stringToArray("batch subject to remove") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "batch removal certificate bytes 1", + "batch removal certificate bytes 2", + "batch removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs before removing them" + ); + // echo -n "batch removal certificate bytes 1" | sha256sum | xxd -r -p | base64 + // echo -n "batch removal certificate bytes 2" | sha256sum | xxd -r -p | base64 + // echo -n "batch removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes([ + "EOEEUTuanHZX9NFVCoMKVT22puIJC6g+ZuNPpJgvaa8=", + "Xz6h/Kvn35cCLJEZXkjPqk1GG36b56sreLyAXpO+0zg=", + "Jr7XdiTT8ZONUL+ogNNMW2oxKxanvYOLQPKBPgH/has=", + ]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("batch subject to remove") + ); + Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); +}); + +class CRLiteState { + constructor(subject, spkiHash, state) { + this.subject = btoa(subject); + this.spkiHash = spkiHash; + this.state = state; + } +} +CRLiteState.prototype.QueryInterface = ChromeUtils.generateQI([ + "nsICRLiteState", +]); + +async function addCRLiteState(state) { + let result = await new Promise(resolve => { + certStorage.setCRLiteState(state, resolve); + }); + Assert.equal(result, Cr.NS_OK, "setCRLiteState should succeed"); +} + +add_task(async function test_crlite_state() { + // echo -n "some spki 1" | sha256sum | xxd -r -p | base64 + let crliteState1 = new CRLiteState( + "some subject 1", + "bDlKlhR5ptlvuxclnZ3RQHznG8/3pgIybrRJ/Zvn9L8=", + Ci.nsICertStorage.STATE_ENFORCE + ); + // echo -n "some spki 2" | sha256sum | xxd -r -p | base64 + let crliteState2 = new CRLiteState( + "some subject 2", + "ZlXvlHhtdx4yKwkhZqg7Opv5T1ofwzorlsCoLf0wnlY=", + Ci.nsICertStorage.STATE_UNSET + ); + // echo -n "some spki 3" | sha256sum | xxd -r -p | base64 + let crliteState3 = new CRLiteState( + "some subject 3", + "pp1SRn6njaHX/c+b2uf82JPeBkWhPfTBp/Mxb3xkjRM=", + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState1, crliteState2, crliteState3]); + + let state1 = certStorage.getCRLiteState( + stringToArray("some subject 1"), + stringToArray("some spki 1") + ); + Assert.equal(state1, Ci.nsICertStorage.STATE_ENFORCE); + let state2 = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 2") + ); + Assert.equal(state2, Ci.nsICertStorage.STATE_UNSET); + let state3 = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 3") + ); + Assert.equal(state3, Ci.nsICertStorage.STATE_ENFORCE); + + // Check that if we never set the state of a particular subject/spki pair, we get "unset" when we + // look it up. + let stateNeverSet = certStorage.getCRLiteState( + stringToArray("some unknown subject"), + stringToArray("some unknown spki") + ); + Assert.equal(stateNeverSet, Ci.nsICertStorage.STATE_UNSET); + + // "some subject 1"/"some spki 1" and "some subject 3"/"some spki 3" both have their CRLite state + // set. However, the combination of "some subject 3"/"some spki1" should not. + let stateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 1") + ); + Assert.equal(stateDifferentSubjectSPKI, Ci.nsICertStorage.STATE_UNSET); + + let anotherStateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 1"), + stringToArray("some spki 2") + ); + Assert.equal(anotherStateDifferentSubjectSPKI, Ci.nsICertStorage.STATE_UNSET); + let yetAnotherStateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 1") + ); + Assert.equal( + yetAnotherStateDifferentSubjectSPKI, + Ci.nsICertStorage.STATE_UNSET + ); + + crliteState3 = new CRLiteState( + "some subject 3", + "pp1SRn6njaHX/c+b2uf82JPeBkWhPfTBp/Mxb3xkjRM=", + Ci.nsICertStorage.STATE_UNSET + ); + await addCRLiteState([crliteState3]); + state3 = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 3") + ); + Assert.equal(state3, Ci.nsICertStorage.STATE_UNSET); + + crliteState2 = new CRLiteState( + "some subject 2", + "ZlXvlHhtdx4yKwkhZqg7Opv5T1ofwzorlsCoLf0wnlY=", + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState2]); + state2 = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 2") + ); + Assert.equal(state2, Ci.nsICertStorage.STATE_ENFORCE); + + // Inserting a subject/spki pair with a state value outside of our expected + // values will succeed. However, since our data type is a signed 16-bit value, + // values outside that range will be truncated. The least significant 16 bits + // of 2013003773 are FFFD, which when interpreted as a signed 16-bit integer + // comes out to -3. + // echo -n "some spki 4" | sha256sum | xxd -r -p | base64 + let bogusValueState = new CRLiteState( + "some subject 4", + "1eA0++hCqzt8vpzREYSqHAqpEOLchZca1Gx8viCVYzc=", + 2013003773 + ); + await addCRLiteState([bogusValueState]); + let bogusValueStateValue = certStorage.getCRLiteState( + stringToArray("some subject 4"), + stringToArray("some spki 4") + ); + Assert.equal(bogusValueStateValue, -3); +}); + +async function enrollCertForCRLite(nsCert) { + let { subjectString, spkiHashString } = getSubjectAndSPKIHash(nsCert); + let crliteState = new CRLiteState( + subjectString, + spkiHashString, + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState]); +} + +add_task(async function test_crlite_filter() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let validCertIssuer = constructCertFromFile( + "test_cert_storage_direct/valid-cert-issuer.pem" + ); + await enrollCertForCRLite(validCertIssuer); + let validCert = constructCertFromFile( + "test_cert_storage_direct/valid-cert.pem" + ); + let revokedCertIssuer = constructCertFromFile( + "test_cert_storage_direct/revoked-cert-issuer.pem" + ); + await enrollCertForCRLite(revokedCertIssuer); + let revokedCert = constructCertFromFile( + "test_cert_storage_direct/revoked-cert.pem" + ); + + let filterFile = do_get_file( + "test_cert_storage_direct/test-filter.crlite", + false + ); + ok(filterFile.exists(), "test filter file should exist"); + let filterBytes = stringToArray(readFile(filterFile)); + // First simulate the filter being from before the certificates being tested are valid. With + // CRLite enabled, none of the certificates should appear to be revoked. + let setFullCRLiteFilterResult = await new Promise(resolve => { + certStorage.setFullCRLiteFilter( + filterBytes, + new Date("2017-10-28T00:00:00Z").getTime() / 1000, + resolve + ); + }); + Assert.equal( + setFullCRLiteFilterResult, + Cr.NS_OK, + "setFullCRLiteFilter should succeed" + ); + + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // Now "replace" the filter with a more recent one. The revoked certificate should be revoked. + setFullCRLiteFilterResult = await new Promise(resolve => { + certStorage.setFullCRLiteFilter( + filterBytes, + new Date("2019-10-28T00:00:00Z").getTime() / 1000, + resolve + ); + }); + Assert.equal( + setFullCRLiteFilterResult, + Cr.NS_OK, + "setFullCRLiteFilter should succeed" + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // If we're only collecting telemetry, none of the certificates should appear to be revoked. + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeTelemetryOnlyPrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // If CRLite is disabled, none of the certificates should appear to be revoked. + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeDisabledPrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem new file mode 100644 index 0000000000..d775817b33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoDCCA4igAwIBAgIQBpaPlkroI1bHThfCtTZbADANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTE3MTEwNjEyMjI1N1oXDTI3MTEwNjEyMjI1N1owXzEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEeMBwGA1UEAxMVVGhhd3RlIEVWIFJTQSBDQSAyMDE4MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp0Cu52zmdJFnSezXMKvL0rso +WgA/1X7OxjMQHsAllID1eDG836ptJXSTPg+DoEenHfkKyw++wXobgahr0cU/2v8R +WR3fID53ZDhEGHzS+Ol7V+HRtZG5teMWCY7gldtBQH0r7xUEp/3ISVsZUVBqtUmL +VJlf9nxJD6Cxp4LBlcJJ8+N6kSkV+fA+WdQc0HYhXSg3PxJP7XSU28Wc7gf6y9kZ +zQhK4WrZLRrHHbHC2QXdqQYUxR927QV+UCNXnlbTcZy2QpxWTPLzK+/cKXX4cwP6 +MGF7+8RnUgHlij/5V2k/tIF9ep4B72ucqaS/UhEPpIN/T7A3OAw995yrB38glQID +AQABo4IBSTCCAUUwHQYDVR0OBBYEFOcB/AwWGMp9sozshyejb2GBO4Q5MB8GA1Ud +IwQYMBaAFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA4GA1UdDwEB/wQEAwIBhjAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADA0 +BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v +RGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYE +VR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT +MA0GCSqGSIb3DQEBCwUAA4IBAQAWGka+5ffLpfFuzT+WlwDRwhyTZSunnvecZWZT +PPKXipynjpXx5dK8YG+2XoH74285GR1UABuvHMFV94XeDET9Pzz5s/NHS1/eAr5e +GdwfBl80XwPkwXaYqzRtw6J4RAxeLqcbibhUQv9Iev9QcP0kNPyJu413Xov76mSu +JlGThKzcurJPive2eLmwmoIgTPH11N/IIO9nHLVe8KTkt+FGgZCOWHA3kbFBZR39 +Mn2hFS974rhUkM+VS9KbCiQQ5OwkfbZ/6BINkE1CMtiESZ2WkbxJKPsF3dN7p9DF +YWiQSbYjFP+rCT0/MkaHHYUkEvLNPgyJ6z29eMf0DjLu/SXJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem new file mode 100644 index 0000000000..81e01bd783 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHOzCCBiOgAwIBAgIQBi31aKBRMQgg1+xDJ+G6/TANBgkqhkiG9w0BAQsFADBf +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMR4wHAYDVQQDExVUaGF3dGUgRVYgUlNBIENBIDIwMTgw +HhcNMTgwNTI4MDAwMDAwWhcNMjAwNTIxMTIwMDAwWjCB6zEdMBsGA1UEDwwUUHJp +dmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCREUxFjAUBgsrBgEE +AYI3PAIBAhMFSGVzc2UxGDAWBgsrBgEEAYI3PAIBAQwHR2llw59lbjERMA8GA1UE +BRMISFJCIDY5MDIxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIZXNzZW4xFDASBgNV +BAcTC0hldWNoZWxoZWltMRQwEgYDVQQKEwtTY2h1bmsgR21iSDELMAkGA1UECxMC +SVQxGTAXBgNVBAMTEHNjaHVuay1ncm91cC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCvkuQZz2ExPv9paJb622OOk+o4bWnjDe1zHGK6qnK25mMT +Zldk74sXF+Wfr9lbwqHTcjGhQFwmVDqvtr55KVX8FOv0CSqNaewOrnNrFz8Xg4rn +OlIs3+MmqD5CIK+el0rA+xltEY8WvNlwZKG7yeJYrdsr+5DAThDuwCVe8bU7it4h +sjsMsof5ocee9zDkFThNVGR4sMk5EgBxb1Gt4n9wXUj4OBT78whhlkLH/pVZrrhs +tQwC3q90MOPC5RJcEolSCNjGdHCKRbexmRqJgbJj/qZ9JT+fQ+Ko6a+UAWvc2BUc +POnzGV2GzCdFFGOubJb6RjU0nuPG4Lmdc/BuS9kFAgMBAAGjggNkMIIDYDAfBgNV +HSMEGDAWgBTnAfwMFhjKfbKM7Icno29hgTuEOTAdBgNVHQ4EFgQUNb1SY8Bkil98 +tD8zoxE30jBA1NIwZwYDVR0RBGAwXoIQc2NodW5rLWdyb3VwLmNvbYIUd3d3LnNj +aHVuay1ncm91cC5jb22CG3NjaHVuay1jYXJib250ZWNobm9sb2d5LmNvbYIXc2No +dW5rLXNpbnRlcm1ldGFscy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY2Rw +LnRoYXd0ZS5jb20vVGhhd3RlRVZSU0FDQTIwMTguY3JsMEsGA1UdIAREMEIwNwYJ +YIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv +bS9DUFMwBwYFZ4EMAQEwcQYIKwYBBQUHAQEEZTBjMCQGCCsGAQUFBzABhhhodHRw +Oi8vc3RhdHVzLnRoYXd0ZS5jb20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9jYWNlcnRz +LnRoYXd0ZS5jb20vVGhhd3RlRVZSU0FDQTIwMTguY3J0MAkGA1UdEwQCMAAwggF7 +BgorBgEEAdZ5AgQCBIIBawSCAWcBZQB1AKS5CZC0GFgUh7sTosxncAo8NZgE+Rvf +uON3zQ7IDdwQAAABY6Ze9XAAAAQDAEYwRAIgNUeXL3GwlpGQtTS/wKBlOkHJvHR5 +knSop0OPumeCfQECIEdxY7qr/WRVbWkQFvP48fgWkZHkd4vTq70Y0aaSZTbPAHUA +VhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFjpl71tQAABAMARjBE +AiAtxKdc/wum3TE7r9BoRd/gkrjYLWyqeLuL/opRBRy9xwIgPF6uEZxyhEoLZ+9G +AFBAP+X89zjZphVALjIXu0RRea4AdQC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQ +lmQ2jh7RhQAAAWOmXvY1AAAEAwBGMEQCIHc04ERlUbIkVrlC+I89C9xtugvRCwbR +a7qZzSdqHltUAiBRVwTacf1dnO9AgLSgrxft5LV32DvH3qNT7pWYh8dFNjANBgkq +hkiG9w0BAQsFAAOCAQEARJ+tbnM+yS6chgpyzfB3e7IWPq2Den46Ja1H6/4qaKrd +nsbElcvd4cCQf1zYY6jlQkO6qtfMUChKrEar5aqqnyX8x/8T9PkpHp8XyUxgGlmT +hrnHML0gDJFS8O4MB5pFnGkgoOQa+OIQokWCXr4/a4AwsTG3Ms+lC+R+vRYz90lg +TEJLNHB2fSvQyvpXDUL9aAjACBp/9pKxfM9iq06MFO5jP483xJUfdqtVteHMw75w +1mb8IrM9R1dP47GsblTrf2rZYdaoxdyLjtJQG2aaOdU5unE6QeFrXbz0qeTPePs8 +ftuXSW9xb053HjAkCcVo48j07b2cHfU1hxzGGptVbQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite Binary files differnew file mode 100644 index 0000000000..34ced4b840 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash Binary files differnew file mode 100644 index 0000000000..1dbea0be47 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem new file mode 100644 index 0000000000..705827a85e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkDCCA3igAwIBAgIJIrmxUyPlrv3NMA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTIwHhcNMTgwODIy +MDczMjI0WhcNMjgwODIyMDczMjI0WjBQMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEaMBgGA1UEAxMRQ3Jvc3NUcnVz +dCBEViBDQTUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnTNi5Kgrt +FL8qBuEmpL2gvLFY7f9MEgjzClvic/45ebM+DxZ2CMuqtMtImgf8XPIpLaFFbozx +3VgqH41cmGHbpAoDRKpwfF1f53peHYhRxpOVgcnsiVCPZJPBPCUM9St+cuEjfo0d +YGbr3aG5urdT2zeKIFyxKbggdkU0LVRHwvLFsIpXCn/YK/8Rmx87yW9VB80OXkzf +IQoZop83+aebq1VwzjNCN3u4bWSFLYDyJGqE40WlZ53NZh+TwBsa6gld9YXPGQfx +k8x38zkFXberlMQOYhX9KyuTOMdlFkbx6LfIUqVKJavpcr54+XPzVyeroNPpKxtZ +mEqUYiFjAqUVAgMBAAGjggFeMIIBWjAdBgNVHQ4EFgQUT4twz6lAHJbllF13rNZv +TS2b8ncwHwYDVR0jBBgwFoAUCoWpd2UFmHxAgfgPlyw48QrsPM8wEgYDVR0TAQH/ +BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwSQYDVR0fBEIwQDA+oDygOoY4aHR0 +cDovL3JlcG9zaXRvcnkuc2Vjb210cnVzdC5uZXQvU0MtUm9vdDIvU0NSb290MkNS +TC5jcmwwUgYDVR0gBEswSTBHBgoqgwiMmxtkhwUEMDkwNwYIKwYBBQUHAgEWK2h0 +dHBzOi8vcmVwb3NpdG9yeS5zZWNvbXRydXN0Lm5ldC9TQy1Sb290Mi8wQAYIKwYB +BQUHAQEENDAyMDAGCCsGAQUFBzABhiRodHRwOi8vc2Nyb290Y2EyLm9jc3Auc2Vj +b210cnVzdC5uZXQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQAD +ggEBABEDSrrhhR+Js5q45yih2Ne4cMLZmrH0AZwU3eM+7HZplzi1EhppgvcYk/2k +LM9haQGWnAZ5wiixLqKu7WlWrHgblZbXyCxALmMBK1rqeP0omxXExqKVqWNHU8KZ +t3jahH1wDYSzfetM7guWR+PAPpb9oQCtAx8DVyI/3Ocswvti/uWb517Bdo6Nd0+9 +mf0LiphNKcSzSFX0s1Cb47cJROYHGBe2J6NUSWR7wE0asPtKsznGyNO+NJCUR+0h +OLN2cA2KJwPhZjYJt8UkucAF/EE7qC0Fc8B9Q/gttQ52en5BZxdkDrHCi4qnsSvi +gueQme/RzYkEaQlNT1WCZ9AIgVE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem new file mode 100644 index 0000000000..195d2d8ca2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF4DCCBMigAwIBAgIQC3d196+a5UJlyc0yVxB3jjANBgkqhkiG9w0BAQsFADBQ +MQswCQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4s +TFRELjEaMBgGA1UEAxMRQ3Jvc3NUcnVzdCBEViBDQTUwHhcNMTkwNjExMDUyMjEy +WhcNMjEwNjMwMTQ1OTU5WjAUMRIwEAYDVQQDEwlza3luZXcuanAwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeciw7C297026HA4oIwc29vL2h29GVrRF7 +HGdeXzAJA7kh+qwo8rTBFfdX7sgHy6nnE1+flEtFt91Ss8i3BZMEqoFUZFb1jGXd +DbQtmIWxz7O5skkjR1gdKwt9GImy1hEPt8dwU52mwVsSUEKvlZlsjeofUPAEbnYY ++iA/nYaYXiXyCxJzk6Y09VlzghyMIhkLwDa7rL3S9FgUQI6tSUwsiNYNoQzlYgXF +yPfQfd57LbBwZJtqVPC6rjPOZZd0sw7uvrDNuxnAM2k2mzlML9Vwt8EvSlZX60xD +oGQCsQQ/ZgjEQTA8WRZ+fxW/LqQNYYm70KU/1M+e8o4MKmA9xkH5AgMBAAGjggLw +MIIC7DAfBgNVHSMEGDAWgBRPi3DPqUAcluWUXXes1m9NLZvydzA8BggrBgEFBQcB +AQQwMC4wLAYIKwYBBQUHMAGGIGh0dHA6Ly9kdmNhNS5vY3NwLnNlY29tdHJ1c3Qu +bmV0MCMGA1UdEQQcMBqCCXNreW5ldy5qcIINd3d3LnNreW5ldy5qcDBaBgNVHSAE +UzBRMEUGCiqDCIybG26BVQIwNzA1BggrBgEFBQcCARYpaHR0cHM6Ly9yZXBvMS5z +ZWNvbXRydXN0Lm5ldC9zcHBjYS94dGR2NS8wCAYGZ4EMAQIBMBMGA1UdJQQMMAoG +CCsGAQUFBwMBMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9yZXBvMS5zZWNvbXRy +dXN0Lm5ldC9zcHBjYS94dGR2NS9mdWxsY3JsLmNybDAdBgNVHQ4EFgQUuj9305tQ +JIeVAQtsz9JHx3PTqaQwDgYDVR0PAQH/BAQDAgWgMIIBfgYKKwYBBAHWeQIEAgSC +AW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWtF +Bb6pAAAEAwBHMEUCIHUQkmFzUh01r1Px/zWMZSL21dNNQwM+rN1z0gutxV3JAiEA +jSb2/GAm4+2qiNWDtx1EkHsMXjNW+5S4GhJePexjJR8AdgDuS723dc5guuFCaR+r +4Z5mow9+X7By2IMAxHuJeqj9ywAAAWtFBcdeAAAEAwBHMEUCIDVHdfP9wnVgz45l +eX80DpRCRNEV/OCDwfW+B0g/dveYAiEArbpLQb5Z9hul3r00kF2LrivNuI7kwEBy +MpkYsLtSPJoAdgBvU3asMfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAWtF +BdCQAAAEAwBHMEUCIE2GUo6x3qDrIhacnCmjikBCHF2yT6Fv5GAehZB569YCAiEA +vXwMXV8+y3xNFys+A6u9EjKiy8CTKv+SQxqsJ4s6jK0wDQYJKoZIhvcNAQELBQAD +ggEBAAzlm9W+N5fviTJ9wDsc5nXKYur3744V/cm75+8dUM61Rko1isK6IZt5aNPN +wOfhBsTzHHSYmAFMR9Xjoq8iDYZtIk01IGI6LEWuls9F2hVcERiHMWJOLTiH35xN +vRNTG0AbBdIpTX2sURsoCPJ+8DTnVUr3pTzXnIY4EQ4UXfANuYwceOHShF6UJo/L +PK0uRdHcd5SmMa03gFUdkTc9gU6PIEO/UgubazGh9xDBHtHECeleL+gpSfOP3SkF +7W1RgmbE6WJdVPlto7FRQtl2xIzHs/gNaPezqNKPHgFlx4c+ECTjPLqoW8LdeXu+ +N8dueJg1+h+lQifkmgl23DqEIiI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js b/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js new file mode 100644 index 0000000000..153fdc56f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js @@ -0,0 +1,59 @@ +/* -*- 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"; + +// This file tests that cert_storage correctly persists its "has prior data" +// information across runs of the browser. +// (The test DB files for this test were created by running the test +// `test_cert_storage_broken_db.js` and copying them from that test's profile +// directory.) + +/* eslint-disable no-unused-vars */ +add_task(async function() { + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + let dbFile = do_get_file("test_cert_storage_preexisting/data.safe.bin"); + dbFile.copyTo(dbDirectory, "data.safe.bin"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let hasPriorRevocationData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_REVOCATION, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal( + hasPriorRevocationData, + true, + "should have prior revocation data" + ); + + let hasPriorCertData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CERTIFICATE, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal(hasPriorCertData, true, "should have prior cert data"); + + let hasPriorCRLiteData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CRLITE, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal(hasPriorCRLiteData, true, "should have prior cert data"); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb Binary files differnew file mode 100644 index 0000000000..df4cb182a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin Binary files differnew file mode 100644 index 0000000000..011ed93484 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb Binary files differnew file mode 100644 index 0000000000..dc4b50fdfc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js new file mode 100644 index 0000000000..0c6ffbd459 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js @@ -0,0 +1,71 @@ +/* -*- 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"; + +// This file tests that cert_storage correctly persists its information across +// runs of the browser specifically in the case of CRLite. +// (The test DB files for this test were created by running the test +// `test_cert_storage_direct.js` and copying them from that test's profile +// directory.) + +/* eslint-disable no-unused-vars */ +add_task(async function() { + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + let dbFile = do_get_file( + "test_cert_storage_preexisting_crlite/data.safe.bin" + ); + dbFile.copyTo(dbDirectory, "data.safe.bin"); + let crliteFile = do_get_file( + "test_cert_storage_preexisting_crlite/crlite.filter" + ); + crliteFile.copyTo(dbDirectory, "crlite.filter"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let validCertIssuer = constructCertFromFile( + "test_cert_storage_direct/valid-cert-issuer.pem" + ); + let validCert = constructCertFromFile( + "test_cert_storage_direct/valid-cert.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-10-28T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + let revokedCertIssuer = constructCertFromFile( + "test_cert_storage_direct/revoked-cert-issuer.pem" + ); + let revokedCert = constructCertFromFile( + "test_cert_storage_direct/revoked-cert.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter Binary files differnew file mode 100644 index 0000000000..34ced4b840 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin Binary files differnew file mode 100644 index 0000000000..d96571f128 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin diff --git a/security/manager/ssl/tests/unit/test_cert_storage_prefs.js b/security/manager/ssl/tests/unit/test_cert_storage_prefs.js new file mode 100644 index 0000000000..ca7e06ece9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_prefs.js @@ -0,0 +1,34 @@ +/* -*- 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 cert_storage properly handles its preference values. + +function run_test() { + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + // Since none of our prefs start with values, looking them up will fail. cert_storage should use + // safe fallbacks. + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness shouldn't crash" + ); + + // If we set nonsensical values, cert_storage should still use safe fallbacks. + Services.prefs.setIntPref("services.blocklist.onecrl.checked", -2); + Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds", -7); + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness still shouldn't crash" + ); + + // Clearing prefs shouldn't cause failures. + Services.prefs.clearUserPref("services.blocklist.onecrl.checked"); + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness again shouldn't crash" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js new file mode 100644 index 0000000000..43fbaa6174 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust.js @@ -0,0 +1,324 @@ +// -*- 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"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert_name, trust_string) { + let cert_filename = cert_name + ".pem"; + return addCertFromFile( + certdb, + "test_cert_trust/" + cert_filename, + trust_string + ); +} + +function setup_basic_trusts(ca_cert, int_cert) { + certdb.setCertTrust( + ca_cert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL | Ci.nsIX509CertDB.TRUSTED_EMAIL + ); + + certdb.setCertTrust(int_cert, Ci.nsIX509Cert.CA_CERT, 0); +} + +async function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA) { + // On reset most usages are successful + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Test of active distrust. No usage should pass. + setCertTrust(cert_to_modify_trust, "p,p,p"); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailRecipient + ); + + // Trust set to T - trusted CA to issue client certs, where client cert is + // usageSSLClient. + setCertTrust(cert_to_modify_trust, "T,T,T"); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLServer + ); + + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLClient + ); + + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Now tests on the SSL trust bit + setCertTrust(cert_to_modify_trust, "p,C,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); + + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Inherited trust SSL + setCertTrust(cert_to_modify_trust, ",C,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLServer + ); + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Now tests on the EMAIL trust bit + setCertTrust(cert_to_modify_trust, "C,p,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailRecipient + ); + + // inherited EMAIL Trust + setCertTrust(cert_to_modify_trust, "C,,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +} + +add_task(async function() { + let certList = ["ca", "int", "ee"]; + let loadedCerts = []; + for (let certName of certList) { + loadedCerts.push(load_cert(certName, ",,")); + } + + let ca_cert = loadedCerts[0]; + notEqual(ca_cert, null, "CA cert should have successfully loaded"); + let int_cert = loadedCerts[1]; + notEqual(int_cert, null, "Intermediate cert should have successfully loaded"); + let ee_cert = loadedCerts[2]; + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + setup_basic_trusts(ca_cert, int_cert); + await test_ca_distrust(ee_cert, ca_cert, true); + + setup_basic_trusts(ca_cert, int_cert); + await test_ca_distrust(ee_cert, int_cert, false); + + // Reset trust to default ("inherit trust") + setCertTrust(ca_cert, ",,"); + setCertTrust(int_cert, ",,"); + + // End-entities can be trust anchors for interoperability with users who + // prefer not to build a hierarchy and instead directly trust a particular + // server certificate. + setCertTrust(ee_cert, "CTu,CTu,CTu"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ca.pem b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem new file mode 100644 index 0000000000..45de962523 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUVSmns5EZzUHKobrhxdpy/ZtJMucwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQATPLfx55bklmCWgjlOjZjD8EpY +fenI0HAkE0044+KmVlFSpsETog4OK0aZKYKwDysClM/ZipzBpmcZ4ZczM0TbtC7/ +d8nfUmT5R/sXBuMmeNIioAn6J5JaSctKQbsVta9GwIyJUBuYIvccL1c5wUuxV8xf +CaTrFgKWkDWkhOEY+TN/95l+Cm0Gwc3l+jom5UrPRyw9Cb5AhRiRc+x3HhgJ2hGe +kKo4K/AfH/jE7U0u4VM+VZTQf5K92aih3f54vPW+yFfMkgFgzHtwIrj1WStknR7u +yRjBCHfjuoOgQLm1svKtpgnMbRhucCkW+mifY+ZbE51vYMiRlK3sHj9hz3ol +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec new file mode 100644 index 0000000000..d809dbd635 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ee.pem b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem new file mode 100644 index 0000000000..37db649572 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUKXfW0gwCmh3GP4O2Z+Kd/CYbINgwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozUwMzAxBgNVHSUEKjAoBggrBgEF +BQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMEBggrBgEFBQcDAzANBgkqhkiG9w0BAQsF +AAOCAQEArrxwO26t+coTY3AKAoLTFj8Syt469PatjuQA911/QB64+YYrIEs4KTCZ +HHx4/WvWAttXNtYV7NYiLXJOTfJUYKr9MdoM6S4C9HHh3oBzkKvNyg7hM6RKr1va +qd/OVJMulsJ1oP2x2tHeK3k0GkG70yplUxFiaQZ4KVCHsfUo5GPergooQoM64jXC +ILBF/YJ3vtox2AiNCAA8Vv742CBavsq3bOVN2VxZ/B8yBd5D366UBP39TSRdWHH5 +X3dJWkJ1vkJMmWSbP03zNbqG4H0Qimq5Pywr4uUkmckx6ZclEoGbxozutdMx8u9B +erZH6etD3bj9ExPVUcf4qHfcJUrmdQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec new file mode 100644 index 0000000000..9666c18062 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:ee +extension:extKeyUsage:serverAuth,clientAuth,emailProtection,codeSigning diff --git a/security/manager/ssl/tests/unit/test_cert_trust/int.pem b/security/manager/ssl/tests/unit/test_cert_trust/int.pem new file mode 100644 index 0000000000..44e6a36efa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/int.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUNbjVwdBjmiBHgijAyjyGIHuhJqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDjEMMAoGA1UEAwwDaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAO35vcl2OA9fAarEgTCrS42CL +5BeNfQLO7QCIdMZBfcIrQ6v5yw7i07pYGptagz/76OwYOsKO1lqb7sr2nTCNovVp +Co4dCAGQI460C6x3BOG7qyCFgZvf17xXl5filhMZw93LkWaeEIp8JmOTb511i1Bv +1akdFJ+xW40AuHE7EswLXzN0eu+tVAMJcsuxibK3jTkEdIjFCVwMD/7LC1rcoKcg +V18MHbh0zcDrXzo/jk8JfjqkOH5eylBtX2DH/9BjFcKzZDvZQFYlhsmADRHOmqvi +YoEXJj2A6fRzONsNKtQQbmVGvW/rHP7/YIiaAvn0kNb/FDtSqmTcLazSYpRewQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec new file mode 100644 index 0000000000..a7f6d81419 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_trust/moz.build b/security/manager/ssl/tests/unit/test_cert_trust/moz.build new file mode 100644 index 0000000000..8338b13334 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/moz.build @@ -0,0 +1,15 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee.pem', +# 'int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_utf8.js b/security/manager/ssl/tests/unit/test_cert_utf8.js new file mode 100644 index 0000000000..caeddd8158 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8.js @@ -0,0 +1,79 @@ +// -*- 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"; + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function run_test() { + // This certificate has a number of placeholder byte sequences that we can + // replace with invalid UTF-8 to ensure that we handle these cases safely. + let certificateToAlterFile = do_get_file( + "test_cert_utf8/certificateToAlter.pem", + false + ); + let certificateBytesToAlter = atob( + pemToBase64(readFile(certificateToAlterFile)) + ); + testUTF8InField("issuerName", "ISSUER CN", certificateBytesToAlter); + testUTF8InField("issuerOrganization", "ISSUER O", certificateBytesToAlter); + testUTF8InField( + "issuerOrganizationUnit", + "ISSUER OU", + certificateBytesToAlter + ); + testUTF8InField("issuerCommonName", "ISSUER CN", certificateBytesToAlter); + testUTF8InField("organization", "SUBJECT O", certificateBytesToAlter); + testUTF8InField("organizationalUnit", "SUBJECT OU", certificateBytesToAlter); + testUTF8InField("subjectName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField("displayName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField("commonName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField( + "emailAddress", + "SUBJECT EMAILADDRESS", + certificateBytesToAlter + ); +} + +// Every (issuer, serial number) pair must be unique. If NSS ever encounters two +// different (in terms of encoding) certificates with the same values for this +// pair, it will refuse to import it (even as a temporary certificate). Since +// we're creating a number of different certificates, we need to ensure this +// pair is always unique. The easiest way to do this is to change the issuer +// distinguished name each time. To make sure this doesn't introduce additional +// UTF8 issues, always use a printable ASCII value. +var gUniqueIssuerCounter = 32; + +function testUTF8InField(field, replacementPrefix, certificateBytesToAlter) { + let toReplace = `${replacementPrefix} REPLACE ME`; + let replacement = ""; + for (let i = 0; i < toReplace.length; i++) { + replacement += "\xEB"; + } + let bytes = certificateBytesToAlter.replace(toReplace, replacement); + let uniqueIssuerReplacement = + "ALWAYS MAKE ME UNIQU" + String.fromCharCode(gUniqueIssuerCounter); + bytes = bytes.replace("ALWAYS MAKE ME UNIQUE", uniqueIssuerReplacement); + ok( + gUniqueIssuerCounter < 127, + "should have enough ASCII replacements to make a unique issuer DN" + ); + gUniqueIssuerCounter++; + let cert = gCertDB.constructX509(stringToArray(bytes)); + notEqual(cert[field], null, `accessing nsIX509Cert.${field} shouldn't fail`); + notEqual( + cert.getEmailAddresses(), + null, + "calling nsIX509Cert.getEmailAddresses() shouldn't assert" + ); + ok( + !cert.containsEmailAddress("test@test.test"), + "calling nsIX509Cert.containsEmailAddress() shouldn't assert" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem new file mode 100644 index 0000000000..63ce6adb95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIUD0km5IZjROSFHzbVwqApAdud/iAwDQYJKoZIhvcNAQEL +BQAwfDEcMBoGA1UECgwTSVNTVUVSIE8gUkVQTEFDRSBNRTEdMBsGA1UECwwUSVNT +VUVSIE9VIFJFUExBQ0UgTUUxHTAbBgNVBAMMFElTU1VFUiBDTiBSRVBMQUNFIE1F +MR4wHAYDVQQHDBVBTFdBWVMgTUFLRSBNRSBVTklRVUUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowgY8xHTAbBgNVBAoMFFNVQkpFQ1QgTyBSRVBM +QUNFIE1FMR4wHAYDVQQLDBVTVUJKRUNUIE9VIFJFUExBQ0UgTUUxHjAcBgNVBAMM +FVNVQkpFQ1QgQ04gUkVQTEFDRSBNRTEuMCwGCSqGSIb3DQEJARYfU1VCSkVDVCBF +TUFJTEFERFJFU1MgUkVQTEFDRSBNRTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNRME8wTQYDVR0RBEYwRIIeU1VC +SkVDVCBBTFQgRE5TTkFNRSBSRVBMQUNFIE1FgSJTVUJKRUNUIEFMVCBSRkM4MjJA +TkFNRSBSRVBMQUNFIE1FMA0GCSqGSIb3DQEBCwUAA4IBAQA1ZJfPm9pINBPkJ/hu +5we0GtnKeTaIQOvtVnOXIA8NQBDny3pAaGNEQTaf48PL7RViFmUNGubPVzx27ZC4 +HIsUV+fT6ASdkgj9HU3cV7vOIXTDWiZOm8pFoqwV9sbkFToUuEomIHAJ5qXnF7Fv +3O87ePTPf1s4bf8URK3Dn3cLY5N9P0o2wdUKj5Ey94ZMfGnqH7lZ0PSoDTRdzb8j +lHp1bskW/s9jsYqF7zSExur2OZ3DBwQptmoiK6jYu3h5M6+lV/euRjsJLqEIBSu9 +krgKiuGeiG2F8aR+Vi8agulxZnm3zmZPCgIxHOe2O85+Ak1GctL6mRopr4nYgc+P +dfBK +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec new file mode 100644 index 0000000000..6579ac5550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec @@ -0,0 +1,3 @@ +issuer:/O=ISSUER O REPLACE ME/OU=ISSUER OU REPLACE ME/CN=ISSUER CN REPLACE ME/L=ALWAYS MAKE ME UNIQUE +subject:/O=SUBJECT O REPLACE ME/OU=SUBJECT OU REPLACE ME/CN=SUBJECT CN REPLACE ME/emailAddress=SUBJECT EMAILADDRESS REPLACE ME +extension:subjectAlternativeName:SUBJECT ALT DNSNAME REPLACE ME,SUBJECT ALT RFC822@NAME REPLACE ME diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/moz.build b/security/manager/ssl/tests/unit/test_cert_utf8/moz.build new file mode 100644 index 0000000000..f96c97f0e6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'certificateToAlter.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_version.js b/security/manager/ssl/tests/unit/test_cert_version.js new file mode 100644 index 0000000000..73b0f458f7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version.js @@ -0,0 +1,304 @@ +// -*- 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/. + +// Tests the interaction between the basic constraints extension and the +// certificate version field. In general, the testcases consist of verifying +// certificate chains of the form: +// +// end-entity (issued by) intermediate (issued by) trusted X509v3 root +// +// where the intermediate is one of X509 v1, v2, v3, or v4, and either does or +// does not have the basic constraints extension. If it has the extension, it +// either does or does not specify that it is a CA. +// +// To test cases where the trust anchor has a different version and/or does or +// does not have the basic constraint extension, there are testcases where the +// intermediate is trusted as an anchor and the verification is repeated. +// (Loading a certificate with trust "CTu,," means that it is a trust anchor +// for SSL. Loading a certificate with trust ",," means that it inherits its +// trust.) +// +// There are also testcases for end-entities issued by a trusted X509v3 root +// where the end-entities similarly cover the range of versions and basic +// constraint extensions. +// +// Finally, there are testcases for self-signed certificates that, again, cover +// the range of versions and basic constraint extensions. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile("test_cert_version/" + certName + ".pem"); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + certdb, + "test_cert_version/" + certName + ".pem", + trustString + ); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLServer + ); +} + +function checkIntermediate(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLCA + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + + // Section for CAs lacking the basicConstraints extension entirely: + loadCertWithTrust("int-v1-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v1-noBC_ca"), + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + await checkEndEntity( + certFromFile("ee_int-v1-noBC"), + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + // A v1 certificate with no basicConstraints extension may issue certificates + // if it is a trust anchor. + loadCertWithTrust("int-v1-noBC_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v1-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-noBC"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v2-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v2-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v2-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v2-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v3-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v3-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v3-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v3-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v4-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v4-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v4-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v4-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + // Section for CAs with basicConstraints not specifying cA: + loadCertWithTrust("int-v1-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v1-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v1-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v1-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v1-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v1-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v2-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v2-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v2-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v2-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v3-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v3-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v3-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v3-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v4-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v4-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v4-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v4-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + // Section for CAs with basicConstraints specifying cA: + loadCertWithTrust("int-v1-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v1-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v1-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v1-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v2-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v2-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v2-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v2-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v2-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v2-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v3-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v3-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v3-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v3-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v3-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v3-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v4-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v4-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v4-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v4-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v4-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v4-BC-cA"), PRErrorCodeSuccess); + + // Section for end-entity certificates with various basicConstraints: + await checkEndEntity(certFromFile("ee-v1-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v2-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v3-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v4-noBC_ca"), PRErrorCodeSuccess); + + await checkEndEntity(certFromFile("ee-v1-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v2-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v3-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v4-BC-not-cA_ca"), PRErrorCodeSuccess); + + await checkEndEntity( + certFromFile("ee-v1-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v2-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v3-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v4-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + + // Section for self-signed certificates: + await checkEndEntity(certFromFile("ss-v1-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v2-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v3-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v4-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + + await checkEndEntity( + certFromFile("ss-v1-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v2-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v3-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v4-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + + await checkEndEntity(certFromFile("ss-v1-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v2-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v3-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v4-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_version/ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ca.pem new file mode 100644 index 0000000000..1126badb9e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUX0wQbjf3LQAHIgB14ftnKbI1mekwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA3q3li09bMd9Y57E2xPY9NdMiG +SA7DSsGnxOchtT06MfkP6lH4PlKDLATIEv2CSq2z25Thq6yYWyZnWXC+tOptACjQ +FDS5scNAI2KDwtK7pqx1+Tr606DQI9QUF1ZeaKo7DP1ibmwmDu3cY16RaowbgaCh +bU4ADBkZNAlRCvrRGCtBkdUl0hqVT6sW/eFkOK9vA5pDHZryQv/DZSg2bDeJIQBL +ElArPKv3DhETpuf580rkI84+w7HBiUSNHB2KPq7ctn4Zvsou/zxJ9x2px/7t+pLx +TPoYXl9QOgv2uqKqMr5dWMAgZXrFqvXVC01JHPbu4BJDKi5qyKcdZNcdl5pq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec new file mode 100644 index 0000000000..8689ef9ea1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem new file mode 100644 index 0000000000..b39391ce2c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwDCCAagCFEmH4RSzGlM8deH3Cyvvc8BTUkK4MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBYxFDASBgNVBAMMC2VlLXYxLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAMBgNVHRMEBTADAQH/ +MA0GCSqGSIb3DQEBCwUAA4IBAQCe6J0atonkAikXwwKyUEier2uTl/M5H1JoJKQT +8FDYIgDKzZi2I0mt1OBd98r+SxCFEoF/r0Je1vwTzFnK9R460VdZY7kXzPOrQ3nP +3XCXS/sOK+c6BoWF1NsFBzVohgatObe5zMgV9s5xYZqXlmPFDBJicNyO2DkyWHbk +7sLMavGanKa1au1Zpn8GoAattNJW9ihqEZ1ZsXM8zgYzuRN850myynAYcIl9rsON +6mMFe1d1UiEplhAJGGD91A8RtokJlq32uGMWIw76lNbrCEjN6oB6XFS57PcOF+3b +5rVmgfY7IHbB2gjFSKcj8hFF8D0ISZn4mFRsJof62RwM8QCV +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..4570e6e3ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v1-BC-cA +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem new file mode 100644 index 0000000000..f099356266 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAakCFDvg2eVC0vnuGk65tm8Vzurs8Uj1MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBoxGDAWBgNVBAMMD2VlLXYxLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMNMAswCQYDVR0TBAIw +ADANBgkqhkiG9w0BAQsFAAOCAQEAUnEgkyfbh+pY2ZAIpqUSRkMYv+NIXdcnTJZV +GmqhFJEakZ2hMBxELneaxbv49Lj7JyK09CVfBhWFEA0CjnmS+APb3rVozt9uN6yE +KCjGsmdUnthMG6E2D0VbLsNKq57m3naDVgDDedOhheAvsJyQvKubsQiMtuoJCdZO +obx+lYE+16m6+SzJPFt1yh5vn9+hBcTq1zmYQSKbAJXkrDMMQnjywzb77kBKYgyr +uQ3/SlwjzGojQFlWOhkRsQjcC+zz6lobziUeAQ1vXy8t8xaQQjTmwpVi+vVH7w+8 +ATJKEfIE4cl58aAEYHV7qv1fQ6NUQO0lsRumsgoR+E8PhPQKrQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..f4257841fe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v1-BC-not-cA +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem new file mode 100644 index 0000000000..08fce562e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrTCCAZUCFEmbMXhUIOtpbMU4ZOUHBaPfFSv9MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBUxEzARBgNVBAMMCmVlLXYxLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEB +AJkjYBJWNRU/lCHANJUmnuRt7ignqJyGsYR/q5z31B6kWUA1TGX15iyWnmgtRqR3 +jDiZqh3ejnozXtbAHkGykndeY3jvHCMzCNNpAQZKd9hoCb9Ix9yK1zbqtGAuDgT6 +t0nfkvGK9qPulRZ/2cHHHEdryceX2B1aVxv8D2z4M1Fg2Ajplp269EFhd0T5sZL3 +9zlgv9JlcoUVdjlDQ95Kagv4jt0gG3mGci/Oj3pYwhe8bVUE3/vwetR+1akOaBcE +3YSvUW2EbQkGq5ghhIolF2K5DRGjsXkGrJQszRNRPTiEaexL3CV9r7lW0Re6z8Fs +c2TT9q6PeqCvNoM0K4ji8Ag= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec new file mode 100644 index 0000000000..48fe9e5416 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v1-noBC +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem new file mode 100644 index 0000000000..25c6102473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAQIUTUkREc279H3wFGALzwJDTUzA5XYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjItQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG0viSnuppjnIHdiuApCFM55eBf71+Tc +g68DIa0yYtVylF6KAhFMCe7JPg+9viImNGeUktRSpwLtCc8w63gILGF8HhAcOScM +2uMCQMX0HqQqDxZdl1PmQv7oj0pPK4FWiyEXjYaHOaHO+qzo5hV3KUe2iaK0VHbk +vtyAhTrhkHrhLdpDGYtGErAj5E4hySfNW8tNdvrOge9n2SEshDiSr1G3NSQZwlGd +ZOPrOGbDNFGlqzKRwIdn8wz1NC8JUjMWZRI7opnqA59e6RXoosT6Ruycnx6qC6eu +gBKRYMtbVtYmaxHmTR7jKZLdmx+siIkt6nZZJ36sAiQvAd7pWdZrctU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..f714725d2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v2-BC-cA +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem new file mode 100644 index 0000000000..c100e8d026 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAQIUZUYdrYFQ0vpgwxOwG9WoaOfZlCQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjItQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCcsL4DBcZ9blKekKo3s0mhsNm056g4 +/QPMHfZ3V3Wtidz2VDp09LTuXaLDbfMYSlsR6p828rJmHrO1BhIvKKJ7SAfN3QXp +lntK2RzY0G53huTqs8u34DdHdubrG8TSFbq/pqa/2So1YfvVLMQYrkz1p9AxtFqN +/Ym1G33+1RIB5Shji8I8PyzKVL1ymlzfVLPP4jBkxopytZUykc6wPNRZl1FnbZV4 +0+ZFB01fOHmitHiLuPjIm5YYA48jArq6h589PUg3+WyNccd9MzRQgVdXNg5j88d5 +Ta2oXKAPmzTt0L+vkqkPyTYFT1gNAKg4eD6PdjxXtWDYwNtOqG827jfm +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..db72288814 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v2-BC-not-cA +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem new file mode 100644 index 0000000000..74085ee898 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAQIUY4fMtZjVWcwhTGK7pGcExmXLBzAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjItbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEAG+pHmRMmLdRIWHbG+CiU4jBFaTfjRHVOjt2diO4p60dZ5up2tp2KAnHy +U7OJmN0FcTl+7ydDWXyR3gRrR/rOGdx5inq3817+CotMkeai3dnKVjjLxDBCA8Ch +2mqDXR6wYyXccIMokJgVam2b/OHAfpWlphecReKr7kYA8j6Kg52IFZl7iX0l2tL6 +34TJnRdPyGz0AM5uP46pLn7P1zi1M/6+l0y8EnX7KL/k2Bxj2BWwWLJ8L7IXIret +f/zEM4EiHJHSC+HLq9r/XJFJGVXS6bNGPETQ96ySEvNPPQTRWLe8JBj5pUpe5LBj +hrv7fb16fTx/eVdVFmbmdFH6q9nNHA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec new file mode 100644 index 0000000000..cc304ab87e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v2-noBC +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem new file mode 100644 index 0000000000..480bed0f40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAgIUGxHIJJyv/iJrELEMIQD1aphjDaowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjMtQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBABwWiSkeHa9tiZRe2vCYFRgR9OEHPr+z +uN1PFpmLbofm4HTQ+FYD91QrYuDJPoO6+zBLRbZqkBZ8J3X6ts1uRr7qk6x9Cgq5 +ZJNUre5gW8wjZ/WiX2IoY7ucZXuTYKePPyd5RyfPYm+9p9960elo2uNLLG0Nmy1A +YlqjkhaFn6q2eNh/4c0tlRKIKpiUDnBa/ibsJPRzbTAhmIm6ooiphX6E6CG4sIWP +HhWvldTPETvF8PGe4BxqZRBbAzh892yh8FCGos8RLNOoFrr4k4Vysb94n4E1SKrv +ORfes12d6FmFdYlB4mjl50FJGh0hjPcP1tq78EbkipRGTJO/6Q3vcVE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..6f69c35743 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v3-BC-cA +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem new file mode 100644 index 0000000000..574ef68d5f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUb4dXJa+wzvKsmCT/HB8Xu0Cp8YcwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjMtQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQB0pTw1CI81i2uK8HfcfuljDfI1/thC +9QmV+nRLMic+82XNPHYjUBAS9r2kZvNEeSoQQThkefEzcRPP33hl4TbYXCKuFzpT +k0ssjzLAUIWUCaVWnV3p0aryGv/MBITNu4TWTnRwOIinWZ/cExO42iLTDiMbuhQp +b5IubLsj2+15aF56zuTFEqwB+O6D0L+r5uka7Q6I3T3kCrbDFqcjlosKxY67AqLG +dKMahrfX2D1hFIeVz8yMtYCAH0ZWt+ooJE1ntUksbwsQ2pA7AQwKl2ojiqI6FMRm +6jD0ydcYAGdNboNkL9fCC1oC7J66slt5a172GE8IGXVKqNZYLv2+0P+/ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..4a9de06358 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v3-BC-not-cA +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem new file mode 100644 index 0000000000..88b8996d5b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAgIUH6a1yPknNm4Zd5xhXtDsj5JWTVIwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjMtbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEADZVMW87EF24I8XiCc+t0MG+vu8rcR1msyWAwtjxmYNbkt2Up+etwR0U/ +54zFmJiRagPnKZhd9pyp1rpej9nj1liL8mV5hLeX0Mlc6QnCo7gNIY0wWcwtsMXe +NDWBO2i1mTlTBLjJrrcmTd8dwKy4Pru2oQ2+6O3/m58oWtBqsAJp47o8qOTmjJvZ +IF2U6cOgoVNGeOmzq3QGGQnM3/9rXhD5DL3Trz2lCuy91fW0gMyFC3neaKdSDgoP +2cZtvs5plLwBNXMu6W89BZI08mrD/flo3VkUgkxVBDr3PUKdY60Xvpp+sJwEw0Ef +Yr9Zmb1FmDlwTjmAAZVo9OiAg7r2Jw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec new file mode 100644 index 0000000000..9d385900f0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v3-noBC +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem new file mode 100644 index 0000000000..ebb27c0de3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAwIUN2t/Wc6xThY3A8WTT8g4qc3BJccwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjQtQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGcf/zc6xWE/038gQYOrWnTw5B65PsEi +iGWJQgeUOSCwADHJ3DYzf239OmBqhe30/fbT4Z5F9y4OjSGqzKhiAwq6rRCeybFQ +d/tQvT5F197q5b0ZgMSSbu9luGD8kNSrpzmIvqwEVrABbKTFUqaFpSumZKbCRuQ/ +2ReQ2W+nfnL/EDekytU9nDoIMULcCc5cPj8q+gEVPaMm94bDwYe+9vVRwf2JycWt +ldZbH6brAZ4dOpa+hXK4W4RqY0baTRYU/8wrihezQtVElJmXszOzcWveGg5cOGFC +vr1EgdFx4d/dj+Eh7HiMqSJqUlVQ9D84mR1C1NBJdDZESflVT26kB0k= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..1f44c1dd27 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v4-BC-cA +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem new file mode 100644 index 0000000000..adb901d1d2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAwIUXX5wI9ZLvqMcMEKuZ6ShXJ0XfY4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjQtQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAoqp9OCrEoIKeQG+2mtReILd2OW21v +sgvxqDP6MGYtdQ7HfZaHZuv1PZiVzxysqk/0nuUYWzbPh+7/xUWTa21YVjt2fhDV +wotDiE3iNOumE3Pbeg70MIRgQa00pYvjRse9748y4rLMSpZu9Dx8vPS6T2efrjI/ +JwMh0lqjsqGNdMEotfNFeGCrsjr3bjBj43RtRHpL00Cq3A276PmSyfs/r+raxJEU +BkKqjmry3AzOMTIyTxI7qe5/CMAm8GvfGdhr1tj7sh9lwS5oe8II4u4D/9tirHF9 +wTNAhSaTiAsUoynaJtBYTA/MxYvwJ6/qY69Q7oUkX/Gs7Pl9fryyDo05 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..e9659153e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v4-BC-not-cA +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem new file mode 100644 index 0000000000..e7c778415d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAwIUB2z1TvAGiocHPPLxLlCE2W4kKrUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjQtbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEARifsn/PYmP30WdyRw3EBXEolSO+kqeY2fWM/4Qji7jUGLsgXRUt4zXbs +Wgwrvxk+iHlrDwN8ux6OZ0UteKBlWxN6vWUZO3QqCI2prkdzBtHkiBB/sbp6kJPR +IIBLPoXn8IOeV7xP7bjNHDqSqwDy4Ltm+0OmOBaONxhAjAyQPKZtuzLRUQzljLOZ +9vE4CXM3Q/ZugkKOFq4YcJ8fTRXT08Tqtfxn0IIYBsezTPw3kX4qcgiyaSLhCSKC +w1eb46+Kqe9FVC9pApbRFSsYm0guPnRRMASQSiHW3w+7KB35EFl4G5LlxzuZdZh5 +I3pv2YB2zXurIJ7IOizgX9GMVbOzjg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec new file mode 100644 index 0000000000..19229ba766 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v4-noBC +version:4 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem new file mode 100644 index 0000000000..c9fe2a1deb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUYXRFk++ngkM7pfne+aGZuKsxTYUwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYxLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQCwvmF6hChs9K1PKjkg2daU5Lz2zAPhh1q7urmJu8gCWSTGz+PeJvKP +zFptbQNPqFnDG9FBXX1IDkMJuZinwyQb1zcLxUqycX4ZKd09BcRIeS/9BXnOy+Cp +1QFDj0R/wdMYnvh+yfMFOSLVBSFkGtHkvkDoaf7Sm9vzw8xVG8L2785tkfGVsyd4 +oqhDbRJ/RQu4wOjS8NmIRp8bAUg69YA1+wcc9cTbsp772sA529XzNDT6+IUV4H3b +TcDW8/Z/A28616soIN6F1KXmQrj9y1lcj7o4uuHPhlpoF+CQScZNCKE94QqHqHvY +yPuMZS8TZz0F31Jnb9sSncDWtK/MOyia +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec new file mode 100644 index 0000000000..6a7dc5c436 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem new file mode 100644 index 0000000000..1cd6f09ca2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUT5zJeVS8mAKQvZ177AdPjbMcSZkwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYxLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAjr1UeC96xOI/hocWQtnEJxO9+qxnlRzSuM0gZKvjRlaSsGyn +QmN+/hiYSl71Jq4IkLTxkDy+Fn6F/zb353+f0JMZDVjbBuBfr4HPMTdCHKLnNyoH +XkDwIc08bhoeVFj67OA0E/DxyDjoxZNOfvVALC/8xWlvfrik/N6NBNUS/CPCEFa6 +G/R2RPpea9Ftx5op5SMApctxGT5ZiYTSER44EFLJ2GVQWm8Tt/PNNXt+sYAaAESF +vuOYwiRp17TRPq7+ddE3omKB5xA8e51y/NSAtK8SAsE6nDnjJUmM8sBaitfX6vDY +ji8NYlIWVEMLkEPmg3dWiUz0WYG7Z7RkZ9yT2g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..639f83d660 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem new file mode 100644 index 0000000000..22b86450e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUc2AKlc7qreFiWgePu0YLMlgs/YwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYxLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBACgJObqHt39+EYoxXhZWuYTAWF7Kjt5jRxluishYoqZ2SKOvhxe0UJAK +ufWLYDbkE0rRW3SNmFxipkXO8ERztDIjc1tbmFJMQa/mC1A3N7YiCLHO8k7t97ie +diw7nEF6kxNp+OkOwZqWiH4siyTiFcAGArnh7j2FZt9dF03FgjmtqAtpB02fON0G +YXuIms0yWHfQv8kFuOmJ9ScBoDZu0layvueWnCfnejIEMyqynRR+ZkPeb5cGqRpL +HGjZnXYXTR2//DV71uUskCz3SGYwttthlDdaBM/AIg7GZIU4mL7iLSq3hxdpVQoM +QXbqnL6xZrDlSn3OmT7/cNrIxdf9qUU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec new file mode 100644 index 0000000000..d704f3086d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem new file mode 100644 index 0000000000..f113c5d965 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUATfzH/PSKv0xC89ayKzWGTWeIYQwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYyLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQAiY5jZpo5IV7FF4xLax2uq+WdCxUDJgYQeaTiu9RlJ84vEcHIuERwu +CaweD8T/4fE372XyivZlopfJ3QR1owqfjGBA67H50mJAurVIBpb+cBnHSxiSYezG +NNTrHwosfb1G8H/oT1/AQtjB4tMSuD8RkTQMwN2G0N9JAhoKL0EnNxKFzuW3IZrW +A9B5mxEe9LLo4JhiNFUtm2Cyh7KiOgOC4IqZfh+A2yrJYaJoBlc3KJx9EfhC/nnm +jsT4W2xxAXn3mNNKaaxnqF/e1jMSlxuKvXTYu1CssaixqQ3XvdmtGRcFoMSgS3RS +MBnffZz/68BbniBcHIgqUp5M7jMEx6lH +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec new file mode 100644 index 0000000000..5d3a65e650 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem new file mode 100644 index 0000000000..b5768a0c01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUfU0RGDUqR251hZR7j7dGSVvLOCEwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYyLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAUzqCpvNWzcDl+DVO0zNcJ1YHLwCTGzD62ejKfjvSUFNloW1n +VYfWP3FN77vtfHdPWZOWcaPGOgvIAjtrovv8PAqE3zusM8ml+2XHYckXReOv+3xp +qMN+8uGgI/KjyYuuxUOcNnWjwEHs9aB5A2QznNfb73vorBoMGOsp/eRRu/88SIsm +Lb8faovBW/M82DddY01u4pQ7NRdk1lRJP7NDwyeJi0sp0Tt8vkqQmaWwVxJcECQ9 +pjyHdcV6I8X/0unB5aTDVNPk59FQ2mBnL49uhwDLPw/CfvIFUk5t4e5Y8fYENL1o +bCmQwdRtv2uvglGbduN14jNeWi2BrR97CwieaQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..591a16aca0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem new file mode 100644 index 0000000000..e63e7811e4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUH3fF+CwxPCO0p6f03bj8udeTCqMwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYyLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBADV11pKOwjVQe19NU0Dm+mxFwfr3JtigZJTuqLkDuI1ZzoiLdy5Gm7N2 +HEzx+5A6XoV+HxAA3vgDXjcxqNoBlUFZSKcO3dME/YAwtE06y5R1o8xU2ySH6/Dp +N4Cg5hVPNDo/gomEsqDou3IlLXVQO64fBGFT/eK4fnv96jEMl9hkCbHUjrz9XODI +iEkz2wJSiBmrqKBG+ZB66HqvoqoCNTSfV/IHE85QEb9YanJOc+DR9CYN5S1FILEa +LMi/nVB2Ldn42kBFZjXxEdkQFIWPyKZIk4wFAJwsw6fNGUY6UAb7exLTEhkvP1nD +cgozZt5aezZOz8N+xKwseT66ebSnBhM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec new file mode 100644 index 0000000000..7f99393cf2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem new file mode 100644 index 0000000000..6c1a22262c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUc1r1zrsB1TOy5rvPR+6sCmW3WLkwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYzLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQB8cqiLjiCQsWyha7QOnGpJVDbrZ050OuDNgg0RZ4h4+vtzvADZFr9T +bbDS5lBUwCipjySqJezUVAbjXLwFPVilc9HW/dZYQCrTHq1KsKma/hbS4+evrW32 +EbEIWLlSc/Dqh8TIwdPtFCtkaBDibIEw4NRjjr18qckN/QQRDRUTjWPFE3nSsSL8 +ywlfQN22LFZpz9mLDsR7hgHGVQ7lKSn7aFspCguu3Z4H3IotMZKd8HmoItayeOwT +5r/tid/uBWUMEV/8IevoJ97arusRZxpCkgrJLK0lRjYfpdO46G9xyEa9NV6R3I1L +OYG6w/XbJYyJujCE1G9tDGVVB88lR41Z +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec new file mode 100644 index 0000000000..13af934f29 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem new file mode 100644 index 0000000000..5490b63b25 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUMWZpljmNpyGng0Q4Nt3ZY0BTjjAwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYzLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAGx9iRA2sOhzEzfbU7jg502lVEAfj0HwJFRN+DVQNyVuNl4ik +QMVFHJvoMCFGu4loJRLqF/OuF/3tvUp4BC8QjbLqUj4wtSUCDZTF8o+Tjb9kTj3J +60VqqL5/HU1G6FaKPDOU/mvmGkiVUjOcrrUghv8urTpYvx8/7Z+u0WySrxSCPCZZ +mYv4LfCv4oEVpzpUBb4078qkntbezDQ5GAyzhpWHSo8qx0FTGnilyZ6Ql2RXItnf +ube5HxTETDYRqHu9E9GcraGKIgYY7vbG2nNOvl87zxU4lHIwpu1vZftpe3raGLqL +7nDqDqHC+9v64RDYH3U2yrl2SLzwsMR0by1otg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..8539715a03 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem new file mode 100644 index 0000000000..c6a4f4e8c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUb5/nrEpBnFWFYMGAHbxheeinOLwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYzLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAFgzXwCceIuZFJ7jB2Fls1D1XvYiwhxeuSVZHsNz1kpCbpmZi1hnDYOY +gfr3FEpcFI3P93b3hHpl8w7DGJ6bvJDqnNxe/idDDg60jeghcmCsJKYUgyoqoYbo +kjHdg1ce+6xsf4n3of3Cr6xDCjpvTupXTf5zrUGtTAvE6XmQPTx1vOEXK/mOdsBb +6ZiVv726yukaCsBN+zuhIU+0eOj8+2kXeKc4C5S3OZ/48LydMRNxjPT4pZtsHfAe +NWy4hyTqfcKZfU31F5GzdXMgn0vvA/v2fssj+ke9sXhTnpNdI48Rp/l5koEBQBNQ +D2rvAdgdZEEQ9xrl5RkLjAXDpVbSoI4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec new file mode 100644 index 0000000000..a65e41cea5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem new file mode 100644 index 0000000000..dcb3b722aa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUG/xdmUZCt7ps5TMTVbvfWjJHuxMwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXY0LUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQCrG/sSj1dbSebCi92T47mRiq8Pm1ovwfqvcuOAcdOELdpLocJMGlDn +7ywQFXRjWvSYHpnk6ekg1XrkHG/N8rUYijRJ0SyR5kpeqGfxiMxSGjxHtmA0sCuK +inqpZAa58v8nsUsFNH4iBWlRYxOAJ+KjwboTar59A5+gKXkxxmoy+4f+LgbyBBJM +EHp2lMg4Nce0/l7tBtNTw5kuozQ7ds0iRl0h++Aw0SjhpyWGP3WVGNa0z3WlBULx +FRqHLPV7yS0WN8A2j2rPanzIzNpka4QsnPQuDznnI3295k1aaTKXacMDnj10JNHh +VSNkPAii9GM0xubnEwvgioNrIePpRpPn +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec new file mode 100644 index 0000000000..35a3a9ff36 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem new file mode 100644 index 0000000000..417e004719 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUPbBY1V9XpHrNz4pW9hdLlHaE8wowDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXY0LUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAbcIplVCPKWXW3FSoCRZE9gLtlnKN0aWmsqn9mbZij23ZbVXA +i8t+wu0SSbgeJ99YE36Z/NkKCx3pRIGbjdE1r08rTAhoHxbTdeIzD8K3P6JOSqY2 +7HHsNQxkroWB3Mf3iPW/P8/53Q8o3FYfZEmLO18i2PHw+Y9ZVwHSE7pbdwvTrlGq +MrGeSR57JJLHdZteMhr0A8w2qA2Cv+2NIKNLz0Tztvynmmu+laIMvfTpq9WJesmG +Y1CPXrC7y+Z2720LoxtXpxtVKxi88WFFOKVsBdEBfH9E34TSw5B84RWiaQaZfrDJ +Yd3E+Su7BkyfA89q1J8ITgHMEQdkceafCiQ0pA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..7627d3a8a2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem new file mode 100644 index 0000000000..238514cffe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUM3CPGo7kDa/S240PLKd0jQ2d/SAwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXY0LW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAJBYwR2i3Y5sJp1o6Eo7Ue1eOpBLFGSuOz0HmQHrZG4dal1dfVrRkv8S +YV//loHyjmp80patejR3QylK1Y6ARQQm6Wn/fOSsUcy4KyWU+DQ5xSrWpRL1EA/7 +yMvK3uwKpoRGUCplLqpTnboRBuFvd6sqU2badeVBpOx/cJ5CBbTiHzudtoWs+O3x +Pv6rjRS8KPDh0qENyKi0JKALXWmO0eHGKPAlRKjx96/4wfj4nvnj6i+OlIbLNZJ3 +Ff8+KCt2xc6cToClZ7jD68eGRDhBd4r5HcUO9y85BOKLPepTM7gRd1FSVXjL21W2 +H+SGy+jOUZOMSiFpQW7Gohv47xa3s4M= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec new file mode 100644 index 0000000000..a780337539 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/generate.py b/security/manager/ssl/tests/unit/test_cert_version/generate.py new file mode 100755 index 0000000000..2afaace3b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/generate.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python + +# 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/. + +# This file generates the certspec files for test_cert_version.js. The naming +# convention for those files is generally of the form +# "<subject-description>_<issuer-description>.pem.certspec". End-entity +# certificates are generally called "ee". Intermediates are called +# "int". The root CA is called "ca" and self-signed certificates are called +# "ss". +# In the case that the subject and issuer are the same, the redundant part is +# not repeated. +# If there is nothing particularly special about a certificate, it has no +# description ("nothing particularly special" meaning the certificate is X509v3 +# and has or does not have the basic constraints extension as expected by where +# it is in the hierarchy). Otherwise, the description includes its version and +# details about the extension. If the extension is not present, the string +# "noBC" is used. If it is present but the cA bit is not asserted, the string +# "BC-not-cA" is used. If it is present with the cA bit asserted, the string +# "BC-cA" is used. +# For example, a v1 intermediate that does not have the extension that was +# issued by the root CA has the name "int-v1-noBC_ca.pem.certspec". +# A v4 end-entity that does have the extension but does not assert the cA bit +# that was issued by the root CA has the name +# "ee-v4-BC-not-cA_ca.pem.certspec". +# An end-entity issued by a v3 intermediate with the extension that asserts the +# cA bit has the name "ee_int-v3-BC-cA.pem.certspec". + +versions = {"v1": 1, "v2": 2, "v3": 3, "v4": 4} + +basicConstraintsTypes = { + "noBC": "", + "BC-not-cA": "extension:basicConstraints:,", + "BC-cA": "extension:basicConstraints:cA,", +} + + +def writeCertspec(issuer, subject, fields): + filename = "%s_%s.pem.certspec" % (subject, issuer) + if issuer == subject: + filename = "%s.pem.certspec" % subject + with open(filename, "w") as f: + f.write("issuer:%s\n" % issuer) + f.write("subject:%s\n" % subject) + for field in fields: + if len(field) > 0: + f.write("%s\n" % field) + + +keyUsage = "extension:keyUsage:keyCertSign,cRLSign" +basicConstraintsCA = "extension:basicConstraints:cA," + +writeCertspec("ca", "ca", [keyUsage, basicConstraintsCA]) + +for versionStr, versionVal in versions.iteritems(): + # intermediates + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + intermediateName = "int-%s-%s" % (versionStr, basicConstraintsType) + writeCertspec( + "ca", intermediateName, [keyUsage, versionText, basicConstraintsExtension] + ) + writeCertspec(intermediateName, "ee", []) + + # end-entities + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + writeCertspec( + "ca", + "ee-%s-%s" % (versionStr, basicConstraintsType), + [versionText, basicConstraintsExtension], + ) + + # self-signed certificates + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + selfSignedName = "ss-%s-%s" % (versionStr, basicConstraintsType) + writeCertspec( + selfSignedName, selfSignedName, [versionText, basicConstraintsExtension] + ) diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem new file mode 100644 index 0000000000..8b635b1c33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbYCFE3k+54zZHCkzie8w4rzHPcWCvpHMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBcxFTATBgNVBAMMDGludC12MS1CQy1jQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQDAgEG +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACtj7FH0rKA0rkR4jE7D +IoflYPE7meH6vbDEb7m0kALj69+TH6pnBuKiaiWQwyhx4anAbu13JEEpACJoaNER +FtxsKL8y9j+tSbU5RFHx+6f7OOcz5SawscGEF+P3t0lJqU5d5sDs/frd9DZWu3Ho +lzTlbP2YQsqiRAT2Ryx1AN6hrZEDoQ8TEwXqSC3slSeDvC+pkSZbhSg/VlZ9vwjz +zZ/ukePXRg65AcBrlWhMuJoCCzkQk7lVt/oOHcrGl2AYzN+t04FXs+92/5Gr4Qcd +iCweQYIyHm8UKGsA8gNpFzt8jP5cDUNx11FRPA+N7lImdCas9GHwKTKIunsqW8zC +1lQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..77f3ae9147 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v1-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem new file mode 100644 index 0000000000..45db11b6be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzzCCAbcCFE3ZspZvBnOAmWIh05fgdovmSbLrMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBsxGTAXBgNVBAMMEGludC12MS1CQy1ub3QtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAsGA1UdDwQE +AwIBBjAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAbIDFm/7bUqz+GPgQj +m5pCmxph7tF1Hfz1JMW/3Yi7bthN9ih9As18qgDOPVD3qrZFAUNM6mpvBo/UPb5V +vW8IgtvoNffhUKUjUiYDBcPNmhc2XPCQ9CyhCAF2T1dXftp2H+kQ1cu7N/Yq3vz/ +XkadGQphSs+IWNxYf5hAFU12ZnY5L5BJ3Sr0fjzKYdiyv8MbNqxf1NNlg6+gH0aR +qH+EjqJarw+VeGtwbQjiNCIqf60swE7Fj8hlnGXNlv3ISV0rY8Clfmpr9pG6YBZa +30y/XrwECMiCGlGyQKjKHmijFUF6h49fI1M94jhGDWCslhtvpusdZkaTwBfDEf7U +/5Ze +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..2a366535b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v1-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem new file mode 100644 index 0000000000..a3a7d3b154 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvzCCAacCFGUeQFCueydOeMy6qL1r3OWc72slMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBYxFDASBgNVBAMMC2ludC12MS1ub0JDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQELBQADggEBABvfOrDhyQkVROM6IwTPmetz5M2MjZeQjOVYErgE +fUCE+z7EW5jXaMrcIbjpR+FnnJ3nB6d5vwx6Bzw2q127dUQZkWcI/soiL0ERr+Kv +e97+tPdLb5gL+6trnJb5enkfnGp+Ooo6NyBzUJT8EI326JCxkD3SrGBgLtxzd5hz +rkyjp7y6ypK8ihHGgL7fp4kCeM1NjAt3IPLym7yQOkFFivcKN3Wp7+9oN8t3yo3U +is9yEOmYE/VNRdm6nFnLbe+QQqAZwWQitadVVBHOcW9nIdB1e8VPO+1Dja0muX9K +cLt3twV8Yjk+aaAC3T/4ZTUWNdH80gEZE5Esy1PYeoV16iY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec new file mode 100644 index 0000000000..63bf6ed737 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v1-noBC +extension:keyUsage:keyCertSign,cRLSign +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem new file mode 100644 index 0000000000..6250abda7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAQIUf9E2zqRqLx+VENz/4+SpW+a1PeAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXYyLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANmkUyFb9kU1z +kMHtqom8a2oY76fmNcSyk2VbhodFyj4B9nl/wnHIUxFdL34lMHdxpkEKf2WlSWez +fIYU2JHwPA+iuRE0K0bFqyYt0Bpjt2r5faUzk0ELxYoxIRW7KOHutLBhk/gotgWa +7+HiVJrqfBXQlfWIcb+BNEMc+bzGkQDCdFuzxhUTdIY5monTTbHjF/PUhQ3l9Yql +GQ8IfFQYzaTvZN7kHetuG/gl2dcHA3Yv8IjfSr3/ElrVtF9Tp/c30m3i0Z5YMa9M +zyFYUxqNq5btZYqU7E5/9MXt1A45oet6QHO12E3m0816ooT7g9swJnIQ9CV21LYL +HEVn3xw7sg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..ca1bf67a7d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v2-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem new file mode 100644 index 0000000000..8deb1b0eaf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAQIUC1qc7IY2m7UMNztbSNKbdkpXSF0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXYyLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAFSFOD3w2yEL +hJBjs6WtkQGAOLJ5Ip/2DI0W+XJAyCRF5nRVpakj8ub/Y/cGG1dLbXuOFoQFR0Hc +6m9hoNSn4Z0v84K5WEsKHtjawQ7DnXSYVyt3JVbtqtQLlVPgXhGqeuP4geF9Zu5+ +2hb6nkwg4bGkIumcx9WFDt0NI++UU9q7/Pw9CTjk86XGhwz1LlVA/RIfotsG3IeZ +IBoV6qT5URErFpOj1b96VnMQNtnjo2HMq6GhrtOqBxRzkjySJ+2JHRe4cf/Phg7h +DIkHTo+ueLrT9toHciMW5NXssUwuBtvhGyeCuzVTtYSnEKGHdnXcVUx6gB4F0PFI +JsD87eWyB5U= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..fc28ff150e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v2-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem new file mode 100644 index 0000000000..273f23a8ba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAQIUVYXvMaxdKZ4YI73r4J7jv8+sslwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXYyLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAsNqQCwIN/u9TAVkh8Hv4IcfsY8u7Ex+t +Z8kfW0rUz666kTRVGFQbM9gzgb+rqyou14vxHDuBx67kbJLKdJ8tUDoe8bcpWbGB +jLx/f6elA7D0eSArpEAheRgoqOJS05f6S9pOA9RnNySfFyV+ypZxBOEbrGOzdzNd +guwoBYS/CAx+TH/f4o92cdqBtm0psRkTp+Fj/qi6f2zetxNfLjFpy3Zog8GopCWK +Mhg0W8j9zeKDLf3NVFt8XMSW8DfwJrsY9enK6ISrdBjIdDqaFdzsXEykeiZgHemf +jBPdogIQD6ZsdlaFFWOq03DHLw4v9Sj0wgc9C8gtQDrL6K5fmfLXGA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec new file mode 100644 index 0000000000..2d3fe59ffa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v2-noBC +extension:keyUsage:keyCertSign,cRLSign +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem new file mode 100644 index 0000000000..d4b8eee198 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUH8RrlVV1Arzvq9vwD37aGxKswKMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXYzLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFLbj9FU+Oa8R +/9oGqUDa519Et6mg/euJ5tACGLozVoEGCGZN6raLMGlrGNSKLFZBKerg6CdvAuJj +EUNU1utJhH+XGz6ZCIr9SAsDQ3y19cF31WJ9sSamjmChoAsB0zl9EDIrurg5RPHD +wUaTGPLLieLzmAXYynsxIrKZbCCEmR0be2fPqGdkby3iuQnk/Punzluax/6d7pOV +wNbXlRVH9Tcagjcfv/VqPy+8Vt+iOySaAQSj+Mq4chu7wnDYpsDjtAiR6lou3gvt +tjYy66d0Az4SjJeE22r3Xbdz5fgcWyzkiTg0McHpzJqBjPHwONAgy711NOVUNrbM +3RRmkWzpmQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..56fcb21a03 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v3-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem new file mode 100644 index 0000000000..48b81adcf5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUY/xRC7wQthFDkmcRdLMOkyv+UdwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXYzLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAKvTbOiPSNbY +tvjAcbZPsk+XMNJgOsZ9Wv9RGl+Pc2uZQOKLeysL9bhxqI3Hfylma55t4HI2G7Z/ +AhzgkYBr8H0XPF5q0h66up4YJrDCY2goWjv1W2TmVxleQNQO+eXpP4PJqz/bZnB1 +cXj+olt4CjUtbJ99+RnPU2/7pjQ7D0XMnH5KEqoOrqZr4jVrb86kps9OVmvDr8bW +P7uzZywMNJfAuO9SYtSsqQMGz1SA/fDUK2Uhc3AeGyTU3ePAecABCVNaLnMlqR4L +mugayqLdU0OLuNPpo/bNdtyU5GC+wpSFF2jIkASK+4a7KFJq5SViOCT1BV1NoWMN +DzxXo1ODQjw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..a2def8d323 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v3-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem new file mode 100644 index 0000000000..8a97eaafc8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAgIUC26qMXLsjLi4NxcXvpWLTZI5pyUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXYzLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAkdjTbxvps6efTz63F1cnOMKU0NTgR+Qy +IrfrbMX00GOuABe4IoEiq5uuV0Lj0jkd0sKSc516oy79ZujJnow0sQp6igv3fBHz +6ZsQcHjULxd/PTsTGPp/NwLBsn49kXa/hwt1Us+59qH1oFtRPnQb4Hpr2QhXBR03 +DlhgsNHgaStKcfG37q1PIfDNENC4yM7mgQMvtqQX8QOmIEGAfnwBDLZAuD1GEZ5V +qxprydaCHommBoUKUOAxMnZudco9SDDHPI5IiM1kN/cQL+WDHVIJgWMURqS+Xrod +nkM5lFfdWGpU/79QLiCQC3mBpkyJ8Yu3bXCh4W4qxarC3n8QaCadjg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec new file mode 100644 index 0000000000..b336397ab6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v3-noBC +extension:keyUsage:keyCertSign,cRLSign +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem new file mode 100644 index 0000000000..000898b869 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAwIUD7Qul1mX5757Z6c1xfzbff8Bq3kwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXY0LUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAX1ogR2JROTKS +BzUzJ8dsfds1qRR4THa+4+1YcuuTJ1P66dnhnRXJVAdJmJyeqezQf23M5O56h4fL +ilt20gptvf7bFd+DZCnV9iHQidQnukj7CweiHOs5xCdjz6+ozZfFpQZaRWX9/462 +VxYOLIWw8ft23liLUmBP/BhPn7W+ILpwvvqLamO3xm68yAGLOlGfz9FH65wupkq2 +wuXjh2XOVEKZ5RdUzXrF40nzVUBBWPwvQTLge+2wD07jXuDegMVrBKkbZDara9TO +HNXcfbT1+9BcRJXlQDJGPyw6oFWHqH+FilAtbXryw3lc9forDWy6nLFvBGW+Ed7a +lpGnStAJ4A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..12b94e63a5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v4-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem new file mode 100644 index 0000000000..46401840ab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAwIULzzqCIST7DXQ9SzN6d/zzUSfj+UwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXY0LUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAKlQRoxIy8+V +EtYKZJGAsUvfB4+3LRWZy+eD89bhPUzEgh77u2EZS8byT9/I2+1kv1jJ7I6+G2m2 +cOLGILJBinEB8J3tOZHoUdiwAuqD0+zNBq+6sbItvNlJ84fh66Q1PTNnLWiKaQmr +oIQJ+Nu7crZHkfUrCn8DxHgfaZqI+FV3mWie1AQYrsU9g5ZevWokQr4AH9X/jPrt +ECbGoD5tPF0D3bAy3HxS1kCvwFSh0/GSszffYIaPrcUgOcUGYNdQSstE0y+lKZ2M +ncYUxXd6JI/3OFDTMKRh37JcyPAozQyVecJQLjRc4ycB5uy99zdZzHB2DsMHu3aB +gC2zpGY6iL8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..43a04f70fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v4-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem new file mode 100644 index 0000000000..c77ad4f7d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAwIUL9fvs2uc+o6yxIOieQDCERYiO0YwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXY0LW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAe6Q1mwKjfxiOiyvpExwNTAo48PGfDIAF +L9vF94d6fO7Z04Q5LeIMJwfXqb8sTJBBcsV51IYSMnK/EaVVf9vX7abcya6ku8VT +EF9THjT6+8gXKPj1v1te77kvu0tYRpDQeZ1Nhv7fRm8LsZFZPTKeT+ADR2qZo24J +K3073nn13fod1TnUYIWg5vjDezDUdgqWfRO35rPusy8DtIg3CqkYgXbQJQUnvEj+ +VDWbbmqc7tw3O0xFJVOPyo+/GAIqbSzmqJTzS9o3gBIzicBy8Q3B+s1F0+7qZELX +P8ZOSdY4L0iHKSVEZhFnEmcz/cySwTwt5ou90CdVaNCeOntga0e19A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec new file mode 100644 index 0000000000..4970d1e945 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v4-noBC +extension:keyUsage:keyCertSign,cRLSign +version:4 diff --git a/security/manager/ssl/tests/unit/test_cert_version/moz.build b/security/manager/ssl/tests/unit/test_cert_version/moz.build new file mode 100644 index 0000000000..2e2c294961 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/moz.build @@ -0,0 +1,61 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee_int-v1-BC-cA.pem', +# 'ee_int-v1-BC-not-cA.pem', +# 'ee_int-v1-noBC.pem', +# 'ee_int-v2-BC-cA.pem', +# 'ee_int-v2-BC-not-cA.pem', +# 'ee_int-v2-noBC.pem', +# 'ee_int-v3-BC-cA.pem', +# 'ee_int-v3-BC-not-cA.pem', +# 'ee_int-v3-noBC.pem', +# 'ee_int-v4-BC-cA.pem', +# 'ee_int-v4-BC-not-cA.pem', +# 'ee_int-v4-noBC.pem', +# 'ee-v1-BC-cA_ca.pem', +# 'ee-v1-BC-not-cA_ca.pem', +# 'ee-v1-noBC_ca.pem', +# 'ee-v2-BC-cA_ca.pem', +# 'ee-v2-BC-not-cA_ca.pem', +# 'ee-v2-noBC_ca.pem', +# 'ee-v3-BC-cA_ca.pem', +# 'ee-v3-BC-not-cA_ca.pem', +# 'ee-v3-noBC_ca.pem', +# 'ee-v4-BC-cA_ca.pem', +# 'ee-v4-BC-not-cA_ca.pem', +# 'ee-v4-noBC_ca.pem', +# 'int-v1-BC-cA_ca.pem', +# 'int-v1-BC-not-cA_ca.pem', +# 'int-v1-noBC_ca.pem', +# 'int-v2-BC-cA_ca.pem', +# 'int-v2-BC-not-cA_ca.pem', +# 'int-v2-noBC_ca.pem', +# 'int-v3-BC-cA_ca.pem', +# 'int-v3-BC-not-cA_ca.pem', +# 'int-v3-noBC_ca.pem', +# 'int-v4-BC-cA_ca.pem', +# 'int-v4-BC-not-cA_ca.pem', +# 'int-v4-noBC_ca.pem', +# 'ss-v1-BC-cA.pem', +# 'ss-v1-BC-not-cA.pem', +# 'ss-v1-noBC.pem', +# 'ss-v2-BC-cA.pem', +# 'ss-v2-BC-not-cA.pem', +# 'ss-v2-noBC.pem', +# 'ss-v3-BC-cA.pem', +# 'ss-v3-BC-not-cA.pem', +# 'ss-v3-noBC.pem', +# 'ss-v4-BC-cA.pem', +# 'ss-v4-BC-not-cA.pem', +# 'ss-v4-noBC.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem new file mode 100644 index 0000000000..cb9ec2ab97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbECFHd1Crm+6DaFhkTjrm8a2lNZn96/MA0GCSqGSIb3DQEBCwUAMBYx +FDASBgNVBAMMC3NzLXYxLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBYxFDASBgNVBAMMC3NzLXYxLUJDLWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCbtlhHVoAs3xPSRAoXxOuUpyTB +MzQWcIvsS61mkueLRnhBVzkpR+fVlmLUObLpZkVvZpTwlzhutw8A18ALBTfme9vY +8zdzMR/sNDRNe5kFDFWyqRAw7MWKKT70ViM9jJflEpN58wuboB6trwWoGuep5YSG +Tzl9vnxxAPwlvUbMzktFHUYyVfXes5mvA1IjujgexuSLAQP494QWvgjUIIcvd+Vj +FNBhDgj+bt7fhzRc4PF123lFn1bDpl7qxavC6+e7xx0AL1OPbifHTJD9M2sjrHe8 +Jqbq31/YoFQqgI+CTKH2IVnvioacB+rV4AxODP+unfIwNzjef5Z0UM/aXlMO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec new file mode 100644 index 0000000000..731396f034 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v1-BC-cA +subject:ss-v1-BC-cA +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem new file mode 100644 index 0000000000..0a9be9ba44 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbYCFHt8jLZUapQcsSi0Kh9mqYUtCnd8MA0GCSqGSIb3DQEBCwUAMBox +GDAWBgNVBAMMD3NzLXYxLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9zcy12MS1CQy1ub3QtY0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +DTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAFjtTHvdBSPcrUxP3PMM +dnBxm/idtTvwhRcoskIXF/uHw39W9Md4lu9PT5AaSRFy+DCPG6WGuZW7z8qo9ECc +2GbeoBCroJ7yYLQL0avK5SfWsuT79kBBuFXCD8NbDXQGle3RkXg+MrkCsvagoXqt +8vexfNXMwPu6g+iAxZ7LdNjLVmHo8Q8vQKiAxDvjjmscxxrlGc6/biSEychTeEDK +/JQMsD6uSadFCLBcKnZvAox05AxDd08yvlFGtGUx4NFToixkBUJZ8vPL9c0pHXVm +YDKdib/UsN940D+chT7EI4fsolX4F4Ti2c3XbIHqF5yFbySODDKm9eVRCFxfLwrs +7U8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..20d716d494 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v1-BC-not-cA +subject:ss-v1-BC-not-cA +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem new file mode 100644 index 0000000000..ca4d8e167a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CFCmTa/0HEBZWaC3cI4nBeSBnQgArMA0GCSqGSIb3DQEBCwUAMBUx +EzARBgNVBAMMCnNzLXYxLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIw +NTAwMDAwMFowFTETMBEGA1UEAwwKc3MtdjEtbm9CQzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAGsjqQY3SWLufSRTl3mGq0Wv4rI5mSYOJlsZKCMtVXkMMs3QUNCcD +1a7Fnae6tFjcpBElxgFFISLdmQ8lZXa4Et7flcwwYiQO9Hfzwpz/onlq1Cl150a0 +okDieDL5cklYlCoR2KGgq5T56K9PRKsAHWNys5Uhxfo+ysK/R8oqEVOUpm3k/Nsh +k9EMx40a+T7idLj3z+D3hAOm9sus+TVSd0JXT0IFyJKf9+h7A6OCQasO9sTN7vpN +O9nJf2aCU2rFPoTxOShDGJRqIFPLK2F1Efib8VqfZ85VmkepxyyzSpYnLYYtPLkK +bpSqCfUSchX8syla2zeOldxUHWA2RjWYVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec new file mode 100644 index 0000000000..58d2f0d7f5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v1-noBC +subject:ss-v1-noBC +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem new file mode 100644 index 0000000000..1442072cd4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAQIUQQKlrDt19yvMQsPwETMYCCytugwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjItQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjItQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHG8xQ7meUSvopihSREz +/svytvDvWFrlANJTBuUTDQUE/RR6uOgkJkSf3+je2Ngg4zCVkxqq+hSkbo+rQ+nA +MhcDpNDxqu0waYeujbFIPMQ5iapebD7GoGKYZjv8HOHcg+PDDClP5ANIfUJBuTEF +R9PePsHgnlF9wupRywfdd4E98psZmKhiHA7/rMiCmaf3lbxASVbqo2eWNMsBIzCb +FQXab4rplzcQ+B76IzTNWRv08x+K32dApNfirepO5yCE5aLXn3XrChzV8tHgPaco +gta9/I538U1xZOh3Z6qpQzksqL6r3inamvqvI10ZNB+/Mi0jUexPxyoj7MLCbtO1 +lI4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec new file mode 100644 index 0000000000..8dbb3a65ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v2-BC-cA +subject:ss-v2-BC-cA +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem new file mode 100644 index 0000000000..f78ceabdeb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAQIUNbZQDstJLaaiUaQfs27GbUHZ38UwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjItQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXYyLUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAJWGrrP8uHTXB +pIl5CU+IUk88BswSpETWnKenUqwyLfdQlr0fCzWPzZjZ+tbbtKLzHTdIhjAFqpwm +Q7fefDO/CNmmRb49OajJE8HO3cHltcWK8mbIUgMsdcWpCCNyUBmwuxsAMj4ggJHE +2p9KTvRorOj2Jzgvt2PktM7hV3Mh/hGP2VETMr4g1m87mSanFtmOUAX8BJ8Aemjj +HHwPzJMCjnnfDap6YpIzgQQoRK+f/X9PiAfxM1vzjVezdiXjB1WWxqKMf7AcyTbz +1QGA1bfMmJ1pRazpGqzeZmnADjvtcnmYKU0/MY5eAcmAVWRqbffg17Bgoj3ZKgc/ +sIiWXjciJA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..2b8f4bcc55 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v2-BC-not-cA +subject:ss-v2-BC-not-cA +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem new file mode 100644 index 0000000000..46909ed0f8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAQIUFaBZ6C5ChVgFJTuYCY+Fv2HlV9UwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjItbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12Mi1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQBnZXBfG8G0KE0SXdrsOA1pD/WGg0vnlbEZyL2/NCBoyuNb +l57Ktb2ZtmSVgiAAtEnDDmeqUxkLKK0EVxyO1rRfWfgMf9C5+YwZvglnev0fZLN5 +k3+hQp3y4d15fURD70DbVajH4zk3S61GdlvUL4ic2qU4J6B1NudQSaDa8gn9sCBq +rLrwmozkBOqL47QrFzXqigakuV+6b7ZU3Dh3c5xs2LtNMMlblMU2Ib0o/wgF7J6g +bouwR3fbrBTmIwPCSsw/zM98H5v0xWYiKpGd8RKrazVpPnEmKzmud8aYhasRpTeB +yQ+yfqGfJjrEJ/TAz++I/0/lAu63V1pFQRsTejAW +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec new file mode 100644 index 0000000000..7656115a84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v2-noBC +subject:ss-v2-noBC +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem new file mode 100644 index 0000000000..075d1f7071 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUETSep9lFvjlmLDhUIYgZJ9C1AZ4wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjMtQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjMtQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAJA2yM4He8/hSksOiLp +3WCPkSxarm9MIbj/XbbKpiDw5OZLsbwZzth6d1KJ38q57j0boNHNEPM5AJwW0jep +izBQzVS+8Xy0x66MxEIoaxF/tVWNBnWnr6WPci8XpJl60XUcj/T8kPrncZ4jfu8I +99qeMHMsv8LG4BzCZGkiHdmxGFbKvn9Fl1Incq2yTu4jR5nn9AeoyksYbbtbEFIB +YUgWpmSj9Eu2g9JT1nq35ovOZ7wgcDXxnFiCHcULiMOw2ZrMViWhMRKOo5o93kZn +34b4sPJ0dOnKVnLM09wICdvq2c4aDGKy6lCVoZPBV8yjxeqGdUeTVeHMZBJHAZUV +FmQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec new file mode 100644 index 0000000000..df822e99b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v3-BC-cA +subject:ss-v3-BC-cA +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem new file mode 100644 index 0000000000..897001600f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUCxOdFiOnJjGWpdtzdSkevnFmtiUwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjMtQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXYzLUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAsXgT1HoCwbXS +yEW8j3hk7f8XrtC+l5oXby/NtEEh0UqG5/gjkkoPUXKh3kU/EsmwzadFtr9j8H5i +Vy8+zr2rIkNzc8WkpXRLyvuwzRW04sIVmEnvvHWVnWIKoILk5XQ9wKKrXO40H4Jy +6Fva9+f31D5y1hsPbYfmfKZlNxPrM9Mvd+NG5N/PEkBDzHkqMTh0jTmUs99DcoyR +QVIta5ctnV8O+xWVTmKIte7hPGLnAUiDC54LNYkIXhevO6KbqpMvk74sKRPJRryt +2NiTaSKu9YxL+Nv5wWqh2quv8hp6y4kzGt/dp9CrE3GQXkCe/KrTJr4Z6EBQfglL +fy9XXKPejg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..0b2b575573 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v3-BC-not-cA +subject:ss-v3-BC-not-cA +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem new file mode 100644 index 0000000000..41c6121a97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAgIUK8t7xNHS43H4akDzvAdNmXRk9l0wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjMtbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12My1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQCh6MJjtVoXMs9CqIvFGOtC5xZBzApCyVVlO0sWRgdZ85Wr +n0vdkUsRk7TPTeRmxC9aNtUHAYv7PznW59b8Kt3eOC2datSCu/d4HLLZasuwk/ti +7ILH4wnLJx1NQJ/luax74pHmFR/ws+OomzL0IXu+nVsB/rv4OuNVZ2R4BlTsKdma +conhammBSvpgCwOAXnT8lZAY0z9jYZfWYqKFgTz3wj9kyocrlJZNshf5JULEK4KZ +tbJaVhFMv4BQK2ONaWj3fzjSVKW/lqUvd1P0c2Of/x48RXQlkZu5l87K/NQ99Nr5 +VprqZiNgNWMlOlMs+I2ooDjjdHLq/g5tlgF/kK48 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec new file mode 100644 index 0000000000..96314e51a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v3-noBC +subject:ss-v3-noBC +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem new file mode 100644 index 0000000000..b00a723c6c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAwIUGR1OiiW80EkYCQaIVEB2xPm51J8wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjQtQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjQtQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABE/8s/iuB1DHRKW7Odz +uv1MVeVgCYeWfVGJVZ9w5dMVvmng8/7tkSffzVmuKdbvcfugQ6QzTAXFaPeMzFa/ +djSrxTghal5rH36truQrNZKHkcMxzDkD1G7FuEYomZVuODWhRIQ1mZWS/AnyVoA0 +B4Dr7u1ULdDqaaWroxZX0i9UG2QtDX6DAytzeNJwxgJ0UhnHJ3b4uRJN92rObzQ9 +HwBwfWwFGfrjnO/DGn60NxDr6zdjNmK8pgzmEjgGxPE9lHsOkF4skq/9XnyUMh5N +41EXZL3PC7PwgG2nYeFEkUd0rP2HahxkBEIcO2iVWorqhfBWGLRQUzYtfd8V/5QU +B90= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec new file mode 100644 index 0000000000..54269184ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v4-BC-cA +subject:ss-v4-BC-cA +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem new file mode 100644 index 0000000000..b5aa017f80 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAwIUISiwRjGQW0zDa8BcggTNw+Gw6EAwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjQtQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXY0LUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAl20D6S5AemWE +GJMgprIXINyeCpH7K2umFjmzoVk73HosNjOaPDZPgk+v4n8Wf2CVg21uU4U3v5LK +1EHmNicbnI23fV/J/PPb1yy2YZ7+YPVolx8DwsxxYWH6N7aTGCdLwe6L44O91uQk +zCXNXD/mHyRraYb1xPFLIg1GzzIz8LVHrax9V7Jz/u3TlhSeSRORaUbvJgrCm9nX +V/7Ozc8czgtKfnTaeLz6791rK1my+gymoB01wbirqwxEzpWTlTFXUMCyzeLc/vuu +L9+vHAWT4pglrPMRCa4GqGlmIdXpTj65kiYMTVHOdP8xKZL9q6jfDYLB1buYt+pz +Nvh82338Bw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..3d65335316 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v4-BC-not-cA +subject:ss-v4-BC-not-cA +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem new file mode 100644 index 0000000000..275306dc28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAwIUAWcyAUceQlTM7+BoK8oA8uak6q0wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjQtbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12NC1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQCiyfMdjGJ6o4Yw2Q3L5QbFRBijGCTVn1547HXPibTewg8G +Z0/2twX36MKwbUGvq/rWMhsKKMrdbf72W9pCvyPcRQKfxO2XFqfxUF8TDUI0DKw7 +Wj1+vmfsxu99bArAk6ESUgYoYHij+Y5OLIKjWYgqXQEOVx+/Ywtv4kQv+Hlc1kzg +0H3rQcLboya8NxX6zNqO+l7xpKw+eoiEyF+hqjrjbAzKgbQbOA1t9ts1xlFcfTJ1 +36DqE4eWsP+lNBHPAOXSMXUtFEjgXw7UA73zOxWJUqnPRvKjqpMEE8P84bt7PoEX +riT1RslyhX2zDCn4KhLzbqrHk+9hZQ+K+HB+E9r3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec new file mode 100644 index 0000000000..d02e04de51 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v4-noBC +subject:ss-v4-noBC +version:4 diff --git a/security/manager/ssl/tests/unit/test_constructX509FromBase64.js b/security/manager/ssl/tests/unit/test_constructX509FromBase64.js new file mode 100644 index 0000000000..7a4f3915af --- /dev/null +++ b/security/manager/ssl/tests/unit/test_constructX509FromBase64.js @@ -0,0 +1,90 @@ +// -*- 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"; + +// Checks that ConstructX509FromBase64() accepts valid input and rejects invalid +// input. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function excMessage(e) { + if (e.message) { + let msg = e.message; + if (e.data) { + msg = msg + ": " + e.data; + } + return msg; + } + + return e.toString(); +} + +function testGood(data) { + try { + let cert = certDB.constructX509FromBase64(data.cert); + equal( + cert.commonName, + data.cn, + "Actual and expected commonName should match" + ); + } catch (e) { + info(`Exception: ${excMessage(e)}`); + ok(false, `Should not have gotten an exception for "CN=${data.cn}"`); + } +} + +function testBad(data) { + throws( + () => certDB.constructX509FromBase64(data.input), + data.result, + `Should get "${data.result}" for "${data.input}"` + ); +} + +function run_test() { + const badCases = [ + // Wrong type or too short + { input: null, result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "", result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "=", result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "==", result: /NS_ERROR_ILLEGAL_VALUE/ }, + // Not base64 + { input: "forty-four dead stone lions", result: /NS_ERROR_ILLEGAL_VALUE/ }, + // Not a cert + { + input: "Zm9ydHktZm91ciBkZWFkIHN0b25lIGxpb25z", + result: /NS_ERROR_FAILURE/, + }, + ]; + + // Real certs with all three padding levels + const goodCases = [ + { + cn: "A", + cert: + "MIHhMIGcAgEAMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNMTEwMzIzMjMyNTE3WhcNMTEwNDIyMjMyNTE3WjAMMQowCAYDVQQDEwFBMEwwDQYJKoZIhvcNAQEBBQADOwAwOAIxANFm7ZCfYNJViaDWTFuMClX3+9u18VFGiyLfM6xJrxir4QVtQC7VUC/WUGoBUs9COQIDAQABMA0GCSqGSIb3DQEBBQUAAzEAx2+gIwmuYjJO5SyabqIm4lB1MandHH1HQc0y0tUFshBOMESTzQRPSVwPn77a6R9t", + }, + { + cn: "Bo", + cert: + "MIHjMIGeAgEAMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAMTAkJvMB4XDTExMDMyMzIzMjYwMloXDTExMDQyMjIzMjYwMlowDTELMAkGA1UEAxMCQm8wTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEA1FoSl9w9HqMqVgk2K0J3OTiRsgHeNsQdPUl6S82ME33gH+E56PcWZA3nse+fpS3NAgMBAAEwDQYJKoZIhvcNAQEFBQADMQAo/e3BvQAmygiATljQ68tWPoWcbMwa1xxAvpWTEc1LOvMqeDBinBUqbAbSmPhGWb4=", + }, + { + cn: "Cid", + cert: + "MIHlMIGgAgEAMA0GCSqGSIb3DQEBBQUAMA4xDDAKBgNVBAMTA0NpZDAeFw0xMTAzMjMyMzI2MzJaFw0xMTA0MjIyMzI2MzJaMA4xDDAKBgNVBAMTA0NpZDBMMA0GCSqGSIb3DQEBAQUAAzsAMDgCMQDUUxlF5xKN+8KCSsR83sN+SRwJmZdliXsnBB7PU0OgbmOWN0u8yehRkmu39kN9tzcCAwEAATANBgkqhkiG9w0BAQUFAAMxAJ3UScNqRcjHFrNu4nuwRldZLJlVJvRYXp982V4/kYodQEGN4gJ+Qyj+HTsaXy5x/w==", + }, + ]; + + for (let badCase of badCases) { + testBad(badCase); + } + for (let goodCase of goodCases) { + testGood(goodCase); + } +} diff --git a/security/manager/ssl/tests/unit/test_content_signing.js b/security/manager/ssl/tests/unit/test_content_signing.js new file mode 100644 index 0000000000..e96db850b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing.js @@ -0,0 +1,435 @@ +/* -*- 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"; + +// These tests ensure content signatures are working correctly. + +// First, we need to set up some data +const PREF_SIGNATURE_ROOT = "security.content.signature.root_hash"; + +const TEST_DATA_DIR = "test_content_signing/"; + +const ONECRL_NAME = "oneCRL-signer.mozilla.org"; +const ABOUT_NEWTAB_NAME = "remotenewtab.content-signature.mozilla.org"; +var VERIFICATION_HISTOGRAM = Services.telemetry.getHistogramById( + "CONTENT_SIGNATURE_VERIFICATION_STATUS" +); +var ERROR_HISTOGRAM = Services.telemetry.getKeyedHistogramById( + "CONTENT_SIGNATURE_VERIFICATION_ERRORS" +); + +function getSignatureVerifier() { + return Cc["@mozilla.org/security/contentsignatureverifier;1"].getService( + Ci.nsIContentSignatureVerifier + ); +} + +function setRoot(filename) { + let cert = constructCertFromFile(filename); + Services.prefs.setCharPref(PREF_SIGNATURE_ROOT, cert.sha256Fingerprint); +} + +function getCertHash(name) { + let cert = constructCertFromFile(`test_content_signing/${name}.pem`); + return cert.sha256Fingerprint.replace(/:/g, ""); +} + +function loadChain(prefix, names) { + let chain = []; + for (let name of names) { + let filename = `${prefix}_${name}.pem`; + chain.push(readFile(do_get_file(filename))); + } + return chain; +} + +function check_telemetry(expected_index, expected, expectedId) { + for (let i = 0; i < 10; i++) { + let expected_value = 0; + if (i == expected_index) { + expected_value = expected; + } + let errorSnapshot = ERROR_HISTOGRAM.snapshot(); + for (let k in errorSnapshot) { + // We clear the histogram every time so there should be only this one + // category. + equal(k, expectedId); + equal(errorSnapshot[k].values[i] || 0, expected_value); + } + equal( + VERIFICATION_HISTOGRAM.snapshot().values[i] || 0, + expected_value, + "count " + + i + + ": " + + VERIFICATION_HISTOGRAM.snapshot().values[i] + + " expected " + + expected_value + ); + } + VERIFICATION_HISTOGRAM.clear(); + ERROR_HISTOGRAM.clear(); +} + +add_task(async function run_test() { + // set up some data + const DATA = readFile(do_get_file(TEST_DATA_DIR + "test.txt")); + const GOOD_SIGNATURE = + "p384ecdsa=" + + readFile(do_get_file(TEST_DATA_DIR + "test.txt.signature")).trim(); + + const BAD_SIGNATURE = + "p384ecdsa=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2r" + + "UWM4GJke4pE8ecHiXoi-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1G" + + "q25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L"; + + let remoteNewTabChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "remote_newtab_ee", + "int", + "root", + ]); + + let oneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee", + "int", + "root", + ]); + + let oneCRLBadKeyChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_wrong_key_ee", + "int", + "root", + ]); + + let noSANChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_no_SAN_ee", + "int", + "root", + ]); + + let expiredOneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee_expired", + "int", + "root", + ]); + + let notValidYetOneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee_not_valid_yet", + "int", + "root", + ]); + + // Check signature verification works without error before the root is set + VERIFICATION_HISTOGRAM.clear(); + let chain1 = oneCRLChain.join("\n"); + let verifier = getSignatureVerifier(); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "Before the root is set, signatures should fail to verify but not throw." + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + setRoot(TEST_DATA_DIR + "content_signing_root.pem"); + + // Check good signatures from good certificates with the correct SAN + ok( + await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + ), + "A OneCRL signature should verify with the OneCRL chain" + ); + let chain2 = remoteNewTabChain.join("\n"); + ok( + await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain2, + ABOUT_NEWTAB_NAME + ), + "A newtab signature should verify with the newtab chain" + ); + // Check for valid signature + check_telemetry(0, 2, getCertHash("content_signing_remote_newtab_ee")); + + // Check a bad signature when a good chain is provided + chain1 = oneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + BAD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A bad signature should not verify" + ); + // Check for invalid signature + check_telemetry(1, 1, getCertHash("content_signing_onecrl_ee")); + + // Check a good signature from cert with good SAN but a different key than the + // one used to create the signature + let badKeyChain = oneCRLBadKeyChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + badKeyChain, + ONECRL_NAME + )), + "A signature should not verify if the signing key is wrong" + ); + // Check for wrong key in cert. + check_telemetry(9, 1, getCertHash("content_signing_onecrl_wrong_key_ee")); + + // Check a good signature from cert with good SAN but a different key than the + // one used to create the signature (this time, an RSA key) + let rsaKeyChain = oneCRLBadKeyChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + rsaKeyChain, + ONECRL_NAME + )), + "A signature should not verify if the signing key is wrong (RSA)" + ); + // Check for wrong key in cert. + check_telemetry(9, 1, getCertHash("content_signing_onecrl_wrong_key_ee")); + + // Check a good signature from cert with good SAN but with chain missing root + let missingRoot = [oneCRLChain[0], oneCRLChain[1]].join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + missingRoot, + ONECRL_NAME + )), + "A signature should not verify if the chain is incomplete (missing root)" + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + // Check a good signature from cert with good SAN but with no path to root + let missingInt = [oneCRLChain[0], oneCRLChain[2]].join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + missingInt, + ONECRL_NAME + )), + "A signature should not verify if the chain is incomplete (missing int)" + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + // Check good signatures from good certificates with the wrong SANs + chain1 = oneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ABOUT_NEWTAB_NAME + )), + "A OneCRL signature should not verify if we require the newtab SAN" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_onecrl_ee")); + + chain2 = remoteNewTabChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain2, + ONECRL_NAME + )), + "A newtab signature should not verify if we require the OneCRL SAN" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_remote_newtab_ee")); + + // Check good signatures with good chains with some other invalid names + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + "" + )), + "A signature should not verify if the SANs do not match an empty name" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_onecrl_ee")); + + // Test expired certificate. + let chainExpired = expiredOneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chainExpired, + "" + )), + "A signature should not verify if the signing certificate is expired" + ); + // Check for expired cert. + check_telemetry(4, 1, getCertHash("content_signing_onecrl_ee_expired")); + + // Test not valid yet certificate. + let chainNotValidYet = notValidYetOneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chainNotValidYet, + "" + )), + "A signature should not verify if the signing certificate is not valid yet" + ); + // Check for not yet valid cert. + check_telemetry(5, 1, getCertHash("content_signing_onecrl_ee_not_valid_yet")); + + let relatedName = "subdomain." + ONECRL_NAME; + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + relatedName + )), + "A signature should not verify if the SANs do not match a related name" + ); + + let randomName = + "\xb1\x9bU\x1c\xae\xaa3\x19H\xdb\xed\xa1\xa1\xe0\x81\xfb" + + "\xb2\x8f\x1cP\xe5\x8b\x9c\xc2s\xd3\x1f\x8e\xbbN"; + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + randomName + )), + "A signature should not verify if the SANs do not match a random name" + ); + + // check good signatures with chains that have strange or missing SANs + chain1 = noSANChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A signature should not verify if the SANs do not match a supplied name" + ); + + // Check malformed signature data + chain1 = oneCRLChain.join("\n"); + let bad_signatures = [ + // wrong length + "p384ecdsa=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ecHiXoi-" + + "7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L==", + // incorrectly encoded + "p384ecdsa='WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ecHiXoi" + + "-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L=", + // missing directive + "other_directive=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ec" + + "HiXoi-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L", + // actually sha256 with RSA + "p384ecdsa=XS_jiQsS5qlzQyUKaA1nAnQn_OvxhvDfKybflB8Xe5gNH1wNmPGK1qN-jpeTfK" + + "6ob3l3gCTXrsMnOXMeht0kPP3wLfVgXbuuO135pQnsv0c-ltRMWLe56Cm4S4Z6E7WWKLPWaj" + + "jhAcG5dZxjffP9g7tuPP4lTUJztyc4d1z_zQZakEG7R0vN7P5_CaX9MiMzP4R7nC3H4Ba6yi" + + "yjlGvsZwJ_C5zDQzWWs95czUbMzbDScEZ_7AWnidw91jZn-fUK3xLb6m-Zb_b4GAqZ-vnXIf" + + "LpLB1Nzal42BQZn7i4rhAldYdcVvy7rOMlsTUb5Zz6vpVW9LCT9lMJ7Sq1xbU-0g==", + ]; + for (let badSig of bad_signatures) { + await Assert.rejects( + verifier.asyncVerifyContentSignature(DATA, badSig, chain1, ONECRL_NAME), + /NS_ERROR/, + `Bad or malformed signature "${badSig}" should be rejected` + ); + } + + // Check malformed and missing certificate chain data + let chainSuffix = [oneCRLChain[1], oneCRLChain[2]].join("\n"); + let badChains = [ + // no data + "", + // completely wrong data + "blah blah \n blah", + ]; + + let badSections = [ + // data that looks like PEM but isn't + "-----BEGIN CERTIFICATE-----\nBSsPRlYp5+gaFMRIczwUzaioRfteCjr94xyz0g==\n", + // data that will start to parse but won't base64decode + "-----BEGIN CERTIFICATE-----\nnon-base64-stuff\n-----END CERTIFICATE-----", + // data with garbage outside of PEM sections + "this data is garbage\n-----BEGIN CERTIFICATE-----\nnon-base64-stuff\n" + + "-----END CERTIFICATE-----", + ]; + + for (let badSection of badSections) { + // ensure we test each bad section on its own... + badChains.push(badSection); + // ... and as part of a chain with good certificates + badChains.push(badSection + "\n" + chainSuffix); + } + + for (let badChain of badChains) { + await Assert.rejects( + verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + badChain, + ONECRL_NAME + ), + /NS_ERROR/, + `Bad chain data starting "${badChain.substring(0, 80)}" ` + + "should be rejected" + ); + } + + ok( + !(await verifier.asyncVerifyContentSignature( + DATA + "appended data", + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (append)" + ); + ok( + !(await verifier.asyncVerifyContentSignature( + "prefixed data" + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (prefix)" + ); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA.replace(/e/g, "i"), + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (modify)" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem new file mode 100644 index 0000000000..e3d6133226 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUfypncvlf0ZBX1MQ7mXPauUSiPVMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQA/uUqk6o66 +Hfkdkn/XZA7Wszvsz4k+eQEf/0Y15EqvjGPm1pS1qj/aQXhKqwA6kDaIP8urgUOu +53ikXeiSE1LDFYHlduem8MgHg7tJ0QjzSAzdgjslHUuF0umbemwnXAbwGYfMlJOQ +Pc2898QJoev+6YWC0Mb3nV86X0NwH9BTKVCqaxrQi0edqndxKv6VggfAyhPaw+TN +jO8z3Hvv9APY184Spg/ndPhZPJ3hGCve8eus0hRhpSoRpGH6cmCw0IedUVhDpR1R +StT5bZ2/XEGaKFGEIjYKzrreMIgdOfNQlsBB1iD/40qi+Mi1/m9ctYJv2RJaEjpw +gu6XceM2TJaJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec new file mode 100644 index 0000000000..4134a73c6f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-CA +extension:basicConstraints:cA, +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem new file mode 100644 index 0000000000..0908caae85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUETmtBD+18aLFBIz4293Yn084a+MwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmVlLVJTQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaM9MDswEwYDVR0lBAww +CgYIKwYBBQUHAwMwJAYDVR0RBB0wG4IZb25lQ1JMLXNpZ25lci5tb3ppbGxhLm9y +ZzANBgkqhkiG9w0BAQsFAAOCAQEAEnk3u7e+n8mGwAbfy3Wj3RiBhXkJEN31ClBG +/NsXUeRBv89rPb2m8DyLBcEWvyNgQ0woyUPmrP5vsIUYQ64mshWuLgSzEk5/lY2+ +Quro14NKCTWo4F/DNgra5lq7Q3S8tXhmM+mBlsxK5QN2kWQM0ODlZtMp3P9821DH +OqaRTDvqd9dO2lFwlZ3vW5w5Uq/HQxciSkea4D2l1PcoWaqI7Zze66jj3H5kBoMY +SN4n9+RqPXUyBuF1A0d3W/jIzSnW7f3F6Gwe8fzhNsiyVE71tRHNForx4KtDR6BG +lyapz8MMoaTCgaS6gbv6RshJkRusqBQxvBY6JVgYBbkXw/IWBw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec new file mode 100644 index 0000000000..7b2a02bdaf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-CA +subject:ee-RSA +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem new file mode 100644 index 0000000000..7dba148b87 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICPzCCASegAwIBAgIUKVuGEG5eiGwlJfVnv/ULDdeFL0gwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +oWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3Ey2ozpjoMVNOapwMCwnI +1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP8ALwWvcaH93Mg3SqbqnO +oz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAkBgNVHREEHTAbghlvbmVDUkwtc2ln +bmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQA/Lumx62bij+HfehIY +6+jXkePuTOsaRpL1W5jk3ai78rWYRAVzDgM389kTBYJYCViHglgZQmQUeU8+sS46 +L/PO17BboOsCgqZt5QPSGPqSFvmqFgNOT2bl6rKtg6F5pM+orlCU816noIOCFOTJ +AHQHvK6qcy6SBGOn7BqvNMsRhGc7zqn2tTMt0FzjO7ULroR68aOLDCTzTgiDpz3A +DELgbpWFFE+W8flGnO1NRXwQDX3kEVlgVlOGrw5RsryE9HTYFhV4KXymxluKjL7C +oJFn115lsgbmbK38DKhjU4Sk0EHgFjC3K28fGaYtIBWoHAG3XGu1sBhWNCGCWqVH +Q7un +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec new file mode 100644 index 0000000000..ab22807b9e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem new file mode 100644 index 0000000000..ef22669f4d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICTjCCATagAwIBAgIUOQNrYQz01j0SirgoHMLKbtGL9RowDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAx +MDEwMDAwMDBaMBwxGjAYBgNVBAMMEWVlLWludC1DQS1leHBpcmVkMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEoWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3 +Ey2ozpjoMVNOapwMCwnI1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP +8ALwWvcaH93Mg3SqbqnOoz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAkBgNVHREE +HTAbghlvbmVDUkwtc2lnbmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEBCwUAA4IB +AQBZJPo4llgMe5588+BnRLnFguspIiwMWmTeqCfi8VQBx/tUwRiTizbU7J2Yh9bo +yZEPKfPSP2o8J0eSUgvXdVOxU1fNRuocsVfXUlveq5x10ddjXBT9X4AY1mtR7HJw +hl/7269N8b4itfrfvZmCBToJayjv0I2N84bqjpOnXJ/iB5YVdk8oZIJDXWi4SR3B +E9IejwA1fikpt++RjpJSZ1BSNU7FfiyGGUonxHDoP/29znaOJnpAqaH5LVJCRkfN +H12vePBbunZd+ay5r+mMJPaXR+V2sY8OaOfcrPSHQLa8Eb/EEhBuITMKkOucohjx +zqvM6S2iOI9GbwHClybEHRO7 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec new file mode 100644 index 0000000000..48fd9c8cc7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec @@ -0,0 +1,6 @@ +issuer:int-CA +subject:ee-int-CA-expired +subjectKey:secp384r1 +validity:20130101-20140101 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem new file mode 100644 index 0000000000..6cf5c6a312 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVDCCATygAwIBAgIUbV+rBAfhGRv/bU22A92xneoAy3owDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwNTAwMTAxMDAwMDAwWhgPMjA1MTAx +MDEwMDAwMDBaMCIxIDAeBgNVBAMMF2VlLWludC1DQS1ub3QteWV0LXZhbGlkMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEoWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXb +YI4lLeS3Ey2ozpjoMVNOapwMCwnI1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2p +cQO+KIjP8ALwWvcaH93Mg3SqbqnOoz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAk +BgNVHREEHTAbghlvbmVDUkwtc2lnbmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEB +CwUAA4IBAQAjXmLNn2kLa/FzNp7F3PqcSXuAO2jT31Y2g4pZnVqCDfMqplsl2ZFn +oam3wyQnepm3q9DD4BOAW9JFYR3wqnl9cBRNHlSGyjGM4qBpuSD6WxAz7EdFcRO6 +fcA50245fAuB45UJeYJ58QvIBv7AwoBGnqAI7ZDN3eIGopZIL56jiH7vO9WyQPWj +XZAWrXTG68rEf0RxXRtjUv9coFiuInT8+oyXB3NwK2EbaI5IeR+x3qIDEgNKk+t+ +PlE3NrtaAiK19p0s9RtQQilBKNmo+5irrUq/OD2H1aurDaAXpLTM5vLUpfyN3/qD +HzuZujaUIeMsRiXsIRDNql1S+nq4oNRy +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec new file mode 100644 index 0000000000..b2926dfc42 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec @@ -0,0 +1,6 @@ +issuer:int-CA +subject:ee-int-CA-not-yet-valid +subjectKey:secp384r1 +validity:20500101-20510101 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem new file mode 100644 index 0000000000..defa2dca5d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICIDCCAQigAwIBAgIUQQefsZHHyGIzVRjWiIp+2Sojjt8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLW5vLVNBTjB2MBAGByqGSM49AgEGBSuB +BAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMtqM6Y6DFT +TmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC8Fr3Gh/d +zIN0qm6pzqMXMBUwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQAD +ggEBAKT/ZTZsIyuxQFbK8CcN/DwFVxYfSDVLxDdv1hytINxuAHjpOF2kkcxHvUDf +pjXG6pMSFip2+dJp61qDrDzeb68K0bzYjGvalDbv9a8JDKUI+mhGTfm7wh2ZmxRm +SIZEP0fQ9TVB+h29bYqdBaanfWBAcvWKTKDIYE2visis8Jo29fBoeK6TC0fZpzzP +Y5tNZgbwHvMWW39lqTZj0FtKAN7jdRTM0O/KYNAqlbzmtf9gSDNCklxFLRZRlbqO +Z42M6FRc8k2ctbeFAGLZTF7ezolx8HlAUVbaptJPux7oj3dsCiq73aXExDPtiZj6 +9IX27OM4XsJhpS+RmI8GWqVSULI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec new file mode 100644 index 0000000000..4a9b9a3ceb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-CA +subject:ee-no-SAN +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem new file mode 100644 index 0000000000..ce04094e82 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCARSgAwIBAgIUeYPUd9Pk1MZC6Pv1MwwnCAybLMQwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLXdyb25nLWtleTBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABE+/u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnS +M0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjPTA7MBMGA1UdJQQMMAoGCCsG +AQUFBwMDMCQGA1UdEQQdMBuCGW9uZUNSTC1zaWduZXIubW96aWxsYS5vcmcwDQYJ +KoZIhvcNAQELBQADggEBAAsDCFfikCk7qQayhqET9q5qHWiXv+0NuLW9j3zpqwQY +uRXfiY34JsSpNtR+AVICUcierAoKfqXe6HTtDtQfjef8viCaer40dfLI9P5gx1l7 +nwybFl0oRNSBo6CZTcLHEdWHXbQvogj27wt75pRP66e9hFnH9FdOqp5WtP1nBVJr +wF8tdRZHHSLlsrLPtCBXMBtZxCBB6grqeIiuP5qz/+ayRvv+be4D6rqJrizHYgnW +q4y0pxHZzOYwrv+cqzRYaVOlwH0oU6mm0d8QDiry4yIGdNSOtO8/a8cdmbQakFXI +XK62f8bnkuYvn6wp/81lyK5DzFQLVobPnNnwloCyjII= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec new file mode 100644 index 0000000000..fbc8e603f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee-wrong-key +subjectKey:secp256r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem new file mode 100644 index 0000000000..a66b345a72 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICUDCCATigAwIBAgIUMX7ouKJot3CcYRs5Frqu4NZFy/wwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +oWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3Ey2ozpjoMVNOapwMCwnI +1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP8ALwWvcaH93Mg3SqbqnO +o04wTDATBgNVHSUEDDAKBggrBgEFBQcDAzA1BgNVHREELjAsgipyZW1vdGVuZXd0 +YWIuY29udGVudC1zaWduYXR1cmUubW96aWxsYS5vcmcwDQYJKoZIhvcNAQELBQAD +ggEBAAgkFNZeQNsGbNCAAWxVpWDdSgvCOYemduVhNJQTLZiZJkDia6hR+tgGGcoB +dkCOjK38ipFeTttdeGTAGW7XwfM7ViB41sRTZnmkuPfAbiQfd4PjZQQ/KqfWipsZ +UQbsXnoCNA9OfeE3RHK+79n8F+Wx7l0ISskYfMxoFE2HF42FuaZ0zh3CnLKQG+gn +l8tiB1a1XgSBRNvXIgpqbyKD5YlHyhj7mW9SkhKfaFRnmktpQWqpmxczRFRNpMnd +BcZRsmkQ+Kye+blgiBLudWrU18yDArYDHWD8ObhlVq9DSBqq1ClWdhxmMUxE95D0 +Bare3XT1RUSTBIuSH9gJFiiUpUw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec new file mode 100644 index 0000000000..81e1eefe1d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:remotenewtab.content-signature.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem new file mode 100644 index 0000000000..d35153e96d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUG3upUKWDjbYJ8e8IBkIMf7SrvMMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJTAjMAwGA1UdEwQFMAMBAf8wEwYD +VR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAKaz+RKqMBowh2H1 +HBun9kma1zWzkKb4ZNjke2eza3NDWCcDipnpYGB+iNhtzWPc2SA53ZF/yn/xDpWW +zF0UyKsswTxRIS/FmOkXqqTu0bHU7kmdIb+cqSuuDZDshdONGRDspQD/aYPva499 +eKc/X9E96ICCyTAVaL0YQz6UMjPgiTrrP1O5cpYb2uGbny5+okw/Ir3rlKhw0SGb +QqHuXmixawRj3PNzO0B63B0HsMdn+hbybHaZIkgNFrZ4pRmjnbiywMQNsvFzETZc +mgX9vf9puBLgn/3qBpJrObuZ4xux4stfBumKXWQ2S/7HaGn8W1mjOV82TQSCvx4X +Re529ME= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec new file mode 100644 index 0000000000..f5e387b0c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/moz.build b/security/manager/ssl/tests/unit/test_content_signing/moz.build new file mode 100644 index 0000000000..0e09e729e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'content_signing_int.pem', +# 'content_signing_onecrl_RSA_ee.pem', +# 'content_signing_onecrl_ee.pem', +# 'content_signing_onecrl_ee_expired.pem', +# 'content_signing_onecrl_ee_not_valid_yet.pem', +# 'content_signing_onecrl_no_SAN_ee.pem', +# 'content_signing_onecrl_wrong_key_ee.pem', +# 'content_signing_remote_newtab_ee.pem', +# 'content_signing_root.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_content_signing/pysign.py b/security/manager/ssl/tests/unit/test_content_signing/pysign.py new file mode 100644 index 0000000000..2d04cc40ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/pysign.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Create an ECDSA signature on the P-384 curve using the SHA-384 hash of data from +stdin. The key used for the signature is the secp384r1Encoded key used in pykey +and pycert. + +The certificates for the content signature tests make use of this program. +You can use pysign.py like this: + +cat test.txt | python pysign.py > test.txt.signature +""" + +import base64 +import binascii +import hashlib +import os +import six +import sys + +import ecdsa + +# For pykey +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +import pykey + +data = sys.stdin.buffer.read() + +key = pykey.ECCKey("secp384r1") +sig = key.signRaw(b"Content-Signature:\00" + data, pykey.HASH_SHA384) +print base64.b64encode(sig).replace("+", "-").replace("/", "_") diff --git a/security/manager/ssl/tests/unit/test_content_signing/test.txt b/security/manager/ssl/tests/unit/test_content_signing/test.txt new file mode 100644 index 0000000000..2daac1cb00 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/test.txt @@ -0,0 +1 @@ +This is a test file to test content-signature verification with a PKI. diff --git a/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature b/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature new file mode 100644 index 0000000000..e613981473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature @@ -0,0 +1 @@ +hSvmvvA7_QLedDsjRJGBevqLwjPILx1EtWSPP4A0fepaWWPuuZRB8VfDT2j07bKDacRsbmJjmvg_R4CpKmnoWF8-2w5lSszlFFDqYSvQVQxpKhu-HMM_qquu_l0KecQ2 diff --git a/security/manager/ssl/tests/unit/test_crlite_filters.js b/security/manager/ssl/tests/unit/test_crlite_filters.js new file mode 100644 index 0000000000..17d65773cb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters.js @@ -0,0 +1,697 @@ +// -*- 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/. + +// Tests that CRLite filter downloading works correctly. + +"use strict"; +do_get_profile(); // must be called before getting nsIX509CertDB + +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +const { + CRLiteFiltersClient, + IntermediatePreloadsClient, +} = RemoteSecuritySettings.init(); + +const CRLITE_FILTERS_ENABLED_PREF = + "security.remote_settings.crlite_filters.enabled"; +const INTERMEDIATES_ENABLED_PREF = + "security.remote_settings.intermediates.enabled"; +const INTERMEDIATES_DL_PER_POLL_PREF = + "security.remote_settings.intermediates.downloads_per_poll"; + +function getHashCommon(aStr, useBase64) { + let hasher = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hasher.init(Ci.nsICryptoHash.SHA256); + let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + stringStream.data = aStr; + hasher.updateFromStream(stringStream, -1); + + return hasher.finish(useBase64); +} + +// Get a hexified SHA-256 hash of the given string. +function getHash(aStr) { + return hexify(getHashCommon(aStr, false)); +} + +// Get the name of the file in the test directory to serve as the attachment +// for the given filter. +function getFilenameForFilter(filter) { + if (filter.type == "full") { + return "20201017-0-filter"; + } + if (filter.id == "0001") { + return "20201017-1-filter.stash"; + } + // The addition of another stash file was written more than a month after + // other parts of this test. As such, the second stash file for October 17th, + // 2020 was not readily available. Since the structure of stash files don't + // depend on each other, though, any two stash files are compatible, and so + // this stash from December 1st is used instead. + return "20201201-3-filter.stash"; +} + +/** + * Simulate a Remote Settings synchronization by filling up the local data with + * fake records. + * + * @param {*} filters List of filters for which we will create records. + * @param {Boolean} clear Whether or not to clear the local DB first. Defaults + * to true. + */ +async function syncAndDownload(filters, clear = true) { + const localDB = await CRLiteFiltersClient.client.db; + if (clear) { + await localDB.clear(); + } + + for (let filter of filters) { + const filename = getFilenameForFilter(filter); + const file = do_get_file(`test_crlite_filters/${filename}`); + const fileBytes = readFile(file); + + const record = { + details: { + name: `${filter.timestamp}-${filter.type}`, + }, + attachment: { + hash: getHash(fileBytes), + size: fileBytes.length, + filename, + location: `security-state-workspace/cert-revocations/test_crlite_filters/${filename}`, + mimetype: "application/octet-stream", + }, + incremental: filter.type == "diff", + effectiveTimestamp: new Date(filter.timestamp).getTime(), + parent: filter.type == "diff" ? filter.parent : undefined, + id: filter.id, + }; + + await localDB.create(record); + } + // This promise will wait for the end of downloading. + let promise = TestUtils.topicObserved( + "remote-security-settings:crlite-filters-downloaded" + ); + // Simulate polling for changes, trigger the download of attachments. + Services.obs.notifyObservers(null, "remote-settings:changes-poll-end"); + let results = await promise; + return results[1]; // topicObserved gives back a 2-array +} + +add_task(async function test_crlite_filters_disabled() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, false); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + ]); + equal(result, "disabled", "CRLite filter download should not have run"); +}); + +add_task(async function test_crlite_no_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([]); + equal( + result, + "unavailable", + "CRLite filter download should have run, but nothing was available" + ); +}); + +add_task(async function test_crlite_only_incremental_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + ]); + equal( + result, + "unavailable", + "CRLite filter download should have run, but no full filters were available" + ); +}); + +add_task(async function test_crlite_incremental_filters_with_wrong_parent() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0004", + parent: "0003", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + ["2019-01-01T00:00:00Z-full", "2019-01-01T06:00:00Z-diff"], + "Should have downloaded the expected CRLite filters" + ); +}); + +add_task(async function test_crlite_incremental_filter_too_early() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-02T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T00:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + ]); + equal( + result, + "finished;2019-01-02T00:00:00Z-full", + "CRLite filter download should have run" + ); +}); + +add_task(async function test_crlite_filters_basic() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + ]); + equal( + result, + "finished;2019-01-01T00:00:00Z-full", + "CRLite filter download should have run" + ); +}); + +add_task(async function test_crlite_filters_full_and_incremental() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + // These are deliberately listed out of order. + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-01T00:00:00Z-full", + "2019-01-01T06:00:00Z-diff", + "2019-01-01T12:00:00Z-diff", + "2019-01-01T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); +}); + +add_task(async function test_crlite_filters_multiple_days() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + // These are deliberately listed out of order. + { + timestamp: "2019-01-02T06:00:00Z", + type: "diff", + id: "0011", + parent: "0010", + }, + { + timestamp: "2019-01-03T12:00:00Z", + type: "diff", + id: "0022", + parent: "0021", + }, + { + timestamp: "2019-01-02T12:00:00Z", + type: "diff", + id: "0012", + parent: "0011", + }, + { + timestamp: "2019-01-03T18:00:00Z", + type: "diff", + id: "0023", + parent: "0022", + }, + { + timestamp: "2019-01-02T18:00:00Z", + type: "diff", + id: "0013", + parent: "0012", + }, + { timestamp: "2019-01-02T00:00:00Z", type: "full", id: "0010" }, + { timestamp: "2019-01-03T00:00:00Z", type: "full", id: "0020" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-03T06:00:00Z", + type: "diff", + id: "0021", + parent: "0020", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-03T00:00:00Z-full", + "2019-01-03T06:00:00Z-diff", + "2019-01-03T12:00:00Z-diff", + "2019-01-03T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); +}); + +function getCRLiteEnrollmentRecordFor(nsCert) { + let { subjectString, spkiHashString } = getSubjectAndSPKIHash(nsCert); + return { + subjectDN: btoa(subjectString), + pubKeyHash: spkiHashString, + crlite_enrolled: true, + }; +} + +add_task(async function test_crlite_filters_and_check_revocation() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let issuerCert = constructCertFromFile("test_crlite_filters/issuer.pem"); + let noSCTCertIssuer = constructCertFromFile( + "test_crlite_filters/no-sct-issuer.pem" + ); + + let crliteEnrollmentRecords = [ + getCRLiteEnrollmentRecordFor(issuerCert), + getCRLiteEnrollmentRecordFor(noSCTCertIssuer), + ]; + + await IntermediatePreloadsClient.onSync({ + data: { + current: crliteEnrollmentRecords, + created: crliteEnrollmentRecords, + updated: [], + deleted: [], + }, + }); + + let result = await syncAndDownload([ + { timestamp: "2020-10-17T00:00:00Z", type: "full", id: "0000" }, + ]); + equal( + result, + "finished;2020-10-17T00:00:00Z-full", + "CRLite filter download should have run" + ); + + let validCert = constructCertFromFile("test_crlite_filters/valid.pem"); + // NB: by not specifying Ci.nsIX509CertDB.FLAG_LOCAL_ONLY, this tests that + // the implementation does not fall back to OCSP fetching, because if it + // did, the implementation would attempt to connect to a server outside the + // test infrastructure, which would result in a crash in the test + // environment, which would be treated as a test failure. + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "vpn.worldofspeed.org", + 0 + ); + + let revokedCert = constructCertFromFile("test_crlite_filters/revoked.pem"); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + 0 + ); + + // Before any stashes are downloaded, this should verify successfully. + let revokedInStashCert = constructCertFromFile( + "test_crlite_filters/revoked-in-stash.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + result = await syncAndDownload( + [ + { + timestamp: "2020-10-17T03:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + ], + false + ); + equal( + result, + "finished;2020-10-17T03:00:00Z-diff", + "Should have downloaded the expected CRLite filters" + ); + + // After downloading the first stash, this should be revoked. + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + // Before downloading the second stash, this should not be revoked. + let revokedInStash2Cert = constructCertFromFile( + "test_crlite_filters/revoked-in-stash-2.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedInStash2Cert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "icsreps.com", + 0 + ); + + result = await syncAndDownload( + [ + { + timestamp: "2020-10-17T06:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + ], + false + ); + equal( + result, + "finished;2020-10-17T06:00:00Z-diff", + "Should have downloaded the expected CRLite filters" + ); + + // After downloading the second stash, this should be revoked. + await checkCertErrorGenericAtTime( + certdb, + revokedInStash2Cert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "icsreps.com", + 0 + ); + + // The other certificates should still get the same results as they did before. + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "vpn.worldofspeed.org", + 0 + ); + + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + 0 + ); + + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + // This certificate has no embedded SCTs, so it is not guaranteed to be in + // CT, so CRLite can't be guaranteed to give the correct answer, so it is + // not consulted, and the implementation falls back to OCSP. Since the real + // OCSP responder can't be reached, this results in a + // SEC_ERROR_OCSP_SERVER_ERROR. + let noSCTCert = constructCertFromFile("test_crlite_filters/no-sct.pem"); + // NB: this will cause an OCSP request to be sent to localhost:80, but + // since an OCSP responder shouldn't be running on that port, this should + // fail safely. + Services.prefs.setCharPref("network.dns.localDomains", "ocsp.digicert.com"); + Services.prefs.setBoolPref("security.OCSP.require", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + await checkCertErrorGenericAtTime( + certdb, + noSCTCert, + SEC_ERROR_OCSP_SERVER_ERROR, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "mail233.messagelabs.com", + 0 + ); + Services.prefs.clearUserPref("network.dns.localDomains"); + Services.prefs.clearUserPref("security.OCSP.require"); + Services.prefs.clearUserPref("security.OCSP.enabled"); + + // If the earliest certificate timestamp is within the merge delay of the + // logs for the filter we have, it won't be looked up, and thus won't be + // revoked. + // The earliest timestamp in this certificate is in August 2020, whereas + // the filter timestamp is in October 2020, so setting the merge delay to + // this large value simluates the situation being tested. + Services.prefs.setIntPref( + "security.pki.crlite_ct_merge_delay_seconds", + 60 * 60 * 24 * 60 + ); + // Since setting the merge delay parameter this way effectively makes this + // certificate "too new" to be covered by the filter, the implementation + // would fall back to OCSP fetching. Since this would result in a crash and + // test failure, the Ci.nsIX509CertDB.FLAG_LOCAL_ONLY is used. + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + Services.prefs.clearUserPref("security.pki.crlite_ct_merge_delay_seconds"); +}); + +add_task(async function test_crlite_filters_avoid_reprocessing_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-01T00:00:00Z-full", + "2019-01-01T06:00:00Z-diff", + "2019-01-01T12:00:00Z-diff", + "2019-01-01T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); + // This simulates another poll without clearing the database first. The + // filter and stashes should not be re-downloaded. + result = await syncAndDownload([], false); + equal(result, "finished;"); + + // If a new stash is added, only it should be downloaded. + result = await syncAndDownload( + [ + { + timestamp: "2019-01-02T00:00:00Z", + type: "diff", + id: "0004", + parent: "0003", + }, + ], + false + ); + equal(result, "finished;2019-01-02T00:00:00Z-diff"); +}); + +let server; + +function run_test() { + server = new HttpServer(); + server.start(-1); + registerCleanupFunction(() => server.stop(() => {})); + + server.registerDirectory( + "/cdn/security-state-workspace/cert-revocations/", + do_get_file(".") + ); + + server.registerPathHandler("/v1/", (request, response) => { + response.write( + JSON.stringify({ + capabilities: { + attachments: { + base_url: `http://localhost:${server.identity.primaryPort}/cdn/`, + }, + }, + }) + ); + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.setStatusLine(null, 200, "OK"); + }); + + Services.prefs.setCharPref( + "services.settings.server", + `http://localhost:${server.identity.primaryPort}/v1` + ); + + // Set intermediate preloading to download 0 intermediates at a time. + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 0); + + Services.prefs.setCharPref("browser.policies.loglevel", "debug"); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter Binary files differnew file mode 100644 index 0000000000..4da0a2ec14 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash Binary files differnew file mode 100644 index 0000000000..d43193a78c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash b/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash Binary files differnew file mode 100644 index 0000000000..52c9ee8d51 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem b/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem new file mode 100644 index 0000000000..ead19e3c14 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3 +MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE +CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD +EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD +BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv +K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e +cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY +pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n +eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB +AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv +9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n +b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG +CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv +MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz +91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2 +RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi +DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11 +GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x +LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem new file mode 100644 index 0000000000..70b86dfd71 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem new file mode 100644 index 0000000000..a690a0ad0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFpDCCBIygAwIBAgIQDVHBpbd6yyk2LgPoPr9QyjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTkxMTE4MDAwMDAwWhcN +MjExMTE4MTIwMDAwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju +aWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHTAbBgNVBAoTFFN5bWFudGVjIENv +cnBvcmF0aW9uMRcwFQYDVQQLEw5TeW1hbnRlYy5jbG91ZDEgMB4GA1UEAxMXbWFp +bDIzMy5tZXNzYWdlbGFicy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCyM1Fy9hAlahRqqeEnPKDWgUmsxofivWEWKNeSMEKcnXX3TCQOGbLQTthN +xfNU7IWY8ViTPwQ8JBWWDxNhd6dTYLNnytKrNRG8qDQ3rFMKJY4p0dZImMp55X3W +1xcKMxSOkPv0YUCGp7qlAHq6+N3YY1ILw6MRdJ75Njh4Kw8qe5F3rHLwD+AyYQmx +3WsMCRp5NZtWUcU5Vbc9ca/osrh9xBF7U3ZYR6GoPXQlizrNjXv7/BaKWWO5ChbD +iRI4Nj8d3HhWUHsJoGvYDof5Iudgtbubz3c5cwp6+VNNMas7izpvbixqW8zXdUug +8v5v47IkRNYnlma/zvv2IDC1dVlxAgMBAAGjggI2MIICMjAfBgNVHSMEGDAWgBQP +gGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUZnBdWwGQjkPX/+A2ZEYdUdnw +lN8wfQYDVR0RBHYwdIIbY2x1c3RlcjguZXUubWVzc2FnZWxhYnMuY29tgh5jbHVz +dGVyOG91dC5ldS5tZXNzYWdlbGFicy5jb22CHGNsdXN0ZXI4YS5ldS5tZXNzYWdl +bGFicy5jb22CF21haWwyMzMubWVzc2FnZWxhYnMuY29tMA4GA1UdDwEB/wQEAwIF +oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2g +K4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwL6At +oCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzYuY3JsMEwG +A1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3 +LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMHwGCCsGAQUFBwEBBHAwbjAkBggr +BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEYGCCsGAQUFBzAChjpo +dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyU2VjdXJlU2Vy +dmVyQ0EuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAK7vS/qDcGKb +QYu26+jGtBemopT3+2YJjtALeR62eNhF9LoHu+mnmNLvPI0M0NMhz56Ss/6sUHOz +hJgB98SLAQ5ElSWXrnZThLIjsiH5X5MYTD0Y8MqzoJSi2Lf2Muy/UpyrD3wB14E1 +kUYhvUnaWDDPIN81DCFzEosBmnsRqr5zlcZSKs0e1LVQ8cNkt8svVkiwFgeOIhwo +QF22GJAZPtRceSGlbRTFBYKh+u3KN8eNS/X+C935y+F4J/grufDCzRSGtRRseTcd +1QW49+QME/rx1mBb7id4iXNKxvGuJTivBlxaHWBQLh/RGk39DSdHfjAhYvt2gmxh +C3gxXMNrymE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem new file mode 100644 index 0000000000..9550453493 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGNTCCBR2gAwIBAgIIFn0oGKdatdgwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow +GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz +LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1 +cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMjAwOTI3MTE0MzI0WhcN +MjExMDI5MTE0MzI0WjA5MSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0 +ZWQxFDASBgNVBAMTC2ljc3JlcHMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAydMKPhCqRWjy5h1aPUNdRb80kt0hP/g55ytjlSF04PG+1CbIcId1 +GJg1qkbTR1vqZyvaI8wjv3zdfvsvYbka9OQFJiOasJfeqmiA+sDd9AvFiD2EF5zN +D9uKHi+sF8Ut4JMl7jqaRAu/gbjBvY/9ammkz4sUiTlp1x4rteda3tuX9O7yMO7U +ldnyfabHgGmmm8KU3nvRAjNbHCq3J/V/zw8YeolXU5OpOeZMhI8KAGKpxk8tRiIb +LkdSdCTWoKgXO60extYcGTxIT8c8zfY6OoN0VaQY8HA1VyBZQIw2RTWivmI8le0J +ypXYxNcUtInS0ivO4ymiNnCjYR9pgQ6+tQIDAQABo4ICwzCCAr8wDAYDVR0TAQH/ +BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD +AgWgMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rp +ZzJzMS0yMzM0LmNybDBdBgNVHSAEVjBUMEgGC2CGSAGG/W0BBxcBMDkwNwYIKwYB +BQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9y +eS8wCAYGZ4EMAQIBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDov +L29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8vY2VydGlmaWNh +dGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8GA1UdIwQYMBaA +FEDCvSeOzDSDMKIz1/tss/C0LIDOMCcGA1UdEQQgMB6CC2ljc3JlcHMuY29tgg93 +d3cuaWNzcmVwcy5jb20wHQYDVR0OBBYEFEgqFQnM5zH3cKFGtFanJxxD9zdPMIIB +BAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98M +LyALzE7xZOMAAAF0z1/40gAABAMARjBEAiADSOnqg/I15y+dJDSWta8NzBwE6Xti +UzyBKMT2OYHCYwIgb1aFpZxlkhx6XCCuniBLTcr5JbhigoM/lAfUmvvUqrIAdwBc +3EOS/uarRUSxXprUVuYQN/vV+kfcoXOUsl7m9scOygAAAXTPX/oBAAAEAwBIMEYC +IQD6WvavTba+Lydf6uhaaxcRmhuuPeddzSmC8t4+tBLGGgIhANJPxhRl1pGYm6WX +ay9jPCM2SqtBraOJYncaV6k37zGYMA0GCSqGSIb3DQEBCwUAA4IBAQA0IknIoU51 +FCBqpksgo7zR9OJj5MoQmlsQbzSFppdRKgyHhk8rW6IrBi3yrtWjo3HxcwihZlJQ +2AbinRTNnHvBpiiiXXxR5u9yVly+9l3KfF/uHIGMnIqsahaKXNOy5h98uq4o4N0+ +YCGu9wSeDwtaCzdT+V447Fq63nmW629pjwin8FYCz2S8RdztranPZuOgwYqBNlWu +u3Mi9DWIV2hP6eFwMZh7BWgbvnhWiI37TE74YQ+3cEVaLxLHJH9jkBjsel+ZwVIo +9xeE6kGsh5+D0uHS5NWf9zu+fvW0iTgsB8J4VX5OihAa1v4FS4IaF3snkaMa0PCd +MJMOgY5VkZiw +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem new file mode 100644 index 0000000000..1073159662 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGPTCCBSWgAwIBAgIJAJeW47AXop8NMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa +MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 +cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj +dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTIwMDgyMjIzMDI0NVoX +DTIxMDkyMTIxMTYxMVowPDEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh +dGVkMRcwFQYDVQQDEw5zdG9rZWRtb3RvLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANLX8D4Cin6x2bmoSdgnuw9O+tGcD1x1S++3110NJVXUlpSc +3uSUwqpU4rMOkJlRnuaBtHXYUFG8NMMnbTJYY9JuuhAlnHzVqoRWmcTNRp72fpDA +XoD3U20spJeGQZXuQnGfe/k9EouvXt5du029YqItkFbjdbub4FP5MbIz1CWeelEn +fEwpe/peLVYEfKSyYf325tFI9wZhuIM/zTe9DE6lauznM8hg1ioiBujxzeWWSstZ +K2uJKaI8nlWkSr6vwPqJEBvvoShcWHFEmG8SWqPBy1tsNsLNjJkaHfD7gvG/J1Rc +G21D0XO2IA0rEo6lo8MNEkWoHZA/oHO1eHrCjNkCAwEAAaOCAscwggLDMAwGA1Ud +EwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB +/wQEAwIFoDA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vY3JsLmdvZGFkZHkuY29t +L2dkaWcyczEtMjIzNy5jcmwwXQYDVR0gBFYwVDBIBgtghkgBhv1tAQcXATA5MDcG +CCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9z +aXRvcnkvMAgGBmeBDAECATB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0 +dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRp +ZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSME +GDAWgBRAwr0njsw0gzCiM9f7bLPwtCyAzjAtBgNVHREEJjAkgg5zdG9rZWRtb3Rv +LmNvbYISd3d3LnN0b2tlZG1vdG8uY29tMB0GA1UdDgQWBBTP8YI0WwVBgvg5GABQ +fUksbk6evjCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1APZclC/RdzAiFFQYCDCU +Vo7jTRMZM7/fDC8gC8xO8WTjAAABdBhpJtAAAAQDAEYwRAIgcrebTXyuMk/ciVyg +LMbbd6qbkyB3yRAY1QnBs5sGK1ICIGw6EpH/NMXcOfYdkuSmhSYgUx0AIDdT9QWH +rRIT50D3AHUAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDsoAAAF0GGko +AwAABAMARjBEAiBtzQQHVVML3yZhZRsLLhJkYcc11nXeU/S/rouOZCCZQQIgVYKY +jgjCU5HQyY6R5PZQTsCQGWiaOm1VguAIgPbvKzYwDQYJKoZIhvcNAQELBQADggEB +AH6jCZU9+5TMaR5XThGL/z8EYQ1uFVN0hlXXB+gP3IDQLmyxkqrk9cOSf1D6fLRT +5T4tGzPLvmReBLfrzQEkuqkXpUieortbpi116V82K+zBDT5s9Dol6+MxhwIZyZ7K +DkHSbcFyiV9hkr2bf8JZzjvpCOfw9kYZTcYv8M8kheIOQsONdfe/rqNQnMRy56UZ +OGZmxqDT2RwbewHEMAEb5ZsZ55/UHq08vZSVSA8qIqX/BU+7frwwt4vmv4WQ7AoJ +YNml0TdV4R27NlnvhbAclucuqEMBcBg8gNylvKD3Mid7O4c5gCX5Wuml6rLpOr05 +vpJJqSf0uy73EtNcyTqfwUQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem new file mode 100644 index 0000000000..ece7360def --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIIHTjCCBjagAwIBAgIILTXKZQP7G6MwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow +GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz +LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1 +cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMjAwODIyMjM0ODE1WhcN +MjEwMTE0MjEwMzAxWjBDMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0 +ZWQxHjAcBgNVBAMMFSoudXMtZGF0YXJlY292ZXJ5LmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAKzuSr8LaH2Aw/G1aKN4URo0RwaFv4+7MzM0RVTB +189BdE8rgNRfxskoAVfte+iftO7P5qjg+1Jx8SCE1ZCNT2TGtcYwlsjyNLnbP3xV +Cq514bODlwimOKLhpUFH1/ofO4/enbU8E4hlxS4DPtOGbsjouTiRHAOLsi7D+WT3 +3pZelFa5Hgmed5dL/CCJTiwbF10lbTXNwLgI7efUqiwvHRwf/CXEW9IvKJ9HG2We +tT9ouQGOHfz4fyGOMN268dHqP89K+auCcf9b3BzzWOsknhmDisl+06WaIJe/W7Dn ++eG07nAuJLhE6nH9KLYiU2X5CHnLPvBTOPDdm/hzH84hnHkX2pSbst4d1aNtU4uP +hyQcE5aMfnV7Yr1ZQUlLreCKzwIAb6BKqF/gHMASXUX7Fw5OFUHxV1xcPbcHQLs6 +D3XAoLBzopTR4YjxIDqhS3pkxHu5u9OEzFfaeP5zYnrj69Bke3lrdbrKV8aXIxHn +xh9xJV4zAaPoHe8ze03zvdBXfu69DU+TTQkRfzJSZx/sXV6BHe15WGSHZxe0i61z +wA1Oi7QgySMKIKSs6dsPOqppmePc3seMJy7y0FSxF1Kq6a1tR+W3j2WT9nY1c4Wb +4LWc+0gDK3nvibJbFqCfnPznq/Q+q0V6m9BqBNjvqyyWXbgzCVn7qcT4apiP47IV ++MiBAgMBAAGjggLSMIICzjAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwOAYDVR0fBDEwLzAtoCugKYYn +aHR0cDovL2NybC5nb2RhZGR5LmNvbS9nZGlnMnMxLTIyMzcuY3JsMF0GA1UdIARW +MFQwSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmlj +YXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzAIBgZngQwBAgEwdgYIKwYBBQUH +AQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYI +KwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np +dG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4w +NQYDVR0RBC4wLIIVKi51cy1kYXRhcmVjb3ZlcnkuY29tghN1cy1kYXRhcmVjb3Zl +cnkuY29tMB0GA1UdDgQWBBTooRcQfblnnD7pJFCZfGGcf4kD4jCCAQUGCisGAQQB +1nkCBAIEgfYEgfMA8QB3APZclC/RdzAiFFQYCDCUVo7jTRMZM7/fDC8gC8xO8WTj +AAABdBiSoGUAAAQDAEgwRgIhAI4Cd+FhKsWdUZkBugaburD9dzdlVHSxKq6oYNyI +vmIIAiEAwlmkvAiPb9nwDirqe7MZud5nu/lmq/Ip7M1xSKuraykAdgBc3EOS/uar +RUSxXprUVuYQN/vV+kfcoXOUsl7m9scOygAAAXQYkqGUAAAEAwBHMEUCIQCpYqq+ +Uc881tR+ikvsR97FRl6jBfxG50Sum+cdHEQkYQIgZJbGaeNoDS9+LAKI88NNRiCK +vtQZkwWigDYr+2dWguYwDQYJKoZIhvcNAQELBQADggEBAD+sj44+86AvdVUrAN9h +cU6kt4I6K1TM0KBmKg3rG8JEY7+Ec4Rztls3uviLR0ajH5tkQPwD7vRBVrLVDtQS +Ndt2StR38AXiBRWwewy/sPMz11YzOPLyHaTl4pJVfyzHJ+rPdWuFZLtpTras/MIK +IFnnbInlh5XtRhDCv6UEkAmGu5BeftA+9XxTuZlbwQlO5U1yg9Hqor9zANMqX9Ad +3omIZrPtBkTdVOwHRU8SoaS6XxQ9jxcmWRgNTVAhU1/J7Bgvg3CPSpcHyV78sXkS +D9bb1f4jdadaMKuJc0mTHBAxZenr3IFV8upf2FRTJnrCiS0jX8kKobN/+04Gbev6 +Tr0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem b/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem new file mode 100644 index 0000000000..6769ba3d37 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIGyTCCBbGgAwIBAgIJANpPOSv9i86oMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa +MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 +cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj +dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE4MTAxNTE5NTQxNFoX +DTIwMTAyNDE4MzczOFowQjEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh +dGVkMR0wGwYDVQQDExR2cG4ud29ybGRvZnNwZWVkLm9yZzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKb1cjhtYv6yiyZa1feabWaSBOCmN0JuqXIMkX3r +4g+5heKAwPFlPFbZ3vZ3DQXiliV7jb5nhlx0O6nYG+MoGFmj6hEHDptCASAfdd3j +4tCxg0FlilXgrgMkJCg+SjW0npZ86jMkfc0WzufUyMjxv2pUUicPNXyWbaQr+PCq +zs6AsOkmuQ8RUUAqZ+Q0EJfQnjuhql7NCdByNui9S2LmrPcV6TAHHeTwKX733edv +zsNzaLNgE6TLGXSSRvsW/eZ/uNScPHLybE4wdxxCDwSYCPwaQq34csc3a8SUTWfS +4UkdbOn7j5sZPx7Jj0uUlm20ZDsj2FUi/0SXNvz5flFQbVsCAwEAAaOCA00wggNJ +MAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4G +A1UdDwEB/wQEAwIFoDA3BgNVHR8EMDAuMCygKqAohiZodHRwOi8vY3JsLmdvZGFk +ZHkuY29tL2dkaWcyczEtODc4LmNybDBdBgNVHSAEVjBUMEgGC2CGSAGG/W0BBxcB +MDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20v +cmVwb3NpdG9yeS8wCAYGZ4EMAQIBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcw +AYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8v +Y2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8G +A1UdIwQYMBaAFEDCvSeOzDSDMKIz1/tss/C0LIDOMDkGA1UdEQQyMDCCFHZwbi53 +b3JsZG9mc3BlZWQub3Jnghh3d3cudnBuLndvcmxkb2ZzcGVlZC5vcmcwHQYDVR0O +BBYEFGjmOgodY5yPX19UPVcACFpVExz1MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFp +AWcAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWZ5SxEeAAAE +AwBHMEUCIEL5OLHwBpIALbEnLFQntFlGBe8Oko6U/arr15jU4sLDAiEA6uy8DEnh +PFLOxXDC3ZaeOlK2+cdx76IAr6M6As74ETEAdgDuS723dc5guuFCaR+r4Z5mow9+ +X7By2IMAxHuJeqj9ywAAAWZ5SxMzAAAEAwBHMEUCIFWIeePa6jdf6y9o/YYxoqWr +Je3j8W94e4f5bixaGPiyAiEA7aJRZI+aWCE/zz5DpvcyRgkIoSKS3+dKS2irf/mp +qx0AdQBep3P531bA57U2SH3QSeAyepGaDIShEhKEGHWWgXFFWAAAAWZ5SxPjAAAE +AwBGMEQCIEkYw6g/cIZBdOUh+ETwl2XX2S0Bv8iGGiaOKOoXqVK6AiAh3eqABfMc +9b/wLJZo186YgbzmbZB0N3y5TUJKK1oMYDANBgkqhkiG9w0BAQsFAAOCAQEAPEwx +d597oqiP9/TN8RDrZqhn4uLZ9K5mXOD93RorUN8T8O1kV0B4UcXM1CkU2zxv4a9S +tG3diHjmfJgcrhpa4i19sZD7+QpTU8j0e82JlsB3MpbtuaiBwqb979c5qNPixQlJ +kDs4DWf8kV+4B9/DWWLDKvs+FtL8ST8n+LfwstZqi2EyK+1ZyM0p9hkUAzrT/M2h +Ou1DYELbCt2HaKMHMPSlrkESG7Q9v9Ba23EXElG+oFXxgnPwk4n84rYG8lI8pPyA +clunJNqc2cISUTDMdgGctCFdSVGyEq+8VVG5Y6Od5LMwtOLKcv+VPi17+iGfxNt/ ++dAMbzGIlDuJELwn0g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct.js b/security/manager/ssl/tests/unit/test_ct.js new file mode 100644 index 0000000000..59db48f858 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct.js @@ -0,0 +1,75 @@ +// -*- 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"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function expectCT(value) { + return securityInfo => { + Assert.equal( + securityInfo.certificateTransparencyStatus, + value, + "actual and expected CT status should match" + ); + }; +} + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.pki.certificate_transparency.mode"); + let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem"); + setCertTrust(cert, ",,"); +}); + +function run_test() { + Services.prefs.setIntPref("security.pki.certificate_transparency.mode", 1); + add_tls_server_setup("BadCertAndPinningServer", "test_ct"); + // These certificates have a validity period of 800 days, which is a little + // over 2 years and 2 months. This gets rounded down to 2 years (since it's + // less than 2 years and 3 months). Our policy requires N + 1 embedded SCTs, + // where N is 2 in this case. So, a policy-compliant certificate would have at + // least 3 SCTs. + add_connection_test( + "ct-valid.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT + ) + ); + // This certificate has only 2 embedded SCTs, and so is not policy-compliant. + add_connection_test( + "ct-insufficient-scts.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo + .CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS + ) + ); + + // Test that if an end-entity is marked as a trust anchor, CT verification + // returns a "not enough SCTs" result. + add_test(() => { + let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem"); + setCertTrust(cert, "CTu,,"); + clearSessionCache(); + run_next_test(); + }); + add_connection_test( + "ct-valid.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo + .CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS + ) + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem new file mode 100644 index 0000000000..c015087e85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEsjCCA5qgAwIBAgIUD7pA2hQ6aiqRWzwjIb6zStU4wxMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDDCBjdC1pbnN1ZmZpY2llbnQtc2N0cy5leGFt +cGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOCAeEwggHdMBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20w +ggG/BgorBgEEAdZ5AgQCBIIBrwSCAasBqQB2ACq4MEQzuRTe0vMeQgfyUcF6N6CS +aFLZCAIG+F5XORYqAAABUfp73AAAAAQDAEcwRQIgXHVRnxMRUM1dit4go7wGMJH/ +snN1XzFk7P3LQoAKcOYCIQD0nA7JqwaCdhzWfXxdSrCk6FesmzZ8JJ9CHVN7JqEr +JAEvADEI9rbdchgH8BaVhE2FAla2cZNgg9u9OTSgUFJQGiiSAAABUfp73AAAAAQB +AQAJQ/auHYB8PHgYp6ApXGqdIPM6hRnYlX292tOXymT3atbxcBbrwCaW01Y3mU7F +ndLHBxnfcUdGK314D/GF+8Ez5k+/kWsKYkxH+pVFLcHuyJ6bVREfRkqEgwrenDlz +3NvxXGXUoWgYKfT9fWoMJui1IuRIbDjci0qBq+vT6GhcNJHdXHm41Yze+NjmsmKx +5XEwSQIqg/NeUwuDrsPU9LOcjZ3OVEAH1aVWY8cy5EhVA+Zojk9mTXVE/iuBCp/n +90V9dXyK+E7+ougZ+jnhrlcPCmULgW/Q8LNtRtR0KKexWMom2PSjs1GmbU/l8Wm3 +sv7vmhihg5SQsitmM4CHjxWtMA0GCSqGSIb3DQEBCwUAA4IBAQAeXJGA3UeqCgu4 +VXi8ZvPAmz2BXIfEiwtOXwvuvK1u0SsuwkLoSkKwk2Qr5/p69qn8mpQQmd5zSQ2v +sAAviWu0rl4ugfQr8DOHX1DUF0o82xNMhR/xvz4cpNr3SPrVJOgFqf2oKquo7dzI +kE5vYqACL9w/pRht2EUTJ1eWwNDoz9FCY9zmsvFAiCc2WLWWomKW0VmhxJ+8zLCO +Yk3PBHhipjjGobt6UcG4/QViwKZlRIUKyDMHJ16NhXmicmKWz7LVfkN1XtOpOPGh +v7AX58qHA4ZjBg3AOzfvew+pDdnrAIgrUqcatMqu31xieJVLHDGsg2c5ID3xPx+P +AHOmzcCa +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec new file mode 100644 index 0000000000..c40f26d5d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:ct-insufficient-scts.example.com +extension:subjectAlternativeName:*.example.com +extension:embeddedSCTList:secp256r1:20160101,alternate:20160101 diff --git a/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem new file mode 100644 index 0000000000..f7c6ab8b0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF1zCCBL+gAwIBAgIUF5bjHB2T8yqxNGQJmDc0Cm6FVTYwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRjdC12YWxpZC5leGFtcGxlLmNvbTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOCAxIwggMOMBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20wggLwBgorBgEEAdZ5 +AgQCBIIC4ASCAtwC2gEvAFQiJZjzPTZIBULa7ODmuU3hXA7ujFkUykjXXjxIToA/ +AAABUfp73AAAAAQBAQANJRHiZJgVmreqeqGKEvgLaZbuVZyz5Vp1IfzawYVV2J5/ +mbvIxX9yQcJVQhHHdWgyc2WzYvgQTQ8XwUg12Xx2za7c8y0YvEbVfb0bPVDXRvWY +r8YaKgJJuAJO1SqR9lB8iDEz/6BahLGfM9C8ypXoCTtpQ14oV/qSsFzJhys9jlLI +p6AjXgNSqv/NVVMnvTWJ5AOzhIdJJQmVNZM0NXdDZmqlC4Wk8r8rJKYzGswm6CkC +JJ7+WCzuM0ufP5JyLGOp8AsEJvURajm19v09uifDieYysAlBAukPCur3ni8SIxS6 +12iFjawXIeQMkobGanZyKMFYsfeFnQCUBi6Kr1a4AHYAKrgwRDO5FN7S8x5CB/JR +wXo3oJJoUtkIAgb4Xlc5FioAAAFR+nvcAAAABAMARzBFAiBcdVGfExFQzV2K3iCj +vAYwkf+yc3VfMWTs/ctCgApw5gIhAJGsOl/pvErK6FvgTc4TNRBDdX2x37AhywuA +NtqY3PZhAS8AMQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJIAAAFR+nvc +AAAABAEBAIAsvMMHiK9UjMgfOjdtLP2bJwLxQ6qHHgJ6IooQgq95gvXpZmhDhSrB +WzHtjSf0G8NrIYQLfGNqeUFjVq7Yby8FkOMrE/VbQrvSHOADJ65hqPesNfRLjWuD +1u9IjlTZFyIxZcrN2OqjWnBfsAylivHAHGj/1vbZqvOKWmQbBpuNW2P5p35uArEX +r5jhBxfM0HO07UgDJzt8oG3fK+iDV/wv3R6Y4LvO+SebnHiXg9HygwG0wi8bGMYK +2wXNUsQ3tdBq4WeJr9cxoH8Ke9l+sLUc9wZ1N7lV7p7hmZeN+nSt6aJny/DfCLoo +rG62y/At1y4l0FmXXvPftkv1QunvWj0wDQYJKoZIhvcNAQELBQADggEBAEFe0sch +6JG7g3uiNpomqOqNaBHnoe5qsYONRTRajDRl8/qyn9NwkMEks0bR6xwBQmBOpN5X ++0TLa43nv28V7B66Mfnpv9ISKdhOytQYN39us0LMBEP8dR/YK5Ux2JH/+iI6IHl0 +syErYIki6Wuz6NxVKAaQN7iB+Qw+pCSJLkbRojXCqSKUwP1uBrhMW1Oe3N2o/eZr +ZpS9IWYtBeb3zPKlMIQHLEUxOBq6SvrNrxcylNKPBXHWTfvFvZYVgLmqzIyti1mw +yC1fr2sMriB6cFd/7i+Mnh4vK31yH/c1KwxDnpOUCEToryH6z+1ydWxyoLgnO6Za +Vx9PmW79Rj2mSFM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec new file mode 100644 index 0000000000..0ecf46d89c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:ct-valid.example.com +extension:subjectAlternativeName:*.example.com +extension:embeddedSCTList:default:20160101,secp256r1:20160101,alternate:20160101 diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.key b/security/manager/ssl/tests/unit/test_ct/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.pem b/security/manager/ssl/tests/unit/test_ct/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_ct/moz.build b/security/manager/ssl/tests/unit/test_ct/moz.build new file mode 100644 index 0000000000..d0fc04f747 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/moz.build @@ -0,0 +1,23 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ct-valid.example.com.pem', +# 'ct-insufficient-scts.example.com.pem', +# 'default-ee.pem', +# 'test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ct/test-ca.pem b/security/manager/ssl/tests/unit/test_ct/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_db_format_pref_new.js b/security/manager/ssl/tests/unit/test_db_format_pref_new.js new file mode 100644 index 0000000000..b242ad0832 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_db_format_pref_new.js @@ -0,0 +1,22 @@ +// -*- 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 when PSM initializes, we create the sqlite-backed certificate and +// key databases. + +function run_test() { + let profileDir = do_get_profile(); + let certificateDBFile = profileDir.clone(); + certificateDBFile.append("cert9.db"); + ok(!certificateDBFile.exists(), "cert9.db should not exist beforehand"); + let keyDBFile = profileDir.clone(); + keyDBFile.append("key4.db"); + ok(!keyDBFile.exists(), "key4.db should not exist beforehand"); + // This should start PSM. + Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + ok(certificateDBFile.exists(), "cert9.db should exist in the profile"); + ok(keyDBFile.exists(), "key4.db should exist in the profile"); +} diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials.js b/security/manager/ssl/tests/unit/test_delegated_credentials.js new file mode 100644 index 0000000000..a1623ddcb2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials.js @@ -0,0 +1,91 @@ +/* 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 handling of certificates marked as permitting delegated credentials + +function shouldBeDelegatedCredential(aTransportSecurityInfo) { + Assert.ok( + aTransportSecurityInfo.isDelegatedCredential, + "This host should have used a delegated credential" + ); +} + +function shouldNotBeDelegatedCredential(aTransportSecurityInfo) { + Assert.ok( + !aTransportSecurityInfo.isDelegatedCredential, + "This host should not have used a delegated credential" + ); +} + +do_get_profile(); + +add_tls_server_setup( + "DelegatedCredentialsServer", + "test_delegated_credentials" +); + +// Test: +// Server certificate supports DC +// Server DC support enabled +// Client DC support disabled +// Result: Successful connection without DC +add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref( + "security.tls.enable_delegated_credentials", + false + ); + run_next_test(); +}); +add_connection_test( + "delegated-enabled.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeDelegatedCredential +); + +// Test: +// Server certificate does not support DC +// Server DC support enabled +// Client DC support enabled +// Result: SSL_ERROR_DC_INVALID_KEY_USAGE from client when +// checking DC against EE cert, no DC in aTransportSecurityInfo. +add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref("security.tls.enable_delegated_credentials", true); + run_next_test(); +}); +add_connection_test( + "standard-enabled.example.com", + SSL_ERROR_DC_INVALID_KEY_USAGE, + null, + // We'll never |mHaveCipherSuiteAndProtocol|, + // and therefore can't check IsDelegatedCredential + null +); + +// Test: +// Server certificate supports DC +// Server DC support disabled +// Client DC support enabled +// Result: Successful connection without DC +add_connection_test( + "delegated-disabled.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeDelegatedCredential +); + +// Test: +// Server certificate supports DC +// Server DC support enabled +// Client DC support enabled +// Result: Successful connection with DC +add_connection_test( + "delegated-enabled.example.com", + PRErrorCodeSuccess, + null, + shouldBeDelegatedCredential +); diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key new file mode 100644 index 0000000000..a926a54efb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIZFAPVcQvxWiZYGM +1C7W/t8JrdkteLGOeh6f65VSRwKhRANCAARPv7u7YeD4+bGmClmshwTi7AULQj48 +9y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQejBOqgSqbA +-----END EC PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec new file mode 100644 index 0000000000..03c3ce198f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec @@ -0,0 +1 @@ +secp256r1 diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem new file mode 100644 index 0000000000..332793b89e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCATCgAwIBAgIUNeh3F5ZVYezEJKXRBQTRiDY/isMwDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhZGVsZWdhdGVkLWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRl +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBUxEzARBgNVBAMM +CmRlZmF1bHQtZWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARPv7u7YeD4+bGm +ClmshwTi7AULQj489y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQej +BOqgSqbAo0AwPjATBgNVHSUEDDAKBggrBgEFBQcDATAnBgNVHREEIDAeghxzdGFu +ZGFyZC1lbmFibGVkLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBqh2DB +lbCuX6H9CPsdgDLX3z4gS5ab/1g7J4az29EQuFgb2z6gHOOuMDkLgDPpq3Vz0mrk +emsoXToPdHsRZ4S57KeELRLT42bdyYkDR8yWTm588UhDNo3n492RD+dYHILmJdj0 +d9MWlMnl/jpXo8/a36ZJ2QgjSUyzwE/Nyxd8864Pk5ipUwyabSFjiEGcHsrfsSIQ +fqkBXG0UudjjWEPInSQIBNIwCZL3HDwoeV2SO3gjxDwyume2S0K6GGXWs8a+mLBn +Kks7nmQ8pEipNyHDt9TUS+Ywj6txK4cOp4WTh86q0h9mLWqqvg/DdTHLyFyzPWPa +LZl7VR1aKXr9IzE0 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec new file mode 100644 index 0000000000..5ebe9b5ba7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:delegated-credential-intermediate +subjectKey:secp256r1 +subject:default-ee +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:standard-enabled.example.com diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem new file mode 100644 index 0000000000..ece3ae8834 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICiTCCAXGgAwIBAgIUV0N3VFQpvGVw2qP62b/L1yTchOIwDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhZGVsZWdhdGVkLWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRl +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBcxFTATBgNVBAMM +DGRlbGVnYXRlZC1lZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/u7th4Pj5 +saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3st +B6ME6qBKpsCjfzB9MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDBI +BgNVHREEQTA/gh1kZWxlZ2F0ZWQtZW5hYmxlZC5leGFtcGxlLmNvbYIeZGVsZWdh +dGVkLWRpc2FibGVkLmV4YW1wbGUuY29tMA8GCSsGAQQBgtpLLAQCBQAwDQYJKoZI +hvcNAQELBQADggEBAIxXv51QQR9JwM+Q7kQnRpK41Xe4WCDSwoyD+eOgbKznTJvz +v3YDZKkO9cdQDGdd2GgMA/6/a0vc1wK1IO5eI2bAisIbublJ8xkuTeLyhdisGxMb +k0XLlcQ/KnXid3R6dccHguQPpdtDrf2kgKE8Wy9Gvg9LF3A6hIx5BtruInflvgp6 +jtUGlKrftPMhRIEP5FWy5KOJE8VW+ja4zBH6P36kDaNeWK3SrssyNAZmoDrxslJa +LDls1xZ4+ElGUjoywmEG0Fbbrv4mUiwCQ+4flHoopBGqs+3J0gY8SJndTZniSjSh +i7ivXTPlrU0Sm8jt1e/RYlnA6IyvQp8YbR+zX34= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec new file mode 100644 index 0000000000..e90fa3b646 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec @@ -0,0 +1,7 @@ +issuer:delegated-credential-intermediate +subject:delegated-ee +subjectKey:secp256r1 +extension:extKeyUsage:serverAuth +extension:keyUsage:digitalSignature,keyEncipherment +extension:subjectAlternativeName:delegated-enabled.example.com,delegated-disabled.example.com +extension:delegationUsage: diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key new file mode 100644 index 0000000000..1c1af40bda --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDADXHobENn6/oN7ZK2S +8i9c7QeJGGU4ZptcbYcs7D2SYSKzk3crV2Av8xNl7+E5MkahZANiAAShaHJDNitc +exiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05qnAwLCcjWOa3oMgbl +uoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyDdKpuqc4= +-----END EC PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec new file mode 100644 index 0000000000..11f041d996 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec @@ -0,0 +1 @@ +secp384r1 diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build b/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build new file mode 100644 index 0000000000..e6722917e1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'test-ca.pem', +# 'test-int.pem', +# 'delegated-ee.pem', +# 'default-ee.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'delegated.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem new file mode 100644 index 0000000000..52e77a4498 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUXeumyyPJUORUNVVSf/2pTjEDxS4wDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZGVsZWdhdGVkLWNyZWRlbnRpYWwtY2EwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowIjEgMB4GA1UEAwwXZGVsZWdhdGVk +LWNyZWRlbnRpYWwtY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCvQNfsGAcHMiKfrbxHpJVnmxTAzWBSqJnp +V924Ofy80m03jI+99SEi9blzfHhJxRFe3cZYK3Dh4lhR3/RMHfZsepsAMzplS+to +m1T7D9zwFpVuqfAOnlkPPneVf3hTvgmkQqiLWZUb/pWZ2fGWAKtDXPM5HHf6gBKY ++8VbTUpPHhwDH1MRauoK18QysMlBm90OwM6mnzCsJ6xwTDQkFAt4vQ+jS3AglhPd +D5xqKbHwHi//h1EeV6u9mIJuX8HIZl5AM0Be4XaYb9gZFriflIjWxqmgh1alhKUM +H2gTyrzG8NmD+J4CCLEygYdaFlj3QfBypdW/QpdOaV77u7dhmxzg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec new file mode 100644 index 0000000000..91227f5da0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:delegated-credential-ca +subject:delegated-credential-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem new file mode 100644 index 0000000000..2425254722 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUAcAYRaw4AL7AX+7V+/SNR/7bZ0QwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZGVsZWdhdGVkLWNyZWRlbnRpYWwtY2EwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhZGVsZWdhdGVk +LWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/ +MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAgnn4xLqeQUJDkL2Vo5Xl +WYgCcmCa0n01OwenTjTtWyIkbXCLDvyA5F7E79pW+8RevUJkM/JUzo/ZR6qr2cnR +H7lg4EEjVUC8zI60jvFeFZAelCoz6W4C/A4Y9pqLkDgJMWfdOstAe2cescqQPwsY +AK0OtxhdB8x371vwL0hBDL1u6CV+s2TGBc5Pj9lTY6UEDSAXIww2DzipVzalctg9 +oiihe6KDJuN0vTTt46ImksVo05EWT+uq2mJvVMgpcOXShJCmjl/zSM0KVT2VFc6v +xyeWCmmyaem/m9Do7Gnq+DVPII153dWmy1Xr0vX31PhroRETFnY5eyyc8umDD4Qu +uA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec new file mode 100644 index 0000000000..64cc4e5693 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec @@ -0,0 +1,4 @@ +issuer:delegated-credential-ca +subject:delegated-credential-intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_der.js b/security/manager/ssl/tests/unit/test_der.js new file mode 100644 index 0000000000..bae18e98e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_der.js @@ -0,0 +1,380 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests DER.jsm functionality. + +// Until DER.jsm is actually used in production code, this is where we have to +// import it from. +var { DER } = ChromeUtils.import("resource://gre/modules/psm/DER.jsm"); + +function run_simple_tests() { + throws( + () => new DER.DERDecoder("this is not an array"), + /invalid input/, + "should throw given non-array input" + ); + throws( + () => new DER.DERDecoder([0, "invalid input", 1]), + /invalid input/, + "should throw given non-byte data (string case)" + ); + throws( + () => new DER.DERDecoder([31, 1, {}]), + /invalid input/, + "should throw given non-byte data (object case)" + ); + throws( + () => new DER.DERDecoder([0.1, 3, 1]), + /invalid input/, + "should throw given non-byte data (non-integer case)" + ); + throws( + () => new DER.DERDecoder([1, 3, -1]), + /invalid input/, + "should throw given non-byte data (negative integer case)" + ); + throws( + () => new DER.DERDecoder([1, 300, 79]), + /invalid input/, + "should throw given non-byte data (large integer case)" + ); + + let testReadByte = new DER.DERDecoder([0x0a, 0x0b]); + equal(testReadByte.readByte(), 0x0a, "should read 0x0a"); + equal(testReadByte.readByte(), 0x0b, "should read 0x0b"); + throws( + () => testReadByte.readByte(), + /data truncated/, + "reading more data than is available should fail" + ); + + let testReadBytes = new DER.DERDecoder([0x0c, 0x0d, 0x0e]); + deepEqual( + testReadBytes.readBytes(3), + [0x0c, 0x0d, 0x0e], + "should read correct sequence of bytes" + ); + + let testReadNegativeBytes = new DER.DERDecoder([0xff, 0xaf]); + throws( + () => testReadNegativeBytes.readBytes(-4), + /invalid length/, + "reading a negative number of bytes should fail" + ); + + let testReadZeroBytes = new DER.DERDecoder([]); + equal( + testReadZeroBytes.readBytes(0).length, + 0, + "reading zero bytes should result in a zero-length array" + ); + + let testReadTooManyBytes = new DER.DERDecoder([0xab, 0xcd, 0xef]); + throws( + () => testReadTooManyBytes.readBytes(4), + /data truncated/, + "reading too many bytes should fail" + ); + + let testSEQUENCE = new DER.DERDecoder([0x30, 0x01, 0x01]); + let content = testSEQUENCE.readTagAndGetContents(DER.SEQUENCE); + equal(content.length, 1, "content should have length 1"); + equal(content[0], 1, "value of content should be [1]"); + ok(testSEQUENCE.atEnd(), "testSEQUENCE should be at the end of its input"); + testSEQUENCE.assertAtEnd(); + + // The length purports to be 4 bytes, but there are only 2 available. + let truncatedSEQUENCE = new DER.DERDecoder([0x30, 0x04, 0x00, 0x00]); + throws( + () => truncatedSEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /data truncated/, + "should get 'data truncated' error" + ); + + // With 2 bytes of content, there is 1 remaining after reading the content. + let extraDataSEQUENCE = new DER.DERDecoder([0x30, 0x02, 0xab, 0xcd, 0xef]); + content = extraDataSEQUENCE.readTagAndGetContents(DER.SEQUENCE); + equal(content.length, 2, "content should have length 2"); + deepEqual(content, [0xab, 0xcd], "value of content should be [0xab, 0xcd]"); + ok( + !extraDataSEQUENCE.atEnd(), + "extraDataSEQUENCE should not be at the end of its input" + ); + throws( + () => extraDataSEQUENCE.assertAtEnd(), + /extra data/, + "should get 'extra data' error" + ); + + // The length of 0x81 0x01 is invalid because it could be encoded as just + // 0x01, which is shorter. + let invalidLengthSEQUENCE1 = new DER.DERDecoder([0x30, 0x81, 0x01, 0x00]); + throws( + () => invalidLengthSEQUENCE1.readTagAndGetContents(DER.SEQUENCE), + /invalid length/, + "should get 'invalid length' error" + ); + + // Similarly, 0x82 0x00 0x01 could be encoded as just 0x01, which is shorter. + let invalidLengthSEQUENCE2 = new DER.DERDecoder([ + 0x30, + 0x82, + 0x00, + 0x01, + 0x00, + ]); + throws( + () => invalidLengthSEQUENCE2.readTagAndGetContents(DER.SEQUENCE), + /invalid length/, + "should get 'invalid length' error" + ); + + // Lengths requiring 4 bytes to encode are not supported. + let unsupportedLengthSEQUENCE = new DER.DERDecoder([ + 0x30, + 0x83, + 0x01, + 0x01, + 0x01, + ]); + throws( + () => unsupportedLengthSEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /unsupported length/, + "should get 'unsupported length' error" + ); + + // Indefinite lengths are not supported (and aren't DER anyway). + let unsupportedASN1SEQUENCE = new DER.DERDecoder([ + 0x30, + 0x80, + 0x01, + 0x00, + 0x00, + ]); + throws( + () => unsupportedASN1SEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /unsupported asn.1/, + "should get 'unsupported asn.1' error" + ); + + let unexpectedTag = new DER.DERDecoder([0x31, 0x01, 0x00]); + throws( + () => unexpectedTag.readTagAndGetContents(DER.SEQUENCE), + /unexpected tag/, + "should get 'unexpected tag' error" + ); + + let readTLVTestcase = new DER.DERDecoder([0x02, 0x03, 0x45, 0x67, 0x89]); + let bytes = readTLVTestcase.readTLV(); + deepEqual( + bytes, + [0x02, 0x03, 0x45, 0x67, 0x89], + "bytes read with readTLV should be equal to expected value" + ); + + let peekTagTestcase = new DER.DERDecoder([0x30, 0x01, 0x00]); + ok( + peekTagTestcase.peekTag(DER.SEQUENCE), + "peekTag should return true for peeking with a SEQUENCE at a SEQUENCE" + ); + ok( + !peekTagTestcase.peekTag(DER.SET), + "peekTag should return false for peeking with a SET at a SEQUENCE" + ); + peekTagTestcase.readTLV(); + ok( + !peekTagTestcase.peekTag(DER.SEQUENCE), + "peekTag should return false for peeking at a DER with no more data" + ); + + let tlvChoiceTestcase = new DER.DERDecoder([0x31, 0x02, 0xaa, 0xbb]); + let tlvChoiceContents = tlvChoiceTestcase.readTLVChoice([DER.NULL, DER.SET]); + deepEqual( + tlvChoiceContents, + [0x31, 0x02, 0xaa, 0xbb], + "readTLVChoice should return expected bytes" + ); + + let tlvChoiceNoMatchTestcase = new DER.DERDecoder([0x30, 0x01, 0xff]); + throws( + () => tlvChoiceNoMatchTestcase.readTLVChoice([DER.NULL, DER.SET]), + /unexpected tag/, + "readTLVChoice should throw if no matching tag is found" + ); +} + +function run_bit_string_tests() { + let bitstringDER = new DER.DERDecoder([0x03, 0x04, 0x03, 0x01, 0x02, 0xf8]); + let bitstring = bitstringDER.readBIT_STRING(); + equal(bitstring.unusedBits, 3, "BIT STRING should have 3 unused bits"); + deepEqual( + bitstring.contents, + [0x01, 0x02, 0xf8], + "BIT STRING should have expected contents" + ); + + let bitstringTooManyUnusedBits = new DER.DERDecoder([0x03, 0x02, 0x08, 0x00]); + throws( + () => bitstringTooManyUnusedBits.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with too many unused bits should throw" + ); + + // A BIT STRING must have the unused bits byte, and so its length must be at + // least one. + let bitstringMissingUnusedBits = new DER.DERDecoder([0x03, 0x00]); + throws( + () => bitstringMissingUnusedBits.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with missing unused bits (and no contents) should throw" + ); + + // The minimal BIT STRING is 03 01 00 (zero bits of padding and zero bytes of + // content). + let minimalBitstringDER = new DER.DERDecoder([0x03, 0x01, 0x00]); + let minimalBitstring = minimalBitstringDER.readBIT_STRING(); + equal( + minimalBitstring.unusedBits, + 0, + "minimal BIT STRING should have 0 unused bits" + ); + equal( + minimalBitstring.contents.length, + 0, + "minimal BIT STRING should have empty contents" + ); + + // However, a BIT STRING with zero bytes of content can't have any padding, + // because that makes no sense. + let noContentsPaddedBitstringDER = new DER.DERDecoder([0x03, 0x01, 0x03]); + throws( + () => noContentsPaddedBitstringDER.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with no contents with non-zero padding should throw" + ); +} + +function run_compound_tests() { + let derBytes = [ + 0x30, + 0x1a, // SEQUENCE + 0x02, + 0x02, + 0x77, + 0xff, // INTEGER + 0x06, + 0x03, + 0x2b, + 0x01, + 0x01, // OBJECT IDENTIFIER + 0x30, + 0x07, // SEQUENCE + 0x05, + 0x00, // NULL + 0x02, + 0x03, + 0x45, + 0x46, + 0x47, // INTEGER + 0x30, + 0x06, // SEQUENCE + 0x02, + 0x02, + 0x00, + 0xff, // INTEGER + 0x05, + 0x00, + ]; // NULL + let der = new DER.DERDecoder(derBytes); + let contents = new DER.DERDecoder(der.readTagAndGetContents(DER.SEQUENCE)); + let firstINTEGER = contents.readTagAndGetContents(DER.INTEGER); + deepEqual( + firstINTEGER, + [0x77, 0xff], + "first INTEGER should have expected value" + ); + let oid = contents.readTagAndGetContents(DER.OBJECT_IDENTIFIER); + deepEqual( + oid, + [0x2b, 0x01, 0x01], + "OBJECT IDENTIFIER should have expected value" + ); + + let firstNested = new DER.DERDecoder( + contents.readTagAndGetContents(DER.SEQUENCE) + ); + let firstNestedNULL = firstNested.readTagAndGetContents(DER.NULL); + equal( + firstNestedNULL.length, + 0, + "first nested NULL should have expected value (empty array)" + ); + let firstNestedINTEGER = firstNested.readTagAndGetContents(DER.INTEGER); + deepEqual( + firstNestedINTEGER, + [0x45, 0x46, 0x47], + "first nested INTEGER should have expected value" + ); + firstNested.assertAtEnd(); + + let secondNested = new DER.DERDecoder( + contents.readTagAndGetContents(DER.SEQUENCE) + ); + let secondNestedINTEGER = secondNested.readTagAndGetContents(DER.INTEGER); + deepEqual( + secondNestedINTEGER, + [0x00, 0xff], + "second nested INTEGER should have expected value" + ); + let secondNestedNULL = secondNested.readTagAndGetContents(DER.NULL); + equal( + secondNestedNULL.length, + 0, + "second nested NULL should have expected value (empty array)" + ); + secondNested.assertAtEnd(); + + contents.assertAtEnd(); + der.assertAtEnd(); + + let invalidDERBytes = [ + 0x30, + 0x06, // SEQUENCE + 0x30, + 0x02, // SEQUENCE + 0x02, + 0x01, // INTEGER (missing data) + 0x05, + 0x00, // NULL + 0x00, + 0x00, + ]; // (extra data) + let invalidDER = new DER.DERDecoder(invalidDERBytes); + let invalidContents = new DER.DERDecoder( + invalidDER.readTagAndGetContents(DER.SEQUENCE) + ); + let invalidContentsContents = new DER.DERDecoder( + invalidContents.readTagAndGetContents(DER.SEQUENCE) + ); + throws( + () => invalidContentsContents.readTagAndGetContents(DER.INTEGER), + /data truncated/, + "should throw due to missing data" + ); + let nestedNULL = invalidContents.readTagAndGetContents(DER.NULL); + equal(nestedNULL.length, 0, "nested NULL should have expected value"); + invalidContents.assertAtEnd(); + throws( + () => invalidDER.assertAtEnd(), + /extra data/, + "should throw due to extra data" + ); +} + +function run_test() { + run_simple_tests(); + run_bit_string_tests(); + run_compound_tests(); +} diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello.js b/security/manager/ssl/tests/unit/test_encrypted_client_hello.js new file mode 100644 index 0000000000..69d3df8645 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello.js @@ -0,0 +1,93 @@ +/* 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 handling of Encrypted Client Hello. These ECHConfigs +// can be regenerated by running EncryptedClientHelloServer +// and dumping the output of SSL_EncodeEchConfig. They do not +// expire. An update here is only needed if the host or ECH +// ciphersuite configuration changes, or if the keypair in +// EncryptedClientHelloServer.cpp is modified. + +// Public name: ech-public.example.com +const ECH_CONFIG_FIXED = + "AEr+CABGABZlY2gtcHVibGljLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQADADIAAA=="; + +// Public name: ech-public.example.com, Unsupported AEAD to prompt retry_configs from a trusted host. +const ECH_CONFIG_TRUSTED_RETRY = + "AEr+CABGABZlY2gtcHVibGljLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQABADIAAA=="; + +// Public name: selfsigned.example.com. Unsupported AEAD to prompt retry_configs from an untrusted host. +const ECH_CONFIG_UNTRUSTED_RETRY = + "AEr+CABGABZzZWxmc2lnbmVkLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQABADIAAA=="; + +function shouldBeAcceptedEch(aTransportSecurityInfo) { + Assert.ok( + aTransportSecurityInfo.isAcceptedEch, + "This host should have accepted ECH" + ); +} + +function shouldBeRejectedEch(aTransportSecurityInfo) { + Assert.ok( + !aTransportSecurityInfo.isAcceptedEch, + "This host should have rejected ECH" + ); +} + +do_get_profile(); + +add_tls_server_setup( + "EncryptedClientHelloServer", + "test_encrypted_client_hello" +); + +// Connect directly without ECH first +add_connection_test( + "ech-public.example.com", + PRErrorCodeSuccess, + null, + shouldBeRejectedEch +); + +// Connect with ECH +add_connection_test( + "ech-private.example.com", + PRErrorCodeSuccess, + null, + shouldBeAcceptedEch, + null, + null, + ECH_CONFIG_FIXED +); + +// Trigger retry_configs by setting an ECHConfig with a different. +// AEAD than the server supports. +add_connection_test( + "ech-private.example.com", + SSL_ERROR_ECH_RETRY_WITH_ECH, + null, + null, + null, + null, + ECH_CONFIG_TRUSTED_RETRY +); + +// Trigger retry_configs, but from a host that is untrusted +// (due to a self-signed certificate for the public name). +// Retry_configs must not be used or reported as available. +add_connection_test( + "ech-private.example.com", + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT, + null, + null, + null, + null, + ECH_CONFIG_UNTRUSTED_RETRY +); + +// A client-only (retry_without_ech) test is located in +// test_encrypted_client_hello_client_only.js We can't easily restart +// a different server (one without ECHConfigs) here, so put that +// test in a different file that launches a non-ECH server. diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem new file mode 100644 index 0000000000..c71005fc19 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUP5hH78XA0upQ7cmqNASOW6WqkoUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBgxFjAUBgNVBAMMDWVjaC1wdWJsaWMtZWUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJTAjMCEG +A1UdEQQaMBiCFmVjaC1wdWJsaWMuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAIgqt32ojY+McIFUq57FIpI0FsDnY/L+GsmtUziUjM0rfNTuDP0r+CF/1emA +sTukf+YIiohoGjfRMebYdeWtpUjdG9O/Z1ygmGQNms6LP+xy6dPUM4G0sBpkfNdb +u74ymuru0kMopYpVXuDsaYOPTNj2W6a7gLpn3llk8K4SVFEogUTlzzOBtYobf8L5 +9tSDpsMrTPINVbyi8SQHONMrsuqMfMDSTCkQnZJDcbRW56T2+PgrWJnQ78NDM0GB +/KLRW6tIyyTco1IBrFC9+0j5jyHh4+3em0bT7sdcwidjZKipWsvcKK9DuycSSM6O +nL8vxqnekennEVLV7zm6rjB/wns= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec new file mode 100644 index 0000000000..d5c332ceec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ech-ca +subject:ech-public-ee +extension:subjectAlternativeName:ech-public.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build b/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build new file mode 100644 index 0000000000..a3755e779b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'default-ee.pem', +# 'private-ee.pem', +# 'selfsigned.pem', +# 'test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'public-ee.key', +# 'private-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem new file mode 100644 index 0000000000..258b0fc043 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUSXmHaEjlH8Iry6lZ5kbx/TBwgI8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBkxFzAVBgNVBAMMDmVjaC1wcml2YXRlLWVlMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyYwJDAi +BgNVHREEGzAZghdlY2gtcHJpdmF0ZS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF +AAOCAQEAI63cvfxAvxMKJBDTIle1hHjW9wf1FgRyus37hqdLatN3fa4o2vNRLfX7 +MITXlLcmqehrBj/Wi7thMOC77HGE3wGvUNog2Avk4exps/bR1ksTraY5cxM386he +FG2QJ8im2VavNyqwmu2IcbPpZk5MKYolptmRFvz/6XGtLQsRjdtABKoUBB1tXlT2 +go6VULbEQn62fAdBvb/1CO6+jDWIpPzbpFSdWTBSpY1IfhAjsEP6W5kkDaKYwf8G +IJslTTh+4v8Fq06ySdV1T8IYu29YuCye+sbWyWfcfPQqssaQzWpqAyBOO2kV3r3B +XsaWXLsuXMnzBDJ5PM6Wsp8dLFXFzg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec new file mode 100644 index 0000000000..c152462f0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ech-ca +subject:ech-private-ee +extension:subjectAlternativeName:ech-private.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem new file mode 100644 index 0000000000..f7f7c6f2df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUKyuH4MWSNUsG95g0ExZZWo1i0tkwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbU2VsZi1zaWduZWQgVGVzdCBFbmQtZW50aXR5MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCYxJDAiBgNVBAMMG1NlbGYt +c2lnbmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwIQYDVR0RBBowGIIWc2Vs +ZnNpZ25lZC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAqCxzMj+ECM64 +aG9XqCBHkrR45i6UO0jZkGGBRhUJunfSpK8g5jCuRH0wv4SPZG3tl7VgOtFHFhm5 +1SkEOstkShslHCWwEXoMuO9uvRGzjXl3bxES70ERHmcncp0yWXDT+QDyXM489X1M +UtEFzWLMv22BX6J6xrvyhJK3zodHXtBSphG2NUEARPsgxb3sMiQA9jTacsQHC9yZ +dmknp5zhYgCHntO8jFVc04O21wwMlzMB7IR/WFHs67opimHlQlBIWvRDOSsVvxdY +y8ybGmymQ8g3hxHlQ5fc+oX64SDuHQa6kw2ZWQEz3e4It+VU5Y93QhCLgKqijfBr +HRt0AadMpg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec new file mode 100644 index 0000000000..438a08eba2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec @@ -0,0 +1,3 @@ +issuer:Self-signed Test End-entity +subject:Self-signed Test End-entity +extension:subjectAlternativeName:selfsigned.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem new file mode 100644 index 0000000000..00b43c3d66 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUYc9/sZ6jdK4/ErAKn9/aEFPSgxowDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmVjaC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFHcA3r+hl4tWZnO +tG1AsddSxeqxhFsZTNTwzLfnYRlFgxytmgE+r3pp5Aost6ZLhcagQT2uIklEBOnw +se2evClYtC4yVd/FOLaGdd9YCGCggYpoNgNhNMHXI5qS28kslZLnbcD4HScYan66 +KcxGDSBRPggdOkOjhBHax3nni1+kWbzNIFQ2SWR0V/C2pxZJXDGlkE/sggD0nqG+ +iQWJytyJQJsKskNdUOh4R0sANDMTYEQfMrDVuNS6poqRj1C98JyP8qP+jsZZ33WQ +brR7zbYDhBHdIi4MLZMgGCN+0VZ5PD26nT+9XekV8A/7+U29PxdviW6oZqpMT+sD +ne3P1JM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec new file mode 100644 index 0000000000..1735a15075 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ech-ca +subject:ech-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js b/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js new file mode 100644 index 0000000000..eb6cd40e26 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js @@ -0,0 +1,33 @@ +/* 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"; + +// Public Name = delegated-enabled.example.com +const ECH_CONFIG_FIXED = + "AFH+CABNAB1kZWxlZ2F0ZWQtZW5hYmxlZC5leGFtcGxlLmNvbQAgigdWOUn6xiMpNu1vNsT6c1kw7N6u9nNOMUrqw1pW/QoAIAAEAAEAAwAyAAA="; + +do_get_profile(); + +// An arbitrary, non-ECH server. +add_tls_server_setup( + "DelegatedCredentialsServer", + "test_delegated_credentials" +); + +add_test(function() { + clearSessionCache(); + run_next_test(); +}); + +// Connect, sending ECH. The server is not configured for it, +// but *is* authoritative for the public name. +add_connection_test( + "delegated-disabled.example.com", + SSL_ERROR_ECH_RETRY_WITHOUT_ECH, + null, + null, + null, + null, + ECH_CONFIG_FIXED +); diff --git a/security/manager/ssl/tests/unit/test_enterprise_roots.js b/security/manager/ssl/tests/unit/test_enterprise_roots.js new file mode 100644 index 0000000000..24537ccc41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_enterprise_roots.js @@ -0,0 +1,82 @@ +// -*- 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 enterprise root certificate support. When configured to do so, the +// platform will attempt to find and import enterprise root certificates. This +// feature is specific to Windows. + +do_get_profile(); // must be called before getting nsIX509CertDB + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +async function check_no_enterprise_roots_imported( + nssComponent, + certDB, + dbKey = undefined +) { + let enterpriseRoots = nssComponent.getEnterpriseRoots(); + notEqual(enterpriseRoots, null, "enterprise roots list should not be null"); + equal( + enterpriseRoots.length, + 0, + "should not have imported any enterprise roots" + ); + if (dbKey) { + let cert = certDB.findCertByDBKey(dbKey); + // If the garbage-collector hasn't run, there may be reachable copies of + // imported enterprise root certificates. If so, they shouldn't be trusted + // to issue TLS server auth certificates. + if (cert) { + await asyncTestCertificateUsages(certDB, cert, []); + } + } +} + +async function check_some_enterprise_roots_imported(nssComponent, certDB) { + let enterpriseRoots = nssComponent.getEnterpriseRoots(); + notEqual(enterpriseRoots, null, "enterprise roots list should not be null"); + notEqual( + enterpriseRoots.length, + 0, + "should have imported some enterprise roots" + ); + let foundNonBuiltIn = false; + let savedDBKey = null; + for (let certDer of enterpriseRoots) { + let cert = certDB.constructX509(certDer); + notEqual(cert, null, "should be able to decode cert from DER"); + if (!cert.isBuiltInRoot && !savedDBKey) { + foundNonBuiltIn = true; + savedDBKey = cert.dbKey; + info("saving dbKey from " + cert.commonName); + await asyncTestCertificateUsages(certDB, cert, [certificateUsageSSLCA]); + break; + } + } + ok(foundNonBuiltIn, "should have found non-built-in root"); + return savedDBKey; +} + +add_task(async function run_test() { + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + nssComponent.getEnterpriseRoots(); // blocks until roots are loaded + Services.prefs.setBoolPref("security.enterprise_roots.enabled", false); + await check_no_enterprise_roots_imported(nssComponent, certDB); + Services.prefs.setBoolPref("security.enterprise_roots.enabled", true); + await TestUtils.topicObserved("psm:enterprise-certs-imported"); + let savedDBKey = await check_some_enterprise_roots_imported( + nssComponent, + certDB + ); + Services.prefs.setBoolPref("security.enterprise_roots.enabled", false); + await check_no_enterprise_roots_imported(nssComponent, certDB, savedDBKey); +}); diff --git a/security/manager/ssl/tests/unit/test_ev_certs.js b/security/manager/ssl/tests/unit/test_ev_certs.js new file mode 100644 index 0000000000..937e4509f3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs.js @@ -0,0 +1,437 @@ +// -*- 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, reject) => { + let ocspResponder = + expectedOCSPRequestPaths.length > 0 + ? 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 = gEVExpected + ? [`${testcase}-int`, `${testcase}-ee`] + : [`${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, reject) => { + 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 ensureOneCRLSkipsOCSPForIntermediates(testcase) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + return asyncTestEV(cert, PRErrorCodeSuccess, gEVExpected, [`${testcase}-ee`]); +} + +function verifyWithDifferentOCSPResponseTypes(testcase, responses, expectEV) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + let expectedOCSPRequestPaths = gEVExpected + ? [`${testcase}-int`, `${testcase}-ee`] + : [`${testcase}-ee`]; + let ocspResponseTypes = gEVExpected ? responses : responses.slice(1); + return asyncTestEV( + cert, + PRErrorCodeSuccess, + gEVExpected && expectEV, + expectedOCSPRequestPaths, + ocspResponseTypes + ); +} + +function ensureVerifiesAsEVWithOldIntermediateOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["longvalidityalmostold", "good"], + true + ); +} + +function ensureVerifiesAsDVWithOldEndEntityOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["good", "longvalidityalmostold"], + false + ); +} + +function ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["good", "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 uses the first EV policy it encounters in the end-entity as + // the required one, this successfully verifies as EV. + await ensureVerifiesAsEV("cabforum-and-test-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", + gEVExpected ? ["no-ocsp-ee-path-int"] : [] + ); + await ensureVerifiesAsDV("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"); + // 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 uses the first EV policy it encounters in the end-entity as + // the required one, this fails to verify as EV. + await ensureVerifiesAsDV("test-and-cabforum-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"); +}); + +// Under certain conditions, OneCRL allows us to skip OCSP requests for +// intermediates. +add_task(async function oneCRLTests() { + clearOCSPCache(); + + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the recent past + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 1 + ); + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 1 + ); + + await ensureOneCRLSkipsOCSPForIntermediates("anyPolicy-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("no-ocsp-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("test-oid-path"); + + clearOCSPCache(); + // disable OneCRL OCSP Skipping (no staleness allowed) + Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds", 0); + await ensureVerifiesAsEV("anyPolicy-int-path"); + // Because the intermediate in this case is missing an OCSP URI, it will not + // validate as EV, but it should fall back to DV. + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the more distant past + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 108080 + ); + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 108080 + ); + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // test the OCSP behavior when services.settings.security.onecrl.checked is in the + // distant past and blacklist-background-update-timer is recent + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the recent past + // (services.settings.security.onecrl.checked defaults to 0) + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 1 + ); + + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // test the OCSP behavior when services.settings.security.onecrl.checked is recent + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // now set services.settings.security.onecrl.checked to a recent value + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 1 + ); + await ensureOneCRLSkipsOCSPForIntermediates("anyPolicy-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("no-ocsp-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("test-oid-path"); + + Services.prefs.clearUserPref("security.onecrl.maximum_staleness_in_seconds"); + Services.prefs.clearUserPref("services.settings.security.onecrl.checked"); + Services.prefs.clearUserPref( + "app.update.lastUpdateTime.blocklist-background-update-timer" + ); +}); + +// 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(); + + await ensureVerifiesAsEVWithOldIntermediateOCSPResponse("anyPolicy-int-path"); + await ensureVerifiesAsEVWithOldIntermediateOCSPResponse("test-oid-path"); + + clearOCSPCache(); + await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("anyPolicy-int-path"); + await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("test-oid-path"); + + clearOCSPCache(); + await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse( + "anyPolicy-int-path" + ); + await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse("test-oid-path"); +}); diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem new file mode 100644 index 0000000000..7326ef6d4e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUQx+5x/tjsPB8QKeRGMqa5Xa/prYwDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVYW55UG9saWN5LWVlLXBhdGgtaW50MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGFueVBvbGljeS1l +ZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo4GFMIGCME0GCCsGAQUFBwEBBEEwPzA9BggrBgEFBQcw +AYYxaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2FueVBvbGljeS1lZS1wYXRo +LWVlLzARBgNVHSAECjAIMAYGBFUdIAAwHgYDVR0RBBcwFYITZXYtdGVzdC5leGFt +cGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAM5dSETXj42Kai/sDKzZOaltmATbf +RDm9U8Pa1luk+m1Y2wgPDQfjcklPIkbyxsAwhdy1OCAUSVjWttAKs5w23TroT5Dq +tJAt823UD2xjwA3x1tTTmielwhc5cRL9uddrKAZ+EnRNLsI4wlTvjX1OBS61BgA6 +V/4//SJgS72Yj1Ebl9D5mA6iVHyUZblAwhsrogTwzWKMPzcAVgGp7YQK4b1yV4vc +zmcx9HrlsJuwpNwPQvysOhtOcbX1CbCdq9qzj6cCdIOZ3H5qzrr9swoZreVUsbic +xeHxhXGcp4+Bk+djBqlKvSGuw9FSlOSgpaB/K3ceDRjewje2rzTgAzSg7Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..a9175c32ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:anyPolicy-ee-path-int +subject:anyPolicy-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-ee-path-ee/ +extension:certificatePolicies:any +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem new file mode 100644 index 0000000000..faaea5d176 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRDCCAiygAwIBAgIUR7Qq6/A9VAD2EfTAFB5di93IJx8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCAxHjAcBgNVBAMMFWFueVBvbGljeS1lZS1wYXRoLWludDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOBgDB+MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGME4GCCsGAQUFBwEBBEIw +QDA+BggrBgEFBQcwAYYyaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2FueVBv +bGljeS1lZS1wYXRoLWludC8wEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEB +CwUAA4IBAQCCOVv8KxGwhAsLedhqkwyLkg7MnmFKYdGJo5LHXU5eszyRTHNy5L5/ +nvy6uCwA4h/FBL/XZb+VYIvbMpL8i7Oduf8kvWGWkfNPfUNgXK2ZdX3y1uBQda89 +kX2FTuP2ajdjZHkHPuA2wzpce8pDzlv0ULvIV4anOGgxuYqxKM1ihddYs/6LT/vs +cFjLJDLIvqv7heucPJ3ungJY4IEaYRv3zEXwrS3FY/zakfpEGLqTNlLOppp82LPB +7McNBxcxXrFdSfWqbLTl8U93Xe48utWl/qmUA/0+QBB7MvnaABss8pmzPGnC/FSV +AhS442Jz7DkpyTFzKuWarWdQN4ggoTIg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec new file mode 100644 index 0000000000..c49f6c4bcc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:anyPolicy-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem new file mode 100644 index 0000000000..8b2f95b556 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUCeueEj6OFftd56Jw0VZ9VzHQVcowDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWYW55UG9saWN5LWludC1wYXRoLWludDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAgMR4wHAYDVQQDDBVhbnlQb2xpY3kt +aW50LXBhdGgtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjgZQwgZEwTgYIKwYBBQUHAQEEQjBAMD4GCCsGAQUF +BzABhjJodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvYW55UG9saWN5LWludC1w +YXRoLWVlLzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREE +FzAVghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAROBgq +JsnJtkdWyOTrG4jVhQ6WU6tmiUXEHGqDr8ARrRImX9+oekgKcGN7gyiDkvGq74rm +uqaeD4AlLkx9kXMKAd9Imr+efoOhzBbmZapCzeyrDFu343RIis2yjCSsjyLrNASZ +JWmuwsL44WOY/vSem7NIkbVEw6po0nxYpsNA94fgfPJA8Ut82vixr7+dnrCWlWM1 +7boWU8S56HuDi9TjiE4ADqmbJ+j+UZcEktCIFo9tVMh7tbd9KbO54/nDG+qgAfJU +yk8VJrYucrJa+Vtsa3CrCG640NcUD17618iwYw1c2Rseo/3yixTIQY8ujjSqC4j/ +oBiqhI8Wl7QOmX4h +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec new file mode 100644 index 0000000000..1c643c2f95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:anyPolicy-int-path-int +subject:anyPolicy-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem new file mode 100644 index 0000000000..bbb407b7d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRjCCAi6gAwIBAgIUMw+R5DkD+4bOA7KD8UDYcG3RD2IwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmFueVBvbGljeS1pbnQtcGF0aC1pbnQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjgYEwfzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBPBggrBgEFBQcBAQRD +MEEwPwYIKwYBBQUHMAGGM2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9hbnlQ +b2xpY3ktaW50LXBhdGgtaW50LzARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcN +AQELBQADggEBAEHWJ58QNHayFGL5fxbvN66qffLJVpO5L+NM5MIaeEykSj7Weaem +8Fx6V8b+j6TKs6DD4yy7o/5PODbjc7v62a25XbTE4VrlG9T58hnxRpOXfMeHFu3L +oJajIIrJI4Am23rvHyQ/achk+cKqGIgBC6eBaEb5bV13OeM4dWM34Qo0VDmOAyo5 +Rgfeh0W5XBPi7fcnDhbIyJ3JQBhlHotR3krBv98nhy5mCi4bxTjERKMAgYaLvxUb +UOAT87BxNgHAiP4vvXbxl5T/TD1KLOFuypa0Q2LpUONbW6c4fcfKRoWkyA1u3+sE +RB/0RTleOS8Ekwzex8FgQMp9D5BrIA7JDbg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec new file mode 100644 index 0000000000..5f5adacc7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:anyPolicy-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-int-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..c3a64d8890 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIUAXnU/fLGVanzfXZztetMUPvcgM0wDQYJKoZIhvcNAQEL +BQAwPTE7MDkGA1UEAwwyY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLWNhYmZvcnVt +LW9pZC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowPDE6MDgGA1UEAwwxY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLWNhYmZv +cnVtLW9pZC1pbnQtcGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBuTCBtjBqBggrBgEFBQcBAQReMFww +WgYIKwYBBQUHMAGGTmh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9jYWJmb3J1 +bS1hbmQtdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWVlLzAoBgNV +HSAEITAfMAcGBWeBDAEBMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBAyAiPnxab +CxbHi47hZ8xWcfpmyItTzPCzsKx9VGkbnFM7hA7p0CP116YlFny9wJoOi49+Qm3D +qyrnKPWme1tyW9DuDe0jz5eiUcBZ72jL5CZbXkQ1LfPKt1sGnwHoAu0NDNPeE/lQ +0RDSp/XW1kgjBDPDlTJ6k1MMdy9A0fEQosUH4bOpTOEeeTl3ZGVxJZmc2PcZebdV +Z/fizZ1JiKalKpYcAvgXGLw5HE+/OvGFlPrqxcQRa2f+MZFFDS/X7ZAiIFp7qqZg +h314bFrrPpB/v2oLMz2tdvTrIxJfj3+VXw19zkxuWavl6a/V5jiEZUQsJLgjLGdS +zQ9m/Jf6yLjU +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..c72237e453 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-and-test-oid-ee-cabforum-oid-int-path-int +subject:cabforum-and-test-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..b4728a8ea6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUIejtPWmffl6VTrZjY+grxp67lQAwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMD0xOzA5BgNVBAMMMmNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1j +YWJmb3J1bS1vaWQtaW50LXBhdGgtaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GfMIGcMAwGA1UdEwQFMAMB +Af8wCwYDVR0PBAQDAgEGMGsGCCsGAQUFBwEBBF8wXTBbBggrBgEFBQcwAYZPaHR0 +cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZvcnVtLWFuZC10ZXN0LW9pZC1l +ZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtaW50LzASBgNVHSAECzAJMAcGBWeBDAEB +MA0GCSqGSIb3DQEBCwUAA4IBAQB/zhtz6FPxar2eL9imF0/5lchKCYPLoHtMkMPo +YPmyfsOODBw0MMTKlzvzYdy4hORU8zQ8JiKJa28GlyIf08fdtaIWPjf+PmNGhMex +pD0KTCfJrmOeDVNwf3lKwM5TrWnH7nNTQ4SfRQCPBR91H6XuwgmuD8vTe1oebuX5 +ziPsjHgKp6qR707qlNQ54JSkTEnY7iLSB8O033Nrzqbz1LtFTX1kGLy0h4F/DKIJ +q2yzixcU5mHwQHKKIiirjy6ZW25Acl5xsTc0Wj9zppbEItd+Jkma2rn4EvHeYAHa +YUDwnsCqVp0WIG4QFhjzJsxoHqCnJek83E/5Av9vZX1JTwMs +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..92ebdb37fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-and-test-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem new file mode 100644 index 0000000000..51ee5e9861 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUOXwNT5oauz67TgsKQiAb5GqLxy4wDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLXBhdGgtaW50 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCsxKTAnBgNVBAMM +IGNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GoMIGlMFkG +CCsGAQUFBwEBBE0wSzBJBggrBgEFBQcwAYY9aHR0cDovL3d3dy5leGFtcGxlLmNv +bTo4ODg4L2NhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1wYXRoLWVlLzAoBgNVHSAE +ITAfMAcGBWeBDAEBMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQCY5y+AbntV59z+ +5tR6RV3Qs1ibjC/83zG3iPXLv6QqTGTB9C93d0i/cN0f2j8QE11TpPUU7pHMmblk +ZDOVLpaZtv26viXCYHJaS7OMhusmVruOJ2AoSBRdX47Z7aZB8vbmGIdSB4p6ESet +eID6Wd73189xakvUAoxFB8+zEZo1pmuTJ11tQlyIDWKz6XDrO0cIHTjF+EAAeKnv +AanOis7N/UwYEau72cErZCAwsih3V3WZ6TIwA3BCt2XmrYKtTEtFMaJNg5pR3feI +e9ZqKKT2UO1YZykFLMEYUkCAUQMUdA13MSWiA2EjnYdVRieI5nHajNhmm8hipgnf +OBEt0Zw4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..36f80e017b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-and-test-oid-ee-path-int +subject:cabforum-and-test-oid-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem new file mode 100644 index 0000000000..7a5a0914d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIUTSLwbOxOBuzeSe9coAOylouA6sEwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCwxKjAoBgNVBAMMIWNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1w +YXRoLWludDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBjTCBijAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBa +BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAGGPmh0dHA6Ly93d3cuZXhhbXBsZS5j +b206ODg4OC9jYWJmb3J1bS1hbmQtdGVzdC1vaWQtZWUtcGF0aC1pbnQvMBEGA1Ud +IAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEArzFPBw43mrcgEhmCcGAy +1eglq5KnMgtDY4lTYTfVLxrx4tOqQTDoKyMp63o6//KJxhPvEzuD6O4Gq+FMzlVu +MrGcRo78esgIkkp/I77L8YAoSALhmfBIQdiv1bC5xLWkk7MWyvHCUhQ91ZXXAOo9 +7kE/Jah0PqHZQ8GFZ50sJWaO7t1Werxw+H3uX0edUix9BhqUXt3eWxQ7f1rlcueE +poiqEhc4ECG5XVt77GswtIfTvlfXZ0iELV3BtWqgDUxBGNgmHf+k8XtN9uEIB1Lg +wJQ/zclk56ZrquaQLGm2GVIQIHQMHqkZQqWGr0SllsSXq72xX9k9WxHSGXqgfgRH +kQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec new file mode 100644 index 0000000000..79ae7ae801 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-and-test-oid-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem new file mode 100644 index 0000000000..dd103dcb7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWDCCAkCgAwIBAgIUQzfIanDdubWVWC4810gYEPO4i0swDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVY2FiZm9ydW0tb2lkLXBhdGgtaW50MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGNhYmZvcnVtLW9p +ZC1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo4GGMIGDME0GCCsGAQUFBwEBBEEwPzA9BggrBgEFBQcw +AYYxaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZvcnVtLW9pZC1wYXRo +LWVlLzASBgNVHSAECzAJMAcGBWeBDAEBMB4GA1UdEQQXMBWCE2V2LXRlc3QuZXhh +bXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAJ9Md1ZCs0/Hr6gqayb9vBSGdX1i +vT8ufJef6ViOlW0L5RrH7cYU5tIDHIRTFy+KeOhL/CWbL7zVJKofw7RUYskPucwa +ll4SeMGFMT0vDADhec9WLd+F9D8YCVhbWkb+OxeoOs98nlGhrl3ZEVP+aH55DtqF +ufiUsl8cjHY2ye1pxkfv1IlNpjORi+xtsYkkCQvgY1B5KzGg9Fe5wIC8VtyslrR5 +f7EkfSnZjrQYEHNcJTvGojRniDXhKS/AGsyDYFMgUTd/Ur3l9Wn2WfzhyyeAO+vX +6YGyLnghtcx4pvEHaKpkhCoQskjkcGOQhlq3Fq48p12IyFMCQP1LdWnHzZA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec new file mode 100644 index 0000000000..86fd9aca39 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-oid-path-int +subject:cabforum-oid-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-oid-path-ee/ +extension:certificatePolicies:2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem new file mode 100644 index 0000000000..2476d73cde --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUHxkuPQNGVMkABbeiiiNkn5pyPdgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCAxHjAcBgNVBAMMFWNhYmZvcnVtLW9pZC1wYXRoLWludDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOBgTB/MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGME4GCCsGAQUFBwEBBEIw +QDA+BggrBgEFBQcwAYYyaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZv +cnVtLW9pZC1wYXRoLWludC8wEgYDVR0gBAswCTAHBgVngQwBATANBgkqhkiG9w0B +AQsFAAOCAQEAfOjhFxR9ILmgEhFc0QtS1QxamGbs4aEPLfJpIf//IOMubqpSVr+7 +nS8nL+Fnglx4eeql6+LZNL6NUHY4xGVH9a9+RVZcfsFeJxUI9KCKBPrkD5Xetat4 +GpoYqjKT41UdJq+dLmXAs1YmF7XAVJY4vjYpFUbjML4JKlOw79jO72VRQC7MKl7t +gxGq0/IPB3/zEVGtVdIWU73aFhvJ+2H3L4sFaVY5d9BTfYvOcQtebF3SWaVIDOlw +13OdogmB1kzb2gaLs6tZAXCCtG+mxkd/+mrUXXDCsnfY7IEGf82z5cmEFJorgwEH +uw/YpAPooZCMfvp5BNE6MIi6EYR/nHjCGw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec new file mode 100644 index 0000000000..343307164b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-oid-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-oid-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.key b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ev_certs/moz.build b/security/manager/ssl/tests/unit/test_ev_certs/moz.build new file mode 100644 index 0000000000..927fadf1d0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/moz.build @@ -0,0 +1,48 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'anyPolicy-ee-path-ee.pem', +# 'anyPolicy-ee-path-int.pem', +# 'anyPolicy-int-path-ee.pem', +# 'anyPolicy-int-path-int.pem', +# 'cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem', +# 'cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem', +# 'cabforum-and-test-oid-ee-path-ee.pem', +# 'cabforum-and-test-oid-ee-path-int.pem', +# 'cabforum-oid-path-ee.pem', +# 'cabforum-oid-path-int.pem', +# 'evroot.pem', +# 'no-ocsp-ee-path-ee.pem', +# 'no-ocsp-ee-path-int.pem', +# 'no-ocsp-int-path-ee.pem', +# 'no-ocsp-int-path-int.pem', +# 'non-ev-root-path-ee.pem', +# 'non-ev-root-path-int.pem', +# 'non-evroot-ca.pem', +# 'reverse-order-oids-path-ee.pem', +# 'reverse-order-oids-path-int.pem', +# 'test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem', +# 'test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem', +# 'test-and-cabforum-oid-ee-path-ee.pem', +# 'test-and-cabforum-oid-ee-path-int.pem', +# 'test-oid-ee-cabforum-oid-int-path-ee.pem', +# 'test-oid-ee-cabforum-oid-int-path-int.pem', +# 'test-oid-path-ee.pem', +# 'test-oid-path-int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'evroot.key', +# 'test-oid-path-int.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem new file mode 100644 index 0000000000..1eb17e0d4a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEDCCAfigAwIBAgIUEVaHlHZqtF7YUMSMX768HxJ2o6QwDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTbm8tb2NzcC1lZS1wYXRoLWludDAiGA8yMDE5MTEyODAw +MDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAdMRswGQYDVQQDDBJuby1vY3NwLWVlLXBh +dGgtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjQzBBMB8GA1UdIAQYMBYwFAYSKwYBBAHrSYUahRqFGgGDdAkB +MB4GA1UdEQQXMBWCE2V2LXRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAEOYKTjhumr1vgG+VTbI09KXlkdy40/PKEKx6qqgcPVzJdwv9zcrcC0diJGm +bgReRgaw7CauoL9iY/BaBI+awYfLeQR7+Sasyg3M7QPLHXTAvJYzjYWQrcI2Bq9f +FpF6vGdN3O6OEifA+cdNWMAXQi2KnFdxCrwV1isLFSnonk+2qhmQmGBUCqVzSC+I +09IzhxcZPtWYKPJL0Cfnx4r/+tLt/A+tfhUUcDxT3H6TgfhmN4oeMq01MQ/H/und +ARclew0opuHEUQg1UL5cYJUTO/+rbslcRbwDkJNbw2CN6u2CCtaYEjkZQlQ+rfd8 +5m9OsORT8NhDwyGkCNoqU0eTYPY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..ece1cf816f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:no-ocsp-ee-path-int +subject:no-ocsp-ee-path-ee +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem new file mode 100644 index 0000000000..7eea57927f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPzCCAiegAwIBAgIUO1Rn0qhER6ecygoAUilco/BzuwUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB4xHDAaBgNVBAMME25vLW9jc3AtZWUtcGF0aC1pbnQwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +fjB8MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMEwGCCsGAQUFBwEBBEAwPjA8 +BggrBgEFBQcwAYYwaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L25vLW9jc3At +ZWUtcGF0aC1pbnQvMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOC +AQEAkwxxKtURPe9v3BjIpNuig5QVEf5NXSoxqbScpEK/fumMsegQekfAqomKbmCn +O5B3Qhn146UclkoeKaJJQ+DpWcRDqg9pMkwWbJDd7SpBGqzo34juHR2q7mnBEXQM +jte6jJnV5XTNG0RSaBL523CcSByk0H6AtBI+vqYJlF2Ks7/9S94QD7fW7gvqBDPQ +zXMbO4qXl34sA8rpaDQBjOmwMl0JXtt0/CrbOTkb7GcaNGaoNORKey6MxMQCmVbD +KkMoU98lJwO5PMZkid03vN4ooTNoOFLevyDjP6dGBf3/+x7IASr7NQsdtXdWeSOs +W31qevNBQqgSY/vA2graLBoKGQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec new file mode 100644 index 0000000000..5eb952a9a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:no-ocsp-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/no-ocsp-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem new file mode 100644 index 0000000000..24c1a97670 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIUU2GeukGa6dcsNWCnTyp5K0jKQO8wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUbm8tb2NzcC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTbm8tb2NzcC1pbnQt +cGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBkjCBjzBMBggrBgEFBQcBAQRAMD4wPAYIKwYBBQUHMAGG +MGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9uby1vY3NwLWludC1wYXRoLWVl +LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAYiSEHOmStRPXW +y5vUwnM98/F1YLNse2fC8PSsG3i+74YRVmtCi+A+KSIwVH6bRVSZCAXn0Ie86sQh +UIty2qzWyn/nFrX3KS1N660GsSpvQmtnn31dMGGbEbEoLH5MOm1EPD/ydAdTZc9H ++Jg+0SSlELBTsdOI6mUj84JL4p8piYtIvgVWDUqn3d2Q4qp5m2IWsWJn/x/YrtJ9 +qcTHEYD1B3WGSg6LeUlqWCCmz/2CaYzd0SRSXPqOZpR5RCckoY5f7o1Lev+/yqLK +ExfJrMIg+encVBPvPxIZrNLa+8GT705rVvX4MbKP0tIpTzPv1DimxaKauytRNkgR +sN4lGvFc +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec new file mode 100644 index 0000000000..623057e9e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:no-ocsp-int-path-int +subject:no-ocsp-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/no-ocsp-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem new file mode 100644 index 0000000000..51fbc28ed2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUPy5yIOPguO2ZrWK+N5gQKt6P8vQwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB8xHTAbBgNVBAMMFG5vLW9jc3AtaW50LXBhdGgtaW50MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ozAwLjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjARBgNVHSAECjAIMAYGBFUd +IAAwDQYJKoZIhvcNAQELBQADggEBAHLIQ3h5ckWiymYNqo255k6T/8bIupCPn6Z0 +qVoNmlb3s0XZfTy/64GRCqdRDMMhT80po7IVInalhfrxlBsoG4ASQ1Rc1HI3I1c5 +4umDOTxDrTIiCxJlMFGodb7ZWsrsIO0a9FpDAuuXRkl2wdqEo2UpfJBq3/LPhq4w +Uzv5KUFDo5frBytVJFR+qpnrSEeekORLqszUw5eYy50YegC1qlXca2Vk/m2oQGKC +4yAT+dS7i7WYrZ20aoAngBLrBr0EJuBjjDCpIGM3z41RcT7VOsezfmteGzoRoVBh +GjHgM7gesSuC8oOOr8i9aT1X5MQMhfVo/MdS/UDtLlSt5bCVwQo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec new file mode 100644 index 0000000000..548241de3a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec @@ -0,0 +1,6 @@ +issuer:evroot +subject:no-ocsp-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem new file mode 100644 index 0000000000..93139ba9db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIUd59Z/7YSXGFqK6Mbt0Q0cLiJV94wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUbm9uLWV2LXJvb3QtcGF0aC1pbnQwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTbm9uLWV2LXJvb3Qt +cGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBkjCBjzBMBggrBgEFBQcBAQRAMD4wPAYIKwYBBQUHMAGG +MGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9ub24tZXYtcm9vdC1wYXRoLWVl +LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAlsnI1h5nJcbp2 +0qwOoxUZZhmztKVGp5Oy9ae0TbkEgqVYYRTnNSSVd82cULRrMY4p3kEaAwbU7ej7 +YhxsNIBf1f9pRozRIdY/SZv20nh2/r3N6RfjvxHXRcoav9dpEti8kLFsRDaEbxo9 +yxS+9vbEmg9iuVkvMHAd3tZ0lBg5lYFXVk6BKrJF9nqrOiZhl5//0+tUfCenvleJ +ngoB8MLZGR5Y25Vov0rSzj6HM3XLBoV5MIeFcB3n/JcBCXPPFwikQgIHTzInF4+H +UgQOhv7L1nzSrIAZjiGHbD3R4RNwMlkIAlt6nzWse7e2zwBedYjpcFy4qFN3sweU +91MM5I3h +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec new file mode 100644 index 0000000000..9895732b15 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:non-ev-root-path-int +subject:non-ev-root-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/non-ev-root-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem new file mode 100644 index 0000000000..74e5066cec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIUCa1ByR+IaXRuP5HPyIyTz7ZjGSAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNbm9uLWV2cm9vdC1jYTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRub24tZXYtcm9vdC1wYXRoLWlu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaN/MH0wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwTQYIKwYBBQUH +AQEEQTA/MD0GCCsGAQUFBzABhjFodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgv +bm9uLWV2LXJvb3QtcGF0aC1pbnQvMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG +9w0BAQsFAAOCAQEAZU5zl2ENgMl0Y+Yvstp/aDqF1s8OTSEQgaYdRd5z5lh2tZKc +vQdj/eH9EuT9ao3HsYFLao79ukbvHBPmtU6snsbO82kf7fFO/LtaGoKYKWnTJVyF +1jOlQ1YCpntdkEdrdgSH1dbxQCqffvPQUxlHUYuhPXM/OyC6ZPuH3409bH7NFE8d +d9FzlOZu7wX+aIttXJUeH+QklPomOp2Ef0aZwj9TMi9yjRdomfD/amYPYKmvpXlN +Vem+Lx3O9sN6zsTcDs3tmY0pQ9GRAWPO9n8wv4drUVyhtF4LU87bShJ66zxW/lN4 +50jdCVPBizdvAbDB1iNVHBiagWX1rL4unY8g5w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec new file mode 100644 index 0000000000..5ce035ae1e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec @@ -0,0 +1,6 @@ +issuer:non-evroot-ca +subject:non-ev-root-path-int +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/non-ev-root-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem new file mode 100644 index 0000000000..c987c4826c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUGVWjVL2eG3LHefW8SbN9qKKBkR8wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNbm9uLWV2cm9vdC1jYTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1ub24tZXZyb290LWNhMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAIL1Lg6t9nhLv8OMt5Jupz2pz7r2l+OQOeVklrV4defOgh5GNA6Ib27iqbp3u +WiKHKHwUIjNUCbjYulnDqyQOugU7c3MCq4iy+rJhPECmTkrwTW8D3Rk0HtaABG3I +hlsf3ol+5TWP/84+eu3Re9GELv3ot9j9BGH29lW8wF6K2lw4Q61uXxTS1FZFfBw0 +fXxyQYeKLc/NXnde1I05/vgieogPJa8klb6IOhHgdnfyfFUyTSKRUTuchCNJWlua +cxuMEYDkbusVVN3mNaBanqSuP4o8LnyOXvxUhDIm9I8dpcYD45db+2Et5SwPq1jB +9Bm5lW6mnQkcBeSDAhXs8WjYWA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec new file mode 100644 index 0000000000..7b61447a80 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:non-evroot-ca +subject:non-evroot-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem new file mode 100644 index 0000000000..80720f9856 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUEXmqqsX9kzkkT1kcgsKRmjz4I3owDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbcmV2ZXJzZS1vcmRlci1vaWRzLXBhdGgtaW50MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCUxIzAhBgNVBAMMGnJldmVy +c2Utb3JkZXItb2lkcy1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GiMIGfMFMGCCsGAQUFBwEBBEcw +RTBDBggrBgEFBQcwAYY3aHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3JldmVy +c2Utb3JkZXItb2lkcy1wYXRoLWVlLzAoBgNVHSAEITAfMAcGBWeBDAEBMBQGEisG +AQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNldi10ZXN0LmV4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQBUE1VSHa5kqgpWz91KR8zawKi+hFSszqXN8bFU +H5WEl7j7W0fCBmpqKTlz6V3HFuphFaE6kDctZ33H8TLVTROPusCxY28dgphJPZQG +LaOwdU0YcdCH20wEXgkoujM/cgnyNkTgBkRG5psvtAvTg28bsOWbqpgxiSaKBo0z +xYPMq+J+schGpK02zLlkbANZQdBYg37jBVFWCTW5/tGS4rPEDC/agn33y6Pvv6mq +XUrxOP0E8sZ3XPnjMBIXRI9NRm6urNMPQsteEHdhDVSo9LXV3d6GmlSW8xoGTmEA +G4HYR1A6+D7PGJDVyvWaGENkGEfJUi7ngfiMEvDTwbQLy08V +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec new file mode 100644 index 0000000000..31e3e69e53 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:reverse-order-oids-path-int +subject:reverse-order-oids-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/reverse-order-oids-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem new file mode 100644 index 0000000000..17ccdcd549 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUVyTXYnGBHJHjCi2C6eJVXi/iBbUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCYxJDAiBgNVBAMMG3JldmVyc2Utb3JkZXItb2lkcy1wYXRoLWlu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaOBnjCBmzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBUBggrBgEF +BQcBAQRIMEYwRAYIKwYBBQUHMAGGOGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4 +OC9yZXZlcnNlLW9yZGVyLW9pZHMtcGF0aC1pbnQvMCgGA1UdIAQhMB8wFAYSKwYB +BAHrSYUahRqFGgGDdAkBMAcGBWeBDAEBMA0GCSqGSIb3DQEBCwUAA4IBAQAWdeBD +aq3w2mJQWpFQLh9ilFWk0wR1wPTEu/G2sJlZiaj3hoQmjtAb2hzuoKorSDSv0z6l +mTrvT1CLztFJmTosimY+aoDolDJ07cqMQ5LrzSRMw48vhzeeyy13DX5uCYUxRK27 +EHAovqpg9AoPBlA0oSEM1FHxxzWmnh3eJRsos6TBIeryzX3U3j9yVkXALprWc26W +DK1SeAZjpALx2rapYRMKIypFmWmyYzOf2Ix5np6QwGCBnQyTvYSK2a8I4f4fGS2R +y+ZSyd1JwVMD7ok6zfG3+KjXRgbAL3UFkT45h/BghBfavAuJbbjzbnUwHzy8NwQh +e0303QOYHHq0vJIh +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec new file mode 100644 index 0000000000..a2b523073e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:reverse-order-oids-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/reverse-order-oids-path-int/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..3ef4e6ab5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIUY4rG8NqK821vmnElwuFYW26zGUEwDQYJKoZIhvcNAQEL +BQAwPTE7MDkGA1UEAwwydGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLWNhYmZvcnVt +LW9pZC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowPDE6MDgGA1UEAwwxdGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLWNhYmZv +cnVtLW9pZC1pbnQtcGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBuTCBtjBqBggrBgEFBQcBAQReMFww +WgYIKwYBBQUHMAGGTmh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC90ZXN0LWFu +ZC1jYWJmb3J1bS1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWVlLzAoBgNV +HSAEITAfMBQGEisGAQQB60mFGoUahRoBg3QJATAHBgVngQwBATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAd+Daw/djP +TluuhjaKDlybSeAF7k3Y7ndQXGkXHnnjyDSzVUsgaqZ5snUkYVLVFV5dG+IsYhhu +hhkXok4nq+6Jc9O08/Uu7kIpjf7Ouv5Z0OZBBojAvcaYDH98bjxxx5Lec0nV+GTP +PTh6BgJosCOTXEan6QzPHOV3xyNuDzrXMVDglyVFvBgOj8AavNUPiqi9lB9gN23w +AjzxSo3i5J0oEYfwUjnPlwI5zQ9yOKG1pnno4lBI7XMhDs5J7BEMt9fz+W5U+/2p +MAUkku6bPT94uOH4Lj6Chu2ppFo+herNAdNO1UznNWOcOkOap+SUQJubPqTwdf8c +BJ4WinbiDmDf +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..edac2fc1ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-and-cabforum-oid-ee-cabforum-oid-int-path-int +subject:test-and-cabforum-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..dc2d66256c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUB38LWV7K1ZtRLJtMguF5H4CVwXAwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMD0xOzA5BgNVBAMMMnRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1j +YWJmb3J1bS1vaWQtaW50LXBhdGgtaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GfMIGcMAwGA1UdEwQFMAMB +Af8wCwYDVR0PBAQDAgEGMGsGCCsGAQUFBwEBBF8wXTBbBggrBgEFBQcwAYZPaHR0 +cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3Rlc3QtYW5kLWNhYmZvcnVtLW9pZC1l +ZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtaW50LzASBgNVHSAECzAJMAcGBWeBDAEB +MA0GCSqGSIb3DQEBCwUAA4IBAQA2ga4887r55Lcv0LUHtIAd9DqcgqzY59nXDXOX +PnS5gR58r1LF/u/7jPSJ6K3qzON6ug+PDoJhUf1UXBWzXhWusm8Eb5Fxo9OJV521 +GqZVsPdt8c1rnRLlrNi2GsLmywhgAy1w3mAR33laYeuT9PPQokn1W8hnU7hdWEwV +V24CVsAK5YPH/BoSmnxVqG22/ZPbetqRKRzUanuOEOAuDBgPrt7NRm5djMpKyH4D +k3drl+ZM0HFy3zH5XHN+a93E+iWrLy9/+kDq/7/2BBnXFSa7bTq+d/aWFrIXfW57 +Qx0bLWxz1SbqIElXnUKWGwWHoWObMRw7nP6orVKBqefyqRLL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..68dfd00573 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-and-cabforum-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem new file mode 100644 index 0000000000..6c746a4773 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUTezLjnCdM9De3GXzBHXuGsNnVKowDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhdGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLXBhdGgtaW50 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCsxKTAnBgNVBAMM +IHRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GoMIGlMFkG +CCsGAQUFBwEBBE0wSzBJBggrBgEFBQcwAYY9aHR0cDovL3d3dy5leGFtcGxlLmNv +bTo4ODg4L3Rlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1wYXRoLWVlLzAoBgNVHSAE +ITAfMBQGEisGAQQB60mFGoUahRoBg3QJATAHBgVngQwBATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAYzsZA6rEPjGaO +3B9F7YLtYBFxtstq1++z+MRuLFXsXnaGgS65bP8C+phNNQQUYcTzjp/+nbA2HIVL +OOtf0Z0Ciqxb6ALXhuHnPYX8pSby7afY1I4NAOuEKA844TZ2hwf6hGxMGFYC1Khv ++k0iFMLLzYA0gvVRMnhRvhoPqVQL0CxO0TRiYpf0pmPPiTkop37eNbaHorEAnCtf +gZpfbDiYgh9USBGcfehKmwXjNRM0M+uVUdcsdzOwTHMeAUV5teRtf82D3j3moWhg +HUjGRNpVDZjSp+Wn7psAWtKLETJhmfWPu5/b6X91+N2L20oWYk4ONCEsKezqDMxS +Z5Ix+EJT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..affbd87458 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-and-cabforum-oid-ee-path-int +subject:test-and-cabforum-oid-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem new file mode 100644 index 0000000000..3579205224 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIUIQbkixAb+1Y/Mab1Sh8NPYs0GLgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCwxKjAoBgNVBAMMIXRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1w +YXRoLWludDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBjTCBijAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBa +BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAGGPmh0dHA6Ly93d3cuZXhhbXBsZS5j +b206ODg4OC90ZXN0LWFuZC1jYWJmb3J1bS1vaWQtZWUtcGF0aC1pbnQvMBEGA1Ud +IAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAk6yOHhUbvCaulXNXvAUc +X97+o1CkeFk1QCavnZUURyGZQlGppyKXU+RuEITsiGbYU/eqOrTGsxmdbLQ3QsPc +hjiToDnXD7Bt7Nr98PDUFmIdh2sd++Wcjo9qjxoKrmxVvpxo8bdIRY3gVQaI/3Wy +Hz+/iBKYKO07b3ql3cApqnnl+DEi4KFIfHOca4iBricDWWUBuJUmhwIiKqxsP/yv +Y96xgMmO2/zVBG9bAwpbqnqygKoiaxZDEpFR7/4w0CKkgS85k6fVsE1Ozz8K8BZZ +xuLfgn9A6I4qjfCxCGfH9Gojh61BwlHIUIJ8Rjbpn5kt7E9V3WMGTcopQISRoKEN +vg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec new file mode 100644 index 0000000000..11630b4b4f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-and-cabforum-oid-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..fa64ee0636 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlTCCAn2gAwIBAgIUV330em+9Xec1DGZ4wJhdv0RjswMwDQYJKoZIhvcNAQEL +BQAwMDEuMCwGA1UEAwwldGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRo +LWludDAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAvMS0wKwYD +VQQDDCR0ZXN0LW9pZC1lZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtZWUwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +gaMwgaAwXQYIKwYBBQUHAQEEUTBPME0GCCsGAQUFBzABhkFodHRwOi8vd3d3LmV4 +YW1wbGUuY29tOjg4ODgvdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRo +LWVlLzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQCh1PqRvUqb +ZLTd7bxaQ//insQtmlqcflBQkPEkFLkyiyKOuBIeO5B+sgr2l8GsUfrVhqd6e2Xe +qL/6+RNlLGm5tKaTLgmXo9iG/oADW8WKyf6oCXuFMU7AiZH6cS4//ewcWdZxO7xz +vRfu5M6TDJMMEFk71wQSzx163/aidZ3u6tcPC+PSkCVD8vzQcJPBKcF+/hFyVOPT +PJgF/NvUY3CBykH54zm12SEFh+iOkrbQRlazlJfUTXX+dGD3iohZ+KlpQUZ8Yibk +OzHbgM5rggesRSvcu7Ud5e42XDdTq+gDVVbwEmYer6+h+qdT4WJ6bF3qNt7gKKf/ +FqqTAPIlcQFx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..bd0f955ada --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-oid-ee-cabforum-oid-int-path-int +subject:test-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..a2c85f5efc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIUacgXv3Tmh0nRe3yh82VGGbTiqtkwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMDAxLjAsBgNVBAMMJXRlc3Qtb2lkLWVlLWNhYmZvcnVtLW9pZC1p +bnQtcGF0aC1pbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjgZIwgY8wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzABhkJodHRwOi8vd3d3LmV4YW1w +bGUuY29tOjg4ODgvdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWlu +dC8wEgYDVR0gBAswCTAHBgVngQwBATANBgkqhkiG9w0BAQsFAAOCAQEAFRoD650v +OtuTmJQO9NepvUZl8M3FqcQhrzl5u1qH9fKhpWaK2oXCsxirquCTitnFvIHwRARW +2UUgGgngwKDVJ+c7ohRudQIrBaS4utKpIv6ljZQ/oF6W0Z+4SSkbv3wj1Aw0ThbQ +am4Jhpf7KsxSwwrFwXn+8vCWahQvk31vZTw0S9EGdEL9P8xyor/pcG4RDB7+WYDP +dHNdexGSYrnQINgQthPUSHfWJPI44CxyyACgpsu7zqd8UZ3BSP51wJARWBky5xhs +RoVs9yVmXeah7ejpFSdI+fAS9ZAfHs0owrD+fEa2+2jdhpPEyay5DdLsGn/mMJ+Q +K54zhyttXeyMtQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..37d4d133a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem new file mode 100644 index 0000000000..6d9acef5b1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWTCCAkGgAwIBAgIUZWC2u4FJNGtmdv2n5Yk6Q7xQ8OQwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRdGVzdC1vaWQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowGzEZMBcGA1UEAwwQdGVzdC1vaWQtcGF0aC1l +ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaOBjzCBjDBJBggrBgEFBQcBAQQ9MDswOQYIKwYBBQUHMAGGLWh0dHA6 +Ly93d3cuZXhhbXBsZS5jb206ODg4OC90ZXN0LW9pZC1wYXRoLWVlLzAfBgNVHSAE +GDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNldi10ZXN0LmV4 +YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQB3iZ8RGk7s3jwZY1cgJyJfjWIb +A6DpKtL6KcvL/lcAF2VbrTdAHkEQ7TbSmDMZM484hRxckG7gs2C7rb+lUTDNk4JS +WGm+WhTGd98DDM2ZIY3UPrGEKycqfrFqdjaJhMwd/BcgQgw5DgHUWlfKO1utSDLh +vv212o2uzldYaGnVgyr6QK+kzpm+zLuveSxmiZSw3PE1+fZ8+yS5Ku6bo5yfdSg+ +jC9j6BZDiaf6B73offVyNlOMqD6LHczWENKCl7bCeLkH9OEl2eF7KMf3SL17b+fw +QXvNBwHcKkEd1ElqyZOadUtAtRvaF0bWjOJ5QirH3czhPaq4XZJI8KVQyeWz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec new file mode 100644 index 0000000000..a9d62c65e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-oid-path-int +subject:test-oid-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem new file mode 100644 index 0000000000..2be083fca1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIUEcfv2VQb1qigZ7waPro3Nb2Ury8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBwxGjAYBgNVBAMMEXRlc3Qtb2lkLXBhdGgtaW50MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GL +MIGIMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMEoGCCsGAQUFBwEBBD4wPDA6 +BggrBgEFBQcwAYYuaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3Rlc3Qtb2lk +LXBhdGgtaW50LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATANBgkq +hkiG9w0BAQsFAAOCAQEAJCZU0IPgdXwzNObNGVAa5SRNx3J9CZ9j6++cfitpaYc9 +sG6mdyyAjUbumaIgo84aH6dER+FxICt124AkAWFNPZtL+RVBV6/Y54KXSYKViXGl +DRWOYqrbF+RGELQr5OW2kTr/u1Fsd7DWBjPBRvxLHzgSXvu3+knjXo9Mfsw+tpkH +av8FGvxHvrj1Ad4tBXPL2MvwfT/KNtDLDVpWbkUW7sHhcEiVlitD6JONopiAmPEU +8yNUERTw2eTDO16UMmh205wI4Z2f4SnZqrsueCQv86Nr5i12V6TWiipVvNKJLjQU +UiBVkuFLI6o/rZMjJwgJrYgeeBmJa3E1Xa4cXf3Ehw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec new file mode 100644 index 0000000000..53534eb526 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-oid-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-path-int/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js b/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js new file mode 100644 index 0000000000..cf697d94e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js @@ -0,0 +1,205 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=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"; + +// Ensures that HSTS (HTTP Strict Transport Security) information is cleared +// when using "Forget About This Site". + +const { ForgetAboutSite } = ChromeUtils.import( + "resource://gre/modules/ForgetAboutSite.jsm" +); + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.cert_pinning.enforcement_level"); +}); + +const GOOD_MAX_AGE_SECONDS = 69403; +const GOOD_MAX_AGE = `max-age=${GOOD_MAX_AGE_SECONDS};`; + +const sss = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); +const uri = Services.io.newURI("https://a.pinning.example.com"); + +function add_tests() { + let secInfo = null; + + add_connection_test( + "a.pinning.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + // Test the normal case of processing HSTS headers for a.pinning.example.com, + // using "Forget About Site" on a.pinning2.example.com, and then checking + // that the platform doesn't consider a.pinning.example.com to be HSTS any + // longer. + add_task(async function() { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should be HSTS" + ); + + await ForgetAboutSite.removeDataFromDomain("a.pinning.example.com"); + + Assert.ok( + !sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should not be HSTS now" + ); + }); + + // Test the case of processing HSTS headers for a.pinning.example.com, using + // "Forget About Site" on example.com, and then checking that the platform + // doesn't consider the subdomain to be HSTS any longer. Also test that + // unrelated sites don't also get removed. + add_task(async function() { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should be HSTS (subdomain case)" + ); + + // Add an unrelated site to HSTS. + let unrelatedURI = Services.io.newURI("https://example.org"); + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI, 0), + "example.org should be HSTS" + ); + + await ForgetAboutSite.removeDataFromDomain("example.com"); + + Assert.ok( + !sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should not be HSTS now (subdomain case)" + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI, 0), + "example.org should still be HSTS" + ); + }); + + // Test the case of processing HSTS headers for a.pinning.example.com with + // various originAttributes, using "Forget About Site" on example.com, and + // then checking that the platform doesn't consider the subdomain to be HSTS + // for any originAttributes any longer. Also test that unrelated sites don't + // also get removed. + add_task(async function() { + let originAttributesList = [ + {}, + { userContextId: 1 }, + { firstPartyDomain: "foo.com" }, + { userContextId: 1, firstPartyDomain: "foo.com" }, + ]; + + let unrelatedURI = Services.io.newURI("https://example.org"); + + for (let originAttributes of originAttributesList) { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ); + + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + "a.pinning.example.com should be HSTS (originAttributes case)" + ); + + // Add an unrelated site to HSTS. + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ); + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + 0, + originAttributes + ), + "example.org should be HSTS (originAttributes case)" + ); + } + + await ForgetAboutSite.removeDataFromDomain("example.com"); + + for (let originAttributes of originAttributesList) { + Assert.ok( + !sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + "a.pinning.example.com should not be HSTS now " + + "(originAttributes case)" + ); + + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + 0, + originAttributes + ), + "example.org should still be HSTS (originAttributes case)" + ); + } + }); +} + +function run_test() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_hash_algorithms.js b/security/manager/ssl/tests/unit/test_hash_algorithms.js new file mode 100644 index 0000000000..ccdaf831e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hash_algorithms.js @@ -0,0 +1,158 @@ +"use strict"; + +// This file tests various aspects of the nsICryptoHash implementation for all +// of the supported algorithms. + +const messages = ["The quick brown fox jumps over the lazy dog", ""]; +const ALGORITHMS = [ + { + initString: "md5", + initConstant: Ci.nsICryptoHash.MD5, + hexHashes: [ + "9e107d9d372bb6826bd81d3542a419d6", + "d41d8cd98f00b204e9800998ecf8427e", + ], + b64Hashes: ["nhB9nTcrtoJr2B01QqQZ1g==", "1B2M2Y8AsgTpgAmY7PhCfg=="], + }, + { + initString: "sha1", + initConstant: Ci.nsICryptoHash.SHA1, + hexHashes: [ + "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + ], + b64Hashes: ["L9ThxnotKPzthJ7hu3bnORuT6xI=", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="], + }, + { + initString: "sha256", + initConstant: Ci.nsICryptoHash.SHA256, + hexHashes: [ + "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + ], + b64Hashes: [ + "16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=", + "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", + ], + }, + { + initString: "sha384", + initConstant: Ci.nsICryptoHash.SHA384, + hexHashes: [ + "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", + "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", + ], + b64Hashes: [ + "ynN/EBSkj0wLbdQ8sXewr9nlFpNnVExJQBHjMX2/mlCcseXcHoWpQbvuPX8q+8mx", + "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", + ], + }, + { + initString: "sha512", + initConstant: Ci.nsICryptoHash.SHA512, + hexHashes: [ + "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", + ], + b64Hashes: [ + "B+VH2VhvanP3P7rAQ17XaVEhj7fQyNeIownXhUNru2Quk6JSqVTyORJUfR6KO17W4b/XCXghIz+gU489uFT+5g==", + "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", + ], + }, +]; + +function doHash(algo, value, cmp) { + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.initWithString(algo); + + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + value = converter.convertToByteArray(value); + hash.update(value, value.length); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match` + ); + + hash.initWithString(algo); + hash.update(value, value.length); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match after re-init` + ); +} + +function doHashStream(algo, value, cmp) { + // TODO(Bug 459835): Make updateFromStream() accept zero length streams. + if (value.length == 0) { + return; + } + + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.initWithString(algo); + + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let stream = converter.convertToInputStream(value); + hash.updateFromStream(stream, stream.available()); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match updating from stream` + ); +} + +function testInitConstantAndBase64( + initConstant, + algoName, + message, + expectedOutput +) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let value = converter.convertToByteArray(message); + + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.init(initConstant); + hash.update(value, value.length); + equal( + hash.finish(true), + expectedOutput, + `Actual and expected base64 hash for ${algoName} should match` + ); +} + +function run_test() { + for (let algo of ALGORITHMS) { + algo.hexHashes.forEach((hash, i) => { + doHash(algo.initString, messages[i], hash); + doHashStream(algo.initString, messages[i], hash); + }); + algo.b64Hashes.forEach((hash, i) => { + testInitConstantAndBase64( + algo.initConstant, + algo.initString, + messages[i], + hash + ); + }); + } + + // Our buffer size for working with streams is 4096 bytes. This tests we + // handle larger inputs. + doHashStream("md5", " ".repeat(4100), "59f337d82f9ef5c9571bec4d78d66641"); +} diff --git a/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js b/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js new file mode 100644 index 0000000000..f2b7016c05 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js @@ -0,0 +1,5 @@ +"use strict"; + +function run_test() { + run_test_in_child("test_hash_algorithms.js"); +} diff --git a/security/manager/ssl/tests/unit/test_hmac.js b/security/manager/ssl/tests/unit/test_hmac.js new file mode 100644 index 0000000000..8bb6139133 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hmac.js @@ -0,0 +1,157 @@ +"use strict"; + +// This file tests various aspects of the nsICryptoHMAC implementation for all +// of the supported algorithms. + +function getHMAC(data, key, alg, returnBase64) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let dataArray = converter.convertToByteArray(data); + + let keyObject = Cc["@mozilla.org/security/keyobjectfactory;1"] + .getService(Ci.nsIKeyObjectFactory) + .keyFromString(Ci.nsIKeyObject.HMAC, key); + + let cryptoHMAC = Cc["@mozilla.org/security/hmac;1"].createInstance( + Ci.nsICryptoHMAC + ); + + cryptoHMAC.init(alg, keyObject); + cryptoHMAC.update(dataArray, dataArray.length); + let digest1 = cryptoHMAC.finish(returnBase64); + + cryptoHMAC.reset(); + cryptoHMAC.update(dataArray, dataArray.length); + let digest2 = cryptoHMAC.finish(returnBase64); + + let stream = converter.convertToInputStream(data); + cryptoHMAC.reset(); + cryptoHMAC.updateFromStream(stream, stream.available()); + let digestFromStream = cryptoHMAC.finish(returnBase64); + + equal( + digest1, + digest2, + "Initial digest and digest after calling reset() should match" + ); + + equal( + digest1, + digestFromStream, + "Digest from buffer and digest from stream should match" + ); + + return digest1; +} + +function testHMAC(alg) { + const key1 = "MyKey_ABCDEFGHIJKLMN"; + const key2 = "MyKey_01234567890123"; + + const dataA = "Secret message"; + const dataB = "Secres message"; + + let digest1a = getHMAC(key1, dataA, alg, false); + let digest2 = getHMAC(key2, dataA, alg, false); + let digest1b = getHMAC(key1, dataA, alg, false); + + equal( + digest1a, + digest1b, + "The digests for the same key, data and algorithm should match" + ); + notEqual( + digest1a, + digest2, + "The digests for different keys should not match" + ); + + let digest1 = getHMAC(key1, dataA, alg, false); + digest2 = getHMAC(key1, dataB, alg, false); + + notEqual(digest1, digest2, "The digests for different data should not match"); +} + +function testVectors() { + const keyTestVector = "Jefe"; + const dataTestVector = "what do ya want for nothing?"; + + // The base 64 values aren't in either of the RFCs below; they were just + // calculated using the hex vectors. + const vectors = [ + // RFC 2202 section 2 test case 2. + { + algoID: Ci.nsICryptoHMAC.MD5, + algoName: "MD5", + expectedDigest: "750c783e6ab0b503eaa86e310a5db738", + expectedBase64: "dQx4PmqwtQPqqG4xCl23OA==", + }, + // RFC 2202 section 2 test case 3. + { + algoID: Ci.nsICryptoHMAC.SHA1, + algoName: "SHA-1", + expectedDigest: "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", + expectedBase64: "7/zfauXrL6LSdBbV8YTfnCWafHk=", + }, + // RFC 4231 section 4.3. + { + algoID: Ci.nsICryptoHMAC.SHA256, + algoName: "SHA-256", + expectedDigest: + "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843", + expectedBase64: "W9zBRr9gdU5qBCQmCJV1x1oAPwidJzmDnexYuWTsOEM=", + }, + { + algoID: Ci.nsICryptoHMAC.SHA384, + algoName: "SHA-384", + expectedDigest: + "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649", + expectedBase64: + "r0XS43ZIQDFhf3jStYprG5x+9GT1oBtH5C7Dc2MiRF6OIkDKXmnix4syOez6shZJ", + }, + { + algoID: Ci.nsICryptoHMAC.SHA512, + algoName: "SHA-512", + expectedDigest: + "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737", + expectedBase64: + "Fkt6e/z4GeLjlfvnO1bgo4e9ZCIugx/WECcM1+olBVSXWL91wFqZSm0DT2X48Ob9yuqxo01Ka0tjbgcKOLznNw==", + }, + ]; + + for (let vector of vectors) { + let digest = getHMAC(dataTestVector, keyTestVector, vector.algoID, false); + equal( + hexify(digest), + vector.expectedDigest, + `Actual and expected ${vector.algoName} digests should match` + ); + let b64Digest = getHMAC(dataTestVector, keyTestVector, vector.algoID, true); + equal( + b64Digest, + vector.expectedBase64, + `Actual and expected ${vector.algoName} base64 digest should match` + ); + } +} + +function run_test() { + testVectors(); + + testHMAC(Ci.nsICryptoHMAC.MD5); + testHMAC(Ci.nsICryptoHMAC.SHA1); + testHMAC(Ci.nsICryptoHMAC.SHA256); + testHMAC(Ci.nsICryptoHMAC.SHA384); + testHMAC(Ci.nsICryptoHMAC.SHA512); + + // Our buffer size for working with streams is 4096 bytes. This tests we + // handle larger inputs. + let digest = getHMAC(" ".repeat(4100), "test", Ci.nsICryptoHMAC.MD5, false); + equal( + hexify(digest), + "befbc875f73a088cf04e77f2b1286010", + "Actual and expected digest for large stream should match" + ); +} diff --git a/security/manager/ssl/tests/unit/test_imminent_distrust.js b/security/manager/ssl/tests/unit/test_imminent_distrust.js new file mode 100644 index 0000000000..861269e784 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_imminent_distrust.js @@ -0,0 +1,39 @@ +/* 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 handling of certificates that are selected to emit a distrust warning +// to the console. + +function shouldBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(isDistrust, "This host should be imminently distrusted"); +} + +function shouldNotBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(!isDistrust, "This host should not be imminently distrusted"); +} + +do_get_profile(); + +add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + +add_connection_test( + "imminently-distrusted.example.com", + PRErrorCodeSuccess, + null, + shouldBeImminentlyDistrusted +); + +add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeImminentlyDistrusted +); diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js new file mode 100644 index 0000000000..5bb4b1cecb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js @@ -0,0 +1,138 @@ +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(name, trust) { + let filename = "test_intermediate_basic_usage_constraints/" + name + ".pem"; + addCertFromFile(certdb, filename, trust); +} + +function test_cert_for_usages(certChainNicks, expected_usages) { + let certs = []; + for (let i in certChainNicks) { + let certNick = certChainNicks[i]; + let certPEM = readFile( + do_get_file( + "test_intermediate_basic_usage_constraints/" + certNick + ".pem" + ), + false + ); + certs.push(certdb.constructX509FromBase64(pemToBase64(certPEM))); + } + + let cert = certs[0]; + return asyncTestCertificateUsages(certdb, cert, expected_usages); +} + +add_task(async function() { + let ee_usages = [ + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, + ]; + let ca_usages = [certificateUsageSSLCA]; + let eku_usages = [certificateUsageSSLClient, certificateUsageSSLServer]; + + // Load the ca into mem + let ca_name = "ca"; + load_cert(ca_name, "CTu,CTu,CTu"); + await test_cert_for_usages([ca_name], ca_usages); + + // A certificate with no basicConstraints extension is considered an EE. + await test_cert_for_usages(["int-no-extensions"], ee_usages); + + // int-no-extensions is an EE (see previous case), so no certs can chain to + // it. + await test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], []); + + // a certificate with basicConstraints.cA==false is considered an EE. + await test_cert_for_usages(["int-not-a-ca"], ee_usages); + + // int-not-a-ca is an EE (see previous case), so no certs can chain to it. + await test_cert_for_usages(["ee-int-not-a-ca", "int-not-a-ca"], []); + + // a certificate with basicConstraints.cA==false but with the keyCertSign + // key usage may not act as a CA (it can act like an end-entity). + await test_cert_for_usages(["int-cA-FALSE-asserts-keyCertSign"], ee_usages); + await test_cert_for_usages( + ["ee-int-cA-FALSE-asserts-keyCertSign", "int-cA-FALSE-asserts-keyCertSign"], + [] + ); + + // int-limited-depth has cA==true and a path length constraint of zero. + await test_cert_for_usages(["int-limited-depth"], ca_usages); + + // path length constraints do not affect the ability of a non-CA cert to + // chain to to the CA cert. + await test_cert_for_usages( + ["ee-int-limited-depth", "int-limited-depth"], + ee_usages + ); + + // ca + // int-limited-depth (cA==true, pathLenConstraint==0) + // int-limited-depth-invalid (cA==true) + // + await test_cert_for_usages( + ["int-limited-depth-invalid", "int-limited-depth"], + [] + ); + await test_cert_for_usages( + [ + "ee-int-limited-depth-invalid", + "int-limited-depth-invalid", + "int-limited-depth", + ], + [] + ); + + // int-valid-ku-no-eku has keyCertSign + await test_cert_for_usages(["int-valid-ku-no-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-valid-ku-no-eku", "int-valid-ku-no-eku"], + ee_usages + ); + + // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension + // but the KU extension is missing keyCertSign. Note that mozilla::pkix + // doesn't validate certificates with basicConstraints.Ca==true for non-CA + // uses. + await test_cert_for_usages(["int-bad-ku-no-eku"], []); + await test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], []); + + // int-no-ku-no-eku has basicConstraints.cA==true and no KU extension. + // We treat a missing KU as "any key usage is OK". + await test_cert_for_usages(["int-no-ku-no-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-no-ku-no-eku", "int-no-ku-no-eku"], + ee_usages + ); + + // int-valid-ku-server-eku has basicConstraints.cA==true, keyCertSign in KU, + // and EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-valid-ku-server-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-valid-ku-server-eku", "int-valid-ku-server-eku"], + eku_usages + ); + + // int-bad-ku-server-eku has basicConstraints.cA==true, a KU without + // keyCertSign, and EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-bad-ku-server-eku"], []); + await test_cert_for_usages( + ["ee-int-bad-ku-server-eku", "int-bad-ku-server-eku"], + [] + ); + + // int-bad-ku-server-eku has basicConstraints.cA==true, no KU, and + // EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-no-ku-server-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-no-ku-server-eku", "int-no-ku-server-eku"], + eku_usages + ); +}); diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem new file mode 100644 index 0000000000..a42c7532c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvDCCAaSgAwIBAgIUPbAn5aKDD+kIa7hReaL37pIRoqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBAByxcmVDqkg7zc2gVsSg2E+gTXDjMWp/DvVlbjOQoek1 +eRR6SmEEYQ8yYC4FMemiy2b1BXHkbcu4RlKJ/sr5n3qd+eKF1hSiekl8IAVO46lk +I22qHCs3eRPkhSTXKfUqR8mOqLAMHNwmZ+4/S5xqrnSpq3+8q9o0a/A+osy1aj4K +JNA+/Ey9HyxjOwTeq44JiMWbotqFAtrr4yQO8BVh6Kdskcp81UtRbm2gRjXtbIjO +FSREK358HkIkcOYNT/qNgijwyJpQiWBUJ99dv3dgVXQpm+acsIgjQ8axT6Np+3+0 +f/kIT6Xl/umiMes/Q6auaRjdQMtok9nPTPFtWB0AlsM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec new file mode 100644 index 0000000000..eb7c4b4bee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem new file mode 100644 index 0000000000..b78901e441 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUJb+8nRpsie/LSW/e1iNkPRuYeGswDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWJhZC1rdS1uby1la3UwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LWJhZC1rdS1u +by1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQBOyG/keiC1S06CjERcBFMpKlu4iPclxxZi8kscxlhpCfqUUW/v +8bxR6AV7B5llfxW7fjxP1cx2tUzFMmipC6ShlO2M3Vfc4bxUy2plp0CVtt8099dR +uXcuLxohJNL+hMs2Unt3rC+S4sZUypnWvDXcwCYhrsBZNq7IQ5oXy6m2oMxwHq29 +qUdIIFCmJ/wci6q2EaZttmLD3BW0IuPt7Z14oeAODYnIpnAjCIlPYUNRkFFT/2Tw +cyEQlSeHqAc10dDuc7wLI8UMf0VOkxE5srTd3LPcXzrqBzeURwctZUFrwToE6Xk7 +g8czZIjwInmhjdES2r/iCLAlZX7/bl7tmDDS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..390adf2344 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-bad-ku-no-eku +subject:ee-int-bad-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem new file mode 100644 index 0000000000..4c2423e772 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUY4lZzPdovquC7Mbz72zTaN4o1y4wDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVaW50LWJhZC1rdS1zZXJ2ZXItZWt1MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGVlLWludC1iYWQt +a3Utc2VydmVyLWVrdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gw +DQYJKoZIhvcNAQELBQADggEBAEbel/uwJK/uVtGY33gMAcUi1M7dFeCrxbo51f3M +dWf+qG4rMpZ9Jh9oUAk2OUuhkDfu52Vh4y17hjcPirOxWcy05UutefuEqUTLsiZ/ +Ykg+2RUMLtMPCjMgIv6OxWzwiN7hjuHW3MDmkEkT7YNzJnTE0isLwtd3gKiRILsM +WtQ3AFdR1KK+CUj6pGht+yDYR0kTI7a/1d5fCcdWD6usuIWtJlzGTtA5X9KFaiB+ +40UZs0p5NAVq2jS6W+DMUjHfrH07e94R6cYHM0DFXQLqDJucpeOrBX1Pd6//Jl2h +NtimaXJoTWiUOqclQstkhPrSLtT1GWj9S9MjDmB9G3hsLYc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..32bb6c2485 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-bad-ku-server-eku +subject:ee-int-bad-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem new file mode 100644 index 0000000000..7c670abd58 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUd8ffH/82BvEHZUunrKaA0Zk6FG4wDQYJKoZIhvcNAQEL +BQAwKzEpMCcGA1UEAwwgaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNpZ24w +IhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLjEsMCoGA1UEAwwj +ZWUtaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNpZ24wggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkG +A1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3DQEBCwUAA4IBAQAVF9pewrYN +HHFzPaQg07aY2le/pM3MgH2srjfHC+AZxrz0BeN0HFgmOcE/gnbN0hMPayVld+bh +JvFFiHLTQ8/HyvcmGkHagHdcgjo+5NiD2baBWFPZ49Bj8N6XJyQKCyjF7YkOlpx1 +l6mte8APVgundg2iKXXVljIuJS+g3U6V6p7z5pkW/yU/Xbl+3GKYgPtGe/uIQA1S +3fchFO11b/XWHw4PBQGMRxQKhS+e3Ih1TXJq5SwFp50RotkG/fLLw/q++W42bgcQ +k+Eyww1HtI54wAC6AQyZ66pSkusk5OuQbs+dV83k5WEUnLFexImKUNIItCvM/2qq +rEfSyd/jN5A8 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec new file mode 100644 index 0000000000..9e0fb65fd6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-cA-FALSE-asserts-keyCertSign +subject:ee-int-cA-FALSE-asserts-keyCertSign +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem new file mode 100644 index 0000000000..53160a7800 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgIUPzIc4Q/DpFWUx8qcM7GOe4M/RF0wDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWxpbWl0ZWQtZGVwdGgtaW52YWxpZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAnMSUwIwYDVQQDDBxlZS1pbnQt +bGltaXRlZC1kZXB0aC1pbnZhbGlkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1Ud +DwQEAwID+DANBgkqhkiG9w0BAQsFAAOCAQEAil4HrKZ8ZItNn8riFIoViEPt1aif +ATej/kVDhGRNOqqXIuR1+blS8VTbmKB4YA+HxyG4d2g4fZLPNbqRrNdFDIwRI08h +EPk0ScoS+xBks5MS6EVqy507nR1XYHXRMjr9xD1L+hhMr+I42gFNDOm6BUfY2eb1 +11BttnNXk3PSakwAkt3sg8aZFLrZs1eW0EPjdbdmJPNV52ToUo0exydabJDrrFl1 +t2QJZCoz9MR+N/QPZkxpvOxjzmOCEFVHU8I4FIH2ddJVacg9LOZgh4CdLson8ug7 +mehOK8yk+QnfjoC0hlXi4FJdsNQFSL6SiCzuFlxk5AGs08pEfZQ75CvfIQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec new file mode 100644 index 0000000000..f00b4d1591 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-limited-depth-invalid +subject:ee-int-limited-depth-invalid +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem new file mode 100644 index 0000000000..d109bcd492 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUV/tRlNSDvu7BruxM6b8StzTZACUwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LWxpbWl0ZWQt +ZGVwdGgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQATRYSRBITskOkSFUKBg9DCA4bHR63pNBlEwb4L+aJYZnSdd2kc +Cgz0x5GdoVdETz878x9O9yvNESspoASqwiobxFHsbWeW0h6eqt3LoVFI3Njt8OaG +1kxynlyBvx3Q8E/b6ZT0hAbhum8GLqTxE10PZecvOjfDgNovCIhHk4PXpeXZNKo+ +p1yaXB4brxwVBEhv8iSBXnT60bt7vbqbJWCE2ASF2bgXTuARX1onkJz5+LWuGSF1 +ng9glpgB10r2XmOb52Hdlb9K1P4MM+Nofsb5XZ5WgdSEQnBb1b3pHLAwHXkNto3T +E2AqOkV105ic8bkKGIMi/oCd06R0gZ7QO/u2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec new file mode 100644 index 0000000000..df85342d98 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-limited-depth +subject:ee-int-limited-depth +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem new file mode 100644 index 0000000000..9bfb1203c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUX0rT0GAv2W7gbUOUYEYetQADH1wwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LW5vLWV4dGVuc2lvbnMwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LW5vLWV4dGVu +c2lvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQAw74cGcE+TWUij1up8e6PZJpTX5JHgpYmtZcSVKR7gFKlfLxg0 +6oB6JKkN7EIfJ85FnG0vYu0yFAHZG2bZJrqE3vUCAkRe2Q3Q39g1CBrlTkNy13pm +U41KqojfAGCGR6iS0pjDbDqu5bIpPh/sX9bmiLBq3nv+xIHYNdRU36KaRAdJ9l6+ +VAjq1b7WvPN7mF0rWN5C35pqxXu50i2gejOxlsxM2hUEODCCZoAKAweSVO3qKGCv +093AQ/WiHpvSjvMdFO0aA+WvnIya7KRYI1lpERJltIJPBS2CNgkKOnKonGgVpBoh +nZm+5PMjIiDU/cIrgXU3DzY9hAXmlwuCOAzL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec new file mode 100644 index 0000000000..c5279046d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-extensions +subject:ee-int-no-extensions +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem new file mode 100644 index 0000000000..2087990cc3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUcw4XUsGVtCZtRXKmHHReaOglg8kwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LW5vLWt1LW5vLWVrdTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1pbnQtbm8ta3Utbm8t +ZWt1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DANBgkqhkiG9w0B +AQsFAAOCAQEAG2jH13dTldiSOyQAtgKNJ8kv7zVK278ge0Dcihn5B1Q4JWgPCRn8 +d/RDDVajlBo3fIkQwlAnGU4YjSKDnjpSZoiU/qVmW7TGUZxY61nijgqgNMGBVO1z +/81w17YNSHI1r6TEFAYo/NNRDCBpR4J+u3tKgQ8ZKWUv7ZdJbhHTPD+LwcoY8G07 +s9QgXisyB1KTofQAvWb4p+arjtjciTPfLg0QIf6dXOowg1+29IaGimnpb2P7yKB8 ++Drg3VL+lnhDhDrTsS+VVbP7YRfI3nzTXmRTObukb9HCuT7AXacw0GbJvcNh7rFX +2LPgZelDL5Xy/+l0osIbklL+fkcRb41xcA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..92ee3cc6d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-ku-no-eku +subject:ee-int-no-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem new file mode 100644 index 0000000000..4ee9fa145b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUSydkZNHcPpeuo7P9vZIuqBGKd6YwDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUaW50LW5vLWt1LXNlcnZlci1la3UwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowIjEgMB4GA1UEAwwXZWUtaW50LW5vLWt1 +LXNlcnZlci1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0G +CSqGSIb3DQEBCwUAA4IBAQBUaqs/EWro+OEULUWHRLBiLJCi1gA9tAHdxpisa0uT +/tyodyY4L1xbgQWwlA13R5AjaVn1RfDnPAn6o1q/Xqbf53CGmyOCDkxTSXZifJbJ +D4/4xF6ewsNPnERMkTjzBcrchIh8EbppoS9Bd1L3RVq1s6GOU6gVTF2BAXfpIwZo +9bqTBc+DrCbT8+PoaZY8UJl4M7oy11Ye/GbwNd2Gm0TZU2zWdi2tsVTb82nr9wET +BgDrwM63AdrrUQCaUC2I+vlOhuxWWboLl+W4XME22A+5t3S/+DBYyM8vf2S0SLyd +h7NX2YzfBY9WI0r/rMJ0ubH7mbk1hypPjldbsygel/vw +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..c148896710 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-ku-server-eku +subject:ee-int-no-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem new file mode 100644 index 0000000000..2392d94115 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUUQAgWvrw7svP/y7EUHKfSCcVkjMwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LW5vdC1hLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD2VlLWludC1ub3QtYS1jYTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwDQYJKoZIhvcNAQELBQADggEB +AAB8UNQ3JeAdPqtNhn1VFnZZzpLYcUGq1c+C8nQEOCmvy8s+QmdKsCKaO449t0fM +Q8JyMuuH/ObHE54YzSEg/FWNrnO6hzTf05k8bxoUsFutL+xXvsLa7VGftz0VL2IC +8xlYMvGDIZ3TGdU8B9D0B72Usn3nZvf+vbm/wZ5Wj3Bl//Fk8eqcosGJ6j5cQ1Bk +DUQceGm6pRYtBERqkOPct9G+FOrd51tZ0+vTelJKC8v3OfK8pGwYqSjonhI146bp +djCKAZsU9KynW1BZ61E0iU+D8/8F1ELi4SxTQtHeOWBkYq31mYnZO2ze3XYAE78C +kkbfT9Qy0fIb9EpNn9FqOtU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec new file mode 100644 index 0000000000..a95b0dc260 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-not-a-ca +subject:ee-int-not-a-ca +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem new file mode 100644 index 0000000000..c30fbe0dc2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUFTa2zYscnDR5ILK/7lqO+cxtDUcwDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTaW50LXZhbGlkLWt1LW5vLWVrdTAiGA8yMDE5MTEyODAw +MDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZlZS1pbnQtdmFsaWQt +a3Utbm8tZWt1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DANBgkq +hkiG9w0BAQsFAAOCAQEAmTBGZeCTRdr342Ff+rQuMiGwBl9prO45VGzGcb+QPQVF +w1bubYX7lk9UlKNZZE4ZB8nBFDSNf7kMLn8T6MI8YYihOrUF1KxGCKmWgcSttmg0 +kZS02nrd+yVe+iYaWEK/VN8jQkyUyM5u8MJK0k0EEnljjnNs168I/pAWgcNf1zls +1S9D3azqB0MFHe1CQzRtK6iOjE2deZHyYBb6T1uH3Gm2nm5kkpRgJ9mPGbccJS7p +q903lUvxT7fmAj0ixaDABMggEU/hLNxNrCiV3XhxpNalNnBc1UiGJiPZBkHdSlAl +nA0Ov7XuvCDmty7h8vWyUfZo0gchx43WTZImokBz8g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..89a66b9f97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-valid-ku-no-eku +subject:ee-int-valid-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem new file mode 100644 index 0000000000..5c10a70b41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUR3XzgtGCKrGxY8HRXSHlPF7GxWUwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXaW50LXZhbGlkLWt1LXNlcnZlci1la3UwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowJTEjMCEGA1UEAwwaZWUtaW50LXZh +bGlkLWt1LXNlcnZlci1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQD +AgP4MA0GCSqGSIb3DQEBCwUAA4IBAQBE2wXCNaiIiuKCv3PV/jHaYR1VDcc6Ypsp +GrClISVncIlQ+vav7bRCBfNvog8YycfP/roevVWvvoBwryoHWBNj/g6N3Skrn3+P +510oo0GDJrh/X6ITRk3uqu+6DIGtK4FJ3IcKL51zJpyuOi/YbH9m3RC5zb74EdNJ +pT1AVdLkwn5JxKNQ+ydXuIskYtvyNQt1xcv3k/HgqBKx3A14MsKBfuMoJBkifxVh +EPgX4Q5rrSb9Ztdmhux13UsVvt2ECuF2MGW8E/VgKh/XcXBh2WNZ6xNIiPTBM6S8 +RGefE1lVOeVlH5a5h43mI09JWxISQr0wTFvaHrJhWgQ1gsIRgwFj +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..43e83a336e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-valid-ku-server-eku +subject:ee-int-valid-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem new file mode 100644 index 0000000000..b41eb0ef1b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2DCCAcCgAwIBAgIUZzy02i7tvAs/6RTdJfLYIt87D9cwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LWJhZC1rdS1uby1la3UwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwG +A1UdEwQFMAMBAf8wCwYDVR0PBAQDAgH6MA0GCSqGSIb3DQEBCwUAA4IBAQAAHnJc +VICzmnlR5N8AZlWrRHq3cye+ScZEQUXZRwxg3nLPIDwoNu0bgVAcoY2slrQEQ3d6 +Jq5UyBh6E6gjy0p3dVXO5bVlTTfdpoN3TmLUNERAqCyqRUw+tZUqqqOeLi8CT3jI +JlW8usKSP4NaFZODWifLPQQ2DeQoBZbn6Em7YwalGqnA3Izb8zmMxPWZrwgWmYEa +PG50Q3oh9j2dnkR4EOU0saT+gen86NwbvHZLSyAiIGH9/IJw9b5YvetZNRQ+wVuQ +U7im69QqlZSTeDLq80YA2CCcVL617oKB+H+ChquMwnmTvviO2qnM7WcZK0Zqy9F3 +LpP0Hmpv067ExIdk +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..f6525449b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-bad-ku-no-eku +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem new file mode 100644 index 0000000000..3bd7dea894 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgIUT+TsShZ32vzo05KpLbrZpGyUbCkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowIDEeMBwGA1UEAwwVaW50LWJhZC1rdS1zZXJ2ZXItZWt1MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozww +OjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB+jAdBgNVHSUEFjAUBggrBgEFBQcD +AQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBADETpYdt9P1ael7B2UilTCIu +zaXfSBUZHAKidpNMENdqcYJScyLTrUSOsbHKzignTCoDN3NHVd7o/YJmV457yRKl +nvtBaJQFd/9ycLtEiiksxvca1Zp7QfIeRRzspW23/n+bPa6CYEudbIp5KTzgi0uL +1bEg52LoEM+ikrpT1QdgQ+q+v1Ao/BaybTumC+7nC3jvGj4itLsYTIskaacWEf/K +WSFZ/K6cWIgKS5iEI+fAhx2IyJp4kK1jdIvmvtCiOG61r2f4GkxDkrQ5I2lvLEPF +wS+S3scFNprbybPOpI7GAqSsewHWu+Ge81G2M+Z1ndBH9oV7qWhVlpvf2U/yXvg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..2d324508d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-bad-ku-server-eku +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem new file mode 100644 index 0000000000..efc707bb5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIUWz8ZXOO6fSSbmQau3JwsY5zTrDMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKzEpMCcGA1UEAwwgaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNp +Z24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgH+MA0GCSqGSIb3DQEB +CwUAA4IBAQCv+2MLK5Sm5TWC9WmEbavSz9bW315LIy/09r6NFaCQksbZzZ01b0n7 +jsuq6ZIhVfaMepUF1Fc7K5avfCzyJlPiOGsm9SmfT4XFIX5Ugu5mEAGva8jYDeOn +3ie/VzwvQRPmb7fIDQ/in5siiQ3OcL3f7KaOZQM/zP34pxh2C2oZYz+xu/byaLhb +qPXoTM8wnqVeNP7wqZDmv7ZZFXDT0dEKqCRs+G3YzPmfk/9tBokFla7jrrtG1vHt +vWXmeRfJPzJq+bDDJo9BmzHjPWYTYajfDFTOs24AbNacZdyNdNnRLgXqKIn5slk7 +F2mjSU/KIeiQB9nGxC/nfqe1uAR5MdtY +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec new file mode 100644 index 0000000000..39785d8a48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-cA-FALSE-asserts-keyCertSign +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem new file mode 100644 index 0000000000..5eaf98add4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIULycRMzIhSjpkHsE2X111MeoH++4wDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowJDEiMCAGA1UEAwwZaW50LWxpbWl0ZWQtZGVw +dGgtaW52YWxpZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAQEAQ20RfnhWErcr9Bvu6mjwrmB7WGXO+vvwODj2IeG+r9y+25ZClHYp/87p +dKUknyhmQ7O+lgKDp+lzNFkt92JaEW2im1gBPFN/ZZi/WCOS6y+s3r/2Ji/+6BHr +R+SXvrizmpyNEzlAHOiG6bKv4UuECM4kK656tJmH+dH0sGiYSdmhf9lwM1m6X3r6 +kTToN0G8rUJc6hS3WuVRoKNrtBZxq7f0Z+lcBtnnCH7PQc94Sm06bauo1WBGE0E+ +1CXmL8M/22hDDfyI1Ve0NMmrK1YGRCY3YD+A9dCnc6zM60YtXAXhsGA8Mh8mdIfV +8y8gFBiMrWlNnWB/AC4bea8HBguxqA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec new file mode 100644 index 0000000000..9fdb2a248a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-limited-depth +subject:int-limited-depth-invalid +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem new file mode 100644 index 0000000000..39c00d26ce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUcylHQcmSUhRsK5erE0SNaPg0+okwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEzARMA8G +A1UdEwQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggEBAHHwYSdzz1ScKu0ShKs/ +9CVPkIuGIYrMpyBYCarzkQOs+bQIV91JPpoUt2W6enHixZ54M8bdACKYC3CnBiYe +wbPcZP0thQB7Sd5yHI3uNT8JSvinVv2EXcCNlZSei2Y+agc8d/9KMYvBYMG7SMHX +Egp5L4xrwkKrWOQ88DnokFMHf650Ddq5A1b1NFBHAjkRIQGhjRnwlxuVGf1cAle+ +C6tDK7ptHQM5CtAEdzGmf51MoErFRH0RCxJmUcbGnHTiq7HBMWw6Q/8PMTUsndS6 +W9igwATnCJqLpynZ0SvaETMa42JFJ+goSOYKVZTy2/uhvRlW81ZaR2E3lqj4W6jB +Svc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec new file mode 100644 index 0000000000..64f54b0441 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-limited-depth +extension:basicConstraints:cA,0 diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem new file mode 100644 index 0000000000..90a2f26b95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuTCCAaGgAwIBAgIUYcfJhXqUXKOGw+E5MNKdPih6hZ8wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LW5vLWV4dGVuc2lvbnMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAI7R3HB8uiokTZA8E4dciZE6IQXm+cwTwwC41KXk8gKwIdXN +wuJiYmpFJS+ckS2azp8prxw9oGk1rv5V3v1b3yQ1js1MAEOcGlhFG02OMoEegOVe +RI5p1WN0A6S8sf4HwvbyxBWgM0J+uFez+GKpX2X/UVGtG+YI9yZ0x5BGdUsdKbvS +KJVgYmAjOg9wfl2vM71mfzMTVSHk7Nva7c0qjC3tNtGpILWrZH9tyccdJqSRTZzO +Xge+BUCe5hiTpT+sAGij6ESR1QBe1F8U2QmQRUhy3K2s43JFxWu5gep0XBY/p6kR +6EXpbTn9mWFuRg7nLEcOwYtbAXA1mNtH9QXw6PE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec new file mode 100644 index 0000000000..c99626bd5a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:int-no-extensions diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem new file mode 100644 index 0000000000..00f1d1ddfe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUQXSt+CjpOfyWdZcfjuLpGReDI5QwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LW5vLWt1LW5vLWVrdTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYD +VR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEASpnks6qV+XZPFh2HPqCPcm9H +M4zZafwvx+OvwALtsu3goai06A2z2lWt/uGDNa773kkQI8rRBieuwjk7mUgAZFhm +HbcGmVaih01VYVrPzr5iKhoY0p3RVDxtPJusy8OXv4+jPEpQ8SnIUIPzpoSUhpA4 +ejH/rZNOUuKnz5aI01mmAq2Q0eUlQLFvjJPy4qfJ7R2vuhDi7T/Op3Fbd78a1A2I +/411XZ7rpjbh2tJVHI71kpaHGXGeppciYxPwjRG+hlebKFD9NVXldCcvVzy8DNzu +FjCMqGOsHm87uu6R6ZDekW+Zxy30Ui2qW74b06nxlxphHgO0LglFhwwKVhs3Dw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..306a218db9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-no-ku-no-eku +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem new file mode 100644 index 0000000000..e2c2941f73 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUe0/iqtgXpUCqSBbTkk3j6cHrF40wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHzEdMBsGA1UEAwwUaW50LW5vLWt1LXNlcnZlci1la3UwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAt +MAwGA1UdEwQFMAMBAf8wHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0G +CSqGSIb3DQEBCwUAA4IBAQA66A/sfTMBP0yPBfI4TtxMv1Af0gpOchsekkY4lUxg +IgsSvqjrlW/r7oBVpucIqH03wlHZkoiY+rl2hokh5fVNmztaBSaSQSdzrwW7qpsS +0OFmUmPPcV4Kjy4EaaFXk2diNP/xCENwci6CN6iVvTrHt1Nu5DVEAbEwQVjN2Lme +f1prvxAcqkyoJqHNQyS5nr31Bc4OdBFEJJ4ZjMvJV0UfRH0fkwhutIW4kgYgHp6o +6BVpnDyqEN0yZaNHIQ8VP1hl+gSoHYmhX6BuF6vI739ACKlZXMCtGEEOi0o/oZb8 +GMUgv22QZFC5JMiWwhbcN6LJC5XpGEl9X/FwDndrv2JZ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..1482b627c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-no-ku-server-eku +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem new file mode 100644 index 0000000000..9857f050c3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAaugAwIBAgIULcyFCPC5AqS4vb2uiw2vfP5d52swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LW5vdC1hLWNhMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNVHRME +AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAib9DQGbyyJ/RSZet5VQiZ/1WLmOZNDU63 +1tmavPbUWtoV6ac2nvObfMBxiMfog51CyS9kys9umj5i4wBOFc07ADPnZvZ4JzCH +DMJqe83Q9DNMRqiUFgoioLmZM4+t6gOFdfv0Hcm1/dPrT7PAX/68aa2OP95vPrec +LTKHirbpV9BxgH2ZFWmiI/iMYlEJpb9BcJfpAV9VzmOAoXwuP87qqxdWUhMuE3V/ +Jopnz32iH/j6HEsmhG5cixmiDOoVcuKo0EpsZSAV6QjQJWZ0KYBfnFwqSkaNLAzd +Tsql/80wHPgrlb5G0na1VWqfzijcWrMM9GwYu2nliE0b8Erl70Wc +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec new file mode 100644 index 0000000000..3161680b1c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-not-a-ca +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem new file mode 100644 index 0000000000..b426d19e30 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2jCCAcKgAwIBAgIUAQgTd7cj4mynq7/pBIjhOMglEsUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHjEcMBoGA1UEAwwTaW50LXZhbGlkLWt1LW5vLWVrdTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBsw +DAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAI+T +Z5fdjBIEKwA7tLJHWAkXLYYX2/NIjc3ZS5J1+LMpQXA+Rmw7T8zZ5Tecf7wvHJNd +qsjNFkOx9IkV3tiGPsv7J3B53Kk5qJ1LR3sNj99YW6zs0SpETYbVc0IY49ZP8eOA +BMS6eGrkSYgXXTWN6fu83gr+/QB6vCri8xkOw7NM0gnfoZhOAXmKkWILW3S1Arj0 +E6FpW88Pww6miceSa8ecdc4QL8qRIFKDZTXCIwykjeOLZgw3JTOr0YYGO0uBjspj +ASheUaiNfEGbLIU+PySMvgX3RRheSDMIxeoKCL8Wg5nyIg/6yE5vXipiTexqk9rR +0z/z588qvYn2g5AqUB0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..d7f9b0387a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-valid-ku-no-eku +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem new file mode 100644 index 0000000000..834ea6ef65 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUWWZayMVWHspFSBkAYaO7s8p84NAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowIjEgMB4GA1UEAwwXaW50LXZhbGlkLWt1LXNlcnZlci1la3UwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +PDA6MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgIEMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAud9bDsVnUs48CsoNie24 +ZnxZPn6RJe6JjZUDdAYwVVYVzJz4UqZF2kwwjXm0Dzs758WdbqgP22bBrs6sZZBI +39Rw74d2apnh8PpVzrsKVQSQqh8RAk38c6MDDRhYo859sTW2/Lvyo2PHr4wIR2jH ++awmkP3EEq7c1kt23q2c0u+rxKR20pYjJJ0br92b/buiOfjdA9q0pF/rRdm6/U4L +ApUHYzyXiuEoekLbLf5tIL3Xel/OkaD7jBrrEWll/vWj+RBI4B33LViDJ9lMjavP +KJHDM7PbzM1XKogapqmfqxYXzyY+ZtxurIXTkyWuuNfINd+OMOzRkvwDYkATNEGD +OQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..84314bfa40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-valid-ku-server-eku +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build new file mode 100644 index 0000000000..e2b0dd7599 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build @@ -0,0 +1,35 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee-int-bad-ku-no-eku.pem', +# 'ee-int-bad-ku-server-eku.pem', +# 'ee-int-cA-FALSE-asserts-keyCertSign.pem', +# 'ee-int-limited-depth.pem', +# 'ee-int-limited-depth-invalid.pem', +# 'ee-int-no-extensions.pem', +# 'ee-int-no-ku-no-eku.pem', +# 'ee-int-no-ku-server-eku.pem', +# 'ee-int-not-a-ca.pem', +# 'ee-int-valid-ku-no-eku.pem', +# 'ee-int-valid-ku-server-eku.pem', +# 'int-bad-ku-no-eku.pem', +# 'int-bad-ku-server-eku.pem', +# 'int-cA-FALSE-asserts-keyCertSign.pem', +# 'int-limited-depth.pem', +# 'int-limited-depth-invalid.pem', +# 'int-no-extensions.pem', +# 'int-no-ku-no-eku.pem', +# 'int-no-ku-server-eku.pem', +# 'int-not-a-ca.pem', +# 'int-valid-ku-no-eku.pem', +# 'int-valid-ku-server-eku.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads.js b/security/manager/ssl/tests/unit/test_intermediate_preloads.js new file mode 100644 index 0000000000..1f8b289eb3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads.js @@ -0,0 +1,645 @@ +// -*- 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"; +do_get_profile(); // must be called before getting nsIX509CertDB + +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); +const { TelemetryTestUtils } = ChromeUtils.import( + "resource://testing-common/TelemetryTestUtils.jsm" +); +const { IntermediatePreloadsClient } = RemoteSecuritySettings.init(); + +let server; + +let intermediate1Data; +let intermediate2Data; + +const INTERMEDIATES_DL_PER_POLL_PREF = + "security.remote_settings.intermediates.downloads_per_poll"; +const INTERMEDIATES_ENABLED_PREF = + "security.remote_settings.intermediates.enabled"; + +function getHashCommon(aStr, useBase64) { + let hasher = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hasher.init(Ci.nsICryptoHash.SHA256); + let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + stringStream.data = aStr; + hasher.updateFromStream(stringStream, -1); + + return hasher.finish(useBase64); +} + +// Get a hexified SHA-256 hash of the given string. +function getHash(aStr) { + return hexify(getHashCommon(aStr, false)); +} + +function countTelemetryReports(histogram) { + let count = 0; + for (let x in histogram.values) { + count += histogram.values[x]; + } + return count; +} + +function clearTelemetry() { + Services.telemetry.getHistogramById("INTERMEDIATE_PRELOADING_ERRORS").clear(); + Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_UPDATE_TIME_MS") + .clear(); + Services.telemetry.clearScalars(); +} + +function getSubjectBytes(certDERString) { + let bytes = stringToArray(certDERString); + let cert = new X509.Certificate(); + cert.parse(bytes); + return arrayToString(cert.tbsCertificate.subject._der._bytes); +} + +function getSPKIBytes(certDERString) { + let bytes = stringToArray(certDERString); + let cert = new X509.Certificate(); + cert.parse(bytes); + return arrayToString(cert.tbsCertificate.subjectPublicKeyInfo._der._bytes); +} + +/** + * Simulate a Remote Settings synchronization by filling up the + * local data with fake records. + * + * @param {*} filenames List of pem files for which we will create + * records. + * @param {*} options Options for records to generate. + */ +async function syncAndDownload(filenames, options = {}) { + const { + hashFunc = getHash, + lengthFunc = arr => arr.length, + clear = true, + } = options; + + const localDB = await IntermediatePreloadsClient.client.db; + if (clear) { + await localDB.clear(); + } + + let count = 1; + for (const filename of filenames) { + const file = do_get_file(`test_intermediate_preloads/${filename}`); + const certBytes = readFile(file); + const certDERBytes = atob(pemToBase64(certBytes)); + + const record = { + details: { + who: "", + why: "", + name: "", + created: "", + }, + derHash: getHashCommon(certDERBytes, true), + subject: "", + subjectDN: btoa(getSubjectBytes(certDERBytes)), + attachment: { + hash: hashFunc(certBytes), + size: lengthFunc(certBytes), + filename: `intermediate certificate #${count}.pem`, + location: `security-state-workspace/intermediates/${filename}`, + mimetype: "application/x-pem-file", + }, + whitelist: false, + pubKeyHash: getHashCommon(getSPKIBytes(certDERBytes), true), + crlite_enrolled: true, + }; + + await localDB.create(record); + count++; + } + // This promise will wait for the end of downloading. + const updatedPromise = TestUtils.topicObserved( + "remote-security-settings:intermediates-updated" + ); + // Simulate polling for changes, trigger the download of attachments. + Services.obs.notifyObservers(null, "remote-settings:changes-poll-end"); + const results = await updatedPromise; + return results[1]; // topicObserved gives back a 2-array +} + +/** + * Return the list of records whose attachment was downloaded. + */ +async function locallyDownloaded() { + return IntermediatePreloadsClient.client.get({ + filters: { cert_import_complete: true }, + syncIfEmpty: false, + }); +} + +add_task(async function test_preload_empty() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + equal( + await syncAndDownload([]), + "success", + "Preloading update should have run" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should have been no downloads" + ); + + // check that ee cert 1 is unknown + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_disabled() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, false); + + equal( + await syncAndDownload(["int.pem"]), + "disabled", + "Preloading update should not have run" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should have been no downloads" + ); +}); + +add_task(async function test_preload_invalid_hash() { + // Enable the collection (during test) for all products so even products + // that don't collect the data will be able to run the test without failure. + Services.prefs.setBoolPref( + "toolkit.telemetry.testing.overrideProductsCheck", + true + ); + + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + const invalidHash = + "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"; + + clearTelemetry(); + + const result = await syncAndDownload(["int.pem"], { + hashFunc: () => invalidHash, + }); + equal(result, "success", "Preloading update should have run"); + + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + + equal( + countTelemetryReports(errors_histogram), + 1, + "There should be one error report" + ); + equal( + errors_histogram.values[7], + 1, + "There should be one invalid hash error" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should be no local entry" + ); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // We should still have a missing intermediate. + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_invalid_length() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + clearTelemetry(); + + const result = await syncAndDownload(["int.pem"], { + lengthFunc: () => 42, + }); + equal(result, "success", "Preloading update should have run"); + + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + + equal( + countTelemetryReports(errors_histogram), + 1, + "There should be only one error report" + ); + equal( + errors_histogram.values[7], + 1, + "There should be one invalid content hash error" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should be no local entry" + ); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // We should still have a missing intermediate. + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_basic() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // load the second end entity, ignore both intermediate and root + let ee_cert_2 = constructCertFromFile("test_intermediate_preloads/ee2.pem"); + notEqual(ee_cert_2, null, "EE cert 2 should have successfully loaded"); + + // check that the missing intermediate causes an unknown issuer error, as + // expected, in both cases + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certDB, + ee_cert_2, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let intermediateBytes = readFile( + do_get_file("test_intermediate_preloads/int.pem") + ); + let intermediateDERBytes = atob(pemToBase64(intermediateBytes)); + let intermediateCert = new X509.Certificate(); + intermediateCert.parse(stringToArray(intermediateDERBytes)); + let crliteStateBefore = certStorage.getCRLiteState( + intermediateCert.tbsCertificate.subject._der._bytes, + intermediateCert.tbsCertificate.subjectPublicKeyInfo._der._bytes + ); + equal( + crliteStateBefore, + Ci.nsICertStorage.STATE_UNSET, + "crlite state should be unset before" + ); + + const result = await syncAndDownload(["int.pem", "int2.pem"]); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + // check that ee cert 1 verifies now the update has happened and there is + // an intermediate + + // First verify by connecting to a server that uses that end-entity + // certificate but doesn't send the intermediate. + await asyncStartTLSTestServer( + "BadCertAndPinningServer", + "test_intermediate_preloads" + ); + // This ensures the test server doesn't include the intermediate in the + // handshake. + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("test_intermediate_preloads"); + Assert.ok(certDir.exists(), "test_intermediate_preloads should exist"); + let args = ["-D", "-n", "int"]; + // If the certdb is cached from a previous run, the intermediate will have + // already been deleted, so this may "fail". + run_certutil_on_directory(certDir.path, args, false); + let certsCachedPromise = TestUtils.topicObserved( + "psm:intermediate-certs-cached" + ); + await asyncConnectTo("ee.example.com", PRErrorCodeSuccess); + let subjectAndData = await certsCachedPromise; + Assert.equal(subjectAndData.length, 2, "expecting [subject, data]"); + // Since the intermediate is preloaded, we don't save it to the profile's + // certdb. + Assert.equal(subjectAndData[1], "0", `expecting "0" certs imported`); + + await checkCertErrorGeneric( + certDB, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + + let localDB = await IntermediatePreloadsClient.client.db; + let data = await localDB.list(); + ok(data.length > 0, "should have some entries"); + // simulate a sync (syncAndDownload doesn't actually... sync.) + await IntermediatePreloadsClient.client.emit("sync", { + data: { + current: data, + created: data, + deleted: [], + updated: [], + }, + }); + + let crliteStateAfter = certStorage.getCRLiteState( + intermediateCert.tbsCertificate.subject._der._bytes, + intermediateCert.tbsCertificate.subjectPublicKeyInfo._der._bytes + ); + equal( + crliteStateAfter, + Ci.nsICertStorage.STATE_ENFORCE, + "crlite state should be set after" + ); + + // check that ee cert 2 does not verify - since we don't know the issuer of + // this certificate + await checkCertErrorGeneric( + certDB, + ee_cert_2, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_200() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + const files = []; + for (let i = 0; i < 200; i++) { + files.push(["int.pem", "int2.pem"][i % 2]); + } + + clearTelemetry(); + + let result = await syncAndDownload(files); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 100, + "There should have been only 100 downloaded" + ); + + const scalars = TelemetryTestUtils.getProcessScalars("parent"); + TelemetryTestUtils.assertScalar( + scalars, + "security.intermediate_preloading_num_preloaded", + 100, + "Should have preloaded 100 certs" + ); + TelemetryTestUtils.assertScalar( + scalars, + "security.intermediate_preloading_num_pending", + 100, + "Should report 100 pending" + ); + + let time_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_UPDATE_TIME_MS") + .snapshot(); + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + equal(countTelemetryReports(time_histogram), 1, "Should report time once"); + equal( + countTelemetryReports(errors_histogram), + 0, + "There should be no error reports" + ); + + // Re-run + result = await syncAndDownload([], { clear: false }); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 200, + "There should have been 200 downloaded" + ); +}); + +add_task(async function test_delete() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let syncResult = await syncAndDownload(["int.pem", "int2.pem"]); + equal(syncResult, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + let localDB = await IntermediatePreloadsClient.client.db; + let data = await localDB.list(); + ok(data.length > 0, "should have some entries"); + let subject = data[0].subjectDN; + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let resultsBefore = certStorage.findCertsBySubject( + stringToArray(atob(subject)) + ); + equal( + resultsBefore.length, + 1, + "should find the intermediate in cert storage before" + ); + // simulate a sync where we deleted the entry + await IntermediatePreloadsClient.client.emit("sync", { + data: { + current: [], + created: [], + deleted: [data[0]], + updated: [], + }, + }); + let resultsAfter = certStorage.findCertsBySubject( + stringToArray(atob(subject)) + ); + equal( + resultsAfter.length, + 0, + "shouldn't find intermediate in cert storage now" + ); +}); + +function findCertByCommonName(certDB, commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +add_task(async function test_healer() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + // Add an intermediate as if it had previously been cached. + addCertFromFile(certDB, "test_intermediate_preloads/int.pem", ",,"); + // Add an intermediate with non-default trust settings as if it had been added by the user. + addCertFromFile(certDB, "test_intermediate_preloads/int2.pem", "CTu,,"); + + let syncResult = await syncAndDownload(["int.pem", "int2.pem"]); + equal(syncResult, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + let healerRanPromise = TestUtils.topicObserved( + "psm:intermediate-preloading-healer-ran" + ); + Services.prefs.setIntPref( + "security.intermediate_preloading_healer.timer_interval_ms", + 500 + ); + Services.prefs.setBoolPref( + "security.intermediate_preloading_healer.enabled", + true + ); + await healerRanPromise; + Services.prefs.setBoolPref( + "security.intermediate_preloading_healer.enabled", + false + ); + + let intermediate = findCertByCommonName( + certDB, + "intermediate-preloading-intermediate" + ); + equal(intermediate, null, "should not find intermediate in NSS"); + let intermediate2 = findCertByCommonName( + certDB, + "intermediate-preloading-intermediate2" + ); + notEqual(intermediate2, null, "should find second intermediate in NSS"); +}); + +function run_test() { + server = new HttpServer(); + server.start(-1); + registerCleanupFunction(() => server.stop(() => {})); + + server.registerDirectory( + "/cdn/security-state-workspace/intermediates/", + do_get_file("test_intermediate_preloads") + ); + + server.registerPathHandler("/v1/", (request, response) => { + response.write( + JSON.stringify({ + capabilities: { + attachments: { + base_url: `http://localhost:${server.identity.primaryPort}/cdn/`, + }, + }, + }) + ); + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.setStatusLine(null, 200, "OK"); + }); + + Services.prefs.setCharPref( + "services.settings.server", + `http://localhost:${server.identity.primaryPort}/v1` + ); + + Services.prefs.setCharPref("browser.policies.loglevel", "debug"); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem new file mode 100644 index 0000000000..680b068f34 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+TCCAeGgAwIBAgIUN/Y56TvJcL2liqk2Feh/QfKrlLwwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EwIhgPMjAx +MDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowJTEjMCEGA1UEAwwaaW50ZXJt +ZWRpYXRlLXByZWxvYWRpbmctY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBSPwr2BfSHT3saxwx6YGEautZx +w/sdM9AJAubFLqDd3MYHtzCZcQXaeDGbAzvo8m/PKA4Yt+UYbKyDnRR8sLA4f/iu +z1zHeenlzBWpRVHu/++ZSk/ESwn0zLprIsOcXjaYkbfrqcEGNWvLJzpT4T36Gr9t +DvxHnpsaMsJviZS3WHzTSoioWkcRyF78bYa51ZJWYJHFKZQppqhJ+jcoJhiomRlc +WwhI8NAU3dOOFJuEg/z+vQpcEQi0rRW9J6X/15BUZRQlF5Hs2wilGa8ViNX2+B5I +kjbmNrdT5hcnGEfR7JpHFuihFdxQc4CFY87u1chI8yaHLhhriUP6Jq0+J5ur +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec new file mode 100644 index 0000000000..4ccabc25b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:intermediate-preloading-ca +subject:intermediate-preloading-ca +validity:20100101-20500101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem new file mode 100644 index 0000000000..1838ab40e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIUTw97bCabpmjf11gbMSrUIZkrl30wDQYJKoZIhvcNAQEL +BQAwLzEtMCsGA1UEAwwkaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRp +YXRlMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBkxFzAVBgNV +BAMMDmVlLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozIwMDATBgNVHSUEDDAKBggrBgEFBQcD +ATAZBgNVHREEEjAQgg5lZS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA +J7Ff5mE6qJuS+kszRFBNnD2OBj0ss6mrayQCqqJqeM01JHRFJ295iDvxHMbtzfYH +EMSytow8dZ8vWoxPSDSr3TV8kJOYYKXjW5ClYi6rWwHt6aC9zPTQ87AspBBKhf3q +2jX+fPoLIKzauktAnzYApvyTTe8fNE/LfLHpDpR2ipQBKTz1J2Pw9RHcp7WxC9rW +6PTH40kMLD2F3fRYdrsJ37nIe853MvUsH3Fa6oMfGxpvIpN3gJtj3w0OPj8rWq9X +gQbN/56afzE4zG0HhX+RP71LXpn1US0twQfP0GM0q6xh0P7pfWT8Z7lHk1j4j7u+ +3RU1do8+1Ak6TLrMnfkZBw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec new file mode 100644 index 0000000000..e9decb76dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-intermediate +subject:ee.example.com +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:ee.example.com diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem new file mode 100644 index 0000000000..dcb44b9953 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUV3PLWwVDtiZkBpRLWYBIrcA3uowwDQYJKoZIhvcNAQEL +BQAwMDEuMCwGA1UEAwwlaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRp +YXRlMjAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAOMQwwCgYD +VQQDDANlZTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3 +DQEBCwUAA4IBAQBSxrC9YRPkmqYz2MsbyytjlG/f0g2uVv78Q3yR0tVsGW67VH0l +X3rUdqWXCrYi8NtmZjbwx/EERtXc4dLXmJ2DEaHWPygQ3zAiKBAEWh9COaz7b11/ +wHu3uZVOXsWKqt212FpjKob6n4ceQu2RlnYYX+VVSKrt4ct3ph5X31D/heerNvLp +Et6UETIAY6PhC982XC3wn/r0ykIPQygXKdMJ3Umvq+OzOObn7RTX10EPdOmyU9su +bmpR4oYBPB71GWGoeNpp17swOe9BVvQvIcnEwiWuVeWhaZvFAmrFe1484PnTgcjg +kLtYKtzg0Z8t1jWExmdb00A8CP92iHa2HGl+ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec new file mode 100644 index 0000000000..089ac63831 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec @@ -0,0 +1,3 @@ +issuer:intermediate-preloading-intermediate2 +subject:ee2 +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem new file mode 100644 index 0000000000..ad98f78efd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUHyDRZ9EprKjXteNSxinckLtLUqMwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLzEtMCsGA1UEAwwkaW50ZXJt +ZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARadVY9uVwXt3 +8p81yXQxJ87Vyc02HL9qc1l1+ttJ0g0CL10pEJjT8rbXwghaGQ8Jw/GGhoYVy0VH ++5+uqnpvLaBgFX7noX5+eKABzVW3NfcD9705Ul3N8dFo11mGsvzL3+B5ucOyjY+9 +CPLIzYCBY5OnCIrsU+zkS9TcoqblvPQGkzVdHcNQLy01Fs6XJ4VQhoP6KZ2rsCJn +QcHlg5t5HXywCf5ihzXPqWB7Ib7GL7nLIv7ViyHK6QkEPpeHtSxcs2OiwkJCeKTs +v2HFnnLiKfF0zGhOp8nLaMXmFTCaNBLs7YaSbWqOYct9zNTBlDtO+GcYqDx74B6c ++W7hLcJ9aA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec new file mode 100644 index 0000000000..5863b3131f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-ca +subject:intermediate-preloading-intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem new file mode 100644 index 0000000000..c11853b08a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUb7hTHv3uBY6lDd0XbWQLu/+jjIQwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMDAxLjAsBgNVBAMMJWludGVy +bWVkaWF0ZS1wcmVsb2FkaW5nLWludGVybWVkaWF0ZTIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1Ud +EwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBJYzhJ9SuX +sqKTHwITcbGmv30f1CFOE23Pwf1KSk/Rqw2yx7CCeobGpLQUlIU72lGqZ0W4BVGy +TJDwGOGTKtFYVtYddo5DXVuUREUcUeRzAwSZwEhm2ANyEXypRffmQNR+h4VH3skX +2pWfNH8TAes+z6Vz4HCkEOqa3uBUe9GMjbg8Gtrqsx2Vt3hJrg9dB2/0I5POMM95 +9nRtl6ZHx81DMccy6YT/lhsBDIA106u75THS45yuFNRtzPaL06/7iiNFjW+upsf7 +3Bg6x7VKBt2ZGFebHFiMnGyVPsMyXQw/i1w6yiXD04F9PHdYjMtY90hH69aGhQNk +Lgcw88dDaKaL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec new file mode 100644 index 0000000000..27e9a008df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-ca2 +subject:intermediate-preloading-intermediate2 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build b/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build new file mode 100644 index 0000000000..855b02df7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'default-ee.pem', +# 'ee2.pem', +# 'int.pem', +# 'int2.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_keysize.js b/security/manager/ssl/tests/unit/test_keysize.js new file mode 100644 index 0000000000..45066a3888 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize.js @@ -0,0 +1,204 @@ +// -*- 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"; + +// Checks that RSA certs with key sizes below 1024 bits are rejected. +// Checks that ECC certs using curves other than the NIST P-256, P-384 or P-521 +// curves are rejected. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * Tests a cert chain. + * + * @param {String} rootKeyType + * The key type of the root certificate, or the name of an elliptic + * curve, as output by the 'openssl ecparam -list_curves' command. + * @param {Number} rootKeySize + * @param {String} intKeyType + * @param {Number} intKeySize + * @param {String} eeKeyType + * @param {Number} eeKeySize + * @param {PRErrorCode} eeExpectedError + * @return {Promise} a promise that will resolve when the verification has + * completed + */ +function checkChain( + rootKeyType, + rootKeySize, + intKeyType, + intKeySize, + eeKeyType, + eeKeySize, + eeExpectedError +) { + let rootName = "root_" + rootKeyType + "_" + rootKeySize; + let intName = "int_" + intKeyType + "_" + intKeySize; + let eeName = "ee_" + eeKeyType + "_" + eeKeySize; + + let intFullName = intName + "-" + rootName; + let eeFullName = eeName + "-" + intName + "-" + rootName; + + addCertFromFile(certdb, `test_keysize/${rootName}.pem`, "CTu,CTu,CTu"); + addCertFromFile(certdb, `test_keysize/${intFullName}.pem`, ",,"); + let eeCert = constructCertFromFile(`test_keysize/${eeFullName}.pem`); + + info("cert o=" + eeCert.organization); + info("cert issuer o=" + eeCert.issuerOrganization); + return checkCertErrorGeneric( + certdb, + eeCert, + eeExpectedError, + certificateUsageSSLServer + ); +} + +/** + * Tests various RSA chains. + * + * @param {Number} inadequateKeySize + * @param {Number} adequateKeySize + */ +async function checkRSAChains(inadequateKeySize, adequateKeySize) { + // Chain with certs that have adequate sizes for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + PRErrorCodeSuccess + ); + + // Chain with a root cert that has an inadequate size for DV + await checkChain( + "rsa", + inadequateKeySize, + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + // Chain with an intermediate cert that has an inadequate size for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + inadequateKeySize, + "rsa", + adequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + // Chain with an end entity cert that has an inadequate size for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + "rsa", + inadequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); +} + +async function checkECCChains() { + await checkChain( + "secp256r1", + 256, + "secp384r1", + 384, + "secp521r1", + 521, + PRErrorCodeSuccess + ); + await checkChain( + "secp256r1", + 256, + "secp224r1", + 224, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "secp256r1", + 256, + "secp224r1", + 224, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp224r1", + 224, + "secp256r1", + 256, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "secp256r1", + 256, + "secp256k1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256k1", + 256, + "secp256r1", + 256, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); +} + +async function checkCombinationChains() { + await checkChain( + "rsa", + 2048, + "secp256r1", + 256, + "secp384r1", + 384, + PRErrorCodeSuccess + ); + await checkChain( + "rsa", + 2048, + "secp256r1", + 256, + "secp224r1", + 224, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "rsa", + 1016, + "secp256r1", + 256, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); +} + +add_task(async function() { + await checkRSAChains(1016, 1024); + await checkECCChains(); + await checkCombinationChains(); +}); diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..a505fe3b6c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4DCCAUmgAwIBAgIUP87ifngF30j5hBghK5jGe5gcLtswDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMTYtaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwgZ4wDQYJKoZIhvcNAQEB +BQADgYwAMIGIAoGAANKbsS+4T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDr +kgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drX +zLSF2BouGdUNTwtoVKyvbXvmnZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEA +ATANBgkqhkiG9w0BAQsFAAOBgQCiWMxWN4+CamDzXDW90neja5RHg/pDlBI9pI+Q +NRyUycpJwN5Flv+/C+OCdmxH/dd15SeGiXCrjJQcSXFBeMD/1JK427SR1acE6z+W +qY+rYzJ+b68Dybx/4cj2VeFWpdMhZtttgvNrGfwGMbHs9gWG7n6wPKjg6h0OuThf +2TfVIw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..7b86ef7861 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1024 +subject:ee_rsa_1016-int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1016 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem new file mode 100644 index 0000000000..dadab2f898 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4DCCAUqgAwIBAgIUFclsTfsYyWNzZajFqzlMZX7fOHswDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDE2LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMjQtaW50X3JzYV8xMDE2LXJvb3RfcnNhXzEwMjQwgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANOpdEAQHrqMXflQPm+TXrUv/rPr6dDcXKzib5c8qUy8DZwx +1mwMATvOnILQ1IAyjfBftrzXmQpTEt2uYVKtbuYcjBvdhmPGi9NiJKmIKueOifVW +39vm9R2mESy/wnyKSTNrQa/bdTIbUrJKc0TRNI5kY1GlUcdXHM2guP419hp1AgMB +AAEwDQYJKoZIhvcNAQELBQADgYAAy04O696YrNhCjvlDn3FEPZ1Ce4dmSvJQzw3U +A6nAq3PLq16WwopAus+b3fEXke5k/u+pYfM4+5X7XRDNZW9i+5nUQVmGgiEzG3TU ++WYwGa5V0z6xMXl39i0tIaY4irYwzEpA+DvbJOz/gExQ9dpP/LW5Y8rE0kdMvBbZ +Gz6gjw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..326d665dcc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1016-root_rsa_1024 +subject:ee_rsa_1024-int_rsa_1016-root_rsa_1024 +issuerKey:rsa1016 +subjectKey:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem new file mode 100644 index 0000000000..f540304e90 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRjCCAa+gAwIBAgIUU7Z8PfJj0EkU6p/oJRcYHJt+uckwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMTYwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowEjEQMA4GA1UEAwwHcnNhMTAy +NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQAr4tqhlbfFvYm2bAmba+gdsk6+EwQ7 +I4qed6vUQfzFcNMSOFBfFLo5q6CG+UsZ06/Hl3YXDHOhVhZC5QANZRO9tEV59eGS +Hbo3lfSQF8zXJ99vc0q3vNJejGgU/74FjTXX54Pe7KhdUSSjUPEapvpkc2/Y8SFF +CcL9Lsz8hh7dQw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..c44a089ed6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1016 +subject:ee_rsa_1024-int_rsa_1024-root_rsa_1016 +issuerKey:rsa1024 +subject:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..d9c8f4ea0a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4TCCAUqgAwIBAgIUcbFravMReDSDzA6Uxk8BzwUwF2MwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMjQtaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANOpdEAQHrqMXflQPm+TXrUv/rPr6dDcXKzib5c8qUy8DZwx +1mwMATvOnILQ1IAyjfBftrzXmQpTEt2uYVKtbuYcjBvdhmPGi9NiJKmIKueOifVW +39vm9R2mESy/wnyKSTNrQa/bdTIbUrJKc0TRNI5kY1GlUcdXHM2guP419hp1AgMB +AAEwDQYJKoZIhvcNAQELBQADgYEABBfO6S+wGG0HKRb07V+bQpV8eiARnq5ZzoDV +EpfClXnyorjhuU4sYuzvTUMUcKF5lSmiCF9yl4zSoV8fiDJY2qScZ2C+xMSXnf/7 +plub8Pu0oaSb0KSWSSvon4DDbjSpNfQ/QZZkjvtj2wwK9XVK/7aiZ2e7NuGwOLrd +tTs3wec= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..a6ee408ec9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1024 +subject:ee_rsa_1024-int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..20b43091bd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBXDCCAQOgAwIBAgIUOZ6qI6KmpVBIQuNSmsJSrHJ2W1gwCgYIKoZIzj0EAwIw +KjEoMCYGA1UEAwwfaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9yc2FfMjA0ODAiGA8y +MDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBlZV9z +ZWNwMjI0cjFfMjI0LWludF9zZWNwMjU2cjFfMjU2LXJvb3RfcnNhXzIwNDgwTTAQ +BgcqhkjOPQIBBgUrgQQAIQM5AARmjXLMpv1qGzVXtTZhBNhECOy2N/COjIa7/4LM +6I8AZtevY8Mpi6N3NIoSArA7N/1rH/QVqjEeMAoGCCqGSM49BAMCA0cAMEQCIFx1 +UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiBvUw1d8jQrTL7jxcshvTvj +a/7XJT41KYCZC4kHc1sn8A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..87d2f67339 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_rsa_2048 +subject:ee_secp224r1_224-int_secp256r1_256-root_rsa_2048 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..6e00e043be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBZzCCAQ2gAwIBAgIUQd9nJAnSoGdsru1U5XzdnZSmQngwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyMjRyMV8yMjQtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +cjFfMjU2ME0wEAYHKoZIzj0CAQYFK4EEACEDOQAEZo1yzKb9ahs1V7U2YQTYRAjs +tjfwjoyGu/+CzOiPAGbXr2PDKYujdzSKEgKwOzf9ax/0FaoxHjAKBggqhkjOPQQD +AgNIADBFAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctCgApw5gIhAIgKiG6Y +Wn7JOkWTie+T+AVcLVZU1CT171W8r/AtOYkq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..1aadce0765 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256r1_256 +subject:ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..0de0ebca77 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbzCCARagAwIBAgIUF4GiHggPJErLtUU4O82JTDsn9/UwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZrMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +cjFfMjU2MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAENe58conY/veoav5dpm2Lwuu2 +qFQ/0v6tCJ9FznrND6ZDgqlQDEHa13D/1LURv0tJLrEjiADDLE92xzo/MpTnxTAK +BggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctCgApw +5gIgUp27SDHsVOPJ3xOj87plJRqBLZ/mkOWbhZjp8SUTsVs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..ba999e8f14 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256r1_256 +subject:ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256k1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem new file mode 100644 index 0000000000..083641b7c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqDCCARKgAwIBAgIUJd4SuF585qlYm74gqnZsBTfIYhQwDQYJKoZIhvcNAQEL +BQAwKjEoMCYGA1UEAwwfaW50X3JzYV8xMDE2LXJvb3Rfc2VjcDI1NnIxXzI1NjAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBl +ZV9zZWNwMjU2cjFfMjU2LWludF9yc2FfMTAxNi1yb290X3NlY3AyNTZyMV8yNTYw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARPv7u7YeD4+bGmClmshwTi7AULQj48 +9y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQejBOqgSqbAMA0GCSqG +SIb3DQEBCwUAA4GAAH+y3CZOoy2Z3zegsj4EmKuwAYBRm7WjV7J7gM2Bak6JaycQ +NhA2hAd3z3vLEVNlgw0b/WM6lVBNH6fFXikKEzNBytofZtxFqRH66J0qc/CAbmw5 +fG8rkHL4vrDQ1vr3Lyh/qbGXZJxPd2lbFk029o8BkBZADra8QcPuD2EHmDk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..1e2e0a3759 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1016-root_secp256r1_256 +subject:ee_secp256r1_256-int_rsa_1016-root_secp256r1_256 +issuerKey:rsa1016 +subjectKey:secp256r1 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem new file mode 100644 index 0000000000..1bf347fc08 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBazCCARmgAwIBAgIUF+3Ha/HblkQ9RVAnd5VUa5BPQ2YwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyMjRyMV8yMjQtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyMjRyMV8yMjQtcm9vdF9zZWNwMjU2 +cjFfMjU2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNAADA9Ah0Amjxv8EbbcPJV9S/WmFIc1y28BSBjT5W2S7JS +VAIcL1LLWdbRbY2jphtXTfe1/t7vRvZlRgQPxxlSrg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..bd7bc770c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp224r1_224-root_secp256r1_256 +subject:ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256 +issuerKey:secp224r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem new file mode 100644 index 0000000000..5f4a80948f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARmgAwIBAgIUUfZawfrAes7uJnC3lbyou+3HboEwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjI0cjFfMjI0 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjI0 +cjFfMjI0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctC +gApw5gIgbc9p70u5ogMPqCSTG4IpDnjR+Cguf8a+8Erbgfur7Dg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..fe7b7f7482 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp224r1_224 +subject:ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem new file mode 100644 index 0000000000..b13b1fb264 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARmgAwIBAgIUdduB4Waw8NoEQbwRm8oYqzYqyF8wCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2azFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +azFfMjU2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctC +gApw5gIgKk16br1bktVUX0hUgSKha7mCXqcLm2OqbEfhnnvTGQI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..aefffd9810 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256k1_256 +subject:ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..a3aa1bccba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhTCCASygAwIBAgIUP57NpzW0TiQ7Dv+Eu/Jsec7uG1EwCgYIKoZIzj0EAwIw +KjEoMCYGA1UEAwwfaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9yc2FfMjA0ODAiGA8y +MDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBlZV9z +ZWNwMzg0cjFfMzg0LWludF9zZWNwMjU2cjFfMjU2LXJvb3RfcnNhXzIwNDgwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtg +jiUt5LcTLajOmOgxU05qnAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalx +A74oiM/wAvBa9xof3cyDdKpuqc4wCgYIKoZIzj0EAwIDRwAwRAIgXHVRnxMRUM1d +it4go7wGMJH/snN1XzFk7P3LQoAKcOYCIFJ475L6BSzMQmSQ4of5j0VvzGWLlc4p +P7WljL/PnuoG +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..615818d08b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_rsa_2048 +subject:ee_secp384r1_384-int_secp256r1_256-root_rsa_2048 +issuerKey:secp256r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem new file mode 100644 index 0000000000..fa2b1196d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1zCCAVygAwIBAgIUZSV+XPsVuShLaoK1fI9SUQtuqpUwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AzODRyMV8zODQtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3A1MjFyMV81MjEtaW50X3NlY3AzODRyMV8zODQtcm9vdF9zZWNwMjU2 +cjFfMjU2MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBTNycrMR5QQlrycxmdS7C +f1l3NPpmxit5L4jFGdbTfw0W6hxIOhgnoBC5Eo46CAcMoz719Xg1t8G6JR9sw1Id +xCsBBlNFGYG0RdND7tN4KjXWz/D/SE9aiD0gnxuQQrcmcDVosvMm4YuDO92KoHND +krzRlQHhDWmKefU+EeCiK90qrZAwCgYIKoZIzj0EAwIDaQAwZgIxAO0GJz6haDpU +tNgaQ3SESJY85j6+gRcD7Nc9cvCiVAZZ1OxFRuhW515lVbeTqfcA8wIxAKIisY3l ++oJ2fwRVdjaU3+DIoB72CX208Piq2hSKjF8eVtEHV2liiAfQoH9ktR+0mw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..b2ae9d0c8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp384r1_384-root_secp256r1_256 +subject:ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256 +issuerKey:secp384r1 +subjectKey:secp521r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem new file mode 100644 index 0000000000..c63c086abb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAU+gAwIBAgIUN856fz51l3lVM7u/s/R3tvFzxkgwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMTYtcm9vdF9y +c2FfMTAyNDCBnjANBgkqhkiG9w0BAQEFAAOBjAAwgYgCgYAA0puxL7hP3c0ps6UZ +y2bEO42Pi+VFunk4TOZj7QPfdZkWAOuSB5DSUwzs5UTbmacfBYlqPtIHFlU0qpkF +fkfEfjvIGtpvoeEuNyaLUEalUmj52tfMtIXYGi4Z1Q1PC2hUrK9te+admggxNuFa ++o9TwcjIT8YHcnndDlXXNppb3QIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud +DwQEAwIBBjANBgkqhkiG9w0BAQsFAAOBgQAwJyIekNQXnajDVspHOAAsNBkPw0MW +Q8r7OPH9Q9ZzXkz1oXHdwnEXyW4uIOhBYKRvtaqEEQI3SXvV72d5gKIXbP2cf/mQ +RLRS0GBsy1ulg2w4dSvkwkwFgeYZ+BxM5+esVECzFKZsXrPUcYraymqurqdZcAxy +0edmg/yt37w8zA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..c6e77116b7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:int_rsa_1016-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1016 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem new file mode 100644 index 0000000000..a47ac14370 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBsDCCAVagAwIBAgIUe0w3IjAYBfw32mIJMH/pETsJGAcwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMCoxKDAmBgNVBAMMH2ludF9yc2FfMTAxNi1yb290 +X3NlY3AyNTZyMV8yNTYwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAANKbsS+4 +T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7S +BxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvm +nZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAaMdMBswDAYDVR0TBAUwAwEB +/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIgXHVRnxMRUM1dit4go7wG +MJH/snN1XzFk7P3LQoAKcOYCIQCPyLXUG26XZLO3nMf58EJ2Ej+o+gXDAllaLBW5 +2nS+jA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..27728ca374 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_rsa_1016-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:rsa1016 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem new file mode 100644 index 0000000000..812e259332 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAVCgAwIBAgIUeZhovVNDUuRN9h3SwWVSaVKNv14wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAxNjAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMjQtcm9vdF9y +c2FfMTAxNjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06l0QBAeuoxd+VA+ +b5NetS/+s+vp0NxcrOJvlzypTLwNnDHWbAwBO86cgtDUgDKN8F+2vNeZClMS3a5h +Uq1u5hyMG92GY8aL02IkqYgq546J9Vbf2+b1HaYRLL/CfIpJM2tBr9t1MhtSskpz +RNE0jmRjUaVRx1cczaC4/jX2GnUCAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYAAximjztC//bRBDGD/zQzHBU9DC2CR +cfdN0A7LgtHgyue5DFtdj1RRioj3ZLIfEgMLi+gESTmZPH1YkMExF2xCJRBdTu3O +dweani8aTdLWSF3ikt00jCSGH1kiPjWM9pRXhLEz62VW4yvxFt4eVB1xmM5VPOwZ +B9EHfdS8AeaNVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..fafb393bf9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1016 +subject:int_rsa_1024-root_rsa_1016 +issuerKey:rsa1016 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..45d9ac8ee2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5zCCAVCgAwIBAgIUYcS07xR3ydcgKjUYhNFcmIw+FKQwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMjQtcm9vdF9y +c2FfMTAyNDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06l0QBAeuoxd+VA+ +b5NetS/+s+vp0NxcrOJvlzypTLwNnDHWbAwBO86cgtDUgDKN8F+2vNeZClMS3a5h +Uq1u5hyMG92GY8aL02IkqYgq546J9Vbf2+b1HaYRLL/CfIpJM2tBr9t1MhtSskpz +RNE0jmRjUaVRx1cczaC4/jX2GnUCAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAzgSst5WpRJFjBpDYQ+/oQE99sYmc +JZ6lA2Lf5kFDMXb/bF7jf0/FbEheFNRHs+I5kc95lPbwyzpA2bQ3TK9jzFpoDTjK +kPYnXKn0xa+H7mUS4V6VQh28GdBcWffLZC8vBkB+DKR6N3M2s7erDZjEA8PodKUd +dR5G85B8pwswVJM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..66891f9793 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem new file mode 100644 index 0000000000..04d2564718 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBYjCCAQmgAwIBAgIUZf9BUQycH51qhAjba7oMtj+YWtowCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjI0cjFfMjI0 +LXJvb3Rfc2VjcDI1NnIxXzI1NjBNMBAGByqGSM49AgEGBSuBBAAhAzkABGaNcsym +/WobNVe1NmEE2EQI7LY38I6Mhrv/gszojwBm169jwymLo3c0ihICsDs3/Wsf9BWq +MR6jHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cA +MEQCIFx1UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiAgvRpeJMeD41PQ +ydWsdlfwmrgnjM+Vn+bBX0ty9NcEEA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..89d77d3b89 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp224r1_224-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..e5e8f573fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICJjCCAQ6gAwIBAgIUG/u+QDiBCAoaoWJYvqL0uwY1/iIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMjA0ODAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAqMSgwJgYDVQQDDB9pbnRfc2VjcDI1NnIxXzI1Ni1y +b290X3JzYV8yMDQ4MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+Pmx +pgpZrIcE4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0H +owTqoEqmwKMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN +AQELBQADggEBADJyKAFPb7ilK80rDDSGNqf7ls/rpElvmhpVJvivJ3Yv1DRm7EEM +38mwE14TcmayyOS+0avA4gDqH7T9du5NhNWMfluNediBjzl2CgFgXXjSsE7sr1py +RAi3nYSnUiih6k9Q4a69RteD6FigfSfO0w0nrmLi+njkSVqJ+0pSvnmvf2RKBK9H +i0VR2oFjoEM/cyxibv1ETqaT6V0CWZSAu6IMT7gpmvvkF5Ti7+KeXXkbuZuQTqIo +ow/zOhW7aMK24jGDKBLwunbh4EeLyWWtIy88ZNbdGmJkf7+s+/km6DziS9TkcQxn +tCUR7ze5cYRZ49TNfAcQC0ogdokgo1Cag+U= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..44a65ef5a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:root_rsa_2048 +subject:int_secp256r1_256-root_rsa_2048 +subjectKey:secp256r1 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem new file mode 100644 index 0000000000..d4d73c25da --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBaDCCARWgAwIBAgIULWja0CElNsf9uHoMLXihbb0y8dMwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjI0cjFfMjI0MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDIyNHIxXzIyNDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0EAMD4CHQCaPG/wRttw8lX1L9aYUhzXLbwFIGNPlbZLslJUAh0A +4ZWHxPcxexTE/kShvISJeBka5jGQ1baqxDM6ng== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..66ebc1b93e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp224r1_224 +subject:int_secp256r1_256-root_secp224r1_224 +issuerKey:secp224r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem new file mode 100644 index 0000000000..8a69c3e52a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbzCCARWgAwIBAgIUeQnFuTzLPx3FrBWD3ouZIpqXfFUwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDI1NmsxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0gAMEUCIFuwodUwyOUnIR4KN5ZCSrU7y4iz4/1EWRdHm5kWKi8d +AiEA8M23PrqXz5+5jx1UeQEuaN+Q4ln3gT+XclPmR9P82tA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..c7e190ab0b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256k1_256 +subject:int_secp256r1_256-root_secp256k1_256 +issuerKey:secp256k1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..a060a6fe1c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbjCCARWgAwIBAgIUS3I7amSSwFamYMLcx8D/W1zjoCowCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDI1NnIxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0cAMEQCIFx1UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDm +AiBnPZ/DApW1c90gQo+deVHt8TrmT4zNesvqmTzEpU4Tkg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..6854d21876 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem new file mode 100644 index 0000000000..8e43a8e0d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBizCCATKgAwIBAgIUIwvMnx4+Cfvo4LHUHSyx8+OIpLIwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMzg0cjFfMzg0 +LXJvb3Rfc2VjcDI1NnIxXzI1NjB2MBAGByqGSM49AgEGBSuBBAAiA2IABKFockM2 +K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMtqM6Y6DFTTmqcDAsJyNY5regy +BuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC8Fr3Gh/dzIN0qm6pzqMdMBsw +DAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDRwAwRAIgXHVR +nxMRUM1dit4go7wGMJH/snN1XzFk7P3LQoAKcOYCIEefciT9jaPnIvEiHC2ktArf +XGf7h0FGlxLkN9YhKmZ1 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..de8e851981 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp384r1_384-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/moz.build b/security/manager/ssl/tests/unit/test_keysize/moz.build new file mode 100644 index 0000000000..80b3152dac --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/moz.build @@ -0,0 +1,41 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem', +# 'ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem', +# 'ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem', +# 'ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem', +# 'ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem', +# 'ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem', +# 'ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem', +# 'ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem', +# 'ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem', +# 'ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem', +# 'int_rsa_1016-root_rsa_1024.pem', +# 'int_rsa_1016-root_secp256r1_256.pem', +# 'int_rsa_1024-root_rsa_1016.pem', +# 'int_rsa_1024-root_rsa_1024.pem', +# 'int_secp224r1_224-root_secp256r1_256.pem', +# 'int_secp256r1_256-root_rsa_2048.pem', +# 'int_secp256r1_256-root_secp224r1_224.pem', +# 'int_secp256r1_256-root_secp256k1_256.pem', +# 'int_secp256r1_256-root_secp256r1_256.pem', +# 'int_secp384r1_384-root_secp256r1_256.pem', +# 'root_rsa_1016.pem', +# 'root_rsa_1024.pem', +# 'root_rsa_2048.pem', +# 'root_secp224r1_224.pem', +# 'root_secp256k1_256.pem', +# 'root_secp256r1_256.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem new file mode 100644 index 0000000000..42064fb0b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2DCCAUKgAwIBAgIUbY90vJ4/+tgc8hsO+VMaaSWW1kgwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAxNjAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8xMDE2MIGeMA0G +CSqGSIb3DQEBAQUAA4GMADCBiAKBgADSm7EvuE/dzSmzpRnLZsQ7jY+L5UW6eThM +5mPtA991mRYA65IHkNJTDOzlRNuZpx8FiWo+0gcWVTSqmQV+R8R+O8ga2m+h4S43 +JotQRqVSaPna18y0hdgaLhnVDU8LaFSsr2175p2aCDE24Vr6j1PByMhPxgdyed0O +Vdc2mlvdAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG +SIb3DQEBCwUAA4GAAIV+rBvvS1MrBSnjxfYBmX/Kp4bWEXtrStskD9xfyKkmWVxO +9NxHmA7L3NTqxkYgzfANE1OdFSd+mKK/Bx/xDCUgfRIQZCPZId4GLGl+gRq25R6X +V3IV53b8UHiGJP0ASJbXUqTQF/7fZvuvBLBDgg9nXObe3ZwHUgWfc3I974I= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..b0b5ba8e5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1016 +subject:root_rsa_1016 +issuerKey:rsa1016 +subjectKey:rsa1016 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem new file mode 100644 index 0000000000..7262a5cfb0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2jCCAUOgAwIBAgIUEWZ1ZXY8sKYaumyn9kCsWK1AEZMwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8xMDI0MIGfMA0G +CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTqXRAEB66jF35UD5vk161L/6z6+nQ3Fys +4m+XPKlMvA2cMdZsDAE7zpyC0NSAMo3wX7a815kKUxLdrmFSrW7mHIwb3YZjxovT +YiSpiCrnjon1Vt/b5vUdphEsv8J8ikkza0Gv23UyG1KySnNE0TSOZGNRpVHHVxzN +oLj+NfYadQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq +hkiG9w0BAQsFAAOBgQBL16xkIAjU8a2lPy+Ax4N6OjeTrT+pBbj90/ynUiRuEYkI +GR0Qpv2vcKoFBGIywsJm61z6VRojuaoZGww4D1xlKaHp4R2DmPQYPG/EsUcPdyNK +MszBmNHK+gRG0HoR4XJUIFMIfnF2R9m9vpVK1XPikLA10UlETdnp9tGuYIXcQw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..09cd420f70 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem new file mode 100644 index 0000000000..82c625161f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUFbP+AdxwM3PsfxQino2TeiJLnW4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMjA0ODAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8yMDQ4MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAt1vYMFhLBuETUi2evjncIdzhu8cAqvqnN9WdB/SWL/PsS3cwGb6zu03fxkvZ +/z07qSs/ojSUR1I70S23NDcmX5Q2vToo8H3Zks2MS+AI0BPVnxo+RllO+zOqMYOQ +LPGJ+o9M6TGbL/jzYRhCWdF64jOnzgRFN1LU56fWYJLXMwIBHMQ/qMokiDkfc4pG +O3TOeJHAlfm49pJ1VhTZv3otCel+EkTa7mv0TTaJ+su0/zxgNFtUYWGcCuBJ95hi +t6Zh6GpOq0ML6NtZK7vMB7BvCIwihU3Fq2ApAiIq/I4tk9ROTvwKCNW6THQ+3+YH +eSUgFEYNH1T1dcCjsdthf9sKJw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..cebc2f8e6a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec @@ -0,0 +1,4 @@ +issuer:root_rsa_2048 +subject:root_rsa_2048 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem new file mode 100644 index 0000000000..a3945cf4c9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSTCB96ADAgECAhRLUpJGgls27Ph+GqVq1TzwkXgSPTAKBggqhkjOPQQDAjAd +MRswGQYDVQQDDBJyb290X3NlY3AyMjRyMV8yMjQwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowHTEbMBkGA1UEAwwScm9vdF9zZWNwMjI0cjFfMjI0 +ME0wEAYHKoZIzj0CAQYFK4EEACEDOQAEZo1yzKb9ahs1V7U2YQTYRAjstjfwjoyG +u/+CzOiPAGbXr2PDKYujdzSKEgKwOzf9ax/0FaoxHqMdMBswDAYDVR0TBAUwAwEB +/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDQQAwPgIdAJo8b/BG23DyVfUv1phS +HNctvAUgY0+VtkuyUlQCHQDZkK9gapfJf6mFLQZOVyj5QrFII+O1AhmojjBO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..31370f6f73 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp224r1_224 +subject:root_secp224r1_224 +issuerKey:secp224r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem new file mode 100644 index 0000000000..0067d0297c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBWjCCAQCgAwIBAgIUExiTXNGw/1/DWr3T+8iOfYQqhoYwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB0xGzAZBgNVBAMMEnJvb3Rfc2VjcDI1NmsxXzI1 +NjBWMBAGByqGSM49AgEGBSuBBAAKA0IABDXufHKJ2P73qGr+XaZti8LrtqhUP9L+ +rQifRc56zQ+mQ4KpUAxB2tdw/9S1Eb9LSS6xI4gAwyxPdsc6PzKU58WjHTAbMAwG +A1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIFuwodUw +yOUnIR4KN5ZCSrU7y4iz4/1EWRdHm5kWKi8dAiEA5z1yM2Xj8Xz+mTzaSV3Ic3Xi +wEJTXssXlwfECKILxX8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..c78aa61bba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256k1_256 +subject:root_secp256k1_256 +issuerKey:secp256k1 +subjectKey:secp256k1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem new file mode 100644 index 0000000000..c8e8fd20a4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBXDCCAQOgAwIBAgIUH8NJbu+U7yxLh2580Q2Bh0WUOX0wCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB0xGzAZBgNVBAMMEnJvb3Rfc2VjcDI1NnIxXzI1 +NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/u7th4Pj5saYKWayHBOLsBQtC +Pjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjHTAb +MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cAMEQCIFx1 +UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiA1QYiu/g1qUtMLwoIqOMYb +Qi7ckS6Dd1TkOR0kW1dGAw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..4447fc4b47 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev.js b/security/manager/ssl/tests/unit/test_keysize_ev.js new file mode 100644 index 0000000000..60ebf99f82 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev.js @@ -0,0 +1,171 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Checks that RSA certs with key sizes below 2048 bits when verifying for EV +// are rejected. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function getOCSPResponder(expectedCertNames) { + let expectedPaths = expectedCertNames.slice(); + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_keysize_ev/", + expectedCertNames, + expectedPaths + ); +} + +function loadCert(certName, trustString) { + let certFilename = "test_keysize_ev/" + certName + ".pem"; + addCertFromFile(certDB, certFilename, trustString); + return constructCertFromFile(certFilename); +} + +/** + * Asynchronously runs a single EV key size test. + * + * @param {Array} expectedNamesForOCSP + * An array of nicknames of the certs to be responded to. + * @param {String} rootCertFileName + * The file name of the root cert. Can begin with ".." to reference + * certs in folders other than "test_keysize_ev/". + * @param {Array} intCertFileNames + * An array of file names of any intermediate certificates. + * @param {String} endEntityCertFileName + * The file name of the end entity cert. + * @param {Boolean} expectedResult + * Whether the chain is expected to validate as EV. + */ +async function keySizeTestForEV( + expectedNamesForOCSP, + rootCertFileName, + intCertFileNames, + endEntityCertFileName, + expectedResult +) { + clearOCSPCache(); + let ocspResponder = getOCSPResponder(expectedNamesForOCSP); + + loadCert(rootCertFileName, "CTu,CTu,CTu"); + for (let intCertFileName of intCertFileNames) { + loadCert(intCertFileName, ",,"); + } + await checkEVStatus( + certDB, + constructCertFromFile(`test_keysize_ev/${endEntityCertFileName}.pem`), + certificateUsageSSLServer, + expectedResult + ); + + await stopOCSPResponder(ocspResponder); +} + +/** + * For debug builds which have the test EV roots compiled in, checks RSA chains + * which contain certs with key sizes adequate for EV are validated as such, + * while chains that contain any cert with an inadequate key size fail EV and + * validate as DV. + * For opt builds which don't have the test EV roots compiled in, checks that + * none of the chains validate as EV. + * + * Note: This function assumes that the key size requirements for EV are greater + * than the requirements for DV. + * + * @param {Number} inadequateKeySize + * The inadequate key size of the generated certs. + * @param {Number} adequateKeySize + * The adequate key size of the generated certs. + */ +async function checkRSAChains(inadequateKeySize, adequateKeySize) { + // Reuse the existing test RSA EV root + let rootOKCertFileName = "../test_ev_certs/evroot"; + let rootOKName = "evroot"; + let rootNotOKName = "ev_root_rsa_" + inadequateKeySize; + let intOKName = "ev_int_rsa_" + adequateKeySize; + let intNotOKName = "ev_int_rsa_" + inadequateKeySize; + let eeOKName = "ev_ee_rsa_" + adequateKeySize; + let eeNotOKName = "ev_ee_rsa_" + inadequateKeySize; + + // Chain with certs that have adequate sizes for EV and DV + // In opt builds, this chain is only validated for DV. Hence, an OCSP fetch + // will for example not be done for the "ev_int_rsa_2048-evroot" intermediate + // in such a build. + let intFullName = intOKName + "-" + rootOKName; + let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName; + let expectedNamesForOCSP = gEVExpected + ? [intFullName, eeFullName] + : [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + gEVExpected + ); + + // Chain with a root cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intOKName + "-" + rootNotOKName; + eeFullName = eeOKName + "-" + intOKName + "-" + rootNotOKName; + expectedNamesForOCSP = [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootNotOKName, + [intFullName], + eeFullName, + false + ); + + // Chain with an intermediate cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intNotOKName + "-" + rootOKName; + eeFullName = eeOKName + "-" + intNotOKName + "-" + rootOKName; + expectedNamesForOCSP = [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + false + ); + + // Chain with an end entity cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intOKName + "-" + rootOKName; + eeFullName = eeNotOKName + "-" + intOKName + "-" + rootOKName; + expectedNamesForOCSP = gEVExpected ? [intFullName, eeFullName] : [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + false + ); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + let smallKeyEVRoot = constructCertFromFile( + "test_keysize_ev/ev_root_rsa_2040.pem" + ); + equal( + smallKeyEVRoot.sha256Fingerprint, + "40:AB:5D:A5:89:15:A9:4B:82:87:B8:A6:9A:84:B1:DB:" + + "7A:9D:DB:B8:4E:E1:23:E3:C6:64:E7:50:DC:35:8C:68", + "test sanity check: the small-key EV root must have the same " + + "fingerprint as the corresponding entry in ExtendedValidation.cpp" + ); + + await checkRSAChains(2040, 2048); +}); diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..3df0d3dada --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIUY8VXvB5H7AGqWbz0hoVm0b7dAnIwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQ4LWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0MC1ldl9pbnRfcnNhXzIwNDgtZXZyb290MIIBITANBgkqhkiG9w0BAQEFAAOC +AQ4AMIIBCQKCAQAAusBlL9+8AFWIL/uurO7Ij6LQg8KX3V1AZk3T2Q9S+aoCvYpQ ++6FuD9mRh470dfmzUNn44+sqvXF84yewl4hTHxPfjj5OO51ha7ikHlMG7tJHIWMW +EFEYASdqTrZvBzMbXLyLyucBao+bPU8qxFU8Ykz1JjvLNI6IQN5mEocJYKeSGRsT +j7IX92XOx7/46U8Ws5QZv3UExZp+T3m9bRc+nHvz2dKk5zzBgLBZCnPVhPt/ybVP +pURgflP8aFx6Vf1EqB1BQravUepvps6lKWWi6MXYTzygJNb7ubAFuWUc5dny7PQO +1ASYGp/8AmNuMRsJXGMyoMh9w5JxtVUUgXdLAgMBAAGjgYQwgYEwXgYIKwYBBQUH +AQEEUjBQME4GCCsGAQUFBzABhkJodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgv +ZXZfZWVfcnNhXzIwNDAtZXZfaW50X3JzYV8yMDQ4LWV2cm9vdC8wHwYDVR0gBBgw +FjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEBAJlhONR0 +b4Ov6D8ZLINHf06gcsvLXOHvK3UlbB2COdd6Oe1c5bePo6D+zU44vUH4rwb1z25k +OQt6d4LW1ISuw1Wf7HZN1PFwBpvQZ72JcvLwouSqCEuMz68tKTzZy9E9fbRdzMLo +8N5OKxPiTY9R3gziR0AXnadZ0P0yP2mT2Oro/o7+punU4kJsOxzcfu0nMaRTht22 +6XcF6goHUD74zGxwgSeCKdImN4JvA2GYVAniDyOvJCMCjyryxeETZlgsPmXZGAVH +hiGVhFrH1E6FVxagebdK6eB7UJ9Cau5tLefAEHpCr5Xut4QNj9ck0A1J/mj3dwl/ +wV5OZmqoCAEk2h4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..e64c651bc7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_rsa_2048-evroot +subject:ev_ee_rsa_2040-ev_int_rsa_2048-evroot +subjectKey:rsa2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2040-ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem new file mode 100644 index 0000000000..fdf7002fab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAlCgAwIBAgIUf03mHDtKgdbREowlJgpuQsbxVXQwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQwLWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0OC1ldl9pbnRfcnNhXzIwNDAtZXZyb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GEMIGBMF4GCCsGAQUF +BwEBBFIwUDBOBggrBgEFBQcwAYZCaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2V2X2VlX3JzYV8yMDQ4LWV2X2ludF9yc2FfMjA0MC1ldnJvb3QvMB8GA1UdIAQY +MBYwFAYSKwYBBAHrSYUahRqFGgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAABud5gZ +fQFcRyWt2bw3rxs+c0/FsV7XSHnGxYX9DXUiGFL2glNmu4DVQEHYk3CDbAPafTBD +7143VCXQu97AuLl7OAApEbsteRtSX2uMjatA2xDFACUPWqTAVNjhs3/oumldK4GS +Fq7hrPrFim/OQ/pwRvIjE12fUhz4G5uClhCVArtDwCo+0SCWsPveBVVCPmgKM6TI +3t0b20Cya2H7XCB8HC61wftGw0dIjxw5MmA7VAQmoGAxD1DOh0UAXMgMaet93riI +96g8UETpPo89cdPSZ4tMM8JSvnyrc9bns8hvX1KxQyctjXKPgtfszd9pEYv/Aked +S82jJp6aPYt7DFA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec new file mode 100644 index 0000000000..0b7bfd4269 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_rsa_2040-evroot +subject:ev_ee_rsa_2048-ev_int_rsa_2040-evroot +issuerKey:rsa2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2040-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem new file mode 100644 index 0000000000..c8c52a1d00 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhjCCAm6gAwIBAgIUG40lfqXpVIsXGwWLss7U0Guh2lcwDQYJKoZIhvcNAQEL +BQAwKzEpMCcGA1UEAwwgZXZfaW50X3JzYV8yMDQ4LWV2X3Jvb3RfcnNhXzIwNDAw +IhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowOjE4MDYGA1UEAwwv +ZXZfZWVfcnNhXzIwNDgtZXZfaW50X3JzYV8yMDQ4LWV2X3Jvb3RfcnNhXzIwNDAw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjgY4wgYswaAYIKwYBBQUHAQEEXDBaMFgGCCsGAQUFBzABhkxodHRwOi8v +d3d3LmV4YW1wbGUuY29tOjg4ODgvZXZfZWVfcnNhXzIwNDgtZXZfaW50X3JzYV8y +MDQ4LWV2X3Jvb3RfcnNhXzIwNDAvMB8GA1UdIAQYMBYwFAYSKwYBBAHrSYUahRqF +GgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAQAQWGc/1fHcFeIavOXfSSFDn+b9+saU +xIuK4SujRstki8AUxoFyLDa5Hm5aLIU4MTpOxDLBGjFVyv9hGi4aEKnZuzdUDrSe +6ezdNNfTuwgwU1VeivTDzm2lkj9C/F7MnOgste6MMcEj+Cun34ORh7F2adE8KRxU +RgGQYhlurmUEe14ewxyEZ9PZ210v7xSqa+XPg5GNjZHjPoNUYEliASnflJ1eSRqh +Xzm0HabdSJEoUBClQLp2m/BstlkzQgEe7m+S83XPVuRPe79Ey4BnzVYqkpFdeAGO +ffs15R7qbIbOG2DeU5mQFiEFnRTv+80MVHGz0gspMBiyYI1h4wItnYx4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..a36acf887d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec @@ -0,0 +1,4 @@ +issuer:ev_int_rsa_2048-ev_root_rsa_2040 +subject:ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..389e359e93 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUSxuZebHYtwEQBNR2ItC9xEgw7CkwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQ4LWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0OC1ldl9pbnRfcnNhXzIwNDgtZXZyb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GEMIGBMF4GCCsGAQUF +BwEBBFIwUDBOBggrBgEFBQcwAYZCaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2V2X2VlX3JzYV8yMDQ4LWV2X2ludF9yc2FfMjA0OC1ldnJvb3QvMB8GA1UdIAQY +MBYwFAYSKwYBBAHrSYUahRqFGgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAQAMgEzp +6Q8vRl95TLzhiLXC/9otBQpV50iq8Waqf8B2JfOPIP0M/Emz9VKQxavw6iti3YPz +utsdGyIje2W0GhlJVtMKHfvfKYXCwtVEe/XNF/Ojz7znk8KEuUPBzjKTjBuICw4F +PnmKyzoYsD1HwkgrkoII9hr+WBqY5vWLNJA1IXyA2cc3u9oAM1+QqPWEwX+bKjai +4QbngYKTL2ybQbM7TcCkvY/dSOoyyF4K4Kz0eAFXrH1cLHlPj2wo5kgexXRWAgO0 +klZrS2b3C3cJVEWi/bYCg7E3I1noNsgnZ1zQgXqjf7frAUwZURoSSPVO3azM88UJ +FCh9RLnIOgbs7zos +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..0b34be6db8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,4 @@ +issuer:ev_int_rsa_2048-evroot +subject:ev_ee_rsa_2048-ev_int_rsa_2048-evroot +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem new file mode 100644 index 0000000000..ad92bf75eb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIUM/wVnL73PZefwiXVUHFwY4BBJGwwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmV2X2ludF9yc2FfMjA0MC1ldnJvb3QwggEh +MA0GCSqGSIb3DQEBAQUAA4IBDgAwggEJAoIBAAC6wGUv37wAVYgv+66s7siPotCD +wpfdXUBmTdPZD1L5qgK9ilD7oW4P2ZGHjvR1+bNQ2fjj6yq9cXzjJ7CXiFMfE9+O +Pk47nWFruKQeUwbu0kchYxYQURgBJ2pOtm8HMxtcvIvK5wFqj5s9TyrEVTxiTPUm +O8s0johA3mYShwlgp5IZGxOPshf3Zc7Hv/jpTxazlBm/dQTFmn5Peb1tFz6ce/PZ +0qTnPMGAsFkKc9WE+3/JtU+lRGB+U/xoXHpV/USoHUFCtq9R6m+mzqUpZaLoxdhP +PKAk1vu5sAW5ZRzl2fLs9A7UBJgan/wCY24xGwlcYzKgyH3DknG1VRSBd0sCAwEA +AaOBkDCBjTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBPBggrBgEFBQcBAQRD +MEEwPwYIKwYBBQUHMAGGM2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9ldl9p +bnRfcnNhXzIwNDAtZXZyb290LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoB +g3QJATANBgkqhkiG9w0BAQsFAAOCAQEAWnghIlyjOs/GO6obJdu5wmjDghKBP/pQ +5L6yF9jTdfVaTudO/liGBeP1Lnor+0QbTNWlOE2MhPobve6WPbpcGbDoCk+QorFH +sgnLbMMlSUXPgvGt4yNJefsmy02G472T9kSn6KkoLM3Zzanv0crqOUYXsQVODs17 +NEvuWuxcvsA+tuuFxwVMUuBK4AWW64zOmio/xTNqxijV8/Cd7w/20ORDhExtzxsu +l3V04WcZp8GNk6PVbmSCyZ+Oqv8aoF3sI3JCHK0cKHdM5+sQzJyTbKZ1J7kfLE+4 +aB/LZyf3EHOS5/Qv5wCSBxIBHSmQL19l48IU6FBZ+65RtIooczs3bg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec new file mode 100644 index 0000000000..80be711742 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec @@ -0,0 +1,8 @@ +issuer:evroot +subject:ev_int_rsa_2040-evroot +issuerKey:ev +subjectKey:rsa2040 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2040-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key new file mode 100644 index 0000000000..63b267865f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEtwIBADANBgkqhkiG9w0BAQEFAASCBKEwggSdAgEAAoIBAAC6wGUv37wAVYgv ++66s7siPotCDwpfdXUBmTdPZD1L5qgK9ilD7oW4P2ZGHjvR1+bNQ2fjj6yq9cXzj +J7CXiFMfE9+OPk47nWFruKQeUwbu0kchYxYQURgBJ2pOtm8HMxtcvIvK5wFqj5s9 +TyrEVTxiTPUmO8s0johA3mYShwlgp5IZGxOPshf3Zc7Hv/jpTxazlBm/dQTFmn5P +eb1tFz6ce/PZ0qTnPMGAsFkKc9WE+3/JtU+lRGB+U/xoXHpV/USoHUFCtq9R6m+m +zqUpZaLoxdhPPKAk1vu5sAW5ZRzl2fLs9A7UBJgan/wCY24xGwlcYzKgyH3DknG1 +VRSBd0sCAwEAAQKB/2A9smffl1VcvthrjfNVA0ryjx638+eCnSObzCc6fHppoQvo +8h8bbEsCxrrjcxwxWLW7/0YF9Xq3t7Kgy6LsAFottbHqbgrO6lvHRdzS0OnWuA1+ +sOorwIEnvONfpQxCzEEYcbpZHiO6ajhISjPv8TR/kH7ppakqIxG7C0NVEAIPeOO7 +AAmdtNEYKSgJZQX8uoTzyhI4/R66XuofORu7zFQksWgGP8F+HKbhkSzLpE+dApIw +ih/tuAYSUps59Z0KP4GAtbogETIZf5OlgV3tk43459k8mxV2ZYjzObtZEAr9pJSn +5FLX3UyaGc4uw6M6GLIPC02t4XK+4Z8m8Ny+QQKBgA7Dhpy5LUBsrd96MZqylEi8 +UFoFkTcHhzNh/FuYakmftl7rgVp+N2h9GfEoCHKJ2buIGOe8ylAsSQCtmuzhF5vh +L/PkZ9YG/IIOqPB6yev/4iNuOBaEEgKIIj5C2+aN/ZcqhaZEflFpXyNNp5EcZ8mr +lTHzPfO5lDLU7ojJpO+7AoGADKY5NFSehf6sjg9WBDA/0YSf6Ir0t/fhITKDu8ei +wqUJ+Sc8Qoxo3j25PmFF8bQAvW1KJiYU6QQ602LU66SmuZU5nIk0o5mRIZnoQdjo +2/8EifaeZjeWcwspgFMLMctwaVohYl6irczAnZMFFvqHIhGpHiLdif2et9qFdLci +NbECgYANfTp14X9l+KZYpIXECVwQpPZpeeK3O8qc+O8hJT4frKxtR5H1g5LOhlb4 +jxJAzJDCllPjEAxtejjtRLFjsznl87bjiRISbGmzzv8uUZJCbZZJtv/KGrt10rou +1tmiaqODxZc9ViFv8u25DM+Id0Kg8YOskslM8YdldkXHdy2a1wKBgAP1UBlMEX8k +vqKFsgkFgDL0KYX/Vazr6IsW35o3UntOYdyRpo28mmRRNFKM5fJIvaKJPJbLe+ee +5zmWx8Ild/bC95BAbzRyrbOyEbfpRJTzLFxvzAl4g5/kckwxsGMYokiVZ7T8oDN6 +yxuEEieqpfbHSACiMGkp8CzgOLrZQ99BAoGACAp9v6jCWEgUxxZkxW62LOTK8Wr+ +iNRJkVnWdHdKOj7N3xJWwC/JFSXFJ2kkItCrqU5cQe4S3HG7Zvhnn6F+CW8oCAhR +ugRusxiFwUFOiYWt5ZnZB68XRT0cyuosDQZEP4Nnpr4VSxJeOQ7g2Q90bwiAHdP1 +Nn9Z+6LlpnwF83U= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec new file mode 100644 index 0000000000..f488e73a94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec @@ -0,0 +1 @@ +rsa2040 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem new file mode 100644 index 0000000000..416ad67fa1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDcjCCAlugAwIBAgIUFdhUsJK/XuSsxS2GLAc6Q/dnYpowDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQZXZfcm9vdF9yc2FfMjA0MDAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjArMSkwJwYDVQQDDCBldl9pbnRfcnNhXzIwNDgt +ZXZfcm9vdF9yc2FfMjA0MDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBmjCBlzAMBgNVHRMEBTADAQH/MAsGA1Ud +DwQEAwIBBjBZBggrBgEFBQcBAQRNMEswSQYIKwYBBQUHMAGGPWh0dHA6Ly93d3cu +ZXhhbXBsZS5jb206ODg4OC9ldl9pbnRfcnNhXzIwNDgtZXZfcm9vdF9yc2FfMjA0 +MC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQEL +BQADggEAAJNwhipzaCUDddzc+heX+MgcJ9DcupEFuuSmEgdne3PgxhfhXrIqIT4X +4DpxmtUS4oB3FhhXLxlndiBVbC2GRzPN5Qhss3ULbyfVa3Bf45LyMpDNfjs2MozJ ++xLPjhQDJcMwq10RsDUhwQz4BCcCb5AoXHaMXZJe0J2ZhYBZMMZt/22an7mR9HRc +AOvnLXtzUEZSrIsIXC0LvnAcEMy6g3WPfeJCcJZ5cWw0DVabtGBTlPy7/dOFYtmI +2BHxsDj1pTKjitmgbVfA67u24Ct5glHzkVsQEPD4vB2J5Ptu0UidQ7fRyuZwpZuW +Q72nXFdSEs0UVGp8fSsQ8ORv2m21nQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..5bc5674b2c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec @@ -0,0 +1,7 @@ +issuer:ev_root_rsa_2040 +subject:ev_int_rsa_2048-ev_root_rsa_2040 +issuerKey:evRSA2040 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2048-ev_root_rsa_2040/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..1ab32ed4e2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIUO+CV3E1g9n7p1BWTj+qvQOZRjLUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmV2X2ludF9yc2FfMjA0OC1ldnJvb3QwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjgZAwgY0wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwTwYIKwYBBQUHAQEE +QzBBMD8GCCsGAQUFBzABhjNodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvZXZf +aW50X3JzYV8yMDQ4LWV2cm9vdC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUa +AYN0CQEwDQYJKoZIhvcNAQELBQADggEBAJ7HDMpaOr+hmteHqb414a3xwUpEO+X9 +Jh5zHvsAHG8DXXKu36Q25w+7joXsusD5GrDbZdXVEcNF3tpx+SqahzzDK0jzOIuO +26ZRVXxkJmhyI6WdMbIrm6fC0WjGeJl0ByHo3MYJrnOgNOrGxJy3Ecpk5ttlge41 +m8TzQIi7hXYmOLqmqJ0yQoyukfX7uSr/PZsKI3tjZ8Na/q/7HesgGVH4vdbzhlmu +lZP1MPPZmn9hWHkoLxjG4KI8hGAgaUlkwk2WKn5SC9IUuz52bm3Xz0rkK+C3RSQo +MJagAa0x+heCFeWJpuhiIOWKRCwol72o0Nm+mFKi4/qAxNWBI1kTD1A= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..a0cb6250dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:ev_int_rsa_2048-evroot +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key new file mode 100644 index 0000000000..bcd996ab23 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuQIBADANBgkqhkiG9w0BAQEFAASCBKMwggSfAgEAAoIBAADKcCDcIV9XkU00 +P65KAVERaXr5l6Xs6RhmSZ/CPxuIoRjL0wsQ2Rx7mg1O6JcvyuVsr1fyX8EnWipN +vLmCQowy71h78jh0EDMKD/sWuAKb14OWnvZ19t44wY9nGTy2wHL4sj0LM3QRJiel +e5AFV3HZ5iYD9TeI1/Y6+nJPXRCAlt8x+J8msetffENXmA4Aj81V2CfdJiOVyi9S +ageJfMQMWTs4cW68DKpZZxnG8prJtzp6lEdIo6o+CenrTUYeoAJ+VAkmYUcoudJD +l1z5oFQb79JedrUflREQsOdkT8fjhEF5G20iJzhMuABOIzQjcrHPXMPnPjG3u++h +YOaGLrsCAwEAAQKCAQAAstt0vOkjYqv3KVWmOK6HILowM7t/lxyvORiNdULqocGr +tdIFseIRH0eRwIkRouFB6M/XBUcC0jEAtWQsBuGjGxGK/R+aLzlsztQlxQHZFDXK +hlZ2bO0rk7u4Zp/Om6zXJ9Hayz2vq8MpPjU4nu+OoLWOGusaIOamH5/NRT91Z/4x +0SO2FqJv703x1sn3SQER0Cju/R2XIEWxokInPdemfr8RHbJ0GlqTx7IonMSiNvWp +mm7HqCBv2uHB0EvbsZgNSimMWhfa5BhkdKX3g12IK87ySu9O1vFJ+U2WyffXjmR/ +x3ipAX/yCNO0oXaLGCFiECzasDL6u6s41SAKMkZJAoGADzhE0NTU1qIazXam/DcL +hVDh1+xaYjQXLnkPACmuZR9tXFkzCrGYArnXogfeeh+3eON3T9vcQRdQYz2NGz/g +dQBv/P0dEOdjx6kifS1fDC2t4cnmWcNQoVnTa7mG8SY21PmUKyiLwP4h2oeZR3Fz +FEJJyi44nmxcJap4yMrX1N8CgYANTQvt0ZYvB6Hq1rI6TtZ66vEnDwUqbSm6B0lF +xjYaXE+PB7+FngZ67T9ObjI+8qqKas00CwvcfP5P0ynjyX+HDH93NXksaqnQ9+dU +KijtbwGw5VorjZwkplxtoxTJVIT1x8OVSoG7AWsH7RfumwYDlpW8oFmnn43CQj0y +jVJlpQKBgAnymi/wW+ipbWFLoxsIk1QgqGxrxCuZpmkuoNpXY/AeWWlZt93Oc++c +Lk9uW0BxCIdQDUS6DDzTEyy6J0dfOcLfdVLi0SOiSXpPlwZAKHaaSKNiRlf3K/U5 +89DeI0/szTvooKqQxr9umwvtQwcKJNBh/z7RdRo+8v9/a5C529X7AoGAAaZZ4XDK +wSCgO+HPj53xyqNTsDWTvXR25YU72HTChziGAcbDQc6dHShKXu8aOmadMrgWpers +2LeET+BwZLm8oMKzGNVAJ3s/fxUQ04a7NuA7BHceXSKeiIk+E7dTv7lFGLtjjiQE +vW5qmTwWaNk/wLgv8IqvNDR9P+g5cQjIfKUCgYAEAlfA1KIcC5hDKXxlZS22YwT7 +Jjdz1yi2q/oG03rAymLGKAI+CeN9wKkB5M4SJBgOJYKjqktqGnuY4r1wB3rsFKyK +tmp1XHHg/BAkcfm7wbRqlaoLZF8sOOdkUCiWGeo/XormEDe//PgknyKqTnbioBkJ +8/6ykM6T7fV7EOvnlg== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec new file mode 100644 index 0000000000..a85e16858b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec @@ -0,0 +1 @@ +evRSA2040 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem new file mode 100644 index 0000000000..fe3abd78a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcygAwIBAgIUJ7nCMgtzNcSPG7jAh3CWzlTGHQgwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQZXZfcm9vdF9yc2FfMjA0MDAiGA8yMDE1MDEwMTAwMDAw +MFoYDzIwMzUwMTAxMDAwMDAwWjAbMRkwFwYDVQQDDBBldl9yb290X3JzYV8yMDQw +MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQAAynAg3CFfV5FNND+uSgFR +EWl6+Zel7OkYZkmfwj8biKEYy9MLENkce5oNTuiXL8rlbK9X8l/BJ1oqTby5gkKM +Mu9Ye/I4dBAzCg/7FrgCm9eDlp72dfbeOMGPZxk8tsBy+LI9CzN0ESYnpXuQBVdx +2eYmA/U3iNf2OvpyT10QgJbfMfifJrHrX3xDV5gOAI/NVdgn3SYjlcovUmoHiXzE +DFk7OHFuvAyqWWcZxvKaybc6epRHSKOqPgnp601GHqACflQJJmFHKLnSQ5dc+aBU +G+/SXna1H5URELDnZE/H44RBeRttIic4TLgATiM0I3Kxz1zD5z4xt7vvoWDmhi67 +AgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEB +CwUAA4IBAAA/4/YVyeRLPr05Uw5j0JOCx5WNUv2HxemfvTZgF4QEg4vDt8ba3VDR +Xj3Z8hiGYG+s2Wz4k+82wCNRTglm3iutCJ/LbwOAZIa8dFyQUa03EssS0BBvVNhx +uu6+kYMqGteIX5Q94daqZe+0KM9xKbydNCQJKSMD8IV1YHKvotF91MFQHDdnVAZX +anpqDnw0j4YGknFHA1i++0GZC0aWxhRn6Epfza+bYCVogC5BviY6xYIg2kZE8kII +msQ6iUrKQ2OV7HmZ03BdpsGADorycyJ/wRGR3xDDg8RYUur80jU/D0eBq8BX1md8 +Rc+IyDmcFcs7hYRUaJAoxuLPvQ+/vy4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..fd1ade8dea --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec @@ -0,0 +1,7 @@ +issuer:ev_root_rsa_2040 +subject:ev_root_rsa_2040 +issuerKey:evRSA2040 +subjectKey:evRSA2040 +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/moz.build b/security/manager/ssl/tests/unit/test_keysize_ev/moz.build new file mode 100644 index 0000000000..96ea30e1f9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/moz.build @@ -0,0 +1,31 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem', +# 'ev_int_rsa_2040-evroot.pem', +# 'ev_int_rsa_2048-ev_root_rsa_2040.pem', +# 'ev_int_rsa_2048-evroot.pem', +# 'ev_root_rsa_2040.pem', +# 'evroot.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'ev_int_rsa_2040.key', +# 'ev_int_rsa_2048.key', +# 'ev_root_rsa_2040.key', +# 'evroot.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_local_cert.js b/security/manager/ssl/tests/unit/test_local_cert.js new file mode 100644 index 0000000000..2b0e804380 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_local_cert.js @@ -0,0 +1,87 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const certService = Cc["@mozilla.org/security/local-cert-service;1"].getService( + Ci.nsILocalCertService +); + +const gNickname = "local-cert-test"; + +function run_test() { + // Need profile dir to store the key / cert + do_get_profile(); + // Ensure PSM is initialized + Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + run_next_test(); +} + +function getOrCreateCert(nickname) { + return new Promise((resolve, reject) => { + certService.getOrCreateCert(nickname, { + handleCert(c, rv) { + if (rv) { + reject(rv); + return; + } + resolve(c); + }, + }); + }); +} + +function removeCert(nickname) { + return new Promise((resolve, reject) => { + certService.removeCert(nickname, { + handleResult(rv) { + if (rv) { + reject(rv); + return; + } + resolve(); + }, + }); + }); +} + +add_task(async function() { + // No master password, so no prompt required here + ok(!certService.loginPromptRequired); + + let certA = await getOrCreateCert(gNickname); + // The local cert service implementation takes the given nickname and uses it + // as the common name for the certificate it creates. nsIX509Cert.displayName + // uses the common name if it is present, so these should match. Should either + // implementation change to do something else, this won't necessarily work. + equal(certA.displayName, gNickname); + + // Getting again should give the same cert + let certB = await getOrCreateCert(gNickname); + equal(certB.displayName, gNickname); + + // Should be matching instances + ok(certA.equals(certB)); + + // Check an expected attribute + equal(certA.certType, Ci.nsIX509Cert.USER_CERT); + + // New nickname should give a different cert + let diffNameCert = await getOrCreateCert("cool-stuff"); + ok(!diffNameCert.equals(certA)); + + // Remove the cert, and get a new one again + await removeCert(gNickname); + let newCert = await getOrCreateCert(gNickname); + ok(!newCert.equals(certA)); + + // Drop all cert references and GC + let serial = newCert.serialNumber; + certA = certB = diffNameCert = newCert = null; + Cu.forceGC(); + Cu.forceCC(); + + // Should still get the same cert back + let certAfterGC = await getOrCreateCert(gNickname); + equal(certAfterGC.serialNumber, serial); +}); diff --git a/security/manager/ssl/tests/unit/test_logoutAndTeardown.js b/security/manager/ssl/tests/unit/test_logoutAndTeardown.js new file mode 100644 index 0000000000..1546bd2cce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_logoutAndTeardown.js @@ -0,0 +1,207 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +"use strict"; + +// This test ensures that in-progress https connections are cancelled when the +// user logs out of a PKCS#11 token. + +// Get a profile directory and ensure PSM initializes NSS. +do_get_profile(); +Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + +function getCert() { + return new Promise((resolve, reject) => { + let certService = Cc[ + "@mozilla.org/security/local-cert-service;1" + ].getService(Ci.nsILocalCertService); + certService.getOrCreateCert("beConservative-test", { + handleCert: (c, rv) => { + if (rv) { + reject(rv); + return; + } + resolve(c); + }, + }); + }); +} + +class InputStreamCallback { + constructor(output) { + this.output = output; + this.stopped = false; + } + + onInputStreamReady(stream) { + info("input stream ready"); + if (this.stopped) { + info("input stream callback stopped - bailing"); + return; + } + let available = 0; + try { + available = stream.available(); + } catch (e) { + // onInputStreamReady may fire when the stream has been closed. + equal( + e.result, + Cr.NS_BASE_STREAM_CLOSED, + "error should be NS_BASE_STREAM_CLOSED" + ); + } + if (available > 0) { + let request = NetUtil.readInputStreamToString(stream, available, { + charset: "utf8", + }); + ok( + request.startsWith("GET / HTTP/1.1\r\n"), + "Should get a simple GET / HTTP/1.1 request" + ); + let response = + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 2\r\n" + + "Content-Type: text/plain\r\n" + + "\r\nOK"; + let written = this.output.write(response, response.length); + equal( + written, + response.length, + "should have been able to write entire response" + ); + } + this.output.close(); + info("done with input stream ready"); + } + + stop() { + this.stopped = true; + this.output.close(); + } +} + +class TLSServerSecurityObserver { + constructor(input, output) { + this.input = input; + this.output = output; + this.callbacks = []; + this.stopped = false; + } + + onHandshakeDone(socket, status) { + info("TLS handshake done"); + info(`TLS version used: ${status.tlsVersionUsed}`); + + if (this.stopped) { + info("handshake done callback stopped - bailing"); + return; + } + + let callback = new InputStreamCallback(this.output); + this.callbacks.push(callback); + this.input.asyncWait(callback, 0, 0, Services.tm.currentThread); + + // We've set up everything needed for a successful request/response, + // but calling logoutAndTeardown should cause the request to be cancelled. + Cc["@mozilla.org/security/sdr;1"] + .getService(Ci.nsISecretDecoderRing) + .logoutAndTeardown(); + } + + stop() { + this.stopped = true; + this.input.close(); + this.output.close(); + this.callbacks.forEach(callback => { + callback.stop(); + }); + } +} + +class ServerSocketListener { + constructor() { + this.securityObservers = []; + } + + onSocketAccepted(socket, transport) { + info("accepted TLS client connection"); + let connectionInfo = transport.securityInfo.QueryInterface( + Ci.nsITLSServerConnectionInfo + ); + let input = transport.openInputStream(0, 0, 0); + let output = transport.openOutputStream(0, 0, 0); + let securityObserver = new TLSServerSecurityObserver(input, output); + this.securityObservers.push(securityObserver); + connectionInfo.setSecurityObserver(securityObserver); + } + + // For some reason we get input stream callback events after we've stopped + // listening, so this ensures we just drop those events. + onStopListening() { + info("onStopListening"); + this.securityObservers.forEach(observer => { + observer.stop(); + }); + } +} + +function getStartedServer(cert) { + let tlsServer = Cc["@mozilla.org/network/tls-server-socket;1"].createInstance( + Ci.nsITLSServerSocket + ); + tlsServer.init(-1, true, -1); + tlsServer.serverCert = cert; + tlsServer.setSessionTickets(false); + tlsServer.asyncListen(new ServerSocketListener()); + return tlsServer; +} + +const hostname = "example.com"; + +function storeCertOverride(port, cert) { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let overrideBits = + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH; + certOverrideService.rememberValidityOverride( + hostname, + port, + cert, + overrideBits, + true + ); +} + +function startClient(port) { + let req = new XMLHttpRequest(); + req.open("GET", `https://${hostname}:${port}`); + return new Promise((resolve, reject) => { + req.onload = () => { + ok(false, "should not have gotten load event"); + resolve(); + }; + req.onerror = () => { + ok(true, "should have gotten an error"); + resolve(); + }; + + req.send(); + }); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", hostname); + let cert = await getCert(); + + let server = getStartedServer(cert); + storeCertOverride(server.port, cert); + await startClient(server.port); + server.close(); +}); + +registerCleanupFunction(function() { + Services.prefs.clearUserPref("network.dns.localDomains"); +}); diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate.js b/security/manager/ssl/tests/unit/test_missing_intermediate.js new file mode 100644 index 0000000000..2a22666369 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate.js @@ -0,0 +1,95 @@ +// -*- 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 if a server does not send a complete certificate chain, we can +// make use of cached intermediates to build a trust path. + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +registerCleanupFunction(() => { + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + let args = ["-D", "-n", "manually-added-missing-intermediate"]; + run_certutil_on_directory(certDir.path, args, false); +}); + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + // If we don't know about the intermediate, we'll get an unknown issuer error. + add_connection_test( + "ee-from-missing-intermediate.example.com", + SEC_ERROR_UNKNOWN_ISSUER + ); + + // Make BadCertAndPinningServer aware of the intermediate. + add_test(() => { + let args = [ + "-A", + "-n", + "manually-added-missing-intermediate", + "-i", + "test_missing_intermediate/missing-intermediate.pem", + "-a", + "-t", + ",,", + ]; + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + run_certutil_on_directory(certDir.path, args); + run_next_test(); + }); + + // We have to start observing the topic before there's a chance it gets + // emitted. + add_test(() => { + TestUtils.topicObserved("psm:intermediate-certs-cached").then( + subjectAndData => { + Assert.equal(subjectAndData.length, 2, "expecting [subject, data]"); + Assert.equal(subjectAndData[1], "1", `expecting "1" cert imported`); + run_next_test(); + } + ); + run_next_test(); + }); + // Connect and cache the intermediate. + add_connection_test( + "ee-from-missing-intermediate.example.com", + PRErrorCodeSuccess + ); + + // Add a dummy test so that the only way we advance from here is by observing + // "psm:intermediate-certs-cached". + add_test(() => {}); + + // Delete the intermediate on the server again. + add_test(() => { + clearSessionCache(); + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + let args = ["-D", "-n", "manually-added-missing-intermediate"]; + run_certutil_on_directory(certDir.path, args); + run_next_test(); + }); + + // Since we cached the intermediate in gecko, this should succeed. + add_connection_test( + "ee-from-missing-intermediate.example.com", + PRErrorCodeSuccess + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem new file mode 100644 index 0000000000..985077c6b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUVwdwwrCWfp82pGODTXMV35GajGQwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRNaXNzaW5nIEludGVybWVkaWF0ZTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQAD +ggEBAFDTK/9saOeJ3Sb0vjJ0ogp/E7WrpjHaMsx7janNrpaIGqn+vaICF30Muazb +/LywCjvXsJCFI1aPh+s4eavMPZVEdDIsoQIwdBLCU8u/s1wVlA+BHOy/M0u+7rGw ++F2AeKd4vUfZJ4jrxSorxqCuwyE606UXImSSngpJq4dRJul4cDcHOg6uSRl/hPU+ +sjGdo2DIJKiGquBwmMVgEwIF6qSP7iI+qguy2k6XykGnVSN/HASqB+0UfYvvHhkI +3sPcsU1LM3tW5hnM/81SE0JUHyvNgXEHHXO1FST2U6H6LyrTsem3Ga33yhBoayD/ +L1P2Qgq8tryeqcV4cqolR7MfYx4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec new file mode 100644 index 0000000000..c21e757449 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Missing Intermediate +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build b/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build new file mode 100644 index 0000000000..d9282b6044 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# BadCertAndPinningServer takes as an argument a path to a directory and loads +# every key and certificate in it. We want to test what happens when a +# server doesn't include an intermediate that is necessary to build a +# complete trust path. The easiest way to do this right now is to put +# the intermediate in a different directory, so that BadCertAndPinningServer +# doesn't know about it and can't send it in the TLS handshake. +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'missing-intermediate.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_name_constraints.js b/security/manager/ssl/tests/unit/test_name_constraints.js new file mode 100644 index 0000000000..e04eb93b0c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints.js @@ -0,0 +1,71 @@ +// -*- 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"; + +// This test tests two specific items: +// 1. Are name constraints properly enforced across the entire constructed +// certificate chain? This makes use of a certificate hierarchy like so: +// - (trusted) root CA with permitted subtree dNSName example.com +// - intermediate CA with permitted subtree dNSName example.org +// a. end-entity with dNSNames example.com and example.org +// (the first entry is allowed by the root but not by the intermediate, +// and the second entry is allowed by the intermediate but not by the +// root) +// b. end-entity with dNSName example.com (not allowed by the intermediate) +// c. end-entity with dNSName examle.org (not allowed by the root) +// d. end-entity with dNSName example.test (not allowed by either) +// All of these cases should fail to verify with the error that the +// end-entity is not in the name space permitted by the hierarchy. +// +// 2. Are externally-imposed name constraints properly enforced? This makes use +// of a certificate hierarchy rooted by a certificate with the same DN as an +// existing hierarchy that has externally-imposed name constraints (DCISS). + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(name) { + return constructCertFromFile(`test_name_constraints/${name}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, `test_name_constraints/${certName}.pem`, trustString); +} + +function checkCertNotInNameSpace(cert) { + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_CERT_NOT_IN_NAME_SPACE, + certificateUsageSSLServer + ); +} + +function checkCertInNameSpace(cert) { + return checkCertErrorGeneric( + certdb, + cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); +} + +add_task(async function() { + // Test that name constraints from the entire certificate chain are enforced. + loadCertWithTrust("ca-example-com-permitted", "CTu,,"); + loadCertWithTrust("int-example-org-permitted", ",,"); + await checkCertNotInNameSpace(certFromFile("ee-example-com-and-org")); + await checkCertNotInNameSpace(certFromFile("ee-example-com")); + await checkCertNotInNameSpace(certFromFile("ee-example-org")); + await checkCertNotInNameSpace(certFromFile("ee-example-test")); + + // Test that externally-imposed name constraints are enforced (DCISS tests). + loadCertWithTrust("dciss", "CTu,,"); + await checkCertInNameSpace(certFromFile("NameConstraints.dcissallowed")); + await checkCertNotInNameSpace(certFromFile("NameConstraints.dcissblocked")); +}); diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem new file mode 100644 index 0000000000..819737c643 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUH/IH7a1iPGpyhpstium2HZvHBr0wDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEExCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJDQTEMMAoGA1UECgwDRm9vMRcwFQYDVQQDDA5mb28uZXhhbXBsZS5m +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEALZy0l4IRtgX2v24zAUssBpdMpfUt +2Evctbg02kRX3y1cWvoXMq4qrnoMhoaNBpdMf8m1kqbsirPaT5NHsr7V/NgJGPwA +cHBEb1oV+Smy8KfhqF12VD2gWYHxs9Ooc67+Bf90cZO9yPpOjiNqJeMtat/xVA+e +dG1kE6V5tMufIi4wARy4tjaMWoD2aw4oYFn1VREkOeyT79JzCTJMBR1bArVhas7D +mn+EON5e16oYmFPfSRT3oWmtEHa3Er0M5v0icSaEA7YFkPdoXLRNxstggh7IPcD4 +3dmH0xosUax8+E4gp0lVk+ok0nEvRNcw+KTopFSO83tPn/4yLQMGjGB8Rg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec new file mode 100644 index 0000000000..1a02a0cc1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec @@ -0,0 +1,2 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:/C=US/ST=CA/O=Foo/CN=foo.example.fr diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem new file mode 100644 index 0000000000..ac0349ac7b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWDCCAkCgAwIBAgIUdb90UMieOa6hVljB8cPlSVhDhNUwDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEIxCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJDQTEMMAoGA1UECgwDRm9vMRgwFgYDVQQDDA9mb28uZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKIQo2A4GXqb8uYaOekw5f/SJBg4 +iPiOlhNNGEmczSCty8UbFDrd3L44EpH1Wi5YvuxnqWwHzLxU4Ze2aJIwIZ04godV +nHCd57qFsuakPdxesdGeFdeM/Ni2h6YhZkyoZzmUKtKbMcoCQOq/WPzXehU9/D2n +okuePkoXw92YVSFq/IBuKcPpQKIpKq+Oho9PbDXho3ZDYW5PVReif2I9Pp9mIIfN +rGkM/oSA+3brZGe8fXUIg6zXlTiXX70FdIuWeXcd5TjY141+27jshjXvIy+5ZZep +uPCx9jYjmOUklbf8hKeKZzFZfXo3Fg1QlXcMOmZbE4rgF7wKysux6jgnEo8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec new file mode 100644 index 0000000000..eabee87e83 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec @@ -0,0 +1,2 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:/C=US/ST=CA/O=Foo/CN=foo.example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem new file mode 100644 index 0000000000..efb0e9828c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUW/imFdGk/JA1NKPzOw1+UoGjVIUwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2EtZXhhbXBsZS1jb20tcGVybWl0dGVkMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGNhLWV4YW1w +bGUtY29tLXBlcm1pdHRlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaM5MDcwDAYDVR0TBAUwAwEB/zALBgNVHQ8E +BAMCAQYwGgYDVR0eBBMwEaAPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUA +A4IBAQBCxftaoGEXtPvmno3v44S7ahV7PYR6kNE1VxZDifghRNneBc+um3r/S6Rz +Qfej9e+u6/pSNyW1laZE3EXCKX9za5LE//qbm4l7UaomqO95BD3oVNV5pVNuC5Hc +JyLLbFTT4QKi1pHoD/Wjv17f4rBl13MFqXB4Nt9KqvZOn1RGcU+dPgivuuNYXGEq +0REsQRqloVOdZ9WhF0lEUNDvWhxxZi1arLlv5UCrQZ+srvroZMrjyQJ9Wu3RH6Hm +HdpBkIkoghiykIILF23zWeb8tgqlakkTtuVU1dnzFhP8NZDMYG7Ms2vpTkbBjnwb +cYKuzvcsfwnFbmAN9v0/Hzo4zZrh +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec new file mode 100644 index 0000000000..1cc3c1d81b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-example-com-permitted +subject:ca-example-com-permitted +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:nameConstraints:permitted:example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem new file mode 100644 index 0000000000..ae37ac46a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIUcxz6c/GMYB7/nrD4zXg4j6UrJckwDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMIGFMQswCQYDVQQGEwJGUjEP +MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEQMA4GA1UEChMHUE0vU0dE +TjEOMAwGA1UECxMFRENTU0kxDjAMBgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcNAQkB +FhRpZ2NhQHNnZG4ucG0uZ291di5mcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zAL +BgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKUhmbYZJnpAEOUHAxYTaGZD +0juaNppvdhTeI2T3bfIVgL3qFqPeom3pLNU+Rnl1hTplxl0C9wxIEl849nc9cWxa +EK/JCnGHrBCZ4qJn9xUN96AhGICE654c7CgBNLKs8KZ6tAunAGtxCR6c5R7L5G7m +fA7DWX9lEI0R9L0NJzWyhELsafoMlZGFTiIERiYGhotemxf+QEPWAWn3cfFgN0ma +aK23cFbzw6SXHbC2y9OCtz8nWgn417Los+H2emQrBqISdvPh54EU2uCb7vxH2/ly +KZW8QFo5M3/UCuy/X47y7gUTHQQ+BhX9Dz40sp7DP0pDSwt0fksVxXlZoldMppM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec new file mode 100644 index 0000000000..5d53706bc5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem new file mode 100644 index 0000000000..10064a2c0b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAeagAwIBAgIUcVd3d0Lp6rsQX88nbU7VYHOOVKswDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZlZS1leGFt +cGxlLWNvbS1hbmQtb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABoycwJTAjBgNVHREEHDAaggtleGFtcGxlLmNv +bYILZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADggEBAKZjORSM/94cF9uzMJCX +MZ3JmZKiMRXCW9Y1mCKeimvV5LqFyRVMlE7DAHXuPwzaJVS1y/q99dUcUfMd5q1b +jEMdLc4qM+7JSpI1qxoeFQPym+3tCH15u6ZXkPzrAdGElVraCEYsCWjEmpMaZS6Q +Zfbe7mcBqIDiFKQma6tioiwfdg2KLKb/bFML/guxGVIYFla8UaiOFtQ0mLg6qMrp +1RdjqJhGqqD71IS+ez65W4gaizKgAyBmKqOqRoSjvF7lqrQNAOk7m+pY4Dzlxyg9 +iGYyNVWen1R436FLJEgdFQOefGY5vhtg5dVX+D/MH+vRX8apumQ3Q1sVMgoLb5v3 +yWw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec new file mode 100644 index 0000000000..904ca65955 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-com-and-org +extension:subjectAlternativeName:example.com,example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem new file mode 100644 index 0000000000..3b04129003 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIULdge2q8uLXhglJkSVlCLPnl/KsswDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAZMRcwFQYDVQQDDA5lZS1leGFt +cGxlLWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAKazM8Y0fbv4mYND26inNXWTooZz6G4zFxa9TDVEYYl0W5mS +kC0nE1L38cP7hFpuKwChl87UNHgkpxplSozadgSUg1yqyZ+F1KzpAs1647WHqAgB +cIPzhR1Y7d1v3/jkCxioYvwudeXwO8eqH3EPOz5h70U8LRY+Dney+qT9OLAvyAl/ +dpF3ZjT3AQRTT90ZL15I+rLR10kI4a2MwqUALaEmZtZAp1ecDoh/71VJF4CEPb3l +JE7rR/Ff5VHC6fNMJcoc9Ze6laEOH3+BK+l8wpf4ABGiCdkfUsHbO3W/g0h4QKhS +Me7tz24aSISqinNGxOGcFVBB//V1sPGkH3lFVTc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec new file mode 100644 index 0000000000..46630c4a1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-com +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem new file mode 100644 index 0000000000..12545e3748 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUd1DYJK/QJRwY0oGdFXeMsRKcwhAwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAZMRcwFQYDVQQDDA5lZS1leGFt +cGxlLW9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5vcmcwDQYJKoZI +hvcNAQELBQADggEBAJyjoYfBfON+x24YHczjV3ngQfTH0SZ4WzebR/lqsIrKKx08 +siDPKpdrkNGDyQ0A9pxaLMgDjl9e+7Z8aWLklzGYY1TN8/KWaQdqAN9VAL/9QfIz +qo5jxzEt29nNvO9NTc9sBQ/fPiTydI96JJgsWPg/ikw3y0c+1IPVYT0jSCxHc7qN +MLXtmDxl7ZoMyPKU9ZIACHSU3+BZee/TTqZT97TIEYkS39bJUyP6UwttTfh4Zm8l +3Eju6bMPrQGu/M1hy+n6bliY+qxnJ0TDaJcHfd6ox9SFGajjAvU2KMVfiG7NzzBP +qdmp5Hw6BIskbjzGD9TfOiQiDd/CqwfuoXStH1M= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec new file mode 100644 index 0000000000..6a24090e51 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-org +extension:subjectAlternativeName:example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem new file mode 100644 index 0000000000..a15e04cf60 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUMV6sDJo62fVf2QrGVmoUYUmkl5AwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9lZS1leGFt +cGxlLXRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjGzAZMBcGA1UdEQQQMA6CDGV4YW1wbGUudGVzdDANBgkq +hkiG9w0BAQsFAAOCAQEAZyhNrPkiThyQJBib0iYbXOP7NOEdenQzeyCRZJ5QcPZM +jO5iXpRRzyEqBDyOtnIG6UihP98qOmF7T8RTZmZ0Ex8Kzw5iHniXYDJPr5pnaTG+ +INyKLMMVr884xHEKKarX2sg52b+u01gAUBD6B9yQZ3MAdqjNyqcbYmOVzreFsYcL +ddhhC9/B0iE801OPf2/vbAIcLNKVXSkPJ0Xry3KeGqwc3v5a4SNmEGLYBZKdaIAb +q4a6ViUPFxS/MduXzXxzU8FaXDMZj8eGezExuDUWrZvWLjmfl5RaV+/JJbTRcMKR +xIVqTKtCbuXvNsetc0/IIQ4lz7eMniQrGQd6QM3HRg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec new file mode 100644 index 0000000000..0926ce477a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-test +extension:subjectAlternativeName:example.test diff --git a/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem new file mode 100644 index 0000000000..4c491d708c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEjCCAfqgAwIBAgIUTwrMhhSd1s9Xs6fjDP+FeWX6YigwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2EtZXhhbXBsZS1jb20tcGVybWl0dGVkMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCQxIjAgBgNVBAMMGWludC1leGFt +cGxlLW9yZy1wZXJtaXR0ZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOTA3MAwGA1UdEwQFMAMBAf8wCwYDVR0P +BAQDAgEGMBoGA1UdHgQTMBGgDzANggtleGFtcGxlLm9yZzANBgkqhkiG9w0BAQsF +AAOCAQEAoHM57NeL7TRmMXZ5eR6hep2vYELQ6x6OHIZQy6v/B9mDY5kdNkO3tcbW +jEbdL3wInvxxaUWgDfdHlW6isUDMWn9pqAejytzwQveCHHve+yPmaR5Kgnm/LR7U +ygE8f1CDpm/u/+q8UXzG7B8g3qwo1HRWx07G43ZXbMp/0BiBdA2Hjhj9drohosAY +g2aDqaRIUeq97PCarNztkzr//zt9eCXg8qQBjVSghB03ikFRBmkCBVBNLqq6iqN+ +wb6Crc5RKKEec8n1HHEBnl16sfF/W9Z3GYFXf/Oesnz9JyaLuns1MiZx+TEf9afn +sg4XFW8K1vQ+t/1CR+OB1sEhmgkd2A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec new file mode 100644 index 0000000000..87e2cf8a56 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-example-com-permitted +subject:int-example-org-permitted +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:nameConstraints:permitted:example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/moz.build b/security/manager/ssl/tests/unit/test_name_constraints/moz.build new file mode 100644 index 0000000000..0bc6b1bb38 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'NameConstraints.dcissallowed.pem', +# 'NameConstraints.dcissblocked.pem', +# 'ca-example-com-permitted.pem', +# 'int-example-org-permitted.pem', +# 'ee-example-com-and-org.pem', +# 'ee-example-com.pem', +# 'ee-example-org.pem', +# 'ee-example-test.pem', +# 'dciss.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_nonascii_path.js b/security/manager/ssl/tests/unit/test_nonascii_path.js new file mode 100644 index 0000000000..cac942b212 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nonascii_path.js @@ -0,0 +1,62 @@ +// -*- 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 to make sure that the certificate DB works with non-ASCII paths. + +// Append a single quote and non-ASCII characters to the profile path. +let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment +); +let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); +let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); +file.initWithPath(profd); +file.append("'÷1"); +env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + +file = do_get_profile(); // must be called before getting nsIX509CertDB +Assert.ok( + /[^\x20-\x7f]/.test(file.path), + "the profile path should contain a non-ASCII character" +); +if (mozinfo.os == "win") { + file.QueryInterface(Ci.nsILocalFileWin); + Assert.ok( + /[^\x20-\x7f]/.test(file.canonicalPath), + "the profile short path should contain a non-ASCII character" + ); +} + +// Restore the original value. +env.set("XPCSHELL_TEST_PROFILE_DIR", profd); + +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert_name, trust_string) { + let cert_filename = cert_name + ".pem"; + return addCertFromFile( + certdb, + "test_cert_trust/" + cert_filename, + trust_string + ); +} + +function run_test() { + let certList = ["ca", "int", "ee"]; + let loadedCerts = []; + for (let certName of certList) { + loadedCerts.push(load_cert(certName, ",,")); + } + + let ca_cert = loadedCerts[0]; + notEqual(ca_cert, null, "CA cert should have successfully loaded"); + let int_cert = loadedCerts[1]; + notEqual(int_cert, null, "Intermediate cert should have successfully loaded"); + let ee_cert = loadedCerts[2]; + notEqual(ee_cert, null, "EE cert should have successfully loaded"); +} diff --git a/security/manager/ssl/tests/unit/test_nsCertType.js b/security/manager/ssl/tests/unit/test_nsCertType.js new file mode 100644 index 0000000000..8341575473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsCertType.js @@ -0,0 +1,32 @@ +// -*- 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/. +// +// While the Netscape certificate type extension is not a standard and has been +// discouraged from use for quite some time, it is still encountered. Thus, we +// handle it slightly differently from other unknown extensions. +// If it is not marked critical, we ignore it. +// If it is marked critical: +// If the basic constraints and extended key usage extensions are also +// present, we ignore it, because they are standardized and should convey the +// same information. +// Otherwise, we reject it with an error indicating an unknown critical +// extension. + +"use strict"; + +function run_test() { + do_get_profile(); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_connection_test("nsCertTypeNotCritical.example.com", PRErrorCodeSuccess); + add_connection_test( + "nsCertTypeCriticalWithExtKeyUsage.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "nsCertTypeCritical.example.com", + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION + ); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js b/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js new file mode 100644 index 0000000000..5febcbf169 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js @@ -0,0 +1,70 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// This file tests the nsIX509CertValidity implementation. + +function fuzzyEqual(attributeName, dateString, expectedTime) { + info(`${attributeName}: ${dateString}`); + let absTimeDiff = Math.abs(expectedTime - Date.parse(dateString)); + const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; + lessOrEqual( + absTimeDiff, + ONE_DAY_IN_MS, + `Time difference for ${attributeName} should be <= one day` + ); +} + +function run_test() { + // Date.parse("2013-01-01T00:00:00Z") + const NOT_BEFORE_IN_MS = 1356998400000; + // Date.parse("2014-01-01T00:00:00Z") + const NOT_AFTER_IN_MS = 1388534400000; + let cert = constructCertFromFile("bad_certs/expired-ee.pem"); + + equal( + cert.validity.notBefore, + NOT_BEFORE_IN_MS * 1000, + "Actual and expected notBefore should be equal" + ); + equal( + cert.validity.notAfter, + NOT_AFTER_IN_MS * 1000, + "Actual and expected notAfter should be equal" + ); + + // The following tests rely on the implementation of nsIX509CertValidity + // providing long formatted dates to work. If this is not true, a returned + // short formatted date such as "12/31/12" may be interpreted as something + // other than the expected "December 31st, 2012". + // + // On Android, the implementation of nsIDateTimeFormat currently does not + // return a long formatted date even if it is asked to. This, combined with + // the reason above is why the following tests are disabled on Android. + if (AppConstants.platform != "android") { + fuzzyEqual( + "notBeforeLocalTime", + cert.validity.notBeforeLocalTime, + NOT_BEFORE_IN_MS + ); + fuzzyEqual( + "notBeforeLocalDay", + cert.validity.notBeforeLocalDay, + NOT_BEFORE_IN_MS + ); + fuzzyEqual("notBeforeGMT", cert.validity.notBeforeGMT, NOT_BEFORE_IN_MS); + + fuzzyEqual( + "notAfterLocalTime", + cert.validity.notAfterLocalTime, + NOT_AFTER_IN_MS + ); + fuzzyEqual( + "notAfterLocalDay", + cert.validity.notAfterLocalDay, + NOT_AFTER_IN_MS + ); + fuzzyEqual("notAfterGMT", cert.validity.notAfterGMT, NOT_AFTER_IN_MS); + } +} diff --git a/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js b/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js new file mode 100644 index 0000000000..6305b878b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js @@ -0,0 +1,96 @@ +// -*- 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"; + +// Checks that various nsIX509Cert attributes correctly handle UTF-8. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function run_test() { + let cert = certDB.constructX509FromBase64( + "MIIF3DCCBMSgAwIBAgIEAJiZbzANBgkqhkiG9w0BAQUFADCCAQ0xYTBfBgNVBAMM" + + "WEkuQ0EgLSBRdWFsaWZpZWQgcm9vdCBjZXJ0aWZpY2F0ZSAoa3ZhbGlmaWtvdmFu" + + "w70gY2VydGlmaWvDoXQgcG9za3l0b3ZhdGVsZSkgLSBQU0VVRE9OWU0xCzAJBgNV" + + "BAYTAkNaMS8wLQYDVQQHDCZQb2R2aW5uw70gbWzDvW4gMjE3OC82LCAxOTAgMDAg" + + "UHJhaGEgOTEsMCoGA1UECgwjUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRh" + + "IGEucy4xPDA6BgNVBAsMM0FrcmVkaXRvdmFuw70gcG9za3l0b3ZhdGVsIGNlcnRp" + + "ZmlrYcSNbsOtY2ggc2x1xb5lYjAeFw0wMjEyMTIxMzMzNDZaFw0wMzEyMTIxMzMz" + + "NDZaMIIBFDELMAkGA1UEBhMCQ1oxHzAdBgNVBAMeFgBMAHUAZAEbAGsAIABSAGEB" + + "YQBlAGsxGTAXBgNVBAgeEABWAHkAcwBvAQ0AaQBuAGExLzAtBgNVBAceJgBQAGEA" + + "YwBvAHYALAAgAE4A4QBkAHIAYQF+AG4A7QAgADcANgA5MSUwIwYJKoZIhvcNAQkB" + + "FhZsdWRlay5yYXNla0BjZW50cnVtLmN6MRMwEQYDVQQqHgoATAB1AGQBGwBrMQ0w" + + "CwYDVQQrHgQATABSMR8wHQYDVQQpHhYATAB1AGQBGwBrACAAUgBhAWEAZQBrMRMw" + + "EQYDVQQEHgoAUgBhAWEAZQBrMRcwFQYDVQQFEw5JQ0EgLSAxMDAwMzc2OTCBnzAN" + + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxc7dGd0cNlHZ7tUUl5k30bfYlY3lnOD0" + + "49JGbTXSt4jNFMRLj6s/777W3kcIdcIwdKxjQULBKgryDvZJ1DAWp2TwzhPDVYj3" + + "sU4Niqb7mOUcp/4ckteUxGF6FmXtJR9+XHTuLZ+omF9HOUefheBKnXvZuqrLM16y" + + "nbJn4sPwwdcCAwEAAaOCAbswggG3MCUGA1UdEQQeMBygGgYKKwMGAQQB3BkCAaAM" + + "DAoxNzYyODk2ODgzMGkGA1UdHwRiMGAwHqAcoBqGGGh0dHA6Ly9xLmljYS5jei9x" + + "aWNhLmNybDAeoBygGoYYaHR0cDovL2IuaWNhLmN6L3FpY2EuY3JsMB6gHKAahhho" + + "dHRwOi8vci5pY2EuY3ovcWljYS5jcmwwHwYDVR0jBBgwFoAUK1oKfvvlDYUsZTBy" + + "vGN701mca/UwHQYDVR0OBBYEFPAs70DB+LS0PnA6niPUfJ5wdQH5MIG4BgNVHSAE" + + "gbAwga0wgaoGCysGAQQBs2EBAQQEMIGaMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3" + + "LmljYS5jei9xY3AvY3BxcGljYTAyLnBkZjBnBggrBgEFBQcCAjBbGllUZW50byBj" + + "ZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28gS3ZhbGlmaWtvdmFueSBjZXJ0aWZpa2F0" + + "IHYgc291bGFkdSBzZSB6YWtvbmVtIDIyNy8yMDAwIFNiLjAYBggrBgEFBQcBAwQM" + + "MAowCAYGBACORgEBMA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQUFAAOCAQEA" + + "v2V+nnYYMIgabmmgHx49CtlZIHdGS3TuWKXw130xFhbXDnNhEbx3alaskNsvjQQR" + + "Lqs1ZwKy58yynse+eJYHqenmHDACpAfVpCF9PXC/mDarVsoQw7NTcUpsAFhSd/zT" + + "v9jIf3twECyxx/RVzONVcob7nPePESHiKoG4FbtcuUh0wSHvCmTwRIQqPDCIuHcF" + + "StSt3Jr9iXcbXEhe4mSccOZ8N+r7Rv3ncKcevlRl7uFfDKDTyd43SZeRS/7J8KRf" + + "hD/h2nawrCFwc5gJW10aLJGFL/mcS7ViAIT9HCVk23j4TuBjsVmnZ0VKxB5edux+" + + "LIEqtU428UVHZWU/I5ngLw==" + ); + + equal( + cert.emailAddress, + "ludek.rasek@centrum.cz", + "Actual and expected emailAddress should match" + ); + equal( + cert.subjectName, + 'serialNumber=ICA - 10003769,SN=Rašek,name=Luděk Rašek,initials=LR,givenName=Luděk,E=ludek.rasek@centrum.cz,L="Pacov, Nádražní 769",ST=Vysočina,CN=Luděk Rašek,C=CZ', + "Actual and expected subjectName should match" + ); + equal( + cert.commonName, + "Luděk Rašek", + "Actual and expected commonName should match" + ); + equal(cert.organization, "", "Actual and expected organization should match"); + equal( + cert.organizationalUnit, + "", + "Actual and expected organizationalUnit should match" + ); + equal( + cert.displayName, + "Luděk Rašek", + "Actual and expected displayName should match" + ); + equal( + cert.issuerName, + 'OU=Akreditovaný poskytovatel certifikačních služeb,O=První certifikační autorita a.s.,L="Podvinný mlýn 2178/6, 190 00 Praha 9",C=CZ,CN=I.CA - Qualified root certificate (kvalifikovaný certifikát poskytovatele) - PSEUDONYM', + "Actual and expected issuerName should match" + ); + equal( + cert.issuerCommonName, + "I.CA - Qualified root certificate (kvalifikovaný certifikát poskytovatele) - PSEUDONYM", + "Actual and expected issuerCommonName should match" + ); + equal( + cert.issuerOrganization, + "První certifikační autorita a.s.", + "Actual and expected issuerOrganization should match" + ); + equal( + cert.issuerOrganizationUnit, + "Akreditovaný poskytovatel certifikačních služeb", + "Actual and expected issuerOrganizationUnit should match" + ); +} diff --git a/security/manager/ssl/tests/unit/test_nss_shutdown.js b/security/manager/ssl/tests/unit/test_nss_shutdown.js new file mode 100644 index 0000000000..36cf283477 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nss_shutdown.js @@ -0,0 +1,48 @@ +/* -*- 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"; + +// This test attempts to ensure that PSM doesn't deadlock or crash when shutting +// down NSS while a background thread is attempting to use NSS. +// Uses test_signed_apps/app_mf-1_sf-1_p7-1.zip from test_signed_apps.js. + +function startAsyncNSSOperation(certdb, appFile) { + return new Promise((resolve, reject) => { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + appFile, + function(rv, aZipReader, aSignerCert) { + // rv will either indicate success (if NSS hasn't been shut down yet) or + // it will be some error code that varies depending on when NSS got shut + // down. As such, there's nothing really to check here. Just resolve the + // promise to continue execution. + resolve(); + } + ); + }); +} + +add_task(async function() { + do_get_profile(); + let psm = Cc["@mozilla.org/psm;1"] + .getService(Ci.nsISupports) + .QueryInterface(Ci.nsIObserver); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let appFile = do_get_file("test_signed_apps/app_mf-1_sf-1_p7-1.zip"); + + let promises = []; + for (let i = 0; i < 25; i++) { + promises.push(startAsyncNSSOperation(certdb, appFile)); + } + // Trick PSM into thinking it should shut down NSS. If this test doesn't + // hang or crash, we're good. + psm.observe(null, "profile-before-change", null); + for (let i = 0; i < 25; i++) { + promises.push(startAsyncNSSOperation(certdb, appFile)); + } + await Promise.all(promises); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_caching.js b/security/manager/ssl/tests/unit/test_ocsp_caching.js new file mode 100644 index 0000000000..68b3778bb9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js @@ -0,0 +1,406 @@ +// -*- 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"; + +// Checks various aspects of the OCSP cache, mainly to to ensure we do not fetch +// responses more than necessary. + +var gFetchCount = 0; +var gGoodOCSPResponse = null; +var gResponsePattern = []; +var gMessage = ""; + +function respondWithGoodOCSP(request, response) { + info("returning 200 OK"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gGoodOCSPResponse); +} + +function respondWithSHA1OCSP(request, response) { + info("returning 200 OK with sha-1 delegated response"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + + let args = [["good-delegated", "default-ee", "delegatedSHA1Signer", 0]]; + let responses = generateOCSPResponses(args, "ocsp_certs"); + response.write(responses[0]); +} + +function respondWithError(request, response) { + info("returning 500 Internal Server Error"); + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + let body = "Refusing to return a response"; + response.bodyOutputStream.write(body, body.length); +} + +function generateGoodOCSPResponse(thisUpdateSkew) { + let args = [["good", "default-ee", "unused", thisUpdateSkew]]; + let responses = generateOCSPResponses(args, "ocsp_certs"); + return responses[0]; +} + +function add_ocsp_test( + aHost, + aExpectedResult, + aResponses, + aMessage, + aOriginAttributes +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + clearSessionCache(); + gFetchCount = 0; + gResponsePattern = aResponses; + gMessage = aMessage; + }, + function() { + // check the number of requests matches the size of aResponses + equal( + gFetchCount, + aResponses.length, + "should have made " + + aResponses.length + + " OCSP request" + + (aResponses.length == 1 ? "" : "s") + ); + }, + null, + aOriginAttributes + ); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + info("gFetchCount: " + gFetchCount); + let responseFunction = gResponsePattern[gFetchCount]; + Assert.notEqual(undefined, responseFunction); + + ++gFetchCount; + responseFunction(request, response); + }); + ocspResponder.start(8888); + + add_tests(); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + run_next_test(); +} + +function add_tests() { + // Test that verifying a certificate with a "short lifetime" doesn't result + // in OCSP fetching. Due to longevity requirements in our testing + // infrastructure, the certificate we encounter is valid for a very long + // time, so we have to define a "short lifetime" as something very long. + add_test(function() { + Services.prefs.setIntPref( + "security.pki.cert_short_lifetime_in_days", + 12000 + ); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "expected zero OCSP requests for a short-lived certificate" + ); + + add_test(function() { + Services.prefs.setIntPref("security.pki.cert_short_lifetime_in_days", 100); + run_next_test(); + }); + + // If a "short lifetime" is something more reasonable, ensure that we do OCSP + // fetching for this long-lived certificate. + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithError], + "expected one OCSP request for a long-lived certificate" + ); + add_test(function() { + Services.prefs.clearUserPref("security.pki.cert_short_lifetime_in_days"); + run_next_test(); + }); + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // This test assumes that OCSPStaplingServer uses the same cert for + // ocsp-stapling-unknown.example.com and ocsp-stapling-none.example.com. + + // Get an Unknown response for the *.example.com cert and put it in the + // OCSP cache. + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + [], + "Stapled Unknown response -> a fetch should not have been attempted" + ); + + // A failure to retrieve an OCSP response must result in the cached Unknown + // response being recognized and honored. + add_ocsp_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + [ + respondWithError, + respondWithError, + respondWithError, + respondWithError, + respondWithError, + respondWithError, + ], + "No stapled response -> a fetch should have been attempted" + ); + + // A valid Good response from the OCSP responder must override the cached + // Unknown response. + // + // Note that We need to make sure that the Unknown response and the Good + // response have different thisUpdate timestamps; otherwise, the Good + // response will be seen as "not newer" and it won't replace the existing + // entry. + add_test(function() { + gGoodOCSPResponse = generateGoodOCSPResponse(1200); + run_next_test(); + }); + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "Cached Unknown response, no stapled response -> a fetch" + + " should have been attempted" + ); + + // The Good response retrieved from the previous fetch must have replaced + // the Unknown response in the cache, resulting in the catched Good response + // being returned and no fetch. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Cached Good response -> a fetch should not have been attempted" + ); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // A failure to retrieve an OCSP response will result in an error entry being + // added to the cache. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithError], + "No stapled response -> a fetch should have been attempted" + ); + + // The error entry will prevent a fetch from happening for a while. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure -> a fetch should not have been attempted" + ); + + // The error entry must not prevent a stapled OCSP response from being + // honored. + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + [], + "Stapled Revoked response -> a fetch should not have been attempted" + ); + + // --------------------------------------------------------------------------- + + // Ensure OCSP responses from signers with SHA1 certificates are OK. This + // is included in the OCSP caching tests since there were OCSP cache-related + // regressions when sha-1 telemetry probes were added. + add_test(function() { + clearOCSPCache(); + // set security.OCSP.require so that checking the OCSP signature fails + Services.prefs.setBoolPref("security.OCSP.require", true); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithSHA1OCSP], + "signing cert is good (though sha1) - should succeed" + ); + + add_test(function() { + Services.prefs.setBoolPref("security.OCSP.require", false); + run_next_test(); + }); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // This test makes sure that OCSP cache are isolated by firstPartyDomain. + + let gObservedCnt = 0; + let protocolProxyService = Cc[ + "@mozilla.org/network/protocol-proxy-service;1" + ].getService(Ci.nsIProtocolProxyService); + + // Observe all channels and make sure the firstPartyDomain in their loadInfo's + // origin attributes are aFirstPartyDomain. + function startObservingChannels(aFirstPartyDomain) { + // We use a dummy proxy filter to catch all channels, even those that do not + // generate an "http-on-modify-request" notification. + let proxyFilter = { + applyFilter(aChannel, aProxy, aCallback) { + // We have the channel; provide it to the callback. + if (aChannel.originalURI.spec == "http://localhost:8888/") { + gObservedCnt++; + equal( + aChannel.loadInfo.originAttributes.firstPartyDomain, + aFirstPartyDomain, + "firstPartyDomain should match" + ); + } + // Pass on aProxy unmodified. + aCallback.onProxyFilterResult(aProxy); + }, + }; + protocolProxyService.registerChannelFilter(proxyFilter, 0); + // Return the stop() function: + return () => protocolProxyService.unregisterChannelFilter(proxyFilter); + } + + let stopObservingChannels; + add_test(function() { + stopObservingChannels = startObservingChannels("foo.com"); + run_next_test(); + }); + + // A good OCSP response will be cached. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (firstPartyDomain = foo.com) -> a fetch " + + "should have been attempted", + { firstPartyDomain: "foo.com" } + ); + + // The cache will prevent a fetch from happening. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (firstPartyDomain = foo.com) -> a " + + "fetch should not have been attempted", + { firstPartyDomain: "foo.com" } + ); + + add_test(function() { + stopObservingChannels(); + equal(gObservedCnt, 1, "should have observed only 1 OCSP requests"); + gObservedCnt = 0; + run_next_test(); + }); + + add_test(function() { + stopObservingChannels = startObservingChannels("bar.com"); + run_next_test(); + }); + + // But using a different firstPartyDomain should result in a fetch. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (firstPartyDomain = bar.com) -> a fetch " + + "should have been attempted", + { firstPartyDomain: "bar.com" } + ); + + add_test(function() { + stopObservingChannels(); + equal(gObservedCnt, 1, "should have observed only 1 OCSP requests"); + gObservedCnt = 0; + run_next_test(); + }); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // Test that the OCSP cache is not isolated by userContextId. + + // A good OCSP response will be cached. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (userContextId = 1) -> a fetch " + + "should have been attempted", + { userContextId: 1 } + ); + + // The cache will prevent a fetch from happening. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (userContextId = 1) -> a " + + "fetch should not have been attempted", + { userContextId: 1 } + ); + + // Fetching is prevented even if in a different userContextId. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (userContextId = 2) -> a " + + "fetch should not have been attempted", + { userContextId: 2 } + ); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js b/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js new file mode 100644 index 0000000000..cf64ed17fb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js @@ -0,0 +1,150 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Checks that the security.OCSP.enabled pref correctly controls OCSP fetching +// behavior. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function certFromFile(filename) { + return constructCertFromFile(`test_ev_certs/${filename}.pem`); +} + +function loadCert(certName, trustString) { + addCertFromFile(gCertDB, `test_ev_certs/${certName}.pem`, trustString); +} + +function getFailingOCSPResponder() { + return getFailingHttpServer(SERVER_PORT, ["www.example.com"]); +} + +function getOCSPResponder(expectedCertNames) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ev_certs", + expectedCertNames, + [] + ); +} + +// Tests that in ocspOff mode, OCSP fetches are never done. +async function testOff() { + Services.prefs.setIntPref("security.OCSP.enabled", 0); + info("Setting security.OCSP.enabled to 0"); + + // EV chains should verify successfully but never get EV status. + clearOCSPCache(); + let ocspResponder = getFailingOCSPResponder(); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + false + ); + await stopOCSPResponder(ocspResponder); + + // A DV chain should verify successfully. + clearOCSPCache(); + ocspResponder = getFailingOCSPResponder(); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +// Tests that in ocspOn mode, OCSP fetches are done for both EV and DV certs. +async function testOn() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + info("Setting security.OCSP.enabled to 1"); + + // If a successful OCSP response is fetched, then an EV chain should verify + // successfully and get EV status as well. + clearOCSPCache(); + let ocspResponder = getOCSPResponder( + gEVExpected + ? ["test-oid-path-int", "test-oid-path-ee"] + : ["test-oid-path-ee"] + ); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + gEVExpected + ); + await stopOCSPResponder(ocspResponder); + + // If a successful OCSP response is fetched, then a DV chain should verify + // successfully. + clearOCSPCache(); + ocspResponder = getOCSPResponder(["non-ev-root-path-ee"]); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +// Tests that in ocspEVOnly mode, OCSP fetches are done for EV certs only. +async function testEVOnly() { + Services.prefs.setIntPref("security.OCSP.enabled", 2); + info("Setting security.OCSP.enabled to 2"); + + // If a successful OCSP response is fetched, then an EV chain should verify + // successfully and get EV status as well. + clearOCSPCache(); + let ocspResponder = gEVExpected + ? getOCSPResponder(["test-oid-path-int", "test-oid-path-ee"]) + : getFailingOCSPResponder(); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + gEVExpected + ); + await stopOCSPResponder(ocspResponder); + + // A DV chain should verify successfully even without doing OCSP fetches. + clearOCSPCache(); + ocspResponder = getFailingOCSPResponder(); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("network.dns.localDomains"); + Services.prefs.clearUserPref("security.OCSP.enabled"); + Services.prefs.clearUserPref("security.OCSP.require"); + }); + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + // Enable hard fail to ensure chains that should only succeed because they get + // a good OCSP response do not succeed due to soft fail leniency. + Services.prefs.setBoolPref("security.OCSP.require", true); + + loadCert("evroot", "CTu,,"); + loadCert("test-oid-path-int", ",,"); + loadCert("non-evroot-ca", "CTu,,"); + loadCert("non-ev-root-path-int", ",,"); + + await testOff(); + await testOn(); + await testEVOnly(); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_must_staple.js b/security/manager/ssl/tests/unit/test_ocsp_must_staple.js new file mode 100644 index 0000000000..46f6127c50 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_must_staple.js @@ -0,0 +1,160 @@ +// -*- 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 OCSP Must Staple handling by connecting to various domains (as faked by +// a server running locally) that correspond to combinations of whether the +// extension is present in intermediate and end-entity certificates. + +var gExpectOCSPRequest; + +function add_ocsp_test( + aHost, + aExpectedResult, + aStaplingEnabled, + aExpectOCSPRequest = false, + aWithSecurityInfo = undefined +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + gExpectOCSPRequest = aExpectOCSPRequest; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref( + "security.ssl.enable_ocsp_stapling", + aStaplingEnabled + ); + }, + aWithSecurityInfo + ); +} + +function add_tests() { + // Next, a case where it's present in the intermediate, not the ee + add_ocsp_test( + "ocsp-stapling-plain-ee-with-must-staple-int.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + true + ); + + // We disable OCSP stapling in the next two tests so we can perform checks + // on TLS Features in the chain without needing to support the TLS + // extension values used. + // Test an issuer with multiple TLS features in matched in the EE + add_ocsp_test( + "multi-tls-feature-good.example.com", + PRErrorCodeSuccess, + false + ); + + // Finally, an issuer with multiple TLS features not matched by the EE. + add_ocsp_test( + "multi-tls-feature-bad.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + false + ); + + // Now a bunch of operations with only a must-staple ee + add_ocsp_test( + "ocsp-stapling-must-staple.example.com", + PRErrorCodeSuccess, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + true, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-empty.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + PRErrorCodeSuccess, + false, + true + ); + + // If the stapled response is expired, we will try to fetch a new one. + // If that fails, we should report the original error. + add_ocsp_test( + "ocsp-stapling-must-staple-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + true, + true + ); + // Similarly with a "try server later" response. + add_ocsp_test( + "ocsp-stapling-must-staple-try-later.example.com", + SEC_ERROR_OCSP_TRY_SERVER_LATER, + true, + true + ); + // And again with an invalid OCSP response signing certificate. + add_ocsp_test( + "ocsp-stapling-must-staple-invalid-signer.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // check that disabling must-staple works + add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", false); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + PRErrorCodeSuccess, + true, + true + ); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // This test may sometimes fail on android due to an OCSP request timing out. + // That aspect of OCSP requests is not what we're testing here, so we can just + // bump the timeout and hopefully avoid these failures. + Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + ok( + gExpectOCSPRequest, + "Should be getting an OCSP request only when expected" + ); + }); + fakeOCSPResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_tests(); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js new file mode 100644 index 0000000000..1c9ba6dcce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js @@ -0,0 +1,68 @@ +// -*- 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"; + +// Test that if an OCSP request is made to a domain that (erroneously) +// has HSTS status, the request is not upgraded from HTTP to HTTPS. + +function run_test() { + do_get_profile(); + // OCSP required means this test will only pass if the request succeeds. + Services.prefs.setBoolPref("security.OCSP.require", true); + + // We don't actually make use of stapling in this test. This is just how we + // get a TLS connection. + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let args = [["good", "default-ee", "unused", 0]]; + let ocspResponses = generateOCSPResponses(args, "ocsp_certs"); + let goodOCSPResponse = ocspResponses[0]; + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(goodOCSPResponse); + }); + ocspResponder.start(8888); + + // ocsp-stapling-none.example.com does not staple an OCSP response in the + // handshake, so the revocation checking code will attempt to fetch one. + // Since the domain of the certificate's OCSP AIA URI is an HSTS host + // (as added in the setup of this test, below), a buggy implementation would + // upgrade the OCSP request to HTTPS. We specifically prevent this. This + // test demonstrates that our implementation is correct in this regard. + add_connection_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess); + add_test(function() { + run_next_test(); + }); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("http://localhost"); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=10000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "Domain for the OCSP AIA URI should be considered a HSTS host, otherwise" + + " we wouldn't be testing what we think we're testing" + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_private_caching.js b/security/manager/ssl/tests/unit/test_ocsp_private_caching.js new file mode 100644 index 0000000000..a3ee41af3f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_private_caching.js @@ -0,0 +1,138 @@ +// -*- 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"; + +// In which we connect to a host and encounter OCSP responses with the +// Cache-Control header set, which Necko will normally cache. We need to ensure +// that these responses aren't cached to disk when the original https request +// was in a private context. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function start_ocsp_responder( + expectedCertNames, + expectedPaths, + expectedMethods +) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ocsp_fetch_method", + expectedCertNames, + expectedPaths, + expectedMethods + ); +} + +function add_flush_cache() { + add_test(() => { + // This appears to either fire multiple times or fire once for every + // observer that has ever been passed to flush. To prevent multiple calls to + // run_next_test, keep track of if this observer has already called it. + let observed = false; + let observer = { + observe: () => { + if (!observed) { + observed = true; + run_next_test(); + } + }, + }; + Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(observer); + }); +} + +function add_ocsp_necko_cache_test(loadContext, shouldFindEntry) { + // Pre-testcase cleanup/setup. + add_test(() => { + Services.cache2.clear(); + run_next_test(); + }); + add_flush_cache(); + + let responder; + add_test(() => { + clearOCSPCache(); + clearSessionCache(); + responder = startOCSPResponder( + SERVER_PORT, + "localhost", + "ocsp_certs", + ["default-ee"], + [], + [], + [], + [["Cache-Control", "max-age: 1000"]] + ); + run_next_test(); + }); + + // Prepare a connection that will cause an OCSP request. + add_connection_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + null, + null, + null, + loadContext.originAttributes + ); + + add_flush_cache(); + + // Traverse the cache and ensure the response made it into the cache with the + // appropriate properties (private or not private). + add_test(() => { + let foundEntry = false; + let visitor = { + onCacheStorageInfo() {}, + onCacheEntryInfo( + aURI, + aIdEnhance, + aDataSize, + aFetchCount, + aLastModifiedTime, + aExpirationTime, + aPinned, + aInfo + ) { + Assert.equal( + aURI.spec, + "http://localhost:8888/", + "expected OCSP request URI should match" + ); + foundEntry = true; + }, + onCacheEntryVisitCompleted() { + Assert.equal( + foundEntry, + shouldFindEntry, + "should only find a cached entry if we're expecting one" + ); + run_next_test(); + }, + QueryInterface: ChromeUtils.generateQI(["nsICacheStorageVisitor"]), + }; + Services.cache2.asyncVisitAllStorages(visitor, true); + }); + + // Clean up (stop the responder). + add_test(() => { + responder.stop(run_next_test); + }); +} + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + add_ocsp_necko_cache_test(Services.loadContextInfo.private, false); + add_ocsp_necko_cache_test(Services.loadContextInfo.default, true); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_required.js b/security/manager/ssl/tests/unit/test_ocsp_required.js new file mode 100644 index 0000000000..6e1c52a6eb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_required.js @@ -0,0 +1,74 @@ +// -*- 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"; + +// In which we connect to a domain (as faked by a server running locally) and +// start up an OCSP responder (also basically faked) that gives a response with +// a bad signature (and later, an empty response). With security.OCSP.require +// set to true, these connections should fail (but they also shouldn't cause +// assertion failures). + +var gOCSPRequestCount = 0; +var gOCSPResponse; + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.OCSP.require", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + // We don't actually make use of stapling in this test. This is just how we + // get a TLS connection. + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let args = [["bad-signature", "default-ee", "unused", 0]]; + let ocspResponses = generateOCSPResponses(args, "ocsp_certs"); + // Start by replying with a response with a bad signature. + gOCSPResponse = ocspResponses[0]; + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gOCSPResponse); + gOCSPRequestCount++; + }); + ocspResponder.start(8888); + + add_tests(); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + + run_next_test(); +} + +function add_tests() { + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_BAD_SIGNATURE + ); + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_BAD_SIGNATURE + ); + add_test(function() { + equal( + gOCSPRequestCount, + 1, + "OCSP request count should be 1 due to OCSP response caching" + ); + gOCSPRequestCount = 0; + // Now set the OCSP responder to reply with 200 OK but empty content. + gOCSPResponse = ""; + clearOCSPCache(); + run_next_test(); + }); + + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE + ); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling.js b/security/manager/ssl/tests/unit/test_ocsp_stapling.js new file mode 100644 index 0000000000..a41610392b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js @@ -0,0 +1,393 @@ +// -*- 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"; + +// In which we connect to a number of domains (as faked by a server running +// locally) with and without OCSP stapling enabled to determine that good +// things happen and bad things don't. + +var gExpectOCSPRequest; + +function add_ocsp_test( + aHost, + aExpectedResult, + aStaplingEnabled, + aExpectOCSPRequest = false +) { + add_connection_test(aHost, aExpectedResult, function() { + gExpectOCSPRequest = aExpectOCSPRequest; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref( + "security.ssl.enable_ocsp_stapling", + aStaplingEnabled + ); + }); +} + +function add_tests() { + // In the absence of OCSP stapling, these should actually all work. + add_ocsp_test( + "ocsp-stapling-good.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-malformed.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-srverr.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-trylater.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-needssig.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-unauthorized.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-skip-responseBytes.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-critical-extension.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-noncritical-extension.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-empty-extensions.example.com", + PRErrorCodeSuccess, + false, + true + ); + + // Now test OCSP stapling + // The following error codes are defined in security/nss/lib/util/SECerrs.h + + add_ocsp_test("ocsp-stapling-good.example.com", PRErrorCodeSuccess, true); + + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); + + // This stapled response is from a CA that is untrusted and did not issue + // the server's certificate. + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let otherTestCA = constructCertFromFile("ocsp_certs/other-test-ca.pem"); + add_test(function() { + certDB.setCertTrust( + otherTestCA, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.UNTRUSTED + ); + run_next_test(); + }); + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // The stapled response is from a CA that is trusted but did not issue the + // server's certificate. + add_test(function() { + certDB.setCertTrust( + otherTestCA, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ); + run_next_test(); + }); + // TODO(bug 979055): When using ByName instead of ByKey, the error here is + // SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE. We should be testing both cases. + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // TODO: Test the case where the signing cert can't be found at all, which + // will result in SEC_ERROR_BAD_DATABASE in the NSS classic case. + + add_ocsp_test( + "ocsp-stapling-malformed.example.com", + SEC_ERROR_OCSP_MALFORMED_REQUEST, + true + ); + add_ocsp_test( + "ocsp-stapling-srverr.example.com", + SEC_ERROR_OCSP_SERVER_ERROR, + true + ); + add_ocsp_test( + "ocsp-stapling-trylater.example.com", + SEC_ERROR_OCSP_TRY_SERVER_LATER, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-needssig.example.com", + SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, + true + ); + add_ocsp_test( + "ocsp-stapling-unauthorized.example.com", + SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, + true + ); + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other.example.com", + MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING, + true + ); + // If the server doesn't staple an OCSP response, we continue as normal + // (this means that even though stapling is enabled, we expect an OCSP + // request). + add_connection_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + function() { + gExpectOCSPRequest = true; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + } + ); + add_ocsp_test( + "ocsp-stapling-empty.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-skip-responseBytes.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-critical-extension.example.com", + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, + true + ); + add_ocsp_test( + "ocsp-stapling-noncritical-extension.example.com", + PRErrorCodeSuccess, + true + ); + // TODO(bug 997994): Disallow empty Extensions in responses + add_ocsp_test( + "ocsp-stapling-empty-extensions.example.com", + PRErrorCodeSuccess, + true + ); + + add_ocsp_test( + "ocsp-stapling-delegated-included.example.com", + PRErrorCodeSuccess, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-included-last.example.com", + PRErrorCodeSuccess, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-missing.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-missing-multiple.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-no-extKeyUsage.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-from-intermediate.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // ocsp-stapling-expired.example.com and + // ocsp-stapling-expired-fresh-ca.example.com are handled in + // test_ocsp_stapling_expired.js + + // Check that OCSP responder certificates with key sizes below 1024 bits are + // rejected, even when the main certificate chain keys are at least 1024 bits. + add_ocsp_test( + "keysize-ocsp-delegated.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + add_ocsp_test( + "revoked-ca-cert-used-as-end-entity.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); +} + +function check_ocsp_stapling_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_OCSP_STAPLING") + .snapshot(); + equal( + histogram.values[0], + 0, + "Should have 0 connections for unused histogram bucket 0" + ); + equal( + histogram.values[1], + 5, + "Actual and expected connections with a good response should match" + ); + equal( + histogram.values[2], + 18, + "Actual and expected connections with no stapled response should match" + ); + equal( + histogram.values[3] || 0, + 0, + "Actual and expected connections with an expired response should match" + ); + equal( + histogram.values[4], + 21, + "Actual and expected connections with bad responses should match" + ); + run_next_test(); +} + +function run_test() { + do_get_profile(); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // This test may sometimes fail on android due to an OCSP request timing out. + // That aspect of OCSP requests is not what we're testing here, so we can just + // bump the timeout and hopefully avoid these failures. + Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + ok( + gExpectOCSPRequest, + "Should be getting an OCSP request only when expected" + ); + }); + fakeOCSPResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_tests(); + + add_test(function() { + fakeOCSPResponder.stop(check_ocsp_stapling_telemetry); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js new file mode 100644 index 0000000000..4e65baeb01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js @@ -0,0 +1,319 @@ +// -*- 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"; + +// In which we connect to a number of domains (as faked by a server running +// locally) with OCSP stapling enabled to determine that good things happen +// and bad things don't, specifically with respect to various expired OCSP +// responses (stapled and otherwise). +// According to RFC 6066, if a stapled OCSP response can't be satisfactorilly +// verified, the client should terminate the connection. Unfortunately, due to +// some bugs where servers will staple any old garbage without verifying it, we +// can't be this strict in practice. Originally this caveat only applied to +// expired responses, but recent high-profile failures have caused us to expand +// this to "try later" responses and responses where the signing certificate +// doesn't verify successfully. + +var gCurrentOCSPResponse = null; +var gOCSPRequestCount = 0; + +function add_ocsp_test( + aHost, + aExpectedResult, + aOCSPResponseToServe, + aExpectedRequestCount +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + clearOCSPCache(); + clearSessionCache(); + gCurrentOCSPResponse = aOCSPResponseToServe; + gOCSPRequestCount = 0; + }, + function() { + equal( + gOCSPRequestCount, + aExpectedRequestCount, + "Should have made " + + aExpectedRequestCount + + " fallback OCSP request" + + (aExpectedRequestCount == 1 ? "" : "s") + ); + } + ); +} + +do_get_profile(); +Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); +Services.prefs.setIntPref("security.OCSP.enabled", 1); +// Sometimes this test will fail on android due to an OCSP request timing out. +// That aspect of OCSP requests is not what we're testing here, so we can just +// bump the timeout and hopefully avoid these failures. +Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); +Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); +var args = [ + ["good", "default-ee", "unused", 0], + ["expiredresponse", "default-ee", "unused", 0], + ["oldvalidperiod", "default-ee", "unused", 0], + ["revoked", "default-ee", "unused", 0], + ["unknown", "default-ee", "unused", 0], + ["good", "must-staple-ee", "unused", 0], +]; +var ocspResponses = generateOCSPResponses(args, "ocsp_certs"); +// Fresh response, certificate is good. +var ocspResponseGood = ocspResponses[0]; +// Expired response, certificate is good. +var expiredOCSPResponseGood = ocspResponses[1]; +// Fresh signature, old validity period, certificate is good. +var oldValidityPeriodOCSPResponseGood = ocspResponses[2]; +// Fresh signature, certificate is revoked. +var ocspResponseRevoked = ocspResponses[3]; +// Fresh signature, certificate is unknown. +var ocspResponseUnknown = ocspResponses[4]; +var ocspResponseGoodMustStaple = ocspResponses[5]; + +// sometimes we expect a result without re-fetch +var willNotRetry = 1; +// but sometimes, since a bad response is in the cache, OCSP fetch will be +// attempted for each validation - in practice, for these test certs, this +// means 6 requests because various hash algorithm and key size combinations +// are tried. +var willRetry = 6; + +function run_test() { + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + if (gCurrentOCSPResponse) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gCurrentOCSPResponse); + } else { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + response.write("Internal Server Error"); + } + gOCSPRequestCount++; + }); + ocspResponder.start(8888); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + // In these tests, the OCSP stapling server gives us a stapled + // response based on the host name ("ocsp-stapling-expired" or + // "ocsp-stapling-expired-fresh-ca"). We then ensure that we're + // properly falling back to fetching revocation information. + // For ocsp-stapling-expired.example.com, the OCSP stapling server + // staples an expired OCSP response. The certificate has not expired. + // For ocsp-stapling-expired-fresh-ca.example.com, the OCSP stapling + // server staples an OCSP response with a recent signature but with an + // out-of-date validity period. The certificate has not expired. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + // if we can't fetch a more recent response when + // given an expired stapled response, we terminate the connection. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + oldValidityPeriodOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + oldValidityPeriodOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + null, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + null, + willNotRetry + ); + // Of course, if the newer response indicates Revoked or Unknown, + // that status must be returned. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + + // If the response is expired but indicates Revoked or Unknown and a + // newer status can't be fetched, the Revoked or Unknown status will + // be returned. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + null, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + null, + willNotRetry + ); + // If the response is expired but indicates Revoked or Unknown and + // a newer status can be fetched and successfully verified, this + // should result in a successful certificate verification. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + // If a newer status can be fetched but it fails to verify, the + // Revoked or Unknown status of the expired stapled response + // should be returned. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + expiredOCSPResponseGood, + willRetry + ); + + // These tests are verifying that an valid but very old response + // is rejected as a valid stapled response, requiring a fetch + // from the ocsp responder. + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + + // Test how OCSP-must-staple (i.e. TLS feature) interacts with stapled OCSP + // responses that don't successfully verify. + // A strict reading of the relevant RFCs might say that these connections + // should all fail because a satisfactory stapled OCSP response is not + // present, but for compatibility reasons we fall back to active OCSP fetching + // in these situations. If the fetch succeeds, then connection succeeds. + add_ocsp_test( + "ocsp-stapling-must-staple-expired.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-must-staple-try-later.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-must-staple-invalid-signer.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + add_test(check_ocsp_stapling_telemetry); + run_next_test(); +} + +function check_ocsp_stapling_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_OCSP_STAPLING") + .snapshot(); + equal( + histogram.values[0] || 0, + 0, + "Should have 0 connections for unused histogram bucket 0" + ); + equal( + histogram.values[1] || 0, + 0, + "Actual and expected connections with a good response should match" + ); + equal( + histogram.values[2] || 0, + 0, + "Actual and expected connections with no stapled response should match" + ); + equal( + histogram.values[3], + 22, + "Actual and expected connections with an expired response should match" + ); + equal( + histogram.values[4], + 2, + "Actual and expected connections with bad responses should match" + ); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js new file mode 100644 index 0000000000..4fc8013ea9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js @@ -0,0 +1,48 @@ +// -*- 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"; + +// In which we connect to a server that staples an OCSP response for a +// certificate signed by an intermediate that has an OCSP AIA to ensure +// that an OCSP request is not made for the intermediate. + +var gOCSPRequestCount = 0; + +function add_ocsp_test(aHost, aExpectedResult) { + add_connection_test(aHost, aExpectedResult, function() { + clearOCSPCache(); + clearSessionCache(); + }); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + gOCSPRequestCount++; + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + let body = "Refusing to return a response"; + response.bodyOutputStream.write(body, body.length); + }); + ocspResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_ocsp_test( + "ocsp-stapling-with-intermediate.example.com", + PRErrorCodeSuccess + ); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + add_test(function() { + equal(gOCSPRequestCount, 0, "No OCSP requests should have been made"); + run_next_test(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_timeout.js b/security/manager/ssl/tests/unit/test_ocsp_timeout.js new file mode 100644 index 0000000000..e06f064d04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_timeout.js @@ -0,0 +1,100 @@ +// -*- 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"; + +// This test connects to ocsp-stapling-none.example.com to test that OCSP +// requests are cancelled if they're taking too long. +// ocsp-stapling-none.example.com doesn't staple an OCSP response, so +// connecting to it will cause a request to the OCSP responder. As with all of +// these tests, the OCSP AIA (i.e. the url of the responder) in the certificate +// is http://localhost:8888. Since this test opens a TCP socket listening on +// port 8888 that just accepts connections and then ignores them (with +// connect/read/write timeouts of 30 seconds), the OCSP requests should cancel +// themselves. When OCSP hard-fail is enabled, connections will be terminated. +// Otherwise, they will succeed. + +var gSocketListener = { + onSocketAccepted(serverSocket, socketTransport) { + socketTransport.setTimeout(Ci.nsISocketTransport.TIMEOUT_CONNECT, 30); + socketTransport.setTimeout(Ci.nsISocketTransport.TIMEOUT_READ_WRITE, 30); + }, + + onStopListening(serverSocket, status) {}, +}; + +function run_test() { + do_get_profile(); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let socket = Cc["@mozilla.org/network/server-socket;1"].createInstance( + Ci.nsIServerSocket + ); + socket.init(8888, true, -1); + socket.asyncListen(gSocketListener); + + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 1000); + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 2000); + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 4000); + + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 3000); + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 10000); + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 15000); + + add_test(function() { + socket.close(); + run_next_test(); + }); + run_next_test(); +} + +function add_one_test(useHardFail, timeoutPrefName, timeoutMilliseconds) { + let startTime; + add_test(function() { + Services.prefs.setBoolPref("security.OCSP.require", useHardFail); + Services.prefs.setIntPref(timeoutPrefName, timeoutMilliseconds); + startTime = new Date(); + run_next_test(); + }); + + add_connection_test( + "ocsp-stapling-none.example.com", + useHardFail ? SEC_ERROR_OCSP_SERVER_ERROR : PRErrorCodeSuccess, + clearSessionCache + ); + + add_test(function() { + let endTime = new Date(); + let timeDifference = endTime - startTime; + info(`useHardFail = ${useHardFail}`); + info(`startTime = ${startTime.getTime()} (${startTime})`); + info(`endTime = ${endTime.getTime()} (${endTime})`); + info(`timeDifference = ${timeDifference}ms`); + // Date() is not guaranteed to be monotonic, so add extra fuzz time to + // prevent intermittent failures (this only appeared to be a problem on + // Windows XP). See Bug 1121117. + const FUZZ_MS = 300; + ok( + timeDifference + FUZZ_MS > timeoutMilliseconds, + `OCSP timeout should be ~${timeoutMilliseconds}s for ` + + `${useHardFail ? "hard" : "soft"}-fail` + ); + // Make sure we didn't wait too long. + // (Unfortunately, we probably can't have a tight upper bound on + // how long is too long for this test, because we might be running + // on slow hardware.) + ok( + timeDifference < 60000, + "Automatic OCSP timeout shouldn't be more than 60s" + ); + + // Reset state + clearOCSPCache(); + Services.prefs.clearUserPref("security.OCSP.require"); + Services.prefs.clearUserPref(timeoutPrefName); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_url.js b/security/manager/ssl/tests/unit/test_ocsp_url.js new file mode 100644 index 0000000000..b26d74b3b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url.js @@ -0,0 +1,122 @@ +// -*- 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"; + +// In which we try to validate several ocsp responses, checking in particular +// if the ocsp url is valid and the path expressed is correctly passed to +// the caller. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function failingOCSPResponder() { + return getFailingHttpServer(SERVER_PORT, ["www.example.com"]); +} + +function start_ocsp_responder(expectedCertNames, expectedPaths) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ocsp_url", + expectedCertNames, + expectedPaths + ); +} + +function check_cert_err(cert_name, expected_error) { + let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".pem"); + return checkCertErrorGeneric( + certdb, + cert, + expected_error, + certificateUsageSSLServer + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_ocsp_url/ca.pem", "CTu,CTu,CTu"); + addCertFromFile(certdb, "test_ocsp_url/int.pem", ",,"); + + // Enabled so that we can force ocsp failure responses. + Services.prefs.setBoolPref("security.OCSP.require", true); + + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + // Note: We don't test the case of a well-formed HTTP URL with an empty port + // because the OCSP code would then send a request to port 80, which we + // can't use in tests. + + clearOCSPCache(); + let ocspResponder = failingOCSPResponder(); + await check_cert_err("bad-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("empty-scheme-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("ftp-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("https-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["hTTp-url"], ["hTTp-url"]); + await check_cert_err("hTTp-url", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("negative-port", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("no-host-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["no-path-url"], [""]); + await check_cert_err("no-path-url", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err( + "no-scheme-host-port", + SEC_ERROR_CERT_BAD_ACCESS_LOCATION + ); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("no-scheme-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("unknown-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + // Note: We currently don't have anything that ensures user:pass sections + // weren't sent. The following test simply checks that such sections + // don't cause failures. + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["user-pass"], [""]); + await check_cert_err("user-pass", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem new file mode 100644 index 0000000000..15a15922f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUd7u/VsqA+jFMod09OYNM6n5mIjQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBUxEzARBgNVBAMMCmJhZC1zY2hlbWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMTAvMC0GCCsGAQUF +BwEBBCEwHzAdBggrBgEFBQcwAYYRL3d3dy5leGFtcGxlLmNvbS8wDQYJKoZIhvcN +AQELBQADggEBAKqR40rThjJ83dCqvxt2tqzfVWNsG8/j8Ylkh2PVe4duegymNbtx +lrGs7e+bR4s3HXwGdtCNqInFuFlZBK1j1LWZTd0o8o/p8VxXk3ZRyWFfaBM96mfM +EkbWSlmgraoS3OJXemV1mU8HpOnsN/P7jkTeAocf+UqXOuyg08f4qKlAwkkX4DIu +A6NHuFmPqDjj2uclq/e/xtL1Xah22kIkql00CmMqBdbtKYnYHd4k5wCWRkEiUzlc +Y8qBnTcamQiNYGgQUOHh/5J0mCrNDmh17A1rnJ4mjkAy4F+bDp2KFwzPtLJKhQeJ +jLclopcJHcmgn3hFbHMcgDwQxVl6UIZXOes= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec new file mode 100644 index 0000000000..12cc072792 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:bad-scheme +extension:authorityInformationAccess:/www.example.com/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem new file mode 100644 index 0000000000..45de962523 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUVSmns5EZzUHKobrhxdpy/ZtJMucwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQATPLfx55bklmCWgjlOjZjD8EpY +fenI0HAkE0044+KmVlFSpsETog4OK0aZKYKwDysClM/ZipzBpmcZ4ZczM0TbtC7/ +d8nfUmT5R/sXBuMmeNIioAn6J5JaSctKQbsVta9GwIyJUBuYIvccL1c5wUuxV8xf +CaTrFgKWkDWkhOEY+TN/95l+Cm0Gwc3l+jom5UrPRyw9Cb5AhRiRc+x3HhgJ2hGe +kKo4K/AfH/jE7U0u4VM+VZTQf5K92aih3f54vPW+yFfMkgFgzHtwIrj1WStknR7u +yRjBCHfjuoOgQLm1svKtpgnMbRhucCkW+mifY+ZbE51vYMiRlK3sHj9hz3ol +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec new file mode 100644 index 0000000000..d809dbd635 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem new file mode 100644 index 0000000000..8fe9d26633 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUC7eHAf4GqnJKXvCpc9aTUTnkKgEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBsxGTAXBgNVBAMMEGVtcHR5LXNjaGVtZS11cmwwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjODA2MDQG +CCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYOi8vd3d3LmV4YW1wbGUuY29tOjg4 +ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCNWUubk4gbD3KqPPJW/vNw8LUHoQHjglk3 +6+RdbY/UCNfd6y3aGSrDLV8a/tVnV55UM9ADi4pd35Otu5i6fGunQcoL19QqFzDV +4dYC3WWGw+AqcF4pgqHBBBVtgDx+kZAS9NwwKCgaagPx7QOWJCDRgNxuol7q1UCI +vthWRt2PPIh4TCA5GDrFfrEYmVH6KgLKtHHr7TBrW0j3Cy6EIAsMMGXbj7z4DIxr +Lh0lP9sW87QJlU1cJF8VO1la9yDWvEQsETw5X5SYBdsG4y+AJ6dJI4872/fgAG7G +DP6nKhXuFvNbbpDTDKAwW2Xu4rVmPmUzv8G2+xis/u8jPhxv9zOS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec new file mode 100644 index 0000000000..e8959653f3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:empty-scheme-url +extension:authorityInformationAccess:://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem new file mode 100644 index 0000000000..d582a2216a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUPf/7zF8sBjFB4sd3ys4pW8gWQZAwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBIxEDAOBgNVBAMMB2Z0cC11cmwwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOzA5MDcGCCsGAQUFBwEB +BCswKTAnBggrBgEFBQcwAYYbZnRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvMA0G +CSqGSIb3DQEBCwUAA4IBAQBoJzEDwSyDzVxFuPRiRs3kcxZBa9FKXJK472UKrwvc +w3xx8+TJPwMZorN/UMe+rxOBMORh1U3bx/nLqfyRB6VxGD2NO/JAUuaXsrEt5cD9 +RekCsFg/nZ4kjnFS8W0ImXGs5MaAEHKyVLaQFaCySpz3lSBd6laJOLpj1qkFIMuv +Z/AsflArUst/hZr+JbsPORu1TBOAWSUofKcfMEGs7WFZS5TwNOxFe0va1ejht7Bh +v1eohpaa5c9SA61Z5uD2vvT3+MiDDs7IAqb1m5hHWPVsgqxSbhzEdqwtR68NejLA +kCeintbVE3FgH/ZC5oT/DYo/9DqAD+CGlbIfORvK7rhJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec new file mode 100644 index 0000000000..9f50a7d792 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:ftp-url +extension:authorityInformationAccess:ftp://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem new file mode 100644 index 0000000000..87efc65d28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgIUFyY16h/GkLcgYETfxjsZRxt38JIwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBMxETAPBgNVBAMMCGhUVHAtdXJsMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo0QwQjBABggrBgEFBQcB +AQQ0MDIwMAYIKwYBBQUHMAGGJGhUVHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9o +VFRwLXVybDANBgkqhkiG9w0BAQsFAAOCAQEAg1XOX1zbHNpzMW9ivatvCMi9rMgQ +ZPFkuu6i4c5diLgo1VbzpM569nsfZnXkWGBv5hhGlFlJPRPc+q9joJMMsebnAlR+ +Q27kAqd/Q9kLQfA5x1Vail+7fin/cI5gR2XbmsXztbX7QYnE1lLSR1BWkJ99LNj4 +lfG5Ofu8CG0dBPfbO4+WtwNnije+J2O3iRc54EEv9kTBaieM34ejxPwg3WY/cUsw +h6UuRjOJf5Q/uhhRwzPZ4sphsdZcdzPhamIBSF2aCnUiFJlYLDV5eBLbr3GVAuFE +bJN5zNNCn2lzyo5dxbzuQO6VaGsZcI4/Y2gMn5Q9Gxym59qniVGLCmzTOg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec new file mode 100644 index 0000000000..10b1504b29 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:hTTp-url +extension:authorityInformationAccess:hTTp://www.example.com:8888/hTTp-url diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem new file mode 100644 index 0000000000..16ce146d3c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUL0PWDEnxL9Qrouxs08+j0g981AEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBQxEjAQBgNVBAMMCWh0dHBzLXVybDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNGMEQwQgYIKwYBBQUH +AQEENjA0MDIGCCsGAQUFBzABhiZodHRwczovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2h0dHBzLXVybDANBgkqhkiG9w0BAQsFAAOCAQEAXzQbnyFm4vlXOrCe9Pt42bt+ +6gg5UZieDPBYIiTBTfUY2e1EII4pxyRJJXjubbfajd+6bxRt38nd0/Ts56WljwiN +ZefieOoMVsRVrX6APHiMvkkZwmtqwOpAgxICpg/pRqEn2BAFIPB3Lrm5rfGHZhw2 +be+FJp4SbBHlnQUnG4oCl6yzR9hAcRssZL+6ewsWNet02aNJgDAVg00wLxNhCFAt +ZdtPq+E6l80/LYLYoVY6O+osC5eMR4Z48FoN8NQ8Yu/pe/t8Km/59NdyQxJFneXr +HXpcpdYsVOr4gzbNFO2552esXwx96tprehFtVc2ZxqnorfMayJz2uO/NVcrPxA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec new file mode 100644 index 0000000000..891005bf5c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:https-url +extension:authorityInformationAccess:https://www.example.com:8888/https-url diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.key b/security/manager/ssl/tests/unit/test_ocsp_url/int.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec b/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.pem b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem new file mode 100644 index 0000000000..44e6a36efa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUNbjVwdBjmiBHgijAyjyGIHuhJqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDjEMMAoGA1UEAwwDaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAO35vcl2OA9fAarEgTCrS42CL +5BeNfQLO7QCIdMZBfcIrQ6v5yw7i07pYGptagz/76OwYOsKO1lqb7sr2nTCNovVp +Co4dCAGQI460C6x3BOG7qyCFgZvf17xXl5filhMZw93LkWaeEIp8JmOTb511i1Bv +1akdFJ+xW40AuHE7EswLXzN0eu+tVAMJcsuxibK3jTkEdIjFCVwMD/7LC1rcoKcg +V18MHbh0zcDrXzo/jk8JfjqkOH5eylBtX2DH/9BjFcKzZDvZQFYlhsmADRHOmqvi +YoEXJj2A6fRzONsNKtQQbmVGvW/rHP7/YIiaAvn0kNb/FDtSqmTcLazSYpRewQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec new file mode 100644 index 0000000000..a7f6d81419 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build new file mode 100644 index 0000000000..7863d3dff4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build @@ -0,0 +1,33 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'bad-scheme.pem', +# 'ca.pem', +# 'empty-scheme-url.pem', +# 'ftp-url.pem', +# 'hTTp-url.pem', +# 'https-url.pem', +# 'int.pem', +# 'negative-port.pem', +# 'no-host-url.pem', +# 'no-path-url.pem', +# 'no-scheme-host-port.pem', +# 'no-scheme-url.pem', +# 'unknown-scheme.pem', +# 'user-pass.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'int.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem new file mode 100644 index 0000000000..6827a1b6a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUe2K7ATAb5CY6+Kltt7J1qxX5Yn0wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBgxFjAUBgNVBAMMDW5lZ2F0aXZlLXBvcnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOjA4MDYGCCsG +AQUFBwEBBCowKDAmBggrBgEFBQcwAYYaaHR0cDovL3d3dy5leGFtcGxlLmNvbTot +MS8wDQYJKoZIhvcNAQELBQADggEBAJbJQ0Qp9K4dFRMu5te+e4MPi+zb9ZHa1nmE +wQLYKbmJ0/HSP7RjAnk2LqPi3Kej5aAqSWfd9x4pahEro9CEjVSrjD4y7iBTXbM8 +9jTyN01BJED2uHjVwOuaT6dVvx5I+QD7rAByxweQ0aoa14Rsf/odAszWmiburmar +3LuVBwfB3gyqBk8z6VdfqgUMjs+vi/DesvSZ5IvHwWGFok9uab8v5Ar8L0KoM5gT +1fAERsxk6W31SsDsSyd5si4dQo6tLJU6jVm2C+rEbt/iOU8CLHs/IozD0jXf1j9S +XeqFoTBvmJaUqpDdgjzXX/ZACz/s5YffRuDfrRqo7H7cBNaK1r0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec new file mode 100644 index 0000000000..fce6d43848 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:negative-port +extension:authorityInformationAccess:http://www.example.com:-1/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem new file mode 100644 index 0000000000..23b1b101e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcugAwIBAgIUY6ACuApKijUD7p8u8yUDVv95Qr0wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBYxFDASBgNVBAMMC25vLWhvc3QtdXJsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoy0wKzApBggrBgEF +BQcBAQQdMBswGQYIKwYBBQUHMAGGDWh0dHA6Ly86ODg4OC8wDQYJKoZIhvcNAQEL +BQADggEBAKft+lbYDwaC4MkOViz/t9Zke8sOCkydLJ+gRhx7iaFjQ00VZOURHWrf +wbOKHaCe3WYofBMlmKARmCB5U8ohvnDqVuCnyt9hXKg3dhWLRGYZOxLEeToTddxc +OSyl736QFCT1GUtyzRE9fG7RZtSmTMrrhxDUkBf5wuwHboXEiN8pXEQY/L1wxze8 +lbGEBvUnQdTtMm2O9kz0Dg186BBw3Fi4yVcUU9COnvDRMfLt8Yt/MGbckfsdpRSn +qC80pJ3kFvJkzBF2MwkJVlZMBPFNexBovxAuVk48uyJLDyNp4J397h09JgvCl7Fl +FMhwIBglV3EvWERD9uq/7Hl1+zLD6GE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec new file mode 100644 index 0000000000..4ac76e7eb3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-host-url +extension:authorityInformationAccess:http://:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem new file mode 100644 index 0000000000..76bd6d16dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUE41GlTjHpx516QFRZ73bImTTVmwwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBYxFDASBgNVBAMMC25vLXBhdGgtdXJsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozswOTA3BggrBgEF +BQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4 +ODANBgkqhkiG9w0BAQsFAAOCAQEARnXgGgNQHB4JClN93VLOVYzJoPkCtO70HjXc +nIuhAAwEISvIk9RWeDlE33x5T+g8SFaEOp/pqSZaa9FUr0y7PyxEwfF72JPQMff0 +L6dYtKiKS1+Uh5FNHC38ev4SJdOyGvD8k7og4+VVlitcDtQgVqiKxBoBCzl37wuK +s1aFx9a7FZcum3sdyFAQCwqpr9qWf9NBbiDdbZDTNyCg7zxk8olsr/DjQLKrAo40 +n2DPfYw+kAfXZgAi1XJjREe4BAaMJw9zCl7Ugsxl53YbUSl1CeicOH5yUiQ3vlCp +eW2QVjq/HRi6zUrSiOhgIzgVys4LivV3FgKIV/m4hgAGPHYLlw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec new file mode 100644 index 0000000000..497bb28796 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-path-url +extension:authorityInformationAccess:http://www.example.com:8888 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem new file mode 100644 index 0000000000..035792b4af --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUD/zYHQI03aXMAELGGvMX7vnOnyQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMB4xHDAaBgNVBAMME25vLXNjaGVtZS1ob3N0LXBvcnQwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjITAf +MB0GCCsGAQUFBwEBBBEwDzANBggrBgEFBQcwAYYBLzANBgkqhkiG9w0BAQsFAAOC +AQEAddd/BUyk8OMHan7wrkL8m3euWJ7+UjxDP1yQL9Gehb34sHiSwr1pE3hfbmHU +Xc92MX9Fnm/M/uZRoMQqUqU0aqPr91rwwnf47+sd86yNvXxCgjAIN31W4wISDuqU +4j6dOYPyz0KGlD9qRJorJ4oxhnQfleTcvz3COrPrRypK4QuRJu3v7wR1qFvZP8Iq +loJ4cY8WwMMpaYecuZHrhfBpG8yO3wihc6IkXqWRWIzBia00v8DNSm+neEF5FTk5 +oCXNJAdh+qWwfzad5gUYGAlPaPdNxbO6G0SOfn7RRGSQj1Nb2Cl2RWzGAcGSGdfL +2h4H1w0XLwjStLtUM/8eQUvQrA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec new file mode 100644 index 0000000000..42a555e411 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-scheme-host-port +extension:authorityInformationAccess:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem new file mode 100644 index 0000000000..ca639a4acb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUBziqKKOqXlKjkoU2XMzG67w9qZQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBgxFjAUBgNVBAMMDW5vLXNjaGVtZS11cmwwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjNTAzMDEGCCsG +AQUFBwEBBCUwIzAhBggrBgEFBQcwAYYVd3d3LmV4YW1wbGUuY29tOjg4ODgvMA0G +CSqGSIb3DQEBCwUAA4IBAQB2TQq4V9zThvWdOYtaIGY/p3o6OHgtkU2n9RFVxImD +h+CObFyHbyDpbMMKghZOfdbI9Tl3QMk+d04TnMJRyiw/XhRJqoDY1fKv1N7AT3TM +Jmx3mR1wD1l9Zo/c4XOywljeypw++Z1DmtwP5TER0u4oLTklBzw9oTSR8snTyfSn +YA3gQL1jFVWwVKou1Gm4pZTavUdCpjJpF3Bp7QUKRFncTvYViVSibzVAIG+/PiY9 +K/EodGfokxgcKG2GUW6kUe2XadhJ8m2KSWtJrBKXnQ1pY8ZPbWHD/jfQsExRMGJL +wJx7HqA+8WNBPwqlqIbQejaieRIKOi++QIRuW4QPKA+6 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec new file mode 100644 index 0000000000..a82196a6d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-scheme-url +extension:authorityInformationAccess:www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem new file mode 100644 index 0000000000..4717e6907a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUST8AviJzhAkMzTRIKaSHBtla3aEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBkxFzAVBgNVBAMMDnVua25vd24tc2NoZW1lMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozYwNDAyBggr +BgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFnR0cDovL3d3dy5leGFtcGxlLmNvbS8w +DQYJKoZIhvcNAQELBQADggEBALJakuxDp5Gpygxj3MY9tK33Dr/JrxN9NH0GmgcR +ruhT6DwStz7irOadxVUqNxxSIMf95QBHPEAWihXxn5qyrmH5Pz/M2H6H9xpWiK1r +fy5UTynUpcqZKVHHfER7tdw371XNdyPeGAfUKQwzO6LS4aBFhDssWxba0ZAt/iQU +Gqf0X9d73mfEvJZeiMJSqXReITRjTb+0f++0s95IfEhKs3YL9nbP/LHw9XxfmLU/ +2ZUvuAfOTq5U1XnoGIoqg2C8LtQxPXjvezAW/XQNcjQBwyYBxa64HFp5deWv7imf +QjF9yYYJOBz+BdyXCM+DZL+YJ/Ic6SpuEquVHewvegOpDDE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec new file mode 100644 index 0000000000..0089455398 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:unknown-scheme +extension:authorityInformationAccess:ttp://www.example.com/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem new file mode 100644 index 0000000000..018f6d0614 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUc+MjmGMCD8xzGcHP2/uSyWK/9D4wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBQxEjAQBgNVBAMMCXVzZXItcGFzczCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNGMEQwQgYIKwYBBQUH +AQEENjA0MDIGCCsGAQUFBzABhiZodHRwOi8vdXNlcjpwYXNzQHd3dy5leGFtcGxl +LmNvbTo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAOZmeoErLJLw7l2J8terpOiFf +68YxI5/QZcRMZhVCMG71XjcZHj6mHLAgKi3Iw2iBeaUnfb5sfg5J7nOXUzebDoHD +j9W6h0tUxMyYDSdi8aXdvJ4WywPvYlJpWc33O+iDm3cLy224wF14eVD3rZcwroes +r/wf/86aszBY+xpkwHf/lD6KLNhmaAo0HKq8U4Ys6kJzLpvXMLcwnTs93lCE/VE3 +PYxzndXfRikAQ3j+e8KntIb99NeXMErjnq7vhrcjY7YPHTX60y8QC3fmX60qTAtV +YWYJusDKXiSDqo1wSHMgpgJ1EEptPsR/DdcCFLfg0PnAvYD8T7LI8jvJt8H8jw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec new file mode 100644 index 0000000000..337e67e5f9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:user-pass +extension:authorityInformationAccess:http://user:pass@www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem new file mode 100644 index 0000000000..e963b71b90 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIBHzANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0 +IEludGVybWVkaWF0ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAw +WjAwMS4wLAYDVQQDDCVBbm90aGVyIEVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMu +dHh0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCZh0XjjDVy1Ev/wSgS850t9KtD +YbFnqn3dCQjeECmXAH3BXAgb+hZwQEPvNcg1C7tzAowdZ+8h3+SbRLlEL50SkjXQ +euMrIOSBlJcOQTKYQrpTkbT68MhvFlLsM/BCjQ6lGRIKVGTGv4Q2k8NDF3+9N//Q +0QaTZ/3gZrmXSOGrbFUjiKrONMpQZhgVW8TMceJHnmOsxO5sQ4VPRVS3oYAbyoWU +JwWZYN/moFvQ/bE1ZceWhdyspzF3NVy0SP+eLQ/LznkZeQ+5ZVvNftwE8D3w+rYQ +t8ppnbaSPWQFgyL07OdFmhIpBWODrpjNQOq+ZmPkRBLKHiagw+c73gNbx5ui +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec new file mode 100644 index 0000000000..d3ba461104 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:Another EE Revoked by revocations.txt +serialNumber:31 diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem new file mode 100644 index 0000000000..7146aebe48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIBTjANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0 +IEludGVybWVkaWF0ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAw +WjAwMS4wLAYDVQQDDCVBbm90aGVyIEVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMu +dHh0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAGkBeSA8w5p5awb4t6gWXuXwpO ++N3LQcIAfdWcHuOXaYfWM6tuGRD7fumskMh1fp/7IcqxI0dvNd4iRuWm2IMypQN1 +rlYhkk6Z6N4Z2q8x+vlUl9cdFbXy8q3Iyo7dZflSkk/4vyWpIL6VBZEYs8wc+zJC +iEFFxjakhs8lNtFgJfcKDJGpb47q2burXP7D9rPkfYhNA8JnjSc2gXFd/wqP25ns +kmtUyjt/7kCKEtEsn2jLiIWOeASYMOzn10PVIrpX2hMphNw9DDljbIXbEbMat2p4 +GmN7xOLJgCFXZ1c1tGIxxbSsCjeHVjLY1j7D0ovOx5pn/+Fuga6FdWBdeTxC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec new file mode 100644 index 0000000000..10f8f07cce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:Another EE Revoked by revocations.txt +serialNumber:78 diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem new file mode 100644 index 0000000000..41d69f6b9a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAZ+gAwIBAgIBKjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0 +IENBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCgxJjAkBgNV +BAMMHUVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMudHh0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3 +DQEBCwUAA4IBAQCnVdUu30/kzE7JGkVtpRb/obsNkFySebWpr3gNfkHQJcwAXB+6 +jX6zluZW2e+2jdalTmJ7r1jfQnC76P/trz5GyWQGiM1ht50l1yZonTPtC1Qzkzfh +DPyqUr9PgeZZMdVPD8vaMqxYCqELRrCTxrUmC+vEjGKkBlvtY48ZBcEb/wrSm+4+ +j7vdHDpAxmg6dxZrWlvOBz7TOMwGWlF8loJD3bJYepV1w5N1LB5YR4rc6Peis3LA +EFHhbUFZlkbY7shChIh1S0PEiTSB5yFopC4iMkALBAJxfdPNKFUyzbVIZolpxA0m +Bk9uBCR3zv4lpm1JkUR/AOL8zXI7wrRvhh9F +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec new file mode 100644 index 0000000000..a2a67d909c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:EE Revoked by revocations.txt +serialNumber:42 diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem new file mode 100644 index 0000000000..3f6b4651ef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzTCCAbWgAwIBAgIUZylsQT6JPUjiShyHn9bjtXVZ1BEwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDDCBFRSBSZXZva2VkIEJ5IFN1YmplY3QgYW5k +IFB1YktleTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeMJzZMlfsHzM/gTj02WQ +scQ9rdvDSaPI52IWt0Dwu+Iv+nLCvn6Z2eL6E7DVp613u5y47GwtohTCvNoe9/Nt +SWKN5WlwaOLbRA5wmt5sbrB6w1z5qt+YDJuVvaw2OmLc7klBpF+ZXHufS7XIPg3e +xWyqnnJ7ewlYF7fMe8q6WhHlzZ5BYuhNXntpf3dvAA9xMxGYr5CQcXSDF9CqdaAF +n2P6ZgI7K7CpWzOqLinc+kTyJ8WmcW6WiHIN2ce2XFL49oRFXasjpJtGHmIr5ns4 +yGkHw9WKKzmMG5kgLy5Ar3PSdqAD51l4IGLPIzquhnlo/oTe/Lwi5fZIiHWOmr/z +1Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec new file mode 100644 index 0000000000..cadbcf9038 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec @@ -0,0 +1,2 @@ +issuer:Test CA +subject:EE Revoked By Subject and PubKey diff --git a/security/manager/ssl/tests/unit/test_onecrl/moz.build b/security/manager/ssl/tests/unit/test_onecrl/moz.build new file mode 100644 index 0000000000..f01134991b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'another-ee-revoked-by-revocations-txt-serial-2.pem', +# 'another-ee-revoked-by-revocations-txt.pem', +# 'ee-revoked-by-revocations-txt.pem', +# 'ee-revoked-by-subject-and-pubkey.pem', +# 'same-issuer-ee.pem', +# 'test-int-ee.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem new file mode 100644 index 0000000000..d48771c638 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUB8T8WSJXA+AFg+rEJQ6d49gVhG4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdBbm90aGVyIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNbMFkwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMDIG +CCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4 +LzANBgkqhkiG9w0BAQsFAAOCAQEAXEPHIKtQkyoGnJ0TjHvybmECV9OKdmQg34JL +EZ276YtRZBfcPIlt6v0dTzYy8kS68OTjQ2wAa+jVyJRg24x7Jln0R2XVgyGX7FKJ +646dlYC5sqXPx1N7bh2Zh9aU6erBBbQZbBC3KGYT6pFxHcddmSFIlkxLREj10lr1 +CTVE7Xq5pel4jE9YS4Su/n0zVmMCLdEh2mOml+L0N2oxFchczJVcogi9iGVSElPx +PaQBsAtRW7Kl/yCEsENNXqYm/B+QaJd6c+MxYTd+DuKx3TZiT3Pk4xDGExdW+yUv +BvVaHBtavJYAw+IDzz6MxuUIiJ/wpUXP/CnsK8eD3ADyabxkFA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec new file mode 100644 index 0000000000..8b20f03f59 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Another Test End-entity +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt b/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt new file mode 100644 index 0000000000..8983eb65c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt @@ -0,0 +1,41 @@ +# a sample revocations.txt for tests +# Lines starting with '#' are ignored - as are empty lines like this: + +# otherwise: +# non-empty lines are treated as base-64 encoded DER DN data (e.g. issuer or +# subject) +# ...unless the line starts with a ' ' (space) character, in which case it's +# assumed to be base-64 encoded DER serial data, or +# the line starts with a '\t' (tab) character, in which case it's assumed to +# be a base-64 encoded SHA256 hash of a public key + +# First a serial with no issuer to ensure this doesn't cause parsing to fail +# (there should be an issuer first, but we need to test this won't fail) + dGVzdA== +# next, let's ensure data that isn't valid base64 doesn't cause breakage. + this serial isn't valid base64 (but then there's no issuer anyway) +Neither is this issuer, though the serial is fine + dGVzdA== +dGVzdA== + in this case, issuer is fine but not the serial +# Next two entries; we can add valid base-64 encoded data for some basic tests: +# issuer is the base-64 encoded subject DN for the shared Test CA +# serial is the base-64 encoded integer 42 +MBIxEDAOBgNVBAMMB1Rlc3QgQ0E= + Kg== +# issuer is the base-64 encoded subject DN for the shared Test Intermediate +# the first serial is the base-64 encoded integer 78 +# the second serial is the base-64 encoded integer 31 +MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl + Tg== + Hw== + c2VyaWFsMi4= +# subject is base-64 encoded subject DN "CN=EE Revoked By Subject and PubKey" +# pubKeyHash is the base-64 encoded sha256 hash of the shared RSA SPKI +MCsxKTAnBgNVBAMMIEVFIFJldm9rZWQgQnkgU3ViamVjdCBhbmQgUHViS2V5 + VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8 +# and some more data to ensure that mixed items don't cause parsing failure +a DN + a serial + a hash + another serial diff --git a/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem new file mode 100644 index 0000000000..b7e0246486 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIUE/Ee/Yl0qsBfU62Pa29Gu17/HNMwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowJDEiMCAGA1UEAwwZRUUgaXNzdWVkIGJ5IGlu +dGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqG +SIb3DQEBCwUAA4IBAQAnJwAGpGTVIkzj1a9MyPYLMgy+36xRzYe6WmIgsFPV/51u +AZZqcxlI+haWQQf13erUoM2HnvQXw+h4cwWTqZ59NqrWeZWFtHiVFCQVip+/1+dX +IUmOJjgAOsKUtgg/plvp6mtaT/4ko8mA8dmhdOhASYpEocT4veDpovAQD00B2YCx +2qxRypDTSd4oM1RFf7KsKglFOPmi5lOjfvSGprIMbj6JgoplYk+vAZC53mK5UgF+ +qCnXGJr3dEpGy7uJHX69hBtZWom84a62YqTeUMRsMDcz15XS5L6Gdrc4YW0NHRci +lId9qfDpC7jhL1mWAPEBHOtKxsrCPjkToPND9WVz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec new file mode 100644 index 0000000000..24792d540a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:EE issued by intermediate +extension:subjectAlternativeName:localhost diff --git a/security/manager/ssl/tests/unit/test_osclientcerts_module.js b/security/manager/ssl/tests/unit/test_osclientcerts_module.js new file mode 100644 index 0000000000..8ac31b648a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_osclientcerts_module.js @@ -0,0 +1,63 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the platform can load the osclientcerts module. + +// Ensure that the appropriate initialization has happened. +Services.prefs.setBoolPref("security.osclientcerts.autoload", false); +do_get_profile(); + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +async function check_osclientcerts_module_loaded() { + // Loading happens asynchronously, so we have to wait for the notification. + await TestUtils.topicObserved("psm:load-os-client-certs-module-task-ran"); + let testModule = checkPKCS11ModuleExists( + "OS Client Cert Module", + "osclientcerts" + ); + + // Check that listing the slots for the osclientcerts module works. + let testModuleSlotNames = Array.from( + testModule.listSlots(), + slot => slot.name + ); + testModuleSlotNames.sort(); + const expectedSlotNames = [ + "OS Client Cert Slot (Legacy)", + "OS Client Cert Slot (Modern)", + ]; + deepEqual( + testModuleSlotNames, + expectedSlotNames, + "Actual and expected slot names should be equal" + ); +} + +add_task(async function run_test() { + // Check that if we haven't loaded the osclientcerts module, we don't find it + // in the module list. + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); + + // Check that enabling the pref that loads the osclientcerts module makes it + // appear in the module list. + Services.prefs.setBoolPref("security.osclientcerts.autoload", true); + await check_osclientcerts_module_loaded(); + + // Check that disabling the pref that loads the osclientcerts module (thus + // unloading the module) makes it disappear from the module list. + Services.prefs.setBoolPref("security.osclientcerts.autoload", false); + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); + + // Check that loading the module again succeeds. + Services.prefs.setBoolPref("security.osclientcerts.autoload", true); + await check_osclientcerts_module_loaded(); + + // And once more check that unloading succeeds. + Services.prefs.setBoolPref("security.osclientcerts.autoload", false); + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); +}); diff --git a/security/manager/ssl/tests/unit/test_oskeystore.js b/security/manager/ssl/tests/unit/test_oskeystore.js new file mode 100644 index 0000000000..5333cb27ea --- /dev/null +++ b/security/manager/ssl/tests/unit/test_oskeystore.js @@ -0,0 +1,413 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with nsIOSKeyStore. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const LABELS = ["mylabel1", "mylabel2", "mylabel3"]; + +async function delete_all_secrets() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + for (let label of LABELS) { + if (await keystore.asyncSecretAvailable(label)) { + await keystore.asyncDeleteSecret(label); + ok( + !(await keystore.asyncSecretAvailable(label)), + label + " should be deleted now." + ); + } + } +} + +// Test that Firefox handles locking and unlocking of the OSKeyStore properly. +// Does so by mocking out the actual dialog and "filling in" the +// password. Also tests that providing an incorrect password will fail (well, +// technically the user will just get prompted again, but if they then cancel +// the dialog the overall operation will fail). + +var gMockPrompter = { + passwordToTry: null, + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + if (this.passwordToTry == "DontTryThisPassword") { + // Cancel the prompt in this case. + return false; + } + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +async function encrypt_decrypt_test() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "The secret should not be available yet." + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + let recoveryPhrase2 = await keystore.asyncGenerateSecret(LABELS[1]); + ok(recoveryPhrase2, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x01, 0x00, 0x01]); + let ciphertext = ""; + try { + ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + } catch (e) { + ok(false, "Error encrypting " + e); + } + + // Decrypting should give us the plaintext bytes again. + try { + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text." + ); + } catch (e) { + ok(false, "Error decrypting ciphertext " + e); + } + + // Decrypting with a wrong key should throw an error. + try { + await keystore.asyncDecryptBytes(LABELS[1], ciphertext); + ok(false, "Decrypting with the wrong key should fail."); + } catch (e) { + ok(true, "Decrypting with the wrong key should fail " + e); + } +} + +add_task(async function() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + let windowWatcherCID; + if (keystore.isNSSKeyStore) { + windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + } + + await delete_all_secrets(); + await encrypt_decrypt_test(); + await delete_all_secrets(); + + if ( + AppConstants.platform == "macosx" || + AppConstants.platform == "win" || + AppConstants.platform == "linux" + ) { + ok( + !keystore.isNSSKeyStore, + "OS X, Windows, and Linux should use the non-NSS implementation" + ); + } + + if (keystore.isNSSKeyStore) { + // If we use the NSS key store implementation test that everything works + // when a master password is set. + // Set an initial password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("hunter2"); + + // Lock the key store. This should be equivalent to token.logoutSimple() + await keystore.asyncLock(); + + // Set the correct password so that the test operations should succeed. + gMockPrompter.passwordToTry = "hunter2"; + await encrypt_decrypt_test(); + ok( + gMockPrompter.numPrompts == 1, + "There should've been one password prompt." + ); + await delete_all_secrets(); + } + + // Check lock/unlock behaviour. + // Unfortunately we can only test this automatically for the NSS key store. + // Uncomment the outer keystore.isNSSKeyStore to test other key stores manually. + if (keystore.isNSSKeyStore) { + await delete_all_secrets(); + await encrypt_decrypt_test(); + await keystore.asyncLock(); + info("Keystore should be locked. Cancel the login request."); + try { + if (keystore.isNSSKeyStore) { + gMockPrompter.passwordToTry = "DontTryThisPassword"; + } + await keystore.asyncUnlock(); + ok(false, "Unlock should've rejected."); + } catch (e) { + ok( + e.result == Cr.NS_ERROR_FAILURE || e.result == Cr.NS_ERROR_ABORT, + "Rejected login prompt." + ); + } + // clean up + if (keystore.isNSSKeyStore) { + gMockPrompter.passwordToTry = "hunter2"; + } + await delete_all_secrets(); + } +}); + +// Test that if we kick off a background operation and then call a synchronous function on the +// keystore, we don't deadlock. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + try { + let text = new Uint8Array(8192); + let promise = keystore.asyncEncryptBytes(LABELS[0], text); + /* eslint-disable no-unused-expressions */ + keystore.isNSSKeyStore; // we don't care what this is - we just need to access it + /* eslint-enable no-unused-expressions */ + let ciphertext = await promise; + ok(ciphertext, "We should have a ciphertext now."); + } catch (e) { + ok(false, "Error encrypting " + e); + } + + await delete_all_secrets(); +}); + +// Test that using a recovery phrase works. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x01, 0x00, 0x01]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + await keystore.asyncDeleteSecret(LABELS[0]); + // Decrypting should fail after deleting the secret. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => + ok(false, "decrypting didn't throw as expected after deleting the secret") + ) + .catch(() => + ok(true, "decrypting threw as expected after deleting the secret") + ); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text." + ); + + await delete_all_secrets(); +}); + +// Test that trying to use a non-base64 recovery phrase fails. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + await keystore + .asyncRecoverSecret(LABELS[0], "@##$^&*()#$^&*(@#%&*_") + .then(() => + ok(false, "base64-decoding non-base64 should have failed but didn't") + ) + .catch(() => ok(true, "base64-decoding non-base64 failed as expected")); + + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok( + recoveryPhrase && recoveryPhrase.length > 0, + "we should be able to re-use that label to generate a new secret" + ); + await delete_all_secrets(); +}); + +// Test that re-using a label overwrites any previously-stored secret. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x66, 0x6f, 0x6f, 0x66]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + let newRecoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(newRecoveryPhrase, "A new recovery phrase should've been created."); + + // The new secret replaced the old one so we shouldn't be able to decrypt the ciphertext now. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => + ok(false, "decrypting without the original key should have failed") + ) + .catch(() => + ok(true, "decrypting without the original key failed as expected") + ); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text (once we have the original key again)." + ); + + await delete_all_secrets(); +}); + +// Test that re-using a label (this time using a recovery phrase) overwrites any previously-stored +// secret. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let newRecoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(newRecoveryPhrase, "A new recovery phrase should've been created."); + + let text = new Uint8Array([0x66, 0x6f, 0x6f, 0x66]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + + // We recovered the old secret, so decrypting ciphertext that had been encrypted with the newer + // key should fail. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => ok(false, "decrypting without the new key should have failed")) + .catch(() => ok(true, "decrypting without the new key failed as expected")); + + await keystore.asyncRecoverSecret(LABELS[0], newRecoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text (once we have the new key again)." + ); + + await delete_all_secrets(); +}); + +// Test that trying to use recovery phrases that are the wrong size fails. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + await keystore + .asyncRecoverSecret(LABELS[0], "") + .then(() => ok(false, "'recovering' with an empty key should have failed")) + .catch(() => ok(true, "'recovering' with an empty key failed as expected")); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + await keystore + .asyncRecoverSecret(LABELS[0], "AAAAAA") + .then(() => + ok(false, "recovering with a key that is too short should have failed") + ) + .catch(() => + ok(true, "recovering with a key that is too short failed as expected") + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + await keystore + .asyncRecoverSecret( + LABELS[0], + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + ) + .then(() => + ok(false, "recovering with a key that is too long should have failed") + ) + .catch(() => + ok(true, "recovering with a key that is too long failed as expected") + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok( + recoveryPhrase && recoveryPhrase.length > 0, + "we should be able to use that label to generate a new secret" + ); + ok( + await keystore.asyncSecretAvailable(LABELS[0]), + "the generated secret should now be available" + ); + + await delete_all_secrets(); +}); diff --git a/security/manager/ssl/tests/unit/test_osreauthenticator.js b/security/manager/ssl/tests/unit/test_osreauthenticator.js new file mode 100644 index 0000000000..01784a5fef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_osreauthenticator.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests nsIOSReauthenticator.asyncReauthenticateUser(). +// As this gets implemented on various platforms, running this test +// will result in a prompt from the OS. Consequently, we won't be able +// to run this in automation, but it will help in testing locally. +add_task(async function test_asyncReauthenticateUser() { + const reauthenticator = Cc[ + "@mozilla.org/security/osreauthenticator;1" + ].getService(Ci.nsIOSReauthenticator); + ok(reauthenticator, "nsIOSReauthenticator should be available"); + const EXPECTED = false; // Change this variable to suit your needs while testing. + ok( + ( + await reauthenticator.asyncReauthenticateUser( + "this is the prompt string", + "this is the caption string", + null + ) + )[0] == EXPECTED, + "nsIOSReauthenticator.asyncReauthenticateUser should return a boolean array with the first item being the authentication result of: " + + EXPECTED + ); +}); diff --git a/security/manager/ssl/tests/unit/test_password_prompt.js b/security/manager/ssl/tests/unit/test_password_prompt.js new file mode 100644 index 0000000000..cf4c6db7bf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_password_prompt.js @@ -0,0 +1,87 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that PSM can successfully ask for a password from the user and relay it +// back to NSS. Does so by mocking out the actual dialog and "filling in" the +// password. Also tests that providing an incorrect password will fail (well, +// technically the user will just get prompted again, but if they then cancel +// the dialog the overall operation will fail). + +var gMockPrompter = { + passwordToTry: null, + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +function run_test() { + do_get_profile(); + + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + + // Set an initial password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("hunter2"); + token.logoutSimple(); + + // Try with the correct password. + gMockPrompter.passwordToTry = "hunter2"; + // Using nsISecretDecoderRing will cause the password prompt to come up if the + // token has a password and is logged out. + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + sdr.encryptString("poke"); + equal(gMockPrompter.numPrompts, 1, "should have prompted for password once"); + + // Reset state. + gMockPrompter.numPrompts = 0; + token.logoutSimple(); + + // Try with an incorrect password. + gMockPrompter.passwordToTry = "*******"; + throws( + () => sdr.encryptString("poke2"), + /NS_ERROR_FAILURE/, + "logging in with the wrong password should fail" + ); + equal(gMockPrompter.numPrompts, 2, "should have prompted for password twice"); +} diff --git a/security/manager/ssl/tests/unit/test_pinning.js b/security/manager/ssl/tests/unit/test_pinning.js new file mode 100644 index 0000000000..89539ac2bf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pinning.js @@ -0,0 +1,319 @@ +// -*- 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/. +// +// For all cases, the acceptable pinset includes only certificates pinned to +// Test End Entity Cert (signed by issuer testCA). Other certificates +// are issued by otherCA, which is never in the pinset but is a user-specified +// trust anchor. This test covers multiple cases: +// +// Pinned domain include-subdomains.pinning.example.com includes subdomains +// - PASS: include-subdomains.pinning.example.com serves a correct cert +// - PASS: good.include-subdomains.pinning.example.com serves a correct cert +// - FAIL (strict): bad.include-subdomains.pinning.example.com serves a cert +// not in the pinset +// - PASS (mitm): bad.include-subdomains.pinning.example.com serves a cert not +// in the pinset, but issued by a user-specified trust domain +// +// Pinned domain exclude-subdomains.pinning.example.com excludes subdomains +// - PASS: exclude-subdomains.pinning.example.com serves a correct cert +// - FAIL: exclude-subdomains.pinning.example.com serves an incorrect cert +// (TODO: test using verifyCertNow) +// - PASS: sub.exclude-subdomains.pinning.example.com serves an incorrect cert + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function add_clear_override(host) { + add_test(function() { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride(host, 8443); + run_next_test(); + }); +} + +function test_strict() { + // In strict mode, we always evaluate pinning data, regardless of whether the + // issuer is a built-in trust anchor. We only enforce pins that are not in + // test mode. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + run_next_test(); + }); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // Issued by otherCA, which is not in the pinset for pinning.example.com. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // Check that using a FQDN doesn't bypass pinning. + add_connection_test( + "bad.include-subdomains.pinning.example.com.", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + // For some reason this is also navigable (see bug 1118522). + add_connection_test( + "bad.include-subdomains.pinning.example.com..", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // These domains serve certs that match the pinset. + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain serves a cert that doesn't match the pinset, but subdomains + // are excluded. + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain's pinset is exactly the same as + // include-subdomains.pinning.example.com, serves the same cert as + // bad.include-subdomains.pinning.example.com, but it should pass because + // it's in test_mode. + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + // Similarly, this pin is in test-mode, so it should be overridable. + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_mitm() { + // In MITM mode, we allow pinning to pass if the chain resolves to any + // user-specified trust anchor, even if it is not in the pinset. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1); + run_next_test(); + }); + + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides (since building a trusted chain fails, + // we have no reason to believe this was issued by a user-added trust + // anchor, so we can't allow overrides for it). + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // In this case, even though otherCA is not in the pinset, it is a + // user-specified trust anchor and the pinning check succeeds. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_disabled() { + // Disable pinning. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 0); + run_next_test(); + }); + + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "bad.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + + add_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_enforce_test_mode() { + // In enforce test mode, we always enforce all pins, even test pins. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 3); + run_next_test(); + }); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // Issued by otherCA, which is not in the pinset for pinning.example.com. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // These domains serve certs that match the pinset. + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain serves a cert that doesn't match the pinset, but subdomains + // are excluded. + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain's pinset is exactly the same as + // include-subdomains.pinning.example.com, serves the same cert as + // bad.include-subdomains.pinning.example.com, is in test-mode, but we are + // enforcing test mode pins. + add_connection_test( + "test-mode.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + // Normally this is overridable. But, since we have pinning information for + // this host (and since we're enforcing test mode), we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function check_pinning_telemetry() { + let prod_histogram = Services.telemetry + .getHistogramById("CERT_PINNING_RESULTS") + .snapshot(); + let test_histogram = Services.telemetry + .getHistogramById("CERT_PINNING_TEST_RESULTS") + .snapshot(); + // Because all of our test domains are pinned to user-specified trust + // anchors, effectively only strict mode and enforce test-mode get evaluated + equal( + prod_histogram.values[0], + 4, + "Actual and expected prod (non-Mozilla) failure count should match" + ); + equal( + prod_histogram.values[1], + 6, + "Actual and expected prod (non-Mozilla) success count should match" + ); + equal( + test_histogram.values[0], + 2, + "Actual and expected test (non-Mozilla) failure count should match" + ); + equal( + test_histogram.values[1] || 0, + 0, + "Actual and expected test (non-Mozilla) success count should match" + ); + + run_next_test(); +} + +function run_test() { + // Ensure that static pinning works when HPKP is disabled. + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", false); + + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + // Add a user-specified trust anchor. + addCertFromFile(certdb, "bad_certs/other-test-ca.pem", "CTu,u,u"); + + test_strict(); + test_mitm(); + test_disabled(); + test_enforce_test_mode(); + + add_test(function() { + check_pinning_telemetry(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_module.js b/security/manager/ssl/tests/unit/test_pkcs11_module.js new file mode 100644 index 0000000000..abad2dbb54 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_module.js @@ -0,0 +1,58 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 module and +// the module database. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const gModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB +); + +function run_test() { + // Check that if we have never added the test module, that we don't find it + // in the module list. + checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule"); + + // Check that adding the test module makes it appear in the module list. + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + loadPKCS11Module(libraryFile, "PKCS11 Test Module", true); + let testModule = checkPKCS11ModuleExists( + "PKCS11 Test Module", + "pkcs11testmodule" + ); + + // Check that listing the slots for the test module works. + let testModuleSlotNames = Array.from( + testModule.listSlots(), + slot => slot.name + ); + testModuleSlotNames.sort(); + const expectedSlotNames = [ + "Empty PKCS11 Slot", + "Test PKCS11 Slot", + "Test PKCS11 Slot 二", + ]; + deepEqual( + testModuleSlotNames, + expectedSlotNames, + "Actual and expected slot names should be equal" + ); + + // Check that deleting the test module makes it disappear from the module list. + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + pkcs11ModuleDB.deleteModule("PKCS11 Test Module"); + checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule"); + + // Check miscellaneous module DB methods and attributes. + ok(!gModuleDB.canToggleFIPS, "It should NOT be possible to toggle FIPS"); + ok(!gModuleDB.isFIPSEnabled, "FIPS should not be enabled"); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js b/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js new file mode 100644 index 0000000000..52795ccd3c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js @@ -0,0 +1,50 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that adding modules with invalid names are prevented. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const gModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB +); + +function run_test() { + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + ok(libraryFile.exists(), "The pkcs11testmodule file should exist"); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + throws( + () => moduleDB.addModule("Root Certs", libraryFile.path, 0, 0), + /NS_ERROR_ILLEGAL_VALUE/, + "Adding a module named 'Root Certs' should fail." + ); + throws( + () => moduleDB.addModule("", libraryFile.path, 0, 0), + /NS_ERROR_ILLEGAL_VALUE/, + "Adding a module with an empty name should fail." + ); + + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + let rootsModuleName = bundle.GetStringFromName("RootCertModuleName"); + let foundRootsModule = false; + for (let module of moduleDB.listModules()) { + if (module.name == rootsModuleName) { + foundRootsModule = true; + break; + } + } + ok( + foundRootsModule, + "Should be able to find builtin roots module by localized name." + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js b/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js new file mode 100644 index 0000000000..724b98d664 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js @@ -0,0 +1,61 @@ +/* -*- 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"; + +// In safe mode, PKCS#11 modules should not be loaded. This test tests this by +// simulating starting in safe mode and then attempting to load a module. + +function run_test() { + do_get_profile(); + + // Simulate starting in safe mode. + let xulRuntime = { + inSafeMode: true, + logConsoleErrors: true, + OS: "XPCShell", + XPCOMABI: "noarch-spidermonkey", + invalidateCachesOnRestart: function invalidateCachesOnRestart() { + // Do nothing + }, + QueryInterface: ChromeUtils.generateQI(["nsIXULRuntime"]), + }; + + let xulRuntimeFactory = { + createInstance(outer, iid) { + if (outer != null) { + throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION); + } + return xulRuntime.QueryInterface(iid); + }, + }; + + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + const XULRUNTIME_CONTRACTID = "@mozilla.org/xre/runtime;1"; + const XULRUNTIME_CID = Components.ID( + "{f0f0b230-5525-4127-98dc-7bca39059e70}" + ); + registrar.registerFactory( + XULRUNTIME_CID, + "XULRuntime", + XULRUNTIME_CONTRACTID, + xulRuntimeFactory + ); + + // When starting in safe mode, the test module should fail to load. + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let libraryName = ctypes.libraryName("pkcs11testmodule"); + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(libraryName); + ok(libraryFile.exists(), "The pkcs11testmodule file should exist"); + throws( + () => + pkcs11ModuleDB.addModule("PKCS11 Test Module", libraryFile.path, 0, 0), + /NS_ERROR_FAILURE/, + "addModule should throw when in safe mode" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_slot.js b/security/manager/ssl/tests/unit/test_pkcs11_slot.js new file mode 100644 index 0000000000..993a09d951 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_slot.js @@ -0,0 +1,135 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 slot. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function find_slot_by_name(module, name) { + for (let slot of module.listSlots()) { + if (slot.name == name) { + return slot; + } + } + return null; +} + +function find_module_by_name(moduleDB, name) { + for (let slot of moduleDB.listModules()) { + if (slot.name == name) { + return slot; + } + } + return null; +} + +function run_test() { + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + loadPKCS11Module(libraryFile, "PKCS11 Test Module", false); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let testModule = find_module_by_name(moduleDB, "PKCS11 Test Module"); + notEqual(testModule, null, "should be able to find test module"); + let testSlot = find_slot_by_name(testModule, "Test PKCS11 Slot 二"); + notEqual(testSlot, null, "should be able to find 'Test PKCS11 Slot 二'"); + + equal( + testSlot.name, + "Test PKCS11 Slot 二", + "Actual and expected name should match" + ); + equal( + testSlot.desc, + "Test PKCS11 Slot 二", + "Actual and expected description should match" + ); + equal( + testSlot.manID, + "Test PKCS11 Manufacturer ID", + "Actual and expected manufacturer ID should match" + ); + equal( + testSlot.HWVersion, + "0.0", + "Actual and expected hardware version should match" + ); + equal( + testSlot.FWVersion, + "0.0", + "Actual and expected firmware version should match" + ); + equal( + testSlot.status, + Ci.nsIPKCS11Slot.SLOT_READY, + "Actual and expected status should match" + ); + equal( + testSlot.tokenName, + "Test PKCS11 Tokeñ 2 Label", + "Actual and expected token name should match" + ); + + let testToken = testSlot.getToken(); + notEqual(testToken, null, "getToken() should succeed"); + equal( + testToken.tokenName, + "Test PKCS11 Tokeñ 2 Label", + "Spot check: the actual and expected test token names should be equal" + ); + ok(!testToken.isInternalKeyToken, "This token is not the internal key token"); + + testSlot = find_slot_by_name(testModule, "Empty PKCS11 Slot"); + notEqual(testSlot, null, "should be able to find 'Empty PKCS11 Slot'"); + equal(testSlot.tokenName, null, "Empty slot is empty"); + equal( + testSlot.status, + Ci.nsIPKCS11Slot.SLOT_NOT_PRESENT, + "Actual and expected status should match" + ); + + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + let internalModule = find_module_by_name( + moduleDB, + "NSS Internal PKCS #11 Module" + ); + notEqual(internalModule, null, "should be able to find internal module"); + let cryptoSlot = find_slot_by_name( + internalModule, + bundle.GetStringFromName("TokenDescription") + ); + notEqual(cryptoSlot, "should be able to find internal crypto slot"); + equal( + cryptoSlot.desc, + bundle.GetStringFromName("SlotDescription"), + "crypto slot should have expected 'desc'" + ); + equal( + cryptoSlot.manID, + bundle.GetStringFromName("ManufacturerID"), + "crypto slot should have expected 'manID'" + ); + let keySlot = find_slot_by_name( + internalModule, + bundle.GetStringFromName("PrivateTokenDescription") + ); + notEqual(keySlot, "should be able to find internal key slot"); + equal( + keySlot.desc, + bundle.GetStringFromName("PrivateSlotDescription"), + "key slot should have expected 'desc'" + ); + equal( + keySlot.manID, + bundle.GetStringFromName("ManufacturerID"), + "key slot should have expected 'manID'" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_token.js b/security/manager/ssl/tests/unit/test_pkcs11_token.js new file mode 100644 index 0000000000..06096eda96 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_token.js @@ -0,0 +1,149 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 token, using +// the internal key token. +// We don't use either of the test tokens in the test PKCS #11 module because: +// 1. Test token 1 cyclically inserts and removes itself in a tight loop. +// Using token 1 would complicate the test and introduce intermittent +// failures. +// 2. Neither test token implements login or password related functionality. +// We want to test such functionality. +// 3. Using the internal token lets us actually test the internal token works +// as expected. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function checkBasicAttributes(token) { + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + + let expectedTokenName = bundle.GetStringFromName("PrivateTokenDescription"); + equal( + token.tokenName, + expectedTokenName, + "Actual and expected name should match" + ); + equal( + token.tokenManID, + bundle.GetStringFromName("ManufacturerID"), + "Actual and expected manufacturer ID should match" + ); + equal( + token.tokenHWVersion, + "0.0", + "Actual and expected hardware version should match" + ); + equal( + token.tokenFWVersion, + "0.0", + "Actual and expected firmware version should match" + ); + equal( + token.tokenSerialNumber, + "0000000000000000", + "Actual and expected serial number should match" + ); +} + +/** + * Checks the various password related features of the given token. + * The token should already have been init with a password and be logged into. + * The password of the token will be reset after calling this function. + * + * @param {nsIPK11Token} token + * The token to test. + * @param {String} initialPW + * The password that the token should have been init with. + */ +function checkPasswordFeaturesAndResetPassword(token, initialPW) { + ok( + !token.needsUserInit, + "Token should not need user init after setting a password" + ); + ok( + token.hasPassword, + "Token should have a password after setting a password" + ); + + ok( + token.checkPassword(initialPW), + "checkPassword() should succeed if the correct initial password is given" + ); + token.changePassword(initialPW, "newPW ÿ 一二三"); + ok( + token.checkPassword("newPW ÿ 一二三"), + "checkPassword() should succeed if the correct new password is given" + ); + + ok( + !token.checkPassword("wrongPW"), + "checkPassword() should fail if an incorrect password is given" + ); + ok( + !token.isLoggedIn(), + "Token should be logged out after an incorrect password was given" + ); + ok( + !token.needsUserInit, + "Token should still be init with a password even if an incorrect " + + "password was given" + ); + + token.reset(); + ok(token.needsUserInit, "Token should need password init after reset"); + ok(!token.hasPassword, "Token should not have a password after reset"); + ok(!token.isLoggedIn(), "Token should be logged out of after reset"); +} + +function run_test() { + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + notEqual(token, null, "The internal token should be present"); + ok( + token.isInternalKeyToken, + "The internal token should be represented as such" + ); + + checkBasicAttributes(token); + + ok(!token.isLoggedIn(), "Token should not be logged into yet"); + // Test that attempting to log out even when the token was not logged into + // does not result in an error. + token.logoutSimple(); + ok(!token.isLoggedIn(), "Token should still not be logged into"); + ok( + !token.hasPassword, + "Token should not have a password before it has been set" + ); + + let initialPW = "foo 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/? 一二三"; + token.initPassword(initialPW); + token.login(/* force */ false); + ok(token.isLoggedIn(), "Token should now be logged into"); + + checkPasswordFeaturesAndResetPassword(token, initialPW); + + // We reset the password previously, so we need to initialize again. + token.initPassword("arbitrary"); + ok( + token.isLoggedIn(), + "Token should be logged into after initializing password again" + ); + token.logoutSimple(); + ok( + !token.isLoggedIn(), + "Token should be logged out after calling logoutSimple()" + ); + + ok( + token.needsLogin(), + "The internal token should always need authentication" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js b/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js new file mode 100644 index 0000000000..127c533439 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js @@ -0,0 +1,20 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods for interfacing with the PKCS #11 token database. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function run_test() { + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + + notEqual( + tokenDB.getInternalKeyToken(), + null, + "The internal token should be non-null" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem b/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem new file mode 100644 index 0000000000..29428ad015 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVDCCAtugAwIBAgIQE1Iuv8HdXOEe8nZAdR/n3zAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTE2MDYwOTAwMDAwMFoXDTMxMDYwODIzNTk1OVowYjEcMBoGA1UE +AwwTQXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAELVSOaLAQE+/0LdvYCbJD6J1lmW40uNSXyY7J +1qgiNzLIcWDusPHyxWT2ukdf/OYHeDIt9sqAIMn9cPhykyGIRaOCATowggE2MBIG +A1UdEwEB/wQIMAYBAf8CAQAwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2cuc3lt +Y2IuY29tL0dlb1RydXN0UENBLUcyLmNybDAOBgNVHQ8BAf8EBAMCAQYwLgYIKwYB +BQUHAQEEIjAgMB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wSQYDVR0g +BEIwQDA+BgZngQwBAgIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2VvdHJ1 +c3QuY29tL3Jlc291cmNlcy9jcHMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF +BwMCMB0GA1UdDgQWBBTDxKRYBWPXgwa6lo3cso8y9ru3QTAfBgNVHSMEGDAWgBQV +XzVXUVX7JbKtA2n8AaP6vhFV1TAKBggqhkjOPQQDAwNnADBkAjBH2jMNybjCk3Ts +OidXxJX9YDPMd5S3KDCv8vyTdJGhtoly7fQJRNv5rnVz+6YGfsMCMEp6wyheL7NK +mqavsduix2R+j1B3wRjelzJYgXzgM3nwhQKKlJWxpF7IGHuva1taxg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.key b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key new file mode 100644 index 0000000000..8af23e068d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem b/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem new file mode 100644 index 0000000000..ce7c05fd0c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIGuzCCBmCgAwIBAgIQJwfBKDdrh96xNA/Wr1LyATAKBggqhkjOPQQDAjBiMRww +GgYDVQQDDBNBcHBsZSBJU1QgQ0EgOCAtIEcxMSAwHgYDVQQLDBdDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw +HhcNMTkwMzExMjA1MDE0WhcNMjEwNDA5MjA1MDE0WjCBgjEiMCAGA1UEAwwZZ3Nw +ZTcyLTQtc3NsLmxzLmFwcGxlLmNvbTElMCMGA1UECwwcbWFuYWdlbWVudDppZG1z +Lmdyb3VwLjY2NTAzNTETMBEGA1UECgwKQXBwbGUgSW5jLjETMBEGA1UECAwKQ2Fs +aWZvcm5pYTELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATr +NqVhtJlzuIqo/qrkTFUFe8IRKh9sOr6HXrbvE1vUIbUcWcfhWs8dczP9RBCw6TNI +TGHAhuG2RZ/f9IrUjSldo4IE1TCCBNEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW +gBTDxKRYBWPXgwa6lo3cso8y9ru3QTB+BggrBgEFBQcBAQRyMHAwNAYIKwYBBQUH +MAKGKGh0dHA6Ly9jZXJ0cy5hcHBsZS5jb20vYXBwbGVpc3RjYThnMS5kZXIwOAYI +KwYBBQUHMAGGLGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYXBwbGVpc3Rj +YThnMTA1MCQGA1UdEQQdMBuCGWdzcGU3Mi00LXNzbC5scy5hcHBsZS5jb20wgf4G +A1UdIASB9jCB8zCB8AYKKoZIhvdjZAULBDCB4TCBpAYIKwYBBQUHAgIwgZcMgZRS +ZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVz +IGFjY2VwdGFuY2Ugb2YgYW55IGFwcGxpY2FibGUgdGVybXMgYW5kIGNvbmRpdGlv +bnMgb2YgdXNlIGFuZC9vciBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVu +dHMuMDgGCCsGAQUFBwICMCwMKmh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj +YXRlYXV0aG9yaXR5LzAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYD +VR0fBDAwLjAsoCqgKIYmaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYThn +MS5jcmwwHQYDVR0OBBYEFNNlLsYlY4okSG2S2Gl2UMdPlkbzMA4GA1UdDwEB/wQE +AwIDiDCCAnAGCisGAQQB1nkCBAIEggJgBIICXAJaAHYAu9nfvB+KcbWTlCOXqpJ7 +RzhXlQqrUugakJZkNo4e0YUAAAFpbo5SYgAABAMARzBFAiATXJMIgS9+f9P92SWY +0oYi/vRuE4hTvLANoLv0FLE7WwIhAJBMLXnqV3k8R7yWdISnvRZF0/QBmMK632Cp +N/kcpd3SAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFpbo5S +WQAABAMARzBFAiBCsSdFBiDjDEMsKdI8FyXD0aS6fCZ9bAuNYIGNPfAGhQIhAJ/R +mCOrVp/GBOg0CLYrjJcBbIAGditNOg8Kd8WTP85fAHYA7ku9t3XOYLrhQmkfq+Ge +ZqMPfl+wctiDAMR7iXqo/csAAAFpbo5SXgAABAMARzBFAiEAvzTu/MJBrBuyhPCj +6R6qtyTLyTrin/HmOttlH6iJ4IsCICuqq2EK9+k8w0c6BuBtfK1BDw/lUUGqtSDZ +svcDKVkIAHcAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0wwAAAFpbo5U +5wAABAMASDBGAiEA92TvuiKRNcHjkIZlCo2TBW/ZFWvOoZwgoC6mB1CHmTcCIQDm +cHuw1Ap1MUC6W+s76Im/js9KBumICSxByBkjxI1w6AB3AG9Tdqwx8DEZ2JkApFEV +/3cVHBHZAsEAKQaNsgiaN9kTAAABaW6OVTEAAAQDAEgwRgIhAPaUtnaDmwkQvO3i +nzgdo7AOVh1DEco+axckyrcxJgAKAiEA++0eb4HftQ9rUh9oZNYvqnyVSwNZfZwW +5DYuKcTTRhswCgYIKoZIzj0EAwIDSQAwRgIhAJVASCnbb+d9zglT5b7wirXUxvEu +nkHBAsB7VcVNqBEfAiEAiAlD40/WXTh31J41SVyb4CaQDTn0V+MstUnS1h+M1Cg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/moz.build b/security/manager/ssl/tests/unit/test_sanctions/moz.build new file mode 100644 index 0000000000..7318333a99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'default-ee.pem', +# 'symantec-ee-from-allowlist-after-cutoff.pem', +# 'symantec-ee-from-allowlist-before-cutoff.pem', +# 'symantec-ee-not-allowlisted-after-cutoff.pem', +# 'symantec-ee-not-allowlisted-before-cutoff.pem', +# 'symantec-intermediate-other.pem', +# 'symantec-intermediate-other-crossigned.pem', +# 'symantec-intermediate-allowlisted.pem', +# 'symantec-test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem new file mode 100644 index 0000000000..95316b235e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUN+Dcp+HeMvZhIJ3BD5af4bwrj4IwDQYJKoZIhvcNAQEL +BQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMT +HEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwIhgPMjAxNjA2MDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowKTEnMCUGA1UEAwweZWUtZnJvbS1hbGxvd2xpc3Qt +YWZ0ZXItY3V0b2ZmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABozowODA2BgNVHREELzAtgitzeW1hbnRlYy1hbGxv +d2xpc3QtYWZ0ZXItY3V0b2ZmLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IB +AQB/2Pgyyje+T4uKkibYZ537NZB6OUvef4nrGtswjxKbUnHzrLK1kJd3mtyNpydK +fzW8WV1CR+nltFI5oaoOAf26FuQfaoCADmlmFlirgnm2fEH2xCokDCQHIgQxNwXr +Ok6JTHWeuaOsu+verDPjkuUATnONY+FRTBxfPh5B3OA+aBO62bAeNCAjIya1U60S +emAnleYtwhXs0Q9TLsR7O7aSYP3FgnqnWPuOkPF3wrUiE8Nrd3givz5OJW42IU63 +ijiojHtPpjAiudbzD8y1zuDcxTxiI4jEjTDS1kIqnvHd3f4bSxpgcQUPk44nu+wO +j5+as/TRu5dC+xHmWCVT10yd +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec new file mode 100644 index 0000000000..c8a4249dfc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +subject:ee-from-allowlist-after-cutoff +validity:20160601-20500101 +extension:subjectAlternativeName:symantec-allowlist-after-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem new file mode 100644 index 0000000000..0c8a52b8d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUVWP+EbM7hYQLOXoABvWpRwoPWJ0wDQYJKoZIhvcNAQEL +BQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMT +HEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwIhgPMjAxNDA2MDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowKjEoMCYGA1UEAwwfZWUtZnJvbS1hbGxvd2xpc3Qt +YmVmb3JlLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaM7MDkwNwYDVR0RBDAwLoIsc3ltYW50ZWMtYWxs +b3dsaXN0LWJlZm9yZS1jdXRvZmYuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAFhn9xNv/Yp1Ua9OX7oXgbVgzxCIAm6/zDK7V4V37P5em/lI85OpbuuTO4ns +9VB2/nijkELhSkiyCjmCaxQhlUBzA/2wJeNIfaWu9Mq5MR6jWShhNXND66lTCDIQ +wGVQkBl8/3OqSD4IFI3pKAiPhCGsUnRIhGSARcrFMQpKssnN5XN1ump1YA7/u6Kv +apNbKccgKvLekO8/kUpFrpHt+uQaNS2IeVrmOnNh4GtyD3DG1ZDcZ1VgLAnzbVUg +xiUbs58mY0o1qumuzqJ0/ie5UPOjWnoXSNq6dd4jqsXcFeYXe106G6arV5BLN1Pa +gNxxfOfBcebE1OwxZpfQwNy3JxI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec new file mode 100644 index 0000000000..51cecd1f8e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +subject:ee-from-allowlist-before-cutoff +validity:20140601-20500101 +extension:subjectAlternativeName:symantec-allowlist-before-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem new file mode 100644 index 0000000000..65eab919b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIUNWWgyC4I0/jmqdamoCRL0qhP3QQwDQYJKoZIhvcNAQEL +BQAwTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3RoZXIgQ0EgSW5jLjEmMCQG +A1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhlcnMwIhgPMjAxNjA2MDEw +MDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowKjEoMCYGA1UEAwwfZWUtbm90LWFsbG93 +bGlzdGVkLWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNAMD4wPAYDVR0RBDUwM4Ixc3ltYW50 +ZWMtbm90LWFsbG93bGlzdGVkLWFmdGVyLWN1dG9mZi5leGFtcGxlLmNvbTANBgkq +hkiG9w0BAQsFAAOCAQEARlQNYz+w2ekzdX8FKwlWoMX6Df5o4ZhXreRK9V4SuYJg +SvAucL35TuTKkBz9C5VPjAL/Qts4n5DKWaWQfsvoCJOGtTMEKd1MEL9RbMFOewI0 +tN9sV9aMNsmhNPL4PB3A7lKJb8gi/tyoN3BXjsaZBxmyi5A6Vt3lyybgMOSTdzR6 +u2XAPm+zNDrOzc2tavZEyhEKzptaJuCQrefcnAM9JTHtJhvJp30WWighJyclqmRX +bLDYaHRRuRI0jkgrrcUKolau8YKsSoIBoxP2aels8drZDH4UAC86GW2iF/tK+J65 ++JJ2Mk9erdcLoYGLxHZqQySpRaFtciSF+Uym1nmNxA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec new file mode 100644 index 0000000000..85edcf742d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +subject:ee-not-allowlisted-after-cutoff +validity:20160601-20500101 +extension:subjectAlternativeName:symantec-not-allowlisted-after-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem new file mode 100644 index 0000000000..23d6fec107 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTTCCAjWgAwIBAgIUaxGuzjOrA/2qScMaz5tKQTUrvAYwDQYJKoZIhvcNAQEL +BQAwTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3RoZXIgQ0EgSW5jLjEmMCQG +A1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhlcnMwIhgPMjAxNDA2MDEw +MDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowKzEpMCcGA1UEAwwgZWUtbm90LWFsbG93 +bGlzdGVkLWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjQTA/MD0GA1UdEQQ2MDSCMnN5bWFu +dGVjLW5vdC1hbGxvd2xpc3RlZC1iZWZvcmUtY3V0b2ZmLmV4YW1wbGUuY29tMA0G +CSqGSIb3DQEBCwUAA4IBAQBCkIIEXnX/3rv0JuF0FZEpROnQw8zoa4vZjwG1NmvH ++PwnTL7FvBg9QBK0n8ZKfCMqJU98jR5+x6V9Eo2amXEYRAsxCU6kY/Xz43OxGLQz +5cbr9eDswWmt7h/LXl0tsprpgfBNaQ9512UbPMkDG4MSwLjkuTgdnM4dBsLURrAU +5lcukutuNYJ7x92/Ah7hffouB6QHyP80onxqqQTQs2j/0MvJxlUWrnKBzk+B475W +/1iMOCE3r2q6+TVp1sun9mcn7UvRHQRPvjSdjujjJ++5fqH5s4cF2Sv4lv+dEGJn +xrr/a9GA3bUE6Iq9PbAeX3l7RaP+q/znSDBtaLYZ1Xau +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec new file mode 100644 index 0000000000..b736169a04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +subject:ee-not-allowlisted-before-cutoff +validity:20140601-20500101 +extension:subjectAlternativeName:symantec-not-allowlisted-before-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem new file mode 100644 index 0000000000..e912276ff2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAnmgAwIBAgIUWaPXi1S7qZSZ1omEbmdrNrvj/0MwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjBJMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMc +R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQD +AgEGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALSeQ+T+3AVPidHI +Mk5D6qOJm57AQ1J5VWoD+S/vqO9jaBjXGtPfx1yBCgLfZvF5N9Wy/foNLhx49BXf +gwUZPXr5skG9TXPdiZinPW1Txfq/JfJPIeHKdL1eHCm9L/7HVAv1TNlfWFIukGOh +ZIuzBXID5MH9ubOpY1RcgAxa4wQknPAQ2ZPAcdTzEvKOOv6O78EHTv5TKU6/vk+B +COS3S86eInm0JcomC+L0H7JT0mCGAzFB7EgWEgnPH8hvi40H2Bml35a192VOdq3o +XZSoA0ZfARlpcetAu+PjPyoo6UwQ52p4ifXVJoOuZSsRsxmADJpjq1JwTQy3Axah +ELBHK0c= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec new file mode 100644 index 0000000000..745bd9436a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem new file mode 100644 index 0000000000..819d8a30da --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFzCCAf+gAwIBAgIUBy1RVPb6jMqyBSQwtlK+jZftnKIwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVW5rbm93biBJc3N1ZXIwIhgPMjAxMDAxMDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3Ro +ZXIgQ0EgSW5jLjEmMCQGA1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhl +cnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQAs7dfRClCtgzMfYVRIciVqdjNR+jeFLmYFCDDqx5h6zve4VfxK +AEQPWNsIVdPlu+djILHHd9+RvLSHh5HqeXKppBevnux2SxwfXJQ3T+ysqGxH4tEQ +BCgXryt8v5q/DL9H2+T352NJCh7ZMkftEta3Hchtr4TSaT7udtib1uQ9JeLx97LJ +A6aI8SpfI/as1Ku1LAAV9rfhkJgMyeC0ppMfTVGj/gjgq8fL52/9Su9Id8l+SeYD +yLCXjPX0rhAjTeJyiOpAK9OPQgk7i3DRvdO/F+JCkTNE9V6PLX0J+30g+3YZND+a +R81zibhRfa6Ki5cqRflHYhAY4GCFk7mhHLsL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec new file mode 100644 index 0000000000..fdcb287cd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec @@ -0,0 +1,5 @@ +issuer:Unknown Issuer +subject:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem new file mode 100644 index 0000000000..fae3cd2055 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlzCCAn+gAwIBAgIUcwyTGJUUq4KcHJ1Vb27ydVW1+8UwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjBPMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPQW5vdGhlciBDQSBJbmMuMSYwJAYD +VQQDEx1Tb21lIE90aGVyIENBIFRoYW4gVGhlIE90aGVyczCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYD +VR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHO5Uxu5 +l0orJ5uxTWaaeRrrua66fnDWZoI4BLJ988CpNtZQ7eyXglg2CnSPdQ8GwDKY7JPl +WGXnXNjbkxW7Br705yFFQOglVyLErXqaqzaTMGNqqS2vxZe/msiKUbhQN66glCSV +2apocQceCIP9dvP7EZvnWcZFn/6/qjgfZ3E7VNTRC8hGcd9NI1rfreHWevBierDe +l9cNIta1Qjvj8qzHKDfsrxrk1UlDJemtLvBvE3aGU7YrtVcOZA3l8mnrtfbBgoTJ +FH3H5Z1rw7uY7TcHK8YSIr4BGh8AAYmx69w87tL6FpOTuJvfW24Fj3aIbm5C4JDP +Or8OZj97VdCJ9ds= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec new file mode 100644 index 0000000000..980edf8ac7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem new file mode 100644 index 0000000000..c9aba820ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIUdbQmR0wwLxnOuBWx8JRJkIlK0skwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjCBmDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNV +BAsTMChjKSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug +b25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAQEAMheHA8TX+WozmLeUr8J3FF+x2l2vGSWiW8W4 +wkC1ETDEc81FxEVip0EDpp6aFurIwOOejL8a8B3hEXd7rqCCsaO8yUYQxaQMPuB5 +4OtBuTcCtIpHeCfwCcUQPes12dCyf3v5stQl5tAF9S/ddEn84Rbntb2ZIRotQnof +MjpelWuZRmMRvTtQ9BIUID5GuZcMvCmRap011az1nGOJvSsOh2ag+Yz9tTOD3gDM +z0DIoUUGSQuu0Csw1nJiAIdtlBzwgy1g2YoGTEc3vuFp9KHywPDsdOytlLuIh03k +C5Vi3DQOO5elqy/I8eeM86PfO9lySyVF7wjiB//IFlQoyl8TMA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec new file mode 100644 index 0000000000..1367ecf53e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js b/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js new file mode 100644 index 0000000000..b94de49c41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js @@ -0,0 +1,107 @@ +/* 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 handling of certificates issued by Symantec. If such certificates were +// issued by an Apple or Google intermediate, they are allowlisted. Otherwise, +// If they have a notBefore before 1 June 2016, they should be distrusted, while +// those from that date or later emit a warning to the console. + +function shouldBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(isDistrust, "This host should be imminently distrusted"); +} + +do_get_profile(); + +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +add_tls_server_setup( + "SanctionsTestServer", + "test_sanctions", + /* Don't try to load non-existent test-ca.pem */ false +); + +addCertFromFile(certDB, "test_sanctions/symantec-test-ca.pem", "CTu,u,u"); + +// Add the necessary intermediates. This is important because the test server, +// though it will attempt to send along an intermediate, isn't able to reliably +// pick between the intermediate-other-crossigned and intermediate-other. +add_test(function() { + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-allowlisted.pem", + ",," + ); + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-other.pem", + ",," + ); + run_next_test(); +}); + +add_connection_test( + "symantec-not-allowlisted-before-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +add_connection_test( + "symantec-not-allowlisted-after-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +// Add a cross-signed intermediate into the database, and ensure we still get +// the expected error. +add_test(function() { + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-other-crossigned.pem", + ",," + ); + run_next_test(); +}); + +add_connection_test( + "symantec-not-allowlisted-before-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +// Load the Apple EE cert and its intermediate, then verify +// it at a reasonable time and make sure the allowlists work +add_task(async function() { + addCertFromFile( + certDB, + "test_sanctions/apple-ist-ca-8-g1-intermediate.pem", + ",," + ); + let allowlistedCert = constructCertFromFile( + "test_sanctions/gspe72-4-ssl-ls-apple-com.pem" + ); + + // Since we don't want to actually try to fetch OCSP for this certificate, + // (as an external fetch is bad in the tests), disable OCSP first. + Services.prefs.setIntPref("security.OCSP.enabled", 0); + + // (new Date("2020-01-01")).getTime() / 1000 + const VALIDATION_TIME = 1577836800; + + await checkCertErrorGenericAtTime( + certDB, + allowlistedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + VALIDATION_TIME + ); +}); diff --git a/security/manager/ssl/tests/unit/test_sdr.js b/security/manager/ssl/tests/unit/test_sdr.js new file mode 100644 index 0000000000..e9e477efc5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr.js @@ -0,0 +1,272 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various aspects of the nsISecretDecoderRing implementation. + +do_get_profile(); + +let gSetPasswordShownCount = 0; + +// Mock implementation of nsITokenPasswordDialogs. +const gTokenPasswordDialogs = { + setPassword(ctx, tokenName) { + gSetPasswordShownCount++; + info(`setPassword() called; shown ${gSetPasswordShownCount} times`); + info(`tokenName: ${tokenName}`); + return false; // Returning false means "the user didn't cancel". + }, + + QueryInterface: ChromeUtils.generateQI(["nsITokenPasswordDialogs"]), +}; + +let gMockPrompter = { + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + // Returning false simulates the user canceling the password prompt. + return false; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +let gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +add_task(function setup() { + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); +}); + +add_task(function testEncryptString() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let inputs = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + for (let input of inputs) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(input); + convertedInput += converter.Finish(); + + let encrypted = sdr.encryptString(convertedInput); + + notEqual( + convertedInput, + encrypted, + "Encrypted input should not just be the input itself" + ); + + try { + atob(encrypted); + } catch (e) { + ok(false, `encryptString() should have returned Base64: ${e}`); + } + + equal( + convertedInput, + sdr.decryptString(encrypted), + "decryptString(encryptString(input)) should return input" + ); + } + + // Test invalid inputs for decryptString(). + throws( + () => sdr.decryptString("*"), + /NS_ERROR_ILLEGAL_VALUE/, + "decryptString() should throw if given non-Base64 input" + ); + + // Test calling changePassword() pops up the appropriate dialog. + // Note: On Android, nsITokenPasswordDialogs is apparently not implemented, + // which also seems to prevent us from mocking out the interface. + if (AppConstants.platform != "android") { + let tokenPasswordDialogsCID = MockRegistrar.register( + "@mozilla.org/nsTokenPasswordDialogs;1", + gTokenPasswordDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(tokenPasswordDialogsCID); + }); + + equal( + gSetPasswordShownCount, + 0, + "changePassword() dialog should have been shown zero times" + ); + sdr.changePassword(); + equal( + gSetPasswordShownCount, + 1, + "changePassword() dialog should have been shown exactly once" + ); + } +}); + +add_task(async function testAsyncEncryptStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let inputs = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + + let encrypteds = await sdr.asyncEncryptStrings(inputs); + for (let i = 0; i < inputs.length; i++) { + let encrypted = encrypteds[i]; + let input = inputs[i]; + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(input); + convertedInput += converter.Finish(); + notEqual( + convertedInput, + encrypted, + "Encrypted input should not just be the input itself" + ); + + try { + atob(encrypted); + } catch (e) { + ok(false, `encryptString() should have returned Base64: ${e}`); + } + + equal( + convertedInput, + sdr.decryptString(encrypted), + "decryptString(encryptString(input)) should return input" + ); + } +}); + +add_task(async function testAsyncDecryptStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let testCases = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + + let convertedTestCases = testCases.map(tc => { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(tc); + convertedInput += converter.Finish(); + return convertedInput; + }); + + let encryptedStrings = convertedTestCases.map(tc => sdr.encryptString(tc)); + let decrypteds = await sdr.asyncDecryptStrings(encryptedStrings); + for (let i = 0; i < encryptedStrings.length; i++) { + let decrypted = decrypteds[i]; + + equal( + decrypted, + testCases[i], + "decrypted string should match expected value" + ); + equal( + sdr.decryptString(encryptedStrings[i]), + convertedTestCases[i], + "decryptString(encryptString(input)) should return the initial decrypted string value" + ); + } +}); + +add_task(async function testAsyncDecryptInvalidStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test invalid inputs for sdr.asyncDecryptStrings + let testCases = [ + "~bmV0cGxheQ==", // invalid base64 encoding + "bmV0cGxheQ==", // valid base64 characters but not encrypted + "https://www.example.com", // website address from erroneous migration + ]; + + let decrypteds = await sdr.asyncDecryptStrings(testCases); + equal( + decrypteds.length, + testCases.length, + "each testcase should still return a response" + ); + for (let i = 0; i < decrypteds.length; i++) { + let decrypted = decrypteds[i]; + + equal( + decrypted, + "", + "decrypted string should be empty when trying to decrypt an invalid input with asyncDecryptStrings" + ); + + Assert.throws( + () => sdr.decryptString(testCases[i]), + /NS_ERROR_ILLEGAL_VALUE|NS_ERROR_FAILURE/, + `Check testcase would have thrown: ${testCases[i]}` + ); + } +}); + +add_task(async function testAsyncDecryptLoggedOut() { + // Set a master password. + let token = Cc["@mozilla.org/security/pk11tokendb;1"] + .getService(Ci.nsIPK11TokenDB) + .getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + await Assert.rejects( + sdr.asyncDecryptStrings(["irrelevant"]), + /NS_ERROR_NOT_AVAILABLE/, + "Check error is thrown instead of returning empty strings" + ); + + token.reset(); + token.initPassword(""); +}); diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting.js b/security/manager/ssl/tests/unit/test_sdr_preexisting.js new file mode 100644 index 0000000000..69b5c194df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting.js @@ -0,0 +1,79 @@ +// -*- 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 the SDR implementation is able to decrypt strings encrypted using +// a preexisting NSS key database. Creating the database is straight-forward: +// simply run Firefox (or xpcshell) and encrypt something using +// nsISecretDecoderRing (e.g. by saving a password or directly using the +// interface). The resulting key4.db file (in the profile directory) now +// contains the private key used to encrypt the data. + +function run_test() { + const keyDBName = "key4.db"; + let profile = do_get_profile(); + let keyDBFile = do_get_file(`test_sdr_preexisting/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + let testcases = [ + // a full padding block + { + ciphertext: + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d", + plaintext: "password", + }, + // 7 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECCAzLDVmYG2/BAh3IoIsMmT8dQ==", + plaintext: "a", + }, + // 6 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECPN8zlZzn8FdBAiu2acpT8UHsg==", + plaintext: "bb", + }, + // 1 byte of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECD5px1eMKkJQBAgUPp35GlrDvQ==", + plaintext: "!seven!", + }, + // 2 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECMh0hLtKDyUdBAixw9UZsMt+vA==", + plaintext: "sixsix", + }, + // long plaintext requiring more than two blocks + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDATFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "thisismuchlongerandsotakesupmultipleblocks", + }, + // this differs from the previous ciphertext by one bit and demonstrates + // that this implementation does not enforce message integrity + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDAbFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "nnLbuwLRkhlongerandsotakesupmultipleblocks", + }, + ]; + + for (let testcase of testcases) { + let decrypted = sdr.decryptString(testcase.ciphertext); + equal( + decrypted, + testcase.plaintext, + "decrypted ciphertext should match expected plaintext" + ); + } +} diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db b/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db Binary files differnew file mode 100644 index 0000000000..8f320dfdbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js new file mode 100644 index 0000000000..8502d88a40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js @@ -0,0 +1,138 @@ +// -*- 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 the SDR implementation is able to decrypt strings encrypted using +// a preexisting NSS key database that has a password. +// To create such a database, run Firefox (or xpcshell), set a primary +// password, and then encrypt something using nsISecretDecoderRing. + +var gMockPrompter = { + passwordToTry: "password", + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +function run_test() { + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + + // Append a single quote and non-ASCII characters to the profile path. + let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + file.initWithPath(profd); + file.append("'÷1"); + env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + + let profile = do_get_profile(); // must be called before getting nsIX509CertDB + Assert.ok( + /[^\x20-\x7f]/.test(profile.path), + "the profile path should contain a non-ASCII character" + ); + + let key4DBFile = do_get_file("test_sdr_preexisting_with_password/key4.db"); + key4DBFile.copyTo(profile, "key4.db"); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + let testcases = [ + // a full padding block + { + ciphertext: + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d", + plaintext: "password", + }, + // 7 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECCAzLDVmYG2/BAh3IoIsMmT8dQ==", + plaintext: "a", + }, + // 6 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECPN8zlZzn8FdBAiu2acpT8UHsg==", + plaintext: "bb", + }, + // 1 byte of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECD5px1eMKkJQBAgUPp35GlrDvQ==", + plaintext: "!seven!", + }, + // 2 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECMh0hLtKDyUdBAixw9UZsMt+vA==", + plaintext: "sixsix", + }, + // long plaintext requiring more than two blocks + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDATFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "thisismuchlongerandsotakesupmultipleblocks", + }, + // this differs from the previous ciphertext by one bit and demonstrates + // that this implementation does not enforce message integrity + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDAbFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "nnLbuwLRkhlongerandsotakesupmultipleblocks", + }, + ]; + + for (let testcase of testcases) { + let decrypted = sdr.decryptString(testcase.ciphertext); + equal( + decrypted, + testcase.plaintext, + "decrypted ciphertext should match expected plaintext" + ); + } + equal( + gMockPrompter.numPrompts, + 1, + "Should have been prompted for a password once" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db Binary files differnew file mode 100644 index 0000000000..959718da34 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db diff --git a/security/manager/ssl/tests/unit/test_self_signed_certs.js b/security/manager/ssl/tests/unit/test_self_signed_certs.js new file mode 100644 index 0000000000..662cd59714 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_self_signed_certs.js @@ -0,0 +1,69 @@ +// -*- 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"; + +// This test uses a specially-crafted NSS cert DB containing 12 self-signed certificates that all +// have the same subject and issuer distinguished name. Since they all have different keys and none +// of them are trust anchors, there are a large number of potential trust paths that could be +// explored. If our trust domain were naive enough to allow mozilla::pkix to explore them all, it +// would take a long time to perform (mozilla::pkix does have the concept of a path-building budget, +// but even on a fast computer, it takes an unacceptable amount of time to exhaust). To prevent the +// full exploration of this space, NSSCertDBTrustDomain skips searching through self-signed +// certificates that aren't trust anchors, since those would never otherwise be essential to +// complete a path (note that this is only true as long as the extensions we support are restrictive +// rather than additive). +// When we try to verify one of these certificates in this test, we should finish relatively +// quickly, even on slow hardware. +// Should these certificates ever need regenerating, they were produced with the following commands: +// certutil -N -d . --empty-password +// for num in 00 01 02 03 04 05 06 07 08 09 10 11; do +// echo -ne "5\n6\n9\ny\ny\n\ny\n" | certutil -d . -S -s "CN=self-signed cert" -t ,, \ +// -q secp256r1 -x -k ec -z <(date +%s) -1 -2 -n cert$num; sleep 2; +// done + +add_task(async function run_test_no_overlong_path_building() { + let profile = do_get_profile(); + const CERT_DB_NAME = "cert9.db"; + let srcCertDBFile = do_get_file(`test_self_signed_certs/${CERT_DB_NAME}`); + srcCertDBFile.copyTo(profile, CERT_DB_NAME); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let certToVerify = null; + for (let cert of certDB.getCerts()) { + if (cert.subjectName == "CN=self-signed cert") { + certToVerify = cert; + break; + } + } + notEqual( + certToVerify, + null, + "should have found one of the preloaded self-signed certs" + ); + let timeBefore = Date.now(); + // As mentioned above, mozilla::pkix limits how much it will search for a trusted path, even if a + // trust domain keeps providing potential issuers. So, if we only tried to verify a certificate + // once, this test could potentially pass on a fast computer even if we weren't properly skipping + // unnecessary paths. If we were to try and lower our time limit (the comparison with + // secondsElapsed, below), this test would intermittently fail on slow hardware. By trying to + // verify the certificate 10 times, we hopefully end up with a meaningful test (it should still + // fail on fast hardware if we don't properly skip unproductive paths) that won't intermittently + // time out on slow hardware. + for (let i = 0; i < 10; i++) { + let date = new Date("2019-05-15T00:00:00.000Z"); + await checkCertErrorGenericAtTime( + certDB, + certToVerify, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLCA, + date.getTime() / 1000 + ); + } + let timeAfter = Date.now(); + let secondsElapsed = (timeAfter - timeBefore) / 1000; + ok(secondsElapsed < 120, "verifications shouldn't take too long"); +}); diff --git a/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db b/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db Binary files differnew file mode 100644 index 0000000000..5450fe82e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db diff --git a/security/manager/ssl/tests/unit/test_session_resumption.js b/security/manager/ssl/tests/unit/test_session_resumption.js new file mode 100644 index 0000000000..eb8e1796b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_session_resumption.js @@ -0,0 +1,298 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that PSM makes the correct determination of the security status of +// loads involving session resumption (i.e. when a TLS handshake bypasses the +// AuthCertificate callback). + +do_get_profile(); +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.OCSP.enabled"); + Services.prefs.clearUserPref("network.ssl_tokens_cache_enabled"); +}); + +Services.prefs.setIntPref("security.OCSP.enabled", 1); + +addCertFromFile(certdb, "bad_certs/evroot.pem", "CTu,,"); +addCertFromFile(certdb, "bad_certs/ev-test-intermediate.pem", ",,"); + +// For expired.example.com, the platform will make a connection that will fail. +// Using information gathered at that point, an override will be added and +// another connection will be made. This connection will succeed. At that point, +// as long as the session cache isn't cleared, subsequent new connections should +// use session resumption, thereby bypassing the AuthCertificate hook. We need +// to ensure that the correct security state is propagated to the new connection +// information object. +function add_resume_non_ev_with_override_test() { + // This adds the override and makes one successful connection. + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + + // This connects again, using session resumption. Note that we don't clear + // the TLS session cache between these operations (that would defeat the + // purpose). + add_connection_test( + "expired.example.com", + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "expired.example.com should have STATE_CERT_USER_OVERRIDDEN flag" + ); + equal( + transportSecurityInfo.succeededCertChain.length, + 0, + "ev-test.example.com should not have succeededCertChain set" + ); + ok( + !transportSecurityInfo.isDomainMismatch, + "expired.example.com should not have isDomainMismatch set" + ); + ok( + transportSecurityInfo.isNotValidAtThisTime, + "expired.example.com should have isNotValidAtThisTime set" + ); + ok( + !transportSecurityInfo.isUntrusted, + "expired.example.com should not have isUntrusted set" + ); + ok( + !transportSecurityInfo.isExtendedValidation, + "expired.example.com should not have isExtendedValidation set" + ); + + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("expired.example.com", 8443); + } + ); +} + +// Helper function that adds a test that connects to ev-test.example.com and +// verifies that it validates as EV (or not, if we're running a non-debug +// build). This assumes that an appropriate OCSP responder is running or that +// good responses are cached. +function add_one_ev_test() { + add_connection_test( + "ev-test.example.com", + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + !( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN + ), + "ev-test.example.com should not have STATE_CERT_USER_OVERRIDDEN flag" + ); + ok( + transportSecurityInfo.succeededCertChain, + "ev-test.example.com should have succeededCertChain set" + ); + ok( + !transportSecurityInfo.isDomainMismatch, + "ev-test.example.com should not have isDomainMismatch set" + ); + ok( + !transportSecurityInfo.isNotValidAtThisTime, + "ev-test.example.com should not have isNotValidAtThisTime set" + ); + ok( + !transportSecurityInfo.isUntrusted, + "ev-test.example.com should not have isUntrusted set" + ); + ok( + !gEVExpected || transportSecurityInfo.isExtendedValidation, + "ev-test.example.com should have isExtendedValidation set " + + "(or this is a non-debug build)" + ); + } + ); +} + +// This test is similar, except with extended validation. We should connect +// successfully, and the certificate should be EV in debug builds. Without +// clearing the session cache, we should connect successfully again, this time +// with session resumption. The certificate should again be EV in debug builds. +function add_resume_ev_test() { + const SERVER_PORT = 8888; + let expectedRequestPaths = gEVExpected + ? ["ev-test-intermediate", "ev-test"] + : ["ev-test"]; + let responseTypes = gEVExpected ? ["good", "good"] : ["good"]; + // Since we cache OCSP responses, we only ever actually serve one set. + let ocspResponder; + // If we don't wrap this in an `add_test`, the OCSP responder will be running + // while we are actually running unrelated testcases, which can disrupt them. + add_test(() => { + ocspResponder = startOCSPResponder( + SERVER_PORT, + "localhost", + "bad_certs", + expectedRequestPaths, + expectedRequestPaths.slice(), + null, + responseTypes + ); + run_next_test(); + }); + // We should be able to connect and verify the certificate as EV (in debug + // builds). + add_one_ev_test(); + // We should be able to connect again (using session resumption). In debug + // builds, the certificate should be noted as EV. Again, it's important that + // nothing clears the TLS cache in between these two operations. + add_one_ev_test(); + + add_test(() => { + ocspResponder.stop(run_next_test); + }); +} + +const GOOD_DOMAIN = "good.include-subdomains.pinning.example.com"; + +// Helper function that adds a test that connects to a domain that should +// succeed (but isn't EV) and verifies that its succeededCertChain gets set +// appropriately. +function add_one_non_ev_test() { + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + !( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN + ), + `${GOOD_DOMAIN} should not have STATE_CERT_USER_OVERRIDDEN flag` + ); + ok( + transportSecurityInfo.succeededCertChain, + `${GOOD_DOMAIN} should have succeededCertChain set` + ); + ok( + !transportSecurityInfo.isDomainMismatch, + `${GOOD_DOMAIN} should not have isDomainMismatch set` + ); + ok( + !transportSecurityInfo.isNotValidAtThisTime, + `${GOOD_DOMAIN} should not have isNotValidAtThisTime set` + ); + ok( + !transportSecurityInfo.isUntrusted, + `${GOOD_DOMAIN} should not have isUntrusted set` + ); + ok( + !transportSecurityInfo.isExtendedValidation, + `${GOOD_DOMAIN} should not have isExtendedValidation set` + ); + } + ); +} + +// This test is similar, except with non-extended validation. We should connect +// successfully, and the certificate should not be EV. Without clearing the +// session cache, we should connect successfully again, this time with session +// resumption. In this case, though, we want to ensure the succeededCertChain is +// set. +function add_resume_non_ev_test() { + add_one_non_ev_test(); + add_one_non_ev_test(); +} + +const statsPtr = getSSLStatistics(); +const toInt32 = ctypes.Int64.lo; + +// Connect to the same domain with two origin attributes and check if any ssl +// session is resumed. +function add_origin_attributes_test( + originAttributes1, + originAttributes2, + resumeExpected +) { + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + clearSessionCache, + null, + null, + originAttributes1 + ); + + let hitsBeforeConnect; + let missesBeforeConnect; + let expectedHits = resumeExpected ? 1 : 0; + let expectedMisses = 1 - expectedHits; + + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + function() { + // Add the hits and misses before connection. + let stats = statsPtr.contents; + hitsBeforeConnect = toInt32(stats.sch_sid_cache_hits); + missesBeforeConnect = toInt32(stats.sch_sid_cache_misses); + }, + function() { + let stats = statsPtr.contents; + equal( + toInt32(stats.sch_sid_cache_hits), + hitsBeforeConnect + expectedHits, + "Unexpected cache hits" + ); + equal( + toInt32(stats.sch_sid_cache_misses), + missesBeforeConnect + expectedMisses, + "Unexpected cache misses" + ); + }, + null, + originAttributes2 + ); +} + +function add_resumption_tests() { + add_resume_ev_test(); + add_resume_non_ev_test(); + add_resume_non_ev_with_override_test(); + add_origin_attributes_test({}, {}, true); + add_origin_attributes_test({ userContextId: 1 }, { userContextId: 2 }, false); + add_origin_attributes_test({ userContextId: 3 }, { userContextId: 3 }, true); + add_origin_attributes_test( + { firstPartyDomain: "foo.com" }, + { firstPartyDomain: "bar.com" }, + false + ); + add_origin_attributes_test( + { firstPartyDomain: "baz.com" }, + { firstPartyDomain: "baz.com" }, + true + ); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_resumption_tests(); + // Enable external session cache and reset the status. + add_test(function() { + Services.prefs.setBoolPref("network.ssl_tokens_cache_enabled", true); + certdb.clearOCSPCache(); + run_next_test(); + }); + // Do tests again. + add_resumption_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps.js b/security/manager/ssl/tests/unit/test_signed_apps.js new file mode 100644 index 0000000000..13f9a995fa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps.js @@ -0,0 +1,1013 @@ +"use strict"; + +// Tests the API nsIX509CertDB.openSignedAppFileAsync, which backs add-on +// signature verification. Testcases include various ways of tampering with +// add-ons as well as different hash algorithms used in the various +// signature/metadata files. + +// from prio.h +const PR_RDWR = 0x04; +const PR_CREATE_FILE = 0x08; +const PR_TRUNCATE = 0x20; +const PR_USEC_PER_MSEC = 1000; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// Creates a new app package based in the inFilePath package, with a set of +// modifications (including possibly deletions) applied to the existing entries, +// and/or a set of new entries to be included. +function tamper(inFilePath, outFilePath, modifications, newEntries) { + let writer = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter); + writer.open(outFilePath, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); + try { + let reader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance( + Ci.nsIZipReader + ); + reader.open(inFilePath); + try { + for (let entryName of reader.findEntries("")) { + let inEntry = reader.getEntry(entryName); + let entryInput = reader.getInputStream(entryName); + try { + let f = modifications[entryName]; + let outEntry, outEntryInput; + if (f) { + [outEntry, outEntryInput] = f(inEntry, entryInput); + delete modifications[entryName]; + } else { + [outEntry, outEntryInput] = [inEntry, entryInput]; + } + // if f does not want the input entry to be copied to the output entry + // at all (i.e. it wants it to be deleted), it will return null. + if (outEntryInput) { + try { + writer.addEntryStream( + entryName, + outEntry.lastModifiedTime, + outEntry.compression, + outEntryInput, + false + ); + } finally { + if (entryInput != outEntryInput) { + outEntryInput.close(); + } + } + } + } finally { + entryInput.close(); + } + } + } finally { + reader.close(); + } + + // Any leftover modification means that we were expecting to modify an entry + // in the input file that wasn't there. + for (let name in modifications) { + if (modifications.hasOwnProperty(name)) { + throw new Error("input file was missing expected entries: " + name); + } + } + + // Now, append any new entries to the end + newEntries.forEach(function(newEntry) { + let sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + try { + sis.setData(newEntry.content, newEntry.content.length); + writer.addEntryStream( + newEntry.name, + new Date() * PR_USEC_PER_MSEC, + Ci.nsIZipWriter.COMPRESSION_BEST, + sis, + false + ); + } finally { + sis.close(); + } + }); + } finally { + writer.close(); + } +} + +function removeEntry(entry, entryInput) { + return [null, null]; +} + +function truncateEntry(entry, entryInput) { + if (entryInput.available() == 0) { + throw new Error( + "Truncating already-zero length entry will result in " + + "identical entry." + ); + } + + let content = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + content.data = ""; + + return [entry, content]; +} + +function check_open_result(name, expectedRv) { + return function openSignedAppFileCallback(rv, aZipReader, aSignerCert) { + info("openSignedAppFileCallback called for " + name); + equal(rv, expectedRv, "Actual and expected return value should match"); + equal( + aZipReader != null, + Components.isSuccessCode(expectedRv), + "ZIP reader should be null only if the return value denotes failure" + ); + equal( + aSignerCert != null, + Components.isSuccessCode(expectedRv), + "Signer cert should be null only if the return value denotes failure" + ); + run_next_test(); + }; +} + +function original_app_path(test_name) { + return do_get_file("test_signed_apps/" + test_name + ".zip", false); +} + +function tampered_app_path(test_name) { + return FileUtils.getFile("TmpD", ["test_signed_app-" + test_name + ".zip"]); +} + +var hashTestcases = [ + // SHA-256 in PKCS#7 + SHA-256 present elsewhere => OK + { name: "app_mf-1-256_sf-1-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-1-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-1-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-1-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-256_p7-256", expectedResult: Cr.NS_OK }, + + // SHA-1 in PKCS#7 + SHA-1 present elsewhere => OK + { name: "app_mf-1-256_sf-1-256_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-1_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1_sf-1-256_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1_sf-1_p7-1", expectedResult: Cr.NS_OK }, + + // SHA-256 in PKCS#7 + SHA-256 not present elsewhere => INVALID + { + name: "app_mf-1-256_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1-256_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1-256_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1-256_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + + // SHA-1 in PKCS#7 + SHA-1 not present elsewhere => INVALID + { + name: "app_mf-1-256_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, +]; + +// Policy values for the preference "security.signed_app_signatures.policy" +const PKCS7WithSHA1OrSHA256 = 0b0; +const PKCS7WithSHA256 = 0b1; +const COSEAndPKCS7WithSHA1OrSHA256 = 0b10; +const COSEAndPKCS7WithSHA256 = 0b11; +const COSERequiredAndPKCS7WithSHA1OrSHA256 = 0b100; +const COSERequiredAndPKCS7WithSHA256 = 0b101; +const COSEOnly = 0b110; +const COSEOnlyAgain = 0b111; + +function add_signature_test(policy, test) { + // First queue up a test to set the desired policy: + add_test(function() { + Services.prefs.setIntPref("security.signed_app_signatures.policy", policy); + run_next_test(); + }); + // Then queue up the test itself: + add_test(test); +} + +for (let testcase of hashTestcases) { + add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path(testcase.name), + check_open_result(testcase.name, testcase.expectedResult) + ); + }); +} + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("empty_signerInfos"), + check_open_result( + "the signerInfos in the PKCS#7 signature is empty", + Cr.NS_ERROR_CMS_VERIFY_NOT_SIGNED + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("unsigned_app"), + check_open_result("unsigned", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("unknown_issuer_app"), + check_open_result( + "unknown_issuer", + getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER) + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_signed_with_pkcs7"), + check_open_result("cose_signed_with_pkcs7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result("no COSE but correct PK#7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-256_p7-256"), + check_open_result( + "no COSE and wrong PK#7 hash", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "COSE signature missing (SHA1 or 256)", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "COSE signature missing (SHA256)", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "COSE signature only (PK#7 allowed, not present)", + Cr.NS_OK + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "COSE signature only (PK#7 allowed, not present)", + Cr.NS_OK + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_multiple_signed_with_pkcs7"), + check_open_result("cose_multiple_signed_with_pkcs7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_int_signed_with_pkcs7"), + check_open_result("COSE signed with an intermediate", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "PK7 signature missing", + Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_multiple_signed_with_pkcs7"), + check_open_result( + "Expected only COSE signature", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_multiple_signed"), + check_open_result("only Multiple COSE signatures", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result("only_cose_signed", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnlyAgain, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result("only_cose_signed (again)", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_signed_with_pkcs7"), + check_open_result( + "COSE only expected but also PK#7 signed", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +// Sanity check to ensure a no-op tampering gives a valid result +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("identity_tampering"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, []); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-1_p7-1"), + check_open_result("identity_tampering", Cr.NS_OK) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_rsa"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.RSA": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_rsa", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_sf"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.SF": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_sf", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_manifest_mf"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/MANIFEST.MF": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "missing_manifest_mf", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_entry"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_entry", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_entry"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("truncated_entry", Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_manifestFile"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/MANIFEST.MF": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "truncated_manifestFile", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_signatureFile"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.SF": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "truncated_signatureFile", + getXPCOMStatusFromNSS(SEC_ERROR_PKCS7_BAD_SIGNATURE) + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_pkcs7File"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.RSA": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("truncated_pkcs7File", Cr.NS_ERROR_CMS_VERIFY_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("unsigned_entry"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("unsigned_entry", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("unsigned_metainf_entry"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, [ + { name: "META-INF/unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "unsigned_metainf_entry", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(PKCS7WithSHA256, function testSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-1_p7-1"), + check_open_result( + "SHA-1 should not be accepted if disabled by policy", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(PKCS7WithSHA256, function testSHA256WorksWithSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "SHA-256 should work if SHA-1 is disabled by policy", + Cr.NS_OK + ) + ); +}); + +add_signature_test( + PKCS7WithSHA256, + function testMultipleSignaturesWorkWithSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1-256_sf-1-256_p7-1-256"), + check_open_result( + "Multiple signatures should work if SHA-1 is " + + "disabled by policy (if SHA-256 signature verifies)", + Cr.NS_OK + ) + ); + } +); + +var cosePolicies = [ + COSEAndPKCS7WithSHA1OrSHA256, + COSERequiredAndPKCS7WithSHA1OrSHA256, +]; + +// PS256 is not yet supported. +var coseTestcasesStage = [ + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, +]; + +var coseTestcasesProd = [ + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, +]; + +for (let policy of cosePolicies) { + for (let testcase of coseTestcasesStage) { + add_signature_test(policy, function() { + certdb.openSignedAppFileAsync( + testcase.root, + original_app_path(testcase.name), + check_open_result(testcase.name, testcase.expectedResult) + ); + }); + } +} + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSESigTampered() { + let tampered = tampered_app_path("cose_sig_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.sig": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_sig_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// PKCS7 is processed before COSE, so if a COSE signature file is removed or +// tampered with, this appears as a PKCS7 signature verification failure. +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSESigRemoved() { + let tampered = tampered_app_path("cose_sig_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.sig": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_sig_removed", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEManifestTampered() { + let tampered = tampered_app_path("cose_manifest_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.manifest": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_manifest_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEManifestRemoved() { + let tampered = tampered_app_path("cose_manifest_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.manifest": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_manifest_removed", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileAdded() { + let tampered = tampered_app_path("cose_file_added"); + tamper(original_app_path("cose_signed_with_pkcs7"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_file_added", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileRemoved() { + let tampered = tampered_app_path("cose_file_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_file_removed", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileTampered() { + let tampered = tampered_app_path("cose_file_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_file_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSESigTampered() { + let tampered = tampered_app_path("only_cose_sig_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.sig": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_sig_tampered", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSESigRemoved() { + let tampered = tampered_app_path("only_cose_sig_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.sig": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_sig_removed", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEManifestTampered() { + let tampered = tampered_app_path("only_cose_manifest_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.manifest": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_manifest_tampered", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEManifestRemoved() { + let tampered = tampered_app_path("only_cose_manifest_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.manifest": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_manifest_removed", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileAdded() { + let tampered = tampered_app_path("only_cose_file_added"); + tamper(original_app_path("only_cose_signed"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_added", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileRemoved() { + let tampered = tampered_app_path("only_cose_file_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_removed", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileTampered() { + let tampered = tampered_app_path("only_cose_file_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// This was signed with only COSE first, and then the contents were tampered +// with (making the signature invalid). Then, the file was signed with +// PKCS7/SHA1. We need to ensure that if we're configured to process COSE, this +// verification fails. +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should fail " + + "when COSE and PKCS7 is processed", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should fail " + + "when only COSE is processed", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// If we're not processing COSE, this should verify successfully. +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should succeed" + + "when COSE is not processed", + Cr.NS_OK + ) + ); +}); + +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("bug_1411458"), + check_open_result("bug 1411458", Cr.NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO) + ); +}); + +// This has a big manifest file (~2MB). It should verify correctly. +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("big_manifest"), + check_open_result("add-on with big manifest file", Cr.NS_OK) + ); +}); + +// This has a huge manifest file (~10MB). Manifest files this large are not +// supported (8MB is the limit). It should not verify correctly. +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("huge_manifest"), + check_open_result( + "add-on with huge manifest file", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_INVALID + ) + ); +}); + +// TODO: tampered MF, tampered SF +// TODO: too-large MF, too-large RSA, too-large SF +// TODO: MF and SF that end immediately after the last main header +// (no CR nor LF) +// TODO: broken headers to exercise the parser diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/README b/security/manager/ssl/tests/unit/test_signed_apps/app/README new file mode 100644 index 0000000000..4f4db4f73e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app/README @@ -0,0 +1 @@ +This is the readme for the test extension. diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png b/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png Binary files differnew file mode 100644 index 0000000000..f4a62faddf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json b/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json new file mode 100644 index 0000000000..eacaedfa7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json @@ -0,0 +1,5 @@ +{ + "manifest_version": 2, + "name": "Test Extension", + "version": "0.0.1" +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest new file mode 100644 index 0000000000..be5069f57b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 + +Name: README +SHA256-Digest: bY0l9xqGJYCpqYeJ0K6q4DWUQqu0mNBFM4H4emhjiJg= + +Name: manifest.json +SHA256-Digest: BTnCpT154N26RZm8bhdD43WXd0tj5bg6ofM19NLI0OE= + +Name: data/image.png +SHA256-Digest: EPjkNZwya9X+pruLlxG+FACLwGC48XU4S9oZOA0lVVQ= diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig Binary files differnew file mode 100644 index 0000000000..ee9f3e2ce9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README new file mode 100644 index 0000000000..46217087d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README @@ -0,0 +1,2 @@ +This is the readme for the test extension. +This app was created by unzipping only_cose_signed.zip and adding this line (thus invalidating the COSE signature). diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png Binary files differnew file mode 100644 index 0000000000..f4a62faddf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json new file mode 100644 index 0000000000..eacaedfa7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json @@ -0,0 +1,5 @@ +{ + "manifest_version": 2, + "name": "Test Extension", + "version": "0.0.1" +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..47c40c6bd5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..1420cd5579 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..669b4d8a8b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..f39b297300 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip Binary files differnew file mode 100644 index 0000000000..710dc42788 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip Binary files differnew file mode 100644 index 0000000000..001b80177f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..b529044fcc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..cdb365ae9c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..0e9eb538ec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..c94f001690 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..30c1a2f4c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..20a6236356 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..6570b1afb2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip Binary files differnew file mode 100644 index 0000000000..413bcba3ef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip Binary files differnew file mode 100644 index 0000000000..31a481c954 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..850917b843 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..9b17b3b736 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..9c2c8a6b8a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..5795fe4f3d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..3436f161ab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..d9f3fa9fca --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..8000501fd6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip Binary files differnew file mode 100644 index 0000000000..7c6f9bcbfa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip Binary files differnew file mode 100644 index 0000000000..8a4509c112 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip Binary files differnew file mode 100644 index 0000000000..adc6ecf26c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip Binary files differnew file mode 100644 index 0000000000..abeaa61a81 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip Binary files differnew file mode 100644 index 0000000000..3b90736b24 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip Binary files differnew file mode 100644 index 0000000000..40b4fc7857 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip Binary files differnew file mode 100644 index 0000000000..d364e590e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip Binary files differnew file mode 100644 index 0000000000..a4353bba19 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip Binary files differnew file mode 100644 index 0000000000..51ae592ee9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip Binary files differnew file mode 100644 index 0000000000..b74e087620 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip Binary files differnew file mode 100644 index 0000000000..772c42e494 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip Binary files differnew file mode 100644 index 0000000000..b1d1999551 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip Binary files differnew file mode 100644 index 0000000000..0ce563680d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip b/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip Binary files differnew file mode 100644 index 0000000000..7a0ec4698c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip b/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip Binary files differnew file mode 100644 index 0000000000..0b296945ab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip Binary files differnew file mode 100644 index 0000000000..d1fa6a7356 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip Binary files differnew file mode 100644 index 0000000000..afd449fcb5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip Binary files differnew file mode 100644 index 0000000000..a1c3175e4f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip Binary files differnew file mode 100644 index 0000000000..bedc6a9c1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip b/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip Binary files differnew file mode 100644 index 0000000000..7a7432596b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip b/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip Binary files differnew file mode 100644 index 0000000000..af2573abf7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/moz.build b/security/manager/ssl/tests/unit/test_signed_apps/moz.build new file mode 100644 index 0000000000..5d50d06e11 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/moz.build @@ -0,0 +1,72 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + + +@template +def SignedAppFile(name, flags, app_directory="app/"): + if not CONFIG["COMPILE_ENVIRONMENT"]: + return + + GENERATED_FILES += [name] + props = GENERATED_FILES[name] + props.script = "/security/manager/ssl/tests/unit/sign_app.py" + props.inputs = [app_directory] + props.flags = flags + # Turn RELATIVEDIR into list entry: like + # 'security/manager/ssl/tests/unit/test_signed_apps' -> + # TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_signed_apps. + files = TEST_HARNESS_FILES.xpcshell + for part in RELATIVEDIR.split("/"): + files = files[part] + files += ["!%s" % name] + + +# Except for unusual testcases (unknown issuer, unsigned app, empty +# signerInfos), the naming scheme is as follows: +# app_mf{-1,-256}_sf{-1,-256}_p7{-1,-256}.zip, where: +# "mf" refers to the manifest file, "sf" refers to the signature file, +# and "p7" refers to the pkcs#7 file. The "{-1,-256}" indicates which +# hash algorithms are present in the corresponding file (both may be +# present). +# For example, "app_mf-1_sf-1-256_p7-256.zip" means that the manifest +# file has sha-1 hashes, the signature file has sha-1 hashes and sha-256 +# hashes, and the pkcs#7 file only has sha-256. +# +# Temporarily disabled. See bug 1256495. +# signed_app_files = ( +# ['unknown_issuer_app.zip', '-i', 'unknown issuer', '-p', 'sha256'], +# ['unsigned_app.zip'], +# ['empty_signerInfos.zip', '-e'], +# ) +# +# for signed_app_file_params in signed_app_files: +# SignedAppFile(signed_app_file_params[0], signed_app_file_params[1:]) +# +# for mf_algs in [['1'], ['256'], ['1', '256']]: +# for sf_algs in [['1'], ['256'], ['1', '256']]: +# for p7_algs in [['1'], ['256'], ['1', '256']]: +# filename = "app_mf-%s_sf-%s_p7-%s.zip" % ('-'.join(mf_algs), '-'.join(sf_algs), '-'.join(p7_algs)) +# args = [] +# for mf_alg in mf_algs: +# args.append('-m') +# args.append('sha%s' % mf_alg) +# for sf_alg in sf_algs: +# args.append('-s') +# args.append('sha%s' % sf_alg) +# for p7_alg in p7_algs: +# args.append('-p') +# args.append('sha%s' % p7_alg) +# SignedAppFile(filename, args) +# +# COSE test-cases +# SignedAppFile('cose_signed_with_pkcs7.zip', ['-c', 'ES256', '-p', 'sha256']) +# SignedAppFile('cose_int_signed_with_pkcs7.zip', ['-c', 'ES256', '-r', 'xpcshell signed apps test root', '-p', 'sha256']) +# SignedAppFile('cose_multiple_signed_with_pkcs7.zip', ['-c', 'ES256', '-c', 'ES384', '-p', 'sha256']) +# SignedAppFile('only_cose_signed.zip', ['-c', 'ES256']) +# SignedAppFile('only_cose_multiple_signed.zip', ['-c', 'ES384', '-c', 'ES256']) +# SignedAppFile('cose_tampered_good_pkcs7.zip', ['-m', 'sha1', '-s', 'sha1', '-p', 'sha1'], 'app_cose_tampered/') +# SignedAppFile('big_manifest.zip', ['-p', 'sha256', '--pad-headers', '2']) +# SignedAppFile('huge_manifest.zip', ['-p', 'sha256', '--pad-headers', '10']) diff --git a/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip Binary files differnew file mode 100644 index 0000000000..3536354f37 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip Binary files differnew file mode 100644 index 0000000000..4ff76efcb8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip b/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip Binary files differnew file mode 100644 index 0000000000..4fa533a77a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip b/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip Binary files differnew file mode 100644 index 0000000000..f28e5df226 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip diff --git a/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der Binary files differnew file mode 100644 index 0000000000..3c1869b13b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der diff --git a/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec new file mode 100644 index 0000000000..500c4185cd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec @@ -0,0 +1,6 @@ +issuer:xpcshell signed apps test root +subject:xpcshell signed apps test root +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyEncipherment,keyCertSign +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_ssl_status.js b/security/manager/ssl/tests/unit/test_ssl_status.js new file mode 100644 index 0000000000..16484ebb59 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ssl_status.js @@ -0,0 +1,76 @@ +// -*- 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"; + +do_get_profile(); + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + // Test successful connection (failedCertChain should be null, + // succeededCertChain should be set as expected) + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess, + null, + function withSecurityInfo(aSecInfo) { + equal( + aSecInfo.failedCertChain.length, + 0, + "failedCertChain for a successful connection should be empty" + ); + ok( + areCertArraysEqual( + aSecInfo.succeededCertChain, + build_cert_chain(["default-ee", "test-ca"]) + ), + "succeededCertChain for a successful connection should be as expected" + ); + } + ); + + // Test failed connection (failedCertChain should be set as expected, + // succeededCertChain should be null) + add_connection_test( + "expired.example.com", + SEC_ERROR_EXPIRED_CERTIFICATE, + null, + function withSecurityInfo(aSecInfo) { + equal( + aSecInfo.succeededCertChain.length, + 0, + "succeededCertChain for a failed connection should be null" + ); + ok( + areCertArraysEqual( + aSecInfo.failedCertChain, + build_cert_chain(["expired-ee", "test-ca"]) + ), + "failedCertChain for a failed connection should be as expected" + ); + } + ); + + // Ensure the correct failed cert chain is set on cert override + let overrideStatus = { + failedCertChain: build_cert_chain(["expired-ee", "test-ca"]), + }; + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE, + undefined, + overrideStatus + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_enumerate.js b/security/manager/ssl/tests/unit/test_sss_enumerate.js new file mode 100644 index 0000000000..e039660f33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_enumerate.js @@ -0,0 +1,101 @@ +/* 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"; + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +const SECS_IN_A_WEEK = 7 * 24 * 60 * 60 * 1000; +const TESTCASES = [ + { + hostname: "a.pinning.example.com", + includeSubdomains: true, + expireTime: Date.now() + 12 * SECS_IN_A_WEEK * 1000, + }, + { + hostname: "b.pinning.example.com", + includeSubdomains: false, + expireTime: Date.now() + 13 * SECS_IN_A_WEEK * 1000, + }, +].sort((a, b) => a.expireTime - b.expireTime); + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); + +function getEntries(type) { + return Array.from(sss.enumerate(type)); +} + +function checkSiteSecurityStateAttrs(entries) { + entries.sort((a, b) => a.expireTime - b.expireTime); + equal( + entries.length, + TESTCASES.length, + "Should get correct number of entries" + ); + for (let i = 0; i < TESTCASES.length; i++) { + equal(entries[i].hostname, TESTCASES[i].hostname, "Hostnames should match"); + equal( + entries[i].securityPropertyState, + Ci.nsISiteSecurityState.SECURITY_PROPERTY_SET, + "Entries should have security property set" + ); + equal( + entries[i].includeSubdomains, + TESTCASES[i].includeSubdomains, + "IncludeSubdomains should match" + ); + // There's a delay from our "now" and the "now" that the implementation uses. + less( + Math.abs(entries[i].expireTime - TESTCASES[i].expireTime), + 60000, + "ExpireTime should be within 60-second error" + ); + } +} + +function add_tests() { + sss.clearAll(); + + for (const testcase of TESTCASES) { + add_connection_test( + testcase.hostname, + PRErrorCodeSuccess, + undefined, + function insertEntry(secInfo) { + const uri = Services.io.newURI(`https://${testcase.hostname}`); + + // MaxAge is in seconds. + let maxAge = Math.round((testcase.expireTime - Date.now()) / 1000); + let header = `max-age=${maxAge}`; + if (testcase.includeSubdomains) { + header += "; includeSubdomains"; + } + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + ); + } + + add_task(() => { + let hstsEntries = getEntries(Ci.nsISiteSecurityService.HEADER_HSTS); + + checkSiteSecurityStateAttrs(hstsEntries); + + sss.clearAll(); + hstsEntries = getEntries(Ci.nsISiteSecurityService.HEADER_HSTS); + + equal(hstsEntries.length, 0, "Should clear all HSTS entries"); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_eviction.js b/security/manager/ssl/tests/unit/test_sss_eviction.js new file mode 100644 index 0000000000..dbb0880064 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_eviction.js @@ -0,0 +1,100 @@ +/* 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"; + +// The purpose of this test is to check that a frequently visited site +// will not be evicted over an infrequently visited site. + +var gSSService = null; +var gProfileDir = null; + +function do_state_written(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + let stateFileContents = readFile(stateFile); + // the last part is removed because it's the empty string after the final \n + let lines = stateFileContents.split("\n").slice(0, -1); + // We can receive multiple data-storage-written events. In particular, we + // may receive one where DataStorage wrote out data before we were done + // processing all of our headers. In this case, the data may not be + // as we expect. We only care about the final one being correct, however, + // so we return and wait for the next event if things aren't as we expect. + // There should be 1024 entries. + if (lines.length != 1024) { + return; + } + + let foundLegitSite = false; + for (let line of lines) { + if (line.startsWith("frequentlyused.example.com:HSTS")) { + foundLegitSite = true; + break; + } + } + + ok(foundLegitSite); + do_test_finished(); +} + +function do_state_read(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://frequentlyused.example.com"), + 0 + ) + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + for (let i = 0; i < 2000; i++) { + let uri = Services.io.newURI("http://bad" + i + ".example.com"); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + do_test_pending(); + Services.obs.addObserver(do_state_written, "data-storage-written"); + do_test_finished(); +} + +function run_test() { + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + gProfileDir = do_get_profile(); + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = new Date().getTime(); + let line = + "frequentlyused.example.com:HSTS\t4\t0\t" + (now + 100000) + ",1,0\n"; + outputStream.write(line, line.length); + outputStream.close(); + Services.obs.addObserver(do_state_read, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_originAttributes.js b/security/manager/ssl/tests/unit/test_sss_originAttributes.js new file mode 100644 index 0000000000..181a57ee28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_originAttributes.js @@ -0,0 +1,179 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=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"; + +// Ensures nsISiteSecurityService APIs respects origin attributes. + +const GOOD_MAX_AGE_SECONDS = 69403; +const GOOD_MAX_AGE = `max-age=${GOOD_MAX_AGE_SECONDS};`; + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); +let host = "a.pinning.example.com"; +let uri = Services.io.newURI("https://" + host); + +// Check if originAttributes1 and originAttributes2 are isolated with respect +// to HSTS storage. +function doTest(secInfo, originAttributes1, originAttributes2, shouldShare) { + sss.clearAll(); + let header = GOOD_MAX_AGE; + // Set HSTS for originAttributes1. + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes1 + ); + ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should be secure given original origin attributes" + ); + equal( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes2 + ), + shouldShare, + "URI should be secure given different origin attributes if and " + + "only if shouldShare is true" + ); + + if (!shouldShare) { + // Remove originAttributes2 from the storage. + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes2 + ); + ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should still be secure given original origin attributes" + ); + } + + // Remove originAttributes1 from the storage. + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ); + ok( + !sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should not be secure after removeState" + ); + + sss.clearAll(); +} + +function testInvalidOriginAttributes(secInfo, originAttributes) { + let header = GOOD_MAX_AGE; + + let callbacks = [ + () => + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ), + () => + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + () => + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + ]; + + for (let callback of callbacks) { + throws( + callback, + /NS_ERROR_ILLEGAL_VALUE/, + "Should get an error with invalid origin attributes" + ); + } +} + +function add_tests() { + sss.clearAll(); + + let secInfo = null; + add_connection_test( + "a.pinning.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + add_task(function() { + let originAttributesList = []; + for (let userContextId of [0, 1, 2]) { + for (let firstPartyDomain of ["", "foo.com", "bar.com"]) { + originAttributesList.push({ userContextId, firstPartyDomain }); + } + } + for (let attrs1 of originAttributesList) { + for (let attrs2 of originAttributesList) { + // SSS storage is not isolated by userContext + doTest( + secInfo, + attrs1, + attrs2, + attrs1.firstPartyDomain == attrs2.firstPartyDomain + ); + } + } + + testInvalidOriginAttributes(secInfo, undefined); + testInvalidOriginAttributes(secInfo, null); + testInvalidOriginAttributes(secInfo, 1); + testInvalidOriginAttributes(secInfo, "foo"); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + add_tests(); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate.js b/security/manager/ssl/tests/unit/test_sss_readstate.js new file mode 100644 index 0000000000..1f3951a3f0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate.js @@ -0,0 +1,161 @@ +/* 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"; + +// The purpose of this test is to create a site security service state file +// and see that the site security service reads it properly. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + + // Clearing the data should make everything go back to default. + gSSService.clearAll(); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = Date.now(); + let lines = [ + `expired.example.com:HSTS\t0\t0\t${now - 100000},1,0`, + `notexpired.example.com:HSTS\t0\t0\t${now + 100000},1,0`, + // This overrides an entry on the preload list. + `includesubdomains.preloaded.test:HSTS\t0\t0\t${now + 100000},1,0`, + `incsubdomain.example.com:HSTS\t0\t0\t${now + 100000},1,1`, + // This overrides an entry on the preload list. + "includesubdomains2.preloaded.test:HSTS\t0\t0\t0,2,0", + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_child.js b/security/manager/ssl/tests/unit/test_sss_readstate_child.js new file mode 100644 index 0000000000..e45fedd18d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_child.js @@ -0,0 +1,40 @@ +/* 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"; + +// The purpose of this test is to create a site security service state file +// and see that the site security service reads it properly. We also verify +// that state changes are reflected in the child process. + +function start_test_in_child() { + run_test_in_child("sss_readstate_child_worker.js"); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = Date.now(); + let lines = [ + `expired.example.com:HSTS\t0\t0\t${now - 100000},1,0`, + `notexpired.example.com:HSTS\t0\t0\t${now + 100000},1,0`, + // This overrides an entry on the preload list. + `includesubdomains.preloaded.test:HSTS\t0\t0\t${now + 100000},1,0`, + `incsubdomain.example.com:HSTS\t0\t0\t${now + 100000},1,1`, + // This overrides an entry on the preload list. + "includesubdomains2.preloaded.test:HSTS\t0\t0\t0,2,0", + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(start_test_in_child, "data-storage-ready"); + do_test_pending(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(SSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_empty.js b/security/manager/ssl/tests/unit/test_sss_readstate_empty.js new file mode 100644 index 0000000000..b1def6bdd8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_empty.js @@ -0,0 +1,56 @@ +/* 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"; + +// The purpose of this test is to create an empty site security service state +// file and see that the site security service doesn't fail when reading it. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + // nonexistent.example.com should never be an HSTS host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://nonexistent.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + // notexpired.example.com is an HSTS host in a different test - we + // want to make sure that test hasn't interfered with this one. + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + stateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0x1a4); // 0x1a4 == 0o644 + ok(stateFile.exists()); + // Initialize nsISiteSecurityService after do_get_profile() so it + // can read the state file. + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js b/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js new file mode 100644 index 0000000000..94f1ca9e6b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js @@ -0,0 +1,110 @@ +/* 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"; + +// The purpose of this test is to create a mostly bogus site security service +// state file and see that the site security service handles it properly. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + const HSTS_HOSTS = [ + "https://example1.example.com", + "https://example2.example.com", + ]; + for (let host of HSTS_HOSTS) { + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI(host), + 0 + ), + `${host} should be HSTS enabled` + ); + } + + const NOT_HSTS_HOSTS = [ + "https://example.com", + "https://example3.example.com", + "https://extra.comma.example.com", + "https://empty.statestring.example.com", + "https://rubbish.statestring.example.com", + "https://spaces.statestring.example.com", + "https://invalid.expirytime.example.com", + "https://text.securitypropertystate.example.com", + "https://invalid.securitypropertystate.example.com", + "https://text.includesubdomains.example.com", + "https://invalid.includesubdomains.example.com", + ]; + for (let host of NOT_HSTS_HOSTS) { + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI(host), + 0 + ), + `${host} should not be HSTS enabled` + ); + } + + do_test_finished(); +} + +const PINNING_ROOT_KEY_HASH = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="; +const BASE64_BUT_NOT_SHA256 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; +const STARTS_WITH_NUMBER = "1ABC23defG/hiJKlmNoP+QRStuVwxYZ9a+bcD/+/EFg="; +const STARTS_WITH_SYMBOL = "+ABC23defG/hiJKlmNoP+QRStuVwxYZ9a+bcD/+/EFg="; +const MULTIPLE_KEYS = + PINNING_ROOT_KEY_HASH + STARTS_WITH_NUMBER + STARTS_WITH_SYMBOL; + +function run_test() { + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", true); + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let expiryTime = Date.now() + 100000; + let lines = [ + // General state file entry tests. + `example1.example.com:HSTS\t0\t0\t${expiryTime},1,0`, + "I'm a lumberjack and I'm okay; I work all night and I sleep all day!", + "This is a totally bogus entry\t", + "0\t0\t0\t0\t", + "\t\t\t\t\t\t\t", + "example.com:HSTS\t\t\t\t\t\t\t", + "example3.example.com:HSTS\t0\t\t\t\t\t\t", + `example2.example.com:HSTS\t0\t0\t${expiryTime},1,0`, + // HSTS state string parsing tests + `extra.comma.example.com:HSTS\t0\t0\t${expiryTime},,1,0`, + "empty.statestring.example.com:HSTS\t0\t0\t", + "rubbish.statestring.example.com:HSTS\t0\t0\tfoobar", + `spaces.statestring.example.com:HSTS\t0\t0\t${expiryTime}, 1,0 `, + `invalid.expirytime.example.com:HSTS\t0\t0\t${expiryTime}foo123,1,0`, + `text.securitypropertystate.example.com:HSTS\t0\t0\t${expiryTime},1foo,0`, + `invalid.securitypropertystate.example.com:HSTS\t0\t0\t${expiryTime},999,0`, + `text.includesubdomains.example.com:HSTS\t0\t0\t${expiryTime},1,1foo`, + `invalid.includesubdomains.example.com:HSTS\t0\t0\t${expiryTime},1,0foo`, + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); + + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.cert_pinning.enforcement_level"); + }); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_huge.js b/security/manager/ssl/tests/unit/test_sss_readstate_huge.js new file mode 100644 index 0000000000..d0c7a7541d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_huge.js @@ -0,0 +1,98 @@ +/* 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"; + +// The purpose of this test is to create a site security service state file +// that is too large and see that the site security service reads it properly +// (this means discarding all entries after the 1024th). + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example0.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example423.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1023.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1024.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1025.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example9000.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example99999.example.com"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let expiryTime = Date.now() + 100000; + let lines = []; + for (let i = 0; i < 10000; i++) { + // The 0s will all get squashed down into one 0 when they are read. + // This is just to make the file size large (>2MB). + lines.push( + `example${i}.example.com:HSTS\t` + + "0000000000000000000000000000000000000000000000000\t" + + "00000000000000000000000000000000000000\t" + + `${expiryTime},1,0000000000000000000000000000000000000000000000000000000000000000000000000` + ); + } + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_resetState.js b/security/manager/ssl/tests/unit/test_sss_resetState.js new file mode 100644 index 0000000000..1850442b64 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_resetState.js @@ -0,0 +1,113 @@ +// -*- 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 resetting HSTS state in the way the "forget about this site" +// functionality does works as expected for preloaded and non-preloaded sites. + +do_get_profile(); + +var gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +function test_removeState(secInfo, type, flags) { + info(`running test_removeState(type=${type}, flags=${flags})`); + // Simulate visiting a non-preloaded site by processing an HSTS header check + // that the HSTS bit gets set, simulate "forget about this site" (call + // removeState), and then check that the HSTS bit isn't set. + let notPreloadedURI = Services.io.newURI("https://not-preloaded.example.com"); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.processHeader( + type, + notPreloadedURI, + "max-age=1000;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.resetState(type, notPreloadedURI, flags); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + + // Simulate visiting a non-preloaded site that unsets HSTS by processing + // an HSTS header with "max-age=0", check that the HSTS bit isn't + // set, simulate "forget about this site" (call removeState), and then check + // that the HSTS bit isn't set. + gSSService.processHeader( + type, + notPreloadedURI, + "max-age=0;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.resetState(type, notPreloadedURI, flags); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + + // Simulate visiting a preloaded site by processing an HSTS header, check + // that the HSTS bit is still set, simulate "forget about this site" + // (call removeState), and then check that the HSTS bit is still set. + let preloadedHost = "includesubdomains.preloaded.test"; + let preloadedURI = Services.io.newURI(`https://${preloadedHost}`); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.processHeader( + type, + preloadedURI, + "max-age=1000;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.resetState(type, preloadedURI, flags); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + + // Simulate visiting a preloaded site that unsets HSTS by processing an + // HSTS header with "max-age=0", check that the HSTS bit is what we + // expect (see below), simulate "forget about this site" (call removeState), + // and then check that the HSTS bit is set. + gSSService.processHeader( + type, + preloadedURI, + "max-age=0;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.resetState(type, preloadedURI, flags); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); +} + +function add_tests() { + let secInfo = null; + add_connection_test( + "not-preloaded.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + add_task(() => { + test_removeState(secInfo, Ci.nsISiteSecurityService.HEADER_HSTS, 0); + test_removeState( + secInfo, + Ci.nsISiteSecurityService.HEADER_HSTS, + Ci.nsISocketProvider.NO_PERMANENT_STORAGE + ); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js b/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js new file mode 100644 index 0000000000..6e1142b4b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js @@ -0,0 +1,72 @@ +/* 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"; + +// The purpose of this test is to ensure that Firefox sanitizes site security +// service data on shutdown if configured to do so. + +XPCOMUtils.defineLazyModuleGetters(this, { + TestUtils: "resource://testing-common/TestUtils.jsm", + Sanitizer: "resource:///modules/Sanitizer.jsm", +}); + +Sanitizer.onStartup(); + +// This helps us away from test timed out. If service worker manager(swm) hasn't +// been initilaized before profile-change-teardown, this test would fail due to +// the shutdown blocker added by swm. Normally, swm should be initialized before +// that and the similar crash signatures are fixed. So, assume this cannot +// happen in the real world and initilaize swm here as a workaround. +const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService( + Ci.nsIServiceWorkerManager +); + +function getStateFileContents() { + let stateFile = do_get_profile(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + return readFile(stateFile); +} + +add_task(async function run_test() { + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + do_get_profile(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + let header = "max-age=50000"; + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("http://example.com"), + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + await TestUtils.topicObserved( + "data-storage-written", + (_, data) => data == SSS_STATE_FILE_NAME + ); + let stateFileContents = getStateFileContents(); + ok( + stateFileContents.includes("example.com"), + "should have written out state file" + ); + + // Configure Firefox to clear this data on shutdown. + Services.prefs.setBoolPref( + Sanitizer.PREF_SHUTDOWN_BRANCH + "siteSettings", + true + ); + Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, true); + + // Simulate shutdown. + Services.obs.notifyObservers(null, "profile-change-teardown"); + Services.obs.notifyObservers(null, "profile-before-change"); + + equal(getStateFileContents(), "", "state file should be empty"); +}); diff --git a/security/manager/ssl/tests/unit/test_sss_savestate.js b/security/manager/ssl/tests/unit/test_sss_savestate.js new file mode 100644 index 0000000000..300afe4983 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_savestate.js @@ -0,0 +1,122 @@ +/* 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"; + +// The purpose of this test is to see that the site security service properly +// writes its state file. + +const EXPECTED_ENTRIES = 5; +const EXPECTED_HSTS_COLUMNS = 4; +var gProfileDir = null; + +const NON_ISSUED_KEY_HASH = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + +// For reference, the format of the state file is a list of: +// <domain name> <expiration time in milliseconds>,<sts status>,<includeSubdomains> +// separated by newlines ('\n') + +function checkStateWritten(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + let stateFileContents = readFile(stateFile); + // the last line is removed because it's just a trailing newline + let lines = stateFileContents.split("\n").slice(0, -1); + equal(lines.length, EXPECTED_ENTRIES); + let sites = {}; // a map of domain name -> [the entry in the state file] + for (let line of lines) { + let parts = line.split("\t"); + let host = parts[0]; + let entry = parts[3].split(","); + let expectedColumns = EXPECTED_HSTS_COLUMNS; + equal(entry.length, expectedColumns); + sites[host] = entry; + } + + // We can receive multiple data-storage-written events. In particular, we + // may receive one where DataStorage wrote out data before we were done + // processing all of our headers. In this case, the data may not be + // as we expect. We only care about the final one being correct, however, + // so we return and wait for the next event if things aren't as we expect. + // sites[url][1] corresponds to SecurityPropertySet (if 1) and + // SecurityPropertyUnset (if 0) + // sites[url][2] corresponds to includeSubdomains + if (sites["includesubdomains.preloaded.test:HSTS"][1] != 1) { + return; + } + if (sites["includesubdomains.preloaded.test:HSTS"][2] != 0) { + return; + } + if (sites["a.example.com:HSTS"][1] != 1) { + return; + } + if (sites["a.example.com:HSTS"][2] != 1) { + return; + } + if (sites["b.example.com:HSTS"][1] != 1) { + return; + } + if (sites["b.example.com:HSTS"][2] != 0) { + return; + } + if (sites["c.c.example.com:HSTS"][1] != 1) { + return; + } + if (sites["c.c.example.com:HSTS"][2] != 1) { + return; + } + if (sites["d.example.com:HSTS"][1] != 1) { + return; + } + if (sites["d.example.com:HSTS"][2] != 0) { + return; + } + + do_test_finished(); +} + +function run_test() { + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", true); + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + gProfileDir = do_get_profile(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + let uris = [ + Services.io.newURI("http://includesubdomains.preloaded.test"), + Services.io.newURI("http://a.example.com"), + Services.io.newURI("http://b.example.com"), + Services.io.newURI("http://c.c.example.com"), + Services.io.newURI("http://d.example.com"), + ]; + + for (let i = 0; i < 1000; i++) { + let uriIndex = i % uris.length; + // vary max-age + let maxAge = "max-age=" + i * 1000; + // alternate setting includeSubdomains + let includeSubdomains = i % 2 == 0 ? "; includeSubdomains" : ""; + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uris[uriIndex], + maxAge + includeSubdomains, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + + do_test_pending(); + Services.obs.addObserver(checkStateWritten, "data-storage-written"); +} diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign.js b/security/manager/ssl/tests/unit/test_startcom_wosign.js new file mode 100644 index 0000000000..1fda3a9a96 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign.js @@ -0,0 +1,67 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests handling of certificates issued by StartCom and WoSign. If such +// certificates have a notBefore before 21 October 2016, they are handled +// normally. Otherwise, they are treated as revoked. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + certdb, + "test_startcom_wosign/" + certName + ".pem", + trustString + ); +} + +function certFromFile(certName) { + return constructCertFromFile("test_startcom_wosign/" + certName + ".pem"); +} + +function checkEndEntity(cert, expectedResult) { + // (new Date("2016-11-01")).getTime() / 1000 + const VALIDATION_TIME = 1477958400; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + // This is not a real StartCom CA - it merely has the same distinguished name + // as one (namely "/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority + // G2", encoded with PrintableStrings). By checking for specific DNs, we can + // enforce the date-based policy in a way that is testable. + loadCertWithTrust("StartComCA", ",,"); + await checkEndEntity( + certFromFile("StartCom-before-cutoff"), + PRErrorCodeSuccess + ); + await checkEndEntity( + certFromFile("StartCom-after-cutoff"), + SEC_ERROR_REVOKED_CERTIFICATE + ); + + // Similarly, this is not a real WoSign CA. It has the same distinguished name + // as "/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign", + // encoded with PrintableStrings). + loadCertWithTrust("WoSignCA", ",,"); + await checkEndEntity( + certFromFile("WoSign-before-cutoff"), + PRErrorCodeSuccess + ); + await checkEndEntity( + certFromFile("WoSign-after-cutoff"), + SEC_ERROR_REVOKED_CERTIFICATE + ); +}); diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem new file mode 100644 index 0000000000..031b2e8674 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHzCCAgegAwIBAgIUMzsA8O2TjNkD5ARjfvom8NIOGV0wDQYJKoZIhvcNAQEL +BQAwUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAqBgNV +BAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMCIYDzIwMTYx +MDIyMDAwMDAwWhgPMjAxNzEwMjIwMDAwMDBaMCAxHjAcBgNVBAMMFVN0YXJ0Q29t +LWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w +DQYJKoZIhvcNAQELBQADggEBAF45Nn67efx82OhjZ865DeQdHjTL4IhIo3dcZwf2 +1fLgV1+ZXDFUewnE0Sw7pR57uUKGmaISjoF2lXvNm0U/5Nq6dUbhN9KtnRifaM3x +NavEvpTZAwERnnphDJFlgSJAFSPWLGZDULl7JaZyLyQe0AoQXAFTyghkXrk/QA5m +1LfDYqLiwL1G4NHLGu7QRvLUZ/pxkLS3PaKfZVILCnKiOvI7bmPq+2U7H6ZgTPPP +24Sy/E9AKV5I6IEojGuM6qP+QYgLANOaGygWrIVJ+QpS36V8uRRbetzTcJUHDesw +iMJaepPkWnFNhz2CSS3HyoG9wu/RqfRwiLWqjsOs0dEZTRw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec new file mode 100644 index 0000000000..9f0fe22fcd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +subject:StartCom-after-cutoff +validity:20161022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem new file mode 100644 index 0000000000..61ef3cbf72 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIUF7D74A6qEV/s6DRPxUqAk7N+bX8wDQYJKoZIhvcNAQEL +BQAwUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAqBgNV +BAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMCIYDzIwMTUx +MDIyMDAwMDAwWhgPMjAxNzEwMjIwMDAwMDBaMCExHzAdBgNVBAMMFlN0YXJ0Q29t +LWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQB2r07MUxWXUj7gAlQJUKNhNJ9Fqlt13751C4Lo +KL9TeUeROqDviPtpwoigG0NV+IMWdXJorRmbkcFmgBOFOZmhyspi2BJ4rCCWC1FI +WFe9SlFsuka7a7sAov9B3ClLJE+JX48H84kZ1yMq1jQmv0tAko9di3d7oMhHpLMp +tBzOQUnuq/kBeS5VlHxyZoRxj7U0MSIORhIOkih/pRzmeLDnn7xBj9FZ6ipoukRL +n3l3wTmj9/aar7DhhgA8QvD6ZtNHXP8ZnheVqW07OZVjWcrzg7nID3+j4LWOZNq/ +hdm1nZG5DltMk7JqIGuA4PmdStXQNftEVbeWMzdQ+8cb/wmC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec new file mode 100644 index 0000000000..b7fbd4954e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +subject:StartCom-before-cutoff +validity:20151022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem new file mode 100644 index 0000000000..98ce37dabe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAfegAwIBAgIUY5ffXJsiXdmKh2ybX2nxSg57mRwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAq +BgNVBAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAe6mpnTBxkfYlTrzuvtKQ73A5KCEBfmtRGZaMRPh8rSxdnd8Zf2zTl3eUHYX1 +y+pqY1U9YJOkR1TKfbtvQll7bnD5RJ+FJD6eA9QEwSpII7v66teRS7wBPxQrvsrq +SWVZuHyKMpBG3148/nmrPvaIB5kAO5fdedIET88PL3K8LM1XzoVZc272V577pmeD +4N116ghEIz7rhrR6yoGVN0s2TXT7H5AlOscZuVRkirickVUbjSWZma+mYJWdd8hi +Cjufl43OY4EY31w9qO8BKxx8ZugmoSmp93VyMvqWZAV1AoxgxMpOsC9e7ZB83yrU +luXN7wik7bf+xNz78Be6XhBOBA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec new file mode 100644 index 0000000000..d1e3c4c4f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem new file mode 100644 index 0000000000..dc976c7c61 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHzCCAgegAwIBAgIUC57N1fgWjCRoz95Wt5tIBI4U+AMwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVkMSow +KAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wIhgPMjAx +NjEwMjIwMDAwMDBaGA8yMDE3MTAyMjAwMDAwMFowHjEcMBoGA1UEAwwTV29TaWdu +LWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w +DQYJKoZIhvcNAQELBQADggEBAK+d8oCtnO+HwtV1nEqKAd1/3ATIGmbDJn5kQWKY +m5cVi4NO6UivqhQO7Z8if+sO5DuX/VoodC+LESuv8NQdn8pDH1Ou7WUtm9xyG5Ly +j+D+WgpjmxKfBfD2L0Pd4b8ZrCg8Az3wmz6Jz7MwEU8FqmScQkxJN4JH7S2QlmLa +asrPwrFKy9uOD3jSW6d5H3gv+nV7thIiMASor3up5KV//UdVqWTISOpBZdJKE8wp +QtlPfvIgP5DbrfhtOzDYLuPnO3WzT7oC4Pau0eMXlT5EKC41p+fXGqtU402H0xMB +5ftgAboQ42FDDkp+y13a7wfm1KqcaahWR9CQKrO1ag7Mspk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec new file mode 100644 index 0000000000..2afb5d6ea6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +subject:WoSign-after-cutoff +validity:20161022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem new file mode 100644 index 0000000000..8dc84c549c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIUI4ScwRAmd+wFemr14yqwfKljyEswDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVkMSow +KAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wIhgPMjAx +NTEwMjIwMDAwMDBaGA8yMDE3MTAyMjAwMDAwMFowHzEdMBsGA1UEAwwUV29TaWdu +LWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQAtq4bkF5Dh+Gouc8D+v4c5Siol9ucFZziegFTe +CwCel//tShZwFSObespSLFVjrPPrEhdv+9Wl7/faHaFEIYjX/xBJ+ZsdKal56E/+ +hnuXzCWhojpnMcMzWRVPBzKo0KD3g673pdC6m86r78eXDwG+8zYak+IQ4CJAaUOd +hT23GDajLjBbUNdT1pBjIKxYa2iNJOyQ8SVil18r2c1/AtoejS0xZda2MO+FDnf5 +01413PgAU1Lf1C6tEQNnncLtMQhT+LKlDIMo9PolJcvMto57f/awQhyiYMLvIAE+ +O8NIYXn0cyn+dbpaL59hmx1AJJwtyn3RsskVKQjle7ky3gt7 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec new file mode 100644 index 0000000000..224522bf01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +subject:WoSign-before-cutoff +validity:20151022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem new file mode 100644 index 0000000000..490e22cfdd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUYx3n8sfSMjvHAMPX4R896bPDFB4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVk +MSowKAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQABpMKSJzIqD+0DHDAzcBl99nTDTYalGAbYvKvnxKOiD0WVw8K/Lp+Ofoh2 +ZicDP35liyEPiyZMfR5IIyfPwPkgvRTIrZtX87SFxHcrsvZHVj+ilijOSWBx9Tgy +z1PhkAdTg49ljzsKa77+nEKDkRXSWIbmt3MUymvCSMq1HXUFOwpPSqB98ssvjMhs +acKcMnpSe5m39Z9OIAczhsR64otg+flV4XH2ocdE0ywBzMnw4HVY49TXEkojs1bY +aXgkTEaFrFKj45UeGw2yBbftZB18bhPemOtkxiMR7ChOtilMKHGI/qH5rvQJXuwV +HkC3s3YcMbHtx0w3aYSC8caspSxt +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec new file mode 100644 index 0000000000..8c293bf9b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem new file mode 100644 index 0000000000..560684144f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUGUKJPXqFyHlaMLy7vfWOkCn+6RswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCV2ftsqVDw6pxfW7ToIowvicAL +H1Gwj5AL1aVpPOBFHXJGkKbYkAVl62t2R8OTJzrqjNo9D4sgRKKtqJXwmqlAEyuk +dsA18pA/0/jIEU12/Oq68ra6HB+efTfxQrm4/uU2Yr2UNcCcAo8nKtzxsPsPAiMm +hqKCRkCtYZjGRk18S2y85XihanfTkAqBGlI4GC7q4Otnq7j7y9FwtiQ7iWP+IYQv +OlS+FwCoctrNLGOQE9Jzc4GRD2zlwsbWfHDQUvB1p3tjKwtT35EtWf6F5NpKLWTm +m3SmHIG6pvIePX0zhlac1tR/uvCSpyFAiQ7nG4XDpNyPle1WEFreiS8+ITeM +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec new file mode 100644 index 0000000000..efd24b1532 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build b/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build new file mode 100644 index 0000000000..657bcf6bed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'StartCom-after-cutoff.pem', +# 'StartCom-before-cutoff.pem', +# 'StartComCA.pem', +# 'WoSign-after-cutoff.pem', +# 'WoSign-before-cutoff.pem', +# 'WoSignCA.pem', +# 'ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_sts_fqdn.js b/security/manager/ssl/tests/unit/test_sts_fqdn.js new file mode 100644 index 0000000000..d8ecbf1530 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_fqdn.js @@ -0,0 +1,50 @@ +/* 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 run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("https://example.com"); + let uri1 = Services.io.newURI("https://example.com."); + let uri2 = Services.io.newURI("https://example.com.."); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + // These cases are only relevant as long as bug 1118522 hasn't been fixed. + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000;includeSubdomains", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + SSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + // Somehow creating this malformed URI succeeds - we need to handle it + // gracefully. + uri = Services.io.newURI("https://../foo"); + equal(uri.host, ".."); + throws( + () => { + SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + }, + /NS_ERROR_UNEXPECTED/, + "Malformed URI should be rejected" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js b/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js new file mode 100644 index 0000000000..1950d7b1bd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js @@ -0,0 +1,59 @@ +"use strict"; + +function check_ip(s, v, ip) { + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + + let str = "https://"; + if (v == 6) { + str += "["; + } + str += ip; + if (v == 6) { + str += "]"; + } + str += "/"; + + let uri = Services.io.newURI(str); + ok(!s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + let parsedMaxAge = {}; + let parsedIncludeSubdomains = {}; + s.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000;includeSubdomains", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + {}, + parsedMaxAge, + parsedIncludeSubdomains + ); + ok( + !s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "URI should not be secure if it contains an IP address" + ); + + /* Test that processHeader will ignore headers for an uri, if the uri + * contains an IP address not a hostname. + * If processHeader indeed ignore the header, then the output parameters will + * remain empty, and we shouldn't see the values passed as the header. + */ + notEqual(parsedMaxAge.value, 1000); + notEqual(parsedIncludeSubdomains.value, true); + notEqual(parsedMaxAge.value, undefined); + notEqual(parsedIncludeSubdomains.value, undefined); +} + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + check_ip(SSService, 4, "127.0.0.1"); + check_ip(SSService, 4, "10.0.0.1"); + check_ip(SSService, 6, "2001:db8::1"); + check_ip(SSService, 6, "1080::8:800:200C:417A"); +} diff --git a/security/manager/ssl/tests/unit/test_sts_parser.js b/security/manager/ssl/tests/unit/test_sts_parser.js new file mode 100644 index 0000000000..8475d2e558 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_parser.js @@ -0,0 +1,146 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=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"; + +// STS parser tests + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); +let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" +].createInstance(Ci.nsITransportSecurityInfo); + +function testSuccess(header, expectedMaxAge, expectedIncludeSubdomains) { + let dummyUri = Services.io.newURI("https://foo.com/bar.html"); + let maxAge = {}; + let includeSubdomains = {}; + + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + dummyUri, + header, + secInfo, + 0, + sss.SOURCE_ORGANIC_REQUEST, + {}, + maxAge, + includeSubdomains + ); + + equal(maxAge.value, expectedMaxAge, "Did not correctly parse maxAge"); + equal( + includeSubdomains.value, + expectedIncludeSubdomains, + "Did not correctly parse presence/absence of includeSubdomains" + ); +} + +function testFailure(header) { + let dummyUri = Services.io.newURI("https://foo.com/bar.html"); + let maxAge = {}; + let includeSubdomains = {}; + + throws( + () => { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + dummyUri, + header, + secInfo, + 0, + sss.SOURCE_ORGANIC_REQUEST, + {}, + maxAge, + includeSubdomains + ); + }, + /NS_ERROR_FAILURE/, + "Parsed invalid header: " + header + ); +} + +function run_test() { + // SHOULD SUCCEED: + testSuccess("max-age=100", 100, false); + testSuccess("max-age =100", 100, false); + testSuccess(" max-age=100", 100, false); + testSuccess("max-age = 100 ", 100, false); + testSuccess('max-age = "100" ', 100, false); + testSuccess('max-age="100"', 100, false); + testSuccess(' max-age ="100" ', 100, false); + testSuccess('\tmax-age\t=\t"100"\t', 100, false); + testSuccess("max-age = 100 ", 100, false); + + testSuccess("maX-aGe=100", 100, false); + testSuccess("MAX-age =100", 100, false); + testSuccess("max-AGE=100", 100, false); + testSuccess("Max-Age = 100 ", 100, false); + testSuccess("MAX-AGE = 100 ", 100, false); + + testSuccess("max-age=100;includeSubdomains", 100, true); + testSuccess("max-age=100\t; includeSubdomains", 100, true); + testSuccess(" max-age=100; includeSubdomains", 100, true); + testSuccess("max-age = 100 ; includeSubdomains", 100, true); + testSuccess( + "max-age = 100 ; includeSubdomains", + 100, + true + ); + + testSuccess("maX-aGe=100; includeSUBDOMAINS", 100, true); + testSuccess("MAX-age =100; includeSubDomains", 100, true); + testSuccess("max-AGE=100; iNcLuDeSuBdoMaInS", 100, true); + testSuccess("Max-Age = 100; includesubdomains ", 100, true); + testSuccess("INCLUDESUBDOMAINS;MaX-AgE = 100 ", 100, true); + // Turns out, the actual directive is entirely optional (hence the + // trailing semicolon) + testSuccess("max-age=100;includeSubdomains;", 100, true); + + // these are weird tests, but are testing that some extended syntax is + // still allowed (but it is ignored) + testSuccess("max-age=100 ; includesubdomainsSomeStuff", 100, false); + testSuccess( + "\r\n\t\t \tcompletelyUnrelated = foobar; max-age= 34520103" + + "\t \t; alsoUnrelated;asIsThis;\tincludeSubdomains\t\t \t", + 34520103, + true + ); + testSuccess('max-age=100; unrelated="quoted \\"thingy\\""', 100, false); + + // SHOULD FAIL: + // invalid max-ages + testFailure("max-age"); + testFailure("max-age "); + testFailure("max-age=p"); + testFailure("max-age=*1p2"); + testFailure("max-age=.20032"); + testFailure("max-age=!20032"); + testFailure("max-age==20032"); + + // invalid headers + testFailure("foobar"); + testFailure("maxage=100"); + testFailure("maxa-ge=100"); + testFailure("max-ag=100"); + testFailure("includesubdomains"); + testFailure(";"); + testFailure('max-age="100'); + // The max-age directive here doesn't conform to the spec, so it MUST + // be ignored. Consequently, the REQUIRED max-age directive is not + // present in this header, and so it is invalid. + testFailure("max-age=100, max-age=200; includeSubdomains"); + testFailure("max-age=100 includesubdomains"); + testFailure("max-age=100 bar foo"); + testFailure("max-age=100randomstuffhere"); + // All directives MUST appear only once in an STS header field. + testFailure("max-age=100; max-age=200"); + testFailure("includeSubdomains; max-age=200; includeSubdomains"); + testFailure("max-age=200; includeSubdomains; includeSubdomains"); + // The includeSubdomains directive is valueless. + testFailure("max-age=100; includeSubdomains=unexpected"); + // LWS must have at least one space or horizontal tab + testFailure("\r\nmax-age=200"); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js b/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js new file mode 100644 index 0000000000..f66f13ddd9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js @@ -0,0 +1,86 @@ +// -*- 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 the dynamic preloading of HPKP hosts: +// * checks that preloads can be set +// * checks that includeSubdomains is honored +// * checks that clearing preloads works correctly +// * checks that clearing a host's HSTS state via a header correctly +// overrides dynamic preload entries + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + let unlikelyHost = "highlyunlikely.example.com"; + let uri = Services.io.newURI("https://" + unlikelyHost); + let subDomainUri = Services.io.newURI("https://subdomain." + unlikelyHost); + + // first check that a host probably not on the preload list is not identified + // as an sts host + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // now add a preload entry for this host + SSService.setHSTSPreload(unlikelyHost, false, Date.now() + 60000); + + // check that it's now an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // check that it's honoring the fact we set includeSubdomains to false + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + + // clear the non-preloaded entries + SSService.clearAll(); + + // check that it's still an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // clear the preloads + SSService.clearPreloads(); + + // Check that it's no longer an STS host now that the preloads have been + // cleared + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // Now let's do the same, this time with includeSubdomains on + SSService.setHSTSPreload(unlikelyHost, true, Date.now() + 60000); + + // check that it's now an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // check that it's now including subdomains + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + + // Now let's simulate overriding the entry by setting an entry from a header + // with max-age set to 0 + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + // this should no longer be an HSTS host + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js new file mode 100644 index 0000000000..142825829e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js @@ -0,0 +1,455 @@ +"use strict"; + +var gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +function Observer() {} +Observer.prototype = { + observe(subject, topic, data) { + if (topic == "last-pb-context-exited") { + run_next_test(); + } + }, +}; + +var gObserver = new Observer(); +var secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" +].createInstance(Ci.nsITransportSecurityInfo); + +function cleanup() { + Services.obs.removeObserver(gObserver, "last-pb-context-exited"); + gSSService.clearAll(); +} + +function run_test() { + do_get_profile(); + + registerCleanupFunction(cleanup); + Services.obs.addObserver(gObserver, "last-pb-context-exited"); + + add_test(test_part1); + add_test(test_private_browsing1); + add_test(test_private_browsing2); + + run_next_test(); +} + +function test_part1() { + // check that a host not in the list is not identified as an sts host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://nonexistent.example.com"), + 0 + ) + ); + + // check that an ancestor domain is not identified as an sts host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://com"), + 0 + ) + ); + + // check that the pref to toggle using the preload list works + Services.prefs.setBoolPref( + "network.stricttransportsecurity.preloadlist", + false + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + Services.prefs.setBoolPref( + "network.stricttransportsecurity.preloadlist", + true + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that a subdomain is an sts host (includeSubdomains is set) + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that another subdomain is an sts host (includeSubdomains is set) + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://a.b.c.def.includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that a subdomain is not an sts host (includeSubdomains is not set) + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://subdomain.noincludesubdomains.preloaded.test" + ), + 0 + ) + ); + + // check that a host with a dot on the end won't break anything + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notsts.nonexistent.example.com."), + 0 + ) + ); + + // check that processing a header with max-age: 0 will remove a preloaded + // site from the list + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + let subDomainUri = Services.io.newURI( + "https://subdomain.includesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + // check that processing another header (with max-age non-zero) will + // re-enable a site's sts status + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + // but this time include subdomains was not set, so test for that + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + gSSService.clearAll(); + + // check that processing a header with max-age: 0 from a subdomain of a site + // will not remove that (ancestor) site from the list + uri = Services.io.newURI( + "https://subdomain.noincludesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://noincludesubdomains.preloaded.test"), + 0 + ) + ); + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + uri = Services.io.newURI( + "https://subdomain.includesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + // we received a header with "max-age=0", so we have "no information" + // regarding the sts state of subdomain.includesubdomains.preloaded.test specifically, + // but it is actually still an STS host, because of the preloaded + // includesubdomains.preloaded.test including subdomains. + // Here's a drawing: + // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host + // |-- subdomain.includesubdomains.preloaded.test IS sts host + // | `-- another.subdomain.includesubdomains.preloaded.test IS sts host + // `-- sibling.includesubdomains.preloaded.test IS sts host + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sibling.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://another.subdomain.includesubdomains.preloaded.test" + ), + 0 + ) + ); + + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + // Here's what we have now: + // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host + // |-- subdomain.includesubdomains.preloaded.test (include subdomains is false) IS sts host + // | `-- another.subdomain.includesubdomains.preloaded.test IS NOT sts host + // `-- sibling.includesubdomains.preloaded.test IS sts host + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sibling.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://another.subdomain.includesubdomains.preloaded.test" + ), + 0 + ) + ); + + // Test that an expired non-private browsing entry results in correctly + // identifying a host that is on the preload list as no longer sts. + // (This happens when we're in regular browsing mode, we get a header from + // a site on the preload list, and that header later expires. We need to + // then treat that host as no longer an sts host.) + // (sanity check first - this should be in the preload list) + uri = Services.io.newURI("https://includesubdomains2.preloaded.test"); + ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + do_timeout(1250, function() { + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + run_next_test(); + }); +} + +const IS_PRIVATE = Ci.nsISocketProvider.NO_PERMANENT_STORAGE; + +function test_private_browsing1() { + gSSService.clearAll(); + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + let subDomainUri = Services.io.newURI( + "https://a.b.c.subdomain.includesubdomains.preloaded.test" + ); + // sanity - includesubdomains.preloaded.test is preloaded, includeSubdomains set + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // check adding it back in + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + // but no includeSubdomains this time + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // do the hokey-pokey... + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // Test that an expired private browsing entry results in correctly + // identifying a host that is on the preload list as no longer sts. + // (This happens when we're in private browsing mode, we get a header from + // a site on the preload list, and that header later expires. We need to + // then treat that host as no longer an sts host.) + // (sanity check first - this should be in the preload list) + uri = Services.io.newURI("https://includesubdomains2.preloaded.test"); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + do_timeout(1250, function() { + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + // Simulate leaving private browsing mode + Services.obs.notifyObservers(null, "last-pb-context-exited"); + }); +} + +function test_private_browsing2() { + // if this test gets this far, it means there's a private browsing service + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + // the includesubdomains.preloaded.test entry has includeSubdomains set + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + + // Now that we're out of private browsing mode, we need to make sure + // we've "forgotten" that we "forgot" this site's sts status. + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js b/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js new file mode 100644 index 0000000000..897fcbd3be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js @@ -0,0 +1,22 @@ +"use strict"; + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + + // check that a host on the preload list is identified as an sts host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // now simulate that it's 19 weeks later than it actually is + let offsetSeconds = 19 * 7 * 24 * 60 * 60; + Services.prefs.setIntPref("test.currentTimeOffsetSeconds", offsetSeconds); + + // check that the preloaded host is no longer considered sts + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // just make sure we can get everything back to normal + Services.prefs.clearUserPref("test.currentTimeOffsetSeconds"); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); +} diff --git a/security/manager/ssl/tests/unit/test_validity.js b/security/manager/ssl/tests/unit/test_validity.js new file mode 100644 index 0000000000..1809faf24c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity.js @@ -0,0 +1,108 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that chains containing an end-entity cert with an overly long validity +// period are rejected. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function getOCSPResponder(expectedCertNames) { + let expectedPaths = expectedCertNames.slice(); + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_validity", + expectedCertNames, + expectedPaths + ); +} + +function certFromFile(filename) { + return constructCertFromFile(`test_validity/${filename}`); +} + +function loadCert(certFilename, trustString) { + addCertFromFile(certDB, `test_validity/${certFilename}`, trustString); +} + +/** + * Asynchronously runs a single EV test. + * + * @param {Array} expectedNamesForOCSP + * An array of nicknames of the certs to be responded to. + * @param {String} rootCertFileName + * The file name of the root cert. Can begin with ".." to reference + * certs in folders other than "test_validity/". + * @param {Array} intCertFileNames + * An array of file names of any intermediate certificates. + * @param {String} endEntityCertFileName + * The file name of the end entity cert. + * @param {Boolean} expectedResult + * Whether the chain is expected to validate as EV. + */ +async function doEVTest( + expectedNamesForOCSP, + rootCertFileName, + intCertFileNames, + endEntityCertFileName, + expectedResult +) { + clearOCSPCache(); + let ocspResponder = getOCSPResponder(expectedNamesForOCSP); + + loadCert(`${rootCertFileName}.pem`, "CTu,CTu,CTu"); + for (let intCertFileName of intCertFileNames) { + loadCert(`${intCertFileName}.pem`, ",,"); + } + await checkEVStatus( + certDB, + certFromFile(`${endEntityCertFileName}.pem`), + certificateUsageSSLServer, + expectedResult + ); + + await stopOCSPResponder(ocspResponder); +} + +async function checkEVChains() { + // Chain with an end entity cert with a validity period that is acceptable + // for EV. + const intFullName = "ev_int_60_months-evroot"; + let eeFullName = `ev_ee_27_months-${intFullName}`; + let expectedNamesForOCSP = gEVExpected + ? [intFullName, eeFullName] + : [eeFullName]; + await doEVTest( + expectedNamesForOCSP, + "../test_ev_certs/evroot", + [intFullName], + eeFullName, + gEVExpected + ); + + // Chain with an end entity cert with a validity period that is too long + // for EV. + eeFullName = `ev_ee_28_months-${intFullName}`; + expectedNamesForOCSP = gEVExpected ? [intFullName, eeFullName] : [eeFullName]; + await doEVTest( + expectedNamesForOCSP, + "../test_ev_certs/evroot", + [intFullName], + eeFullName, + false + ); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + await checkEVChains(); +}); diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..ea41b00545 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIUYYDQjys/AnzMoLUwrnp0+jqAmQMwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZXZfaW50XzYwX21vbnRocy1ldnJvb3QwIhgPMjAxOTEx +MTYxMjAwMDBaGA8yMDIyMDIxNjEyMDAwMFowMjEwMC4GA1UEAwwnZXZfZWVfMjdf +bW9udGhzLWV2X2ludF82MF9tb250aHMtZXZyb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GGMIGDMGAGCCsG +AQUFBwEBBFQwUjBQBggrBgEFBQcwAYZEaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4 +ODg4L2V2X2VlXzI3X21vbnRocy1ldl9pbnRfNjBfbW9udGhzLWV2cm9vdC8wHwYD +VR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEB +AIP1/h4cT0t0hvLupI1lMwefjvlUtiXfTLW8u6BU8kEaENJybcWbIsCnPM2Bi2bz +AwxQ6ByBMyicnxzgiHZofC9ATxXUrIKHLOk5I8aW6FNvEcD4KdJoju3u/EmbaDjP +ORijvoa9gm9FQjl9SKYohfnjmOfNKcHQDQafnm4GHJV4nh7cIPfzl9kLrFYD9Hsu +Ct2Yo8qEaWltZ84JqZX2GYD0eNLDt6WSxhIDB1WcRhMsa/XNBm5TwzfGt1yx/Mqb +SHOKviSFUv5HTjJ/l5NDtzvUV+KVEcTA99Ve12Ok74JO7ChRG1U3nHONRKcfJWu9 +7va//Iq102BI6uilMkbGjlQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..d2c7fa1275 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_60_months-evroot +subject:ev_ee_27_months-ev_int_60_months-evroot +validity:823 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_27_months-ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..672175fe84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIUD55RmXcxc2Ubvzh7CUeXD5mJm20wDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZXZfaW50XzYwX21vbnRocy1ldnJvb3QwIhgPMjAxOTEx +MDEwMDAwMDBaGA8yMDIyMDMwNDAwMDAwMFowMjEwMC4GA1UEAwwnZXZfZWVfMjhf +bW9udGhzLWV2X2ludF82MF9tb250aHMtZXZyb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GGMIGDMGAGCCsG +AQUFBwEBBFQwUjBQBggrBgEFBQcwAYZEaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4 +ODg4L2V2X2VlXzI4X21vbnRocy1ldl9pbnRfNjBfbW9udGhzLWV2cm9vdC8wHwYD +VR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEB +AF1J9oNzg5u2a/E4nHHY1WgEPrMD3A4KFgprQxzzyebOqypMWK3+jXNdloF8AS8u +5mIQoLNNw/bCFb0zgpK+0qKwxGHkreN+eJyfoi+zJr2Ygf4BmRlb02t79v4mYcFN +rfCFSyvgwOI5aUr5n/BYFkUn38IAllJDn5igGGeROHSyOYZa9lOQZRAsh4vnas99 +V1RWo9E+hOmDH5be67HqJw4DHJ0sld8SWDxtjyXd6RbdJd4VIXScp2sk1W6F49Av +otRZSrZFaZeS95a9SmN+xhCfpL3VNF3YdHCbfYeam/A/AUlD0TFBSoqJo6l9nT1c +Of56pBg7jLup+dDdx7whu/w= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..2dcfb2e29c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_60_months-evroot +subject:ev_ee_28_months-ev_int_60_months-evroot +validity:854 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_28_months-ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..6fc6bdeec5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUGWNNFPvyjk63DRepZV/gB/+L1VUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTgwNzAzMTIwMDAwWhgPMjAyMzA3 +MDIxMjAwMDBaMCIxIDAeBgNVBAMMF2V2X2ludF82MF9tb250aHMtZXZyb290MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMFAGCCsGAQUFBwEB +BEQwQjBABggrBgEFBQcwAYY0aHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2V2 +X2ludF82MF9tb250aHMtZXZyb290LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUa +hRoBg3QJATANBgkqhkiG9w0BAQsFAAOCAQEADae0P+9+rtDogzf5zQega4VLX+Nj +tUru5/tU1IKifEGO1UibkrACklVZPh5I8A0scUNQVuvsSTmRSR3np25bhFtibs0T +7cx4x9Uwuk/KO2257NUJwj1tZFMdTCxkcIDOujU5XIWo3q1+b2MMgzwgcESjSV8K +1dUi0mDbhut9SjfimmUgfB+53ZVJDk40RTQIZYFvQy1XKnFpd0R/FXxz3YTZkICm +E0fAuSsif/wjopUgMnjgXHxA7bZYAuWQxgcZ28MRuqI9JESDZ3eH2oPUkYcpR8DK +FGd5wcJGvQtR2u/e3EmzcC9jZzBzZE7rvXuyl+AAwXhC25eq1Tqg/7XxjA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..e169514ffa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,8 @@ +issuer:evroot +subject:ev_int_60_months-evroot +issuerKey:ev +validity:1825 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.key b/security/manager/ssl/tests/unit/test_validity/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.pem b/security/manager/ssl/tests/unit/test_validity/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_validity/moz.build b/security/manager/ssl/tests/unit/test_validity/moz.build new file mode 100644 index 0000000000..9121c4e49b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ev_ee_27_months-ev_int_60_months-evroot.pem', +# 'ev_ee_28_months-ev_int_60_months-evroot.pem', +# 'ev_int_60_months-evroot.pem', +# 'evroot.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'ev_int_60_months-evroot.key', +# 'evroot.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_x509.js b/security/manager/ssl/tests/unit/test_x509.js new file mode 100644 index 0000000000..73eb4ed97a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_x509.js @@ -0,0 +1,142 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests X509.jsm functionality. + +function stringToArray(s) { + let b = []; + for (let i = 0; i < s.length; i++) { + b.push(s.charCodeAt(i)); + } + return b; +} + +function readPEMToBytes(filename) { + return stringToArray(atob(pemToBase64(readFile(do_get_file(filename))))); +} + +function run_test() { + let certificate = new X509.Certificate(); + // We use this certificate because it has a set validity period, which means that when + // the test certificates get regenerated each year, the values in this test won't change. + certificate.parse(readPEMToBytes("bad_certs/expired-ee.pem")); + + equal( + certificate.tbsCertificate.version, + 3, + "expired-ee.pem should be x509v3" + ); + + // serialNumber + deepEqual( + certificate.tbsCertificate.serialNumber, + [ + 0x63, + 0xd1, + 0x11, + 0x00, + 0x82, + 0xa3, + 0xd2, + 0x3b, + 0x3f, + 0x61, + 0xb8, + 0x49, + 0xa0, + 0xca, + 0xdc, + 0x2e, + 0x78, + 0xfe, + 0xfa, + 0xea, + ], + "expired-ee.pem should have expected serialNumber" + ); + + deepEqual( + certificate.tbsCertificate.signature.algorithm._values, + [1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption + "expired-ee.pem should have sha256WithRSAEncryption signature" + ); + deepEqual( + certificate.tbsCertificate.signature.parameters._contents, + [], + "expired-ee.pem should have NULL parameters for signature" + ); + + equal( + certificate.tbsCertificate.issuer.rdns.length, + 1, + "expired-ee.pem should have one RDN in issuer" + ); + equal( + certificate.tbsCertificate.issuer.rdns[0].avas.length, + 1, + "expired-ee.pem should have one AVA in RDN in issuer" + ); + deepEqual( + certificate.tbsCertificate.issuer.rdns[0].avas[0].value.value, + stringToArray("Test CA"), + "expired-ee.pem should have issuer 'Test CA'" + ); + + equal( + certificate.tbsCertificate.validity.notBefore.time.getTime(), + Date.parse("2013-01-01T00:00:00.000Z"), + "expired-ee.pem should have the correct value for notBefore" + ); + equal( + certificate.tbsCertificate.validity.notAfter.time.getTime(), + Date.parse("2014-01-01T00:00:00.000Z"), + "expired-ee.pem should have the correct value for notAfter" + ); + + equal( + certificate.tbsCertificate.subject.rdns.length, + 1, + "expired-ee.pem should have one RDN in subject" + ); + equal( + certificate.tbsCertificate.subject.rdns[0].avas.length, + 1, + "expired-ee.pem should have one AVA in RDN in subject" + ); + deepEqual( + certificate.tbsCertificate.subject.rdns[0].avas[0].value.value, + stringToArray("Expired Test End-entity"), + "expired-ee.pem should have subject 'Expired Test End-entity'" + ); + + deepEqual( + certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm._values, + [1, 2, 840, 113549, 1, 1, 1], // rsaEncryption + "expired-ee.pem should have a spki algorithm of rsaEncryption" + ); + + equal( + certificate.tbsCertificate.extensions.length, + 2, + "expired-ee.pem should have two extensions" + ); + + deepEqual( + certificate.signatureAlgorithm.algorithm._values, + [1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption + "expired-ee.pem should have sha256WithRSAEncryption signatureAlgorithm" + ); + deepEqual( + certificate.signatureAlgorithm.parameters._contents, + [], + "expired-ee.pem should have NULL parameters for signatureAlgorithm" + ); + + equal( + certificate.signatureValue.length, + 2048 / 8, + "length of signature on expired-ee.pem should be 2048 bits" + ); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp new file mode 100644 index 0000000000..b13d2e9e61 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp @@ -0,0 +1,140 @@ +/* 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/. */ + +// This is a standalone server that uses various bad certificates. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include <stdio.h> + +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct BadCertAndPinningHost { + const char* mHostName; + const char* mCertName; +}; + +// Hostname, cert nickname pairs. +const BadCertAndPinningHost sBadCertAndPinningHosts[] = { + {"expired.example.com", "expired-ee"}, + {"notyetvalid.example.com", "notYetValid"}, + {"before-epoch.example.com", "beforeEpoch"}, + {"selfsigned.example.com", "selfsigned"}, + {"unknownissuer.example.com", "unknownissuer"}, + {"mismatch.example.com", "mismatch"}, + {"mismatch-CN.example.com", "mismatchCN"}, + {"mitm.example.com", "mitm"}, + {"expiredissuer.example.com", "expiredissuer"}, + {"notyetvalidissuer.example.com", "notYetValidIssuer"}, + {"before-epoch-issuer.example.com", "beforeEpochIssuer"}, + {"md5signature.example.com", "md5signature"}, + {"untrusted.example.com", "default-ee"}, + {"untrustedissuer.example.com", "untrustedissuer"}, + {"mismatch-expired.example.com", "mismatch-expired"}, + {"mismatch-notYetValid.example.com", "mismatch-notYetValid"}, + {"mismatch-untrusted.example.com", "mismatch-untrusted"}, + {"untrusted-expired.example.com", "untrusted-expired"}, + {"md5signature-expired.example.com", "md5signature-expired"}, + {"mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired"}, + {"inadequatekeyusage.example.com", "inadequatekeyusage-ee"}, + {"selfsigned-inadequateEKU.example.com", "selfsigned-inadequateEKU"}, + {"self-signed-end-entity-with-cA-true.example.com", + "self-signed-EE-with-cA-true"}, + {"ca-used-as-end-entity.example.com", "ca-used-as-end-entity"}, + {"ca-used-as-end-entity-name-mismatch.example.com", + "ca-used-as-end-entity"}, + // All of include-subdomains.pinning.example.com is pinned to End Entity + // Test Cert with nick default-ee. Any other nick will only + // pass pinning when security.cert_pinning.enforcement.level != strict and + // otherCA is added as a user-specified trust anchor. See StaticHPKPins.h. + {"include-subdomains.pinning.example.com", "default-ee"}, + {"good.include-subdomains.pinning.example.com", "default-ee"}, + {"bad.include-subdomains.pinning.example.com", "other-issuer-ee"}, + {"bad.include-subdomains.pinning.example.com.", "other-issuer-ee"}, + {"bad.include-subdomains.pinning.example.com..", "other-issuer-ee"}, + {"exclude-subdomains.pinning.example.com", "default-ee"}, + {"sub.exclude-subdomains.pinning.example.com", "other-issuer-ee"}, + {"test-mode.pinning.example.com", "other-issuer-ee"}, + {"unknownissuer.include-subdomains.pinning.example.com", "unknownissuer"}, + {"unknownissuer.test-mode.pinning.example.com", "unknownissuer"}, + {"nsCertTypeNotCritical.example.com", "nsCertTypeNotCritical"}, + {"nsCertTypeCriticalWithExtKeyUsage.example.com", + "nsCertTypeCriticalWithExtKeyUsage"}, + {"nsCertTypeCritical.example.com", "nsCertTypeCritical"}, + {"end-entity-issued-by-v1-cert.example.com", "eeIssuedByV1Cert"}, + {"end-entity-issued-by-non-CA.example.com", "eeIssuedByNonCA"}, + {"inadequate-key-size-ee.example.com", "inadequateKeySizeEE"}, + {"badSubjectAltNames.example.com", "badSubjectAltNames"}, + {"ipAddressAsDNSNameInSAN.example.com", "ipAddressAsDNSNameInSAN"}, + {"noValidNames.example.com", "noValidNames"}, + {"bug413909.xn--hxajbheg2az3al.xn--jxalpdlp", "idn-certificate"}, + {"emptyissuername.example.com", "emptyIssuerName"}, + {"ev-test.example.com", "ev-test"}, + {"ee-from-missing-intermediate.example.com", + "ee-from-missing-intermediate"}, + {"imminently-distrusted.example.com", "ee-imminently-distrusted"}, + {"localhost", "unknownissuer"}, + {"a.pinning.example.com", "default-ee"}, + {"b.pinning.example.com", "default-ee"}, + {"not-preloaded.example.com", "default-ee"}, + {"ee.example.com", "default-ee"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const BadCertAndPinningHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sBadCertAndPinningHosts); + if (!host) { + // No static cert <-> hostname mapping found. This happens when we use a + // collection of certificates in a given directory and build a cert DB at + // runtime, rather than using an NSS cert DB populated at build time. + // (This will be the default in the future.) + // For all given server names, check if the runtime-built cert DB contains + // a certificate with a matching subject CN. + return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize); + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp new file mode 100644 index 0000000000..5f12756425 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp @@ -0,0 +1,142 @@ +/* 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/. */ + +// This is a standalone server used to test Delegated Credentials +// (see: https://tools.ietf.org/html/draft-ietf-tls-subcerts-03). +// +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include <iostream> + +#include "TLSServer.h" + +#include "sslexp.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct DelegatedCertHost { + const char* mHostName; + const char* mCertName; + const char* mDCKeyNick; + bool mEnableDelegatedCredentials; +}; + +const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */; + +// {host, eeCert, dcCert, enableDC} +const DelegatedCertHost sDelegatedCertHosts[] = { + {"delegated-enabled.example.com", "delegated-ee", "delegated.key", true}, + {"standard-enabled.example.com", "default-ee", "delegated.key", true}, + {"delegated-disabled.example.com", "delegated-ee", + /* anything non-null */ "delegated.key", false}, + {nullptr, nullptr, nullptr, false}}; + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const DelegatedCertHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sDelegatedCertHosts); + if (!host) { + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + std::cerr << "Identified host " << host->mHostName << std::endl; + } + + UniqueCERTCertificate delegatorCert( + PK11_FindCertFromNickname(host->mCertName, nullptr)); + if (!delegatorCert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return SSL_SNI_SEND_ALERT; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SSL_SNI_SEND_ALERT; + } + + SSLExtraServerCertData extra_data = {ssl_auth_null, + /* Filled in by callee */ nullptr, + nullptr, + nullptr, + /* DC */ nullptr, + /* DC PrivKey */ nullptr}; + + UniqueSECKEYPrivateKey delegatorPriv( + PK11_FindKeyByDERCert(slot.get(), delegatorCert.get(), nullptr)); + if (!delegatorPriv) { + PrintPRError("PK11_FindKeyByDERCert failed"); + return SSL_SNI_SEND_ALERT; + } + + // Find the DC keypair by the file (nick) name. + ScopedAutoSECItem dc; + UniqueSECKEYPrivateKey dcPriv; + if (host->mEnableDelegatedCredentials) { + if (gDebugLevel >= DEBUG_VERBOSE) { + std::cerr << "Enabling a delegated credential for host " + << host->mHostName << std::endl; + } + + if (PK11_NeedLogin(slot.get())) { + SECStatus rv = PK11_Authenticate(slot.get(), PR_TRUE, nullptr); + if (rv != SECSuccess) { + PrintPRError("PK11_Authenticate failed"); + return SSL_SNI_SEND_ALERT; + } + } + UniqueSECKEYPrivateKeyList list(PK11_ListPrivKeysInSlot( + slot.get(), const_cast<char*>(host->mDCKeyNick), nullptr)); + if (!list) { + PrintPRError("PK11_ListPrivKeysInSlot failed"); + return SSL_SNI_SEND_ALERT; + } + SECKEYPrivateKeyListNode* node = PRIVKEY_LIST_HEAD(list); + + dcPriv.reset(SECKEY_CopyPrivateKey(node->key)); + if (!dcPriv) { + PrintPRError("PK11_ListPrivKeysInSlot could not find dcPriv"); + return SSL_SNI_SEND_ALERT; + } + + UniqueSECKEYPublicKey dcPub(SECKEY_ConvertToPublicKey(dcPriv.get())); + if (!dcPub) { + PrintPRError("SECKEY_ConvertToPublicKey failed"); + return SSL_SNI_SEND_ALERT; + } + + // Create and set the DC. + if (SSL_DelegateCredential(delegatorCert.get(), delegatorPriv.get(), + dcPub.get(), ssl_sig_ecdsa_secp384r1_sha384, + kDCValidFor, PR_Now(), &dc) != SECSuccess) { + PrintPRError("SSL_DelegateCredential failed"); + return SSL_SNI_SEND_ALERT; + } + extra_data.delegCred = &dc; + extra_data.delegCredPrivKey = dcPriv.get(); + + // The list should only have a single key. + PORT_Assert(PRIVKEY_LIST_END(PRIVKEY_LIST_NEXT(node), list)); + } + + if (ConfigSecureServerWithNamedCert(aFd, host->mCertName, nullptr, nullptr, + &extra_data) != SECSuccess) { + PrintPRError("ConfigSecureServerWithNamedCert failed"); + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp new file mode 100644 index 0000000000..f768b888f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp @@ -0,0 +1,143 @@ +/* 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/. */ + +// This is a standalone server that offers TLS 1.3 Encrypted +// Client Hello support. + +#include <stdio.h> + +#include "nspr.h" +#include "ScopedNSSTypes.h" +#include "ssl.h" +#include "sslexp.h" +#include "TLSServer.h" +#include <pk11pub.h> +#include <vector> + +using namespace mozilla; +using namespace mozilla::test; + +struct EchHost { + const char* mHostName; + const char* mCertName; +}; + +const std::vector<uint32_t> kSuiteChaCha = { + (static_cast<uint32_t>(HpkeKdfHkdfSha256) << 16) | + HpkeAeadChaCha20Poly1305}; + +// Hostname, cert nickname pairs. +const EchHost sEchHosts[] = {{"ech-public.example.com", "default-ee"}, + {"ech-private.example.com", "private-ee"}, + {"selfsigned.example.com", "selfsigned"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const EchHost* host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sEchHosts); + if (!host) { + PrintPRError("No cert found for hostname"); + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +SECStatus ConfigureServer(PRFileDesc* aFd) { + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + + UniqueSECKEYPublicKey pubKey; + UniqueSECKEYPrivateKey privKey; + SECKEYPublicKey* tmpPubKey = nullptr; + SECKEYPrivateKey* tmpPrivKey = nullptr; + + static const std::vector<uint8_t> pkcs8{ + 0x30, 0x67, 0x02, 0x01, 0x00, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, + 0x47, 0x0f, 0x01, 0x04, 0x4c, 0x30, 0x4a, 0x02, 0x01, 0x01, 0x04, 0x20, + 0x8c, 0x49, 0x0e, 0x5b, 0x0c, 0x7d, 0xbe, 0x0c, 0x6d, 0x21, 0x92, 0x48, + 0x4d, 0x2b, 0x7a, 0x04, 0x23, 0xb3, 0xb4, 0x54, 0x4f, 0x24, 0x81, 0x09, + 0x5a, 0x99, 0xdb, 0xf2, 0x38, 0xfb, 0x35, 0x0f, 0xa1, 0x23, 0x03, 0x21, + 0x00, 0x8a, 0x07, 0x56, 0x39, 0x49, 0xfa, 0xc6, 0x23, 0x29, 0x36, 0xed, + 0x6f, 0x36, 0xc4, 0xfa, 0x73, 0x59, 0x30, 0xec, 0xde, 0xae, 0xf6, 0x73, + 0x4e, 0x31, 0x4a, 0xea, 0xc3, 0x5a, 0x56, 0xfd, 0x0a}; + + SECItem pkcs8Item = {siBuffer, const_cast<uint8_t*>(pkcs8.data()), + static_cast<unsigned int>(pkcs8.size())}; + SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot.get(), &pkcs8Item, nullptr, nullptr, false, false, KU_ALL, + &tmpPrivKey, nullptr); + + if (rv != SECSuccess) { + PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); + return SECFailure; + } + privKey.reset(tmpPrivKey); + tmpPubKey = SECKEY_ConvertToPublicKey(privKey.get()); + pubKey.reset(tmpPubKey); + + if (!privKey || !pubKey) { + PrintPRError("ECH/HPKE Public or Private key is null!"); + return SECFailure; + } + + std::vector<uint8_t> echConfig(1000, 0); + unsigned int len = 0; + rv = SSL_EncodeEchConfig("ech-public.example.com", kSuiteChaCha.data(), 1, + HpkeDhKemX25519Sha256, pubKey.get(), 50, + echConfig.data(), &len, echConfig.size()); + if (rv != SECSuccess) { + PrintPRError("SSL_EncodeEchConfig failed"); + return rv; + } + + rv = SSL_SetServerEchConfigs(aFd, pubKey.get(), privKey.get(), + echConfig.data(), len); + if (rv != SECSuccess) { + PrintPRError("SSL_SetServerEchConfigs failed"); + return rv; + } + + return SECSuccess; +} + +int main(int argc, char* argv[]) { + int rv = StartServer(argc, argv, DoSNISocketConfig, nullptr, ConfigureServer); + if (rv < 0) { + return rv; + } +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp new file mode 100644 index 0000000000..113e668f89 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 tw=80 et: */ +/* 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/. */ + +/* This simple program takes a database directory, and one or more tuples like + * <typeOfResponse> <CertNick> <ExtraCertNick> <outPutFilename> + * to generate (one or more) ocsp responses. + */ + +#include <stdio.h> +#include <string> +#include <vector> + +#include "mozilla/ArrayUtils.h" + +#include "cert.h" +#include "nspr.h" +#include "nss.h" +#include "plarenas.h" +#include "prerror.h" +#include "ssl.h" +#include "secerr.h" + +#include "OCSPCommon.h" +#include "ScopedNSSTypes.h" +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct OCSPResponseName { + const char* mTypeString; + const OCSPResponseType mORT; +}; + +const static OCSPResponseName kOCSPResponseNameList[] = { + {"good", ORTGood}, // the certificate is good + {"good-delegated", ORTDelegatedIncluded}, // the certificate is good, using + // a delegated signer + {"revoked", ORTRevoked}, // the certificate has been revoked + {"unknown", ORTUnknown}, // the responder doesn't know if the + // cert is good + {"goodotherca", ORTGoodOtherCA}, // the wrong CA has signed the + // response + {"expiredresponse", ORTExpired}, // the signature on the response has + // expired + {"oldvalidperiod", ORTExpiredFreshCA}, // fresh signature, but old validity + // period + {"empty", ORTEmpty}, // an empty stapled response + + {"malformed", ORTMalformed}, // the response from the responder + // was malformed + {"serverr", ORTSrverr}, // the response indicates there was a + // server error + {"trylater", ORTTryLater}, // the responder replied with + // "try again later" + {"resp-unsigned", ORTNeedsSig}, // the response needs a signature + {"unauthorized", ORTUnauthorized}, // the responder does not know about + // the cert + {"bad-signature", ORTBadSignature}, // the response has a bad signature + {"longvalidityalmostold", + ORTLongValidityAlmostExpired}, // the response is + // still valid, but the generation + // is almost a year old + {"ancientstillvalid", ORTAncientAlmostExpired}, // The response is still + // valid but the generation + // is almost two years old +}; + +bool StringToOCSPResponseType(const char* respText, + /*out*/ OCSPResponseType* OCSPType) { + if (!OCSPType) { + return false; + } + for (auto ocspResponseName : kOCSPResponseNameList) { + if (strcmp(respText, ocspResponseName.mTypeString) == 0) { + *OCSPType = ocspResponseName.mORT; + return true; + } + } + return false; +} + +bool WriteResponse(const char* filename, const SECItem* item) { + if (!filename || !item || !item->data) { + PR_fprintf(PR_STDERR, "invalid parameters to WriteResponse"); + return false; + } + + UniquePRFileDesc outFile( + PR_Open(filename, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0644)); + if (!outFile) { + PrintPRError("cannot open file for writing"); + return false; + } + int32_t rv = PR_Write(outFile.get(), item->data, item->len); + if (rv < 0 || (uint32_t)rv != item->len) { + PrintPRError("File write failure"); + return false; + } + + return true; +} + +int main(int argc, char* argv[]) { + if (argc < 7 || (argc - 7) % 5 != 0) { + PR_fprintf( + PR_STDERR, + "usage: %s <NSS DB directory> <responsetype> " + "<cert_nick> <extranick> <this_update_skew> <outfilename> [<resptype> " + "<cert_nick> <extranick> <this_update_skew> <outfilename>]* \n", + argv[0]); + exit(EXIT_FAILURE); + } + SECStatus rv = InitializeNSS(argv[1]); + if (rv != SECSuccess) { + PR_fprintf(PR_STDERR, "Failed to initialize NSS\n"); + exit(EXIT_FAILURE); + } + UniquePLArenaPool arena(PORT_NewArena(256 * argc)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + exit(EXIT_FAILURE); + } + + for (int i = 2; i + 3 < argc; i += 5) { + const char* ocspTypeText = argv[i]; + const char* certNick = argv[i + 1]; + const char* extraCertname = argv[i + 2]; + const char* skewChars = argv[i + 3]; + const char* filename = argv[i + 4]; + + OCSPResponseType ORT; + if (!StringToOCSPResponseType(ocspTypeText, &ORT)) { + PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n", + ocspTypeText); + exit(EXIT_FAILURE); + } + + UniqueCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n", + certNick); + exit(EXIT_FAILURE); + } + + time_t skew = static_cast<time_t>(atoll(skewChars)); + + SECItemArray* response = + GetOCSPResponseForType(ORT, cert, arena, extraCertname, skew); + if (!response) { + PR_fprintf(PR_STDERR, + "Failed to generate OCSP response of type %s " + "for %s\n", + ocspTypeText, certNick); + exit(EXIT_FAILURE); + } + + if (!WriteResponse(filename, &response->items[0])) { + PR_fprintf(PR_STDERR, "Failed to write file %s\n", filename); + exit(EXIT_FAILURE); + } + } + return 0; +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp new file mode 100644 index 0000000000..b35484572f --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp @@ -0,0 +1,153 @@ +/* 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/. */ + +// This is a standalone server that delivers various stapled OCSP responses. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the OCSP response. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include <stdio.h> + +#include "OCSPCommon.h" +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +const OCSPHost sOCSPHosts[] = { + {"ocsp-stapling-good.example.com", ORTGood, nullptr, nullptr}, + {"ocsp-stapling-revoked.example.com", ORTRevoked, nullptr, nullptr}, + {"ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr, nullptr}, + {"ocsp-stapling-unknown.example.com", ORTUnknown, nullptr, nullptr}, + {"ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr, nullptr}, + {"ocsp-stapling-good-other.example.com", ORTGoodOtherCert, + "ocspOtherEndEntity", nullptr}, + {"ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "other-test-ca", + nullptr}, + {"ocsp-stapling-expired.example.com", ORTExpired, nullptr, nullptr}, + {"ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr, + nullptr}, + {"ocsp-stapling-none.example.com", ORTNone, nullptr, nullptr}, + {"ocsp-stapling-empty.example.com", ORTEmpty, nullptr, nullptr}, + {"ocsp-stapling-malformed.example.com", ORTMalformed, nullptr, nullptr}, + {"ocsp-stapling-srverr.example.com", ORTSrverr, nullptr, nullptr}, + {"ocsp-stapling-trylater.example.com", ORTTryLater, nullptr, nullptr}, + {"ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr, nullptr}, + {"ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr, + nullptr}, + {"ocsp-stapling-with-intermediate.example.com", ORTGood, nullptr, + "ocspEEWithIntermediate"}, + {"ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr, + nullptr}, + {"ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, + nullptr, nullptr}, + {"ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, + nullptr, nullptr}, + {"ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, + nullptr, nullptr}, + {"ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr, + nullptr}, + {"ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, + "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-included-last.example.com", + ORTDelegatedIncludedLast, "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, + "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-missing-multiple.example.com", + ORTDelegatedMissingMultiple, "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, + "invalidDelegatedSignerNoExtKeyUsage", nullptr}, + {"ocsp-stapling-delegated-from-intermediate.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate", nullptr}, + {"ocsp-stapling-delegated-keyUsage-crlSigning.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning", nullptr}, + {"ocsp-stapling-delegated-wrong-extKeyUsage.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage", nullptr}, + {"ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, + nullptr, nullptr}, + {"keysize-ocsp-delegated.example.com", ORTDelegatedIncluded, + "rsa-1016-keysizeDelegatedSigner", nullptr}, + {"revoked-ca-cert-used-as-end-entity.example.com", ORTRevoked, + "ca-used-as-end-entity", nullptr}, + {"ocsp-stapling-must-staple.example.com", ORTGood, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-revoked.example.com", ORTRevoked, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-missing.example.com", ORTNone, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-empty.example.com", ORTEmpty, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-ee-with-must-staple-int.example.com", ORTGood, + nullptr, "must-staple-ee-with-must-staple-int"}, + {"ocsp-stapling-plain-ee-with-must-staple-int.example.com", ORTGood, + nullptr, "must-staple-missing-ee"}, + {"ocsp-stapling-must-staple-expired.example.com", ORTExpired, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-try-later.example.com", ORTTryLater, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-invalid-signer.example.com", ORTGoodOtherCA, + "other-test-ca", "must-staple-ee"}, + {"multi-tls-feature-good.example.com", ORTNone, nullptr, + "multi-tls-feature-good-ee"}, + {"multi-tls-feature-bad.example.com", ORTNone, nullptr, + "multi-tls-feature-bad-ee"}, + {nullptr, ORTNull, nullptr, nullptr}}; + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const OCSPHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sOCSPHosts); + if (!host) { + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + const char* certNickname = + host->mServerCertName ? host->mServerCertName : DEFAULT_CERT_NICKNAME; + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + // If the OCSP response type is "none", don't staple a response. + if (host->mORT == ORTNone) { + return 0; + } + + UniquePLArenaPool arena(PORT_NewArena(1024)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + return SSL_SNI_SEND_ALERT; + } + + // response is contained by the arena - freeing the arena will free it + SECItemArray* response = GetOCSPResponseForType(host->mORT, cert, arena, + host->mAdditionalCertName, 0); + if (!response) { + return SSL_SNI_SEND_ALERT; + } + + // SSL_SetStapledOCSPResponses makes a deep copy of response + SECStatus st = SSL_SetStapledOCSPResponses(aFd, response, certKEA); + if (st != SECSuccess) { + PrintPRError("SSL_SetStapledOCSPResponses failed"); + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp new file mode 100644 index 0000000000..9371617305 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp @@ -0,0 +1,87 @@ +/* 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/. */ + +// This is a standalone server that uses various bad certificates. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include <stdio.h> + +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct SanctionsCertHost { + const char* mHostName; + const char* mCertName; +}; + +// Hostname, cert nickname pairs. +const SanctionsCertHost sSanctionsCertHosts[] = { + {"symantec-allowlist-after-cutoff.example.com", + "symantec-ee-from-allowlist-after-cutoff"}, + {"symantec-allowlist-before-cutoff.example.com", + "symantec-ee-from-allowlist-before-cutoff"}, + {"symantec-not-allowlisted-after-cutoff.example.com", + "symantec-ee-not-allowlisted-after-cutoff"}, + {"symantec-not-allowlisted-before-cutoff.example.com", + "symantec-ee-not-allowlisted-before-cutoff"}, + {"symantec-unaffected.example.com", "symantec-ee-unaffected"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const SanctionsCertHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sSanctionsCertHosts); + if (!host) { + // No static cert <-> hostname mapping found. This happens when we use a + // collection of certificates in a given directory and build a cert DB at + // runtime, rather than using an NSS cert DB populated at build time. + // (This will be the default in the future.) + // For all given server names, check if the runtime-built cert DB contains + // a certificate with a matching subject CN. + return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize); + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build b/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build new file mode 100644 index 0000000000..5c6dbadc71 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build @@ -0,0 +1,30 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +GeckoSimplePrograms( + [ + "BadCertAndPinningServer", + "DelegatedCredentialsServer", + "EncryptedClientHelloServer", + "GenerateOCSPResponse", + "OCSPStaplingServer", + "SanctionsTestServer", + ], + linkage=None, +) + +LOCAL_INCLUDES += [ + "../lib", +] + +USE_LIBS += [ + "mozpkix", + "nspr", + "nss", + "tlsserver", +] + +CXXFLAGS += CONFIG["TK_CFLAGS"] diff --git a/security/manager/ssl/tests/unit/tlsserver/default-ee.der b/security/manager/ssl/tests/unit/tlsserver/default-ee.der new file mode 100644 index 0000000000..3a9b8fa9bc --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/default-ee.der @@ -0,0 +1,3 @@ +This is now an unused file. It exists to ease the coordination between gecko +development trees and the automation infrastructure that runs periodic updates. +See bug 1203312 and bug 1205406. diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp new file mode 100644 index 0000000000..be9a9af9b1 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -0,0 +1,204 @@ +/* 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/. */ + +#include "OCSPCommon.h" + +#include <stdio.h> + +#include "mozpkix/test/pkixtestutil.h" +#include "mozpkix/test/pkixtestnss.h" +#include "TLSServer.h" +#include "secder.h" +#include "secerr.h" + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::pkix::test; +using namespace mozilla::test; + +static TestKeyPair* CreateTestKeyPairFromCert( + const UniqueCERTCertificate& cert) { + ScopedSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(cert.get(), nullptr)); + if (!privateKey) { + return nullptr; + } + ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(cert.get())); + if (!publicKey) { + return nullptr; + } + return CreateTestKeyPair(RSA_PKCS1(), publicKey, privateKey); +} + +SECItemArray* GetOCSPResponseForType(OCSPResponseType aORT, + const UniqueCERTCertificate& aCert, + const UniquePLArenaPool& aArena, + const char* aAdditionalCertName, + time_t aThisUpdateSkew) { + MOZ_ASSERT(aArena); + MOZ_ASSERT(aCert); + // Note: |aAdditionalCertName| may or may not need to be non-null depending + // on the |aORT| value given. + + if (aORT == ORTNone) { + if (gDebugLevel >= DEBUG_WARNINGS) { + fprintf(stderr, + "GetOCSPResponseForType called with type ORTNone, " + "which makes no sense.\n"); + } + return nullptr; + } + + if (aORT == ORTEmpty) { + SECItemArray* arr = SECITEM_AllocArray(aArena.get(), nullptr, 1); + arr->items[0].data = nullptr; + arr->items[0].len = 0; + return arr; + } + + time_t now = time(nullptr) + aThisUpdateSkew; + time_t oldNow = now - (8 * Time::ONE_DAY_IN_SECONDS); + + mozilla::UniqueCERTCertificate cert(CERT_DupCertificate(aCert.get())); + + if (aORT == ORTGoodOtherCert) { + cert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + // XXX CERT_FindCertIssuer uses the old, deprecated path-building logic + mozilla::UniqueCERTCertificate issuerCert( + CERT_FindCertIssuer(aCert.get(), PR_Now(), certUsageSSLCA)); + if (!issuerCert) { + PrintPRError("CERT_FindCertIssuer failed"); + return nullptr; + } + Input issuer; + if (issuer.Init(cert->derIssuer.data, cert->derIssuer.len) != Success) { + return nullptr; + } + Input issuerPublicKey; + if (issuerPublicKey.Init(issuerCert->derPublicKey.data, + issuerCert->derPublicKey.len) != Success) { + return nullptr; + } + Input serialNumber; + if (serialNumber.Init(cert->serialNumber.data, cert->serialNumber.len) != + Success) { + return nullptr; + } + CertID certID(issuer, issuerPublicKey, serialNumber); + OCSPResponseContext context(certID, now); + + mozilla::UniqueCERTCertificate signerCert; + if (aORT == ORTGoodOtherCA || aORT == ORTDelegatedIncluded || + aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissing || + aORT == ORTDelegatedMissingMultiple) { + signerCert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr)); + if (!signerCert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + + ByteString certs[5]; + + if (aORT == ORTDelegatedIncluded) { + certs[0].assign(signerCert->derCert.data, signerCert->derCert.len); + context.certs = certs; + } + if (aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissingMultiple) { + certs[0].assign(issuerCert->derCert.data, issuerCert->derCert.len); + certs[1].assign(cert->derCert.data, cert->derCert.len); + certs[2].assign(issuerCert->derCert.data, issuerCert->derCert.len); + if (aORT != ORTDelegatedMissingMultiple) { + certs[3].assign(signerCert->derCert.data, signerCert->derCert.len); + } + context.certs = certs; + } + + switch (aORT) { + case ORTMalformed: + context.responseStatus = 1; + break; + case ORTSrverr: + context.responseStatus = 2; + break; + case ORTTryLater: + context.responseStatus = 3; + break; + case ORTNeedsSig: + context.responseStatus = 5; + break; + case ORTUnauthorized: + context.responseStatus = 6; + break; + default: + // context.responseStatus is 0 in all other cases, and it has + // already been initialized in the constructor. + break; + } + if (aORT == ORTSkipResponseBytes) { + context.skipResponseBytes = true; + } + if (aORT == ORTExpired || aORT == ORTExpiredFreshCA || + aORT == ORTRevokedOld || aORT == ORTUnknownOld) { + context.thisUpdate = oldNow; + context.nextUpdate = oldNow + Time::ONE_DAY_IN_SECONDS; + } + if (aORT == ORTLongValidityAlmostExpired) { + context.thisUpdate = now - (320 * Time::ONE_DAY_IN_SECONDS); + } + if (aORT == ORTAncientAlmostExpired) { + context.thisUpdate = now - (640 * Time::ONE_DAY_IN_SECONDS); + } + if (aORT == ORTRevoked || aORT == ORTRevokedOld) { + context.certStatus = 1; + } + if (aORT == ORTUnknown || aORT == ORTUnknownOld) { + context.certStatus = 2; + } + if (aORT == ORTBadSignature) { + context.badSignature = true; + } + OCSPResponseExtension extension; + if (aORT == ORTCriticalExtension || aORT == ORTNoncriticalExtension) { + // python DottedOIDToCode.py --tlv + // some-Mozilla-OID 1.3.6.1.4.1.13769.666.666.666.1.500.9.2 + static const uint8_t tlv_some_Mozilla_OID[] = { + 0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, + 0x1a, 0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x02}; + + extension.id.assign(tlv_some_Mozilla_OID, sizeof(tlv_some_Mozilla_OID)); + extension.critical = (aORT == ORTCriticalExtension); + extension.value.push_back(0x05); // tag: NULL + extension.value.push_back(0x00); // length: 0 + extension.next = nullptr; + context.responseExtensions = &extension; + } + if (aORT == ORTEmptyExtensions) { + context.includeEmptyExtensions = true; + } + + if (!signerCert) { + signerCert.reset(CERT_DupCertificate(issuerCert.get())); + } + context.signerKeyPair.reset(CreateTestKeyPairFromCert(signerCert)); + if (!context.signerKeyPair) { + PrintPRError("PK11_FindKeyByAnyCert failed"); + return nullptr; + } + + ByteString response(CreateEncodedOCSPResponse(context)); + if (ENCODING_FAILED(response)) { + PrintPRError("CreateEncodedOCSPResponse failed"); + return nullptr; + } + + SECItem item = {siBuffer, const_cast<uint8_t*>(response.data()), + static_cast<unsigned int>(response.length())}; + SECItemArray arr = {&item, 1}; + return SECITEM_DupArray(aArena.get(), &arr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h new file mode 100644 index 0000000000..c72eae6a8e --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h @@ -0,0 +1,66 @@ +/* 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/. */ + +// Implements generating OCSP responses of various types. Used by the +// programs in tlsserver/cmd. + +#ifndef OCSPCommon_h +#define OCSPCommon_h + +#include "ScopedNSSTypes.h" +#include "certt.h" +#include "seccomon.h" + +enum OCSPResponseType { + ORTNull = 0, + ORTGood, // the certificate is good + ORTRevoked, // the certificate has been revoked + ORTRevokedOld, // same, but the response is old + ORTUnknown, // the responder doesn't know if the cert is good + ORTUnknownOld, // same, but the response is old + ORTGoodOtherCert, // the response references a different certificate + ORTGoodOtherCA, // the wrong CA has signed the response + ORTExpired, // the signature on the response has expired + ORTExpiredFreshCA, // fresh signature, but old validity period + ORTNone, // no stapled response + ORTEmpty, // an empty stapled response + ORTMalformed, // the response from the responder was malformed + ORTSrverr, // the response indicates there was a server error + ORTTryLater, // the responder replied with "try again later" + ORTNeedsSig, // the response needs a signature + ORTUnauthorized, // the responder is not authorized for this certificate + ORTBadSignature, // the response has a signature that does not verify + ORTSkipResponseBytes, // the response does not include responseBytes + ORTCriticalExtension, // the response includes a critical extension + ORTNoncriticalExtension, // the response includes an extension that is not + // critical + ORTEmptyExtensions, // the response includes a SEQUENCE OF Extension that is + // empty + ORTDelegatedIncluded, // the response is signed by an included delegated + // responder + ORTDelegatedIncludedLast, // same, but multiple other certificates are + // included + ORTDelegatedMissing, // the response is signed by a not included delegated + // responder + ORTDelegatedMissingMultiple, // same, but multiple other certificates are + // included + ORTLongValidityAlmostExpired, // a good response, but that was generated a + // almost a year ago + ORTAncientAlmostExpired, // a good response, with a validity of almost two + // years almost expiring +}; + +struct OCSPHost { + const char* mHostName; + OCSPResponseType mORT; + const char* mAdditionalCertName; // useful for ORTGoodOtherCert, etc. + const char* mServerCertName; +}; + +SECItemArray* GetOCSPResponseForType( + OCSPResponseType aORT, const mozilla::UniqueCERTCertificate& aCert, + const mozilla::UniquePLArenaPool& aArena, const char* aAdditionalCertName, + time_t aThisUpdateSkew); + +#endif // OCSPCommon_h diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp new file mode 100644 index 0000000000..463f865411 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp @@ -0,0 +1,669 @@ +/* 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/. */ + +#include "TLSServer.h" + +#include <stdio.h> +#include <string> +#include <thread> +#include <vector> +#include <fstream> +#include <iostream> +#ifdef XP_WIN +# include <windows.h> +#else +# include <unistd.h> +#endif + +#include <utility> + +#include "base64.h" +#include "mozilla/Sprintf.h" +#include "nspr.h" +#include "nss.h" +#include "plarenas.h" +#include "prenv.h" +#include "prerror.h" +#include "prnetdb.h" +#include "prtime.h" +#include "ssl.h" +#include "sslproto.h" + +namespace mozilla { +namespace test { + +static const uint16_t LISTEN_PORT = 8443; + +DebugLevel gDebugLevel = DEBUG_ERRORS; +uint16_t gCallbackPort = 0; + +const std::string kPEMBegin = "-----BEGIN "; +const std::string kPEMEnd = "-----END "; +const char DEFAULT_CERT_NICKNAME[] = "default-ee"; + +struct Connection { + PRFileDesc* mSocket; + char mByte; + + explicit Connection(PRFileDesc* aSocket); + ~Connection(); +}; + +Connection::Connection(PRFileDesc* aSocket) : mSocket(aSocket), mByte(0) {} + +Connection::~Connection() { + if (mSocket) { + PR_Close(mSocket); + } +} + +void PrintPRError(const char* aPrefix) { + const char* err = PR_ErrorToName(PR_GetError()); + if (err) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "%s: %s\n", aPrefix, err); + } + } else { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "%s\n", aPrefix); + } + } +} + +// This decodes a PEM file into `item`. The line endings need to be +// UNIX-style, or there will be cross-platform issues. +static bool DecodePEMFile(const std::string& filename, SECItem* item) { + std::ifstream in(filename); + if (in.bad()) { + return false; + } + + char buf[1024]; + in.getline(buf, sizeof(buf)); + if (in.bad()) { + return false; + } + + if (strncmp(buf, kPEMBegin.c_str(), kPEMBegin.size()) != 0) { + return false; + } + + std::string value; + for (;;) { + in.getline(buf, sizeof(buf)); + if (in.bad()) { + return false; + } + + if (strncmp(buf, kPEMEnd.c_str(), kPEMEnd.size()) == 0) { + break; + } + + value += buf; + } + + unsigned int binLength; + UniquePORTString bin(BitwiseCast<char*, unsigned char*>( + ATOB_AsciiToData(value.c_str(), &binLength))); + if (!bin || binLength == 0) { + PrintPRError("ATOB_AsciiToData failed"); + return false; + } + + if (SECITEM_AllocItem(nullptr, item, binLength) == nullptr) { + return false; + } + + PORT_Memcpy(item->data, bin.get(), binLength); + return true; +} + +static SECStatus AddKeyFromFile(const std::string& path, + const std::string& filename) { + ScopedAutoSECItem item; + + std::string file = path + "/" + filename; + if (!DecodePEMFile(file, &item)) { + return SECFailure; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + + if (PK11_NeedUserInit(slot.get())) { + if (PK11_InitPin(slot.get(), nullptr, nullptr) != SECSuccess) { + PrintPRError("PK11_InitPin failed"); + return SECFailure; + } + } + + SECKEYPrivateKey* privateKey = nullptr; + SECItem nick = {siBuffer, + BitwiseCast<unsigned char*, const char*>(filename.data()), + static_cast<unsigned int>(filename.size())}; + if (PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot.get(), &item, &nick, nullptr, true, false, KU_ALL, &privateKey, + nullptr) != SECSuccess) { + PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); + return SECFailure; + } + + SECKEY_DestroyPrivateKey(privateKey); + return SECSuccess; +} + +static SECStatus AddCertificateFromFile(const std::string& path, + const std::string& filename) { + ScopedAutoSECItem item; + + std::string file = path + "/" + filename; + if (!DecodePEMFile(file, &item)) { + return SECFailure; + } + + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &item, nullptr, false, true)); + if (!cert) { + PrintPRError("CERT_NewTempCertificate failed"); + return SECFailure; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + // The nickname is the filename without '.pem'. + std::string nickname = filename.substr(0, filename.length() - 4); + SECStatus rv = PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE, + nickname.c_str(), false); + if (rv != SECSuccess) { + PrintPRError("PK11_ImportCert failed"); + return rv; + } + + return SECSuccess; +} + +SECStatus LoadCertificatesAndKeys(const char* basePath) { + // The NSS cert DB path could have been specified as "sql:path". Trim off + // the leading "sql:" if so. + if (strncmp(basePath, "sql:", 4) == 0) { + basePath = basePath + 4; + } + + UniquePRDir fdDir(PR_OpenDir(basePath)); + if (!fdDir) { + PrintPRError("PR_OpenDir failed"); + return SECFailure; + } + // On the B2G ICS emulator, operations taken in AddCertificateFromFile + // appear to interact poorly with readdir (more specifically, something is + // causing readdir to never return null - it indefinitely loops through every + // file in the directory, which causes timeouts). Rather than waste more time + // chasing this down, loading certificates and keys happens in two phases: + // filename collection and then loading. (This is probably a good + // idea anyway because readdir isn't reentrant. Something could change later + // such that it gets called as a result of calling AddCertificateFromFile or + // AddKeyFromFile.) + std::vector<std::string> certificates; + std::vector<std::string> keys; + for (PRDirEntry* dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH); dirEntry; + dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH)) { + size_t nameLength = strlen(dirEntry->name); + if (nameLength > 4) { + if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { + certificates.push_back(dirEntry->name); + } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { + keys.push_back(dirEntry->name); + } + } + } + SECStatus rv; + for (std::string& certificate : certificates) { + rv = AddCertificateFromFile(basePath, certificate.c_str()); + if (rv != SECSuccess) { + return rv; + } + } + for (std::string& key : keys) { + rv = AddKeyFromFile(basePath, key.c_str()); + if (rv != SECSuccess) { + return rv; + } + } + return SECSuccess; +} + +SECStatus InitializeNSS(const char* nssCertDBDir) { + // Try initializing an existing DB. + if (NSS_Init(nssCertDBDir) == SECSuccess) { + return SECSuccess; + } + + // Create a new DB if there is none... + SECStatus rv = NSS_Initialize(nssCertDBDir, nullptr, nullptr, nullptr, 0); + if (rv != SECSuccess) { + return rv; + } + + // ...and load all certificates into it. + return LoadCertificatesAndKeys(nssCertDBDir); +} + +nsresult SendAll(PRFileDesc* aSocket, const char* aData, size_t aDataLen) { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "sending '%s'\n", aData); + } + + while (aDataLen > 0) { + int32_t bytesSent = + PR_Send(aSocket, aData, aDataLen, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesSent == -1) { + PrintPRError("PR_Send failed"); + return NS_ERROR_FAILURE; + } + + aDataLen -= bytesSent; + aData += bytesSent; + } + + return NS_OK; +} + +nsresult ReplyToRequest(Connection* aConn) { + // For debugging purposes, SendAll can print out what it's sending. + // So, any strings we give to it to send need to be null-terminated. + char buf[2] = {aConn->mByte, 0}; + return SendAll(aConn->mSocket, buf, 1); +} + +nsresult SetupTLS(Connection* aConn, PRFileDesc* aModelSocket) { + PRFileDesc* sslSocket = SSL_ImportFD(aModelSocket, aConn->mSocket); + if (!sslSocket) { + PrintPRError("SSL_ImportFD failed"); + return NS_ERROR_FAILURE; + } + aConn->mSocket = sslSocket; + + SSL_OptionSet(sslSocket, SSL_SECURITY, true); + SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, false); + SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_SERVER, true); + + SSL_ResetHandshake(sslSocket, /* asServer */ 1); + + return NS_OK; +} + +nsresult ReadRequest(Connection* aConn) { + int32_t bytesRead = + PR_Recv(aConn->mSocket, &aConn->mByte, 1, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + PrintPRError("PR_Recv failed"); + return NS_ERROR_FAILURE; + } else if (bytesRead == 0) { + PR_SetError(PR_IO_ERROR, 0); + PrintPRError("PR_Recv EOF in ReadRequest"); + return NS_ERROR_FAILURE; + } else { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "read '0x%hhx'\n", aConn->mByte); + } + } + return NS_OK; +} + +void HandleConnection(PRFileDesc* aSocket, + const UniquePRFileDesc& aModelSocket) { + Connection conn(aSocket); + nsresult rv = SetupTLS(&conn, aModelSocket.get()); + if (NS_FAILED(rv)) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + PrintPRError("PR_Recv failed"); + exit(1); + } + + // TODO: On tests that are expected to fail (e.g. due to a revoked + // certificate), the client will close the connection wtihout sending us the + // request byte. In those cases, we should keep going. But, in the cases + // where the connection is supposed to suceed, we should verify that we + // successfully receive the request and send the response. + rv = ReadRequest(&conn); + if (NS_SUCCEEDED(rv)) { + rv = ReplyToRequest(&conn); + } +} + +// returns 0 on success, non-zero on error +int DoCallback() { + UniquePRFileDesc socket(PR_NewTCPSocket()); + if (!socket) { + PrintPRError("PR_NewTCPSocket failed"); + return 1; + } + + PRNetAddr addr; + PR_InitializeNetAddr(PR_IpAddrLoopback, gCallbackPort, &addr); + if (PR_Connect(socket.get(), &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) { + PrintPRError("PR_Connect failed"); + return 1; + } + + const char* request = "GET / HTTP/1.0\r\n\r\n"; + SendAll(socket.get(), request, strlen(request)); + char buf[4096]; + memset(buf, 0, sizeof(buf)); + int32_t bytesRead = + PR_Recv(socket.get(), buf, sizeof(buf) - 1, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + PrintPRError("PR_Recv failed 1"); + return 1; + } + if (bytesRead == 0) { + fprintf(stderr, "PR_Recv eof 1\n"); + return 1; + } + fprintf(stderr, "%s\n", buf); + return 0; +} + +SECStatus ConfigSecureServerWithNamedCert( + PRFileDesc* fd, const char* certName, + /*optional*/ UniqueCERTCertificate* certOut, + /*optional*/ SSLKEAType* keaOut, + /*optional*/ SSLExtraServerCertData* extraData) { + UniqueCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return SECFailure; + } + // If an intermediate certificate issued the server certificate (rather than + // directly by a trust anchor), we want to send it along in the handshake so + // we don't encounter unknown issuer errors when that's not what we're + // testing. + UniqueCERTCertificateList certList; + UniqueCERTCertificate issuerCert( + CERT_FindCertByName(CERT_GetDefaultCertDB(), &cert->derIssuer)); + // If we can't find the issuer cert, continue without it. + if (issuerCert) { + // Sadly, CERTCertificateList does not have a CERT_NewCertificateList + // utility function, so we must create it ourselves. This consists + // of creating an arena, allocating space for the CERTCertificateList, + // and then transferring ownership of the arena to that list. + UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + return SECFailure; + } + certList.reset(static_cast<CERTCertificateList*>( + PORT_ArenaAlloc(arena.get(), sizeof(CERTCertificateList)))); + if (!certList) { + PrintPRError("PORT_ArenaAlloc failed"); + return SECFailure; + } + certList->arena = arena.release(); + // We also have to manually copy the certificates we care about to the + // list, because there aren't any utility functions for that either. + certList->certs = static_cast<SECItem*>( + PORT_ArenaAlloc(certList->arena, 2 * sizeof(SECItem))); + if (SECITEM_CopyItem(certList->arena, certList->certs, &cert->derCert) != + SECSuccess) { + PrintPRError("SECITEM_CopyItem failed"); + return SECFailure; + } + if (SECITEM_CopyItem(certList->arena, certList->certs + 1, + &issuerCert->derCert) != SECSuccess) { + PrintPRError("SECITEM_CopyItem failed"); + return SECFailure; + } + certList->len = 2; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + UniqueSECKEYPrivateKey key( + PK11_FindKeyByDERCert(slot.get(), cert.get(), nullptr)); + if (!key) { + PrintPRError("PK11_FindKeyByDERCert failed"); + return SECFailure; + } + + if (extraData) { + SSLExtraServerCertData dataCopy = {ssl_auth_null, nullptr, nullptr, + nullptr, nullptr, nullptr}; + memcpy(&dataCopy, extraData, sizeof(dataCopy)); + dataCopy.certChain = certList.get(); + + if (SSL_ConfigServerCert(fd, cert.get(), key.get(), &dataCopy, + sizeof(dataCopy)) != SECSuccess) { + PrintPRError("SSL_ConfigServerCert failed"); + return SECFailure; + } + + } else { + // This is the deprecated setup mechanism, to be cleaned up in Bug 1569222 + SSLKEAType certKEA = NSS_FindCertKEAType(cert.get()); + if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(), + key.get(), certKEA) != SECSuccess) { + PrintPRError("SSL_ConfigSecureServer failed"); + return SECFailure; + } + + if (keaOut) { + *keaOut = certKEA; + } + } + + if (certOut) { + *certOut = std::move(cert); + } + + SSL_OptionSet(fd, SSL_NO_CACHE, false); + SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS, true); + + return SECSuccess; +} + +#ifdef XP_WIN +using PidType = DWORD; +constexpr bool IsValidPid(long long pid) { + // Excluding `(DWORD)-1` because it is not a valid process ID. + // See https://devblogs.microsoft.com/oldnewthing/20040223-00/?p=40503 + return pid > 0 && pid < std::numeric_limits<PidType>::max(); +} +#else +using PidType = pid_t; +constexpr bool IsValidPid(long long pid) { + return pid > 0 && pid <= std::numeric_limits<PidType>::max(); +} +#endif + +PidType ConvertPid(const char* pidStr) { + long long pid = strtoll(pidStr, nullptr, 10); + if (!IsValidPid(pid)) { + return 0; + } + return static_cast<PidType>(pid); +} + +int StartServer(int argc, char* argv[], SSLSNISocketConfig sniSocketConfig, + void* sniSocketConfigArg, ServerConfigFunc configFunc) { + if (argc != 3) { + fprintf(stderr, "usage: %s <NSS DB directory> <ppid>\n", argv[0]); + return 1; + } + const char* nssCertDBDir = argv[1]; + PidType ppid = ConvertPid(argv[2]); + + const char* debugLevel = PR_GetEnv("MOZ_TLS_SERVER_DEBUG_LEVEL"); + if (debugLevel) { + int level = atoi(debugLevel); + switch (level) { + case DEBUG_ERRORS: + gDebugLevel = DEBUG_ERRORS; + break; + case DEBUG_WARNINGS: + gDebugLevel = DEBUG_WARNINGS; + break; + case DEBUG_VERBOSE: + gDebugLevel = DEBUG_VERBOSE; + break; + default: + PrintPRError("invalid MOZ_TLS_SERVER_DEBUG_LEVEL"); + return 1; + } + } + + const char* callbackPort = PR_GetEnv("MOZ_TLS_SERVER_CALLBACK_PORT"); + if (callbackPort) { + gCallbackPort = atoi(callbackPort); + } + + if (InitializeNSS(nssCertDBDir) != SECSuccess) { + PR_fprintf(PR_STDERR, "InitializeNSS failed"); + return 1; + } + + if (NSS_SetDomesticPolicy() != SECSuccess) { + PrintPRError("NSS_SetDomesticPolicy failed"); + return 1; + } + + if (SSL_ConfigServerSessionIDCache(0, 0, 0, nullptr) != SECSuccess) { + PrintPRError("SSL_ConfigServerSessionIDCache failed"); + return 1; + } + + UniquePRFileDesc serverSocket(PR_NewTCPSocket()); + if (!serverSocket) { + PrintPRError("PR_NewTCPSocket failed"); + return 1; + } + + PRSocketOptionData socketOption; + socketOption.option = PR_SockOpt_Reuseaddr; + socketOption.value.reuse_addr = true; + PR_SetSocketOption(serverSocket.get(), &socketOption); + + PRNetAddr serverAddr; + PR_InitializeNetAddr(PR_IpAddrLoopback, LISTEN_PORT, &serverAddr); + if (PR_Bind(serverSocket.get(), &serverAddr) != PR_SUCCESS) { + PrintPRError("PR_Bind failed"); + return 1; + } + + if (PR_Listen(serverSocket.get(), 1) != PR_SUCCESS) { + PrintPRError("PR_Listen failed"); + return 1; + } + + UniquePRFileDesc rawModelSocket(PR_NewTCPSocket()); + if (!rawModelSocket) { + PrintPRError("PR_NewTCPSocket failed for rawModelSocket"); + return 1; + } + + UniquePRFileDesc modelSocket(SSL_ImportFD(nullptr, rawModelSocket.release())); + if (!modelSocket) { + PrintPRError("SSL_ImportFD of rawModelSocket failed"); + return 1; + } + + SSLVersionRange range = {0, 0}; + if (SSL_VersionRangeGet(modelSocket.get(), &range) != SECSuccess) { + PrintPRError("SSL_VersionRangeGet failed"); + return 1; + } + + if (range.max < SSL_LIBRARY_VERSION_TLS_1_3) { + range.max = SSL_LIBRARY_VERSION_TLS_1_3; + if (SSL_VersionRangeSet(modelSocket.get(), &range) != SECSuccess) { + PrintPRError("SSL_VersionRangeSet failed"); + return 1; + } + } + + if (SSL_SNISocketConfigHook(modelSocket.get(), sniSocketConfig, + sniSocketConfigArg) != SECSuccess) { + PrintPRError("SSL_SNISocketConfigHook failed"); + return 1; + } + + // We have to configure the server with a certificate, but it's not one + // we're actually going to end up using. In the SNI callback, we pick + // the right certificate for the connection. + // + // Provide an empty |extra_data| to force config via SSL_ConfigServerCert. + // This is a temporary mechanism to work around inconsistent setting of + // |authType| in the deprecated API (preventing the default cert from + // being removed in favor of the SNI-selected cert). This may be removed + // after Bug 1569222 removes the deprecated mechanism. + SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr, + nullptr, nullptr, nullptr}; + if (ConfigSecureServerWithNamedCert(modelSocket.get(), DEFAULT_CERT_NICKNAME, + nullptr, nullptr, + &extra_data) != SECSuccess) { + return 1; + } + + // Call back to implementation-defined configuration func, if provided. + if (configFunc) { + if (((configFunc)(modelSocket.get())) != SECSuccess) { + PrintPRError("configFunc failed"); + return 1; + } + } + + if (gCallbackPort != 0) { + if (DoCallback()) { + return 1; + } + } + + std::thread([ppid] { + if (!ppid) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "invalid ppid\n"); + } + return; + } +#ifdef XP_WIN + HANDLE parent = OpenProcess(SYNCHRONIZE, false, ppid); + if (!parent) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "OpenProcess failed\n"); + } + return; + } + WaitForSingleObject(parent, INFINITE); + CloseHandle(parent); +#else + while (getppid() == ppid) { + sleep(1); + } +#endif + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "Parent process crashed\n"); + } + exit(1); + }).detach(); + + while (true) { + PRNetAddr clientAddr; + PRFileDesc* clientSocket = + PR_Accept(serverSocket.get(), &clientAddr, PR_INTERVAL_NO_TIMEOUT); + HandleConnection(clientSocket, modelSocket); + } + + return 0; +} + +} // namespace test +} // namespace mozilla diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h new file mode 100644 index 0000000000..3927b3e541 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h @@ -0,0 +1,93 @@ +/* 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/. */ + +#ifndef TLSServer_h +#define TLSServer_h + +// This is a standalone server for testing SSL features of Gecko. +// The client is expected to connect and initiate an SSL handshake (with SNI +// to indicate which "server" to connect to). If all is good, the client then +// sends one encrypted byte and receives that same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include <stdint.h> + +#include "ScopedNSSTypes.h" +#include "mozilla/Casting.h" +#include "prio.h" +#include "secerr.h" +#include "ssl.h" + +namespace mozilla { + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePRDir, PRDir, PR_CloseDir); + +} // namespace mozilla + +namespace mozilla { +namespace test { + +typedef SECStatus (*ServerConfigFunc)(PRFileDesc* fd); + +enum DebugLevel { DEBUG_ERRORS = 1, DEBUG_WARNINGS = 2, DEBUG_VERBOSE = 3 }; + +extern DebugLevel gDebugLevel; + +void PrintPRError(const char* aPrefix); + +// The default certificate is trusted for localhost and *.example.com +extern const char DEFAULT_CERT_NICKNAME[]; + +// ConfigSecureServerWithNamedCert sets up the hostname name provided. If the +// extraData parameter is presented, extraData->certChain will be automatically +// filled in using database information. +// Pass DEFAULT_CERT_NICKNAME as certName unless you need a specific +// certificate. +SECStatus ConfigSecureServerWithNamedCert( + PRFileDesc* fd, const char* certName, + /*optional*/ UniqueCERTCertificate* cert, + /*optional*/ SSLKEAType* kea, + /*optional*/ SSLExtraServerCertData* extraData); + +SECStatus InitializeNSS(const char* nssCertDBDir); + +// StartServer initializes NSS, sockets, the SNI callback, and a default +// certificate. configFunc (optional) is a pointer to an implementation- +// defined configuration function, which is called on the model socket +// prior to handling any connections. +int StartServer(int argc, char* argv[], SSLSNISocketConfig sniSocketConfig, + void* sniSocketConfigArg, + ServerConfigFunc configFunc = nullptr); + +template <typename Host> +inline const Host* GetHostForSNI(const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, const Host* hosts) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + for (const Host* host = hosts; host->mHostName; ++host) { + SECItem hostName; + hostName.data = BitwiseCast<unsigned char*, const char*>(host->mHostName); + hostName.len = strlen(host->mHostName); + if (SECITEM_ItemsAreEqual(&hostName, &aSrvNameArr[i])) { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + return host; + } + } + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "could not find host info from SNI\n"); + } + + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return nullptr; +} + +} // namespace test +} // namespace mozilla + +#endif // TLSServer_h diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/moz.build b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build new file mode 100644 index 0000000000..1fd92d724d --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build @@ -0,0 +1,16 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES += [ + "OCSPCommon.cpp", + "TLSServer.cpp", +] + +USE_LIBS += [ + "mozpkix-testlib", +] + +Library("tlsserver") diff --git a/security/manager/ssl/tests/unit/tlsserver/moz.build b/security/manager/ssl/tests/unit/tlsserver/moz.build new file mode 100644 index 0000000000..1488352914 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/moz.build @@ -0,0 +1,8 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# lib must be first, because cmd depends on its output +DIRS += ["lib", "cmd"] diff --git a/security/manager/ssl/tests/unit/xpcshell-smartcards.ini b/security/manager/ssl/tests/unit/xpcshell-smartcards.ini new file mode 100644 index 0000000000..df3cfa1c87 --- /dev/null +++ b/security/manager/ssl/tests/unit/xpcshell-smartcards.ini @@ -0,0 +1,15 @@ +[DEFAULT] +head = head_psm.js +tail = +tags = psm +skip-if = toolkit == 'android' +support-files = + +[test_osclientcerts_module.js] +skip-if = (os != 'win' && os != 'mac') || processor == 'aarch64' +[test_pkcs11_module.js] +[test_pkcs11_moduleDB.js] +[test_pkcs11_safe_mode.js] +[test_pkcs11_slot.js] +[test_pkcs11_token.js] +[test_pkcs11_tokenDB.js] diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini new file mode 100644 index 0000000000..e80615104a --- /dev/null +++ b/security/manager/ssl/tests/unit/xpcshell.ini @@ -0,0 +1,237 @@ +[DEFAULT] +head = head_psm.js +tags = psm +firefox-appdir = browser +support-files = + bad_certs/** + ocsp_certs/** + test_baseline_requirements/** + test_broken_fips/** + test_cert_eku/** + test_cert_embedded_null/** + test_cert_isBuiltInRoot_reload/** + test_cert_keyUsage/** + test_cert_overrides_read_only/** + test_cert_sha1/** + test_cert_signatures/** + test_cert_storage_direct/** + test_cert_storage_preexisting/** + test_cert_storage_preexisting_crlite/** + test_cert_trust/** + test_cert_utf8/** + test_cert_version/** + test_certDB_import/** + test_content_signing/** + test_crlite_filters/** + test_ct/** + test_delegated_credentials/** + test_encrypted_client_hello/** + test_ev_certs/** + test_intermediate_basic_usage_constraints/** + test_intermediate_preloads/** + test_keysize/** + test_keysize_ev/** + test_missing_intermediate/** + test_name_constraints/** + test_ocsp_url/** + test_onecrl/** + test_sanctions/** + test_sdr_preexisting/** + test_sdr_preexisting_with_password/** + test_self_signed_certs/** + test_signed_apps/** + test_startcom_wosign/** + test_validity/** + tlsserver/** + +[test_add_preexisting_cert.js] +[test_baseline_requirements_subject_common_name.js] +[test_blocklist_onecrl.js] +# Skip signature tests for Thunderbird (Bug 1341983). +skip-if = appname == "thunderbird" +tags = remote-settings blocklist psm +[test_blocklist_pinning.js] +tags = remote-settings blocklist psm +[test_broken_fips.js] +# FIPS has never been a thing on Android, so the workaround doesn't +# exist on that platform. +# FIPS still works on Linux, so this test doesn't make any sense there. +# FIPS still works on Windows, but running the test to ensure that it does not +# break with a non-ASCII profile path. +skip-if = toolkit == 'android' || os == 'linux' +[test_cert_storage.js] +tags = addons psm blocklist +[test_cert_storage_broken_db.js] +[test_cert_storage_direct.js] +[test_cert_storage_preexisting.js] +[test_cert_storage_preexisting_crlite.js] +# This test cannot succeed on 32-bit platforms. See bugs 1546361 and 1548956. +skip-if = bits != 64 +[test_cert_storage_prefs.js] +[test_cert_chains.js] +run-sequentially = hardcoded ports +[test_cert_dbKey.js] +[test_cert_eku.js] +[test_cert_embedded_null.js] +[test_cert_expiration_canary.js] +run-if = nightly_build +[test_cert_keyUsage.js] +[test_cert_isBuiltInRoot.js] +[test_cert_isBuiltInRoot_reload.js] +[test_cert_overrides.js] +run-sequentially = hardcoded ports +[test_cert_overrides_read_only.js] +run-sequentially = hardcoded ports +[test_cert_override_bits_mismatches.js] +run-sequentially = hardcoded ports +[test_cert_sha1.js] +[test_cert_signatures.js] +[test_cert_trust.js] +[test_cert_version.js] +[test_cert_utf8.js] +[test_certDB_export_pkcs12.js] +[test_certDB_export_pkcs12_with_master_password.js] +[test_certDB_import.js] +# nsCertificateDialogs not available in geckoview, bug 1554276 +skip-if = toolkit == 'android' && processor == 'x86_64' +[test_certDB_import_pkcs12.js] +[test_certDB_import_with_master_password.js] +# nsCertificateDialogs not available in geckoview, bug 1554276 +skip-if = toolkit == 'android' && processor == 'x86_64' +[test_constructX509FromBase64.js] +[test_content_signing.js] +[test_crlite_filters.js] +tags = remote-settings psm +[test_ct.js] +# Requires hard-coded debug-only data +skip-if = !debug +run-sequentially = hardcoded ports +[test_db_format_pref_new.js] +# Android always has and always will use the new format, so +# this test doesn't apply. +skip-if = toolkit == 'android' +[test_delegated_credentials.js] +run-sequentially = hardcoded ports +[test_encrypted_client_hello.js] +run-sequentially = hardcoded ports +[test_encrypted_client_hello_client_only.js] +run-sequentially = hardcoded ports +[test_der.js] +[test_enterprise_roots.js] +# This feature is implemented for Windows and OS X. However, we don't currently +# have a way to test it on OS X. +skip-if = os != 'win' +[test_ev_certs.js] +tags = blocklist psm +run-sequentially = hardcoded ports +[test_forget_about_site_security_headers.js] +run-sequentially = hardcoded ports +[test_hash_algorithms.js] +[test_hash_algorithms_wrap.js] +# bug 1124289 - run_test_in_child violates the sandbox on android +skip-if = toolkit == 'android' +[test_hmac.js] +[test_intermediate_basic_usage_constraints.js] +[test_intermediate_preloads.js] +run-sequentially = hardcoded ports +tags = blocklist psm remote-settings +# Bug 1520297 - do something to handle tighter resource constraints on Android +skip-if = toolkit == 'android' +[test_imminent_distrust.js] +run-sequentially = hardcoded ports +[test_allow_all_cert_errors.js] +run-sequentially = hardcoded ports +[test_keysize.js] +[test_keysize_ev.js] +run-sequentially = hardcoded ports +[test_local_cert.js] +[test_logoutAndTeardown.js] +skip-if = socketprocess_networking +run-sequentially = hardcoded ports +[test_missing_intermediate.js] +run-sequentially = hardcoded ports +[test_name_constraints.js] +[test_nonascii_path.js] +[test_nsCertType.js] +run-sequentially = hardcoded ports +[test_nsIX509Cert_utf8.js] +[test_nsIX509CertValidity.js] +[test_nss_shutdown.js] +[test_ocsp_caching.js] +run-sequentially = hardcoded ports +[test_ocsp_enabled_pref.js] +run-sequentially = hardcoded ports +[test_ocsp_must_staple.js] +run-sequentially = hardcoded ports +[test_ocsp_private_caching.js] +run-sequentially = hardcoded ports +[test_ocsp_no_hsts_upgrade.js] +run-sequentially = hardcoded ports +[test_ocsp_required.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling_expired.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling_with_intermediate.js] +run-sequentially = hardcoded ports +[test_ocsp_timeout.js] +run-sequentially = hardcoded ports +[test_ocsp_url.js] +run-sequentially = hardcoded ports +[test_oskeystore.js] +[test_osreauthenticator.js] +# Reauthentication has been implemented on Windows and MacOS, so running this +# test results in the OS popping up a dialog, which means we can't run it in +# automation. +skip-if = os == 'win' || os == 'mac' +[test_password_prompt.js] +[test_pinning.js] +run-sequentially = hardcoded ports +[test_sdr.js] +[test_sdr_preexisting.js] +# Not relevant to Android. See the comment in the test. +skip-if = toolkit == 'android' +[test_sdr_preexisting_with_password.js] +# Not relevant to Android. See the comment in the test. +skip-if = toolkit == 'android' +[test_self_signed_certs.js] +[test_session_resumption.js] +skip-if = ccov && webrender && os == "win" # Bug 1585916 +run-sequentially = hardcoded ports +[test_signed_apps.js] +[test_ssl_status.js] +run-sequentially = hardcoded ports +[test_sss_enumerate.js] +run-sequentially = hardcoded ports +[test_sss_eviction.js] +[test_sss_originAttributes.js] +run-sequentially = hardcoded ports +[test_sss_readstate.js] +[test_sss_readstate_child.js] +support-files = sss_readstate_child_worker.js +# bug 1124289 - run_test_in_child violates the sandbox on android +skip-if = toolkit == 'android' +[test_sss_readstate_empty.js] +[test_sss_readstate_garbage.js] +[test_sss_readstate_huge.js] +[test_sss_resetState.js] +run-sequentially = hardcoded ports +[test_sss_savestate.js] +[test_sss_sanitizeOnShutdown.js] +firefox-appdir = browser +# Sanitization works differently on Android - this doesn't apply. +# browser/modules/Sanitizer.jsm used by the test isn't available in Thunderbird. +skip-if = toolkit == 'android' || appname == 'thunderbird' +[test_startcom_wosign.js] +[test_sts_fqdn.js] +[test_sts_ipv4_ipv6.js] +[test_sts_parser.js] +[test_sts_preload_dynamic.js] +[test_sts_preloadlist_perwindowpb.js] +[test_sts_preloadlist_selfdestruct.js] +[test_sanctions_symantec_apple_google.js] +run-sequentially = hardcoded ports +[test_validity.js] +run-sequentially = hardcoded ports +[test_x509.js] |