diff --git a/README.md b/README.md index b35a803..2b6a154 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,14 @@ It currently requires at least Firefox 62. ## Developing and Installing Locally -It is recommend that developers use [web-ext](https://github.com/mozilla/web-ext) for installation and testing. It provides a number of useful features, such as automated installation and autoreload upon source changes. For testing and development, run the following commands in two separate terminal windows: +It is recommend that developers use [web-ext](https://github.com/mozilla/web-ext) for installation and testing. It provides a number of useful features, such as automated installation and autoreload upon source changes. + +Install web-ext using the following command: + +````bash +$ npm install --global web-ext +```` +For testing and development, run the following commands in two separate terminal windows: ```bash $ npm run-script watch diff --git a/package.json b/package.json index 12ea6d4..ad6b341 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,9 @@ }, "homepage": "https://github.com/april/certainly-something#readme", "dependencies": { - "handlebars": "^4.0.12", + "handlebars": "^4.1.1", "license-webpack-plugin": "^1.5.0", - "pkijs": "^2.1.74" + "pkijs": "^2.1.76" }, "devDependencies": { "babel-core": "^6.26.3", @@ -28,7 +28,7 @@ "babel-preset-env": "^1.7.0", "copy-webpack-plugin": "^4.6.0", "handlebars-loader": "^1.7.1", - "webpack": "^4.28.4", - "webpack-cli": "^3.2.1" + "webpack": "^4.29.6", + "webpack-cli": "^3.3.0" } } diff --git a/src/viewer/css/index.css b/src/viewer/css/index.css index 4a75476..6fa3034 100644 --- a/src/viewer/css/index.css +++ b/src/viewer/css/index.css @@ -18,6 +18,27 @@ h2 { margin: 0; } +/* generic spacing utilities */ +.mt-1 { + margin-top: .25rem !important; +} + +.mt-2 { + margin-top: .5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + .certificate .panel-section-header { border: 0; } @@ -44,7 +65,7 @@ h2 { .panel-section-subheader:after { content: ""; flex: 1 1; - border-bottom: 1px solid #b8b8b8; + border-bottom: solid 1px #b8b8b8; margin: auto 3.5em auto 1em; } @@ -98,6 +119,9 @@ h2 { /* overrides to extension.css */ .panel-list-item { + border-bottom: solid 1px white; /* same as background to fix hover issue, see issue #41 */ + border-top: solid 1px white; + cursor: text; height: inherit; min-height: 24px; } @@ -116,6 +140,7 @@ h2 { margin-bottom: 12px; position: sticky; top: 0; + cursor: pointer; } /* have the tabs be sticky but only on reasonably sized devices */ @@ -141,6 +166,9 @@ h2 { height: auto; justify-content: center; margin: 0; /* default 0 -1 causes x overflow */ + border: solid 1px rgba(0, 0, 0, 0.1); + border-bottom: 0; + margin: -1px 0 0 -1px; } .panel-section-tabs-button.selected { diff --git a/src/viewer/helpers/truthy.js b/src/viewer/helpers/truthy.js index 5d01695..d92402e 100644 --- a/src/viewer/helpers/truthy.js +++ b/src/viewer/helpers/truthy.js @@ -1,5 +1,5 @@ export default (v) => { - if (v === undefined || v === null || v === 'none') { + if (v === undefined || v === null || v === 'none' || v === false) { return false; } diff --git a/src/viewer/index.handlebars b/src/viewer/index.handlebars index 0c1ed0b..6f570eb 100644 --- a/src/viewer/index.handlebars +++ b/src/viewer/index.handlebars @@ -44,7 +44,6 @@
{{#each certs}}
{{ this.subject.cn }} {{#if this.isBuiltInRoot}}(built-in root){{/if}}
-
{{/each}}
@@ -379,12 +378,52 @@ {{/each}} {{/if}} + {{! Microsoft cryptography }} + {{#if (truthy this.ext.msCrypto.exists)}} +
Microsoft Cryptographic Extensions
+ + {{! Certificate Policies }} + {{#if (truthy this.ext.msCrypto.certificatePolicies)}} +
+ + {{#if this.ext.msCrypto.certificatePolicies.critical}}critical extension{{/if~}} + Certificate Policies + +
+
+
Purposes
+
{{#each this.ext.msCrypto.certificatePolicies.purposes}}{{ this }}{{#unless @last}}, {{/unless}}{{/each}}
+
+ {{/if}} + + {{! Certificate Template }} + {{#if (truthy this.ext.msCrypto.certificateTemplate)}} +
+ + {{#if this.ext.msCrypto.certificateTemplate.critical}}critical extension{{/if~}} + Certificate Template + +
+
+
Identifier
+
{{this.ext.msCrypto.certificateTemplate.id}}
+
+
+
Minor Version
+
{{this.ext.msCrypto.certificateTemplate.minor}}
+
+
+
Major Version
+
{{this.ext.msCrypto.certificateTemplate.major}}
+
+ {{/if}} + + {{/if}} + {{! Unsupported extensions }} {{#if (truthy this.unsupportedExtensions)}} -
- Unknown Extensions -
-
+
Unknown Extensions
+
Identifiers
{{#each this.unsupportedExtensions}}{{ this }}{{#unless @last}}, {{/unless}}{{/each}}
diff --git a/src/viewer/js/ctlognames.js b/src/viewer/js/ctlognames.js index 559fcc5..841d066 100644 --- a/src/viewer/js/ctlognames.js +++ b/src/viewer/js/ctlognames.js @@ -15,6 +15,7 @@ export const ctLogNames = { "c652a0ec48ceb3fcab170992c43a87413309e80065a26252401ba3362a17c565": "DigiCert Nessie2020", "eec095ee8d72640f92e3c3b91bc712a3696a097b4b6a1a1438e647b2cbedc5f9": "DigiCert Nessie2021", "51a3b0f5fd01799c566db837788f0ca47acc1b27cbf79e88429a0dfed48b05e5": "DigiCert Nessie2022", + "b3737707e18450f86386d605a9dc11094a792db1670c0b87dcf0030e7936a59a": "DigiCert Nessie2023", "5614069a2fd7c2ecd3f5e1bd44b23ec74676b9bc99115cc0ef949855d689d0dd": "DigiCert Server", "8775bfe7597cf88c43995fbdf36eff568d475636ff4ab560c1b4eaff5ea0830f": "DigiCert Server 2", "c1164ae0a772d2d4392dc80ac10770d4f0c49bde991a4840c1fa075164f63360": "DigiCert Yeti2018", @@ -22,6 +23,7 @@ export const ctLogNames = { "f095a459f200d18240102d2f93888ead4bfe1d47e399e1d034a6b0a8aa8eb273": "DigiCert Yeti2020", "5cdc4392fee6ab4544b15e9ad456e61037fbd5fa47dca17394b25ee6f6c70eca": "DigiCert Yeti2021", "2245450759552456963fa12ff1f76d86e0232663adc04b7f5dc6835c6ee20f02": "DigiCert Yeti2022", + "35cf191bbfb16c57bf0fad4c6d42cbbbb627202651ea3fe12aefa803c33bd64c": "DigiCert Yeti2023", "717ea7420975be84a2723553f1777c26dd51af4e102144094d9019b462fb6668": "GDCA 1", "14308d90ccd030135005c01ca526d81e84e87624e39b6248e08f724aea3bb42a": "GDCA 2", "c9cf890a21109c666cc17a3ed065c930d0e0135a9feba85af14210b8072421aa": "GDCA CT #1", diff --git a/src/viewer/js/der.js b/src/viewer/js/der.js index 829ba04..198f669 100644 --- a/src/viewer/js/der.js +++ b/src/viewer/js/der.js @@ -58,6 +58,8 @@ const parseSubsidiary = (distinguishedNames) => { export const parse = async (der) => { const supportedExtensions = [ + '1.3.6.1.4.1.311.21.7', // microsoft certificate template + '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 @@ -335,6 +337,30 @@ export const parse = async (der) => { policies: cp, } + // now let's parse the Microsoft cryptographic extensions + let msCrypto = { + 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, + }; + + 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]), + }; + } + + 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, + }; + } + + msCrypto.exists = (msCrypto.certificatePolicies || msCrypto.certificateTemplate) ? true : false; + // determine which extensions weren't supported let unsupportedExtensions = []; x509.extensions.forEach(ext => { @@ -355,6 +381,7 @@ export const parse = async (der) => { cp, eKeyUsages, keyUsages, + msCrypto, ocspStaple, scts: scts, sKID, diff --git a/src/viewer/js/strings.js b/src/viewer/js/strings.js index 810b63f..0c554ca 100644 --- a/src/viewer/js/strings.js +++ b/src/viewer/js/strings.js @@ -30,6 +30,20 @@ export const strings = { 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: {