зеркало из https://github.com/mozilla/gecko-dev.git
bug 1228175 - fix IsCertBuiltInRoot r=Cykesiopka,mgoodwin
When a built-in root certificate has its trust changed from the default value, the platform has to essentially create a copy of it in the read/write certificate database with the new trust settings. At that point, the desired behavior is that the platform still considers that certificate a built-in root. Before this patch, this would indeed happen for the duration of that run of the platform, but as soon as it restarted, the certificate in question would only appear to be from the read/write database, and thus was not considered a built-in root. This patch changes the test of built-in-ness to explicitly search the built-in certificate slot for the certificate in question. If found, it is considered a built-in root. MozReview-Commit-ID: HCtZpPQVEGZ --HG-- extra : rebase_source : 898ef37459723f1d8479cfdc58658ccb00e782a9
This commit is contained in:
Родитель
bf4428afdd
Коммит
f228ba40a1
|
@ -330,6 +330,7 @@ PK11_ExportDERPrivateKeyInfo
|
|||
PK11_ExportEncryptedPrivKeyInfo
|
||||
PK11_ExtractKeyValue
|
||||
PK11_FindCertFromNickname
|
||||
PK11_FindCertInSlot
|
||||
PK11_FindCertsFromEmailAddress
|
||||
PK11_FindCertsFromNickname
|
||||
PK11_FindKeyByAnyCert
|
||||
|
@ -548,6 +549,7 @@ SECMOD_DeleteInternalModule
|
|||
SECMOD_DeleteModule
|
||||
SECMOD_DestroyModule
|
||||
SECMOD_FindModule
|
||||
SECMOD_FindSlot
|
||||
SECMOD_GetDeadModuleList
|
||||
SECMOD_GetDefaultModuleList
|
||||
SECMOD_GetDefaultModuleListLock
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "NSSErrorsService.h"
|
||||
#include "cert.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "pk11pub.h"
|
||||
#include "pkix/pkix.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
#include "prerror.h"
|
||||
#include "secerr.h"
|
||||
#include "secmod.h"
|
||||
#include "sslerr.h"
|
||||
|
||||
using namespace mozilla::pkix;
|
||||
|
@ -71,35 +74,43 @@ IsCertChainRootBuiltInRoot(CERTCertList* chain, bool& result)
|
|||
if (!root) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
SECStatus srv = IsCertBuiltInRoot(root, result);
|
||||
if (srv != SECSuccess) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
return Success;
|
||||
return IsCertBuiltInRoot(root, result);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
Result
|
||||
IsCertBuiltInRoot(CERTCertificate* cert, bool& result)
|
||||
{
|
||||
result = false;
|
||||
UniquePK11SlotList slots(PK11_GetAllSlotsForCert(cert, nullptr));
|
||||
if (!slots) {
|
||||
if (PORT_GetError() == SEC_ERROR_NO_TOKEN) {
|
||||
// no list
|
||||
return SECSuccess;
|
||||
}
|
||||
return SECFailure;
|
||||
nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
|
||||
if (!component) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
for (PK11SlotListElement* le = slots->head; le; le = le->next) {
|
||||
char* token = PK11_GetTokenName(le->slot);
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
|
||||
("BuiltInRoot? subject=%s token=%s",cert->subjectName, token));
|
||||
if (strcmp("Builtin Object Token", token) == 0) {
|
||||
result = true;
|
||||
return SECSuccess;
|
||||
}
|
||||
nsAutoString modName;
|
||||
nsresult rv = component->GetPIPNSSBundleString("RootCertModuleName", modName);
|
||||
if (NS_FAILED(rv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
return SECSuccess;
|
||||
NS_ConvertUTF16toUTF8 modNameUTF8(modName);
|
||||
UniqueSECMODModule builtinRootsModule(SECMOD_FindModule(modNameUTF8.get()));
|
||||
// If the built-in roots module isn't loaded, nothing is a built-in root.
|
||||
if (!builtinRootsModule) {
|
||||
return Success;
|
||||
}
|
||||
UniquePK11SlotInfo builtinSlot(SECMOD_FindSlot(builtinRootsModule.get(),
|
||||
"Builtin Object Token"));
|
||||
// This could happen if the user loaded a module that is acting like the
|
||||
// built-in roots module but doesn't actually have a slot called "Builtin
|
||||
// Object Token". In that case, again nothing is a built-in root.
|
||||
if (!builtinSlot) {
|
||||
return Success;
|
||||
}
|
||||
// Attempt to find a copy of the given certificate in the "Builtin Object
|
||||
// Token" slot of the built-in root module. If we get a valid handle, this
|
||||
// certificate exists in the root module, so we consider it a built-in root.
|
||||
CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(builtinSlot.get(), cert,
|
||||
nullptr);
|
||||
result = (handle != CK_INVALID_HANDLE);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static Result
|
||||
|
|
|
@ -144,7 +144,7 @@ private:
|
|||
};
|
||||
|
||||
void InitCertVerifierLog();
|
||||
SECStatus IsCertBuiltInRoot(CERTCertificate* cert, bool& result);
|
||||
mozilla::pkix::Result IsCertBuiltInRoot(CERTCertificate* cert, bool& result);
|
||||
mozilla::pkix::Result CertListContainsExpectedKeys(
|
||||
const CERTCertList* certList, const char* hostname, mozilla::pkix::Time time,
|
||||
CertVerifier::PinningMode pinningMode);
|
||||
|
|
|
@ -780,9 +780,9 @@ NSSCertDBTrustDomain::IsChainValid(const DERArray& certArray, Time time)
|
|||
}
|
||||
|
||||
bool isBuiltInRoot = false;
|
||||
srv = IsCertBuiltInRoot(root, isBuiltInRoot);
|
||||
if (srv != SECSuccess) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
Result rv = IsCertBuiltInRoot(root, isBuiltInRoot);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
bool skipPinningChecksBecauseOfMITMMode =
|
||||
(!isBuiltInRoot && mPinningMode == CertVerifier::pinningAllowUserCAMITM);
|
||||
|
|
|
@ -901,16 +901,16 @@ GatherBaselineRequirementsTelemetry(const ScopedCERTCertList& certList)
|
|||
return;
|
||||
}
|
||||
bool isBuiltIn = false;
|
||||
SECStatus rv = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (rv != SECSuccess || !isBuiltIn) {
|
||||
Result result = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (result != Success || !isBuiltIn) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: root certificate for '%s' is not a built-in root "
|
||||
"(or IsCertBuiltInRoot failed)\n", commonName.get()));
|
||||
return;
|
||||
}
|
||||
SECItem altNameExtension;
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
|
||||
&altNameExtension);
|
||||
SECStatus rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
|
||||
&altNameExtension);
|
||||
if (rv != SECSuccess) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: no subject alt names extension for '%s'\n",
|
||||
|
@ -1064,8 +1064,8 @@ GatherEKUTelemetry(const ScopedCERTCertList& certList)
|
|||
return;
|
||||
}
|
||||
bool isBuiltIn = false;
|
||||
SECStatus rv = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (rv != SECSuccess || !isBuiltIn) {
|
||||
Result rv = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (rv != Success || !isBuiltIn) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@ interface nsIX509Cert : nsISupports {
|
|||
*/
|
||||
readonly attribute AString emailAddress;
|
||||
|
||||
/**
|
||||
* Did this certificate ship with the platform as a built-in root?
|
||||
*/
|
||||
readonly attribute bool isBuiltInRoot;
|
||||
|
||||
/**
|
||||
* Obtain a list of all email addresses
|
||||
* contained in the certificate.
|
||||
|
|
|
@ -220,6 +220,22 @@ nsNSSCertificate::GetIsSelfSigned(bool* aIsSelfSigned)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetIsBuiltInRoot(bool* aIsBuiltInRoot)
|
||||
{
|
||||
NS_ENSURE_ARG(aIsBuiltInRoot);
|
||||
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
Result rv = IsCertBuiltInRoot(mCert, *aIsBuiltInRoot);
|
||||
if (rv != Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSCertificate::MarkForPermDeletion()
|
||||
{
|
||||
|
|
|
@ -348,6 +348,13 @@ nsNSSCertificateFakeTransport::GetIsSelfSigned(bool*)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificateFakeTransport::GetIsBuiltInRoot(bool* aIsBuiltInRoot)
|
||||
{
|
||||
NS_NOTREACHED("Unimplemented on content process");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificateFakeTransport::RequestUsagesArrayAsync(
|
||||
nsICertVerificationListener*)
|
||||
|
|
|
@ -724,8 +724,8 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
bool isBuiltIn = false;
|
||||
SECStatus srv = IsCertBuiltInRoot(rootNode->cert, isBuiltIn);
|
||||
if (srv != SECSuccess) {
|
||||
mozilla::pkix::Result result = IsCertBuiltInRoot(rootNode->cert, isBuiltIn);
|
||||
if (result != mozilla::pkix::Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "TestHarness.h"
|
||||
#include "cert.h"
|
||||
#include "certdb.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsIX509CertList.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nss.h"
|
||||
#include "prerror.h"
|
||||
#include "secerr.h"
|
||||
|
||||
// This is a certificate that (currently) ships with the platform. This test
|
||||
// loads this certificate into the read/write certificate database, which
|
||||
// simulates the situation where a built-in certificate's trust settings have
|
||||
// been changed. It should still be considered a built-in root.
|
||||
static char sGeoTrustPEM[] = "-----BEGIN CERTIFICATE-----\n\
|
||||
MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL\n\
|
||||
MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj\n\
|
||||
KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2\n\
|
||||
MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\n\
|
||||
eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV\n\
|
||||
BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw\n\
|
||||
NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV\n\
|
||||
BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH\n\
|
||||
MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL\n\
|
||||
So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal\n\
|
||||
tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\n\
|
||||
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG\n\
|
||||
CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT\n\
|
||||
qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz\n\
|
||||
rD6ogRLQy7rQkgu2npaqBA+K\n\
|
||||
-----END CERTIFICATE-----";
|
||||
|
||||
static char sGeoTrustNickname[] =
|
||||
"GeoTrust Primary Certification Authority - G2";
|
||||
|
||||
static char sGeoTrustCertDBKey[] = "AAAAAAAAAAAAAAAQAAAAmzyy9EgK\n\
|
||||
AOL+6yQ7XmA+w2swgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ\n\
|
||||
bmMuMTkwNwYDVQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhv\n\
|
||||
cml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlm\n\
|
||||
aWNhdGlvbiBBdXRob3JpdHkgLSBHMg==";
|
||||
|
||||
// This is the DB key (see nsIX509Cert.idl) of another built-in certificate.
|
||||
// This test makes no changes to its trust settings. It should be considered a
|
||||
// built-in root.
|
||||
static char sVeriSignCertDBKey[] = "AAAAAAAAAAAAAAAQAAAAzS+A/iOM\n\
|
||||
DiIPSGcSKJGHrLMwgcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwg\n\
|
||||
SW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMx\n\
|
||||
KGMpIDIwMDcgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s\n\
|
||||
eTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0\n\
|
||||
aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0";
|
||||
|
||||
// This is a certificate that does not ship with the platform.
|
||||
// It should not be considered a built-in root.
|
||||
static char sLetsEncryptPEM[] = "-----BEGIN CERTIFICATE-----\n\
|
||||
MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw\n\
|
||||
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\n\
|
||||
Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa\n\
|
||||
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD\n\
|
||||
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD\n\
|
||||
ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB\n\
|
||||
BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg\n\
|
||||
PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG\n\
|
||||
dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1\n\
|
||||
gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4\n\
|
||||
4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud\n\
|
||||
EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy\n\
|
||||
BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j\n\
|
||||
b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv\n\
|
||||
ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ\n\
|
||||
MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH\n\
|
||||
AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw\n\
|
||||
MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM\n\
|
||||
LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3\n\
|
||||
pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd\n\
|
||||
v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd\n\
|
||||
ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW\n\
|
||||
ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk\n\
|
||||
6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj\n\
|
||||
f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=\n\
|
||||
-----END CERTIFICATE-----";
|
||||
|
||||
static char sLetsEncryptNickname[] = "Let's Encrypt Authority X1";
|
||||
|
||||
static char sLetsEncryptCertDBKey[] = "AAAAAAAAAAAAAAARAAAAQQCYE\n\
|
||||
/R1E+V1C0PnQx6XHkS9MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRyd\n\
|
||||
XN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=";
|
||||
|
||||
static SECItem* sCertDER = nullptr;
|
||||
|
||||
static SECStatus
|
||||
GetCertDER(void*, SECItem** certs, int numcerts)
|
||||
{
|
||||
if (numcerts != 1) {
|
||||
fail("numcerts should be 1");
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
sCertDER = SECITEM_DupItem(certs[0]);
|
||||
if (!sCertDER) {
|
||||
fail("failed to copy data out (out of memory?)");
|
||||
PR_SetError(SEC_ERROR_NO_MEMORY, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
passed("GetCertDER succeeded");
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
bool
|
||||
AddCertificate(char* pem, char* nickname)
|
||||
{
|
||||
if (CERT_DecodeCertPackage(pem, strlen(pem), GetCertDER, nullptr)
|
||||
!= SECSuccess) {
|
||||
fail("CERT_DecodeCertPackage failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sCertDER) {
|
||||
fail("sCertDER didn't get set as expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
mozilla::ScopedCERTCertificate cert(
|
||||
CERT_NewTempCertificate(CERT_GetDefaultCertDB(), sCertDER, nickname, false,
|
||||
true));
|
||||
if (!cert) {
|
||||
fail("CERT_NewTempCertificate failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
CERTCertTrust trust;
|
||||
trust.sslFlags = 0;
|
||||
trust.emailFlags = 0;
|
||||
trust.objectSigningFlags = 0;
|
||||
if (CERT_AddTempCertToPerm(cert, nickname, &trust) != SECSuccess) {
|
||||
fail("CERT_AddTempCertToPerm failed");
|
||||
return false;
|
||||
}
|
||||
passed("AddCertificate succeeded");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PreloadNSSCertDB(const char* profilePath)
|
||||
{
|
||||
if (NSS_IsInitialized()) {
|
||||
fail("NSS shouldn't already be initialized, or part of this test is moot");
|
||||
return false;
|
||||
}
|
||||
if (NSS_Initialize(profilePath, "", "", SECMOD_DB, 0) != SECSuccess) {
|
||||
fail("couldn't initialize NSS the first time");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddCertificate(sGeoTrustPEM, sGeoTrustNickname)) {
|
||||
fail("couldn't add GeoTrust certificate to NSS");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddCertificate(sLetsEncryptPEM, sLetsEncryptNickname)) {
|
||||
fail("couldn't add Let's Encrypt certificate to NSS");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NSS_Shutdown() != SECSuccess) {
|
||||
fail("couldn't shut down NSS the first time");
|
||||
return false;
|
||||
}
|
||||
passed("PreloadNSSCertDB succeeded");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestIsCertBuiltIn(const char* certDBKey, bool expectedIsBuiltIn)
|
||||
{
|
||||
nsCOMPtr<nsIX509CertDB> certDB(do_GetService(NS_X509CERTDB_CONTRACTID));
|
||||
if (!certDB) {
|
||||
fail("couldn't get certDB");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
if (NS_FAILED(certDB->FindCertByDBKey(certDBKey, getter_AddRefs(cert)))) {
|
||||
fail("couldn't find root certificate in database (maybe it was removed?)");
|
||||
return false;
|
||||
}
|
||||
if (!cert) {
|
||||
fail("FindCertByDBKey says it succeeded but it clearly didn't");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isBuiltInRoot;
|
||||
if (NS_FAILED(cert->GetIsBuiltInRoot(&isBuiltInRoot))) {
|
||||
fail("couldn't determine if the certificate was a built-in or not");
|
||||
return false;
|
||||
}
|
||||
if (isBuiltInRoot != expectedIsBuiltIn) {
|
||||
fail("did not get expected value for isBuiltInRoot");
|
||||
return false;
|
||||
}
|
||||
passed("got expected value for isBuiltInRoot");
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
ScopedXPCOM xpcom("TestIsCertBuiltInRoot");
|
||||
if (xpcom.failed()) {
|
||||
fail("couldn't initialize XPCOM");
|
||||
return 1;
|
||||
}
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (!prefs) {
|
||||
fail("couldn't get pref service");
|
||||
return 1;
|
||||
}
|
||||
nsCOMPtr<nsIFile> profileDirectory(xpcom.GetProfileDirectory());
|
||||
if (!profileDirectory) {
|
||||
fail("couldn't get profile directory");
|
||||
return 1;
|
||||
}
|
||||
nsAutoCString profilePath;
|
||||
if (NS_FAILED(profileDirectory->GetNativePath(profilePath))) {
|
||||
fail("couldn't get profile path");
|
||||
return 1;
|
||||
}
|
||||
// One of the cases we want to test is when (in a previous run of the
|
||||
// platform) a built-in root certificate has had its trust modified from the
|
||||
// defaults. We can't initialize XPCOM twice in this test, but we can use NSS
|
||||
// directly to create a certficate database (before instantiating any XPCOM
|
||||
// objects that rely on NSS and thus would initialize it) with the appropriate
|
||||
// certificates for these tests.
|
||||
if (!PreloadNSSCertDB(profilePath.get())) {
|
||||
fail("couldn't set up NSS certificate DB for test");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!TestIsCertBuiltIn(sVeriSignCertDBKey, true)) {
|
||||
fail("built-in root with no modified trust should be considered built-in");
|
||||
} else {
|
||||
passed("built-in root with no modified trust considered built-in");
|
||||
}
|
||||
|
||||
if (!TestIsCertBuiltIn(sGeoTrustCertDBKey, true)) {
|
||||
fail("built-in root with modified trust should be considered built-in");
|
||||
} else {
|
||||
passed("built-in root with modified trust considered built-in");
|
||||
}
|
||||
|
||||
if (!TestIsCertBuiltIn(sLetsEncryptCertDBKey, false)) {
|
||||
fail("non-built-in root should not be considered built-in");
|
||||
} else {
|
||||
passed("non-built-in root should not considered built-in");
|
||||
}
|
||||
|
||||
return gFailCount;
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
CppUnitTests([
|
||||
'TestIsCertBuiltInRoot',
|
||||
'TestSTSParser',
|
||||
])
|
||||
|
||||
|
@ -16,3 +17,7 @@ GeckoCppUnitTests([
|
|||
'TestCertDB',
|
||||
'TestMD4',
|
||||
])
|
||||
|
||||
USE_LIBS += [
|
||||
'nss',
|
||||
]
|
||||
|
|
|
@ -41,6 +41,7 @@ skip-if = os != 'win'
|
|||
[TestInitializerList]
|
||||
[TestIntegerPrintfMacros]
|
||||
[TestIntegerRange]
|
||||
[TestIsCertBuiltInRoot]
|
||||
[TestJSONWriter]
|
||||
[TestJemalloc]
|
||||
[TestLineBreak]
|
||||
|
|
Загрузка…
Ссылка в новой задаче