зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. CLOSED TREE
This commit is contained in:
Коммит
3a214de2f6
|
@ -330,7 +330,12 @@ mozilla::ipc::IPCResult SocketProcessParent::RecvGetTLSClientCert(
|
|||
|
||||
RefPtr<nsIX509Cert> clientCert;
|
||||
if (aClientCert) {
|
||||
clientCert = new nsNSSCertificate(std::move(aClientCert->data()));
|
||||
clientCert = nsNSSCertificate::ConstructFromDER(
|
||||
BitwiseCast<char*, uint8_t*>(aClientCert->data().Elements()),
|
||||
aClientCert->data().Length());
|
||||
if (!clientCert) {
|
||||
return IPC_OK();
|
||||
}
|
||||
}
|
||||
|
||||
ClientAuthInfo info(aHostName, aOriginAttributes, aPort, aProviderFlags,
|
||||
|
|
|
@ -1322,18 +1322,28 @@ nsresult OpenSignedAppFile(AppTrustedRoot aTrustedRoot, nsIFile* aJarFile,
|
|||
if (aSignerCert) {
|
||||
// The COSE certificate is authoritative.
|
||||
if (aPolicy.COSERequired() || !coseCertDER.IsEmpty()) {
|
||||
if (coseCertDER.IsEmpty()) {
|
||||
if (coseCertDER.IsEmpty() ||
|
||||
coseCertDER.Length() > std::numeric_limits<int>::max()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> signerCert(nsNSSCertificate::ConstructFromDER(
|
||||
reinterpret_cast<char*>(coseCertDER.Elements()),
|
||||
coseCertDER.Length()));
|
||||
if (!signerCert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> signerCert(
|
||||
new nsNSSCertificate(std::move(coseCertDER)));
|
||||
signerCert.forget(aSignerCert);
|
||||
} else {
|
||||
if (pkcs7CertDER.IsEmpty()) {
|
||||
if (pkcs7CertDER.IsEmpty() ||
|
||||
pkcs7CertDER.Length() > std::numeric_limits<int>::max()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> signerCert(nsNSSCertificate::ConstructFromDER(
|
||||
reinterpret_cast<char*>(pkcs7CertDER.Elements()),
|
||||
pkcs7CertDER.Length()));
|
||||
if (!signerCert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> signerCert(
|
||||
new nsNSSCertificate(std::move(pkcs7CertDER)));
|
||||
signerCert.forget(aSignerCert);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,8 +242,16 @@ void CommonSocketControl::RebuildCertificateInfoFromSSLTokenCache() {
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsNSSCertificate> nssc =
|
||||
new nsNSSCertificate(std::move(info.mServerCertBytes));
|
||||
RefPtr<nsNSSCertificate> nssc = nsNSSCertificate::ConstructFromDER(
|
||||
BitwiseCast<char*, uint8_t*>(info.mServerCertBytes.Elements()),
|
||||
info.mServerCertBytes.Length());
|
||||
if (!nssc) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("RebuildCertificateInfoFromSSLTokenCache failed to construct "
|
||||
"server cert"));
|
||||
return;
|
||||
}
|
||||
|
||||
SetServerCert(nssc, info.mEVStatus);
|
||||
SetCertificateTransparencyStatus(info.mCertificateTransparencyStatus);
|
||||
if (info.mSucceededCertChainBytes) {
|
||||
|
|
|
@ -268,7 +268,7 @@ class LocalCertGetTask final : public LocalCertTask {
|
|||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCert = new nsNSSCertificate(cert.get());
|
||||
mCert = nsNSSCertificate::Create(cert.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -948,7 +948,11 @@ PRErrorCode AuthCertificateParseResults(
|
|||
if (overrideService) {
|
||||
bool haveOverride;
|
||||
bool isTemporaryOverride; // we don't care
|
||||
RefPtr<nsIX509Cert> nssCert(new nsNSSCertificate(aCert.get()));
|
||||
RefPtr<nsIX509Cert> nssCert(nsNSSCertificate::Create(aCert.get()));
|
||||
if (!nssCert) {
|
||||
MOZ_ASSERT(false, "nsNSSCertificate::Create failed");
|
||||
return SEC_ERROR_NO_MEMORY;
|
||||
}
|
||||
nsresult rv = overrideService->HasMatchingOverride(
|
||||
aHostName, aPort, aOriginAttributes, nssCert, &overrideBits,
|
||||
&isTemporaryOverride, &haveOverride);
|
||||
|
@ -1086,7 +1090,7 @@ SSLServerCertVerificationJob::Run() {
|
|||
mProviderFlags, mTime, mCertVerifierFlags, builtChainBytesArray, evStatus,
|
||||
certificateTransparencyInfo, isCertChainRootBuiltInRoot);
|
||||
|
||||
RefPtr<nsNSSCertificate> nsc = new nsNSSCertificate(mCert.get());
|
||||
RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
|
||||
if (rv == Success) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX, jobStartTime,
|
||||
|
|
|
@ -985,7 +985,11 @@ static nsresult CreateCertChain(nsTArray<RefPtr<nsIX509Cert>>& aOutput,
|
|||
nsTArray<nsTArray<uint8_t>> certList = std::move(aCertList);
|
||||
aOutput.Clear();
|
||||
for (auto& certBytes : certList) {
|
||||
RefPtr<nsIX509Cert> cert = new nsNSSCertificate(std::move(certBytes));
|
||||
RefPtr<nsIX509Cert> cert = nsNSSCertificate::ConstructFromDER(
|
||||
BitwiseCast<char*, uint8_t*>(certBytes.Elements()), certBytes.Length());
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aOutput.AppendElement(cert);
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -35,7 +35,7 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
|
|||
("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess",
|
||||
this));
|
||||
|
||||
RefPtr<nsNSSCertificate> nsc = new nsNSSCertificate(mCert.get());
|
||||
RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
|
||||
nsTArray<nsTArray<uint8_t>> certBytesArray;
|
||||
for (auto& cert : aBuiltCertChain) {
|
||||
certBytesArray.AppendElement(std::move(cert.data()));
|
||||
|
@ -56,7 +56,7 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure(
|
|||
"aCollectedErrors=%u",
|
||||
this, aFinalError, aCollectedErrors));
|
||||
|
||||
RefPtr<nsNSSCertificate> nsc = new nsNSSCertificate(mCert.get());
|
||||
RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
|
||||
mResultTask->Dispatch(
|
||||
nsc, nsTArray<nsTArray<uint8_t>>(), std::move(mPeerCertChain),
|
||||
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
|
||||
|
|
|
@ -237,9 +237,15 @@ nsresult CheckForPreferredCertificate(const nsACString& aHostName,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> derArray(::CFDataGetBytePtr(der.get()),
|
||||
::CFDataGetLength(der.get()));
|
||||
nsCOMPtr<nsIX509Cert> cert(new nsNSSCertificate(std::move(derArray)));
|
||||
nsCOMPtr<nsIX509Cert> cert(nsNSSCertificate::ConstructFromDER(
|
||||
// ConstructFromDER is not const-correct so we have to cast away the
|
||||
// const.
|
||||
const_cast<char*>(
|
||||
reinterpret_cast<const char*>(::CFDataGetBytePtr(der.get()))),
|
||||
::CFDataGetLength(der.get())));
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return cert->GetDbKey(aCertDBKey);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1107,7 +1107,7 @@ static void RebuildVerifiedCertificateInformation(PRFileDesc* fd,
|
|||
("HandshakeCallback: couldn't rebuild verified certificate info"));
|
||||
}
|
||||
|
||||
RefPtr<nsNSSCertificate> nssc(new nsNSSCertificate(cert.get()));
|
||||
RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));
|
||||
if (rv == Success && evStatus == EVStatus::EV) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("HandshakeCallback using NEW cert %p (is EV)", nssc.get()));
|
||||
|
|
|
@ -63,35 +63,59 @@ extern LazyLogModule gPIPNSSLog;
|
|||
|
||||
NS_IMPL_ISUPPORTS(nsNSSCertificate, nsIX509Cert, nsISerializable, nsIClassInfo)
|
||||
|
||||
nsNSSCertificate::nsNSSCertificate()
|
||||
: mCert(Nothing()), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {}
|
||||
/*static*/
|
||||
nsNSSCertificate* nsNSSCertificate::Create(CERTCertificate* cert) {
|
||||
if (cert)
|
||||
return new nsNSSCertificate(cert);
|
||||
else
|
||||
return new nsNSSCertificate();
|
||||
}
|
||||
|
||||
nsNSSCertificate* nsNSSCertificate::ConstructFromDER(char* certDER,
|
||||
int derLen) {
|
||||
nsNSSCertificate* newObject = nsNSSCertificate::Create();
|
||||
if (newObject && !newObject->InitFromDER(certDER, derLen)) {
|
||||
delete newObject;
|
||||
newObject = nullptr;
|
||||
}
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
bool nsNSSCertificate::InitFromDER(char* certDER, int derLen) {
|
||||
if (!certDER || !derLen) return false;
|
||||
|
||||
CERTCertificate* aCert = CERT_DecodeCertFromPackage(certDER, derLen);
|
||||
|
||||
if (!aCert) {
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
MOZ_CRASH_UNSAFE_PRINTF("CERT_DecodeCertFromPackage failed in child: %d",
|
||||
PR_GetError());
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aCert->dbhandle) {
|
||||
aCert->dbhandle = CERT_GetDefaultCertDB();
|
||||
}
|
||||
|
||||
mCert.reset(aCert);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert)
|
||||
: mCert(Nothing()), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {
|
||||
: mCert(nullptr), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {
|
||||
if (cert) {
|
||||
mDER.AppendElements(cert->derCert.data, cert->derCert.len);
|
||||
mCert.emplace(UniqueCERTCertificate(CERT_DupCertificate(cert)));
|
||||
mCert.reset(CERT_DupCertificate(cert));
|
||||
}
|
||||
}
|
||||
|
||||
nsNSSCertificate::nsNSSCertificate(nsTArray<uint8_t>&& der)
|
||||
: mDER(std::move(der)),
|
||||
mCert(Nothing()),
|
||||
mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {}
|
||||
nsNSSCertificate::nsNSSCertificate()
|
||||
: mCert(nullptr), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {}
|
||||
|
||||
nsresult nsNSSCertificate::InstantiateCert() {
|
||||
SECItem derItem = {siBuffer, mDER.Elements(),
|
||||
static_cast<unsigned int>(mDER.Length())};
|
||||
UniqueCERTCertificate cert(CERT_NewTempCertificate(
|
||||
CERT_GetDefaultCertDB(), &derItem, nullptr, false, true));
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCert.emplace(std::move(cert));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static uint32_t getCertType(UniqueCERTCertificate& cert) {
|
||||
static uint32_t getCertType(CERTCertificate* cert) {
|
||||
nsNSSCertTrust trust(cert->trust);
|
||||
if (cert->nickname && trust.HasAnyUser()) {
|
||||
return nsIX509Cert::USER_CERT;
|
||||
|
@ -105,7 +129,7 @@ static uint32_t getCertType(UniqueCERTCertificate& cert) {
|
|||
if (trust.HasPeer(false, true) && cert->emailAddr) {
|
||||
return nsIX509Cert::EMAIL_CERT;
|
||||
}
|
||||
if (CERT_IsCACert(cert.get(), nullptr)) {
|
||||
if (CERT_IsCACert(cert, nullptr)) {
|
||||
return nsIX509Cert::CA_CERT;
|
||||
}
|
||||
if (cert->emailAddr) {
|
||||
|
@ -117,13 +141,7 @@ static uint32_t getCertType(UniqueCERTCertificate& cert) {
|
|||
nsresult nsNSSCertificate::GetCertType(uint32_t* aCertType) {
|
||||
if (mCertType == CERT_TYPE_NOT_YET_INITIALIZED) {
|
||||
// only determine cert type once and cache it
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
mCertType = getCertType(*mCert);
|
||||
mCertType = getCertType(mCert.get());
|
||||
}
|
||||
*aCertType = mCertType;
|
||||
return NS_OK;
|
||||
|
@ -134,7 +152,7 @@ nsNSSCertificate::GetIsBuiltInRoot(bool* aIsBuiltInRoot) {
|
|||
NS_ENSURE_ARG(aIsBuiltInRoot);
|
||||
|
||||
pkix::Input certInput;
|
||||
pkix::Result rv = certInput.Init(mDER.Elements(), mDER.Length());
|
||||
pkix::Result rv = certInput.Init(mCert->derCert.data, mCert->derCert.len);
|
||||
if (rv != pkix::Result::Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -151,7 +169,7 @@ nsNSSCertificate::GetDbKey(nsACString& aDbKey) {
|
|||
static_assert(sizeof(uint32_t) == 4, "type size consistency check");
|
||||
|
||||
pkix::Input certInput;
|
||||
pkix::Result result = certInput.Init(mDER.Elements(), mDER.Length());
|
||||
pkix::Result result = certInput.Init(mCert->derCert.data, mCert->derCert.len);
|
||||
if (result != pkix::Result::Success) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
@ -195,17 +213,14 @@ NS_IMETHODIMP
|
|||
nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) {
|
||||
aDisplayName.Truncate();
|
||||
|
||||
MOZ_ASSERT(mCert, "mCert should not be null in GetDisplayName");
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UniquePORTString commonName(CERT_GetCommonName(&(*mCert)->subject));
|
||||
UniquePORTString organizationalUnitName(
|
||||
CERT_GetOrgUnitName(&(*mCert)->subject));
|
||||
UniquePORTString organizationName(CERT_GetOrgName(&(*mCert)->subject));
|
||||
UniquePORTString commonName(CERT_GetCommonName(&mCert->subject));
|
||||
UniquePORTString organizationalUnitName(CERT_GetOrgUnitName(&mCert->subject));
|
||||
UniquePORTString organizationName(CERT_GetOrgName(&mCert->subject));
|
||||
|
||||
bool isBuiltInRoot;
|
||||
nsresult rv = GetIsBuiltInRoot(&isBuiltInRoot);
|
||||
|
@ -226,7 +241,7 @@ nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) {
|
|||
// (the subject really shouldn't be empty), an empty string is returned.
|
||||
nsAutoCString builtInRootNickname;
|
||||
if (isBuiltInRoot) {
|
||||
nsAutoCString fullNickname((*mCert)->nickname);
|
||||
nsAutoCString fullNickname(mCert->nickname);
|
||||
int32_t index = fullNickname.Find(":");
|
||||
if (index != kNotFound) {
|
||||
// Substring will gracefully handle the case where index is the last
|
||||
|
@ -239,7 +254,7 @@ nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) {
|
|||
const char* nameOptions[] = {
|
||||
builtInRootNickname.get(), commonName.get(),
|
||||
organizationalUnitName.get(), organizationName.get(),
|
||||
(*mCert)->subjectName, (*mCert)->emailAddr};
|
||||
mCert->subjectName, mCert->emailAddr};
|
||||
|
||||
for (auto nameOption : nameOptions) {
|
||||
if (nameOption) {
|
||||
|
@ -256,14 +271,8 @@ nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetEmailAddress(nsAString& aEmailAddress) {
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if ((*mCert)->emailAddr) {
|
||||
CopyUTF8toUTF16(MakeStringSpan((*mCert)->emailAddr), aEmailAddress);
|
||||
if (mCert->emailAddr) {
|
||||
CopyUTF8toUTF16(MakeStringSpan(mCert->emailAddr), aEmailAddress);
|
||||
} else {
|
||||
GetPIPNSSBundleString("CertNoEmailAddress", aEmailAddress);
|
||||
}
|
||||
|
@ -272,22 +281,16 @@ nsNSSCertificate::GetEmailAddress(nsAString& aEmailAddress) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetEmailAddresses(nsTArray<nsString>& aAddresses) {
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
uint32_t length = 0;
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress((*mCert).get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress((*mCert).get(), aAddr)) {
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) {
|
||||
++(length);
|
||||
}
|
||||
|
||||
aAddresses.SetCapacity(length);
|
||||
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress((*mCert).get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress((*mCert).get(), aAddr)) {
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) {
|
||||
CopyASCIItoUTF16(MakeStringSpan(aAddr), *aAddresses.AppendElement());
|
||||
}
|
||||
|
||||
|
@ -300,14 +303,8 @@ nsNSSCertificate::ContainsEmailAddress(const nsAString& aEmailAddress,
|
|||
NS_ENSURE_ARG(result);
|
||||
*result = false;
|
||||
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress((*mCert).get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress((*mCert).get(), aAddr)) {
|
||||
for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr;
|
||||
aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) {
|
||||
nsAutoString certAddr;
|
||||
LossyUTF8ToUTF16(aAddr, strlen(aAddr), certAddr);
|
||||
ToLowerCase(certAddr);
|
||||
|
@ -327,113 +324,84 @@ nsNSSCertificate::ContainsEmailAddress(const nsAString& aEmailAddress,
|
|||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetCommonName(nsAString& aCommonName) {
|
||||
aCommonName.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString commonName(CERT_GetCommonName(&mCert->subject));
|
||||
if (commonName) {
|
||||
LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
|
||||
}
|
||||
}
|
||||
UniquePORTString commonName(CERT_GetCommonName(&(*mCert)->subject));
|
||||
if (commonName) {
|
||||
LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetOrganization(nsAString& aOrganization) {
|
||||
aOrganization.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString organization(CERT_GetOrgName(&mCert->subject));
|
||||
if (organization) {
|
||||
LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
|
||||
aOrganization);
|
||||
}
|
||||
}
|
||||
UniquePORTString organization(CERT_GetOrgName(&(*mCert)->subject));
|
||||
if (organization) {
|
||||
LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
|
||||
aOrganization);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetIssuerCommonName(nsAString& aCommonName) {
|
||||
aCommonName.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString commonName(CERT_GetCommonName(&mCert->issuer));
|
||||
if (commonName) {
|
||||
LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
|
||||
}
|
||||
}
|
||||
UniquePORTString commonName(CERT_GetCommonName(&(*mCert)->issuer));
|
||||
if (commonName) {
|
||||
LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetIssuerOrganization(nsAString& aOrganization) {
|
||||
aOrganization.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString organization(CERT_GetOrgName(&mCert->issuer));
|
||||
if (organization) {
|
||||
LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
|
||||
aOrganization);
|
||||
}
|
||||
}
|
||||
UniquePORTString organization(CERT_GetOrgName(&(*mCert)->issuer));
|
||||
if (organization) {
|
||||
LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
|
||||
aOrganization);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetIssuerOrganizationUnit(nsAString& aOrganizationUnit) {
|
||||
aOrganizationUnit.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString organizationUnit(CERT_GetOrgUnitName(&mCert->issuer));
|
||||
if (organizationUnit) {
|
||||
LossyUTF8ToUTF16(organizationUnit.get(), strlen(organizationUnit.get()),
|
||||
aOrganizationUnit);
|
||||
}
|
||||
}
|
||||
UniquePORTString organizationUnit(CERT_GetOrgUnitName(&(*mCert)->issuer));
|
||||
if (organizationUnit) {
|
||||
LossyUTF8ToUTF16(organizationUnit.get(), strlen(organizationUnit.get()),
|
||||
aOrganizationUnit);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetOrganizationalUnit(nsAString& aOrganizationalUnit) {
|
||||
aOrganizationalUnit.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (mCert) {
|
||||
UniquePORTString orgunit(CERT_GetOrgUnitName(&mCert->subject));
|
||||
if (orgunit) {
|
||||
LossyUTF8ToUTF16(orgunit.get(), strlen(orgunit.get()),
|
||||
aOrganizationalUnit);
|
||||
}
|
||||
}
|
||||
UniquePORTString orgunit(CERT_GetOrgUnitName(&(*mCert)->subject));
|
||||
if (orgunit) {
|
||||
LossyUTF8ToUTF16(orgunit.get(), strlen(orgunit.get()), aOrganizationalUnit);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetSubjectName(nsAString& _subjectName) {
|
||||
_subjectName.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if ((*mCert)->subjectName) {
|
||||
LossyUTF8ToUTF16((*mCert)->subjectName, strlen((*mCert)->subjectName),
|
||||
if (mCert->subjectName) {
|
||||
LossyUTF8ToUTF16(mCert->subjectName, strlen(mCert->subjectName),
|
||||
_subjectName);
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -442,15 +410,8 @@ nsNSSCertificate::GetSubjectName(nsAString& _subjectName) {
|
|||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetIssuerName(nsAString& _issuerName) {
|
||||
_issuerName.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if ((*mCert)->issuerName) {
|
||||
LossyUTF8ToUTF16((*mCert)->issuerName, strlen((*mCert)->issuerName),
|
||||
_issuerName);
|
||||
if (mCert->issuerName) {
|
||||
LossyUTF8ToUTF16(mCert->issuerName, strlen(mCert->issuerName), _issuerName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -458,14 +419,8 @@ nsNSSCertificate::GetIssuerName(nsAString& _issuerName) {
|
|||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetSerialNumber(nsAString& _serialNumber) {
|
||||
_serialNumber.Truncate();
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
UniquePORTString tmpstr(
|
||||
CERT_Hexify(&(*mCert)->serialNumber, true /* use colon delimiters */));
|
||||
CERT_Hexify(&mCert->serialNumber, true /* use colon delimiters */));
|
||||
if (tmpstr) {
|
||||
_serialNumber = NS_ConvertASCIItoUTF16(tmpstr.get());
|
||||
return NS_OK;
|
||||
|
@ -477,8 +432,8 @@ nsresult nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint,
|
|||
SECOidTag aHashAlg) {
|
||||
aFingerprint.Truncate();
|
||||
nsTArray<uint8_t> digestArray;
|
||||
nsresult rv =
|
||||
Digest::DigestBuf(aHashAlg, mDER.Elements(), mDER.Length(), digestArray);
|
||||
nsresult rv = Digest::DigestBuf(aHashAlg, mCert->derCert.data,
|
||||
mCert->derCert.len, digestArray);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -507,18 +462,16 @@ nsNSSCertificate::GetSha1Fingerprint(nsAString& _sha1Fingerprint) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetTokenName(nsAString& aTokenName) {
|
||||
MOZ_ASSERT(mCert);
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
UniquePK11SlotInfo internalSlot(PK11_GetInternalSlot());
|
||||
if (!internalSlot) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIPK11Token> token(
|
||||
new nsPK11Token((*mCert)->slot ? (*mCert)->slot : internalSlot.get()));
|
||||
new nsPK11Token(mCert->slot ? mCert->slot : internalSlot.get()));
|
||||
nsAutoCString tmp;
|
||||
nsresult rv = token->GetTokenName(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -534,7 +487,7 @@ nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(
|
|||
aSha256SPKIDigest.Truncate();
|
||||
|
||||
pkix::Input certInput;
|
||||
pkix::Result result = certInput.Init(mDER.Elements(), mDER.Length());
|
||||
pkix::Result result = certInput.Init(mCert->derCert.data, mCert->derCert.len);
|
||||
if (result != pkix::Result::Success) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
@ -553,7 +506,7 @@ nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(
|
|||
return rv;
|
||||
}
|
||||
rv = Base64Encode(nsDependentCSubstring(
|
||||
reinterpret_cast<const char*>(digestArray.Elements()),
|
||||
BitwiseCast<char*, uint8_t*>(digestArray.Elements()),
|
||||
digestArray.Length()),
|
||||
aSha256SPKIDigest);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -564,37 +517,40 @@ nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetRawDER(nsTArray<uint8_t>& aArray) {
|
||||
aArray.SetLength(mDER.Length());
|
||||
memcpy(aArray.Elements(), mDER.Elements(), mDER.Length());
|
||||
return NS_OK;
|
||||
if (mCert) {
|
||||
aArray.SetLength(mCert->derCert.len);
|
||||
memcpy(aArray.Elements(), mCert->derCert.data, mCert->derCert.len);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetBase64DERString(nsACString& base64DERString) {
|
||||
nsDependentCSubstring derString(
|
||||
reinterpret_cast<const char*>(mDER.Elements()), mDER.Length());
|
||||
reinterpret_cast<const char*>(mCert->derCert.data), mCert->derCert.len);
|
||||
|
||||
nsresult rv = Base64Encode(derString, base64DERString);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CERTCertificate* nsNSSCertificate::GetCert() {
|
||||
if (!mCert) {
|
||||
nsresult rv = InstantiateCert();
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return CERT_DupCertificate((*mCert).get());
|
||||
return (mCert) ? CERT_DupCertificate(mCert.get()) : nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity) {
|
||||
NS_ENSURE_ARG(aValidity);
|
||||
if (!mCert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
pkix::Input certInput;
|
||||
pkix::Result rv = certInput.Init(mDER.Elements(), mDER.Length());
|
||||
pkix::Result rv = certInput.Init(mCert->derCert.data, mCert->derCert.len);
|
||||
if (rv != pkix::Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -603,29 +559,108 @@ nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// TODO(bug 1036065): It seems like we only construct CERTCertLists for the
|
||||
// purpose of constructing nsNSSCertLists, so maybe we should change this
|
||||
// function to output an nsNSSCertList instead.
|
||||
SECStatus ConstructCERTCertListFromReversedDERArray(
|
||||
const mozilla::pkix::DERArray& certArray,
|
||||
/*out*/ UniqueCERTCertList& certList) {
|
||||
certList = UniqueCERTCertList(CERT_NewCertList());
|
||||
if (!certList) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
CERTCertDBHandle* certDB(CERT_GetDefaultCertDB()); // non-owning
|
||||
|
||||
size_t numCerts = certArray.GetLength();
|
||||
for (size_t i = 0; i < numCerts; ++i) {
|
||||
SECItem certDER(UnsafeMapInputToSECItem(*certArray.GetDER(i)));
|
||||
UniqueCERTCertificate cert(
|
||||
CERT_NewTempCertificate(certDB, &certDER, nullptr, false, true));
|
||||
if (!cert) {
|
||||
return SECFailure;
|
||||
}
|
||||
// certArray is ordered with the root first, but we want the resulting
|
||||
// certList to have the root last.
|
||||
if (CERT_AddCertToListHead(certList.get(), cert.get()) != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
Unused << cert.release(); // cert is now owned by certList.
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
nsresult nsNSSCertificate::GetIntermediatesAsDER(
|
||||
/* in */ const nsTArray<RefPtr<nsIX509Cert>>& aCertList,
|
||||
/* out */ nsTArray<nsTArray<uint8_t>>& aIntermediates) {
|
||||
if (aCertList.Length() <= 1) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!aIntermediates.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < aCertList.Length() - 1; ++i) {
|
||||
const auto& cert = aCertList[i];
|
||||
aIntermediates.AppendElement();
|
||||
nsTArray<uint8_t>& certBytes = aIntermediates.LastElement();
|
||||
nsresult rv = cert->GetRawDER(certBytes);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNSSCertificate::GetRootCertificate(
|
||||
/* in */ const nsTArray<RefPtr<nsIX509Cert>>& aCertList,
|
||||
/* out */ nsCOMPtr<nsIX509Cert>& aRoot) {
|
||||
if (aRoot) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
// If the list is empty, leave aRoot empty.
|
||||
if (aCertList.IsEmpty()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIX509Cert> cert(aCertList.LastElement());
|
||||
aRoot = cert;
|
||||
if (!aRoot) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// NB: Any updates (except disk-only fields) must be kept in sync with
|
||||
// |SerializeToIPC|.
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::Write(nsIObjectOutputStream* aStream) {
|
||||
NS_ENSURE_STATE(mCert);
|
||||
// This field used to be the cached EV status, but it is no longer necessary.
|
||||
nsresult rv = aStream->Write32(0);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = aStream->Write32(mDER.Length());
|
||||
rv = aStream->Write32(mCert->derCert.len);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return aStream->WriteBytes(Span(mDER));
|
||||
return aStream->WriteBytes(
|
||||
AsBytes(Span(mCert->derCert.data, mCert->derCert.len)));
|
||||
}
|
||||
|
||||
// NB: Any updates (except disk-only fields) must be kept in sync with
|
||||
// |DeserializeFromIPC|.
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::Read(nsIObjectInputStream* aStream) {
|
||||
if (!mDER.IsEmpty() || mCert.isSome()) {
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
NS_ENSURE_STATE(!mCert);
|
||||
|
||||
// This field is no longer used.
|
||||
uint32_t unusedCachedEVStatus;
|
||||
|
@ -640,30 +675,35 @@ nsNSSCertificate::Read(nsIObjectInputStream* aStream) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = aStream->ReadByteArray(len, mDER);
|
||||
nsCString str;
|
||||
rv = aStream->ReadBytes(len, getter_Copies(str));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!InitFromDER(const_cast<char*>(str.get()), len)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsNSSCertificate::SerializeToIPC(IPC::Message* aMsg) {
|
||||
bool hasCert = !mDER.IsEmpty();
|
||||
bool hasCert = static_cast<bool>(mCert);
|
||||
WriteParam(aMsg, hasCert);
|
||||
|
||||
if (!hasCert) {
|
||||
return;
|
||||
}
|
||||
|
||||
WriteParam(aMsg, mDER);
|
||||
const nsDependentCSubstring certBytes(
|
||||
reinterpret_cast<char*>(mCert->derCert.data), mCert->derCert.len);
|
||||
|
||||
WriteParam(aMsg, certBytes);
|
||||
}
|
||||
|
||||
bool nsNSSCertificate::DeserializeFromIPC(const IPC::Message* aMsg,
|
||||
PickleIterator* aIter) {
|
||||
if (!mDER.IsEmpty() || mCert.isSome()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasCert = false;
|
||||
if (!ReadParam(aMsg, aIter, &hasCert)) {
|
||||
return false;
|
||||
|
@ -673,10 +713,18 @@ bool nsNSSCertificate::DeserializeFromIPC(const IPC::Message* aMsg,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!ReadParam(aMsg, aIter, &mDER)) {
|
||||
nsCString derBytes;
|
||||
if (!ReadParam(aMsg, aIter, &derBytes)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (derBytes.Length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NSS accepts a |char*| here, but doesn't modify the contents of the array
|
||||
// and casts it back to an |unsigned char*|.
|
||||
return InitFromDER(const_cast<char*>(derBytes.get()), derBytes.Length());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -6,15 +6,24 @@
|
|||
#ifndef nsNSSCertificate_h
|
||||
#define nsNSSCertificate_h
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "certt.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsSimpleEnumerator.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace pkix {
|
||||
class DERArray;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
class nsINSSComponent;
|
||||
|
||||
class nsNSSCertificate final : public nsIX509Cert,
|
||||
|
@ -26,22 +35,45 @@ class nsNSSCertificate final : public nsIX509Cert,
|
|||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
|
||||
nsNSSCertificate();
|
||||
explicit nsNSSCertificate(CERTCertificate* cert);
|
||||
explicit nsNSSCertificate(nsTArray<uint8_t>&& der);
|
||||
nsNSSCertificate();
|
||||
static nsNSSCertificate* Create(CERTCertificate* cert = nullptr);
|
||||
static nsNSSCertificate* ConstructFromDER(char* certDER, int derLen);
|
||||
|
||||
// This method assumes that the current list object
|
||||
// is ordered [end entity, intermediates..., root].
|
||||
// Will return error if used on self-signed or empty chains.
|
||||
// This method requires that the list `aIntermediates` must be empty.
|
||||
static nsresult GetIntermediatesAsDER(
|
||||
/* int */ const nsTArray<RefPtr<nsIX509Cert>>& aCertList,
|
||||
/* out */ nsTArray<nsTArray<uint8_t>>& aIntermediates);
|
||||
|
||||
// Obtain the root certificate of a certificate chain. On an
|
||||
// empty list, leaves aRoot empty and returns a failure.
|
||||
// Assumes list is ordered [end entity, intermediates..., root].
|
||||
static nsresult GetRootCertificate(
|
||||
const nsTArray<RefPtr<nsIX509Cert>>& aCertList,
|
||||
/* out */ nsCOMPtr<nsIX509Cert>& aRoot);
|
||||
|
||||
private:
|
||||
virtual ~nsNSSCertificate() = default;
|
||||
|
||||
nsTArray<uint8_t> mDER;
|
||||
mozilla::Maybe<mozilla::UniqueCERTCertificate> mCert;
|
||||
mozilla::UniqueCERTCertificate mCert;
|
||||
uint32_t mCertType;
|
||||
nsresult GetSortableDate(PRTime aTime, nsAString& _aSortableDate);
|
||||
bool InitFromDER(char* certDER, int derLen); // return false on failure
|
||||
|
||||
nsresult GetCertificateHash(nsAString& aFingerprint, SECOidTag aHashAlg);
|
||||
|
||||
nsresult InstantiateCert();
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
SECStatus ConstructCERTCertListFromReversedDERArray(
|
||||
const mozilla::pkix::DERArray& certArray,
|
||||
/*out*/ mozilla::UniqueCERTCertList& certList);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_X509CERT_CID \
|
||||
{ /* 660a3226-915c-4ffb-bb20-8985a632df05 */ \
|
||||
0x660a3226, 0x915c, 0x4ffb, { \
|
||||
|
|
|
@ -79,7 +79,10 @@ nsNSSCertificateDB::FindCertByDBKey(const nsACString& aDBKey,
|
|||
if (!cert) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> nssCert = new nsNSSCertificate(cert.get());
|
||||
nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
|
||||
if (!nssCert) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nssCert.forget(_cert);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -384,7 +387,10 @@ nsresult nsNSSCertificateDB::ConstructCertArrayFromUniqueCertList(
|
|||
|
||||
for (CERTCertListNode* node = CERT_LIST_HEAD(aCertListIn.get());
|
||||
!CERT_LIST_END(node, aCertListIn.get()); node = CERT_LIST_NEXT(node)) {
|
||||
RefPtr<nsIX509Cert> cert = new nsNSSCertificate(node->cert);
|
||||
RefPtr<nsIX509Cert> cert = nsNSSCertificate::Create(node->cert);
|
||||
if (!cert) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aCertListOut.AppendElement(cert);
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -400,6 +406,7 @@ nsNSSCertificateDB::ImportCertificates(uint8_t* data, uint32_t length,
|
|||
}
|
||||
|
||||
nsTArray<nsTArray<uint8_t>> certsArray;
|
||||
|
||||
nsresult rv = getCertsFromPackage(certsArray, data, length);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -412,7 +419,11 @@ nsNSSCertificateDB::ImportCertificates(uint8_t* data, uint32_t length,
|
|||
|
||||
// Now let's create some certs to work with
|
||||
for (nsTArray<uint8_t>& certDER : certsArray) {
|
||||
nsCOMPtr<nsIX509Cert> cert = new nsNSSCertificate(std::move(certDER));
|
||||
nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::ConstructFromDER(
|
||||
BitwiseCast<char*, uint8_t*>(certDER.Elements()), certDER.Length());
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = array->AppendElement(cert);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -557,7 +568,7 @@ nsNSSCertificateDB::ImportUserCertificate(uint8_t* data, uint32_t length,
|
|||
|
||||
UniquePK11SlotInfo slot(PK11_KeyForCertExists(cert.get(), nullptr, ctx));
|
||||
if (!slot) {
|
||||
nsCOMPtr<nsIX509Cert> certToShow = new nsNSSCertificate(cert.get());
|
||||
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(cert.get());
|
||||
DisplayCertificateAlert(ctx, "UserCertIgnoredNoPrivateKey", certToShow);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -579,7 +590,7 @@ nsNSSCertificateDB::ImportUserCertificate(uint8_t* data, uint32_t length,
|
|||
slot = nullptr;
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIX509Cert> certToShow = new nsNSSCertificate(cert.get());
|
||||
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(cert.get());
|
||||
DisplayCertificateAlert(ctx, "UserCertImported", certToShow);
|
||||
}
|
||||
|
||||
|
@ -879,7 +890,10 @@ nsresult nsNSSCertificateDB::ConstructX509FromSpan(
|
|||
return (PORT_GetError() == SEC_ERROR_NO_MEMORY) ? NS_ERROR_OUT_OF_MEMORY
|
||||
: NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIX509Cert> nssCert = new nsNSSCertificate(cert.get());
|
||||
nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
|
||||
if (!nssCert) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nssCert.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1281,8 +1295,13 @@ nsresult VerifyCertAtTime(nsIX509Cert* aCert,
|
|||
}
|
||||
|
||||
if (result == mozilla::pkix::Success) {
|
||||
for (auto& certDER : resultChain) {
|
||||
RefPtr<nsIX509Cert> cert = new nsNSSCertificate(std::move(certDER));
|
||||
for (const auto& certDER : resultChain) {
|
||||
RefPtr<nsIX509Cert> cert = nsNSSCertificate::ConstructFromDER(
|
||||
const_cast<char*>(reinterpret_cast<const char*>(certDER.Elements())),
|
||||
static_cast<int>(certDER.Length()));
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aVerifiedChain.AppendElement(cert);
|
||||
}
|
||||
|
||||
|
|
|
@ -2518,7 +2518,10 @@ nsNSSComponent::IsCertTestBuiltInRoot(CERTCertificate* cert, bool* result) {
|
|||
*result = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
RefPtr<nsNSSCertificate> nsc = new nsNSSCertificate(cert);
|
||||
RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(cert);
|
||||
if (!nsc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoString certHash;
|
||||
nsresult rv = nsc->GetSha256Fingerprint(certHash);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -2236,30 +2236,11 @@ mozilla::pkix::Result ClientAuthCertNonverifyingTrustDomain::FindIssuer(
|
|||
}
|
||||
|
||||
mozilla::pkix::Result ClientAuthCertNonverifyingTrustDomain::IsChainValid(
|
||||
const DERArray& certArray, Time, const CertPolicyId&) {
|
||||
mBuiltChain = UniqueCERTCertList(CERT_NewCertList());
|
||||
if (!mBuiltChain) {
|
||||
const DERArray& certChain, Time, const CertPolicyId&) {
|
||||
if (ConstructCERTCertListFromReversedDERArray(certChain, mBuiltChain) !=
|
||||
SECSuccess) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
|
||||
CERTCertDBHandle* certDB(CERT_GetDefaultCertDB()); // non-owning
|
||||
|
||||
size_t numCerts = certArray.GetLength();
|
||||
for (size_t i = 0; i < numCerts; ++i) {
|
||||
SECItem certDER(UnsafeMapInputToSECItem(*certArray.GetDER(i)));
|
||||
UniqueCERTCertificate cert(
|
||||
CERT_NewTempCertificate(certDB, &certDER, nullptr, false, true));
|
||||
if (!cert) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
// certArray is ordered with the root first, but we want the resulting
|
||||
// certList to have the root last.
|
||||
if (CERT_AddCertToListHead(mBuiltChain.get(), cert.get()) != SECSuccess) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
Unused << cert.release(); // cert is now owned by mBuiltChain.
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
@ -2413,7 +2394,7 @@ void ClientAuthDataRunnable::RunOnTargetThread() {
|
|||
if (cars) {
|
||||
nsCString rememberedDBKey;
|
||||
bool found;
|
||||
nsCOMPtr<nsIX509Cert> cert(new nsNSSCertificate(mServerCert));
|
||||
nsCOMPtr<nsIX509Cert> cert(nsNSSCertificate::Create(mServerCert));
|
||||
nsresult rv = cars->HasRememberedDecision(
|
||||
hostname, mInfo.OriginAttributesRef(), cert, rememberedDBKey, &found);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -2465,7 +2446,10 @@ void ClientAuthDataRunnable::RunOnTargetThread() {
|
|||
|
||||
for (CERTCertListNode* node = CERT_LIST_HEAD(certList);
|
||||
!CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) {
|
||||
nsCOMPtr<nsIX509Cert> tempCert = new nsNSSCertificate(node->cert);
|
||||
nsCOMPtr<nsIX509Cert> tempCert = nsNSSCertificate::Create(node->cert);
|
||||
if (NS_WARN_IF(!tempCert)) {
|
||||
return;
|
||||
}
|
||||
nsresult rv = certArray->AppendElement(tempCert);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
|
@ -2506,10 +2490,10 @@ void ClientAuthDataRunnable::RunOnTargetThread() {
|
|||
}
|
||||
|
||||
if (cars && wantRemember) {
|
||||
nsCOMPtr<nsIX509Cert> serverCert(new nsNSSCertificate(mServerCert));
|
||||
nsCOMPtr<nsIX509Cert> serverCert(nsNSSCertificate::Create(mServerCert));
|
||||
nsCOMPtr<nsIX509Cert> clientCert;
|
||||
if (certChosen) {
|
||||
clientCert = new nsNSSCertificate(mSelectedCertificate.get());
|
||||
clientCert = nsNSSCertificate::Create(mSelectedCertificate.get());
|
||||
}
|
||||
rv = cars->RememberDecision(hostname, mInfo.OriginAttributesRef(),
|
||||
serverCert, clientCert);
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
/* -*- 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-----";
|
||||
|
||||
const uint8_t kCaIntermediateDer[] = {
|
||||
0x30, 0x82, 0x02, 0xBF, 0x30, 0x82, 0x01, 0xA9, 0xA0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x01, 0x02, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
|
||||
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x0C, 0x02, 0x63, 0x61, 0x30, 0x22, 0x18, 0x0F,
|
||||
0x32, 0x30, 0x31, 0x35, 0x31, 0x31, 0x32, 0x38, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, 0x30, 0x32, 0x30,
|
||||
0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x1A, 0x31, 0x18,
|
||||
0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x63, 0x61, 0x2D,
|
||||
0x69, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65,
|
||||
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, 0x2D, 0x32, 0xB3, 0xC5, 0x0E,
|
||||
0x99, 0x88, 0x2F, 0x1F, 0x9A, 0xEB, 0x4D, 0xE5, 0x7A, 0xBB, 0xBF, 0x68,
|
||||
0x70, 0x7A, 0x9D, 0x40, 0x5C, 0x1D, 0x99, 0x1E, 0xFF, 0xE1, 0xDD, 0x3C,
|
||||
0x8B, 0x76, 0xAC, 0x0B, 0xB6, 0xFB, 0xD1, 0xDC, 0x34, 0x7A, 0x10, 0x39,
|
||||
0xBE, 0x2E, 0x1C, 0xAB, 0x99, 0xB0, 0x06, 0xF4, 0x0E, 0x19, 0x9A, 0xB8,
|
||||
0xC2, 0xFB, 0x11, 0xE2, 0x34, 0x89, 0x5B, 0x4F, 0xB4, 0x86, 0x35, 0x8B,
|
||||
0xD5, 0xDA, 0xF6, 0x33, 0xA5, 0x71, 0x98, 0x27, 0xE3, 0x76, 0xA8, 0x54,
|
||||
0x35, 0x01, 0xCF, 0x95, 0x8E, 0xB2, 0xEE, 0x52, 0xDF, 0x61, 0x06, 0xC5,
|
||||
0x7D, 0x41, 0xD7, 0xF7, 0xD6, 0x60, 0xCA, 0x02, 0x63, 0x76, 0x69, 0xA6,
|
||||
0xEC, 0x7F, 0x0C, 0x04, 0xFE, 0x14, 0x80, 0xF6, 0xFC, 0x8E, 0x5E, 0x97,
|
||||
0xAB, 0x9D, 0xC5, 0x81, 0x8C, 0xA4, 0x89, 0x7F, 0xEA, 0x3E, 0x67, 0xDB,
|
||||
0xA7, 0x3A, 0x4E, 0x14, 0x70, 0xE2, 0xF9, 0x39, 0x3A, 0xEC, 0x32, 0xC2,
|
||||
0xBC, 0xFC, 0xF4, 0xDD, 0x45, 0x03, 0x60, 0xDC, 0x75, 0x1F, 0x43, 0xA1,
|
||||
0x46, 0x29, 0xA3, 0xD0, 0x35, 0xA1, 0x75, 0x81, 0x94, 0x83, 0x60, 0xC7,
|
||||
0x7C, 0xB4, 0x24, 0x38, 0x46, 0x2F, 0xAD, 0x81, 0xB8, 0xC1, 0x80, 0x7C,
|
||||
0x00, 0x1F, 0xF4, 0x86, 0xB1, 0xB9, 0xD7, 0x21, 0x6C, 0xB9, 0x7A, 0xF3,
|
||||
0x85, 0x87, 0x22, 0x9D, 0x32, 0x9B, 0xCB, 0x5D, 0x50, 0x93, 0xA3, 0xE3,
|
||||
0x9C, 0xE4, 0x3F, 0x69, 0x9B, 0xCA, 0xD3, 0x42, 0x5F, 0x7D, 0xEA, 0x7F,
|
||||
0x44, 0x7B, 0x3C, 0x94, 0x83, 0x96, 0xB7, 0x2F, 0x52, 0x6A, 0xB3, 0x06,
|
||||
0xA0, 0xD4, 0x84, 0x0A, 0x7F, 0xBA, 0x23, 0xD0, 0x20, 0x4A, 0xD2, 0x5D,
|
||||
0xA3, 0xA2, 0xEE, 0x3F, 0x54, 0x0F, 0xCA, 0xB4, 0x1E, 0xDC, 0x36, 0x6D,
|
||||
0x00, 0x78, 0x51, 0x24, 0x03, 0xC0, 0xA1, 0x4E, 0xC1, 0x4A, 0xA3};
|
||||
|
||||
// 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-----";
|
||||
|
||||
const uint8_t kCaSecondIntermediateDer[] = {
|
||||
0x30, 0x82, 0x02, 0xD3, 0x30, 0x82, 0x01, 0xBD, 0xA0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x01, 0x03, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
|
||||
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x30, 0x1A, 0x31, 0x18, 0x30, 0x16, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x63, 0x61, 0x2D, 0x69, 0x6E, 0x74,
|
||||
0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x30, 0x22, 0x18,
|
||||
0x0F, 0x32, 0x30, 0x31, 0x35, 0x31, 0x31, 0x32, 0x38, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, 0x30, 0x32,
|
||||
0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x21, 0x31,
|
||||
0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x63, 0x61,
|
||||
0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x2D, 0x69, 0x6E, 0x74, 0x65,
|
||||
0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 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, 0x68, 0xAE, 0x8A, 0xEF, 0xFD, 0x18, 0xF8, 0xF9, 0x06,
|
||||
0x31, 0x02, 0x63, 0xBA, 0x64, 0xE5, 0xB7, 0xA5, 0xD4, 0x42, 0x34, 0x37,
|
||||
0x63, 0xAC, 0xEE, 0x48, 0xE3, 0x25, 0x67, 0x5C, 0x26, 0x26, 0x80, 0x6A,
|
||||
0x59, 0xA6, 0xD8, 0x84, 0x9E, 0x2A, 0x5D, 0xF7, 0x12, 0x31, 0x08, 0xB0,
|
||||
0xFA, 0x46, 0x7E, 0x99, 0x04, 0xC5, 0x93, 0xE2, 0x1D, 0xBA, 0xB1, 0x82,
|
||||
0x44, 0x7A, 0xC0, 0x2B, 0x00, 0xC6, 0x35, 0x1A, 0xA6, 0x8E, 0x74, 0x39,
|
||||
0xEA, 0xA8, 0xF0, 0x1C, 0xD4, 0xD3, 0xC6, 0x12, 0x68, 0xCC, 0xFD, 0x3D,
|
||||
0xBC, 0x10, 0xA0, 0xB3, 0x77, 0xC8, 0x41, 0x06, 0x3F, 0x36, 0xAF, 0xEE,
|
||||
0x21, 0x2A, 0x10, 0xBC, 0xE6, 0x66, 0xA0, 0x8A, 0xE2, 0x15, 0x97, 0xFA,
|
||||
0xF1, 0xCC, 0xC7, 0x32, 0x58, 0xF5, 0xBC, 0x80, 0xBA, 0xCE, 0x9E, 0x17,
|
||||
0x1D, 0x67, 0x6A, 0x91, 0x0E, 0xDA, 0x17, 0x86, 0x05, 0xB1, 0x37, 0xCC,
|
||||
0xD2, 0x40, 0x4F, 0xAE, 0x6D, 0x18, 0xE8, 0xD9, 0xF4, 0x54, 0xAC, 0xD6,
|
||||
0x35, 0xD9, 0x9A, 0x22, 0xCF, 0xD7, 0xE4, 0xE7, 0x11, 0xE9, 0x90, 0x06,
|
||||
0xCC, 0x63, 0x7D, 0x51, 0x95, 0x7E, 0x65, 0xFB, 0x5C, 0x7D, 0xDA, 0x88,
|
||||
0xD1, 0x74, 0x95, 0x09, 0x54, 0x40, 0x2B, 0x93, 0x1E, 0x11, 0xAF, 0xAD,
|
||||
0xC0, 0xBA, 0xF9, 0x3C, 0x4F, 0xCD, 0x97, 0xBF, 0xC8, 0x83, 0xFB, 0x54,
|
||||
0x24, 0xC5, 0x86, 0x49, 0xB7, 0x2B, 0x59, 0x16, 0x50, 0x4D, 0x74, 0x2E,
|
||||
0x47, 0x1E, 0xC2, 0x48, 0xA7, 0x28, 0x6A, 0xDC, 0x8C, 0x84, 0x93, 0x9D,
|
||||
0xD9, 0x84, 0xF8, 0x06, 0xFA, 0x22, 0x8C, 0x42, 0x42, 0xC5, 0x32, 0x96,
|
||||
0x30, 0x9C, 0xC5, 0x7B, 0x6B, 0x99, 0x02, 0x98, 0x50, 0x1D, 0x49, 0x55,
|
||||
0x98, 0x4F, 0x48, 0x6D, 0x44, 0x0C, 0xD1, 0x3D, 0x4D, 0xE9, 0x13, 0x5D,
|
||||
0xD5, 0xD1, 0xF8, 0xA3, 0x85, 0x1E, 0xB9};
|
||||
|
||||
// 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;
|
||||
|
||||
nsTArray<nsTArray<uint8_t>> intCerts;
|
||||
nsresult rv = nsNSSCertificate::GetIntermediatesAsDER(certList, intCerts);
|
||||
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();
|
||||
|
||||
rv = nsNSSCertificate::GetIntermediatesAsDER(certList, intCerts);
|
||||
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";
|
||||
|
||||
nsTArray<nsTArray<uint8_t>> intCerts;
|
||||
|
||||
rv = nsNSSCertificate::GetIntermediatesAsDER(certList, intCerts);
|
||||
ASSERT_EQ(rv, NS_OK) << "Should have segmented OK";
|
||||
ASSERT_EQ(intCerts.Length(), static_cast<size_t>(0))
|
||||
<< "There should be no intermediates";
|
||||
|
||||
rv = AddCertFromStringToList(kCaIntermediatePem, certList);
|
||||
ASSERT_EQ(rv, NS_OK) << "Should have loaded OK";
|
||||
|
||||
intCerts.Clear();
|
||||
rv = nsNSSCertificate::GetIntermediatesAsDER(certList, intCerts);
|
||||
ASSERT_EQ(rv, NS_OK) << "Should have segmented OK";
|
||||
|
||||
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();
|
||||
rv = nsNSSCertificate::GetIntermediatesAsDER(certList, intCerts);
|
||||
ASSERT_EQ(rv, NS_OK) << "Should have segmented OK";
|
||||
|
||||
ASSERT_EQ(intCerts.Length(), static_cast<size_t>(2))
|
||||
<< "There should be two intermediates";
|
||||
|
||||
const nsTArray<uint8_t> secondIntermediateBinaryArray(
|
||||
kCaSecondIntermediateDer, sizeof(kCaSecondIntermediateDer));
|
||||
const nsTArray<uint8_t> intermediateBinaryArray(kCaIntermediateDer,
|
||||
sizeof(kCaIntermediateDer));
|
||||
|
||||
for (size_t i = 0; i < intCerts.Length(); ++i) {
|
||||
const nsTArray<uint8_t>& certArray = intCerts[i];
|
||||
|
||||
if (i < intCerts.Length() - 1) {
|
||||
if (certArray != secondIntermediateBinaryArray) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (certArray != intermediateBinaryArray) {
|
||||
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";
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
SOURCES += [
|
||||
"CertDBTest.cpp",
|
||||
"CertListTest.cpp",
|
||||
"CoseTest.cpp",
|
||||
"DataStorageTest.cpp",
|
||||
"DeserializeCertTest.cpp",
|
||||
|
|
|
@ -896,8 +896,8 @@ nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
|||
const nsRect& aDirtyRect,
|
||||
DrawOverflow aDrawOverflow) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return Theme::DrawWidgetBackground(
|
||||
aContext, aFrame, aAppearance, aRect, aDirtyRect, aDrawOverflow);
|
||||
return Theme::DrawWidgetBackground(aContext, aFrame, aAppearance, aRect,
|
||||
aDirtyRect, aDrawOverflow);
|
||||
}
|
||||
|
||||
GtkWidgetState state;
|
||||
|
@ -1207,7 +1207,7 @@ bool nsNativeThemeGTK::GetWidgetOverflow(nsDeviceContext* aContext,
|
|||
nsRect* aOverflowRect) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return Theme::GetWidgetOverflow(aContext, aFrame, aAppearance,
|
||||
aOverflowRect);
|
||||
aOverflowRect);
|
||||
}
|
||||
|
||||
nsIntMargin extraSize;
|
||||
|
@ -1232,8 +1232,7 @@ auto nsNativeThemeGTK::IsWidgetNonNative(nsIFrame* aFrame,
|
|||
return NonNative::Always;
|
||||
}
|
||||
// We can't draw light widgets if the current GTK theme is dark or vice versa.
|
||||
if (Theme::ThemeSupportsWidget(aFrame->PresContext(), aFrame,
|
||||
aAppearance) &&
|
||||
if (Theme::ThemeSupportsWidget(aFrame->PresContext(), aFrame, aAppearance) &&
|
||||
LookAndFeel::ColorSchemeForFrame(aFrame) !=
|
||||
LookAndFeel::ColorSchemeForChrome()) {
|
||||
return NonNative::BecauseColorMismatch;
|
||||
|
@ -1248,8 +1247,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
|||
LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) == NonNative::Always) {
|
||||
return Theme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
return Theme::GetMinimumWidgetSize(aPresContext, aFrame, aAppearance,
|
||||
aResult, aIsOverridable);
|
||||
}
|
||||
|
||||
aResult->width = aResult->height = 0;
|
||||
|
@ -1449,8 +1448,8 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame,
|
|||
*aShouldRepaint = false;
|
||||
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return Theme::WidgetStateChanged(
|
||||
aFrame, aAppearance, aAttribute, aShouldRepaint, aOldValue);
|
||||
return Theme::WidgetStateChanged(aFrame, aAppearance, aAttribute,
|
||||
aShouldRepaint, aOldValue);
|
||||
}
|
||||
|
||||
// Some widget types just never change state.
|
||||
|
@ -1519,8 +1518,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) == NonNative::Always) {
|
||||
return Theme::ThemeSupportsWidget(aPresContext, aFrame,
|
||||
aAppearance);
|
||||
return Theme::ThemeSupportsWidget(aPresContext, aFrame, aAppearance);
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче