Bug 1641082 - remove old certificate viewer implementation r=kjacobs,bbeurdouche,fluent-reviewers,johannh

Differential Revision: https://phabricator.services.mozilla.com/D77145
This commit is contained in:
Dana Keeler 2020-06-02 15:48:33 +00:00
parent 34022695b5
commit 0618ab7fe8
38 changed files with 60 additions and 4257 deletions

View File

@ -294,27 +294,14 @@ class NetErrorParent extends JSWindowActorParent {
let securityInfo = this.getSecurityInfo(
message.data.securityInfoAsString
);
let cert = securityInfo.serverCert;
if (
Services.prefs.getBoolPref("security.aboutcertificate.enabled")
) {
let certChain = securityInfo.failedCertChain;
let certs = certChain.map(elem =>
encodeURIComponent(elem.getBase64DERString())
);
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
window.switchToTabHavingURI(url, true, {});
} else {
Services.ww.openWindow(
window,
"chrome://pippki/content/certViewer.xhtml",
"_blank",
"centerscreen,chrome",
cert
);
}
let certChain = securityInfo.failedCertChain;
let certs = certChain.map(elem =>
encodeURIComponent(elem.getBase64DERString())
);
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
window.switchToTabHavingURI(url, true, {});
break;
}
}

View File

@ -989,8 +989,6 @@ pref("security.certerrors.mitm.priming.enabled", true);
pref("security.certerrors.mitm.priming.endpoint", "https://mitmdetection.services.mozilla.com/");
pref("security.certerrors.mitm.auto_enable_enterprise_roots", true);
pref("security.aboutcertificate.enabled", true);
// Whether the bookmark panel should be shown when bookmarking a page.
pref("browser.bookmarks.editDialog.showForNewBookmarks", true);

View File

@ -31,25 +31,15 @@ var security = {
},
viewCert() {
if (Services.prefs.getBoolPref("security.aboutcertificate.enabled")) {
let certChain = this.securityInfo.certChain;
let certs = certChain.map(elem =>
encodeURIComponent(elem.getBase64DERString())
);
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
let win = BrowserWindowTracker.getTopWindow();
win.switchToTabHavingURI(url, true, {});
} else {
Services.ww.openWindow(
window,
"chrome://pippki/content/certViewer.xhtml",
"_blank",
"centerscreen,chrome",
this.securityInfo.cert
);
}
let certChain = this.securityInfo.certChain;
let certs = certChain.map(elem =>
encodeURIComponent(elem.getBase64DERString())
);
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
let win = BrowserWindowTracker.getTopWindow();
win.switchToTabHavingURI(url, true, {});
},
async _getSecurityInfo() {

View File

@ -384,9 +384,6 @@ add_task(async function checkCautionClass() {
add_task(async function checkViewCertificate() {
info("Loading a cert error and checking that the certificate can be shown.");
SpecialPowers.pushPrefEnv({
set: [["security.aboutcertificate.enabled", true]],
});
for (let useFrame of [true, false]) {
if (useFrame) {
// Bug #1573502

View File

@ -23,9 +23,6 @@ const TEST_PATH = getRootDirectory(gTestPath).replace(
// Test opening the correct certificate information when clicking "Show certificate".
add_task(async function test_ShowCertificate() {
SpecialPowers.pushPrefEnv({
set: [["security.aboutcertificate.enabled", true]],
});
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_ORIGIN);
let tab2;
let pageLoaded;

View File

@ -59,69 +59,7 @@ Fips140SlotDescription=FIPS 140 Cryptographic, Key and Certificate Services
# LOCALIZATION NOTE (nick_template): $1s is the common name from a cert (e.g. "Mozilla"), $2s is the CA name (e.g. VeriSign)
nick_template=%1$ss %2$s ID
#These are the strings set for the ASN1 objects in a certificate.
CertDumpCertificate=Certificate
CertDumpVersion=Version
# LOCALIZATION NOTE (CertDumpVersionValue): %S is a version number (e.g. "3" in "Version 3")
CertDumpVersionValue=Version %S
CertDumpSerialNo=Serial Number
CertDumpMD2WithRSA=PKCS #1 MD2 With RSA Encryption
CertDumpMD5WithRSA=PKCS #1 MD5 With RSA Encryption
CertDumpSHA1WithRSA=PKCS #1 SHA-1 With RSA Encryption
CertDumpSHA256WithRSA=PKCS #1 SHA-256 With RSA Encryption
CertDumpSHA384WithRSA=PKCS #1 SHA-384 With RSA Encryption
CertDumpSHA512WithRSA=PKCS #1 SHA-512 With RSA Encryption
CertDumpDefOID=Object Identifier (%S)
CertDumpIssuer=Issuer
CertDumpSubject=Subject
CertDumpAVACountry=C
CertDumpAVAState=ST
CertDumpAVALocality=L
CertDumpAVAOrg=O
CertDumpAVAOU=OU
CertDumpAVACN=CN
CertDumpUserID=UID
CertDumpPK9Email=E
CertDumpAVADN=DN
CertDumpAVADC=DC
CertDumpSurname=Surname
CertDumpGivenName=Given Name
CertDumpValidity=Validity
CertDumpNotBefore=Not Before
CertDumpNotAfter=Not After
CertDumpSPKI=Subject Public Key Info
CertDumpSPKIAlg=Subject Public Key Algorithm
CertDumpAlgID=Algorithm Identifier
CertDumpParams=Algorithm Parameters
CertDumpRSAEncr=PKCS #1 RSA Encryption
CertDumpRSAPSSSignature=PKCS #1 RSASSA-PSS Signature
CertDumpRSATemplate=Modulus (%S bits):\n%S\nExponent (%S bits):\n%S
CertDumpECTemplate=Key size: %S bits\nBase point order length: %S bits\nPublic value:\n%S
CertDumpIssuerUniqueID=Issuer Unique ID
CertDumpSubjPubKey=Subjects Public Key
CertDumpSubjectUniqueID=Subject Unique ID
CertDumpExtensions=Extensions
CertDumpSubjectDirectoryAttr=Certificate Subject Directory Attributes
CertDumpSubjectKeyID=Certificate Subject Key ID
CertDumpKeyUsage=Certificate Key Usage
CertDumpSubjectAltName=Certificate Subject Alt Name
CertDumpIssuerAltName=Certificate Issuer Alt Name
CertDumpBasicConstraints=Certificate Basic Constraints
CertDumpNameConstraints=Certificate Name Constraints
CertDumpCrlDistPoints=CRL Distribution Points
CertDumpCertPolicies=Certificate Policies
CertDumpPolicyMappings=Certificate Policy Mappings
CertDumpPolicyConstraints=Certificate Policy Constraints
CertDumpAuthKeyID=Certificate Authority Key Identifier
CertDumpExtKeyUsage=Extended Key Usage
CertDumpAuthInfoAccess=Authority Information Access
CertDumpAnsiX9DsaSignature=ANSI X9.57 DSA Signature
CertDumpAnsiX9DsaSignatureWithSha1=ANSI X9.57 DSA Signature with SHA1 Digest
CertDumpAnsiX962ECDsaSignatureWithSha1=ANSI X9.62 ECDSA Signature with SHA1
CertDumpAnsiX962ECDsaSignatureWithSha224=ANSI X9.62 ECDSA Signature with SHA224
CertDumpAnsiX962ECDsaSignatureWithSha256=ANSI X9.62 ECDSA Signature with SHA256
CertDumpAnsiX962ECDsaSignatureWithSha384=ANSI X9.62 ECDSA Signature with SHA384
CertDumpAnsiX962ECDsaSignatureWithSha512=ANSI X9.62 ECDSA Signature with SHA512
CertDumpKUSign=Signing
CertDumpKUNonRep=Non-repudiation
CertDumpKUEnc=Key Encipherment
@ -129,124 +67,6 @@ CertDumpKUDEnc=Data Encipherment
CertDumpKUKA=Key Agreement
CertDumpKUCertSign=Certificate Signer
CertDumpKUCRLSigner=CRL Signer
CertDumpCritical=Critical
CertDumpNonCritical=Not Critical
CertDumpSigAlg=Certificate Signature Algorithm
CertDumpCertSig=Certificate Signature Value
CertDumpExtensionFailure=Error: Unable to process extension
CertDumpIsCA=Is a Certificate Authority
CertDumpIsNotCA=Is not a Certificate Authority
CertDumpPathLen=Maximum number of intermediate CAs: %S
CertDumpPathLenUnlimited=unlimited
CertDumpEKU_1_3_6_1_5_5_7_3_1=TLS Web Server Authentication
CertDumpEKU_1_3_6_1_5_5_7_3_2=TLS Web Client Authentication
CertDumpEKU_1_3_6_1_5_5_7_3_3=Code Signing
CertDumpEKU_1_3_6_1_5_5_7_3_4=E-mail protection
CertDumpEKU_1_3_6_1_5_5_7_3_8=Time Stamping
CertDumpEKU_1_3_6_1_5_5_7_3_9=OCSP Signing
CertDumpEKU_1_3_6_1_4_1_311_2_1_21=Microsoft Individual Code Signing
CertDumpEKU_1_3_6_1_4_1_311_2_1_22=Microsoft Commercial Code Signing
CertDumpEKU_1_3_6_1_4_1_311_10_3_1=Microsoft Trust List Signing
CertDumpEKU_1_3_6_1_4_1_311_10_3_2=Microsoft Time Stamping
CertDumpEKU_1_3_6_1_4_1_311_10_3_3=Microsoft Server Gated Crypto
CertDumpEKU_1_3_6_1_4_1_311_10_3_4=Microsoft Encrypting File System
CertDumpEKU_1_3_6_1_4_1_311_10_3_4_1=Microsoft File Recovery
CertDumpEKU_1_3_6_1_4_1_311_10_3_5=Microsoft Windows Hardware Driver Verification
CertDumpEKU_1_3_6_1_4_1_311_10_3_10=Microsoft Qualified Subordination
CertDumpEKU_1_3_6_1_4_1_311_10_3_11=Microsoft Key Recovery
CertDumpEKU_1_3_6_1_4_1_311_10_3_12=Microsoft Document Signing
CertDumpEKU_1_3_6_1_4_1_311_10_3_13=Microsoft Lifetime Signing
CertDumpEKU_1_3_6_1_4_1_311_20_2_2=Microsoft Smart Card Logon
CertDumpEKU_1_3_6_1_4_1_311_21_6=Microsoft Key Recovery Agent
CertDumpMSCerttype=Microsoft Certificate Template Name
CertDumpMSNTPrincipal=Microsoft Principal Name
CertDumpMSCAVersion=Microsoft CA Version
CertDumpMSDomainGUID=Microsoft Domain GUID
CertDumpEKU_2_16_840_1_113730_4_1=Netscape Server Gated Crypto
CertDumpRFC822Name=E-Mail Address
CertDumpDNSName=DNS Name
CertDumpX400Address=X.400 Address
CertDumpDirectoryName=X.500 Name
CertDumpEDIPartyName=EDI Party Name
CertDumpURI=URI
CertDumpIPAddress=IP Address
CertDumpRegisterID=Registered OID
CertDumpKeyID=Key ID
CertDumpVerisignNotices=Verisign User Notices
CertDumpUnused=Unused
CertDumpKeyCompromise=Key Compromise
CertDumpCACompromise=CA Compromise
CertDumpAffiliationChanged=Affiliation Changed
CertDumpSuperseded=Superseded
CertDumpCessation=Cessation of Operation
CertDumpHold=Certificate Hold
CertDumpOCSPResponder=OCSP
CertDumpCAIssuers=CA Issuers
CertDumpCPSPointer=Certification Practice Statement pointer
CertDumpUserNotice=User Notice
CertDumpLogotype=Logotype
CertDumpECPublicKey=Elliptic Curve Public Key
CertDumpECDSAWithSHA1=X9.62 ECDSA Signature with SHA1
CertDumpECprime192v1=ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)
CertDumpECprime192v2=ANSI X9.62 elliptic curve prime192v2
CertDumpECprime192v3=ANSI X9.62 elliptic curve prime192v3
CertDumpECprime239v1=ANSI X9.62 elliptic curve prime239v1
CertDumpECprime239v2=ANSI X9.62 elliptic curve prime239v2
CertDumpECprime239v3=ANSI X9.62 elliptic curve prime239v3
CertDumpECprime256v1=ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)
CertDumpECsecp112r1=SECG elliptic curve secp112r1
CertDumpECsecp112r2=SECG elliptic curve secp112r2
CertDumpECsecp128r1=SECG elliptic curve secp128r1
CertDumpECsecp128r2=SECG elliptic curve secp128r2
CertDumpECsecp160k1=SECG elliptic curve secp160k1
CertDumpECsecp160r1=SECG elliptic curve secp160r1
CertDumpECsecp160r2=SECG elliptic curve secp160r2
CertDumpECsecp192k1=SECG elliptic curve secp192k1
CertDumpECsecp224k1=SECG elliptic curve secp224k1
CertDumpECsecp224r1=SECG elliptic curve secp224r1 (aka NIST P-224)
CertDumpECsecp256k1=SECG elliptic curve secp256k1
CertDumpECsecp384r1=SECG elliptic curve secp384r1 (aka NIST P-384)
CertDumpECsecp521r1=SECG elliptic curve secp521r1 (aka NIST P-521)
CertDumpECc2pnb163v1=ANSI X9.62 elliptic curve c2pnb163v1
CertDumpECc2pnb163v2=ANSI X9.62 elliptic curve c2pnb163v2
CertDumpECc2pnb163v3=ANSI X9.62 elliptic curve c2pnb163v3
CertDumpECc2pnb176v1=ANSI X9.62 elliptic curve c2pnb176v1
CertDumpECc2tnb191v1=ANSI X9.62 elliptic curve c2tnb191v1
CertDumpECc2tnb191v2=ANSI X9.62 elliptic curve c2tnb191v2
CertDumpECc2tnb191v3=ANSI X9.62 elliptic curve c2tnb191v3
CertDumpECc2onb191v4=ANSI X9.62 elliptic curve c2onb191v4
CertDumpECc2onb191v5=ANSI X9.62 elliptic curve c2onb191v5
CertDumpECc2pnb208w1=ANSI X9.62 elliptic curve c2pnb208w1
CertDumpECc2tnb239v1=ANSI X9.62 elliptic curve c2tnb239v1
CertDumpECc2tnb239v2=ANSI X9.62 elliptic curve c2tnb239v2
CertDumpECc2tnb239v3=ANSI X9.62 elliptic curve c2tnb239v3
CertDumpECc2onb239v4=ANSI X9.62 elliptic curve c2onb239v4
CertDumpECc2onb239v5=ANSI X9.62 elliptic curve c2onb239v5
CertDumpECc2pnb272w1=ANSI X9.62 elliptic curve c2pnb272w1
CertDumpECc2pnb304w1=ANSI X9.62 elliptic curve c2pnb304w1
CertDumpECc2tnb359v1=ANSI X9.62 elliptic curve c2tnb359v1
CertDumpECc2pnb368w1=ANSI X9.62 elliptic curve c2pnb368w1
CertDumpECc2tnb431r1=ANSI X9.62 elliptic curve c2tnb431r1
CertDumpECsect113r1=SECG elliptic curve sect113r1
CertDumpECsect113r2=SECG elliptic curve sect113r2
CertDumpECsect131r1=SECG elliptic curve sect131r1
CertDumpECsect131r2=SECG elliptic curve sect131r2
CertDumpECsect163k1=SECG elliptic curve sect163k1 (aka NIST K-163)
CertDumpECsect163r1=SECG elliptic curve sect163r1
CertDumpECsect163r2=SECG elliptic curve sect163r2 (aka NIST B-163)
CertDumpECsect193r1=SECG elliptic curve sect193r1
CertDumpECsect193r2=SECG elliptic curve sect193r2
CertDumpECsect233k1=SECG elliptic curve sect233k1 (aka NIST K-233)
CertDumpECsect233r1=SECG elliptic curve sect233r1 (aka NIST B-233)
CertDumpECsect239k1=SECG elliptic curve sect239k1
CertDumpECsect283k1=SECG elliptic curve sect283k1 (aka NIST K-283)
CertDumpECsect283r1=SECG elliptic curve sect283r1 (aka NIST B-283)
CertDumpECsect409k1=SECG elliptic curve sect409k1 (aka NIST K-409)
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
AVATemplate=%S = %S
PSMERR_SSL_Disabled=Cant connect securely because the SSL protocol has been disabled.
PSMERR_SSL2_Disabled=Cant connect securely because the site uses an older, insecure version of the SSL protocol.

View File

@ -26,42 +26,6 @@ certmgr-people = You have certificates on file that identify these people
certmgr-servers = You have certificates on file that identify these servers
certmgr-ca = You have certificates on file that identify these certificate authorities
certmgr-detail-general-tab-title =
.label = General
.accesskey = G
certmgr-detail-pretty-print-tab-title =
.label = Details
.accesskey = D
certmgr-pending-label =
.value = Currently verifying certificate…
certmgr-subject-label = Issued To
certmgr-issuer-label = Issued By
certmgr-period-of-validity = Period of Validity
certmgr-fingerprints = Fingerprints
certmgr-cert-detail =
.title = Certificate Detail
.buttonlabelaccept = Close
.buttonaccesskeyaccept = C
certmgr-cert-detail-commonname = Common Name (CN)
certmgr-cert-detail-org = Organization (O)
certmgr-cert-detail-orgunit = Organizational Unit (OU)
certmgr-cert-detail-serial-number = Serial Number
certmgr-cert-detail-sha-256-fingerprint = SHA-256 Fingerprint
certmgr-cert-detail-sha-1-fingerprint = SHA1 Fingerprint
certmgr-edit-ca-cert =
.title = Edit CA certificate trust settings
.style = width: 48em;
@ -93,13 +57,9 @@ certmgr-override-lifetime =
certmgr-token-name =
.label = Security Device
certmgr-begins-on = Begins On
certmgr-begins-label =
.label = Begins On
certmgr-expires-on = Expires On
certmgr-expires-label =
.label = Expires On
@ -141,18 +101,6 @@ certmgr-restore =
.label = Import…
.accesskey = m
certmgr-details =
.value = Certificate Fields
.accesskey = F
certmgr-fields =
.value = Field Value
.accesskey = V
certmgr-hierarchy =
.value = Certificate Hierarchy
.accesskey = H
certmgr-add-exception =
.label = Add Exception…
.accesskey = x
@ -236,47 +184,6 @@ delete-email-cert-impact = If you delete a persons e-mail certificate, you wi
cert-with-serial =
.value = Certificate with serial number: { $serialNumber }
## Cert Viewer
# Title used for the Certificate Viewer.
#
# Variables:
# $certificate : a string representative of the certificate being viewed.
cert-viewer-title =
.title = Certificate Viewer: “{ $certName }”
not-present =
.value = <Not Part Of Certificate>
# Cert verification
cert-verified = This certificate has been verified for the following uses:
# Add usage
verify-ssl-client =
.value = SSL Client Certificate
verify-ssl-server =
.value = SSL Server Certificate
verify-ssl-ca =
.value = SSL Certificate Authority
verify-email-signer =
.value = Email Signer Certificate
verify-email-recip =
.value = Email Recipient Certificate
# Cert verification
cert-not-verified-cert-revoked = Could not verify this certificate because it has been revoked.
cert-not-verified-cert-expired = Could not verify this certificate because it has expired.
cert-not-verified-cert-not-trusted = Could not verify this certificate because it is not trusted.
cert-not-verified-issuer-not-trusted = Could not verify this certificate because the issuer is not trusted.
cert-not-verified-issuer-unknown = Could not verify this certificate because the issuer is unknown.
cert-not-verified-ca-invalid = Could not verify this certificate because the CA certificate is invalid.
cert-not-verified_algorithm-disabled = Could not verify this certificate because it was signed using a signature algorithm that was disabled because that algorithm is not secure.
cert-not-verified-unknown = Could not verify this certificate for unknown reasons.
## Add Security Exception dialog
add-exception-branded-warning = You are about to override how { -brand-short-name } identifies this site.
add-exception-invalid-header = This site attempts to identify itself with invalid information.

View File

@ -5,12 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Classes = [
{
'cid': '{4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606}',
'contract_ids': ['@mozilla.org/security/nsASN1Tree;1'],
'type': 'nsNSSASN1Tree',
'headers': ['/security/manager/pki/nsASN1Tree.h'],
},
{
'cid': '{518e071f-1dd2-11b2-937e-c45f14def778}',
'contract_ids': [

View File

@ -6,14 +6,7 @@
DIRS += ['resources']
XPIDL_SOURCES += [
'nsIASN1Tree.idl',
]
XPIDL_MODULE = 'pippki'
UNIFIED_SOURCES += [
'nsASN1Tree.cpp',
'nsNSSDialogHelper.cpp',
'nsNSSDialogs.cpp',
]

View File

@ -1,465 +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 "nsASN1Tree.h"
#include "mozilla/Assertions.h"
#include "nsArrayUtils.h"
#include "nsDebug.h"
#include "nsIMutableArray.h"
#include "nsString.h"
NS_IMPL_ISUPPORTS(nsNSSASN1Tree, nsIASN1Tree, nsITreeView)
nsNSSASN1Tree::nsNSSASN1Tree() : mTopNode(nullptr) {}
nsNSSASN1Tree::~nsNSSASN1Tree() { ClearNodes(); }
void nsNSSASN1Tree::ClearNodesRecursively(myNode* n) {
// Note: |n| is allowed to be null.
myNode* walk = n;
while (walk) {
myNode* kill = walk;
if (walk->child) {
ClearNodesRecursively(walk->child);
}
walk = walk->next;
delete kill;
}
}
void nsNSSASN1Tree::ClearNodes() {
ClearNodesRecursively(mTopNode);
mTopNode = nullptr;
}
void nsNSSASN1Tree::InitChildsRecursively(myNode* n) {
MOZ_ASSERT(n);
if (!n) {
return;
}
if (!n->obj) return;
n->seq = do_QueryInterface(n->obj);
if (!n->seq) return;
// If the object is a sequence, there might still be a reason
// why it should not be displayed as a container.
// If we decide that it has all the properties to justify
// displaying as a container, we will create a new child chain.
// If we decide, it does not make sense to display as a container,
// we forget that it is a sequence by erasing n->seq.
// That way, n->seq and n->child will be either both set or both null.
bool isContainer;
n->seq->GetIsValidContainer(&isContainer);
if (!isContainer) {
n->seq = nullptr;
return;
}
nsCOMPtr<nsIMutableArray> asn1Objects;
n->seq->GetASN1Objects(getter_AddRefs(asn1Objects));
uint32_t numObjects;
asn1Objects->GetLength(&numObjects);
if (!numObjects) {
n->seq = nullptr;
return;
}
myNode* walk = nullptr;
myNode* prev = nullptr;
for (uint32_t i = 0; i < numObjects; i++) {
if (0 == i) {
n->child = walk = new myNode;
} else {
walk = new myNode;
}
walk->parent = n;
if (prev) {
prev->next = walk;
}
walk->obj = do_QueryElementAt(asn1Objects, i);
InitChildsRecursively(walk);
prev = walk;
}
}
void nsNSSASN1Tree::InitNodes() {
ClearNodes();
mTopNode = new myNode;
mTopNode->obj = mASN1Object;
InitChildsRecursively(mTopNode);
}
NS_IMETHODIMP
nsNSSASN1Tree::LoadASN1Structure(nsIASN1Object* asn1Object) {
// Note: |asn1Object| is allowed to be null.
// The tree won't automatically re-draw if the contents
// have been changed. So I do a quick test here to let
// me know if I should forced the tree to redraw itself
// by calling RowCountChanged on it.
//
bool redraw = (mASN1Object && mTree);
int32_t rowsToDelete = 0;
if (redraw) {
// This is the number of rows we will be deleting after
// the contents have changed.
rowsToDelete = 0 - CountVisibleNodes(mTopNode);
}
mASN1Object = asn1Object;
InitNodes();
if (redraw) {
// The number of rows in the new content.
int32_t newRows = CountVisibleNodes(mTopNode);
mTree->BeginUpdateBatch();
// Erase all of the old rows.
mTree->RowCountChanged(0, rowsToDelete);
// Replace them with the new contents
mTree->RowCountChanged(0, newRows);
mTree->EndUpdateBatch();
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetRowCount(int32_t* aRowCount) {
NS_ENSURE_ARG_POINTER(aRowCount);
if (mASN1Object) {
*aRowCount = CountVisibleNodes(mTopNode);
} else {
*aRowCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetSelection(nsITreeSelection** aSelection) {
NS_ENSURE_ARG_POINTER(aSelection);
*aSelection = mSelection;
NS_IF_ADDREF(*aSelection);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::SetSelection(nsITreeSelection* aSelection) {
// Note: |aSelection| is allowed to be null.
mSelection = aSelection;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetRowProperties(int32_t, nsAString&) { return NS_OK; }
NS_IMETHODIMP
nsNSSASN1Tree::GetCellProperties(int32_t, nsTreeColumn*, nsAString&) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetColumnProperties(nsTreeColumn*, nsAString&) { return NS_OK; }
NS_IMETHODIMP
nsNSSASN1Tree::IsContainer(int32_t index, bool* _retval) {
NS_ENSURE_ARG_MIN(index, 0);
NS_ENSURE_ARG_POINTER(_retval);
myNode* n = FindNodeFromIndex(index);
if (!n) return NS_ERROR_FAILURE;
*_retval = (n->seq != nullptr);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::IsContainerOpen(int32_t index, bool* _retval) {
NS_ENSURE_ARG_MIN(index, 0);
NS_ENSURE_ARG_POINTER(_retval);
myNode* n = FindNodeFromIndex(index);
if (!n || !n->seq) return NS_ERROR_FAILURE;
return n->seq->GetIsExpanded(_retval);
}
NS_IMETHODIMP
nsNSSASN1Tree::IsContainerEmpty(int32_t, bool* _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::IsSeparator(int32_t, bool* _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetLevel(int32_t index, int32_t* _retval) {
NS_ENSURE_ARG_MIN(index, 0);
NS_ENSURE_ARG_POINTER(_retval);
int32_t nodeLevel;
myNode* n = FindNodeFromIndex(index, nullptr, &nodeLevel);
if (!n) return NS_ERROR_FAILURE;
*_retval = nodeLevel;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetImageSrc(int32_t, nsTreeColumn*, nsAString&) { return NS_OK; }
NS_IMETHODIMP
nsNSSASN1Tree::GetCellValue(int32_t, nsTreeColumn*, nsAString&) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetCellText(int32_t row, nsTreeColumn*, nsAString& _retval) {
NS_ENSURE_ARG_MIN(row, 0);
_retval.Truncate();
myNode* n = FindNodeFromIndex(row);
if (!n) return NS_ERROR_FAILURE;
// There's only one column for ASN1 dump.
return n->obj->GetDisplayName(_retval);
}
NS_IMETHODIMP
nsNSSASN1Tree::GetDisplayData(uint32_t index, nsAString& _retval) {
myNode* n = FindNodeFromIndex(index);
if (!n) return NS_ERROR_FAILURE;
return n->obj->GetDisplayValue(_retval);
}
NS_IMETHODIMP
nsNSSASN1Tree::SetTree(mozilla::dom::XULTreeElement* tree) {
// Note: |tree| is allowed to be null.
mTree = tree;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::ToggleOpenState(int32_t index) {
NS_ENSURE_ARG_MIN(index, 0);
myNode* n = FindNodeFromIndex(index);
if (!n) return NS_ERROR_FAILURE;
if (!n->seq) return NS_ERROR_FAILURE;
bool IsExpanded;
n->seq->GetIsExpanded(&IsExpanded);
int32_t rowCountChange;
if (IsExpanded) {
rowCountChange = -CountVisibleNodes(n->child);
n->seq->SetIsExpanded(false);
} else {
n->seq->SetIsExpanded(true);
rowCountChange = CountVisibleNodes(n->child);
}
if (mTree) mTree->RowCountChanged(index, rowCountChange);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::CycleHeader(nsTreeColumn*) { return NS_OK; }
NS_IMETHODIMP
nsNSSASN1Tree::SelectionChangedXPCOM() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHODIMP
nsNSSASN1Tree::CycleCell(int32_t, nsTreeColumn*) { return NS_OK; }
NS_IMETHODIMP
nsNSSASN1Tree::IsEditable(int32_t, nsTreeColumn*, bool* _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::SetCellValue(int32_t, nsTreeColumn*, const nsAString&) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::SetCellText(int32_t, nsTreeColumn*, const nsAString&) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::CanDrop(int32_t, int32_t, mozilla::dom::DataTransfer*,
bool* _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::Drop(int32_t, int32_t, mozilla::dom::DataTransfer*) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::IsSorted(bool* _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::GetParentIndex(int32_t rowIndex, int32_t* _retval) {
NS_ENSURE_ARG_MIN(rowIndex, 0);
NS_ENSURE_ARG_POINTER(_retval);
int32_t parentIndex = -1;
myNode* n = FindNodeFromIndex(rowIndex, &parentIndex);
if (!n) return NS_ERROR_FAILURE;
*_retval = parentIndex;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Tree::HasNextSibling(int32_t rowIndex, int32_t afterIndex,
bool* _retval) {
NS_ENSURE_ARG_MIN(rowIndex, 0);
NS_ENSURE_ARG_MIN(afterIndex, 0);
NS_ENSURE_ARG_POINTER(_retval);
myNode* n = FindNodeFromIndex(rowIndex);
if (!n) return NS_ERROR_FAILURE;
if (!n->next) {
*_retval = false;
} else {
int32_t nTotalSize = CountVisibleNodes(n);
int32_t nLastChildPos = rowIndex + nTotalSize - 1;
int32_t nextSiblingPos = nLastChildPos + 1;
*_retval = (nextSiblingPos > afterIndex);
}
return NS_OK;
}
int32_t nsNSSASN1Tree::CountVisibleNodes(myNode* n) {
if (!n) return 0;
myNode* walk = n;
int32_t count = 0;
while (walk) {
++count;
if (walk->seq) {
bool IsExpanded;
walk->seq->GetIsExpanded(&IsExpanded);
if (IsExpanded) {
count += CountVisibleNodes(walk->child);
}
}
walk = walk->next;
}
return count;
}
// Entry point for find
nsNSSASN1Tree::myNode* nsNSSASN1Tree::FindNodeFromIndex(
int32_t wantedIndex, int32_t* optionalOutParentIndex,
int32_t* optionalOutLevel) {
MOZ_ASSERT(wantedIndex >= 0);
if (wantedIndex < 0) {
return nullptr;
}
if (0 == wantedIndex) {
if (optionalOutLevel) {
*optionalOutLevel = 0;
}
if (optionalOutParentIndex) {
*optionalOutParentIndex = -1;
}
return mTopNode;
}
int32_t index = 0;
int32_t level = 0;
return FindNodeFromIndex(mTopNode, wantedIndex, index, level,
optionalOutParentIndex, optionalOutLevel);
}
// Internal recursive helper function
nsNSSASN1Tree::myNode* nsNSSASN1Tree::FindNodeFromIndex(
myNode* n, int32_t wantedIndex, int32_t& indexCounter,
int32_t& levelCounter, int32_t* optionalOutParentIndex,
int32_t* optionalOutLevel) {
MOZ_ASSERT(wantedIndex >= 0);
MOZ_ASSERT(indexCounter >= 0);
MOZ_ASSERT(levelCounter >= 0);
if (!n || wantedIndex < 0 || indexCounter < 0 || levelCounter < 0) {
return nullptr;
}
myNode* walk = n;
int32_t parentIndex = indexCounter - 1;
while (walk) {
if (indexCounter == wantedIndex) {
if (optionalOutLevel) {
*optionalOutLevel = levelCounter;
}
if (optionalOutParentIndex) {
*optionalOutParentIndex = parentIndex;
}
return walk;
}
if (walk->seq) {
bool IsExpanded;
walk->seq->GetIsExpanded(&IsExpanded);
if (IsExpanded) {
++indexCounter; // set to walk->child
++levelCounter;
myNode* found = FindNodeFromIndex(
walk->child, wantedIndex, indexCounter, levelCounter,
optionalOutParentIndex, optionalOutLevel);
--levelCounter;
if (found) return found;
}
}
walk = walk->next;
if (walk) {
++indexCounter;
}
}
return nullptr;
}

View File

@ -1,83 +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 _NSSASNTREE_H_
#define _NSSASNTREE_H_
#include "nscore.h"
#include "nsIASN1Tree.h"
#include "nsIASN1Object.h"
#include "nsIASN1Sequence.h"
#include "nsITreeSelection.h"
#include "nsCOMPtr.h"
/* Disable the "base class XXX should be explicitly initialized
in the copy constructor" warning. */
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wextra"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wextra"
#endif // __clang__ || __GNUC__
#include "mozilla/dom/XULTreeElement.h"
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__)
# pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__
// 4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606
#define NS_NSSASN1OUTINER_CID \
{ \
0x4bfaa9f0, 0x1dd2, 0x11b2, { \
0xaf, 0xae, 0xa8, 0x2c, 0xba, 0xa0, 0xb6, 0x06 \
} \
}
class nsNSSASN1Tree : public nsIASN1Tree {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIASN1TREE
NS_DECL_NSITREEVIEW
nsNSSASN1Tree();
protected:
virtual ~nsNSSASN1Tree();
class myNode {
public:
nsCOMPtr<nsIASN1Object> obj;
nsCOMPtr<nsIASN1Sequence> seq;
myNode* child;
myNode* next;
myNode* parent;
myNode() { child = next = parent = nullptr; }
};
myNode* mTopNode;
nsCOMPtr<nsIASN1Object> mASN1Object;
nsCOMPtr<nsITreeSelection> mSelection;
RefPtr<mozilla::dom::XULTreeElement> mTree;
void InitNodes();
void InitChildsRecursively(myNode* n);
void ClearNodes();
void ClearNodesRecursively(myNode* n);
int32_t CountVisibleNodes(myNode* n);
myNode* FindNodeFromIndex(myNode* n, int32_t wantedIndex,
int32_t& index_counter, int32_t& level_counter,
int32_t* optionalOutParentIndex,
int32_t* optionalOutLevel);
myNode* FindNodeFromIndex(int32_t wantedIndex,
int32_t* optionalOutParentIndex = nullptr,
int32_t* optionalOutLevel = nullptr);
};
#endif //_NSSASNTREE_H_

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "nsCOMPtr.h"
#include "nsIWindowWatcher.h"
#include "nsServiceManagerUtils.h"
static const char kOpenDialogParam[] = "centerscreen,chrome,modal,titlebar";
static const char kOpenWindowParam[] = "centerscreen,chrome,titlebar";

View File

@ -7,6 +7,8 @@
#ifndef nsNSSDialogHelper_h
#define nsNSSDialogHelper_h
#include "nsError.h"
class mozIDOMWindowProxy;
class nsISupports;

View File

@ -12,6 +12,7 @@
#include "mozIDOMWindow.h"
#include "nsArray.h"
#include "nsComponentManagerUtils.h"
#include "nsEmbedCID.h"
#include "nsHashPropertyBag.h"
#include "nsIDialogParamBlock.h"

View File

@ -1,305 +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/. */
/* import-globals-from pippki.js */
"use strict";
/**
* @file Implements functionality for certViewer.xhtml and its general and details
* tabs.
* @argument {nsISupports} window.arguments[0]
* The cert to view, queryable to nsIX509Cert.
*/
/**
* Fills out the "Certificate Hierarchy" tree of the cert viewer "Details" tab.
*
* @param {tree} node
* Parent tree node to append to.
* @param {Array} chain
* An array of nsIX509Cert where cert n is issued by cert n + 1.
*/
function AddCertChain(node, chain) {
if (!chain || chain.length < 1) {
return;
}
let child = document.getElementById(node);
// Clear any previous state.
let preexistingChildren = child.querySelectorAll("treechildren");
for (let preexistingChild of preexistingChildren) {
child.removeChild(preexistingChild);
}
for (let i = chain.length - 1; i >= 0; i--) {
let currCert = chain[i];
let displayValue = currCert.displayName;
let addTwistie = i != 0;
child = addChildrenToTree(child, displayValue, currCert.dbKey, addTwistie);
}
}
/**
* Adds a "verified usage" of a cert to the "General" tab of the cert viewer.
*
* @param {String} l10nId
* l10nId of verified usage to add.
*/
function AddUsage(l10nId) {
let verifyInfoBox = document.getElementById("verify_info_box");
let text = document.createElementNS("http://www.w3.org/1999/xhtml", "input");
document.l10n.setAttributes(text, l10nId);
text.setAttribute("data-l10n-attrs", "value");
text.setAttribute("style", "margin: 2px 5px");
text.setAttribute("readonly", "readonly");
text.setAttribute("class", "scrollfield");
verifyInfoBox.appendChild(text);
}
function setWindowName() {
let cert = window.arguments[0].QueryInterface(Ci.nsIX509Cert);
window.document.l10n.setAttributes(
window.document.documentElement,
"cert-viewer-title",
{ certName: cert.displayName }
);
//
// Set the cert attributes for viewing
//
// Set initial dummy chain of just the cert itself. A more complete chain (if
// one can be found), will be set when the promise chain beginning at
// asyncDetermineUsages finishes.
AddCertChain("treesetDump", [cert]);
DisplayGeneralDataFromCert(cert);
BuildPrettyPrint(cert);
asyncDetermineUsages(cert).then(displayUsages);
}
// Map of certificate usage name to localization identifier.
const certificateUsageToStringBundleName = {
certificateUsageSSLClient: "verify-ssl-client",
certificateUsageSSLServer: "verify-ssl-server",
certificateUsageSSLCA: "verify-ssl-ca",
certificateUsageEmailSigner: "verify-email-signer",
certificateUsageEmailRecipient: "verify-email-recip",
};
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;
/**
* Updates the usage display area given the results from asyncDetermineUsages.
*
* @param {Array} results
* An array of objects with the properties "usageString", "errorCode",
* and "chain".
* 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).
* chain is the built trust path, if one was found
*/
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) {
document.l10n.setAttributes(verified, "cert-verified");
results.forEach(result => {
if (result.errorCode != PRErrorCodeSuccess) {
return;
}
let usageL10nId = certificateUsageToStringBundleName[result.usageString];
AddUsage(usageL10nId);
});
AddCertChain("treesetDump", getBestChain(results));
} else {
const errorRankings = [
{
error: SEC_ERROR_REVOKED_CERTIFICATE,
bundleString: "cert-not-verified-cert-revoked",
},
{
error: SEC_ERROR_UNTRUSTED_CERT,
bundleString: "cert-not-verified-cert-not-trusted",
},
{
error: SEC_ERROR_UNTRUSTED_ISSUER,
bundleString: "cert-not-verified-issuer-not-trusted",
},
{
error: SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED,
bundleString: "cert-not-verified_algorithm-disabled",
},
{
error: SEC_ERROR_EXPIRED_CERTIFICATE,
bundleString: "cert-not-verified-cert-expired",
},
{
error: SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE,
bundleString: "cert-not-verified-ca-invalid",
},
{
error: SEC_ERROR_UNKNOWN_ISSUER,
bundleString: "cert-not-verified-issuer-unknown",
},
];
let errorPresentFlag = false;
for (let errorRanking of errorRankings) {
let errorPresent = results.some(
result => result.errorCode == errorRanking.error
);
if (errorPresent) {
document.l10n.setAttributes(verified, errorRanking.bundleString);
errorPresentFlag = true;
break;
}
}
if (!errorPresentFlag) {
document.l10n.setAttributes(verified, "cert-not-verified-unknown");
}
}
// 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");
}
function addChildrenToTree(parentTree, label, value, addTwistie) {
let treeChild1 = document.createXULElement("treechildren");
let treeElement = addTreeItemToTreeChild(
treeChild1,
label,
value,
addTwistie
);
parentTree.appendChild(treeChild1);
return treeElement;
}
function addTreeItemToTreeChild(treeChild, label, value, addTwistie) {
let treeElem1 = document.createXULElement("treeitem");
if (addTwistie) {
treeElem1.setAttribute("container", "true");
treeElem1.setAttribute("open", "true");
}
let treeRow = document.createXULElement("treerow");
let treeCell = document.createXULElement("treecell");
treeCell.setAttribute("label", label);
if (value) {
treeCell.setAttribute("display", value);
}
treeRow.appendChild(treeCell);
treeElem1.appendChild(treeRow);
treeChild.appendChild(treeElem1);
return treeElem1;
}
function displaySelected() {
var asn1Tree = document
.getElementById("prettyDumpTree")
.view.QueryInterface(Ci.nsIASN1Tree);
var items = asn1Tree.selection;
var certDumpVal = document.getElementById("certDumpVal");
if (items.currentIndex != -1) {
var value = asn1Tree.getDisplayData(items.currentIndex);
certDumpVal.value = value;
} else {
certDumpVal.value = "";
}
}
function BuildPrettyPrint(cert) {
var certDumpTree = Cc["@mozilla.org/security/nsASN1Tree;1"].createInstance(
Ci.nsIASN1Tree
);
certDumpTree.loadASN1Structure(cert.ASN1Structure);
document.getElementById("prettyDumpTree").view = certDumpTree;
}
function addAttributeFromCert(nodeName, value) {
var node = document.getElementById(nodeName);
if (!value) {
document.l10n.setAttributes(node, "not-present");
return;
}
node.value = value;
}
/**
* Displays information about a cert in the "General" tab of the cert viewer.
*
* @param {nsIX509Cert} cert
* Cert to display information about.
*/
function DisplayGeneralDataFromCert(cert) {
addAttributeFromCert("commonname", cert.commonName);
addAttributeFromCert("organization", cert.organization);
addAttributeFromCert("orgunit", cert.organizationalUnit);
addAttributeFromCert("serialnumber", cert.serialNumber);
addAttributeFromCert("sha256fingerprint", cert.sha256Fingerprint);
addAttributeFromCert("sha1fingerprint", cert.sha1Fingerprint);
addAttributeFromCert("validitystart", cert.validity.notBeforeLocalDay);
addAttributeFromCert("validityend", cert.validity.notAfterLocalDay);
addAttributeFromCert("issuercommonname", cert.issuerCommonName);
addAttributeFromCert("issuerorganization", cert.issuerOrganization);
addAttributeFromCert("issuerorgunit", cert.issuerOrganizationUnit);
}
function updateCertDump() {
var asn1Tree = document
.getElementById("prettyDumpTree")
.view.QueryInterface(Ci.nsIASN1Tree);
var tree = document.getElementById("treesetDump");
if (tree.currentIndex >= 0) {
var item = tree.view.getItemAtIndex(tree.currentIndex);
var dbKey = item.firstChild.firstChild.getAttribute("display");
// Get the cert from the cert database
var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
var cert = certdb.findCertByDBKey(dbKey);
asn1Tree.loadASN1Structure(cert.ASN1Structure);
}
displaySelected();
}
function getCurrentCert() {
var realIndex;
var tree = document.getElementById("treesetDump");
if (
tree.view.selection.isSelected(tree.currentIndex) &&
document.getElementById("prettyprint_tab").selected
) {
/* if the user manually selected a cert on the Details tab,
then take that one */
realIndex = tree.currentIndex;
} else {
/* otherwise, take the one at the bottom of the chain
(i.e. the one of the end-entity, unless we're displaying
CA certs) */
realIndex = tree.view.rowCount - 1;
}
if (realIndex >= 0) {
var item = tree.view.getItemAtIndex(realIndex);
var dbKey = item.firstChild.firstChild.getAttribute("display");
var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
var cert = certdb.findCertByDBKey(dbKey);
return cert;
}
/* shouldn't really happen */
return null;
}

View File

@ -1,169 +0,0 @@
<?xml version="1.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/. -->
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<!DOCTYPE window>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
data-l10n-id="certmgr-cert-detail"
data-l10n-attrs="title"
onload="setWindowName();">
<dialog id="certDetails"
data-l10n-id="certmgr-cert-detail"
data-l10n-attrs="buttonlabelaccept, buttonaccesskeyaccept"
buttons="accept">
<linkset>
<html:link rel="localization" href="security/certificates/certManager.ftl"/>
</linkset>
<script src="chrome://pippki/content/pippki.js"/>
<script src="chrome://global/content/globalOverlay.js"/>
<script src="chrome://global/content/editMenuOverlay.js"/>
<script src="chrome://pippki/content/certViewer.js"/>
<html:style>
table {
border-spacing: 0.5ch 2px;
}
td > input {
width: 100%;
}
th {
vertical-align: middle;
text-align: start;
}
th[scope="row"] {
font-weight: normal;
}
input:read-only,
textarea:read-only {
background: none;
border: none;
width: 100%;
padding-block: 0;
margin-inline: 0;
}
</html:style>
<tabbox flex="1">
<tabs>
<tab id="general_tab" data-l10n-id="certmgr-detail-general-tab-title"/>
<tab id="prettyprint_tab" data-l10n-id="certmgr-detail-pretty-print-tab-title"/>
</tabs>
<tabpanels flex="1">
<vbox class="box-padded" id="general_info">
<vbox id="verify_info_box">
<label id="verify_pending" data-l10n-id="certmgr-pending-label"/>
<label class="header" id="verified"/>
</vbox>
<separator class="groove"/>
<table xmlns="http://www.w3.org/1999/xhtml">
<tr>
<th colspan="2" scope="rowgroup" data-l10n-id="certmgr-subject-label"></th>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-commonname"></th>
<td><input id="commonname" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-org"></th>
<td><input id="organization" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-orgunit"></th>
<td><input id="orgunit" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-serial-number"></th>
<td><input id="serialnumber" readonly="readonly"/></td>
</tr>
<tr>
<td colspan="2"><xul:separator class="thin"/></td>
</tr>
<tr>
<th colspan="2" scope="rowgroup" data-l10n-id="certmgr-issuer-label"></th>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-commonname"></th>
<td><input id="issuercommonname" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-org"></th>
<td><input id="issuerorganization" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-orgunit"></th>
<td><input id="issuerorgunit" readonly="readonly"/></td>
</tr>
<tr>
<td colspan="2"><xul:separator class="thin"/></td>
</tr>
<tr>
<th colspan="2" scope="rowgroup" data-l10n-id="certmgr-period-of-validity"></th>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-begins-on"></th>
<td><input id="validitystart" readonly="readonly"/></td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-expires-on"></th>
<td><input id="validityend" readonly="readonly"/></td>
</tr>
<tr>
<td colspan="2"><xul:separator class="thin"/></td>
</tr>
<tr>
<th colspan="2" scope="rowgroup" data-l10n-id="certmgr-fingerprints"></th>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-sha-256-fingerprint"></th>
<td>
<textarea id="sha256fingerprint" readonly="readonly"
style="height: 6ex; width: 48ch; font-family: monospace;"/>
</td>
</tr>
<tr>
<th scope="row" data-l10n-id="certmgr-cert-detail-sha-1-fingerprint"></th>
<td><input id="sha1fingerprint" readonly="readonly" style="min-width:34em;"/></td>
</tr>
</table>
</vbox>
<vbox class="box-padded" id="certPrettyPrint" flex="1">
<label class="header" data-l10n-id="certmgr-hierarchy" control="treesetDump"/>
<tree id="treesetDump" onselect="updateCertDump();" flex="1"
hidecolumnpicker="true" style="height: 8em;">
<treecols>
<treecol id="dumpCol" flex="1" primary="true" hideheader="true"/>
</treecols>
</tree>
<label class="header" data-l10n-id="certmgr-details" control="prettyDumpTree"/>
<tree id="prettyDumpTree" style="height: 15em" treelines="true" flex="1"
onselect="displaySelected();" hidecolumnpicker="true">
<treecols>
<treecol flex="1" id="certDataCol" primary="true" hideheader="true"/>
</treecols>
<treechildren/>
</tree>
<label class="header" data-l10n-id="certmgr-fields" control="certDumpVal"/>
<html:textarea id="certDumpVal" flex="1" readonly="readonly"
style="height: 11em; font-family: -moz-fixed;"/>
<separator class="thin"/>
<hbox>
<button id="export_cert" class="normal" data-l10n-id="certmgr-export"
oncommand="exportToFile(window, getCurrentCert());"/>
</hbox>
</vbox>
</tabpanels>
</tabbox>
</dialog>
</window>

View File

@ -30,31 +30,19 @@ async function viewCertHelper(parent, cert, openingOption = "tab") {
return;
}
if (Services.prefs.getBoolPref("security.aboutcertificate.enabled")) {
let win = Services.wm.getMostRecentBrowserWindow();
let results = await asyncDetermineUsages(cert);
let chain = getBestChain(results);
if (!chain) {
chain = [cert];
}
let certs = chain.map(elem =>
encodeURIComponent(elem.getBase64DERString())
);
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
let opened = win.switchToTabHavingURI(url, false, {});
if (!opened) {
win.openTrustedLinkIn(url, openingOption);
}
} else {
Services.ww.openWindow(
parent && parent.docShell.rootTreeItem.domWindow,
"chrome://pippki/content/certViewer.xhtml",
"_blank",
"centerscreen,chrome",
cert
);
let win = Services.wm.getMostRecentBrowserWindow();
let results = await asyncDetermineUsages(cert);
let chain = getBestChain(results);
if (!chain) {
chain = [cert];
}
let certs = chain.map(elem => encodeURIComponent(elem.getBase64DERString()));
let certsStringURL = certs.map(elem => `cert=${elem}`);
certsStringURL = certsStringURL.join("&");
let url = `about:certificate?${certsStringURL}`;
let opened = win.switchToTabHavingURI(url, false, {});
if (!opened) {
win.openTrustedLinkIn(url, openingOption);
}
}
@ -223,9 +211,8 @@ const certificateUsages = {
};
/**
* Returns a promise that will resolve with a results array (see
* `displayUsages` in certViewer.js) consisting of what usages the given
* certificate successfully verified for.
* Returns a promise that will resolve with a results array consisting of what
* usages the given certificate successfully verified for.
*
* @param {nsIX509Cert} cert
* The certificate to determine valid usages for.
@ -263,11 +250,11 @@ function asyncDetermineUsages(cert) {
}
/**
* Given a results array (see `displayUsages` in certViewer.js), returns the
* "best" verified certificate chain. Since the primary use case is for TLS
* server certificates in Firefox, such a verified chain will be returned if
* present. Otherwise, the priority is: TLS client certificate, email signer,
* email recipient, CA. Returns null if no usage verified successfully.
* Given a results array, returns the "best" verified certificate chain. Since
* the primary use case is for TLS server certificates in Firefox, such a
* verified chain will be returned if present. Otherwise, the priority is: TLS
* client certificate, email signer, email recipient, CA. Returns null if no
* usage verified successfully.
*
* @param {Array} results
* An array of results from `asyncDetermineUsages`. See `displayUsages`.
@ -294,9 +281,8 @@ function getBestChain(results) {
}
/**
* Given a results array (see `displayUsages` in certViewer.js), returns the
* chain corresponding to the desired usage, if verifying for that usage
* succeeded. Returns null otherwise.
* Given a results array, returns the chain corresponding to the desired usage,
* if verifying for that usage succeeded. Returns null otherwise.
*
* @param {Array} results
* An array of results from `asyncDetermineUsages`. See `displayUsages`.

View File

@ -6,8 +6,6 @@ pippki.jar:
% content pippki %content/pippki/
content/pippki/certManager.js (content/certManager.js)
content/pippki/certManager.xhtml (content/certManager.xhtml)
content/pippki/certViewer.js (content/certViewer.js)
content/pippki/certViewer.xhtml (content/certViewer.xhtml)
content/pippki/changepassword.js (content/changepassword.js)
content/pippki/changepassword.xhtml (content/changepassword.xhtml)
content/pippki/clientauthask.js (content/clientauthask.js)

View File

@ -13,9 +13,6 @@ if (CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['CPU_ARCH'] != 'aarch64') or CONFIG[
TEST_DIRS += [ 'tests' ]
XPIDL_SOURCES += [
'nsIASN1Object.idl',
'nsIASN1PrintableItem.idl',
'nsIASN1Sequence.idl',
'nsICertificateDialogs.idl',
'nsICertOverrideService.idl',
'nsIClientAuthDialogs.idl',
@ -114,7 +111,6 @@ UNIFIED_SOURCES += [
'nsClientAuthRemember.cpp',
'nsCryptoHash.cpp',
'nsKeyModule.cpp',
'nsNSSASN1Object.cpp',
'nsNSSCallbacks.cpp',
'nsNSSCertHelper.cpp',
'nsNSSCertificate.cpp',

View File

@ -1,70 +0,0 @@
/* -*- 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 "nsISupports.idl"
/**
* This represents an ASN.1 object,
* where ASN.1 is "Abstract Syntax Notation number One".
*
* The additional state information carried in this interface
* makes it fit for being used as the data structure
* when working with visual reprenstation of ASN.1 objects
* in a human user interface, like in a tree widget
* where open/close state of nodes must be remembered.
*/
[scriptable, uuid(ba8bf582-1dd1-11b2-898c-f40246bc9a63)]
interface nsIASN1Object : nsISupports {
/**
* Identifiers for the possible types of object.
*/
const unsigned long ASN1_END_CONTENTS = 0;
const unsigned long ASN1_BOOLEAN = 1;
const unsigned long ASN1_INTEGER = 2;
const unsigned long ASN1_BIT_STRING = 3;
const unsigned long ASN1_OCTET_STRING = 4;
const unsigned long ASN1_NULL = 5;
const unsigned long ASN1_OBJECT_ID = 6;
const unsigned long ASN1_ENUMERATED = 10;
const unsigned long ASN1_UTF8_STRING = 12;
const unsigned long ASN1_SEQUENCE = 16;
const unsigned long ASN1_SET = 17;
const unsigned long ASN1_PRINTABLE_STRING = 19;
const unsigned long ASN1_T61_STRING = 20;
const unsigned long ASN1_IA5_STRING = 22;
const unsigned long ASN1_UTC_TIME = 23;
const unsigned long ASN1_GEN_TIME = 24;
const unsigned long ASN1_VISIBLE_STRING = 26;
const unsigned long ASN1_UNIVERSAL_STRING = 28;
const unsigned long ASN1_BMP_STRING = 30;
const unsigned long ASN1_HIGH_TAG_NUMBER = 31;
const unsigned long ASN1_CONTEXT_SPECIFIC = 32;
const unsigned long ASN1_APPLICATION = 33;
const unsigned long ASN1_PRIVATE = 34;
/**
* "type" will be equal to one of the defined object identifiers.
*/
attribute unsigned long type;
/**
* This contains a tag as explained in ASN.1 standards documents.
*/
attribute unsigned long tag;
/**
* "displayName" contains a human readable explanatory label.
*/
attribute AString displayName;
/**
* "displayValue" contains the human readable value.
*/
attribute AString displayValue;
};

View File

@ -1,14 +0,0 @@
/* -*- 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 "nsISupports.idl"
#include "nsIASN1Object.idl"
[scriptable, uuid(114e1142-1dd2-11b2-ac26-b6db19d9184a)]
interface nsIASN1PrintableItem : nsIASN1Object {
[noscript] void setData(in charPtr data, in unsigned long len);
[noscript, must_use] void getData(out charPtr data, out unsigned long len);
};

View File

@ -1,56 +0,0 @@
/* -*- 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 "nsISupports.idl"
#include "nsIASN1Object.idl"
interface nsIMutableArray;
/**
* This represents a sequence of ASN.1 objects,
* where ASN.1 is "Abstract Syntax Notation number One".
*
* Overview of how this ASN1 interface is intended to
* work.
*
* First off, the nsIASN1Sequence is any type in ASN1
* that consists of sub-elements (ie SEQUENCE, SET)
* nsIASN1Printable Items are all the other types that
* can be viewed by themselves without interpreting further.
* Examples would include INTEGER, UTF-8 STRING, OID.
* These are not intended to directly reflect the numberous
* types that exist in ASN1, but merely an interface to ease
* producing a tree display the ASN1 structure of any DER
* object.
*
* The additional state information carried in this interface
* makes it fit for being used as the data structure
* when working with visual reprenstation of ASN.1 objects
* in a human user interface, like in a tree widget
* where open/close state of nodes must be remembered.
*/
[scriptable, uuid(b6b957e6-1dd1-11b2-89d7-e30624f50b00)]
interface nsIASN1Sequence : nsIASN1Object {
/**
* The array of objects stored in the sequence.
*/
attribute nsIMutableArray ASN1Objects;
/**
* Whether the node at this position in the ASN.1 data structure
* sequence contains sub elements understood by the
* application.
*/
attribute boolean isValidContainer;
/**
* Whether the contained objects should be shown or hidden.
* A UI implementation can use this flag to store the current
* expansion state when shown in a tree widget.
*/
attribute boolean isExpanded;
};

View File

@ -8,7 +8,6 @@
interface nsIArray;
interface nsIX509CertValidity;
interface nsIASN1Object;
interface nsICertVerificationListener;
%{ C++
@ -189,14 +188,6 @@ interface nsIX509Cert : nsISupports {
[must_use]
readonly attribute AString keyUsages;
/**
* This is the attribute which describes the ASN1 layout
* of the certificate. This can be used when doing a
* "pretty print" of the certificate's ASN1 structure.
*/
[must_use]
readonly attribute nsIASN1Object ASN1Structure;
/**
* Obtain a raw binary encoding of this certificate
* in DER format.

View File

@ -1,377 +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 "nsNSSASN1Object.h"
#include "nsArray.h"
#include "nsArrayUtils.h"
#include "nsReadableUtils.h"
#include "nsXPCOMCID.h"
#include "secasn1.h"
NS_IMPL_ISUPPORTS(nsNSSASN1Sequence, nsIASN1Sequence, nsIASN1Object)
NS_IMPL_ISUPPORTS(nsNSSASN1PrintableItem, nsIASN1PrintableItem, nsIASN1Object)
// This function is used to interpret an integer that
// was encoded in a DER buffer. This function is used
// when converting a DER buffer into a nsIASN1Object
// structure. This interprets the buffer in data
// as defined by the DER (Distinguised Encoding Rules) of
// ASN1.
static int getInteger256(unsigned char* data, unsigned int nb) {
int val;
switch (nb) {
case 1:
val = data[0];
break;
case 2:
val = (data[0] << 8) | data[1];
break;
case 3:
val = (data[0] << 16) | (data[1] << 8) | data[2];
break;
case 4:
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
break;
default:
return -1;
}
return val;
}
// This function is used to retrieve the lenght of a DER encoded
// item. It looks to see if this a multibyte length and then
// interprets the buffer accordingly to get the actual length value.
// This funciton is used mostly while parsing the DER headers.
//
// A DER encoded item has the following structure:
//
// <tag><length<data consisting of lenght bytes>
static int32_t getDERItemLength(unsigned char* data, unsigned char* end,
unsigned long* bytesUsed, bool* indefinite) {
unsigned char lbyte = *data++;
int32_t length = -1;
*indefinite = false;
if (lbyte >= 0x80) {
// Multibyte length
unsigned nb = (unsigned)(lbyte & 0x7f);
if (nb > 4) {
return -1;
}
if (nb > 0) {
if ((data + nb) > end) {
return -1;
}
length = getInteger256(data, nb);
if (length < 0) return -1;
} else {
*indefinite = true;
length = 0;
}
*bytesUsed = nb + 1;
} else {
length = lbyte;
*bytesUsed = 1;
}
return length;
}
static nsresult buildASN1ObjectFromDER(unsigned char* data, unsigned char* end,
nsIASN1Sequence* parent) {
nsresult rv;
nsCOMPtr<nsIASN1Sequence> sequence;
nsCOMPtr<nsIASN1PrintableItem> printableItem;
nsCOMPtr<nsIASN1Object> asn1Obj;
nsCOMPtr<nsIMutableArray> parentObjects;
NS_ENSURE_ARG_POINTER(parent);
if (data >= end) return NS_OK;
unsigned char code, tagnum;
// A DER item has the form of |tag|len|data
// tag is one byte and describes the type of element
// we are dealing with.
// len is a DER encoded int telling us how long the data is
// data is a buffer that is len bytes long and has to be
// interpreted according to its type.
unsigned long bytesUsed;
bool indefinite;
int32_t len;
uint32_t type;
rv = parent->GetASN1Objects(getter_AddRefs(parentObjects));
if (NS_FAILED(rv) || !parentObjects) return NS_ERROR_FAILURE;
while (data < end) {
code = *data;
tagnum = code & SEC_ASN1_TAGNUM_MASK;
/*
* NOTE: This code does not (yet) handle the high-tag-number form!
*/
if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
return NS_ERROR_FAILURE;
}
data++;
len = getDERItemLength(data, end, &bytesUsed, &indefinite);
if (len < 0) {
return NS_ERROR_FAILURE;
}
data += bytesUsed;
if (data + len > end) {
return NS_ERROR_FAILURE;
}
if (code & SEC_ASN1_CONSTRUCTED) {
if (len > 0 || indefinite) {
sequence = new nsNSSASN1Sequence();
switch (code & SEC_ASN1_CLASS_MASK) {
case SEC_ASN1_UNIVERSAL:
type = tagnum;
break;
case SEC_ASN1_APPLICATION:
type = nsIASN1Object::ASN1_APPLICATION;
break;
case SEC_ASN1_CONTEXT_SPECIFIC:
type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
break;
case SEC_ASN1_PRIVATE:
type = nsIASN1Object::ASN1_PRIVATE;
break;
default:
NS_ERROR("Bad DER");
return NS_ERROR_FAILURE;
}
sequence->SetTag(tagnum);
sequence->SetType(type);
rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len,
sequence);
asn1Obj = sequence;
}
} else {
printableItem = new nsNSSASN1PrintableItem();
asn1Obj = printableItem;
asn1Obj->SetType(tagnum);
asn1Obj->SetTag(tagnum);
printableItem->SetData((char*)data, len);
}
data += len;
parentObjects->AppendElement(asn1Obj);
}
return NS_OK;
}
nsresult CreateFromDER(unsigned char* data, unsigned int len,
nsIASN1Object** retval) {
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence;
*retval = nullptr;
nsresult rv = buildASN1ObjectFromDER(data, data + len, sequence);
if (NS_SUCCEEDED(rv)) {
// The actual object will be the first element inserted
// into the sequence of the sequence variable we created.
nsCOMPtr<nsIMutableArray> elements;
sequence->GetASN1Objects(getter_AddRefs(elements));
nsCOMPtr<nsIASN1Object> asn1Obj = do_QueryElementAt(elements, 0);
if (!asn1Obj) {
return NS_ERROR_FAILURE;
}
asn1Obj.forget(retval);
}
return rv;
}
nsNSSASN1Sequence::nsNSSASN1Sequence()
: mType(0), mTag(0), mIsValidContainer(true), mIsExpanded(true) {
/* member initializers and constructor code */
}
nsNSSASN1Sequence::~nsNSSASN1Sequence() { /* destructor code */
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetASN1Objects(nsIMutableArray** aASN1Objects) {
if (!mASN1Objects) {
mASN1Objects = nsArrayBase::Create();
}
*aASN1Objects = mASN1Objects;
NS_IF_ADDREF(*aASN1Objects);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetASN1Objects(nsIMutableArray* aASN1Objects) {
mASN1Objects = aASN1Objects;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetTag(uint32_t* aTag) {
*aTag = mTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetTag(uint32_t aTag) {
mTag = aTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetType(uint32_t* aType) {
*aType = mType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetType(uint32_t aType) {
mType = aType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetDisplayName(nsAString& aDisplayName) {
aDisplayName = mDisplayName;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetDisplayName(const nsAString& aDisplayName) {
mDisplayName = aDisplayName;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetDisplayValue(nsAString& aDisplayValue) {
aDisplayValue = mDisplayValue;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetDisplayValue(const nsAString& aDisplayValue) {
mDisplayValue = aDisplayValue;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetIsValidContainer(bool* aIsValidContainer) {
NS_ENSURE_ARG_POINTER(aIsValidContainer);
*aIsValidContainer = mIsValidContainer;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetIsValidContainer(bool aIsValidContainer) {
mIsValidContainer = aIsValidContainer;
SetIsExpanded(mIsValidContainer);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetIsExpanded(bool* aIsExpanded) {
NS_ENSURE_ARG_POINTER(aIsExpanded);
*aIsExpanded = mIsExpanded;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetIsExpanded(bool aIsExpanded) {
mIsExpanded = aIsExpanded;
return NS_OK;
}
nsNSSASN1PrintableItem::nsNSSASN1PrintableItem()
: mType(0), mTag(0), mData(nullptr), mLen(0) {
/* member initializers and constructor code */
}
nsNSSASN1PrintableItem::~nsNSSASN1PrintableItem() {
/* destructor code */
if (mData) free(mData);
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetDisplayValue(nsAString& aValue) {
aValue = mValue;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetDisplayValue(const nsAString& aValue) {
mValue = aValue;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetTag(uint32_t* aTag) {
*aTag = mTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetTag(uint32_t aTag) {
mTag = aTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetType(uint32_t* aType) {
*aType = mType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetType(uint32_t aType) {
mType = aType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetData(char* data, uint32_t len) {
if (len > 0) {
if (mLen < len) {
mData = (unsigned char*)moz_xrealloc(mData, len);
}
memcpy(mData, data, len);
} else if (len == 0) {
if (mData) {
free(mData);
mData = nullptr;
}
}
mLen = len;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetData(char** outData, uint32_t* outLen) {
NS_ENSURE_ARG_POINTER(outData);
NS_ENSURE_ARG_POINTER(outLen);
*outData = (char*)mData;
*outLen = mLen;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetDisplayName(nsAString& aDisplayName) {
aDisplayName = mDisplayName;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetDisplayName(const nsAString& aDisplayName) {
mDisplayName = aDisplayName;
return NS_OK;
}

View File

@ -1,63 +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 _NSSASN_H_
#define _NSSASN_H_
#include "nscore.h"
#include "nsIX509Cert.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIASN1Sequence.h"
#include "nsIASN1PrintableItem.h"
#include "nsIMutableArray.h"
//
// Read comments in nsIX509Cert.idl for a description of the desired
// purpose for this ASN1 interface implementation.
//
class nsNSSASN1Sequence : public nsIASN1Sequence {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1SEQUENCE
NS_DECL_NSIASN1OBJECT
nsNSSASN1Sequence();
protected:
virtual ~nsNSSASN1Sequence();
/* additional members */
private:
nsCOMPtr<nsIMutableArray> mASN1Objects;
nsString mDisplayName;
nsString mDisplayValue;
uint32_t mType;
uint32_t mTag;
bool mIsValidContainer;
bool mIsExpanded;
};
class nsNSSASN1PrintableItem : public nsIASN1PrintableItem {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1PRINTABLEITEM
NS_DECL_NSIASN1OBJECT
nsNSSASN1PrintableItem();
protected:
virtual ~nsNSSASN1PrintableItem();
/* additional members */
private:
nsString mDisplayName;
nsString mValue;
uint32_t mType;
uint32_t mTag;
unsigned char* mData;
uint32_t mLen;
};
nsresult CreateFromDER(unsigned char* data, unsigned int len,
nsIASN1Object** retval);
#endif //_NSSASN_H_

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,6 @@
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsIX509Cert.h"
#include "nsNSSASN1Object.h"
#include "nsNSSCertHelper.h"
#include "nsNSSCertTrust.h"
#include "nsNSSCertValidity.h"
@ -720,15 +719,6 @@ nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity) {
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificate::GetASN1Structure(nsIASN1Object** aASN1Structure) {
NS_ENSURE_ARG_POINTER(aASN1Structure);
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_SAME_THREAD;
}
return CreateASN1Struct(aASN1Structure);
}
NS_IMETHODIMP
nsNSSCertificate::Equals(nsIX509Cert* other, bool* result) {
NS_ENSURE_ARG(other);

View File

@ -12,7 +12,6 @@
#include "ScopedNSSTypes.h"
#include "certt.h"
#include "nsCOMPtr.h"
#include "nsIASN1Object.h"
#include "nsIClassInfo.h"
#include "nsISerializable.h"
#include "nsIX509Cert.h"
@ -26,7 +25,6 @@ class DERArray;
} // namespace mozilla
class nsINSSComponent;
class nsIASN1Sequence;
class nsNSSCertificate final : public nsIX509Cert,
public nsISerializable,
@ -76,8 +74,6 @@ class nsNSSCertificate final : public nsIX509Cert,
bool mPermDelete;
uint32_t mCertType;
std::vector<nsString> mSubjectAltNames;
nsresult CreateASN1Struct(nsIASN1Object** aRetVal);
nsresult CreateTBSCertificateASN1Struct(nsIASN1Sequence** retSequence);
nsresult GetSortableDate(PRTime aTime, nsAString& _aSortableDate);
bool InitFromDER(char* certDER, int derLen); // return false on failure

View File

@ -12,205 +12,41 @@ var { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
var { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const PREF_ABOUT_CERTIFICATE = "security.aboutcertificate.enabled";
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_ABOUT_CERTIFICATE);
});
add_task(async function testCAandTitle() {
let cert = await readCertificate("ca.pem", "CTu,CTu,CTu");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "ca");
} else {
let win = await displayCertificate(cert);
checkUsages(win, [{ id: "verify-ssl-ca", args: null }]);
checkDetailsPane(win, ["ca"]);
// There's no real need to test the title for every cert, so we just test it
// once here.
Assert.deepEqual(
win.document.l10n.getAttributes(win.document.documentElement),
{ args: { certName: "ca" }, id: "cert-viewer-title" },
"Actual and expected title should match"
);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "ca");
});
add_task(async function testSSLEndEntity() {
let cert = await readCertificate("ssl-ee.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "ssl-ee");
} else {
let win = await displayCertificate(cert);
checkUsages(win, [
{ id: "verify-ssl-server", args: null },
{ id: "verify-ssl-client", args: null },
]);
checkDetailsPane(win, ["ca", "ssl-ee"]);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "ssl-ee");
});
add_task(async function testEmailEndEntity() {
let cert = await readCertificate("email-ee.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "email-ee");
} else {
let win = await displayCertificate(cert);
checkUsages(win, [
{ id: "verify-email-recip", args: null },
{ id: "verify-email-signer", args: null },
]);
checkDetailsPane(win, ["ca", "email-ee"]);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "email-ee");
});
add_task(async function testCodeSignEndEntity() {
let cert = await readCertificate("code-ee.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "code-ee");
} else {
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified-unknown", args: null });
checkDetailsPane(win, ["code-ee"]);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "code-ee");
});
add_task(async function testExpired() {
let cert = await readCertificate("expired-ca.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "expired-ca");
} else {
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified-cert-expired", args: null });
checkDetailsPane(win, ["expired-ca"]);
await BrowserTestUtils.closeWindow(win);
// These tasks may run in any order, so we run this additional testcase in the
// same task.
let eeCert = await readCertificate("ee-from-expired-ca.pem", ",,");
let eeWin = await displayCertificate(eeCert);
checkError(eeWin, { id: "cert-not-verified-ca-invalid", args: null });
checkDetailsPane(eeWin, ["ee-from-expired-ca"]);
await BrowserTestUtils.closeWindow(eeWin);
}
}
});
add_task(async function testUnknownIssuer() {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, false);
let cert = await readCertificate("unknown-issuer.pem", ",,");
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified-issuer-unknown", args: null });
checkDetailsPane(win, ["unknown-issuer"]);
await BrowserTestUtils.closeWindow(win);
});
add_task(async function testInsecureAlgo() {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, false);
let cert = await readCertificate("md5-ee.pem", ",,");
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified_algorithm-disabled", args: null });
checkDetailsPane(win, ["md5-ee"]);
await BrowserTestUtils.closeWindow(win);
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "expired-ca");
});
add_task(async function testUntrusted() {
let cert = await readCertificate("untrusted-ca.pem", "p,p,p");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "untrusted-ca");
} else {
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified-cert-not-trusted", args: null });
checkDetailsPane(win, ["untrusted-ca"]);
await BrowserTestUtils.closeWindow(win);
// These tasks may run in any order, so we run this additional testcase in the
// same task.
let eeCert = await readCertificate("ee-from-untrusted-ca.pem", ",,");
let eeWin = await displayCertificate(eeCert);
checkError(eeWin, {
id: "cert-not-verified-issuer-not-trusted",
args: null,
});
checkDetailsPane(eeWin, ["ee-from-untrusted-ca"]);
await BrowserTestUtils.closeWindow(eeWin);
}
}
});
add_task(async function testRevoked() {
// 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).
if (AppConstants.MOZ_NEW_CERT_STORAGE) {
let certBlocklist = Cc["@mozilla.org/security/certstorage;1"].getService(
Ci.nsICertStorage
);
let result = await new Promise(resolve =>
certBlocklist.setRevocations(
[
{
QueryInterface: ChromeUtils.generateQI([
Ci.nsISubjectAndPubKeyRevocationState,
]),
subject: "MBIxEDAOBgNVBAMMB3Jldm9rZWQ=", // CN=revoked
pubKey: "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=", // hash of the shared key
state: Ci.nsICertStorage.STATE_ENFORCE, // yes, we want this to be revoked
},
],
resolve
)
);
Assert.equal(result, Cr.NS_OK, "setting revocation state should succeed");
} else {
let certBlocklist = Cc["@mozilla.org/security/certblocklist;1"].getService(
Ci.nsICertBlocklist
);
certBlocklist.revokeCertBySubjectAndPubKey(
"MBIxEDAOBgNVBAMMB3Jldm9rZWQ=", // CN=revoked
"VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="
); // hash of the shared key
}
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, false);
let cert = await readCertificate("revoked.pem", ",,");
let win = await displayCertificate(cert);
// As of bug 1312827, OneCRL only applies to TLS web server certificates, so
// this certificate will actually verify successfully for every end-entity
// usage except TLS web server.
checkUsages(win, [
{ id: "verify-email-recip", args: null },
{ id: "verify-email-signer", args: null },
{ id: "verify-ssl-client", args: null },
]);
checkDetailsPane(win, ["ca", "revoked"]);
await BrowserTestUtils.closeWindow(win);
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "untrusted-ca");
});
add_task(async function testInvalid() {
@ -219,207 +55,18 @@ add_task(async function testInvalid() {
// shouldn't be valid for any usage. Sadly, we give a pretty bad error
// message in this case.
let cert = await readCertificate("invalid.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "invalid");
} else {
let win = await displayCertificate(cert);
checkError(win, { id: "cert-not-verified-unknown", args: null });
checkDetailsPane(win, ["invalid"]);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "invalid");
});
add_task(async function testLongOID() {
// This certificate has a certificatePolicies extension with a policy with a
// very long OID. This tests that we don't crash when looking at it.
let cert = await readCertificate("longOID.pem", ",,");
for (let isNewCertViewer of [true, false]) {
Services.prefs.setBoolPref(PREF_ABOUT_CERTIFICATE, isNewCertViewer);
if (isNewCertViewer) {
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "Long OID");
} else {
let win = await displayCertificate(cert);
checkDetailsPane(win, ["Long OID"]);
await BrowserTestUtils.closeWindow(win);
}
}
let url = getURL(cert);
await openCertViewerAndCheckTabName(url, "Long OID");
});
/**
* 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 win = window.openDialog(
"chrome://pippki/content/certViewer.xhtml",
"",
"",
certificate
);
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 {Object[]}
* An array of objects including the L10n Ids 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(win.document.l10n.getAttributes(child));
}
});
return determinedUsages.sort(compareL10Ids);
}
/**
* 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 {Object}
* A object with L10n id of the string describing the error encountered,
* or the success message if the certificate is valid for at least one usage.
*/
function getError(win) {
let verified = win.document.getElementById("verified");
return win.document.l10n.getAttributes(verified);
}
/**
* Given a certificate viewer window and an array of l10n ids 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 {Object[]} usagesL10nIds
* An array of object with l10n ids of expected usage descriptions.
*/
function checkUsages(win, usagesL10nIds) {
Assert.deepEqual(
getError(win),
{ id: "cert-verified", args: null },
"should have successful verification message"
);
let determinedUsages = getUsages(win);
usagesL10nIds.sort(compareL10Ids);
Assert.deepEqual(
determinedUsages.length,
usagesL10nIds.length,
"number of usages as determined by cert viewer should be equal"
);
while (usagesL10nIds.length > 0) {
Assert.deepEqual(
determinedUsages.pop(),
usagesL10nIds.pop(),
"usages as determined by cert viewer should be equal"
);
}
}
/**
* Given a certificate viewer window and l10n id of an expected error, verifies that the
* window is actually showing that error.
*
* @param {window} win
* The certificate viewer window.
* @param {Object} errorL10nId
* The object with l10n id of expected error message.
*/
function checkError(win, errorL10nId) {
let determinedUsages = getUsages(win);
Assert.equal(
determinedUsages.length,
0,
"should not have any successful usages in error case"
);
Assert.deepEqual(
getError(win),
errorL10nId,
"determined error should be the same as expected error"
);
}
/**
* Given a certificate viewer window and an expected list of certificate names,
* verifies that the certificate details pane of the viewer shows the expected
* certificates in the expected order.
*
* @param {window} win
* The certificate viewer window.
* @param {String[]} names
* An array of expected certificate names.
*/
function checkDetailsPane(win, names) {
let tree = win.document.getElementById("treesetDump");
let nodes = tree.querySelectorAll("treecell");
Assert.equal(
nodes.length,
names.length,
"details pane: should have the expected number of cert names"
);
for (let i = 0; i < names.length; i++) {
Assert.equal(
nodes[i].getAttribute("label"),
names[i],
"details pain: should have expected cert name"
);
}
}
/**
* Given two objects with l10n id, compare them by l10n id for sorting.
*
* @param {Objects} ida,idb
* The objects with l10n id.
* @param {integer}
* An integer representing true of false.
*/
function compareL10Ids(ida, idb) {
if (ida.id < idb.id) {
return -1;
} else if (ida.id > idb.id) {
return 1;
}
return 0;
}
/**
* Given a certificate, returns its PEMs (each one of the certificate chain) string in a url.
* @param {Object} cert

View File

@ -12,49 +12,6 @@ const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
);
function run_test() {
const pem =
"MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgN" +
"VBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIE" +
"RpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw" +
"6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQG" +
"EwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWd" +
"pdGFsIC0gQ2VydGljw6FtYXJhIFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbW" +
"FyYSBTLkEuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPU" +
"ZYILrgIem08kBeGqentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9" +
"JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpO" +
"QY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4Ny+LvB" +
"2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ54v5aHxwD6Mq0" +
"Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm8Ibbq0nXl21Ii/kD" +
"wFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhfHjlvgWJsxS3" +
"EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkX" +
"kwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5" +
"lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxE" +
"Cp1bczwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1U" +
"dDwEB/wQEAwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmD" +
"CBlTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb" +
"20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVz" +
"dGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb" +
"3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4" +
"902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBCl" +
"ETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb" +
"0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/Ey" +
"XyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNE" +
"CW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpO" +
"e9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJDW2Za" +
"iogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5hRqGEPQg" +
"nTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecUIw" +
"4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==";
let cert = gCertDB.constructX509FromBase64(pem);
// This certificate contains a string that claims to be compatible with UTF-8
// but isn't. Getting the asn1 structure of it exercises the code path that
// decodes this value. If we don't assert in debug builds, presumably we
// handled this value safely.
notEqual(
cert.ASN1Structure,
null,
"accessing nsIX509Cert.ASN1Structure shouldn't assert"
);
// This certificate has a number of placeholder byte sequences that we can
// replace with invalid UTF-8 to ensure that we handle these cases safely.
let certificateToAlterFile = do_get_file(
@ -120,11 +77,6 @@ function testUTF8InField(field, replacementPrefix, certificateBytesToAlter) {
gUniqueIssuerCounter++;
let cert = gCertDB.constructX509(stringToArray(bytes));
notEqual(cert[field], null, `accessing nsIX509Cert.${field} shouldn't fail`);
notEqual(
cert.ASN1Structure,
null,
"accessing nsIX509Cert.ASN1Structure shouldn't assert"
);
notEqual(
cert.getEmailAddresses(),
null,

View File

@ -64,19 +64,6 @@ function checkIntermediate(cert, expectedResult) {
);
}
// Test that the code that decodes certificates to display them in the
// certificate manager correctly handles the version field.
function checkCertVersion(cert, expectedVersionString) {
let asn1 = cert.ASN1Structure.QueryInterface(Ci.nsIASN1Sequence);
let tbsCertificate = asn1.ASN1Objects.queryElementAt(0, Ci.nsIASN1Sequence);
let version = tbsCertificate.ASN1Objects.queryElementAt(0, Ci.nsIASN1Object);
equal(
version.displayValue,
expectedVersionString,
"Actual and expected version strings should match"
);
}
add_task(async function() {
loadCertWithTrust("ca", "CTu,,");
@ -314,9 +301,4 @@ add_task(async function() {
await checkEndEntity(certFromFile("ss-v2-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER);
await checkEndEntity(certFromFile("ss-v3-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER);
await checkEndEntity(certFromFile("ss-v4-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER);
checkCertVersion(certFromFile("ss-v1-noBC"), "Version 1");
checkCertVersion(certFromFile("int-v2-BC-cA_ca"), "Version 2");
checkCertVersion(certFromFile("ee-v3-BC-not-cA_ca"), "Version 3");
checkCertVersion(certFromFile("int-v4-BC-not-cA_ca"), "Version 4");
});

View File

@ -1,67 +0,0 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
"use strict";
// Checks that invalid OID encodings are detected in the Cert Viewer Details tab.
do_get_profile(); // Must be called before getting nsIX509CertDB
const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
function certFromFile(filename) {
return constructCertFromFile(`test_certviewer_invalid_oids/${filename}.pem`);
}
function test(certFilename, expectedOIDText) {
let cert = certFromFile(certFilename);
let certDumpTree = Cc["@mozilla.org/security/nsASN1Tree;1"].createInstance(
Ci.nsIASN1Tree
);
certDumpTree.loadASN1Structure(cert.ASN1Structure);
let actualOIDText = certDumpTree.getDisplayData(9);
equal(
actualOIDText,
expectedOIDText,
"Actual and expected OID text should match"
);
}
function run_test() {
test(
"bug483440-attack2b",
"Object Identifier (2 5 4 Unknown) = www.bank.com\n" +
"OU = Hacking Division\n" +
"CN = www.badguy.com\nO = Badguy Inc\n"
);
test(
"bug483440-pk10oflo",
"Object Identifier (2 5 4 Unknown) = www.bank.com\n" +
"OU = Hacking Division\n" +
"CN = www.badguy.com\nO = Badguy Inc\n"
);
test(
"bug483440-attack7",
// Check 88 80 80 80 01, not leading, have to pass
"Object Identifier (2 5 4 2147483649) = attack1\n" +
// Check 90 80 80 80 01, not leading, have to fail
"Object Identifier (2 5 4 Unknown) = attack2\n" +
// Check 80 80 80 80 80, not leading, have to fail
"Object Identifier (2 5 4 Unknown) = attack3\n" +
// Check 81 81, trailing, have to fail
"Object Identifier (2 5 4 3 Unknown) = attack4\n" +
// Check FF FF FF 7F, not leading, have to pass
"Object Identifier (2 5 4 268435455) = attack5\n" +
// Check 80 leading, have to fail
"Object Identifier (Unknown 3) = attack6\n" +
// Check 14757 = 2*40 + 14677 leading single byte encoded as F325,
// have to pass
"Object Identifier (2 14677 4 3) = attack7\n"
);
}

View File

@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICKDCCAZGgAwIBAgIFAIyjFPowDQYJKoZIhvcNAQEFBQAwKDEXMBUGA1UEAwwO
KgB3d3cubXlDQS5vcmcxDTALBgNVBAMTBG15Q0EwHhcNMDkwMzE0MTg0NzU2WhcN
MTkwMzE0MTg0NzU2WjBhMRMwEQYDVQQKEwpCYWRndXkgSW5jMRcwFQYDVQQDEw53
d3cuYmFkZ3V5LmNvbTEZMBcGA1UECxMQSGFja2luZyBEaXZpc2lvbjEWMBQGBFUE
gAMTDHd3dy5iYW5rLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2YvL
GgmF0OTLBKz0nYTvR+DlnZai7b2MqAIM9IUEpMfqzJPNYCsXziYXgHtr/do9ppJP
BhDjeyIGEOSpgBqdkWItxlLopUHnf8VKwnDPPj4KkNyXuTLm60X/ph+/zrjTw+kU
m+/kVYstgGMuTIoTuu7loxCqqeVlAgc5lzTpUhkCAwEAAaMlMCMwDAYDVR0TAQH/
BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQAKHl1G
vaXftj5QPK3eIT6Q3fWuGKR39grlg5GL/WocPanYycOlm9zvT1Hx95cY6msIXSKp
xycndJ02ODX35DDgolV6VHUsM9yoagk+eqs5kCqW2qiv3moIshL0yWVhuCobMA+E
D3wHFCPqVU+igRdCrEQDxZHoFOR4J/DKHfGANg==
-----END CERTIFICATE-----

View File

@ -1,16 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICljCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkDERMA8GBPMlBAMTB2F0
dGFjazcxEDAOBgOABAMTB2F0dGFjazYxEzARBgZVBP///38TB2F0dGFjazUxEjAQ
BgVVBAOBgRMHYXR0YWNrNDEUMBIGB1UEgICAgIATB2F0dGFjazMxFDASBgdVBJCA
gIABEwdhdHRhY2syMRQwEgYHVQSIgICAARMHYXR0YWNrMTAeFw0wOTA0MTMxNDAw
MzdaFw0yOTA0MTMxNDAwMzdaMIGQMREwDwYE8yUEAxMHYXR0YWNrNzEQMA4GA4AE
AxMHYXR0YWNrNjETMBEGBlUE////fxMHYXR0YWNrNTESMBAGBVUEA4GBEwdhdHRh
Y2s0MRQwEgYHVQSAgICAgBMHYXR0YWNrMzEUMBIGB1UEkICAgAETB2F0dGFjazIx
FDASBgdVBIiAgIABEwdhdHRhY2sxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC77fQ1wrywBnVmr8XO0/78/qFOz+sjnMlpBvLx5UImittgMNSgEqNulRDbO0qG
K4tlFF2sNsS7aOun6Cq7yl2+a8mIljmjzs+iwCLOEAkQTOM4RsdCosJVy/fjwmH1
xI0uXt5cPkA0FM7B/IZSzWSC+2gY1+u1AhRJ35bXDhu92wIDAQABMA0GCSqGSIb3
DQEBBQUAA4GBAFZitQjsQJ1+XsxKchBefilaHsi4oncc05P29IXcRbHI8wK2vNk8
kkG2c6M4a4Rx1R4C3n99NwXH4vyNUbA9FuMSAdjaS3TW3zm8lKNCuIWGuI2Vvefy
+wNcCfb8B4AuP8pZOqqKsspgiBAE1EPPErnb7nMVLCnf+ts9ARXLBZTi
-----END CERTIFICATE-----

View File

@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICMTCCAZqgAwIBAgIFAIyjFTAwDQYJKoZIhvcNAQEFBQAwKDEXMBUGA1UEAwwO
KgB3d3cubXlDQS5vcmcxDTALBgNVBAMTBG15Q0EwHhcNMDkwMzE0MTg0ODI0WhcN
MTkwMzE0MTg0ODI0WjBqMRMwEQYDVQQKEwpCYWRndXkgSW5jMRcwFQYDVQQDEw53
d3cuYmFkZ3V5LmNvbTEZMBcGA1UECxMQSGFja2luZyBEaXZpc2lvbjEfMB0GDVUE
goCAgICAgICAgAMTDHd3dy5iYW5rLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA2YvLGgmF0OTLBKz0nYTvR+DlnZai7b2MqAIM9IUEpMfqzJPNYCsXziYX
gHtr/do9ppJPBhDjeyIGEOSpgBqdkWItxlLopUHnf8VKwnDPPj4KkNyXuTLm60X/
ph+/zrjTw+kUm+/kVYstgGMuTIoTuu7loxCqqeVlAgc5lzTpUhkCAwEAAaMlMCMw
DAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUF
AAOBgQBr+ekYoADBm6kbHBR1oc/6O9ZciRsTbxIAl3xjA3kNEeiUXXSoe+1dlt3Z
7D6EaQztqR8usCW728J3vi8p/XxociK3r4aq0Sxu29gp21N1V/Um8y3ssI+Yt9Im
oHlo5ikUXra5PtGAwi4FymrU5dWlHxYk1PlNP5nsvxdElPZnZA==
-----END CERTIFICATE-----

View File

@ -21,7 +21,6 @@ support-files =
test_cert_utf8/**
test_cert_version/**
test_certDB_import/**
test_certviewer_invalid_oids/**
test_content_signing/**
test_ct/**
test_delegated_credentials/**
@ -97,8 +96,6 @@ skip-if = toolkit == 'android' && processor == 'x86_64'
[test_certDB_import_with_master_password.js]
# nsCertificateDialogs not available in geckoview, bug 1554276
skip-if = toolkit == 'android' && processor == 'x86_64'
[test_certviewer_invalid_oids.js]
skip-if = toolkit == 'android'
[test_constructX509FromBase64.js]
[test_content_signing.js]
[test_crlite_filters.js]

View File

@ -3,8 +3,6 @@
"use strict";
const PREF = "security.aboutcertificate.enabled";
function checkCertTabs() {
let certificatePages = 0;
for (let tab of gBrowser.tabs) {
@ -21,10 +19,6 @@ add_task(async function testBadCert() {
let tab = await openErrorPage();
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
for (let i = 0; i < 2; i++) {
// try opening two certificates that are the same
@ -59,10 +53,6 @@ add_task(async function testGoodCert() {
info("Testing page info");
let url = "https://example.com/";
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
info(`Loading ${url}`);
await BrowserTestUtils.withNewTab({ gBrowser, url }, async function() {
info("Opening pageinfo");
@ -98,10 +88,6 @@ add_task(async function testPreferencesCert() {
info("Testing preferences cert");
let url = "about:preferences#privacy";
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
info(`Loading ${url}`);
await BrowserTestUtils.withNewTab({ gBrowser, url }, async function(browser) {
checkAndClickButton(browser.contentDocument, "viewCertificatesButton");

View File

@ -6,7 +6,6 @@
const { ContentTaskUtils } = ChromeUtils.import(
"resource://testing-common/ContentTaskUtils.jsm"
);
const PREF = "security.aboutcertificate.enabled";
const TEST_CERT_BASE64 =
"MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd+G7+u6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG/vUUWVrsxC2gsbR8WJq+cYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI+pjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek/ojvedPWe8dhciHkxOC2qPFZvVFMwg1/o/b80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z+lvrSjEgrddemWyGGalqyFp1rXlVM1Tf4/IYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c+yvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT/B9TdQ8eXwebo60/MCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP/zbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM/ed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql/68G5q844kFuC6JPl4LVT9mciD+VW6bHUSXD9xifL9DqdJ0Ic0SllTlM+oq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc/gjxteskq/Vl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8+OJThUbzK16a2CI3Rg4agKSJk+uA47h1/ImmngpFLRb/MvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl/wpPgyQgcTM=";
@ -72,10 +71,6 @@ function openCertDownloadDialog(cert) {
add_task(async function openFromPopUp() {
info("Testing openFromPopUp");
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
@ -116,10 +111,6 @@ add_task(async function testBadCert() {
let tab = await openErrorPage();
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
let tabsCount = gBrowser.tabs.length;
let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
@ -154,10 +145,6 @@ add_task(async function testBadCertIframe() {
let tab = await openErrorPage(true);
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
let tabsCount = gBrowser.tabs.length;
let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
@ -192,10 +179,6 @@ add_task(async function testGoodCert() {
info("Testing page info");
let url = "https://example.com/";
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
let tabsCount = gBrowser.tabs.length;
info(`Loading ${url}`);
@ -231,10 +214,6 @@ add_task(async function testPreferencesCert() {
info("Testing preferences cert");
let url = "about:preferences#privacy";
SpecialPowers.pushPrefEnv({
set: [[PREF, true]],
});
let tabsCount;
info(`Loading ${url}`);