bug 1284946 - remove usages-related APIs from nsIX509Cert r=Cykesiopka,Felipe,jcj

nsIX509Cert provided the APIs getUsagesArray, requestUsagesArrayAsync, and
getUsagesString. These APIs were problematic in that the synchronous ones would
cause certificate verification to block the main thread and the asynchronous one
was needlessly indirect in its definition (it made use of two additional
special-case xpidl types) and needlessly complex in its implementation (it
required nsNSSComponent to manually manage a background thread without the aid
of recent improvements in that area (e.g. CryptoTask)). Furthermore, these APIs
would return string descriptions of the usages the certificate in question had
been verified for rather than using more concrete identifiers or values. This
paradigm is usable but imprecise. The new nsIX509CertDB API
asyncVerifyCertAtTime is much more expressive, enforces off-main-thread
computation, and makes use of CryptoTask for a simple implementation. Using this
API, previous uses of the old nsIX509Cert APIs can be replaced. As an additional
benefit, this removes a ton of obsolete C++ code.

MozReview-Commit-ID: KXVTcjAKehu

--HG--
extra : rebase_source : 50c51f73b2b61ed0ad4dc9702cc5df470ce998bc
This commit is contained in:
David Keeler 2016-07-06 14:45:36 -07:00
Родитель 16124386f7
Коммит 56d2f86c86
41 изменённых файлов: 670 добавлений и 959 удалений

Просмотреть файл

@ -44,8 +44,6 @@ VerifySSLCA=SSL Certificate Authority
VerifyEmailSigner=Email Signer Certificate
VerifyEmailRecip=Email Recipient Certificate
VerifyObjSign=Object Signer
VerifyCAVerifier=CA Verifier
VerifyStatusResponder=Status Responder Certificate
HighGrade=High Grade
MediumGrade=Medium Grade
# LOCALIZATION NOTE (nick_template): $1s is the common name from a cert (e.g. "Mozilla"), $2s is the CA name (e.g. VeriSign)
@ -238,14 +236,6 @@ CertDumpECsect409r1=SECG elliptic curve sect409r1 (aka NIST B-409)
CertDumpECsect571k1=SECG elliptic curve sect571k1 (aka NIST K-571)
CertDumpECsect571r1=SECG elliptic curve sect571r1 (aka NIST B-571)
CertDumpRawBytesHeader=Size: %S Bytes / %S Bits
VerifySSLClient_p=Client
VerifySSLServer_p=Server
VerifySSLCA_p=SSL CA
VerifyEmailSigner_p=Sign
VerifyEmailRecip_p=Encrypt
VerifyObjSign_p=Object Signer
VerifyCAVerifier_p=CA Verifier
VerifyStatusResponder_p=Status Responder
PK11BadPassword=The password entered was incorrect.
SuccessfulP12Backup=Successfully backed up your security certificate(s) and private key(s).
SuccessfulP12Restore=Successfully restored your security certificate(s) and private key(s).
@ -302,18 +292,6 @@ CertInfoPurposes=Purposes
CertInfoEmail=Email
CertInfoStoredIn=Stored in:
P12DefaultNickname=Imported Certificate
VerifyExpired=<Expired>
VerifyRevoked=<Revoked>
VerifyNotTrusted=<Not Trusted>
VerifyIssuerNotTrusted=<Issuer Not Trusted>
VerifyIssuerUnknown=<Issuer Unknown>
VerifyInvalidCA=<Invalid CA>
VerifyDisabledAlgorithm=<Signature Algorithm Not Secure>
VerifyUnknown=<Unknown>
CertUser=Your Cert
CertCA=CA (Certificate Authority)
CertSSL=SSL Server
CertEmail=Peer S/MIME
CertUnknown=Unknown
CertNoNickname=(no nickname)
CertNoEmailAddress=(no email address)

Просмотреть файл

@ -3,17 +3,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const nsIX509Cert = Components.interfaces.nsIX509Cert;
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const nsIX509Cert = Ci.nsIX509Cert;
const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
const nsIX509CertDB = Components.interfaces.nsIX509CertDB;
const nsIX509CertDB = Ci.nsIX509CertDB;
const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
const nsIASN1Object = Components.interfaces.nsIASN1Object;
const nsIASN1Sequence = Components.interfaces.nsIASN1Sequence;
const nsIASN1PrintableItem = Components.interfaces.nsIASN1PrintableItem;
const nsIASN1Tree = Components.interfaces.nsIASN1Tree;
const nsIPK11TokenDB = Ci.nsIPK11TokenDB;
const nsIASN1Object = Ci.nsIASN1Object;
const nsIASN1Sequence = Ci.nsIASN1Sequence;
const nsIASN1PrintableItem = Ci.nsIASN1PrintableItem;
const nsIASN1Tree = Ci.nsIASN1Tree;
const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1";
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
const nsIDialogParamBlock = Ci.nsIDialogParamBlock;
var bundle;
@ -54,11 +57,10 @@ function AddCertChain(node, chain)
*
* @param {String} usage
* Verified usage to add.
* @param {Node} verifyInfoBox
* Parent node to append to.
*/
function AddUsage(usage, verifyInfoBox)
function AddUsage(usage)
{
let verifyInfoBox = document.getElementById("verify_info_box");
let text = document.createElement("textbox");
text.setAttribute("value", usage);
text.setAttribute("style", "margin: 2px 5px");
@ -93,7 +95,140 @@ function setWindowName()
AddCertChain("treesetDump", cert.getChain());
DisplayGeneralDataFromCert(cert);
BuildPrettyPrint(cert);
cert.requestUsagesArrayAsync(new listener());
asyncDetermineUsages(cert);
}
// Certificate usages we care about in the certificate viewer.
const certificateUsageSSLClient = 0x0001;
const certificateUsageSSLServer = 0x0002;
const certificateUsageSSLCA = 0x0008;
const certificateUsageEmailSigner = 0x0010;
const certificateUsageEmailRecipient = 0x0020;
const certificateUsageObjectSigner = 0x0040;
// 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 certificateUsages = {
certificateUsageSSLClient,
certificateUsageSSLServer,
certificateUsageSSLCA,
certificateUsageEmailSigner,
certificateUsageEmailRecipient,
certificateUsageObjectSigner,
};
// Map of certificate usage name to localization identifier.
const certificateUsageToStringBundleName = {
certificateUsageSSLClient: "VerifySSLClient",
certificateUsageSSLServer: "VerifySSLServer",
certificateUsageSSLCA: "VerifySSLCA",
certificateUsageEmailSigner: "VerifyEmailSigner",
certificateUsageEmailRecipient: "VerifyEmailRecip",
certificateUsageObjectSigner: "VerifyObjSign",
};
const PRErrorCodeSuccess = 0;
const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
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_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176;
/**
* Kicks off asynchronous verifications of the given certificate to determine
* what usages it is currently valid for. Updates the usage display area when
* complete.
*
* @param {nsIX509Cert} cert
* The certificate to determine valid usages for.
*/
function asyncDetermineUsages(cert) {
let promises = [];
let now = Date.now() / 1000;
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
Object.keys(certificateUsages).forEach(usageString => {
promises.push(new Promise((resolve, reject) => {
let usage = certificateUsages[usageString];
certdb.asyncVerifyCertAtTime(cert, usage, 0, null, now,
(aPRErrorCode, aVerifiedChain, aHasEVPolicy) => {
resolve({ usageString: usageString, errorCode: aPRErrorCode });
});
}));
});
Promise.all(promises).then(displayUsages);
}
/**
* Updates the usage display area given the results from asyncDetermineUsages.
*
* @param {Array} results
* An array of objects with the properties "usageString" and "errorCode".
* usageString is a string that is a key in the certificateUsages map.
* errorCode is either an NSPR error code or PRErrorCodeSuccess (which is
* a pseudo-NSPR error code with the value 0 that indicates success).
*/
function displayUsages(results) {
document.getElementById("verify_pending").setAttribute("hidden", "true");
let verified = document.getElementById("verified");
let someSuccess = results.some(result =>
result.errorCode == PRErrorCodeSuccess
);
if (someSuccess) {
let verifystr = bundle.getString("certVerified");
verified.textContent = verifystr;
let pipnssBundle = Services.strings.createBundle(
"chrome://pipnss/locale/pipnss.properties");
results.forEach(result => {
if (result.errorCode != PRErrorCodeSuccess) {
return;
}
let bundleName = certificateUsageToStringBundleName[result.usageString];
let usage = pipnssBundle.GetStringFromName(bundleName);
AddUsage(usage);
});
} else {
const errorRankings = [
{ error: SEC_ERROR_REVOKED_CERTIFICATE,
bundleString: "certNotVerified_CertRevoked" },
{ error: SEC_ERROR_UNTRUSTED_CERT,
bundleString: "certNotVerified_CertNotTrusted" },
{ error: SEC_ERROR_UNTRUSTED_ISSUER,
bundleString: "certNotVerified_IssuerNotTrusted" },
{ error: SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED,
bundleString: "certNotVerified_AlgorithmDisabled" },
{ error: SEC_ERROR_EXPIRED_CERTIFICATE,
bundleString: "certNotVerified_CertExpired" },
{ error: SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE,
bundleString: "certNotVerified_CAInvalid" },
{ error: SEC_ERROR_UNKNOWN_ISSUER,
bundleString: "certNotVerified_IssuerUnknown" },
];
let verifystr;
for (let errorRanking of errorRankings) {
let errorPresent = results.some(result =>
result.errorCode == errorRanking.error
);
if (errorPresent) {
verifystr = bundle.getString(errorRanking.bundleString);
break;
}
}
if (!verifystr) {
verifystr = bundle.getString("certNotVerified_Unknown");
}
verified.textContent = verifystr;
}
// Notify that we are done determining the certificate's valid usages (this
// should be treated as an implementation detail that enables tests to run
// efficiently - other code in the browser probably shouldn't rely on this).
Services.obs.notifyObservers(window, "ViewCertDetails:CertUsagesDone", null);
}
function addChildrenToTree(parentTree, label, value, addTwistie)
@ -154,82 +289,6 @@ function addAttributeFromCert(nodeName, value)
node.setAttribute('value', value);
}
function listener() {
}
listener.prototype.QueryInterface =
function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsICertVerificationListener)) {
return this;
}
throw new Error(Components.results.NS_ERROR_NO_INTERFACE);
};
listener.prototype.notify =
function(cert, result) {
DisplayVerificationData(cert, result);
};
function DisplayVerificationData(cert, result)
{
document.getElementById("verify_pending").setAttribute("hidden", "true");
if (!result || !cert) {
return; // no results could be produced
}
if (!(cert instanceof Components.interfaces.nsIX509Cert)) {
return;
}
// Verification and usage
var verifystr = "";
var o1 = {};
var o2 = {};
var o3 = {};
if (!(result instanceof Components.interfaces.nsICertVerificationResult)) {
return;
}
result.getUsagesArrayResult(o1, o2, o3);
var verifystate = o1.value;
var count = o2.value;
var usageList = o3.value;
if (verifystate == cert.VERIFIED_OK) {
verifystr = bundle.getString('certVerified');
} else if (verifystate == cert.CERT_REVOKED) {
verifystr = bundle.getString('certNotVerified_CertRevoked');
} else if (verifystate == cert.CERT_EXPIRED) {
verifystr = bundle.getString('certNotVerified_CertExpired');
} else if (verifystate == cert.CERT_NOT_TRUSTED) {
verifystr = bundle.getString('certNotVerified_CertNotTrusted');
} else if (verifystate == cert.ISSUER_NOT_TRUSTED) {
verifystr = bundle.getString('certNotVerified_IssuerNotTrusted');
} else if (verifystate == cert.ISSUER_UNKNOWN) {
verifystr = bundle.getString('certNotVerified_IssuerUnknown');
} else if (verifystate == cert.INVALID_CA) {
verifystr = bundle.getString('certNotVerified_CAInvalid');
} else if (verifystate == cert.SIGNATURE_ALGORITHM_DISABLED) {
verifystr = bundle.getString('certNotVerified_AlgorithmDisabled');
} else { /* if (verifystate == cert.NOT_VERIFIED_UNKNOWN || == USAGE_NOT_ALLOWED) */
verifystr = bundle.getString('certNotVerified_Unknown');
}
let verified = document.getElementById("verified");
verified.textContent = verifystr;
if (count > 0) {
var verifyInfoBox = document.getElementById('verify_info_box');
for (let i = 0; i < count; i++) {
AddUsage(usageList[i], verifyInfoBox);
}
}
}
/**
* Displays information about a cert in the "General" tab of the cert viewer.
*

Просмотреть файл

@ -93,7 +93,6 @@ UNIFIED_SOURCES += [
'LocalCertService.cpp',
'nsCertOverrideService.cpp',
'nsCertPicker.cpp',
'nsCertVerificationThread.cpp',
'nsClientAuthRemember.cpp',
'nsCrypto.cpp',
'nsCryptoHash.cpp',
@ -132,7 +131,6 @@ UNIFIED_SOURCES += [
'nsSSLSocketProvider.cpp',
'nsSSLStatus.cpp',
'nsTLSSocketProvider.cpp',
'nsUsageArrayHelper.cpp',
'PSMContentListener.cpp',
'PSMRunnable.cpp',
'PublicKeyPinningService.cpp',

Просмотреть файл

@ -1104,47 +1104,6 @@ nsCertTree::GetCellText(int32_t row, nsITreeColumn* col,
rv = cert->GetTokenName(_retval);
} else if (NS_LITERAL_STRING("emailcol").Equals(colID) && cert) {
rv = cert->GetEmailAddress(_retval);
} else if (NS_LITERAL_STRING("purposecol").Equals(colID) && mNSSComponent && cert) {
uint32_t verified;
nsAutoString theUsages;
rv = cert->GetUsagesString(false, &verified, theUsages); // allow OCSP
if (NS_FAILED(rv)) {
verified = nsIX509Cert::NOT_VERIFIED_UNKNOWN;
}
switch (verified) {
case nsIX509Cert::VERIFIED_OK:
_retval = theUsages;
break;
case nsIX509Cert::CERT_REVOKED:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyRevoked", _retval);
break;
case nsIX509Cert::CERT_EXPIRED:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyExpired", _retval);
break;
case nsIX509Cert::CERT_NOT_TRUSTED:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyNotTrusted", _retval);
break;
case nsIX509Cert::ISSUER_NOT_TRUSTED:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyIssuerNotTrusted", _retval);
break;
case nsIX509Cert::ISSUER_UNKNOWN:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyIssuerUnknown", _retval);
break;
case nsIX509Cert::INVALID_CA:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyInvalidCA", _retval);
break;
case nsIX509Cert::SIGNATURE_ALGORITHM_DISABLED:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyDisabledAlgorithm", _retval);
break;
case nsIX509Cert::NOT_VERIFIED_UNKNOWN:
case nsIX509Cert::USAGE_NOT_ALLOWED:
default:
rv = mNSSComponent->GetPIPNSSBundleString("VerifyUnknown", _retval);
break;
}
} else if (NS_LITERAL_STRING("issuedcol").Equals(colID) && cert) {
nsCOMPtr<nsIX509CertValidity> validity;
@ -1161,17 +1120,6 @@ nsCertTree::GetCellText(int32_t row, nsITreeColumn* col,
}
} else if (NS_LITERAL_STRING("serialnumcol").Equals(colID) && cert) {
rv = cert->GetSerialNumber(_retval);
} else if (NS_LITERAL_STRING("overridetypecol").Equals(colID)) {
// default to classic permanent-trust
nsCertOverride::OverrideBits ob = nsCertOverride::ob_Untrusted;
if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
ob = certdi->mOverrideBits;
}
nsAutoCString temp;
nsCertOverride::convertBitsToString(ob, temp);
_retval = NS_ConvertUTF8toUTF16(temp);
} else if (NS_LITERAL_STRING("sitecol").Equals(colID)) {
if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
nsAutoCString hostPort;
@ -1185,28 +1133,6 @@ nsCertTree::GetCellText(int32_t row, nsITreeColumn* col,
const char *stringID =
(certdi->mIsTemporary) ? "CertExceptionTemporary" : "CertExceptionPermanent";
rv = mNSSComponent->GetPIPNSSBundleString(stringID, _retval);
} else if (NS_LITERAL_STRING("typecol").Equals(colID) && cert) {
uint32_t type = nsIX509Cert::UNKNOWN_CERT;
rv = cert->GetCertType(&type);
switch (type) {
case nsIX509Cert::USER_CERT:
rv = mNSSComponent->GetPIPNSSBundleString("CertUser", _retval);
break;
case nsIX509Cert::CA_CERT:
rv = mNSSComponent->GetPIPNSSBundleString("CertCA", _retval);
break;
case nsIX509Cert::SERVER_CERT:
rv = mNSSComponent->GetPIPNSSBundleString("CertSSL", _retval);
break;
case nsIX509Cert::EMAIL_CERT:
rv = mNSSComponent->GetPIPNSSBundleString("CertEmail", _retval);
break;
default:
rv = mNSSComponent->GetPIPNSSBundleString("CertUnknown", _retval);
break;
}
} else {
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -1,182 +0,0 @@
/* 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 "nsCertVerificationThread.h"
#include "nsThreadUtils.h"
#include "nsProxyRelease.h"
using namespace mozilla;
nsCertVerificationThread *nsCertVerificationThread::verification_thread_singleton;
NS_IMPL_ISUPPORTS(nsCertVerificationResult, nsICertVerificationResult)
namespace {
class DispatchCertVerificationResult : public Runnable
{
public:
DispatchCertVerificationResult(const nsMainThreadPtrHandle<nsICertVerificationListener>& aListener,
nsIX509Cert* aCert,
nsICertVerificationResult* aResult)
: mListener(aListener)
, mCert(aCert)
, mResult(aResult)
{ }
NS_IMETHOD Run() {
mListener->Notify(mCert, mResult);
return NS_OK;
}
private:
nsMainThreadPtrHandle<nsICertVerificationListener> mListener;
nsCOMPtr<nsIX509Cert> mCert;
nsCOMPtr<nsICertVerificationResult> mResult;
};
} // namespace
void nsCertVerificationJob::Run()
{
if (!mListener || !mCert)
return;
uint32_t verified;
uint32_t count;
char16_t **usages;
nsCOMPtr<nsICertVerificationResult> ires;
RefPtr<nsCertVerificationResult> vres(new nsCertVerificationResult);
if (vres)
{
nsresult rv = mCert->GetUsagesArray(false, // do not ignore OCSP
&verified,
&count,
&usages);
vres->mRV = rv;
if (NS_SUCCEEDED(rv))
{
vres->mVerified = verified;
vres->mCount = count;
vres->mUsages = usages;
}
ires = vres;
}
nsCOMPtr<nsIRunnable> r = new DispatchCertVerificationResult(mListener, mCert, ires);
NS_DispatchToMainThread(r);
}
nsCertVerificationThread::nsCertVerificationThread()
: mJobQ(nullptr)
{
NS_ASSERTION(!verification_thread_singleton,
"nsCertVerificationThread is a singleton, caller attempts"
" to create another instance!");
verification_thread_singleton = this;
}
nsCertVerificationThread::~nsCertVerificationThread()
{
verification_thread_singleton = nullptr;
}
nsresult nsCertVerificationThread::addJob(nsBaseVerificationJob *aJob)
{
if (!aJob || !verification_thread_singleton)
return NS_ERROR_FAILURE;
if (!verification_thread_singleton->mThreadHandle)
return NS_ERROR_OUT_OF_MEMORY;
MutexAutoLock threadLock(verification_thread_singleton->mMutex);
verification_thread_singleton->mJobQ.Push(aJob);
verification_thread_singleton->mCond.NotifyAll();
return NS_OK;
}
void nsCertVerificationThread::Run(void)
{
while (true) {
nsBaseVerificationJob *job = nullptr;
{
MutexAutoLock threadLock(verification_thread_singleton->mMutex);
while (!exitRequested(threadLock) &&
0 == verification_thread_singleton->mJobQ.GetSize()) {
// no work to do ? let's wait a moment
mCond.Wait();
}
if (exitRequested(threadLock))
break;
job = static_cast<nsBaseVerificationJob*>(mJobQ.PopFront());
}
if (job)
{
job->Run();
delete job;
}
}
{
MutexAutoLock threadLock(verification_thread_singleton->mMutex);
while (verification_thread_singleton->mJobQ.GetSize()) {
nsCertVerificationJob *job =
static_cast<nsCertVerificationJob*>(mJobQ.PopFront());
delete job;
}
postStoppedEventToMainThread(threadLock);
}
}
nsCertVerificationResult::nsCertVerificationResult()
: mRV(NS_OK),
mVerified(0),
mCount(0),
mUsages(0)
{
}
nsCertVerificationResult::~nsCertVerificationResult()
{
if (mUsages)
{
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mUsages);
}
}
NS_IMETHODIMP
nsCertVerificationResult::GetUsagesArrayResult(uint32_t *aVerified,
uint32_t *aCount,
char16_t ***aUsages)
{
if (NS_FAILED(mRV))
return mRV;
// transfer ownership
*aVerified = mVerified;
*aCount = mCount;
*aUsages = mUsages;
mVerified = 0;
mCount = 0;
mUsages = 0;
nsresult rv = mRV;
mRV = NS_ERROR_FAILURE; // this object works only once...
return rv;
}

Просмотреть файл

@ -1,29 +0,0 @@
/* 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 _NSCERTVERIFICATIONTHREAD_H_
#define _NSCERTVERIFICATIONTHREAD_H_
#include "nsCOMPtr.h"
#include "nsDeque.h"
#include "nsPSMBackgroundThread.h"
#include "nsVerificationJob.h"
class nsCertVerificationThread : public nsPSMBackgroundThread
{
private:
nsDeque mJobQ;
virtual void Run(void);
public:
nsCertVerificationThread();
~nsCertVerificationThread();
static nsCertVerificationThread *verification_thread_singleton;
static nsresult addJob(nsBaseVerificationJob *aJob);
};
#endif

Просмотреть файл

@ -168,20 +168,6 @@ interface nsIX509Cert : nsISupports {
*/
readonly attribute boolean isSelfSigned;
/**
* Constants for certificate verification results.
*/
const unsigned long VERIFIED_OK = 0;
const unsigned long NOT_VERIFIED_UNKNOWN = 1 << 0;
const unsigned long CERT_REVOKED = 1 << 1;
const unsigned long CERT_EXPIRED = 1 << 2;
const unsigned long CERT_NOT_TRUSTED = 1 << 3;
const unsigned long ISSUER_NOT_TRUSTED = 1 << 4;
const unsigned long ISSUER_UNKNOWN = 1 << 5;
const unsigned long INVALID_CA = 1 << 6;
const unsigned long USAGE_NOT_ALLOWED = 1 << 7;
const unsigned long SIGNATURE_ALGORITHM_DISABLED = 1 << 8;
/**
* Constants for specifying the chain mode when exporting a certificate
*/
@ -198,40 +184,6 @@ interface nsIX509Cert : nsISupports {
*/
nsIArray getChain();
/**
* Obtain an array of human readable strings describing
* the certificate's certified usages.
*
* @param localOnly Do not hit the network, even if revocation information
* downloading is currently activated.
* @param verified The certificate verification result, see constants.
* @param count The number of human readable usages returned.
* @param usages The array of human readable usages.
*/
void getUsagesArray(in boolean localOnly,
out uint32_t verified,
out uint32_t count,
[array, size_is(count)] out wstring usages);
/**
* Async version of nsIX509Cert::getUsagesArray()
*
* Will not block, will request results asynchronously,
* availability of results will be notified on the main thread.
*/
void requestUsagesArrayAsync(in nsICertVerificationListener cvl);
/**
* Obtain a single comma separated human readable string describing
* the certificate's certified usages.
*
* @param localOnly Do not hit the network, even if revocation information
* downloading is currently activated.
* @param verified The certificate verification result, see constants.
* @param purposes The string listing the usages.
*/
void getUsagesString(in boolean localOnly, out uint32_t verified, out AString usages);
/**
* A comma separated list of localized strings representing the contents of
* the certificate's key usage extension, if present. The empty string if the
@ -307,43 +259,3 @@ interface nsIX509Cert : nsISupports {
*/
void markForPermDeletion();
};
[scriptable, uuid(2fd0a785-9f2d-4327-8871-8c3e0783891d)]
interface nsICertVerificationResult : nsISupports {
/**
* This interface reflects a container of
* verification results. Call will not block.
*
* Obtain an array of human readable strings describing
* the certificate's certified usages.
*
* Mirrors the results produced by
* nsIX509Cert::getUsagesArray()
*
* As of today, this function is a one-shot object,
* only the first call will succeed.
* This allows an optimization in the implementation,
* ownership of result data will be transfered to caller.
*
* @param cert The certificate that was verified.
* @param verified The certificate verification result,
* see constants in nsIX509Cert.
* @param count The number of human readable usages returned.
* @param usages The array of human readable usages.
*/
void getUsagesArrayResult(out uint32_t verified,
out uint32_t count,
[array, size_is(count)] out wstring usages);
};
[scriptable, uuid(6684bce9-50db-48e1-81b7-98102bf81357)]
interface nsICertVerificationListener : nsISupports {
/**
* Notify that results are ready, that have been requested
* using nsIX509Cert::requestUsagesArrayAsync()
*/
void notify(in nsIX509Cert verifiedCert,
in nsICertVerificationResult result);
};

Просмотреть файл

@ -16,7 +16,6 @@
#include "nsArray.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsCertVerificationThread.h"
#include "nsICertificateDialogs.h"
#include "nsIClassInfoImpl.h"
#include "nsIObjectInputStream.h"
@ -35,7 +34,6 @@
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsUnicharUtils.h"
#include "nsUsageArrayHelper.h"
#include "nsXULAppAPI.h"
#include "nspr.h"
#include "nssb64.h"
@ -1273,90 +1271,6 @@ nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity)
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificate::GetUsagesArray(bool localOnly,
uint32_t* _verified,
uint32_t* _count,
char16_t*** _usages)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
nsresult rv;
const int max_usages = 13;
char16_t* tmpUsages[max_usages];
const char* suffix = "";
uint32_t tmpCount;
nsUsageArrayHelper uah(mCert.get());
rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount,
tmpUsages);
NS_ENSURE_SUCCESS(rv,rv);
if (tmpCount > 0) {
*_usages = (char16_t**) moz_xmalloc(sizeof(char16_t*) * tmpCount);
if (!*_usages)
return NS_ERROR_OUT_OF_MEMORY;
for (uint32_t i=0; i<tmpCount; i++) {
(*_usages)[i] = tmpUsages[i];
}
*_count = tmpCount;
return NS_OK;
}
*_usages = (char16_t**) moz_xmalloc(sizeof(char16_t*));
if (!*_usages)
return NS_ERROR_OUT_OF_MEMORY;
*_count = 0;
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificate::RequestUsagesArrayAsync(
nsICertVerificationListener* aResultListener)
{
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_SAME_THREAD);
if (!aResultListener)
return NS_ERROR_FAILURE;
nsCertVerificationJob* job = new nsCertVerificationJob;
job->mCert = this;
job->mListener =
new nsMainThreadPtrHolder<nsICertVerificationListener>(aResultListener);
nsresult rv = nsCertVerificationThread::addJob(job);
if (NS_FAILED(rv))
delete job;
return rv;
}
NS_IMETHODIMP
nsNSSCertificate::GetUsagesString(bool localOnly, uint32_t* _verified,
nsAString& _usages)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
nsresult rv;
const int max_usages = 13;
char16_t* tmpUsages[max_usages];
const char* suffix = "_p";
uint32_t tmpCount;
nsUsageArrayHelper uah(mCert.get());
rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount,
tmpUsages);
NS_ENSURE_SUCCESS(rv,rv);
_usages.Truncate();
for (uint32_t i=0; i<tmpCount; i++) {
if (i>0) _usages.Append(',');
_usages.Append(tmpUsages[i]);
free(tmpUsages[i]);
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificate::GetASN1Structure(nsIASN1Object** aASN1Structure)
{

Просмотреть файл

@ -184,21 +184,6 @@ nsNSSCertificateFakeTransport::GetValidity(nsIX509CertValidity**)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetUsagesArray(bool, uint32_t*, uint32_t*,
char16_t***)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetUsagesString(bool, uint32_t*, nsAString&)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetKeyUsages(nsAString&)
{
@ -362,14 +347,6 @@ nsNSSCertificateFakeTransport::GetIsBuiltInRoot(bool* aIsBuiltInRoot)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::RequestUsagesArrayAsync(
nsICertVerificationListener*)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetAllTokenNames(unsigned int*, char16_t***)
{

Просмотреть файл

@ -23,7 +23,6 @@
#include "mozilla/unused.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsCRT.h"
#include "nsCertVerificationThread.h"
#include "nsClientAuthRemember.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceDefs.h"
@ -250,12 +249,11 @@ GetRevocationBehaviorFromPrefs(/*out*/ CertVerifier::OcspDownloadConfig* odc,
}
nsNSSComponent::nsNSSComponent()
:mutex("nsNSSComponent.mutex"),
mNSSInitialized(false),
: mutex("nsNSSComponent.mutex")
, mNSSInitialized(false)
#ifndef MOZ_NO_SMART_CARDS
mThreadList(nullptr),
, mThreadList(nullptr)
#endif
mCertVerificationThread(nullptr)
{
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ctor\n"));
@ -263,40 +261,9 @@ nsNSSComponent::nsNSSComponent()
++mInstanceCount;
}
void
nsNSSComponent::deleteBackgroundThreads()
{
if (mCertVerificationThread)
{
mCertVerificationThread->requestExit();
delete mCertVerificationThread;
mCertVerificationThread = nullptr;
}
}
void
nsNSSComponent::createBackgroundThreads()
{
NS_ASSERTION(!mCertVerificationThread,
"Cert verification thread already created.");
mCertVerificationThread = new nsCertVerificationThread;
nsresult rv = mCertVerificationThread->startThread(
NS_LITERAL_CSTRING("Cert Verify"));
if (NS_FAILED(rv)) {
delete mCertVerificationThread;
mCertVerificationThread = nullptr;
}
}
nsNSSComponent::~nsNSSComponent()
{
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor\n"));
NS_ASSERTION(!mCertVerificationThread,
"Cert verification thread should have been cleaned up.");
deleteBackgroundThreads();
// All cleanup code requiring services needs to happen in xpcom_shutdown
@ -1945,13 +1912,6 @@ nsNSSComponent::Init()
RememberCertErrorsTable::Init();
createBackgroundThreads();
if (!mCertVerificationThread) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("nsNSSComponent::createBackgroundThreads() failed\n"));
return NS_ERROR_OUT_OF_MEMORY;
}
return RegisterObservers();
}
@ -1969,14 +1929,7 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("receiving profile change topic\n"));
DoProfileBeforeChange();
} else if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: XPCom shutdown observed\n"));
// Cleanup code that requires services, it's too late in destructor.
deleteBackgroundThreads();
}
else if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
} else if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
nsNSSShutDownPreventionLock locker;
bool clearSessionCache = true;
NS_ConvertUTF16toUTF8 prefName(someData);
@ -2117,7 +2070,6 @@ nsNSSComponent::RegisterObservers()
// Using false for the ownsweak parameter means the observer service will
// keep a strong reference to this component. As a result, this will live at
// least as long as the observer service.
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
return NS_OK;

Просмотреть файл

@ -105,7 +105,6 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID)
class nsNSSShutDownList;
class nsCertVerificationThread;
// Implementation of the PSM component interface.
class nsNSSComponent final : public nsINSSComponent
@ -215,10 +214,6 @@ private:
#endif
nsString mContentSigningRootHash;
void deleteBackgroundThreads();
void createBackgroundThreads();
nsCertVerificationThread* mCertVerificationThread;
nsNSSHttpInterface mHttpForNSS;
RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;

Просмотреть файл

@ -1,238 +0,0 @@
/* 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 "nsUsageArrayHelper.h"
#include "ScopedNSSTypes.h"
#include "mozilla/Assertions.h"
#include "nsCOMPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsDateTimeFormatCID.h"
#include "nsIDateTimeFormat.h"
#include "nsNSSCertificate.h"
#include "nsReadableUtils.h"
#include "nsServiceManagerUtils.h"
#include "nspr.h"
#include "pkix/pkixnss.h"
#include "secerr.h"
using namespace mozilla;
using namespace mozilla::psm;
extern LazyLogModule gPIPNSSLog;
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); // XXX? needed?::
nsUsageArrayHelper::nsUsageArrayHelper(CERTCertificate *aCert)
:mCert(aCert)
{
nsNSSShutDownPreventionLock locker;
defaultcertdb = CERT_GetDefaultCertDB();
nssComponent = do_GetService(kNSSComponentCID, &m_rv);
}
namespace {
// Some validation errors are non-fatal in that, we should keep checking the
// cert for other usages after receiving them; i.e. they are errors that NSS
// returns when a certificate isn't valid for a particular usage, but which
// don't indicate that the certificate is invalid for ANY usage. Others errors
// (e.g. revocation) are fatal, and we should immediately stop validation of
// the cert when we encounter them.
bool
isFatalError(uint32_t checkResult)
{
return checkResult != nsIX509Cert::VERIFIED_OK &&
checkResult != nsIX509Cert::USAGE_NOT_ALLOWED &&
checkResult != nsIX509Cert::ISSUER_NOT_TRUSTED &&
checkResult != nsIX509Cert::ISSUER_UNKNOWN;
}
} // unnamed namespace
// Validates the certificate for the given usage. If the certificate is valid
// for the given usage, aCounter is incremented, a string description of the
// usage is appended to outUsages, and nsNSSCertificate::VERIFIED_OK is
// returned. Otherwise, if validation failed, one of the other "Constants for
// certificate verification results" in nsIX509Cert is returned.
uint32_t
nsUsageArrayHelper::check(uint32_t previousCheckResult,
const char *suffix,
CertVerifier * certVerifier,
SECCertificateUsage aCertUsage,
mozilla::pkix::Time time,
CertVerifier::Flags flags,
uint32_t &aCounter,
char16_t **outUsages)
{
if (!aCertUsage) {
MOZ_CRASH("caller should have supplied non-zero aCertUsage");
}
if (isFatalError(previousCheckResult)) {
return previousCheckResult;
}
nsAutoCString typestr;
switch (aCertUsage) {
case certificateUsageSSLClient:
typestr = "VerifySSLClient";
break;
case certificateUsageSSLServer:
typestr = "VerifySSLServer";
break;
case certificateUsageEmailSigner:
typestr = "VerifyEmailSigner";
break;
case certificateUsageEmailRecipient:
typestr = "VerifyEmailRecip";
break;
case certificateUsageObjectSigner:
typestr = "VerifyObjSign";
break;
case certificateUsageSSLCA:
typestr = "VerifySSLCA";
break;
case certificateUsageVerifyCA:
typestr = "VerifyCAVerifier";
break;
case certificateUsageStatusResponder:
typestr = "VerifyStatusResponder";
break;
default:
MOZ_CRASH("unknown cert usage passed to check()");
}
UniqueCERTCertList unusedBuiltChain;
SECStatus rv = certVerifier->VerifyCert(mCert, aCertUsage, time,
nullptr /*XXX:wincx*/,
nullptr /*hostname*/,
unusedBuiltChain, flags);
if (rv == SECSuccess) {
typestr.Append(suffix);
nsAutoString verifyDesc;
m_rv = nssComponent->GetPIPNSSBundleString(typestr.get(), verifyDesc);
if (NS_SUCCEEDED(m_rv)) {
outUsages[aCounter++] = ToNewUnicode(verifyDesc);
}
return nsIX509Cert::VERIFIED_OK;
}
PRErrorCode error = PR_GetError();
uint32_t result = nsIX509Cert::NOT_VERIFIED_UNKNOWN;
verifyFailed(&result, error);
// USAGE_NOT_ALLOWED is the weakest non-fatal error; let all other errors
// override it.
if (result == nsIX509Cert::USAGE_NOT_ALLOWED &&
previousCheckResult != nsIX509Cert::VERIFIED_OK) {
result = previousCheckResult;
}
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("error validating certificate for usage %s: %s (%d) -> %ud \n",
typestr.get(), PR_ErrorToName(error), (int) error, (int) result));
return result;
}
// Maps the error code to one of the Constants for certificate verification
// results" in nsIX509Cert.
void
nsUsageArrayHelper::verifyFailed(uint32_t *_verified, int err)
{
switch (err) {
/* For these cases, verify only failed for the particular usage */
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SEC_ERROR_INADEQUATE_CERT_TYPE:
case SEC_ERROR_CA_CERT_INVALID:
case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY:
case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE:
case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA:
*_verified = nsNSSCertificate::USAGE_NOT_ALLOWED; break;
/* These are the cases that have individual error messages */
case SEC_ERROR_REVOKED_CERTIFICATE:
*_verified = nsNSSCertificate::CERT_REVOKED; break;
case SEC_ERROR_EXPIRED_CERTIFICATE:
*_verified = nsNSSCertificate::CERT_EXPIRED; break;
case SEC_ERROR_UNTRUSTED_CERT:
*_verified = nsNSSCertificate::CERT_NOT_TRUSTED; break;
case SEC_ERROR_UNTRUSTED_ISSUER:
*_verified = nsNSSCertificate::ISSUER_NOT_TRUSTED; break;
case SEC_ERROR_UNKNOWN_ISSUER:
*_verified = nsNSSCertificate::ISSUER_UNKNOWN; break;
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
// XXX are there other error for this?
*_verified = nsNSSCertificate::INVALID_CA; break;
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
*_verified = nsNSSCertificate::SIGNATURE_ALGORITHM_DISABLED; break;
default:
*_verified = nsNSSCertificate::NOT_VERIFIED_UNKNOWN; break;
}
}
nsresult
nsUsageArrayHelper::GetUsagesArray(const char *suffix,
bool localOnly,
uint32_t outArraySize,
uint32_t *_verified,
uint32_t *_count,
char16_t **outUsages)
{
nsNSSShutDownPreventionLock locker;
if (NS_FAILED(m_rv))
return m_rv;
NS_ENSURE_TRUE(nssComponent, NS_ERROR_NOT_AVAILABLE);
if (outArraySize < max_returned_out_array_size)
return NS_ERROR_FAILURE;
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
uint32_t &count = *_count;
count = 0;
mozilla::pkix::Time now(mozilla::pkix::Now());
CertVerifier::Flags flags = localOnly ? CertVerifier::FLAG_LOCAL_ONLY : 0;
// The following list of checks must be < max_returned_out_array_size
uint32_t result;
result = check(nsIX509Cert::VERIFIED_OK, suffix, certVerifier,
certificateUsageSSLClient, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageSSLServer, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageEmailSigner, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageEmailRecipient, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageObjectSigner, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageSSLCA, now, flags, count, outUsages);
result = check(result, suffix, certVerifier,
certificateUsageStatusResponder, now, flags, count, outUsages);
if (isFatalError(result) || count == 0) {
MOZ_ASSERT(result != nsIX509Cert::VERIFIED_OK);
// Clear the output usage strings in the case where we encountered a fatal
// error after we already successfully validated the cert for some usages.
for (uint32_t i = 0; i < count; ++i) {
delete outUsages[i];
outUsages[i] = nullptr;
}
count = 0;
*_verified = result;
} else {
*_verified = nsNSSCertificate::VERIFIED_OK;
}
return NS_OK;
}

Просмотреть файл

@ -1,45 +0,0 @@
/* 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 _NSUSAGEARRAYHELPER_H_
#define _NSUSAGEARRAYHELPER_H_
#include "CertVerifier.h"
#include "nsNSSComponent.h"
#include "certt.h"
#include "pkix/Time.h"
class nsUsageArrayHelper
{
public:
explicit nsUsageArrayHelper(CERTCertificate *aCert);
nsresult GetUsagesArray(const char *suffix,
bool localOnly,
uint32_t outArraySize,
uint32_t *_verified,
uint32_t *_count,
char16_t **tmpUsages);
enum { max_returned_out_array_size = 12 };
private:
CERTCertificate *mCert;
nsresult m_rv;
CERTCertDBHandle *defaultcertdb;
nsCOMPtr<nsINSSComponent> nssComponent;
uint32_t check(uint32_t previousCheckResult,
const char *suffix,
mozilla::psm::CertVerifier * certVerifier,
SECCertificateUsage aCertUsage,
mozilla::pkix::Time time,
mozilla::psm::CertVerifier::Flags flags,
uint32_t &aCounter,
char16_t **outUsages);
void verifyFailed(uint32_t *_verified, int err);
};
#endif

Просмотреть файл

@ -5,3 +5,4 @@ support-files = head.js
[browser_bug627234_perwindowpb.js]
[browser_certificateManagerLeak.js]
[browser_certViewer.js]
support-files = *.pem

Просмотреть файл

@ -3,38 +3,265 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var gBugWindow;
// 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.
function onLoad() {
gBugWindow.removeEventListener("load", onLoad);
gBugWindow.addEventListener("unload", onUnload);
gBugWindow.close();
}
var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
function onUnload() {
gBugWindow.removeEventListener("unload", onUnload);
window.focus();
finish();
}
var certificates = [];
// This test opens and then closes the certificate viewer to test that it
// does not cause assertion failures.
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
let certList = certdb.getCerts();
let enumerator = certList.getEnumerator();
ok(enumerator.hasMoreElements(), "we have at least one certificate");
let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
ok(cert, "found a certificate to look at");
info("looking at certificate with nickname " + cert.nickname);
certificates.forEach(cert => {
certdb.deleteCertificate(cert);
});
});
add_task(function* () {
let cert = yield readCertificate("ca.pem", "CTu,CTu,CTu");
let win = yield displayCertificate(cert);
checkUsages(win, ["SSL Certificate Authority"]);
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("ssl-ee.pem", ",,");
let win = yield displayCertificate(cert);
checkUsages(win, ["SSL Server Certificate", "SSL Client Certificate"]);
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("email-ee.pem", ",,");
let win = yield displayCertificate(cert);
checkUsages(win, ["Email Recipient Certificate", "Email Signer Certificate"]);
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("code-ee.pem", ",,");
let win = yield displayCertificate(cert);
checkUsages(win, ["Object Signer"]);
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("expired-ca.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win, "Could not verify this certificate because it has expired.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("ee-from-expired-ca.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because the CA certificate " +
"is invalid.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("unknown-issuer.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because the issuer is " +
"unknown.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("md5-ee.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because it was signed using " +
"a signature algorithm that was disabled because that algorithm " +
"is not secure.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("untrusted-ca.pem", "p,p,p");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because it is not trusted.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
let cert = yield readCertificate("ee-from-untrusted-ca.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because the issuer is not " +
"trusted.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
// Note that there's currently no way to un-do this. This should only be a
// problem if another test re-uses a certificate with this same key (perhaps
// likely) and subject (less likely).
let certBlocklist = Cc["@mozilla.org/security/certblocklist;1"]
.getService(Ci.nsICertBlocklist);
certBlocklist.revokeCertBySubjectAndPubKey(
"MBIxEDAOBgNVBAMMB3Jldm9rZWQ=", // CN=revoked
"VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="); // hash of the shared key
let cert = yield readCertificate("revoked.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win,
"Could not verify this certificate because it has been revoked.");
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* () {
// 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 lame error
// message in this case.
let cert = yield readCertificate("invalid.pem", ",,");
let win = yield displayCertificate(cert);
checkError(win, "Could not verify this certificate for unknown reasons.");
yield BrowserTestUtils.closeWindow(win);
});
/**
* Helper for readCertificate.
*/
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.
*
* @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, "unused");
let cert = certdb.constructX509FromBase64(base64);
certificates.push(cert); // so we remember to delete this at the end
return cert;
}, error => { throw error; });
}
/**
* Given a certificate, returns a promise that will resolve when the certificate
* viewer has opened is displaying that certificate, and has finished
* determining its valid usages.
*
* @param {nsIX509Cert} certificate
* The certificate to view and determine usages for.
* @return {Promise}
* A promise that will resolve with a handle on the opened certificate
* viewer window when the usages have been determined.
*/
function displayCertificate(certificate) {
let array = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
array.appendElement(cert, false);
array.appendElement(certificate, false);
let params = Cc["@mozilla.org/embedcomp/dialogparam;1"]
.createInstance(Ci.nsIDialogParamBlock);
params.objects = array;
gBugWindow = window.openDialog("chrome://pippki/content/certViewer.xul",
"", "", params);
gBugWindow.addEventListener("load", onLoad);
let win = window.openDialog("chrome://pippki/content/certViewer.xul", "",
"", params);
return TestUtils.topicObserved("ViewCertDetails:CertUsagesDone",
(subject, data) => subject == win)
.then(([subject, data]) => subject, error => { throw error; });
}
/**
* Given a certificate viewer window, finds the usages the certificate is valid
* for.
*
* @param {window} win
* The certificate viewer window.
* @return {String[]}
* An array of strings describing the usages the certificate is valid
* for.
*/
function getUsages(win) {
let determinedUsages = [];
let verifyInfoBox = win.document.getElementById("verify_info_box");
Array.from(verifyInfoBox.children).forEach(child => {
if (child.getAttribute("hidden") != "true" &&
child.getAttribute("id") != "verified") {
determinedUsages.push(child.getAttribute("value"));
}
});
return determinedUsages.sort();
}
/**
* Given a certificate viewer window, returns the error string describing a
* failure encountered when determining the certificate's usages. It will be
* "This certificate has been verified for the following uses:" when the
* certificate has successfully verified for at least one usage.
*
* @param {window} win
* The certificate viewer window.
* @return {String}
* A string describing the error encountered, or the success message if
* the certificate is valid for at least one usage.
*/
function getError(win) {
return win.document.getElementById("verified").textContent;
}
/**
* Given a certificate viewer window and an array of expected usage
* descriptions, verifies that the window is actually showing that the
* certificate has validated for those usages.
*
* @param {window} win
* The certificate viewer window.
* @param {String[]} usages
* An array of expected usage descriptions.
*/
function checkUsages(win, usages) {
Assert.equal(getError(win),
"This certificate has been verified for the following uses:",
"should have successful verification message");
let determinedUsages = getUsages(win);
usages.sort();
Assert.equal(determinedUsages.length, usages.length,
"number of usages as determined by cert viewer should be equal");
while (usages.length > 0) {
Assert.equal(determinedUsages.pop(), usages.pop(),
"usages as determined by cert viewer should be equal");
}
}
/**
* Given a certificate viewer window and an expected error, verifies that the
* window is actually showing that error.
*
* @param {window} win
* The certificate viewer window.
* @param {String} error
* The expected error message.
*/
function checkError(win, error) {
let determinedUsages = getUsages(win);
Assert.equal(determinedUsages.length, 0,
"should not have any successful usages in error case");
Assert.equal(getError(win), error,
"determined error should be the same as expected error");
}

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICxTCCAa+gAwIBAgIUQy+m6w0ZtMTfbmtELQQz8zwqCAowCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud
DwQEAwIBBjALBgkqhkiG9w0BAQsDggEBAJQcekrdR+S6U0I3owUQxVOoUJMzHdTj
u562Ra7cOiJQwe1OQZbvo6rQkQWPrpuDOGpwwr1+HBMGb8mjUqeFo5wIinU003TC
UYYEpDCbPwXOKDkDUukKd1aO4wpJc/v8YIiCz7aCRj9HQ3L5YO5JsgMNSCXKKoUm
ILcz2V+IQZ6lePzFfd2aO3zLMDPwEOyujYYtQnBVZIT4F/x/6nU8E6bkbDSGPjQW
CSVhwa0YQ9lCRSM6e//wGry4i8X8718t1V+Nqh7y6u7UlOrXbNEA4pR6mvJsqPhF
Mj82We4OGNBxXbyuGJObQgLBfmRuwKQT9SNtKWEifiaTw8apT/fBagc=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,4 @@
issuer:ca
subject:ca
extension:basicConstraints:cA,
extension:keyUsage:cRLSign,keyCertSign

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICxDCCAa6gAwIBAgIUdey1Pi3nj8syGBLqTY30bbsak7swCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBIxEDAOBgNVBAMMB2NvZGUtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG
AQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAubYFMnDLOK8/99OLWeejdD6HQ8Qg2W4u
7I9hZySo+g0w2U6jvtgSTvUfN/Zk33fSu90yOnWg1v+6tvd/jdwxfooVfz7zNWa9
i6/oSY/0THBhX9bf9b0wHmZLnuhS7AwG6BCbqulQ3xJxCSWUieFTyoMl4UnW64md
QBI+ZkLkS7O71pARnw0SdE4nxO1J8fLPi/7nYHiGfebqcoBC/AUwMM/Zni9KFkgy
/uQRXUylNAgAByIdG6vS4ULgTKh34FS08Ff7/cWZppe9eUogLLQ+J2cyPupN8LYd
hWC1mCbgCX3QqHiHg6ACX05Zc3YFW80ddlczDVNpM09g1GSGYpllng==
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,3 @@
issuer:ca
subject:code-ee
extension:extKeyUsage:codeSigning

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICvjCCAaigAwIBAgIUMUZEIRRo2v0demTGW3vuRccAgCMwCwYJKoZIhvcNAQEL
MBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3
MDIwNDAwMDAwMFowHTEbMBkGA1UEAwwSZWUtZnJvbS1leHBpcmVkLWNhMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq
5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc
An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39
ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk
zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u
JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB
MAsGCSqGSIb3DQEBCwOCAQEABbpfCUwzbTCDWWwBqaY8+3q3PjeQK/QdyI4HSX5C
+dp7LJF+x/24xArqKf8HTuhndprUvlJOFkojK1CLaece7yC1fh/viFZ6NLoTPNXU
cmdEHsrzO4LTOY/eeR9ml7Rx26B50Wva01SyXkW9TZbPGPQysCgD31XkxmzTAG9t
M5kp+XplMd/UEjkNQaXD0lzm3lJ+3n2U6xMmDc+8us0l6X8yBmjjywBWTSX+U83a
eZXMpU40Y4ZHyNqfALGZUG22trd+68YVvK7jmnbk9fu/FZkjh0qiPlAUJXg0OybW
YHerQxXuf+5+ftPTDkzyPY9txQGFoqY8k3zVQNw33wFzGQ==
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,2 @@
issuer:expired-ca
subject:ee-from-expired-ca

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICwjCCAaygAwIBAgIUTUHM6wHTfIkC0P4Z9VRrPJV6O6IwCwYJKoZIhvcNAQEL
MBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTAiGA8yMDE0MTEyNzAwMDAwMFoYDzIw
MTcwMjA0MDAwMDAwWjAfMR0wGwYDVQQDDBRlZS1mcm9tLXVudHJ1c3RlZC1jYTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9
PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3
HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg
Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7
EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK
lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C
AwEAATALBgkqhkiG9w0BAQsDggEBAJlRi+i7+kPXxfx6If69aQMsAIYwBXhbeHJr
TfaljltazfCirKB1hDb/pTYmSFMWDO+C9GIRBBKWR4+rR6D8n1qiJOJqe+QHtQam
BPi8xMTHEkNVTEax+Ux2im21BPUU8xFzCta/STMCt2E+6g832JX1XxLxRlp631Vn
pF9MFZU9HQqW4z8YBPPKE4ny9eBOGH/PzYHETL5AgJn1K5iRFZjA94iwqsHvJ/6v
AY1b5hw1slwem9ZWYcoUUl3YAV7sF3pIbakrRSjU3HEfGcDUDOePrBZekJhICwK4
xs2cqEX0FLZqsNiS7rpfRZXt4Ufl6V3G8MEO010lICk9ZuHr9vc=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,2 @@
issuer:untrusted-ca
subject:ee-from-untrusted-ca

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICxTCCAa+gAwIBAgIUI2oh2cgrnM8p3D/8Ijd06wwY/UQwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBMxETAPBgNVBAMMCGVtYWlsLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf
vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb
uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S
O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR
3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv
5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxcwFTATBgNVHSUEDDAKBggr
BgEFBQcDBDALBgkqhkiG9w0BAQsDggEBAIpPVolSwoZTwhouPemDUJTP8cZ/IPTg
0GvzU07GH7y0Q9svPEBELRdgdHTWk3s5FaLgVGYStzs9OOpNj4fiP+CUJIwKlm6L
Kt4mPganE67SRvHHYMzH+jjaL+xNl0Wa0O9ms+k+DQ+zB57hX8qE1oMszq00jZxH
VIRl767e66Jgh89ac5BGoj1KXJxtUIocTKC+fMgUHbQ4oZ2v1IU2CeE6k2cvWvcU
gclagK4EgWzIL8O2HLTLkLN163yWBYiOWQTOI+hCqsLz1OeU+J8pZ/eEYemeUV7g
opZ5aLRzvXAkNz/eaeygEAu+6wkqVj3Btcabvx7dxmLkwDV8PjJsscs=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,3 @@
issuer:ca
subject:email-ee
extension:extKeyUsage:emailProtection

Просмотреть файл

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICzTCCAbegAwIBAgIUAfElDw37NeFULPHd+G2eoaHpvEYwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTAwMTAxMDAwMDAwWhgPMjAxMTAxMDEwMDAw
MDBaMBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg
2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ
5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ
PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj
DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W
iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMB
Af8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEBCwOCAQEAde8CQNB8dVo5ly7Lu8x9
5yDz2hpzAqqPDxP3+UqxzEgXeA4vfv1Bzvmxx69XEd+884M9Lkt2WBTrc+OrAgqX
pCCt4X8bjV2t+mG1shtYEGKk5BtRVnorHhZyf6+5xtOfpV9DeWkf/aA1SJK1Kpt3
cNSDW10PwaGuaNiUMEtIFLD/MYZCM98RFOSVDWjqafbfUBn4ZSeoyRi1C2d3lg0C
jRFmOc1I4DQOUezp3C0WyCumJ0SLTIoYJGdAshMbDWPr0OOaB4GmI8miKhS6LM59
o6C3fU8MJrRYKctYj0k9gW0DI6KuEFZj2AY8brv6Ufx1TKy5Z2pqIPeUbuJInCXM
qA==
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,5 @@
issuer:ca
subject:expired-ca
extension:basicConstraints:cA,
extension:keyUsage:cRLSign,keyCertSign
validity:20100101-20110101

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICvDCCAaagAwIBAgIUI3mu28hwWjSE4ii2aLFNdXKo79MwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBIxEDAOBgNVBAMMB2ludmFsaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwIBBjAL
BgkqhkiG9w0BAQsDggEBACKFOLNLmPB5hFhmP3cruJydC3/5/1sKPmig+c5MMBKN
hgKaPhU6JalCdrHK+httffvjwXkPRdqWHWM9ILcDcAuYzJqIMofiFlW6gthTvvdP
sqkqXdxC2S00Dc55z47mKbLPkZm7/HMSOAya6oghywLuL3US6cmKrYZZbFqrecWc
GIja9MtthFcoS84u+GmV3pRiU+sDvwo67u7R3recmAPDU75r9Yhh68H/urKoRhre
+10QOfQ0GGM80RP2fXg6P9MXI7/MEd8QTlUOK8xWrU6Q30R5BzF6lgwUqF5VoVxb
WMPdPIS5gFktfqNituRNdMKlIFQ6f7YjaILDcu3upe0=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,3 @@
issuer:ca
subject:invalid
extension:keyUsage:cRLSign,keyCertSign

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICqjCCAZSgAwIBAgIUT89onfON5U+5LLJ7imzzschILDgwCwYJKoZIhvcNAQEE
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBExDzANBgNVBAMMBm1kNS1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG9w0BAQQDggEBAB4q
QfSzrkQOHwIeVw/W1bpAzJ5Al92wDUNQEcw7JmZZ6Oz3bH+spBhq6xTnXqhMjCYM
srINOlc+u/W6TqE1uPWPZvX1M9VFCWR5okXoFbc+8l6er5tun6tP7oWs7TxXzy7O
e0GimlZ3W+LqA2ICynSYaULipFAJUvmmyFxlC3yPIawncpBWwPofPpGziF0FImSW
PMslU5PExu982go8a6hfNAYEYH8bKetlfFPJ0DHe7/crmjE3NulnHt7HVh11OkuR
FkjVTnuOoHGG4Z4tekPP0g1P+9m3EdTuP9Nk8hTZBThmRdAWIeBaefJJmZ91gJqA
txFeIhOo4f1whxqNDk4=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,3 @@
issuer:ca
subject:md5-ee
signature:md5WithRSAEncryption

Просмотреть файл

@ -6,3 +6,25 @@
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',
# 'code-ee.pem',
# 'ee-from-expired-ca.pem',
# 'ee-from-untrusted-ca.pem',
# 'email-ee.pem',
# 'expired-ca.pem',
# 'invalid.pem',
# 'md5-ee.pem',
# 'revoked.pem',
# 'ssl-ee.pem',
# 'unknown-issuer.pem',
# 'untrusted-ca.pem',
#)
#
#for test_certificate in test_certificates:
# GeneratedTestCertificate(test_certificate)

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICqzCCAZWgAwIBAgIUIYb+7rSz8q+7zTVh7KE/MZTclrAwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBIxEDAOBgNVBAMMB3Jldm9rZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQBF
h+yu2y2s3gulEXR80Hmm45+B/egT1K2fjoz8X5BcbqT5BcbPB4utokvUQq3W6uyr
AHVmo55vpgbWp1Thz0RoHGZ5kkYlcrYy1S7sfuoowoMXv8iWu9DSyXqhqSUhYp9F
9sov5d5lyeHLAekss1Aaybq0vh1O1tHtKHoanlfn5HEBDjbNpQozPh/kGQTuSZVY
e9Ikh1lFNsUCzCElC+wdkATQbo5PpGEsJqk5bmz7W9l90j7+JFdH5onIFD4gSOK8
2hsPCFDhmnma8/CvAY08hwEYmb26gnGQbVusIPr+Ui7LjUqW9b6XAdon2teXXEoa
vCp11ICfcHvIHhoLDjkC
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,2 @@
issuer:ca
subject:revoked

Просмотреть файл

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICzTCCAbegAwIBAgIUZ71J5xveWHK5SkrwbRXbsbUtrlgwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBExDzANBgNVBAMMBnNzbC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMhMB8wHQYDVR0lBBYwFAYIKwYB
BQUHAwEGCCsGAQUFBwMCMAsGCSqGSIb3DQEBCwOCAQEAkDks1086hp7MS0anvQw8
XnkD8ItCFkcVk3aPdLlwODBGqDvrjIR9kCX2aJzdChiCnKPtN5pDiyfb/e+lJ4zN
qXoSP2ksYbFtFr7Vp/eDEI9iwvFTEubYgq9Y8etInetFxEqRQPDtAYtZF7P6i1su
FZUHlHYHsVmCCXXlhTy6BhmJCj0ANaquHHuACty55uNw2IbNYUKN7xp1qOJO2TUc
ip4fybk+Rdm5fJOj48W7uUBpvzfnLI/ifABuVRy2koZvIewjAwwPZ8ggWyi6PHT3
iLrLmorNMDWTWN898zO09skrcobFKrWJCuSafAeZYCYHDC7x1uVlLDM+v6N+fN14
RA==
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,3 @@
issuer:ca
subject:ssl-ee
extension:extKeyUsage:serverAuth,clientAuth

Просмотреть файл

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICtzCCAaGgAwIBAgIUc97erK6I1KzZpBDPfRQkFj/yzHQwCwYJKoZIhvcNAQEL
MBIxEDAOBgNVBAMMB3Vua25vd24wIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
NDAwMDAwMFowGTEXMBUGA1UEAwwOdW5rbm93bi1pc3N1ZXIwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo
V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p
0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk
fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh
W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI
TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZI
hvcNAQELA4IBAQAzi/BVt5ZYRAbAI1sue6Qduqlk6OwVuROZS92xoo1G+bqJuMvv
K1jiJWeZn1xGGrZcCeyTnf+Qst4Hd34PLApNHfDPdNW9C7QiTUva4GELCZsCS0+b
hkX1W62OCS2gY64KVriAzbdKgx8nWhxlEa8zKBJEhWsX0t6PmjCxTEp1uyyJDlgg
vG4OEvUxywbk/MDnsjs7pJ3jUZ3DVQb9t6+z5w29AL7qpzo0CZ77YEuZsV6IuAtg
mNG1jfg7EkWBuxhHoI9UCqMquS4S9IHhuaDQ/qK8hBvjXTRsXyCKuwvIcxEns2aq
1fIW02nd0nX6+UxASTfY+grYNE8US2XFluE3
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,2 @@
issuer:unknown
subject:unknown-issuer

Просмотреть файл

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICzzCCAbmgAwIBAgIUC/H/PjmG29sIm7mYo9C4emq7th8wCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
MDBaMBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl
qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg
w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx
V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1
MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs
vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw
AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQB0kH+mBoFNCKtakbPa
WoptSlYB3v0Hivr64+6RGgbE1Ns0ZcEUpid/0PYCPo+2LE7Db6LRMmygQZ67G5Wq
SQN9Wb2WR/RqwikX+UbsbRuTElM+QMQ2AmOKBjmF7krzixq3zP9/c+CtSN4+E6Qo
XvH6GO3HWJ/7QdS/oGgbP63O9BszCOmZRAjNcBstwiVSxKSvJHpelbHsN7Ml4k0c
CXRkxIebfNUcHSSAgDme7f0bGgG8XJSGONebLAJgQcq59EHYD5sE2xR0rF2lmFEq
LO5IlW7TfTEGSQyinYO09nXcwuIbyFdYKaEBtE+ol6GIQyZGcb2AqSVXiseEWVId
B0CN
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,4 @@
issuer:ca
subject:untrusted-ca
extension:basicConstraints:cA,
extension:keyUsage:cRLSign,keyCertSign

Просмотреть файл

@ -35,6 +35,7 @@
"requestLongerTimeout": false,
"SimpleTest": false,
"SpecialPowers": false,
"TestUtils": false,
"thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
"todo": false,
"todo_is": false,