forked from mirrors/gecko-dev
Bug 1559225 - Build a certificate chain. r=johannh,keeler
Added third party libraries using browserify, builds a certificate chain using some functions defined in https://github.com/april/certainly-something and using a dummy certificate chain. r=johannh Differential Revision: https://phabricator.services.mozilla.com/D34927 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
1000118805
commit
dc61c90a77
21 changed files with 54699 additions and 25 deletions
|
|
@ -198,3 +198,7 @@ tps_result\.json
|
|||
|
||||
# Ignore the build directories of WebRender standalone builds.
|
||||
gfx/wr/target/
|
||||
|
||||
# Ignore this files in certviewer
|
||||
toolkit/components/certviewer/content/node_modules/
|
||||
toolkit/components/certviewer/content/package-lock.json
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ const kESModuleList = new Set([
|
|||
/browser\/aboutlogins\/.*\.js$/,
|
||||
/browser\/protections.js$/,
|
||||
/browser\/lockwise-card.js$/,
|
||||
/toolkit\/content\/global\/certviewer\/components\/.*\.js$/,
|
||||
/toolkit\/content\/global\/certviewer\/.*\.js$/,
|
||||
]);
|
||||
|
||||
// Normally we would use reflect.jsm to get Reflect.parse. However, if
|
||||
|
|
|
|||
13
toolkit/components/certviewer/content/.eslintrc.js
Normal file
13
toolkit/components/certviewer/content/.eslintrc.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"globals": {
|
||||
"asn1js": true,
|
||||
"pvutils": true,
|
||||
"pkijs": true,
|
||||
},
|
||||
}
|
||||
14
toolkit/components/certviewer/content/README.md
Normal file
14
toolkit/components/certviewer/content/README.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Certificate Viewer
|
||||
|
||||
## Dependencies
|
||||
|
||||
[PKI.js](https://github.com/PeculiarVentures/PKI.js)
|
||||
[ASN1.js](https://github.com/PeculiarVentures/ASN1.js)
|
||||
[pvutils.js](https://github.com/PeculiarVentures/pvutils)
|
||||
[Browserify](http://browserify.org/)
|
||||
|
||||
## Updating dependencies
|
||||
|
||||
Install all the dependencies doing `npm i`.
|
||||
|
||||
Run `npm run build` any time you add something new to `pvutils.js`, `pkijs.js`, `asn1.js` or any other file required in that one.
|
||||
9
toolkit/components/certviewer/content/asn1js.js
Normal file
9
toolkit/components/certviewer/content/asn1js.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* 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/. */
|
||||
|
||||
const asn1js = require("asn1js"); // version 2.0.22
|
||||
|
||||
module.exports = {
|
||||
asn1js,
|
||||
};
|
||||
555
toolkit/components/certviewer/content/certDecoder.js
Normal file
555
toolkit/components/certviewer/content/certDecoder.js
Normal file
|
|
@ -0,0 +1,555 @@
|
|||
/* 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/. */
|
||||
|
||||
const { fromBER } = asn1js.asn1js;
|
||||
const { Certificate } = pkijs.pkijs;
|
||||
import {
|
||||
b64urltodec,
|
||||
b64urltohex,
|
||||
getObjPath,
|
||||
hash,
|
||||
hashify,
|
||||
} from "chrome://global/content/certviewer/utils.js";
|
||||
import { strings } from "chrome://global/content/certviewer/strings.js";
|
||||
import { ctLogNames } from "chrome://global/content/certviewer/ctlognames.js";
|
||||
|
||||
const getTimeZone = () => {
|
||||
let timeZone = new Date().toString().match(/\(([A-Za-z\s].*)\)/);
|
||||
if (timeZone === null) {
|
||||
// America/Chicago
|
||||
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
} else if (timeZone.length > 1) {
|
||||
timeZone = timeZone[1]; // Central Daylight Time
|
||||
} else {
|
||||
timeZone = "Local Time"; // not sure if this is right, but let's go with it for now
|
||||
}
|
||||
return timeZone;
|
||||
};
|
||||
|
||||
const getPublicKeyInfo = x509 => {
|
||||
let spki = Object.assign(
|
||||
{
|
||||
crv: undefined,
|
||||
e: undefined,
|
||||
kty: undefined,
|
||||
n: undefined,
|
||||
keysize: undefined,
|
||||
x: undefined,
|
||||
xy: undefined,
|
||||
y: undefined,
|
||||
},
|
||||
x509.subjectPublicKeyInfo
|
||||
);
|
||||
|
||||
if (spki.kty === "RSA") {
|
||||
spki.e = b64urltodec(spki.e); // exponent
|
||||
spki.keysize = b64urltohex(spki.n).length * 8; // key size in bits
|
||||
spki.n = hashify(b64urltohex(spki.n)); // modulus
|
||||
} else if (spki.kty === "EC") {
|
||||
spki.kty = "Elliptic Curve";
|
||||
spki.keysize = parseInt(spki.crv.split("-")[1]); // this is a bit hacky
|
||||
spki.x = hashify(b64urltohex(spki.x)); // x coordinate
|
||||
spki.y = hashify(b64urltohex(spki.y)); // y coordinate
|
||||
spki.xy = `04:${spki.x}:${spki.y}`; // 04 (uncompressed) public key
|
||||
}
|
||||
return spki;
|
||||
};
|
||||
|
||||
const getX509Ext = (extensions, v) => {
|
||||
for (var extension in extensions) {
|
||||
if (extensions[extension].extnID === v) {
|
||||
return extensions[extension];
|
||||
}
|
||||
}
|
||||
return {
|
||||
extnValue: undefined,
|
||||
parsedValue: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
const getKeyUsages = (x509, criticalExtensions) => {
|
||||
let keyUsages = {
|
||||
critical: criticalExtensions.includes("2.5.29.15"),
|
||||
purposes: [],
|
||||
};
|
||||
|
||||
let keyUsagesBS = getX509Ext(x509.extensions, "2.5.29.15").parsedValue;
|
||||
if (keyUsagesBS !== undefined) {
|
||||
// parse the bit string, shifting as necessary
|
||||
let unusedBits = keyUsagesBS.valueBlock.unusedBits;
|
||||
keyUsagesBS = parseInt(keyUsagesBS.valueBlock.valueHex, 16) >> unusedBits;
|
||||
|
||||
// iterate through the bit string
|
||||
strings.keyUsages.slice(unusedBits - 1).forEach(usage => {
|
||||
if (keyUsagesBS & 1) {
|
||||
keyUsages.purposes.push(usage);
|
||||
}
|
||||
|
||||
keyUsagesBS = keyUsagesBS >> 1;
|
||||
});
|
||||
|
||||
// reverse the order for legibility
|
||||
keyUsages.purposes.reverse();
|
||||
}
|
||||
|
||||
return keyUsages;
|
||||
};
|
||||
|
||||
const parseSubsidiary = distinguishedNames => {
|
||||
const subsidiary = {
|
||||
cn: "",
|
||||
dn: [],
|
||||
entries: [],
|
||||
};
|
||||
|
||||
distinguishedNames.forEach(dn => {
|
||||
const name = strings.names[dn.type];
|
||||
const value = dn.value.valueBlock.value;
|
||||
|
||||
if (name === undefined) {
|
||||
subsidiary.dn.push(`OID.${dn.type}=${value}`);
|
||||
subsidiary.entries.push([`OID.${dn.type}`, value]);
|
||||
} else if (name.short === undefined) {
|
||||
subsidiary.dn.push(`OID.${dn.type}=${value}`);
|
||||
subsidiary.entries.push([name.long, value]);
|
||||
} else {
|
||||
subsidiary.dn.push(`${name.short}=${value}`);
|
||||
subsidiary.entries.push([name.long, value]);
|
||||
|
||||
// add the common name for tab display
|
||||
if (name.short === "cn") {
|
||||
subsidiary.cn = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// turn path into a string
|
||||
subsidiary.dn = subsidiary.dn.join(", ");
|
||||
|
||||
return subsidiary;
|
||||
};
|
||||
|
||||
const getSubjectAltNames = (x509, criticalExtensions) => {
|
||||
let san = getX509Ext(x509.extensions, "2.5.29.17").parsedValue;
|
||||
if (san && san.hasOwnProperty("altNames")) {
|
||||
san = Object.keys(san.altNames).map(x => {
|
||||
const type = san.altNames[x].type;
|
||||
|
||||
switch (type) {
|
||||
case 4: // directory
|
||||
return [
|
||||
strings.san[type],
|
||||
parseSubsidiary(san.altNames[x].value.typesAndValues).dn,
|
||||
];
|
||||
case 7: // ip address
|
||||
let address = san.altNames[x].value.valueBlock.valueHex;
|
||||
|
||||
if (address.length === 8) {
|
||||
// ipv4
|
||||
return [
|
||||
strings.san[type],
|
||||
address
|
||||
.match(/.{1,2}/g)
|
||||
.map(x => parseInt(x, 16))
|
||||
.join("."),
|
||||
];
|
||||
} else if (address.length === 32) {
|
||||
// ipv6
|
||||
return [
|
||||
strings.san[type],
|
||||
address
|
||||
.toLowerCase()
|
||||
.match(/.{1,4}/g)
|
||||
.join(":")
|
||||
.replace(/\b:?(?:0+:?){2,}/, "::"),
|
||||
];
|
||||
}
|
||||
return [strings.san[type], "Unknown IP address"];
|
||||
|
||||
default:
|
||||
return [strings.san[type], san.altNames[x].value];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
san = [];
|
||||
}
|
||||
san = {
|
||||
altNames: san,
|
||||
critical: criticalExtensions.includes("2.5.29.17"),
|
||||
};
|
||||
return san;
|
||||
};
|
||||
|
||||
const getBasicConstraints = (x509, criticalExtensions) => {
|
||||
let basicConstraints;
|
||||
const basicConstraintsExt = getX509Ext(x509.extensions, "2.5.29.19");
|
||||
if (basicConstraintsExt && basicConstraintsExt.parsedValue) {
|
||||
basicConstraints = {
|
||||
cA:
|
||||
basicConstraintsExt.parsedValue.cA !== undefined &&
|
||||
basicConstraintsExt.parsedValue.cA,
|
||||
critical: criticalExtensions.includes("2.5.29.19"),
|
||||
};
|
||||
}
|
||||
return basicConstraints;
|
||||
};
|
||||
|
||||
const getEKeyUsages = (x509, criticalExtensions) => {
|
||||
let eKeyUsages = getX509Ext(x509.extensions, "2.5.29.37").parsedValue;
|
||||
if (eKeyUsages) {
|
||||
eKeyUsages = {
|
||||
critical: criticalExtensions.includes("2.5.29.37"),
|
||||
purposes: eKeyUsages.keyPurposes.map(x => strings.eKU[x] || x),
|
||||
};
|
||||
}
|
||||
return eKeyUsages;
|
||||
};
|
||||
|
||||
const getSubjectKeyID = (x509, criticalExtensions) => {
|
||||
let sKID = getX509Ext(x509.extensions, "2.5.29.14").parsedValue;
|
||||
if (sKID) {
|
||||
sKID = {
|
||||
critical: criticalExtensions.includes("2.5.29.14"),
|
||||
id: hashify(sKID.valueBlock.valueHex),
|
||||
};
|
||||
}
|
||||
return sKID;
|
||||
};
|
||||
|
||||
const getAuthorityKeyID = (x509, criticalExtensions) => {
|
||||
let aKID = getX509Ext(x509.extensions, "2.5.29.35").parsedValue;
|
||||
if (aKID) {
|
||||
aKID = {
|
||||
critical: criticalExtensions.includes("2.5.29.35"),
|
||||
id: hashify(aKID.keyIdentifier.valueBlock.valueHex),
|
||||
};
|
||||
}
|
||||
return aKID;
|
||||
};
|
||||
|
||||
const getCRLPoints = (x509, criticalExtensions) => {
|
||||
let crlPoints = getX509Ext(x509.extensions, "2.5.29.31").parsedValue;
|
||||
if (crlPoints) {
|
||||
crlPoints = {
|
||||
critical: criticalExtensions.includes("2.5.29.31"),
|
||||
points: crlPoints.distributionPoints.map(
|
||||
x => x.distributionPoint[0].value
|
||||
),
|
||||
};
|
||||
}
|
||||
return crlPoints;
|
||||
};
|
||||
|
||||
const getOcspStaple = (x509, criticalExtensions) => {
|
||||
let ocspStaple = getX509Ext(x509.extensions, "1.3.6.1.5.5.7.1.24").extnValue;
|
||||
if (ocspStaple && ocspStaple.valueBlock.valueHex === "3003020105") {
|
||||
ocspStaple = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.5.5.7.1.24"),
|
||||
required: true,
|
||||
};
|
||||
} else {
|
||||
ocspStaple = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.5.5.7.1.24"),
|
||||
required: false,
|
||||
};
|
||||
}
|
||||
return ocspStaple;
|
||||
};
|
||||
|
||||
const getAuthorityInfoAccess = (x509, criticalExtensions) => {
|
||||
let aia = getX509Ext(x509.extensions, "1.3.6.1.5.5.7.1.1").parsedValue;
|
||||
if (aia) {
|
||||
aia = aia.accessDescriptions.map(x => {
|
||||
return {
|
||||
location: x.accessLocation.value,
|
||||
method: strings.aia[x.accessMethod],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
aia = {
|
||||
descriptions: aia,
|
||||
critical: criticalExtensions.includes("1.3.6.1.5.5.7.1.1"),
|
||||
};
|
||||
return aia;
|
||||
};
|
||||
|
||||
const getSCTs = (x509, criticalExtensions) => {
|
||||
let scts = getX509Ext(x509.extensions, "1.3.6.1.4.1.11129.2.4.2").parsedValue;
|
||||
if (scts) {
|
||||
scts = Object.keys(scts.timestamps).map(x => {
|
||||
let logId = scts.timestamps[x].logID.toLowerCase();
|
||||
return {
|
||||
logId: hashify(logId),
|
||||
name: ctLogNames.hasOwnProperty(logId) ? ctLogNames[logId] : undefined,
|
||||
signatureAlgorithm: `${scts.timestamps[x].hashAlgorithm.replace(
|
||||
"sha",
|
||||
"SHA-"
|
||||
)} ${scts.timestamps[x].signatureAlgorithm.toUpperCase()}`,
|
||||
timestamp: `${scts.timestamps[
|
||||
x
|
||||
].timestamp.toLocaleString()} (${getTimeZone()})`,
|
||||
version: scts.timestamps[x].version + 1,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
scts = [];
|
||||
}
|
||||
|
||||
scts = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.11129.2.4.2"),
|
||||
timestamps: scts,
|
||||
};
|
||||
return scts;
|
||||
};
|
||||
|
||||
const getCertificatePolicies = (x509, criticalExtensions) => {
|
||||
let cp = getX509Ext(x509.extensions, "2.5.29.32").parsedValue;
|
||||
if (cp && cp.hasOwnProperty("certificatePolicies")) {
|
||||
cp = cp.certificatePolicies.map(x => {
|
||||
let id = x.policyIdentifier;
|
||||
let name = strings.cps.hasOwnProperty(id)
|
||||
? strings.cps[id].name
|
||||
: undefined;
|
||||
let qualifiers = undefined;
|
||||
let value = strings.cps.hasOwnProperty(id)
|
||||
? strings.cps[id].value
|
||||
: undefined;
|
||||
|
||||
// ansi organization identifiers
|
||||
if (id.startsWith("2.16.840.")) {
|
||||
value = id;
|
||||
id = "2.16.840";
|
||||
name = strings.cps["2.16.840"].name;
|
||||
}
|
||||
|
||||
// statement identifiers
|
||||
if (id.startsWith("1.3.6.1.4.1")) {
|
||||
value = id;
|
||||
id = "1.3.6.1.4.1";
|
||||
name = strings.cps["1.3.6.1.4.1"].name;
|
||||
}
|
||||
|
||||
if (x.hasOwnProperty("policyQualifiers")) {
|
||||
qualifiers = x.policyQualifiers.map(qualifier => {
|
||||
let id = qualifier.policyQualifierId;
|
||||
let name = strings.cps.hasOwnProperty(id)
|
||||
? strings.cps[id].name
|
||||
: undefined;
|
||||
let value = qualifier.qualifier.valueBlock.value;
|
||||
|
||||
// sometimes they are multiple qualifier subblocks, and for now we'll
|
||||
// only return the first one because it's getting really messy at this point
|
||||
if (Array.isArray(value) && value.length === 1) {
|
||||
value = value[0].valueBlock.value;
|
||||
} else if (Array.isArray(value) && value.length > 1) {
|
||||
value = "(currently unsupported)";
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
value,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
qualifiers,
|
||||
value,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
cp = {
|
||||
critical: criticalExtensions.includes("2.5.29.32"),
|
||||
policies: cp,
|
||||
};
|
||||
return cp;
|
||||
};
|
||||
|
||||
const getMicrosoftCryptographicExtensions = (x509, criticalExtensions) => {
|
||||
// now let's parse the Microsoft cryptographic extensions
|
||||
let msCrypto = {
|
||||
caVersion: getX509Ext(x509.extensions, "1.3.6.1.4.1.311.21.1").parsedValue,
|
||||
certificatePolicies: getX509Ext(x509.extensions, "1.3.6.1.4.1.311.21.10")
|
||||
.parsedValue,
|
||||
certificateTemplate: getX509Ext(x509.extensions, "1.3.6.1.4.1.311.21.7")
|
||||
.parsedValue,
|
||||
certificateType: getX509Ext(x509.extensions, "1.3.6.1.4.1.311.20.2")
|
||||
.parsedValue,
|
||||
previousHash: getX509Ext(x509.extensions, "1.3.6.1.4.1.311.21.2")
|
||||
.parsedValue,
|
||||
};
|
||||
|
||||
if (
|
||||
msCrypto.caVersion &&
|
||||
Number.isInteger(msCrypto.caVersion.keyIndex) &&
|
||||
Number.isInteger(msCrypto.caVersion.certificateIndex)
|
||||
) {
|
||||
msCrypto.caVersion = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.311.21.1"),
|
||||
caRenewals: msCrypto.caVersion.certificateIndex,
|
||||
keyReuses:
|
||||
msCrypto.caVersion.certificateIndex - msCrypto.caVersion.keyIndex,
|
||||
};
|
||||
}
|
||||
|
||||
if (msCrypto.certificatePolicies) {
|
||||
msCrypto.certificatePolicies = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.311.21.10"),
|
||||
purposes: msCrypto.certificatePolicies.certificatePolicies.map(
|
||||
x => strings.eKU[x.policyIdentifier] || x.policyIdentifier
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
if (msCrypto.certificateTemplate) {
|
||||
msCrypto.certificateTemplate = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.311.21.7"),
|
||||
id: msCrypto.certificateTemplate.extnID,
|
||||
major: msCrypto.certificateTemplate.templateMajorVersion,
|
||||
minor: msCrypto.certificateTemplate.templateMinorVersion,
|
||||
};
|
||||
}
|
||||
|
||||
if (msCrypto.certificateType) {
|
||||
msCrypto.certificateType = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.311.20.2"),
|
||||
type:
|
||||
strings.microsoftCertificateTypes[
|
||||
msCrypto.certificateType.valueBlock.value
|
||||
] || "Unknown",
|
||||
};
|
||||
}
|
||||
|
||||
if (msCrypto.previousHash) {
|
||||
msCrypto.previousHash = {
|
||||
critical: criticalExtensions.includes("1.3.6.1.4.1.311.21.2"),
|
||||
previousHash: hashify(msCrypto.previousHash.valueBlock.valueHex),
|
||||
};
|
||||
}
|
||||
|
||||
msCrypto.exists = !!(
|
||||
msCrypto.caVersion ||
|
||||
msCrypto.certificatePolicies ||
|
||||
msCrypto.certificateTemplate ||
|
||||
msCrypto.certificateType ||
|
||||
msCrypto.previousHash
|
||||
);
|
||||
|
||||
return msCrypto;
|
||||
};
|
||||
|
||||
export const parse = async certificate => {
|
||||
// certificate could be an array of BER or an array of buffers
|
||||
const supportedExtensions = [
|
||||
"1.3.6.1.4.1.311.20.2", // microsoft certificate type
|
||||
"1.3.6.1.4.1.311.21.2", // microsoft certificate previous hash
|
||||
"1.3.6.1.4.1.311.21.7", // microsoft certificate template
|
||||
"1.3.6.1.4.1.311.21.1", // microsoft certification authority renewal
|
||||
"1.3.6.1.4.1.311.21.10", // microsoft certificate policies
|
||||
"1.3.6.1.4.1.11129.2.4.2", // embedded scts
|
||||
"1.3.6.1.5.5.7.1.1", // authority info access
|
||||
"1.3.6.1.5.5.7.1.24", // ocsp stapling
|
||||
"1.3.101.77", // ct redaction - deprecated and not displayed
|
||||
"2.5.29.14", // subject key identifier
|
||||
"2.5.29.15", // key usages
|
||||
"2.5.29.17", // subject alt names
|
||||
"2.5.29.19", // basic constraints
|
||||
"2.5.29.31", // crl points
|
||||
"2.5.29.32", // certificate policies
|
||||
"2.5.29.35", // authority key identifier
|
||||
"2.5.29.37", // extended key usage
|
||||
];
|
||||
|
||||
let timeZone = getTimeZone();
|
||||
|
||||
// parse the certificate
|
||||
const asn1 = fromBER(certificate);
|
||||
|
||||
let x509 = new Certificate({ schema: asn1.result });
|
||||
x509 = x509.toJSON();
|
||||
|
||||
// convert the cert to PEM
|
||||
const certBTOA = window
|
||||
.btoa(String.fromCharCode.apply(null, new Uint8Array(certificate)))
|
||||
.match(/.{1,64}/g)
|
||||
.join("\r\n");
|
||||
|
||||
// get which extensions are critical
|
||||
const criticalExtensions = [];
|
||||
x509.extensions.forEach(ext => {
|
||||
if (ext.hasOwnProperty("critical") && ext.critical === true) {
|
||||
criticalExtensions.push(ext.extnID);
|
||||
}
|
||||
});
|
||||
|
||||
const spki = getPublicKeyInfo(x509);
|
||||
const keyUsages = getKeyUsages(x509, criticalExtensions);
|
||||
const san = getSubjectAltNames(x509, criticalExtensions);
|
||||
const basicConstraints = getBasicConstraints(x509, criticalExtensions);
|
||||
const eKeyUsages = getEKeyUsages(x509, criticalExtensions);
|
||||
const sKID = getSubjectKeyID(x509, criticalExtensions);
|
||||
const aKID = getAuthorityKeyID(x509, criticalExtensions);
|
||||
const crlPoints = getCRLPoints(x509, criticalExtensions);
|
||||
const ocspStaple = getOcspStaple(x509, criticalExtensions);
|
||||
const aia = getAuthorityInfoAccess(x509, criticalExtensions);
|
||||
const scts = getSCTs(x509, criticalExtensions);
|
||||
const cp = getCertificatePolicies(x509, criticalExtensions);
|
||||
const msCrypto = getMicrosoftCryptographicExtensions(
|
||||
x509,
|
||||
criticalExtensions
|
||||
);
|
||||
|
||||
// determine which extensions weren't supported
|
||||
let unsupportedExtensions = [];
|
||||
x509.extensions.forEach(ext => {
|
||||
if (!supportedExtensions.includes(ext.extnID)) {
|
||||
unsupportedExtensions.push(ext.extnID);
|
||||
}
|
||||
});
|
||||
|
||||
// the output shell
|
||||
return {
|
||||
ext: {
|
||||
aia,
|
||||
aKID,
|
||||
basicConstraints,
|
||||
crlPoints,
|
||||
cp,
|
||||
eKeyUsages,
|
||||
keyUsages,
|
||||
msCrypto,
|
||||
ocspStaple,
|
||||
scts,
|
||||
sKID,
|
||||
san,
|
||||
},
|
||||
files: {
|
||||
der: undefined, // TODO: implement!
|
||||
pem: encodeURI(
|
||||
`-----BEGIN CERTIFICATE-----\r\n${certBTOA}\r\n-----END CERTIFICATE-----\r\n`
|
||||
),
|
||||
},
|
||||
fingerprint: {
|
||||
sha1: await hash("SHA-1", certificate),
|
||||
sha256: await hash("SHA-256", certificate),
|
||||
},
|
||||
issuer: parseSubsidiary(x509.issuer.typesAndValues),
|
||||
notBefore: `${x509.notBefore.value.toLocaleString()} (${timeZone})`,
|
||||
notAfter: `${x509.notAfter.value.toLocaleString()} (${timeZone})`,
|
||||
subject: parseSubsidiary(x509.subject.typesAndValues),
|
||||
serialNumber: hashify(getObjPath(x509, "serialNumber.valueBlock.valueHex")),
|
||||
signature: {
|
||||
name: strings.signature[getObjPath(x509, "signature.algorithmId")],
|
||||
type: getObjPath(x509, "signature.algorithmId"),
|
||||
},
|
||||
subjectPublicKeyInfo: spki,
|
||||
unsupportedExtensions,
|
||||
version: (x509.version + 1).toString(),
|
||||
};
|
||||
};
|
||||
|
|
@ -10,11 +10,14 @@
|
|||
<meta http-equiv="Content-Security-Policy" content="default-src chrome:" />
|
||||
<link rel="localization" href="toolkit/certviewer.ftl">
|
||||
<link rel="localization" href="branding/brand.ftl">
|
||||
<script defer="defer" src="chrome://global/content/certviewer/certviewer.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
|
||||
<script defer="defer" type="module" src="chrome://global/content/certviewer/certviewer.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/components/info-item.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/components/info-group.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/components/dummy-info.js"></script>
|
||||
<script defer="defer" src="chrome://global/content/certviewer/components/certificate-section.js"></script>
|
||||
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/dummy-info.js"></script>
|
||||
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/certificate-section.js"></script>
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||
<link rel="stylesheet" href="chrome://global/content/certviewer/certviewer.css">
|
||||
<title>about:certificate</title>
|
||||
|
|
|
|||
|
|
@ -6,13 +6,20 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
import { parse } from "chrome://global/content/certviewer/certDecoder.js";
|
||||
const { stringToArrayBuffer } = pvutils.pvutils;
|
||||
|
||||
const derString =
|
||||
'0\x82\x06F0\x82\x05.\xA0\x03\x02\x01\x02\x02\x10\f\x97n>B8\xF4 \xD6=\xDF\x86\xEF\xEB\xBA\x900\r\x06\t*\x86H\x86\xF7\r\x01\x01\v\x05\x000M1\v0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\fDigiCert Inc1\'0%\x06\x03U\x04\x03\x13\x1EDigiCert SHA2 Secure Server CA0\x1E\x17\r181105000000Z\x17\r191113120000Z0\x81\x831\v0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\b\x13\nCalifornia1\x160\x14\x06\x03U\x04\x07\x13\rMountain View1\x1C0\x1A\x06\x03U\x04\n\x13\x13Mozilla Corporation1\x0F0\r\x06\x03U\x04\v\x13\x06WebOps1\x180\x16\x06\x03U\x04\x03\x13\x0Fwww.mozilla.org0\x82\x01"0\r\x06\t*\x86H\x86\xF7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0F\x000\x82\x01\n\x02\x82\x01\x01\x00\xB8\xAA\xEE\xCAi$\x9AJ\x82&\x1E\xD0\x8Ee\xE5P\xE0\\,Tr\xC3\x92\xC6\xFE\xF5\x14YZ\xEC\xC4-\xA0\xB1\xB4|X\x9A\xBEq\x8A\x18\x06\x9A\rU+J\xAC\xEE\x14\xDA\xB0a\xD4a\x1Bq\xCB\xD3\xEA\xA2\x8E@\x8F\xA9\x8E0\xF1\xC7\xD7&E\xDB\x9B\x191\xA9\xF0\xBD\f\x17Z!V\xF8H\xBD\x82\xEE\x98\xE1(D0\xCFS\x83\xEF\x18\x98\xC6\x85\xE9?\xA2;\xDEt\xF5\x9E\xF1\xD8\\\x88y18-\xAA<VoTS0\x83_\xE8\xFD\xBF4\xD7\x8E\xC1\xC1\x94&\xCC\x1D|\x9Aq\xEC\x99\xCC\x8A\x96\x9B\x027\xCAq\xC3\xCE\xAEj\x8FH\xBA\x7F e\n\xEC\x96U\xBA\xE2\xB4\xD9\x95\x14y\xEA\x91\xDD\x01\xCB\x86\x02\x86ca\x9CpK\xD6~\x96\xFA\xD2\x8CH+u\xD7\xA6[!\x86jZ\xB2\x16\x9Dk^UL\xD57\xF8\xFC\x86\x16\x01\x05\xD3\x815\r\xDFM\xEE\xDF\x13#\xB2\xCE\xD0+\xB7\x94\x0E\xC0\x02G\x18\x96<\xB5\xBD]\x00\xDD\xD5\xCF\xB2\xBD\xA6\t+8\t\xDB\x02\x03\x01\x00\x01\xA3\x82\x02\xE90\x82\x02\xE50\x1F\x06\x03U\x1D#\x04\x180\x16\x80\x14\x0F\x80a\x1C\x821a\xD5/(\xE7\x8DF8\xB4,\xE1\xC6\xD9\xE20\x1D\x06\x03U\x1D\x0E\x04\x16\x04\x14\xDAR\xBD!\x9C7eS\xFC\x1FSu\x0F\x1E_\x07\x9B\xA3\xAD?0\'\x06\x03U\x1D\x11\x04 0\x1E\x82\x0Fwww.mozilla.org\x82\vmozilla.org0\x0E\x06\x03U\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x05\xA00\x1D\x06\x03U\x1D%\x04\x160\x14\x06\b+\x06\x01\x05\x05\x07\x03\x01\x06\b+\x06\x01\x05\x05\x07\x03\x020k\x06\x03U\x1D\x1F\x04d0b0/\xA0-\xA0+\x86)http://crl3.digicert.com/ssca-sha2-g6.crl0/\xA0-\xA0+\x86)http://crl4.digicert.com/ssca-sha2-g6.crl0L\x06\x03U\x1D \x04E0C07\x06\t`\x86H\x01\x86\xFDl\x01\x010*0(\x06\b+\x06\x01\x05\x05\x07\x02\x01\x16\x1Chttps://www.digicert.com/CPS0\b\x06\x06g\x81\f\x01\x02\x020|\x06\b+\x06\x01\x05\x05\x07\x01\x01\x04p0n0$\x06\b+\x06\x01\x05\x05\x070\x01\x86\x18http://ocsp.digicert.com0F\x06\b+\x06\x01\x05\x05\x070\x02\x86:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt0\f\x06\x03U\x1D\x13\x01\x01\xFF\x04\x020\x000\x82\x01\x02\x06\n+\x06\x01\x04\x01\xD6y\x02\x04\x02\x04\x81\xF3\x04\x81\xF0\x00\xEE\x00u\x00\xA4\xB9\t\x90\xB4\x18X\x14\x87\xBB\x13\xA2\xCCgp\n<5\x98\x04\xF9\x1B\xDF\xB8\xE3w\xCD\x0E\xC8\r\xDC\x10\x00\x00\x01f\xE6\x16\x88|\x00\x00\x04\x03\x00F0D\x02 fs\x12\x1FR]\x1B\xA3@Hu\x93\xC0=&\x94\xFF\xF3n\xBD!\xCC\xFD\xBA\xDD\xCD6bm\x03S\xAE\x02 G\xB8@rC?\x8E\xE3\xD1\xBE\xA8L[\xBAF\xB6s\xD4\xD4=r\xAF\x00\xCFR\xA70\xA4nhP%\x00u\x00\x87u\xBF\xE7Y|\xF8\x8CC\x99_\xBD\xF3n\xFFV\x8DGV6\xFFJ\xB5`\xC1\xB4\xEA\xFF^\xA0\x83\x0F\x00\x00\x01f\xE6\x16\x89\x02\x00\x00\x04\x03\x00F0D\x02 1\x18\xB5\xE4Q\xA3\x80\x91\x98W5\xE3Q\xDE\x95\xB2j\x16^*d\x9A1v\x9D\x82\xED|I\xF2\xB5d\x02 *\xDC.\xE5\xE1\xB1+\xBE\xAB\x81\xAB3,&}y\xD0H\x8E\xE54\f\xAA+\xCC\xF5.\xC5E\xC5cD0\r\x06\t*\x86H\x86\xF7\r\x01\x01\v\x05\x00\x03\x82\x01\x01\x00\xA2\xC9\x00S\xB7\xC2\xE6\x8F\xE4\xC3?y\xDDe\x86NTsf\x83\xA2H\\3\xB5\xF2\xBD\xD8D)!\xDB\x80\xF8\\\x80\xCA\x13\xF5\x82\x15\xA0\xF6\xBB\xD2\x03B\xE8\xA1\xDC\xC2\x85\xEE\xD2\x0F0\xB7\xB5\xFAVmj\x97\xFE\xBC\x1B\x9A\xBC\xE3\x89\x05\xB8.\x89>^\vU?fr \xFEUn\x9B\x1DD\x97\x0F\xDCb|\xBFC\xA9\xD2t!\xCD\x12\x96T\xE53\xEA*\xE5\xA0\x1E;\x15\x10\x19xW"\xA8\xFA}$/\xF5\xF4\r\xEAe\xF1@\x8A\x1C\xFE\b\xF1\xB5\xEB$\xAB\xF5e\xF1\x89\x98\xD4R\x19?\xD0a\xEE\r\xBB\x93\x16}\x18\x00\x06B\xD8\xD3/M\xD1\xCC\xA0.J\x0E\xB2x\x89\x98U\xD4\x16j\xC7;P\xF9\xC1^T@\xCD\x9F>8\x94\xE1Q\xBC\xCA\xD7\xA6\xB6\b\x8D\xD1\x83\x86\xA0)"d\xFA\xE08\xEE\x1D\x7F"i\xA7\x82\x91KE\xBF\xCC\xBD\x15\xFA\x1FZ\x16qK\xB2\x1F\xA3\xBB=\x97e\xD1\x8ApN\x9C5Lr.\xA8!\xA5\xFF\nO\x83$ q3';
|
||||
|
||||
let gElements = {};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", e => {
|
||||
buildChain();
|
||||
gElements.certificateSection = document.querySelector("certificate-section");
|
||||
});
|
||||
|
||||
const updateSelectedItem = (() => {
|
||||
export const updateSelectedItem = (() => {
|
||||
let state;
|
||||
return selectedItem => {
|
||||
if (selectedItem) {
|
||||
|
|
@ -25,3 +32,12 @@ const updateSelectedItem = (() => {
|
|||
return state;
|
||||
};
|
||||
})();
|
||||
|
||||
const buildChain = async () => {
|
||||
let chain = [derString];
|
||||
let builtChain = chain.map(cert => {
|
||||
return stringToArrayBuffer(cert);
|
||||
});
|
||||
let certs = await Promise.all(builtChain.map(cert => parse(cert)));
|
||||
console.log("certs ", certs);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
* 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/. */
|
||||
|
||||
/* globals certArray, updateSelectedItem, InfoGroup, ErrorSection */
|
||||
/* globals InfoGroup, ErrorSection */
|
||||
|
||||
import { updateSelectedItem } from "chrome://global/content/certviewer/certviewer.js";
|
||||
import { certArray } from "chrome://global/content/certviewer/components/dummy-info.js";
|
||||
|
||||
class CertificateSection extends HTMLElement {
|
||||
constructor() {
|
||||
|
|
|
|||
|
|
@ -2,26 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
const handshakeArray = [
|
||||
{
|
||||
label: "Protocol",
|
||||
info: "TLS 1.2",
|
||||
},
|
||||
{
|
||||
label: "Cipher Suite",
|
||||
info: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
{
|
||||
label: "Key Exchange Group",
|
||||
info: "P256",
|
||||
},
|
||||
{
|
||||
label: "Signature Scheme",
|
||||
info: "RSA-PKCS1-SHA512",
|
||||
},
|
||||
];
|
||||
|
||||
const certArray = [
|
||||
export const certArray = [
|
||||
[
|
||||
{
|
||||
sectionTitle: "Subject Name",
|
||||
|
|
|
|||
150
toolkit/components/certviewer/content/ctlognames.js
Normal file
150
toolkit/components/certviewer/content/ctlognames.js
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/* 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/. */
|
||||
|
||||
export const ctLogNames = {
|
||||
"9606c02c690033aa1d145f59c6e2648d0549f0df96aab8db915a70d8ecf390a5":
|
||||
"Akamai CT",
|
||||
"39376f545f7b4607f59742d768cd5d2437bf3473b6534a4834bcf72e681c83c9":
|
||||
"Alpha CT",
|
||||
a577ac9ced7548dd8f025b67a241089df86e0f476ec203c2ecbedb185f282638: "CNNIC CT",
|
||||
cdb5179b7fc1c046feea31136a3f8f002e6182faf8896fecc8b2f5b5ab604900: "Certly.IO",
|
||||
"1fbc36e002ede97f40199e86b3573b8a4217d80187746ad0da03a06054d20df4":
|
||||
"Cloudflare “Nimbus2017”",
|
||||
db74afeecb29ecb1feca3e716d2ce5b9aabb36f7847183c75d9d4f37b61fbf64:
|
||||
"Cloudflare “Nimbus2018”",
|
||||
"747eda8331ad331091219cce254f4270c2bffd5e422008c6373579e6107bcc56":
|
||||
"Cloudflare “Nimbus2019”",
|
||||
"5ea773f9df56c0e7b536487dd049e0327a919a0c84a112128418759681714558":
|
||||
"Cloudflare “Nimbus2020”",
|
||||
"4494652eb0eeceafc44007d8a8fe28c0dae682bed8cb31b53fd33396b5b681a8":
|
||||
"Cloudflare “Nimbus2021”",
|
||||
"41c8cab1df22464a10c6a13a0942875e4e318b1b03ebeb4bc768f090629606f6":
|
||||
"Cloudflare “Nimbus2022”",
|
||||
"7a328c54d8b72db620ea38e0521ee98416703213854d3bd22bc13a57a352eb52":
|
||||
"Cloudflare “Nimbus2023”",
|
||||
"6ff141b5647e4222f7ef052cefae7c21fd608e27d2af5a6e9f4b8a37d6633ee5":
|
||||
"DigiCert Nessie2018",
|
||||
fe446108b1d01ab78a62ccfeab6ab2b2babff3abdad80a4d8b30df2d0008830c:
|
||||
"DigiCert Nessie2019",
|
||||
c652a0ec48ceb3fcab170992c43a87413309e80065a26252401ba3362a17c565:
|
||||
"DigiCert Nessie2020",
|
||||
eec095ee8d72640f92e3c3b91bc712a3696a097b4b6a1a1438e647b2cbedc5f9:
|
||||
"DigiCert Nessie2021",
|
||||
"51a3b0f5fd01799c566db837788f0ca47acc1b27cbf79e88429a0dfed48b05e5":
|
||||
"DigiCert Nessie2022",
|
||||
b3737707e18450f86386d605a9dc11094a792db1670c0b87dcf0030e7936a59a:
|
||||
"DigiCert Nessie2023",
|
||||
"5614069a2fd7c2ecd3f5e1bd44b23ec74676b9bc99115cc0ef949855d689d0dd":
|
||||
"DigiCert Server",
|
||||
"8775bfe7597cf88c43995fbdf36eff568d475636ff4ab560c1b4eaff5ea0830f":
|
||||
"DigiCert Server 2",
|
||||
c1164ae0a772d2d4392dc80ac10770d4f0c49bde991a4840c1fa075164f63360:
|
||||
"DigiCert Yeti2018",
|
||||
e2694bae26e8e94009e8861bb63b83d43ee7fe7488fba48f2893019dddf1dbfe:
|
||||
"DigiCert Yeti2019",
|
||||
f095a459f200d18240102d2f93888ead4bfe1d47e399e1d034a6b0a8aa8eb273:
|
||||
"DigiCert Yeti2020",
|
||||
"5cdc4392fee6ab4544b15e9ad456e61037fbd5fa47dca17394b25ee6f6c70eca":
|
||||
"DigiCert Yeti2021",
|
||||
"2245450759552456963fa12ff1f76d86e0232663adc04b7f5dc6835c6ee20f02":
|
||||
"DigiCert Yeti2022",
|
||||
"35cf191bbfb16c57bf0fad4c6d42cbbbb627202651ea3fe12aefa803c33bd64c":
|
||||
"DigiCert Yeti2023",
|
||||
"717ea7420975be84a2723553f1777c26dd51af4e102144094d9019b462fb6668": "GDCA 1",
|
||||
"14308d90ccd030135005c01ca526d81e84e87624e39b6248e08f724aea3bb42a": "GDCA 2",
|
||||
c9cf890a21109c666cc17a3ed065c930d0e0135a9feba85af14210b8072421aa:
|
||||
"GDCA CT #1",
|
||||
"924a30f909336ff435d6993a10ac75a2c641728e7fc2d659ae6188ffad40ce01":
|
||||
"GDCA CT #2",
|
||||
fad4c97cc49ee2f8ac85c5ea5cea09d0220dbbf4e49c6b50662ff868f86b8c28:
|
||||
"Google “Argon2017”",
|
||||
a4501269055a15545e6211ab37bc103f62ae5576a45e4b1714453e1b22106a25:
|
||||
"Google “Argon2018”",
|
||||
"63f2dbcde83bcc2ccf0b728427576b33a48d61778fbd75a638b1c768544bd88d":
|
||||
"Google “Argon2019”",
|
||||
b21e05cc8ba2cd8a204e8766f92bb98a2520676bdafa70e7b249532def8b905e:
|
||||
"Google “Argon2020”",
|
||||
f65c942fd1773022145418083094568ee34d131933bfdf0c2f200bcc4ef164e3:
|
||||
"Google “Argon2021”",
|
||||
"2979bef09e393921f056739f63a577e5be577d9c600af8f94d5d265c255dc784":
|
||||
"Google “Argon2022”",
|
||||
"68f698f81f6482be3a8ceeb9281d4cfc71515d6793d444d10a67acbb4f4ffbc4":
|
||||
"Google “Aviator”",
|
||||
c3bf03a7e1ca8841c607bae3ff4270fca5ec45b186ebbe4e2cf3fc778630f5f6:
|
||||
"Google “Crucible”",
|
||||
"1d024b8eb1498b344dfd87ea3efc0996f7506f235d1d497061a4773c439c25fb":
|
||||
"Google “Daedalus”",
|
||||
"293c519654c83965baaa50fc5807d4b76fbf587a2972dca4c30cf4e54547f478":
|
||||
"Google “Icarus”",
|
||||
a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377cd0ec80ddc10:
|
||||
"Google “Pilot”",
|
||||
ee4bbdb775ce60bae142691fabe19e66a30f7e5fb072d88300c47b897aa8fdcb:
|
||||
"Google “Rocketeer”",
|
||||
bbd9dfbc1f8a71b593942397aa927b473857950aab52e81a909664368e1ed185:
|
||||
"Google “Skydiver”",
|
||||
"52eb4b225ec896974850675f23e43bc1d021e3214ce52ecd5fa87c203cdfca03":
|
||||
"Google “Solera2018”",
|
||||
"0b760e9a8b9a682f88985b15e947501a56446bba8830785c3842994386450c00":
|
||||
"Google “Solera2019”",
|
||||
"1fc72ce5a1b799f400c359bff96ca3913548e8644220610952e9ba1774f7bac7":
|
||||
"Google “Solera2020”",
|
||||
a3c99845e80ab7ce00157b3742df0207dd272b2b602ecf98ee2c12db9c5ae7e7:
|
||||
"Google “Solera2021”",
|
||||
"697aafca1a6b536fae21205046debad7e0eaea13d2432e6e9d8fb379f2b9aaf3":
|
||||
"Google “Solera2022”",
|
||||
a899d8780c9290aaf462f31880ccfbd52451e970d0fbf591ef75b0d99b645681:
|
||||
"Google “Submariner”",
|
||||
b0cc83e5a5f97d6baf7c09cc284904872ac7e88b132c6350b7c6fd26e16c6c77:
|
||||
"Google “Testtube”",
|
||||
b10cd559a6d67846811f7df9a51532739ac48d703bea0323da5d38755bc0ad4e:
|
||||
"Google “Xenon2018”",
|
||||
"084114980071532c16190460bcfc47fdc2653afa292c72b37ff863ae29ccc9f0":
|
||||
"Google “Xenon2019”",
|
||||
"07b75c1be57d68fff1b0c61d2315c7bae6577c5794b76aeebc613a1a69d3a21c":
|
||||
"Google “Xenon2020”",
|
||||
"7d3ef2f88fff88556824c2c0ca9e5289792bc50e78097f2e6a9768997e22f0d7":
|
||||
"Google “Xenon2021”",
|
||||
"46a555eb75fa912030b5a28969f4f37d112c4174befd49b885abf2fc70fe6d47":
|
||||
"Google “Xenon2022”",
|
||||
"7461b4a09cfb3d41d75159575b2e7649a445a8d27709b0cc564a6482b7eb41a3": "Izenpe",
|
||||
"8941449c70742e06b9fc9ce7b116ba0024aa36d59af44f0204404f00f7ea8566":
|
||||
"Izenpe “Argi”",
|
||||
"296afa2d568bca0d2ea844956ae9721fc35fa355ecda99693aafd458a71aefdd":
|
||||
"Let“s Encrypt ”Clicky”",
|
||||
"537b69a3564335a9c04904e39593b2c298eb8d7a6e83023635c627248cd6b440":
|
||||
"Nordu “flimsy”",
|
||||
aae70b7f3cb8d566c86c2f16979c9f445f69ab0eb4535589b2f77a030104f3cd:
|
||||
"Nordu “plausible”",
|
||||
e0127629e90496564e3d0147984498aa48f8adb16600eb7902a1ef9909906273:
|
||||
"PuChuangSiDa CT",
|
||||
cf55e28923497c340d5206d05353aeb25834b52f1f8dc9526809f212efdd7ca6:
|
||||
"SHECA CT 1",
|
||||
"32dc59c2d4c41968d56e14bc61ac8f0e45db39faf3c155aa4252f5001fa0c623":
|
||||
"SHECA CT 2",
|
||||
db76fdadac65e7d09508886e2159bd8b90352f5fead3e3dc5e22eb350acc7b98:
|
||||
"Sectigo (Comodo) “Dodo” CT",
|
||||
"6f5376ac31f03119d89900a45115ff77151c11d902c10029068db2089a37d913":
|
||||
"Sectigo (Comodo) “Mammoth” CT",
|
||||
"5581d4c2169036014aea0b9b573c53f0c0e43878702508172fa3aa1d0713d30c":
|
||||
"Sectigo (Comodo) “Sabre” CT",
|
||||
"34bb6ad6c3df9c03eea8a499ff7891486c9d5e5cac92d01f7bfd1bce19db48ef":
|
||||
"StartCom",
|
||||
ddeb1d2b7a0d4fa6208b81ad8168707e2e8e9d01d55c888d3d11c4cdb6ecbecc: "Symantec",
|
||||
a7ce4a4e6207e0addee5fdaa4b1f86768767b5d002a55d47310e7e670a95eab2:
|
||||
"Symantec Deneb",
|
||||
"15970488d7b997a05beb52512adee8d2e8b4a3165264121a9fabfbd5f85ad93f":
|
||||
"Symantec “Sirius”",
|
||||
bc78e1dfc5f63c684649334da10fa15f0979692009c081b4f3f6917f3ed9b8a5:
|
||||
"Symantec “Vega”",
|
||||
b0b784bc81c0ddc47544e883f05985bb9077d134d8ab88b2b2e533980b8e508b:
|
||||
"Up In The Air “Behind the Sofa”",
|
||||
ac3b9aed7fa9674757159e6d7d575672f9d98100941e9bdeffeca1313b75782d: "Venafi",
|
||||
"03019df3fd85a69a8ebd1facc6da9ba73e469774fe77f579fc5a08b8328c1d6b":
|
||||
"Venafi Gen2 CT",
|
||||
"41b2dc2e89e63ce4af1ba7bb29bf68c6dee6f9f1cc047e30dffae3b3ba259263": "WoSign",
|
||||
"63d0006026dde10bb0601f452446965ee2b6ea2cd4fbc95ac866a550af9075b7":
|
||||
"WoSign 2",
|
||||
"9e4ff73dc3ce220b69217c899e468076abf8d78636d5ccfc85a31a75628ba88b":
|
||||
"WoSign CT #1",
|
||||
};
|
||||
20
toolkit/components/certviewer/content/package.json
Normal file
20
toolkit/components/certviewer/content/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "certviewer",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"build-pvutils": "./node_modules/browserify/bin/cmd.js pvutils.js --standalone pvutils -o ./vendor/pvutils_bundle.js",
|
||||
"build-asn1js": "./node_modules/browserify/bin/cmd.js asn1js.js --standalone asn1js -o ./vendor/asn1js_bundle.js",
|
||||
"build-pkijs": "./node_modules/browserify/bin/cmd.js pkijs.js --standalone pkijs -o ./vendor/pkijs_bundle.js",
|
||||
"build": "npm run build-pvutils && npm run build-asn1js && npm run build-pkijs"
|
||||
},
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"asn1js": "^2.0.22",
|
||||
"pkijs": "^2.1.78",
|
||||
"pvutils": "^1.0.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^16.2.3"
|
||||
}
|
||||
}
|
||||
9
toolkit/components/certviewer/content/pkijs.js
Normal file
9
toolkit/components/certviewer/content/pkijs.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* 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/. */
|
||||
|
||||
const pkijs = require("pkijs"); // version 2.1.78
|
||||
|
||||
module.exports = {
|
||||
pkijs,
|
||||
};
|
||||
9
toolkit/components/certviewer/content/pvutils.js
Normal file
9
toolkit/components/certviewer/content/pvutils.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* 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/. */
|
||||
|
||||
const pvutils = require("pvutils"); // version 1.0.17
|
||||
|
||||
module.exports = {
|
||||
pvutils,
|
||||
};
|
||||
504
toolkit/components/certviewer/content/strings.js
Normal file
504
toolkit/components/certviewer/content/strings.js
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
/* 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/. */
|
||||
|
||||
export const strings = {
|
||||
ux: {
|
||||
upload: "Upload Certificate",
|
||||
},
|
||||
|
||||
names: {
|
||||
// Directory Pilot Attributes
|
||||
"0.9.2342.19200300.100.1.1": {
|
||||
short: "uid",
|
||||
long: "User ID",
|
||||
},
|
||||
"0.9.2342.19200300.100.1.25": {
|
||||
short: "dc",
|
||||
long: "Domain Component",
|
||||
},
|
||||
|
||||
// PKCS-9
|
||||
"1.2.840.113549.1.9.1": {
|
||||
short: "e",
|
||||
long: "Email Address",
|
||||
},
|
||||
|
||||
// Incorporated Locations
|
||||
"1.3.6.1.4.1.311.60.2.1.1": {
|
||||
short: undefined,
|
||||
long: "Inc. Locality",
|
||||
},
|
||||
"1.3.6.1.4.1.311.60.2.1.2": {
|
||||
short: undefined,
|
||||
long: "Inc. State / Province",
|
||||
},
|
||||
"1.3.6.1.4.1.311.60.2.1.3": {
|
||||
short: undefined,
|
||||
long: "Inc. Country",
|
||||
},
|
||||
|
||||
// microsoft cryptographic extensions
|
||||
"1.3.6.1.4.1.311.21.7": {
|
||||
name: {
|
||||
short: "Certificate Template",
|
||||
long: "Microsoft Certificate Template",
|
||||
},
|
||||
},
|
||||
"1.3.6.1.4.1.311.21.10": {
|
||||
name: {
|
||||
short: "Certificate Policies",
|
||||
long: "Microsoft Certificate Policies",
|
||||
},
|
||||
},
|
||||
|
||||
// certificate extensions
|
||||
"1.3.6.1.4.1.11129.2.4.2": {
|
||||
name: {
|
||||
short: "Embedded SCTs",
|
||||
long: "Embedded Signed Certificate Timestamps",
|
||||
},
|
||||
},
|
||||
"1.3.6.1.5.5.7.1.1": {
|
||||
name: {
|
||||
short: undefined,
|
||||
long: "Authority Information Access",
|
||||
},
|
||||
},
|
||||
"1.3.6.1.5.5.7.1.24": {
|
||||
name: {
|
||||
short: "OCSP Stapling",
|
||||
long: "Online Certificate Status Protocol Stapling",
|
||||
},
|
||||
},
|
||||
|
||||
// X.500 attribute types
|
||||
"2.5.4.1": {
|
||||
short: undefined,
|
||||
long: "Aliased Entry",
|
||||
},
|
||||
"2.5.4.2": {
|
||||
short: undefined,
|
||||
long: "Knowledge Information",
|
||||
},
|
||||
"2.5.4.3": {
|
||||
short: "cn",
|
||||
long: "Common Name",
|
||||
},
|
||||
"2.5.4.4": {
|
||||
short: "sn",
|
||||
long: "Surname",
|
||||
},
|
||||
"2.5.4.5": {
|
||||
short: "serialNumber",
|
||||
long: "Serial Number",
|
||||
},
|
||||
"2.5.4.6": {
|
||||
short: "c",
|
||||
long: "Country",
|
||||
},
|
||||
"2.5.4.7": {
|
||||
short: "l",
|
||||
long: "Locality",
|
||||
},
|
||||
"2.5.4.8": {
|
||||
short: "s",
|
||||
long: "State / Province",
|
||||
},
|
||||
"2.5.4.9": {
|
||||
short: "street",
|
||||
long: "Stress Address",
|
||||
},
|
||||
"2.5.4.10": {
|
||||
short: "o",
|
||||
long: "Organization",
|
||||
},
|
||||
"2.5.4.11": {
|
||||
short: "ou",
|
||||
long: "Organizational Unit",
|
||||
},
|
||||
"2.5.4.12": {
|
||||
short: "t",
|
||||
long: "Title",
|
||||
},
|
||||
"2.5.4.13": {
|
||||
short: "description",
|
||||
long: "Description",
|
||||
},
|
||||
"2.5.4.14": {
|
||||
short: undefined,
|
||||
long: "Search Guide",
|
||||
},
|
||||
"2.5.4.15": {
|
||||
short: undefined,
|
||||
long: "Business Category",
|
||||
},
|
||||
"2.5.4.16": {
|
||||
short: undefined,
|
||||
long: "Postal Address",
|
||||
},
|
||||
"2.5.4.17": {
|
||||
short: "postalCode",
|
||||
long: "Postal Code",
|
||||
},
|
||||
"2.5.4.18": {
|
||||
short: "POBox",
|
||||
long: "PO Box",
|
||||
},
|
||||
"2.5.4.19": {
|
||||
short: undefined,
|
||||
long: "Physical Delivery Office Name",
|
||||
},
|
||||
"2.5.4.20": {
|
||||
short: "phone",
|
||||
long: "Phone Number",
|
||||
},
|
||||
"2.5.4.21": {
|
||||
short: undefined,
|
||||
long: "Telex Number",
|
||||
},
|
||||
"2.5.4.22": {
|
||||
short: undefined,
|
||||
long: "Teletex Terminal Identifier",
|
||||
},
|
||||
"2.5.4.23": {
|
||||
short: undefined,
|
||||
long: "Fax Number",
|
||||
},
|
||||
"2.5.4.24": {
|
||||
short: undefined,
|
||||
long: "X.121 Address",
|
||||
},
|
||||
"2.5.4.25": {
|
||||
short: undefined,
|
||||
long: "International ISDN Number",
|
||||
},
|
||||
"2.5.4.26": {
|
||||
short: undefined,
|
||||
long: "Registered Address",
|
||||
},
|
||||
"2.5.4.27": {
|
||||
short: undefined,
|
||||
long: "Destination Indicator",
|
||||
},
|
||||
"2.5.4.28": {
|
||||
short: undefined,
|
||||
long: "Preferred Delivery Method",
|
||||
},
|
||||
"2.5.4.29": {
|
||||
short: undefined,
|
||||
long: "Presentation Address",
|
||||
},
|
||||
"2.5.4.30": {
|
||||
short: undefined,
|
||||
long: "Supported Application Context",
|
||||
},
|
||||
"2.5.4.31": {
|
||||
short: undefined,
|
||||
long: "Member",
|
||||
},
|
||||
"2.5.4.32": {
|
||||
short: undefined,
|
||||
long: "Owner",
|
||||
},
|
||||
"2.5.4.33": {
|
||||
short: undefined,
|
||||
long: "Role Occupant",
|
||||
},
|
||||
"2.5.4.34": {
|
||||
short: undefined,
|
||||
long: "See Also",
|
||||
},
|
||||
"2.5.4.35": {
|
||||
short: undefined,
|
||||
long: "User Password",
|
||||
},
|
||||
"2.5.4.36": {
|
||||
short: undefined,
|
||||
long: "User Certificate",
|
||||
},
|
||||
"2.5.4.37": {
|
||||
short: undefined,
|
||||
long: "CA Certificate",
|
||||
},
|
||||
"2.5.4.38": {
|
||||
short: undefined,
|
||||
long: "Authority Revocation List",
|
||||
},
|
||||
"2.5.4.39": {
|
||||
short: undefined,
|
||||
long: "Certificate Revocation List",
|
||||
},
|
||||
"2.5.4.40": {
|
||||
short: undefined,
|
||||
long: "Cross-certificate Pair",
|
||||
},
|
||||
"2.5.4.41": {
|
||||
short: undefined,
|
||||
long: "Name",
|
||||
},
|
||||
"2.5.4.42": {
|
||||
short: "g",
|
||||
long: "Given Name",
|
||||
},
|
||||
"2.5.4.43": {
|
||||
short: "i",
|
||||
long: "Initials",
|
||||
},
|
||||
"2.5.4.44": {
|
||||
short: undefined,
|
||||
long: "Generation Qualifier",
|
||||
},
|
||||
"2.5.4.45": {
|
||||
short: undefined,
|
||||
long: "Unique Identifier",
|
||||
},
|
||||
"2.5.4.46": {
|
||||
short: undefined,
|
||||
long: "DN Qualifier",
|
||||
},
|
||||
"2.5.4.47": {
|
||||
short: undefined,
|
||||
long: "Enhanced Search Guide",
|
||||
},
|
||||
"2.5.4.48": {
|
||||
short: undefined,
|
||||
long: "Protocol Information",
|
||||
},
|
||||
"2.5.4.49": {
|
||||
short: "dn",
|
||||
long: "Distinguished Name",
|
||||
},
|
||||
"2.5.4.50": {
|
||||
short: undefined,
|
||||
long: "Unique Member",
|
||||
},
|
||||
"2.5.4.51": {
|
||||
short: undefined,
|
||||
long: "House Identifier",
|
||||
},
|
||||
"2.5.4.52": {
|
||||
short: undefined,
|
||||
long: "Supported Algorithms",
|
||||
},
|
||||
"2.5.4.53": {
|
||||
short: undefined,
|
||||
long: "Delta Revocation List",
|
||||
},
|
||||
"2.5.4.58": {
|
||||
short: undefined,
|
||||
long: "Attribute Certificate Attribute", // huh
|
||||
},
|
||||
"2.5.4.65": {
|
||||
short: undefined,
|
||||
long: "Pseudonym",
|
||||
},
|
||||
|
||||
// extensions
|
||||
"2.5.29.14": {
|
||||
name: {
|
||||
short: "Subject Key ID",
|
||||
long: "Subject Key Identifier",
|
||||
},
|
||||
},
|
||||
"2.5.29.15": {
|
||||
name: {
|
||||
short: undefined,
|
||||
long: "Key Usages",
|
||||
},
|
||||
},
|
||||
"2.5.29.17": {
|
||||
name: {
|
||||
short: "Subject Alt Names",
|
||||
long: "Subject Alternative Names",
|
||||
},
|
||||
},
|
||||
"2.5.29.19": {
|
||||
name: {
|
||||
short: undefined,
|
||||
long: "Basic Constraints",
|
||||
},
|
||||
},
|
||||
"2.5.29.31": {
|
||||
name: {
|
||||
short: "CRL Endpoints",
|
||||
long: "Certificate Revocation List Endpoints",
|
||||
},
|
||||
},
|
||||
"2.5.29.32": {
|
||||
name: {
|
||||
short: undefined,
|
||||
long: "Certificate Policies",
|
||||
},
|
||||
},
|
||||
"2.5.29.35": {
|
||||
name: {
|
||||
short: "Authority Key ID",
|
||||
long: "Authority Key Identifier",
|
||||
},
|
||||
},
|
||||
"2.5.29.37": {
|
||||
name: {
|
||||
short: undefined,
|
||||
long: "Extended Key Usages",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
keyUsages: [
|
||||
"CRL Signing",
|
||||
"Certificate Signing",
|
||||
"Key Agreement",
|
||||
"Data Encipherment",
|
||||
"Key Encipherment",
|
||||
"Non-Repudiation",
|
||||
"Digital Signature",
|
||||
],
|
||||
|
||||
san: [
|
||||
"Other Name",
|
||||
"RFC 822 Name",
|
||||
"DNS Name",
|
||||
"X.400 Address",
|
||||
"Directory Name",
|
||||
"EDI Party Name",
|
||||
"URI",
|
||||
"IP Address",
|
||||
"Registered ID",
|
||||
],
|
||||
|
||||
eKU: {
|
||||
"1.3.6.1.4.1.311.10.3.1": "Certificate Trust List (CTL) Signing",
|
||||
"1.3.6.1.4.1.311.10.3.2": "Timestamp Signing",
|
||||
"1.3.6.1.4.1.311.10.3.4": "EFS Encryption",
|
||||
"1.3.6.1.4.1.311.10.3.4.1": "EFS Recovery",
|
||||
"1.3.6.1.4.1.311.10.3.5":
|
||||
"Windows Hardware Quality Labs (WHQL) Cryptography",
|
||||
"1.3.6.1.4.1.311.10.3.7": "Windows NT 5 Cryptography",
|
||||
"1.3.6.1.4.1.311.10.3.8": "Windows NT Embedded Cryptography",
|
||||
"1.3.6.1.4.1.311.10.3.10": "Qualified Subordination",
|
||||
"1.3.6.1.4.1.311.10.3.11": "Escrowed Key Recovery",
|
||||
"1.3.6.1.4.1.311.10.3.12": "Document Signing",
|
||||
"1.3.6.1.4.1.311.10.5.1": "Digital Rights Management",
|
||||
"1.3.6.1.4.1.311.10.6.1": "Key Pack Licenses",
|
||||
"1.3.6.1.4.1.311.10.6.2": "License Server",
|
||||
"1.3.6.1.4.1.311.20.2.1": "Enrollment Agent",
|
||||
"1.3.6.1.4.1.311.20.2.2": "Smartcard Login",
|
||||
"1.3.6.1.4.1.311.21.5": "Certificate Authority Private Key Archival",
|
||||
"1.3.6.1.4.1.311.21.6": "Key Recovery Agent",
|
||||
"1.3.6.1.4.1.311.21.19": "Directory Service Email Replication",
|
||||
"1.3.6.1.5.5.7.3.1": "Server Authentication",
|
||||
"1.3.6.1.5.5.7.3.2": "Client Authentication",
|
||||
"1.3.6.1.5.5.7.3.3": "Code Signing",
|
||||
"1.3.6.1.5.5.7.3.4": "E-mail Protection",
|
||||
"1.3.6.1.5.5.7.3.5": "IPsec End System",
|
||||
"1.3.6.1.5.5.7.3.6": "IPsec Tunnel",
|
||||
"1.3.6.1.5.5.7.3.7": "IPSec User",
|
||||
"1.3.6.1.5.5.7.3.8": "Timestamping",
|
||||
"1.3.6.1.5.5.7.3.9": "OCSP Signing",
|
||||
"1.3.6.1.5.5.8.2.2": "Internet Key Exchange (IKE)",
|
||||
},
|
||||
|
||||
signature: {
|
||||
"1.2.840.113549.1.1.5": "SHA-1 with RSA Encryption",
|
||||
"1.2.840.113549.1.1.11": "SHA-256 with RSA Encryption",
|
||||
"1.2.840.113549.1.1.12": "SHA-384 with RSA Encryption",
|
||||
"1.2.840.113549.1.1.13": "SHA-512 with RSA Encryption",
|
||||
"1.2.840.10040.4.3": "DSA with SHA-1",
|
||||
"2.16.840.1.101.3.4.3.2": "DSA with SHA-256",
|
||||
"1.2.840.10045.4.1": "ECDSA with SHA-1",
|
||||
"1.2.840.10045.4.3.2": "ECDSA with SHA-256",
|
||||
"1.2.840.10045.4.3.3": "ECDSA with SHA-384",
|
||||
"1.2.840.10045.4.3.4": "ECDSA with SHA-512",
|
||||
},
|
||||
|
||||
aia: {
|
||||
"1.3.6.1.5.5.7.48.1": "Online Certificate Status Protocol (OCSP)",
|
||||
"1.3.6.1.5.5.7.48.2": "CA Issuers",
|
||||
},
|
||||
|
||||
// this includes qualifiers as well
|
||||
cps: {
|
||||
"1.3.6.1.4.1": {
|
||||
name: "Statement Identifier",
|
||||
value: undefined,
|
||||
},
|
||||
"1.3.6.1.5.5.7.2.1": {
|
||||
name: "Practices Statement",
|
||||
value: undefined,
|
||||
},
|
||||
"1.3.6.1.5.5.7.2.2": {
|
||||
name: "User Notice",
|
||||
value: undefined,
|
||||
},
|
||||
"2.16.840": {
|
||||
name: "ANSI Organizational Identifier",
|
||||
value: undefined,
|
||||
},
|
||||
"2.23.140.1.1": {
|
||||
name: "Certificate Type",
|
||||
value: "Extended Validation",
|
||||
},
|
||||
"2.23.140.1.2.1": {
|
||||
name: "Certificate Type",
|
||||
value: "Domain Validation",
|
||||
},
|
||||
"2.23.140.1.2.2": {
|
||||
name: "Certificate Type",
|
||||
value: "Organization Validation",
|
||||
},
|
||||
"2.23.140.1.2.3": {
|
||||
name: "Certificate Type",
|
||||
value: "Individual Validation",
|
||||
},
|
||||
"2.23.140.1.3": {
|
||||
name: "Certificate Type",
|
||||
value: "Extended Validation (Code Signing)",
|
||||
},
|
||||
"2.23.140.1.31": {
|
||||
name: "Certificate Type",
|
||||
value: ".onion Extended Validation",
|
||||
},
|
||||
"2.23.140.2.1": {
|
||||
name: "Certificate Type",
|
||||
value: "Test Certificate",
|
||||
},
|
||||
},
|
||||
|
||||
microsoftCertificateTypes: {
|
||||
Administrator: "Administrator",
|
||||
CA: "Root Certification Authority",
|
||||
CAExchange: "CA Exchange",
|
||||
CEPEncryption: "CEP Encryption",
|
||||
CertificateRequestAgent: "Certificate Request Agent",
|
||||
ClientAuth: "Authenticated Session",
|
||||
CodeSigning: "Code Signing",
|
||||
CrossCA: "Cross Certification Authority",
|
||||
CTLSigning: "Trust List Signing",
|
||||
DirectoryEmailReplication: "Directory Email Replication",
|
||||
DomainController: "Domain Controller",
|
||||
DomainControllerAuthentication: "Domain Controller Authentication",
|
||||
EFS: "Basic EFS",
|
||||
EFSRecovery: "EFS Recovery Agent",
|
||||
EnrollmentAgent: "Enrollment Agent",
|
||||
EnrollmentAgentOffline: "Exchange Enrollment Agent (Offline request)",
|
||||
ExchangeUser: "Exchange User",
|
||||
ExchangeUserSignature: "Exchange Signature Only",
|
||||
IPSECIntermediateOffline: "IPSec (Offline request)",
|
||||
IPSECIntermediateOnline: "IPSEC",
|
||||
KerberosAuthentication: "Kerberos Authentication",
|
||||
KeyRecoveryAgent: "Key Recovery Agent",
|
||||
Machine: "Computer",
|
||||
MachineEnrollmentAgent: "Enrollment Agent (Computer)",
|
||||
OCSPResponseSigning: "OCSP Response Signing",
|
||||
OfflineRouter: "Router (Offline request)",
|
||||
RASAndIASServer: "RAS and IAS Server",
|
||||
SmartcardLogon: "Smartcard Logon",
|
||||
SmartcardUser: "Smartcard User",
|
||||
SubCA: "Subordinate Certification Authority",
|
||||
User: "User",
|
||||
UserSignature: "User Signature Only",
|
||||
WebServer: "Web Server",
|
||||
Workstation: "Workstation Authentication",
|
||||
},
|
||||
};
|
||||
59
toolkit/components/certviewer/content/utils.js
Normal file
59
toolkit/components/certviewer/content/utils.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* 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/. */
|
||||
|
||||
const { Integer } = asn1js.asn1js;
|
||||
const { fromBase64, stringToArrayBuffer } = pvutils.pvutils;
|
||||
|
||||
export const b64urltodec = b64 => {
|
||||
return new Integer({
|
||||
valueHex: stringToArrayBuffer(fromBase64("AQAB", true, true)),
|
||||
}).valueBlock._valueDec;
|
||||
};
|
||||
|
||||
export const b64urltohex = b64 => {
|
||||
const hexBuffer = new Integer({
|
||||
valueHex: stringToArrayBuffer(fromBase64(b64, true, true)),
|
||||
}).valueBlock._valueHex;
|
||||
const hexArray = Array.from(new Uint8Array(hexBuffer));
|
||||
|
||||
return hexArray.map(b => ("00" + b.toString(16)).slice(-2));
|
||||
};
|
||||
|
||||
// this particular prototype override makes it easy to chain down complex objects
|
||||
export const getObjPath = (obj, path) => {
|
||||
path = path.split(".");
|
||||
for (let i = 0, len = path.length; i < len; i++) {
|
||||
if (Array.isArray(obj[path[i]])) {
|
||||
obj = obj[path[i]][path[i + 1]];
|
||||
i++;
|
||||
} else {
|
||||
obj = obj[path[i]];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
export const hash = async (algo, buffer) => {
|
||||
const hashBuffer = await crypto.subtle.digest(algo, buffer);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
|
||||
return hashArray
|
||||
.map(b => ("00" + b.toString(16)).slice(-2))
|
||||
.join(":")
|
||||
.toUpperCase();
|
||||
};
|
||||
|
||||
export const hashify = hash => {
|
||||
if (typeof hash === "string") {
|
||||
return hash
|
||||
.match(/.{2}/g)
|
||||
.join(":")
|
||||
.toUpperCase();
|
||||
}
|
||||
return hash.join(":").toUpperCase();
|
||||
};
|
||||
|
||||
export const pemToDER = pem => {
|
||||
return stringToArrayBuffer(window.atob(pem));
|
||||
};
|
||||
5877
toolkit/components/certviewer/content/vendor/asn1js_bundle.js
vendored
Normal file
5877
toolkit/components/certviewer/content/vendor/asn1js_bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
46647
toolkit/components/certviewer/content/vendor/pkijs_bundle.js
vendored
Normal file
46647
toolkit/components/certviewer/content/vendor/pkijs_bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
791
toolkit/components/certviewer/content/vendor/pvutils_bundle.js
vendored
Normal file
791
toolkit/components/certviewer/content/vendor/pvutils_bundle.js
vendored
Normal file
|
|
@ -0,0 +1,791 @@
|
|||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pvutils = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getUTCDate = getUTCDate;
|
||||
exports.getParametersValue = getParametersValue;
|
||||
exports.bufferToHexCodes = bufferToHexCodes;
|
||||
exports.checkBufferParams = checkBufferParams;
|
||||
exports.utilFromBase = utilFromBase;
|
||||
exports.utilToBase = utilToBase;
|
||||
exports.utilConcatBuf = utilConcatBuf;
|
||||
exports.utilConcatView = utilConcatView;
|
||||
exports.utilDecodeTC = utilDecodeTC;
|
||||
exports.utilEncodeTC = utilEncodeTC;
|
||||
exports.isEqualBuffer = isEqualBuffer;
|
||||
exports.padNumber = padNumber;
|
||||
exports.toBase64 = toBase64;
|
||||
exports.fromBase64 = fromBase64;
|
||||
exports.arrayBufferToString = arrayBufferToString;
|
||||
exports.stringToArrayBuffer = stringToArrayBuffer;
|
||||
exports.nearestPowerOf2 = nearestPowerOf2;
|
||||
exports.clearProps = clearProps;
|
||||
//**************************************************************************************
|
||||
/**
|
||||
* Making UTC date from local date
|
||||
* @param {Date} date Date to convert from
|
||||
* @returns {Date}
|
||||
*/
|
||||
function getUTCDate(date) {
|
||||
// noinspection NestedFunctionCallJS, MagicNumberJS
|
||||
return new Date(date.getTime() + date.getTimezoneOffset() * 60000);
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Get value for input parameters, or set a default value
|
||||
* @param {Object} parameters
|
||||
* @param {string} name
|
||||
* @param defaultValue
|
||||
*/
|
||||
function getParametersValue(parameters, name, defaultValue) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS
|
||||
if (parameters instanceof Object === false) return defaultValue;
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (name in parameters) return parameters[name];
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
//**************************************************************************************
|
||||
/**
|
||||
* Converts "ArrayBuffer" into a hexdecimal string
|
||||
* @param {ArrayBuffer} inputBuffer
|
||||
* @param {number} [inputOffset=0]
|
||||
* @param {number} [inputLength=inputBuffer.byteLength]
|
||||
* @param {boolean} [insertSpace=false]
|
||||
* @returns {string}
|
||||
*/
|
||||
function bufferToHexCodes(inputBuffer, inputOffset = 0, inputLength = inputBuffer.byteLength - inputOffset, insertSpace = false) {
|
||||
let result = "";
|
||||
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = new Uint8Array(inputBuffer, inputOffset, inputLength)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
const item = _step.value;
|
||||
|
||||
// noinspection ChainedFunctionCallJS
|
||||
const str = item.toString(16).toUpperCase();
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS
|
||||
if (str.length === 1) result += "0";
|
||||
|
||||
result += str;
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (insertSpace) result += " ";
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.trim();
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection JSValidateJSDoc, FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Check input "ArrayBuffer" for common functions
|
||||
* @param {LocalBaseBlock} baseBlock
|
||||
* @param {ArrayBuffer} inputBuffer
|
||||
* @param {number} inputOffset
|
||||
* @param {number} inputLength
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (inputBuffer instanceof ArrayBuffer === false) {
|
||||
// noinspection JSUndefinedPropertyAssignment
|
||||
baseBlock.error = "Wrong parameter: inputBuffer must be \"ArrayBuffer\"";
|
||||
return false;
|
||||
}
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (inputBuffer.byteLength === 0) {
|
||||
// noinspection JSUndefinedPropertyAssignment
|
||||
baseBlock.error = "Wrong parameter: inputBuffer has zero length";
|
||||
return false;
|
||||
}
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (inputOffset < 0) {
|
||||
// noinspection JSUndefinedPropertyAssignment
|
||||
baseBlock.error = "Wrong parameter: inputOffset less than zero";
|
||||
return false;
|
||||
}
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (inputLength < 0) {
|
||||
// noinspection JSUndefinedPropertyAssignment
|
||||
baseBlock.error = "Wrong parameter: inputLength less than zero";
|
||||
return false;
|
||||
}
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (inputBuffer.byteLength - inputOffset - inputLength < 0) {
|
||||
// noinspection JSUndefinedPropertyAssignment
|
||||
baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Convert number from 2^base to 2^10
|
||||
* @param {Uint8Array} inputBuffer
|
||||
* @param {number} inputBase
|
||||
* @returns {number}
|
||||
*/
|
||||
function utilFromBase(inputBuffer, inputBase) {
|
||||
let result = 0;
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS
|
||||
if (inputBuffer.length === 1) return inputBuffer[0];
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS
|
||||
for (let i = inputBuffer.length - 1; i >= 0; i--) result += inputBuffer[inputBuffer.length - 1 - i] * Math.pow(2, inputBase * i);
|
||||
|
||||
return result;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Convert number from 2^10 to 2^base
|
||||
* @param {!number} value The number to convert
|
||||
* @param {!number} base The base for 2^base
|
||||
* @param {number} [reserved=0] Pre-defined number of bytes in output array (-1 = limited by function itself)
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
function utilToBase(value, base, reserved = -1) {
|
||||
const internalReserved = reserved;
|
||||
let internalValue = value;
|
||||
|
||||
let result = 0;
|
||||
let biggest = Math.pow(2, base);
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
for (let i = 1; i < 8; i++) {
|
||||
if (value < biggest) {
|
||||
let retBuf;
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (internalReserved < 0) {
|
||||
retBuf = new ArrayBuffer(i);
|
||||
result = i;
|
||||
} else {
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (internalReserved < i) return new ArrayBuffer(0);
|
||||
|
||||
retBuf = new ArrayBuffer(internalReserved);
|
||||
|
||||
result = internalReserved;
|
||||
}
|
||||
|
||||
const retView = new Uint8Array(retBuf);
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
const basis = Math.pow(2, j * base);
|
||||
|
||||
retView[result - j - 1] = Math.floor(internalValue / basis);
|
||||
internalValue -= retView[result - j - 1] * basis;
|
||||
}
|
||||
|
||||
return retBuf;
|
||||
}
|
||||
|
||||
biggest *= Math.pow(2, base);
|
||||
}
|
||||
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS
|
||||
/**
|
||||
* Concatenate two ArrayBuffers
|
||||
* @param {...ArrayBuffer} buffers Set of ArrayBuffer
|
||||
*/
|
||||
function utilConcatBuf(...buffers) {
|
||||
//region Initial variables
|
||||
let outputLength = 0;
|
||||
let prevLength = 0;
|
||||
//endregion
|
||||
|
||||
//region Calculate output length
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = buffers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
const buffer = _step2.value;
|
||||
|
||||
outputLength += buffer.byteLength;
|
||||
} //endregion
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const retBuf = new ArrayBuffer(outputLength);
|
||||
const retView = new Uint8Array(retBuf);
|
||||
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = buffers[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
const buffer = _step3.value;
|
||||
|
||||
// noinspection NestedFunctionCallJS
|
||||
retView.set(new Uint8Array(buffer), prevLength);
|
||||
prevLength += buffer.byteLength;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retBuf;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS
|
||||
/**
|
||||
* Concatenate two Uint8Array
|
||||
* @param {...Uint8Array} views Set of Uint8Array
|
||||
*/
|
||||
function utilConcatView(...views) {
|
||||
//region Initial variables
|
||||
let outputLength = 0;
|
||||
let prevLength = 0;
|
||||
//endregion
|
||||
|
||||
//region Calculate output length
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = views[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
const view = _step4.value;
|
||||
|
||||
outputLength += view.length;
|
||||
} //endregion
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const retBuf = new ArrayBuffer(outputLength);
|
||||
const retView = new Uint8Array(retBuf);
|
||||
|
||||
var _iteratorNormalCompletion5 = true;
|
||||
var _didIteratorError5 = false;
|
||||
var _iteratorError5 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator5 = views[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
||||
const view = _step5.value;
|
||||
|
||||
retView.set(view, prevLength);
|
||||
prevLength += view.length;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError5 = true;
|
||||
_iteratorError5 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
||||
_iterator5.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError5) {
|
||||
throw _iteratorError5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retView;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS
|
||||
/**
|
||||
* Decoding of "two complement" values
|
||||
* The function must be called in scope of instance of "hexBlock" class ("valueHex" and "warnings" properties must be present)
|
||||
* @returns {number}
|
||||
*/
|
||||
function utilDecodeTC() {
|
||||
const buf = new Uint8Array(this.valueHex);
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (this.valueHex.byteLength >= 2) {
|
||||
//noinspection JSBitwiseOperatorUsage, ConstantOnRightSideOfComparisonJS, LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
const condition1 = buf[0] === 0xFF && buf[1] & 0x80;
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
const condition2 = buf[0] === 0x00 && (buf[1] & 0x80) === 0x00;
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (condition1 || condition2) this.warnings.push("Needlessly long format");
|
||||
}
|
||||
|
||||
//region Create big part of the integer
|
||||
const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength);
|
||||
const bigIntView = new Uint8Array(bigIntBuffer);
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
for (let i = 0; i < this.valueHex.byteLength; i++) bigIntView[i] = 0;
|
||||
|
||||
// noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
bigIntView[0] = buf[0] & 0x80; // mask only the biggest bit
|
||||
|
||||
const bigInt = utilFromBase(bigIntView, 8);
|
||||
//endregion
|
||||
|
||||
//region Create small part of the integer
|
||||
const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength);
|
||||
const smallIntView = new Uint8Array(smallIntBuffer);
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
for (let j = 0; j < this.valueHex.byteLength; j++) smallIntView[j] = buf[j];
|
||||
|
||||
// noinspection MagicNumberJS
|
||||
smallIntView[0] &= 0x7F; // mask biggest bit
|
||||
|
||||
const smallInt = utilFromBase(smallIntView, 8);
|
||||
//endregion
|
||||
|
||||
return smallInt - bigInt;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Encode integer value to "two complement" format
|
||||
* @param {number} value Value to encode
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
function utilEncodeTC(value) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, ConditionalExpressionJS
|
||||
const modValue = value < 0 ? value * -1 : value;
|
||||
let bigInt = 128;
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
for (let i = 1; i < 8; i++) {
|
||||
if (modValue <= bigInt) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (value < 0) {
|
||||
const smallInt = bigInt - modValue;
|
||||
|
||||
const retBuf = utilToBase(smallInt, 8, i);
|
||||
const retView = new Uint8Array(retBuf);
|
||||
|
||||
// noinspection MagicNumberJS
|
||||
retView[0] |= 0x80;
|
||||
|
||||
return retBuf;
|
||||
}
|
||||
|
||||
let retBuf = utilToBase(modValue, 8, i);
|
||||
let retView = new Uint8Array(retBuf);
|
||||
|
||||
//noinspection JSBitwiseOperatorUsage, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
if (retView[0] & 0x80) {
|
||||
//noinspection JSCheckFunctionSignatures
|
||||
const tempBuf = retBuf.slice(0);
|
||||
const tempView = new Uint8Array(tempBuf);
|
||||
|
||||
retBuf = new ArrayBuffer(retBuf.byteLength + 1);
|
||||
// noinspection ReuseOfLocalVariableJS
|
||||
retView = new Uint8Array(retBuf);
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
for (let k = 0; k < tempBuf.byteLength; k++) retView[k + 1] = tempView[k];
|
||||
|
||||
// noinspection MagicNumberJS
|
||||
retView[0] = 0x00;
|
||||
}
|
||||
|
||||
return retBuf;
|
||||
}
|
||||
|
||||
bigInt *= Math.pow(2, 8);
|
||||
}
|
||||
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleReturnPointsJS, ParameterNamingConventionJS
|
||||
/**
|
||||
* Compare two array buffers
|
||||
* @param {!ArrayBuffer} inputBuffer1
|
||||
* @param {!ArrayBuffer} inputBuffer2
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isEqualBuffer(inputBuffer1, inputBuffer2) {
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (inputBuffer1.byteLength !== inputBuffer2.byteLength) return false;
|
||||
|
||||
// noinspection LocalVariableNamingConventionJS
|
||||
const view1 = new Uint8Array(inputBuffer1);
|
||||
// noinspection LocalVariableNamingConventionJS
|
||||
const view2 = new Uint8Array(inputBuffer2);
|
||||
|
||||
for (let i = 0; i < view1.length; i++) {
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (view1[i] !== view2[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleReturnPointsJS
|
||||
/**
|
||||
* Pad input number with leade "0" if needed
|
||||
* @returns {string}
|
||||
* @param {number} inputNumber
|
||||
* @param {number} fullLength
|
||||
*/
|
||||
function padNumber(inputNumber, fullLength) {
|
||||
const str = inputNumber.toString(10);
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (fullLength < str.length) return "";
|
||||
|
||||
const dif = fullLength - str.length;
|
||||
|
||||
const padding = new Array(dif);
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
for (let i = 0; i < dif; i++) padding[i] = "0";
|
||||
|
||||
const paddingString = padding.join("");
|
||||
|
||||
return paddingString.concat(str);
|
||||
}
|
||||
//**************************************************************************************
|
||||
const base64Template = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
const base64UrlTemplate = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMultipleLoopsJS, OverlyComplexFunctionJS, FunctionTooLongJS, FunctionNamingConventionJS
|
||||
/**
|
||||
* Encode string into BASE64 (or "base64url")
|
||||
* @param {string} input
|
||||
* @param {boolean} useUrlTemplate If "true" then output would be encoded using "base64url"
|
||||
* @param {boolean} skipPadding Skip BASE-64 padding or not
|
||||
* @param {boolean} skipLeadingZeros Skip leading zeros in input data or not
|
||||
* @returns {string}
|
||||
*/
|
||||
function toBase64(input, useUrlTemplate = false, skipPadding = false, skipLeadingZeros = false) {
|
||||
let i = 0;
|
||||
|
||||
// noinspection LocalVariableNamingConventionJS
|
||||
let flag1 = 0;
|
||||
// noinspection LocalVariableNamingConventionJS
|
||||
let flag2 = 0;
|
||||
|
||||
let output = "";
|
||||
|
||||
// noinspection ConditionalExpressionJS
|
||||
const template = useUrlTemplate ? base64UrlTemplate : base64Template;
|
||||
|
||||
if (skipLeadingZeros) {
|
||||
let nonZeroPosition = 0;
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (input.charCodeAt(i) !== 0) {
|
||||
nonZeroPosition = i;
|
||||
// noinspection BreakStatementJS
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection AssignmentToFunctionParameterJS
|
||||
input = input.slice(nonZeroPosition);
|
||||
}
|
||||
|
||||
while (i < input.length) {
|
||||
// noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS
|
||||
const chr1 = input.charCodeAt(i++);
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (i >= input.length) flag1 = 1;
|
||||
// noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS
|
||||
const chr2 = input.charCodeAt(i++);
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (i >= input.length) flag2 = 1;
|
||||
// noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS
|
||||
const chr3 = input.charCodeAt(i++);
|
||||
|
||||
// noinspection LocalVariableNamingConventionJS
|
||||
const enc1 = chr1 >> 2;
|
||||
// noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
const enc2 = (chr1 & 0x03) << 4 | chr2 >> 4;
|
||||
// noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
let enc3 = (chr2 & 0x0F) << 2 | chr3 >> 6;
|
||||
// noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
let enc4 = chr3 & 0x3F;
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (flag1 === 1) {
|
||||
// noinspection NestedAssignmentJS, AssignmentResultUsedJS, MagicNumberJS
|
||||
enc3 = enc4 = 64;
|
||||
} else {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (flag2 === 1) {
|
||||
// noinspection MagicNumberJS
|
||||
enc4 = 64;
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (skipPadding) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS
|
||||
if (enc3 === 64) output += `${template.charAt(enc1)}${template.charAt(enc2)}`;else {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS
|
||||
if (enc4 === 64) output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}`;else output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`;
|
||||
}
|
||||
} else output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionWithMoreThanThreeNegationsJS, FunctionWithMultipleLoopsJS, OverlyComplexFunctionJS, FunctionNamingConventionJS
|
||||
/**
|
||||
* Decode string from BASE64 (or "base64url")
|
||||
* @param {string} input
|
||||
* @param {boolean} [useUrlTemplate=false] If "true" then output would be encoded using "base64url"
|
||||
* @param {boolean} [cutTailZeros=false] If "true" then cut tailing zeroz from function result
|
||||
* @returns {string}
|
||||
*/
|
||||
function fromBase64(input, useUrlTemplate = false, cutTailZeros = false) {
|
||||
// noinspection ConditionalExpressionJS
|
||||
const template = useUrlTemplate ? base64UrlTemplate : base64Template;
|
||||
|
||||
//region Aux functions
|
||||
// noinspection FunctionWithMultipleReturnPointsJS, NestedFunctionJS
|
||||
function indexof(toSearch) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, MagicNumberJS
|
||||
for (let i = 0; i < 64; i++) {
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
if (template.charAt(i) === toSearch) return i;
|
||||
}
|
||||
|
||||
// noinspection MagicNumberJS
|
||||
return 64;
|
||||
}
|
||||
|
||||
// noinspection NestedFunctionJS
|
||||
function test(incoming) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, ConditionalExpressionJS, MagicNumberJS
|
||||
return incoming === 64 ? 0x00 : incoming;
|
||||
}
|
||||
//endregion
|
||||
|
||||
let i = 0;
|
||||
|
||||
let output = "";
|
||||
|
||||
while (i < input.length) {
|
||||
// noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS
|
||||
const enc1 = indexof(input.charAt(i++));
|
||||
// noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS
|
||||
const enc2 = i >= input.length ? 0x00 : indexof(input.charAt(i++));
|
||||
// noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS
|
||||
const enc3 = i >= input.length ? 0x00 : indexof(input.charAt(i++));
|
||||
// noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS
|
||||
const enc4 = i >= input.length ? 0x00 : indexof(input.charAt(i++));
|
||||
|
||||
// noinspection LocalVariableNamingConventionJS, NonShortCircuitBooleanExpressionJS
|
||||
const chr1 = test(enc1) << 2 | test(enc2) >> 4;
|
||||
// noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
const chr2 = (test(enc2) & 0x0F) << 4 | test(enc3) >> 2;
|
||||
// noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS
|
||||
const chr3 = (test(enc3) & 0x03) << 6 | test(enc4);
|
||||
|
||||
output += String.fromCharCode(chr1);
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS
|
||||
if (enc3 !== 64) output += String.fromCharCode(chr2);
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS
|
||||
if (enc4 !== 64) output += String.fromCharCode(chr3);
|
||||
}
|
||||
|
||||
if (cutTailZeros) {
|
||||
const outputLength = output.length;
|
||||
let nonZeroStart = -1;
|
||||
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
for (let i = outputLength - 1; i >= 0; i--) {
|
||||
// noinspection ConstantOnRightSideOfComparisonJS
|
||||
if (output.charCodeAt(i) !== 0) {
|
||||
nonZeroStart = i;
|
||||
// noinspection BreakStatementJS
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection NonBlockStatementBodyJS, NegatedIfStatementJS
|
||||
if (nonZeroStart !== -1) output = output.slice(0, nonZeroStart + 1);else output = "";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
//**************************************************************************************
|
||||
function arrayBufferToString(buffer) {
|
||||
let resultString = "";
|
||||
const view = new Uint8Array(buffer);
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
var _iteratorNormalCompletion6 = true;
|
||||
var _didIteratorError6 = false;
|
||||
var _iteratorError6 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator6 = view[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
|
||||
const element = _step6.value;
|
||||
|
||||
resultString += String.fromCharCode(element);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError6 = true;
|
||||
_iteratorError6 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion6 && _iterator6.return) {
|
||||
_iterator6.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError6) {
|
||||
throw _iteratorError6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
//**************************************************************************************
|
||||
function stringToArrayBuffer(str) {
|
||||
const stringLength = str.length;
|
||||
|
||||
const resultBuffer = new ArrayBuffer(stringLength);
|
||||
const resultView = new Uint8Array(resultBuffer);
|
||||
|
||||
// noinspection NonBlockStatementBodyJS
|
||||
for (let i = 0; i < stringLength; i++) resultView[i] = str.charCodeAt(i);
|
||||
|
||||
return resultBuffer;
|
||||
}
|
||||
//**************************************************************************************
|
||||
const log2 = Math.log(2);
|
||||
//**************************************************************************************
|
||||
// noinspection FunctionNamingConventionJS
|
||||
/**
|
||||
* Get nearest to input length power of 2
|
||||
* @param {number} length Current length of existing array
|
||||
* @returns {number}
|
||||
*/
|
||||
function nearestPowerOf2(length) {
|
||||
const base = Math.log(length) / log2;
|
||||
|
||||
const floor = Math.floor(base);
|
||||
const round = Math.round(base);
|
||||
|
||||
// noinspection ConditionalExpressionJS
|
||||
return floor === round ? floor : round;
|
||||
}
|
||||
//**************************************************************************************
|
||||
/**
|
||||
* Delete properties by name from specified object
|
||||
* @param {Object} object Object to delete properties from
|
||||
* @param {Array.<string>} propsArray Array of properties names
|
||||
*/
|
||||
function clearProps(object, propsArray) {
|
||||
var _iteratorNormalCompletion7 = true;
|
||||
var _didIteratorError7 = false;
|
||||
var _iteratorError7 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator7 = propsArray[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
|
||||
const prop = _step7.value;
|
||||
|
||||
delete object[prop];
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError7 = true;
|
||||
_iteratorError7 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion7 && _iterator7.return) {
|
||||
_iterator7.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError7) {
|
||||
throw _iteratorError7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//**************************************************************************************
|
||||
|
||||
},{}],2:[function(require,module,exports){
|
||||
/* 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/. */
|
||||
|
||||
const pvutils = require("pvutils"); // version 1.0.17
|
||||
|
||||
module.exports = {
|
||||
pvutils,
|
||||
};
|
||||
|
||||
},{"pvutils":1}]},{},[2])(2)
|
||||
});
|
||||
|
|
@ -13,3 +13,10 @@ toolkit.jar:
|
|||
content/global/certviewer/components/info-group.css (content/components/info-group.css)
|
||||
content/global/certviewer/components/info-item.js (content/components/info-item.js)
|
||||
content/global/certviewer/components/info-item.css (content/components/info-item.css)
|
||||
content/global/certviewer/certDecoder.js (content/certDecoder.js)
|
||||
content/global/certviewer/strings.js (content/strings.js)
|
||||
content/global/certviewer/ctlognames.js (content/ctlognames.js)
|
||||
content/global/certviewer/utils.js (content/utils.js)
|
||||
content/global/certviewer/pvutils_bundle.js (content/vendor/pvutils_bundle.js)
|
||||
content/global/certviewer/asn1js_bundle.js (content/vendor/asn1js_bundle.js)
|
||||
content/global/certviewer/pkijs_bundle.js (content/vendor/pkijs_bundle.js)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ testing/web-platform/tests/tools/third_party/
|
|||
testing/xpcshell/node-ip/
|
||||
testing/xpcshell/dns-packet/
|
||||
third_party/
|
||||
toolkit/components/certviewer/content/vendor/
|
||||
toolkit/components/jsoncpp/
|
||||
toolkit/components/normandy/vendor/
|
||||
toolkit/components/protobuf/
|
||||
|
|
|
|||
Loading…
Reference in a new issue