From b146b8ee33e3519ca83c877da4172d12ca2eb6ac Mon Sep 17 00:00:00 2001 From: Hampus Date: Thu, 8 Oct 2026 20:21:04 +0200 Subject: [PATCH] fix(desktop): trust locally added CAs in Chromium on Linux (#3315) --- .../src/main/DesktopChromiumSPKIBlocklist.ts | 109 +++++ .../main/DesktopSystemTrustVerifier.test.mjs | 91 ++++ .../src/main/DesktopSystemTrustVerifier.ts | 448 ++++++++++++++++++ .../src/main/DesktopTrustedCertificates.ts | 92 ++++ .../fixtures/desktop-trust/bool_01_leaf.pem | 18 + .../fixtures/desktop-trust/bool_ff_leaf.pem | 18 + .../main/fixtures/desktop-trust/crit_leaf.pem | 20 + .../main/fixtures/desktop-trust/ec_leaf.pem | 16 + .../main/fixtures/desktop-trust/eku_int.pem | 20 + .../main/fixtures/desktop-trust/eku_leaf.pem | 20 + .../src/main/fixtures/desktop-trust/int.pem | 19 + .../main/fixtures/desktop-trust/kz_root.pem | 35 ++ .../src/main/fixtures/desktop-trust/leaf.pem | 21 + .../main/fixtures/desktop-trust/nc_int.pem | 20 + .../main/fixtures/desktop-trust/nc_leaf.pem | 20 + .../main/fixtures/desktop-trust/pl_int.pem | 19 + .../main/fixtures/desktop-trust/pl_int2.pem | 19 + .../main/fixtures/desktop-trust/pl_leaf.pem | 20 + .../src/main/fixtures/desktop-trust/root.pem | 19 + .../main/fixtures/desktop-trust/sha1_leaf.pem | 20 + .../main/fixtures/desktop-trust/wc_leaf.pem | 21 + .../main/fixtures/desktop-trust/weak_leaf.pem | 17 + fluxer_desktop/src/main/index.ts | 8 +- 23 files changed, 1109 insertions(+), 1 deletion(-) create mode 100644 fluxer_desktop/src/main/DesktopChromiumSPKIBlocklist.ts create mode 100644 fluxer_desktop/src/main/DesktopSystemTrustVerifier.test.mjs create mode 100644 fluxer_desktop/src/main/DesktopSystemTrustVerifier.ts create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/bool_01_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/bool_ff_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/crit_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/ec_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/eku_int.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/eku_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/int.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/kz_root.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/nc_int.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/nc_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/pl_int.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/pl_int2.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/pl_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/root.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/sha1_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/wc_leaf.pem create mode 100644 fluxer_desktop/src/main/fixtures/desktop-trust/weak_leaf.pem diff --git a/fluxer_desktop/src/main/DesktopChromiumSPKIBlocklist.ts b/fluxer_desktop/src/main/DesktopChromiumSPKIBlocklist.ts new file mode 100644 index 000000000..79e9d7316 --- /dev/null +++ b/fluxer_desktop/src/main/DesktopChromiumSPKIBlocklist.ts @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +export const CHROMIUM_SPKI_BLOCKLIST_SOURCE = 'chromium 152.0.7977.78 net/cert/cert_verify_proc_blocklist.inc'; + +export const CHROMIUM_SPKI_BLOCKLIST: ReadonlySet = new Set([ + '04dde9aa9a79f61498682325fa0870276707fb9ca95384120b46893268494fc9', + '0c43ea8bcde9fc3bca165664ac8215567e3489d5393a0c81e1a79141992e1953', + '12132360a33bfdc6c3bf7b7fab26a1684874e72c1263c1f5de565bb49ef03753', + '127da27a9e45f082280b31bf1e561520389f96659093b2697c40fe8600236c8c', + '130ad4e0633521290531b6651f5759b0bc7bc656709ff8f365c2143b0389b6f6', + '15e7ae40cc4b3f7222a5a6fe3e7dc47f6e46ee9a2251839db296d62ada2a0df7', + '1528397da212890a830b0b95a59968cef234773779df5181cf10fa647534bb65', + '1af56c98ff043ef92bebff54cebb4dd67a25ba956c817f3e6dd3c1e52eb584c1', + '1f4224cec84fc99ced881ff6fcfd3e21f8c519c547aa6a5dd3de247302ce50d1', + '25da1ad58bbfcfb227d8723b1857d4c18e7baa7417b4f9eff9366b5e869f8b39', + '2c998e761160c3b06d82faa9fdc7545d9bda9eb60310f992aa510a6280b74245', + '2dc4cb591f7ef0663441646bcf5c0e9dbcded77ca02945193cefc6edb1740614', + '30efe41382476c3380f02f7e23e66ba2f867b059ee1ea68796b441b85b5d1256', + '32ecc96f912f96d889e73088cd031c7ded2c651c805016157a23b6f32f798a3b', + '36ea96128c89839fb621f8ad0e1ee0b9c2206f62ab7b4da2c6765893c9b7ced2', + '381a3fc7a8b082fa28613a4d07f2c7553f4e1918ee07caa9e8b7cede5a9ca06a', + '383e0e137c37bfb9db29f9a8e45e9ff8dd4c30e440fec2acd3dba7b6c720b993', + '394cff589e689312cfc071ee0bc19fe4c606216ce543429de6db62e42dbb3bc1', + '3edbd9ace639ba1a2d4ad04718711fda23e859b2fbf5d137d424045e7919dfb9', + '455b87e96f1cea2f8b6dae0808ec24738fd92b7fd306757198bf389d755c0b6c', + '490b6ec6beb2d6034720b5149b6b29cd35515988cc16af854148b07b9b1f8a11', + '4bb8f35ba1e126f8dde1b0c420625ed86dce61a7bddadbdea9aba578ff13145e', + '4cdb060f3cfe4c3d3f5e31c300fd68a91e0d1e5f46b64e4895f20e1b5cf8269f', + '4eada9b5311e718199d98ea82b95005cba93198ab1f97efcbe8dc6201628f8af', + '4f7162b974491c98585ec28fe759aa00c330d0b465190a896cc4b616231831fc', + '57809446eaf114843854fe636ed9bcb552e3c616663bc44cc95acf5650016d3e', + '5c722cb70fb311f21e0da0e7d12ebc8e05f60796bc49cf511849d5bc62030382', + '5e53f26467f894fde53b3fa406a440cbb3b076bb5b758fe4834ad66500208907', + '6adb8e3e055460922d1501cb97f94c6a02e39c8f2774ca408825b7b58379dc14', + '707d364e72ae521431dd953897f9c4846d5b8c324298fe53fbd4ada1f2d1157f', + '7165e991ade7916d86b466abebb6e457ca931c804e58ce1fbabae509156ffb43', + '781a4cf2e92452f3ee01d0c381a4214f3904165c390adbd61fcd11244e09b2dc', + '7aedddf36b18f8acb7379fe1ce183212b2350d0788abe0e82457be9badad6d54', + '7afe4b071a2f1f46f8ba944a26d584d5960b92fb48c3ba1b7cab84905f32aacd', + '7cd295b75544808abd9409466f0837c5aadc02e33b6150c6644de0a09659f23c', + '7d5e3f50508197b9a478b11340b7dce20a3c4de49c48c9a294158a895c44a21b', + '7e7058ea35ad4359654159973f560187f16d19c514b939c5055672d1d2a518ac', + '87bfd8afa3af5b429d09a9aa54ee61364f5ae11131e438fc41095343cd16b135', + '8a2affbd1a1c5d1bdccbb7f548ba995f966806b3fd0c3a00fae2e52f3c853989', + '8e12d0cb3b7df3ea2257579489fd8658c95603ea6cf4b73163a41eb7b7e93fee', + '8f591f7aa4dc3efe9490c38a4692c9011ed128f1de595569406d77b6fa1f6b4c', + '927a1b8562280576d048c50321ada43d8703d2d9521a18c28b8c46cc6aae4efd', + '93ca2d436cae7f68d2b4256ca175c985ce39926dc9f7eeaeecf2f8970fb97802', + '962e4b54bb98a7ee5d5feb9633f991d3c3300e9514dade7b0d4f828c794f8e87', + '968dba69fbff15bf3762089431ade5a7ead4b7eaf1be70026810bc57d1c64f6e', + '99ba4784f9b08512902eb0c3c86df0ec049eac9b65f77a9ba42be9d6ebce320f', + '9b8a93decccfbafcf4d04d3442128fb35218cfe437a3d8d0328c99f89089e450', + '9c59a3ccaea4699842b068cfc52cf945db51986957c832cdb18ca73849fbb9ee', + '9d98a1fb60538c4cc4857ff1a8c8034faf6fc592093f619994b2c813d250b864', + '9dd55fc573f546cb6a3831d1112d8710a6f4f82dc87f5fae9d3a1a028dd36e4b', + 'a0cf53f422651e39317ae31af64577be450fa376e289ed8342b7fc133c697419', + 'a903af8c07bb91b0d9e3f3a30c6d53339fc5bd47e5d6bdb476598860c068a024', + 'a9b55a9b5531bbf7c71a1e4920efe796c2b67968f55a6ce5cb62172ed9945bca', + 'af591518e2e6c60ebbfc0907afaa49bc4051d45e7f214abfee7512ee00f661ed', + 'b13fa2e6131a888a01f3d62056fb0efbe999eb6b6e14927613e02ba8b8fb046e', + 'b3182e289ae34ddf2be643ab79c244301605fa0f1eaae6d10fb929600af84df0', + 'b4d5c920415ed0cc4f5dbc7f542636762e80da6625f33f2b6ad6db68bdbab29a', + 'b5ba8dd7f89564c2889d3d6453c84998c77824919b64ea0835aa62986591be50', + 'b89bcbb8acd474c1bea7dad65037f48dcecc9dfaa0612c3c2445956419df32fe', + 'c0ed205346bbbde06eb560f5cee02a3634e2474a7e76cf8fbef563bb117dd0e3', + 'c173f0626456ca854ff2a7f0b133a7cf4d0211e552f24b3e33ade8c59f0a424c', + 'c4387d45364a313fbfe79812b35b815d42852ab03b06f11589638021c8f2cb44', + 'c601234e2b9325dc92e3eabac19600b0b49947d4d04d8c99d32127493ea028f8', + 'c63d68c648a18b77641c427a669d61c9768a55f4fcd0322eac96c57700299cf1', + 'c8fddc75cb1bdbb58c07b4ea847287f626659dd66bc10a26add9b575b3a0a38d', + 'cdee9f3305572a677e1a6c82dc1e02a35b11cae6a684338c9f37fe1ac8daec23', + 'ced43902ab5fb57b442322dc0e172a4fb55f7178b808f94e780a6fd6cc6bd818', + 'd31ec39285b7a5319d0157db420ed87c743e333bbc77f8771f70464f436a6049', + 'd34b255b2fe7d1a09656cbab6409f73c796ec7d66af73653ecc39af978297310', + 'd6a18443d348db994f934ccd8e635d833a27ac1e56f8afaf7c97cb4f43eab68b', + 'db15c0062b520f318a19dacfecd64f9e7a3fbe609fd586796f20ae028e8e3058', + 'db1d13ec42a2cba3673ba67af2def812e9c35566617576d95b4d6face3ef0ae8', + 'dd3eeb779bee07f9efdac382408b28d142fa842c78e8bc0e33348d57b92f0583', + 'de8f05074ec0318e7e7e8d3190dae8b00894f0e8dddfd3913d01759b4f79b05d', + 'e42f24bd4d37f4aa2e56b979d83d1e65219fe0e9e3a382a1b3cb66c93955de75', + 'e6e136c86154f32c3e49f47cfc6b338ff2dc61ce14fc7589b3b56a1450132701', + 'e7b932ae7e9bdc701d771d6f39e8a653449eea43bdb47bd91022950d9179d87e', + 'e849c7176c93df65f64b616982366e5663117812b6fa2bc0c8fa8aeaee4181cc', + 'ea08c8d45d52ca593de524f0513ca6418da9859f7b08ef13ff9dd7bf612d6a37', + 'ea87f462deefffbd7775aa2a4b7e0fcb91c22eee6df69ed90100ccc73b311476', + 'ef551284715232de92e246c323329362b132493bb16b589e4775520beb871a56', + 'f034f642ca1d9e88e9efeafcb15c7c937aa19e04b080f27335e1da70d1ca1201', + 'f2bbe04c5dc70d763e89c5a0527048cd9ecd39eb621e2072ff9a5f8432571aa0', + 'f30e8f61011d65873ccb81b40fa6219749b994f01fa24d0201d521c2435603ca', + 'f5293d47ed38d4c31b2d42dee3b5b3ace97ca26ca2ac0365e3622ee802131fbb', + 'fa00bec73dd99795df1162c789987004c26cbf90af4db442f66220de41354ac9', + 'fcd76cca2347e5cd5b39347f51cf43654b69a2bfc9073670a6be47d8701e6e0e', + 'b0fcce78c1664e293544c143e3d2689f723f5b6e6317107e163d22ba8069794a', + 'c56217b7a828c7341c0ae7a590d8790d4def536652e60ae5b8bdfa26978fe09c', + 'e47c5cd2dc8babb4e53f8a4983920275ef6ffaacb089e87a2c1fbe5a585f05ed', + '39736588b94a4ce767f731cad53f4cbe44137e321eadcaef8ce79a229bbca989', + 'ea12705de7c48f6fcce2cb8dbc542e0fc38ac38e08880dd04a02ef67c93ae135', + 'a6aca1ec9809cc5b4821ff9d29c5ebe651960b91b1f19cc89b55ef87818a9509', + '02a95f43431019e9dc225f05f419330190deb4a3f1869caac9842b403dcbee77', + '8928c59398b0f171c0f96fdae6ab8dd0f48ee06d174da10c404ac00143c7a749', + '6c0702e86e0238abdb974f44a30e1a75f627cc50b4e7ce6bb1c0923b98d0e81c', + 'f806c390ef8d1165ef61bc77ef66de4b245a31f5bebf1029038ff31c50a63f59', + 'cef8710dff5e87a2830daa85e884f082033de58ed395a10f7e7c7334b5bfbe58', + '5be28fcf7e31ba64fb2459e278ef032e3a09b61851952d6e85f746150fcadff1', + '29ec436daffa63d25f502cc9952277581876f6893feb783a0444a6f5e73aa422', + '36ce75edea806f0985145683294e54dbdff02fc821870cf5067a308d1504be3a', + 'a4e9af01416e3a029b5d35e5b119de00cfe156c5cf95fc823cf6d05e3c1a8237', + '3472e4f16c570e0dd388aaaa4a64a34a4b939f1ca770996b5be0037c1aded9c1', +]); diff --git a/fluxer_desktop/src/main/DesktopSystemTrustVerifier.test.mjs b/fluxer_desktop/src/main/DesktopSystemTrustVerifier.test.mjs new file mode 100644 index 000000000..930c3f5e9 --- /dev/null +++ b/fluxer_desktop/src/main/DesktopSystemTrustVerifier.test.mjs @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import assert from 'node:assert/strict'; +import {X509Certificate} from 'node:crypto'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import {describe, test} from 'node:test'; +import {fileURLToPath} from 'node:url'; +import {installElectronStub} from './LocalAppTestSupport.test.mjs'; + +installElectronStub(); + +const {buildDesktopTrustAnchors, verifyAgainstDesktopSystemTrust} = await import('./DesktopSystemTrustVerifier.ts'); +const {resolveDesktopLocallyAddedCertificates} = await import('./DesktopTrustedCertificates.ts'); + +const FIXTURES = path.join(path.dirname(fileURLToPath(import.meta.url)), 'fixtures', 'desktop-trust'); +const read = (name) => fs.readFileSync(path.join(FIXTURES, `${name}.pem`), 'utf8'); +const AUTHORITY_INVALID = -202; +const DEFER = -3; +const ACCEPT = 0; + +function chain(names) { + let certificate; + for (const name of [...names].reverse()) certificate = {data: read(name), issuerCert: certificate}; + return certificate; +} + +function verify(names, {hostname = 'host.example', errorCode = AUTHORITY_INVALID, anchors = ['root']} = {}) { + const store = buildDesktopTrustAnchors(anchors.map(read)); + return verifyAgainstDesktopSystemTrust({hostname, certificate: chain(names), errorCode}, () => store); +} + +describe('desktop system trust verifier', () => { + test('accepts a chain that ends at a locally added CA', () => { + assert.equal(verify(['leaf', 'int']), ACCEPT); + assert.equal(verify(['leaf', 'int'], {hostname: 'HOST.example.'}), ACCEPT); + assert.equal(verify(['leaf', 'int'], {hostname: '127.0.0.1'}), ACCEPT); + assert.equal(verify(['leaf', 'int'], {hostname: '[::1]'}), ACCEPT); + assert.equal(verify(['ec_leaf']), ACCEPT); + assert.equal(verify(['wc_leaf'], {hostname: 'a.lan.home.example'}), ACCEPT); + }); + + test('defers to Chromium for other errors, anchors and hosts', () => { + assert.equal(verify(['leaf', 'int'], {errorCode: -201}), DEFER); + assert.equal(verify(['leaf', 'int'], {anchors: ['pl_int']}), DEFER); + assert.equal(verify(['leaf', 'int'], {hostname: 'other.example'}), DEFER); + assert.equal(verify(['wc_leaf'], {hostname: 'a.b.lan.home.example'}), DEFER); + assert.equal(verify(['wc_leaf'], {hostname: 'a.home.example'}), DEFER); + assert.equal(verify(['wc_leaf'], {hostname: 'victim.co.uk'}), DEFER); + }); + + test('defers on constrained, weak or unknown certificates in the path', () => { + assert.equal(verify(['nc_leaf', 'nc_int']), DEFER); + assert.equal(verify(['nc_leaf'], {anchors: ['nc_int']}), DEFER); + assert.equal(verify(['eku_leaf', 'eku_int']), DEFER); + assert.equal(verify(['pl_leaf', 'pl_int2', 'pl_int']), DEFER); + assert.equal(verify(['crit_leaf']), DEFER); + assert.equal(verify(['sha1_leaf']), DEFER); + assert.equal(verify(['weak_leaf']), DEFER); + }); + + test('rejects non-DER booleans and Chromium blocklisted keys', () => { + assert.equal(verify(['bool_ff_leaf']), ACCEPT); + assert.equal(verify(['bool_01_leaf']), DEFER); + assert.equal(buildDesktopTrustAnchors([read('kz_root')]).size, 0); + }); + + test('anchors only on admin added CAs that the distro bundle still trusts', () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-trust-')); + const write = (file, content) => { + fs.mkdirSync(path.dirname(path.join(root, file)), {recursive: true}); + fs.writeFileSync(path.join(root, file), content); + }; + const der = (name) => new X509Certificate(read(name)).raw; + try { + assert.deepEqual(resolveDesktopLocallyAddedCertificates(root), []); + write('etc/ssl/certs/ca-certificates.crt', [read('root'), read('int'), read('kz_root')].join('\n')); + write('usr/local/share/ca-certificates/site/root.crt', read('root')); + write('usr/local/share/ca-certificates/int.der', der('int')); + write('usr/local/share/ca-certificates/deselected.crt', read('pl_int')); + write('cert.pem', read('pl_int')); + process.env.SSL_CERT_FILE = path.join(root, 'cert.pem'); + const added = resolveDesktopLocallyAddedCertificates(root).map((pem) => new X509Certificate(pem).subject); + assert.deepEqual(added.sort(), ['CN=Trust Test Int', 'CN=Trust Test Root']); + } finally { + delete process.env.SSL_CERT_FILE; + fs.rmSync(root, {recursive: true, force: true}); + } + }); +}); diff --git a/fluxer_desktop/src/main/DesktopSystemTrustVerifier.ts b/fluxer_desktop/src/main/DesktopSystemTrustVerifier.ts new file mode 100644 index 000000000..c30503a78 --- /dev/null +++ b/fluxer_desktop/src/main/DesktopSystemTrustVerifier.ts @@ -0,0 +1,448 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import {createHash, X509Certificate} from 'node:crypto'; +import net from 'node:net'; +import {createChildLogger} from '@electron/common/Logger'; +import {CHROMIUM_SPKI_BLOCKLIST, CHROMIUM_SPKI_BLOCKLIST_SOURCE} from '@electron/main/DesktopChromiumSPKIBlocklist'; +import {resolveDesktopLocallyAddedCertificates} from '@electron/main/DesktopTrustedCertificates'; +import type {Certificate, Session} from 'electron'; + +const logger = createChildLogger('DesktopSystemTrustVerifier'); + +const CHROMIUM_DEFAULT_RESULT = -3; +const CHROMIUM_ACCEPT = 0; +const CHROMIUM_CERT_AUTHORITY_INVALID = -202; +const MAX_CHAIN_LENGTH = 6; +const MAX_SIGNATURE_CHECKS = 25; +const MIN_RSA_BITS = 2048; +const MAX_RSA_BITS = 8192; +const MIN_WILDCARD_BASE_LABELS = 3; +const DER_TRUE = 0xff; + +const OID = { + basicConstraints: '2.5.29.19', + keyUsage: '2.5.29.15', + subjectAltName: '2.5.29.17', + extendedKeyUsage: '2.5.29.37', + nameConstraints: '2.5.29.30', + policyConstraints: '2.5.29.36', + inhibitAnyPolicy: '2.5.29.54', + serverAuth: '1.3.6.1.5.5.7.3.1', + anyExtendedKeyUsage: '2.5.29.37.0', +} as const; + +const ALLOWED_CRITICAL_EXTENSIONS: ReadonlySet = new Set([ + OID.basicConstraints, + OID.keyUsage, + OID.subjectAltName, + OID.extendedKeyUsage, +]); +const FORBIDDEN_EXTENSIONS: ReadonlySet = new Set([ + OID.nameConstraints, + OID.policyConstraints, + OID.inhibitAnyPolicy, +]); +const ALLOWED_SIGNATURE_ALGORITHMS: ReadonlySet = new Set([ + '1.2.840.113549.1.1.11', + '1.2.840.113549.1.1.12', + '1.2.840.113549.1.1.13', + '1.2.840.10045.4.3.2', + '1.2.840.10045.4.3.3', + '1.2.840.10045.4.3.4', + '1.3.101.112', +]); +const ALLOWED_EC_CURVES: ReadonlySet = new Set(['prime256v1', 'secp384r1']); + +const KEY_USAGE_DIGITAL_SIGNATURE = 0; +const KEY_USAGE_KEY_ENCIPHERMENT = 2; +const KEY_USAGE_KEY_CERT_SIGN = 5; + +const TAG_BOOLEAN = 0x01; +const TAG_INTEGER = 0x02; +const TAG_BIT_STRING = 0x03; +const TAG_OCTET_STRING = 0x04; +const TAG_OID = 0x06; +const TAG_SEQUENCE = 0x30; +const TAG_VERSION = 0xa0; +const TAG_EXTENSIONS = 0xa3; +const TAG_SAN_DNS = 0x82; +const TAG_SAN_IP = 0x87; + +class MalformedCertificateError extends Error { + constructor() { + super('Malformed certificate DER'); + this.name = 'MalformedCertificateError'; + } +} + +interface DerNode { + readonly tag: number; + readonly content: Buffer; +} + +interface Extension { + readonly critical: boolean; + readonly value: Buffer; +} + +interface ParsedCertificate { + readonly x509: X509Certificate; + readonly signatureAlgorithm: string; + readonly extensions: ReadonlyMap; + readonly isCA: boolean; + readonly pathLength: number | null; +} + +interface DesktopSystemTrustRequest { + readonly hostname: string; + readonly certificate: Certificate; + readonly errorCode: number; +} + +export type DesktopTrustAnchors = ReadonlyMap>; + +function readNodes(buffer: Buffer): Array { + const nodes: Array = []; + let offset = 0; + while (offset < buffer.length) { + if (offset + 2 > buffer.length) throw new MalformedCertificateError(); + const tag = buffer[offset]; + if ((tag & 0x1f) === 0x1f) throw new MalformedCertificateError(); + let length = buffer[offset + 1]; + let cursor = offset + 2; + if (length & 0x80) { + const size = length & 0x7f; + if (size === 0 || size > 4 || cursor + size > buffer.length) throw new MalformedCertificateError(); + length = 0; + for (let index = 0; index < size; index++) length = length * 256 + buffer[cursor + index]; + cursor += size; + } + if (cursor + length > buffer.length) throw new MalformedCertificateError(); + nodes.push({tag, content: buffer.subarray(cursor, cursor + length)}); + offset = cursor + length; + } + return nodes; +} + +function expect(node: DerNode | undefined, tag: number): DerNode { + if (node == null || node.tag !== tag) throw new MalformedCertificateError(); + return node; +} + +function only(buffer: Buffer, tag: number): DerNode { + const nodes = readNodes(buffer); + if (nodes.length !== 1) throw new MalformedCertificateError(); + return expect(nodes[0], tag); +} + +function readDerTrue(node: DerNode): true { + if (node.content.length !== 1 || node.content[0] !== DER_TRUE) throw new MalformedCertificateError(); + return true; +} + +function decodeOid(content: Buffer): string { + if (content.length === 0) throw new MalformedCertificateError(); + const parts: Array = []; + let value = 0; + for (const byte of content) { + value = value * 128 + (byte & 0x7f); + if (value > Number.MAX_SAFE_INTEGER / 128) throw new MalformedCertificateError(); + if ((byte & 0x80) === 0) { + parts.push(value); + value = 0; + } + } + if ((content[content.length - 1] & 0x80) !== 0) throw new MalformedCertificateError(); + const first = parts.shift() ?? 0; + const head = first < 80 ? [Math.floor(first / 40), first % 40] : [2, first - 80]; + return [...head, ...parts].join('.'); +} + +function parseExtensions(tbs: ReadonlyArray): Map { + const extensions = new Map(); + const wrapper = tbs.find((node) => node.tag === TAG_EXTENSIONS); + if (wrapper == null) return extensions; + for (const entry of readNodes(only(wrapper.content, TAG_SEQUENCE).content)) { + const fields = readNodes(expect(entry, TAG_SEQUENCE).content); + const oid = decodeOid(expect(fields[0], TAG_OID).content); + const hasCritical = fields[1]?.tag === TAG_BOOLEAN; + const critical = hasCritical && readDerTrue(fields[1]); + const value = expect(fields[hasCritical ? 2 : 1], TAG_OCTET_STRING).content; + if (fields.length !== (hasCritical ? 3 : 2) || extensions.has(oid)) throw new MalformedCertificateError(); + extensions.set(oid, {critical, value}); + } + return extensions; +} + +function parseBasicConstraints(extension: Extension | undefined): {isCA: boolean; pathLength: number | null} { + if (extension == null) return {isCA: false, pathLength: null}; + const fields = readNodes(only(extension.value, TAG_SEQUENCE).content); + let index = 0; + let isCA = false; + if (fields[index]?.tag === TAG_BOOLEAN) { + isCA = readDerTrue(fields[index]); + index++; + } + let pathLength: number | null = null; + if (fields[index]?.tag === TAG_INTEGER) { + const content = fields[index].content; + if (content.length === 0 || content.length > 2 || (content[0] & 0x80) !== 0) throw new MalformedCertificateError(); + pathLength = content.readUIntBE(0, content.length); + index++; + } + if (index !== fields.length) throw new MalformedCertificateError(); + return {isCA, pathLength}; +} + +function parseCertificate(x509: X509Certificate): ParsedCertificate { + const parts = readNodes(only(x509.raw, TAG_SEQUENCE).content); + if (parts.length !== 3) throw new MalformedCertificateError(); + const tbs = readNodes(expect(parts[0], TAG_SEQUENCE).content); + const algorithm = readNodes(expect(parts[1], TAG_SEQUENCE).content); + const signatureAlgorithm = decodeOid(expect(algorithm[0], TAG_OID).content); + if (tbs[0]?.tag !== TAG_VERSION && tbs.some((node) => node.tag === TAG_EXTENSIONS)) { + throw new MalformedCertificateError(); + } + const extensions = parseExtensions(tbs); + return {x509, signatureAlgorithm, extensions, ...parseBasicConstraints(extensions.get(OID.basicConstraints))}; +} + +function keyUsageHas(certificate: ParsedCertificate, bit: number): boolean | null { + const extension = certificate.extensions.get(OID.keyUsage); + if (extension == null) return null; + const bits = only(extension.value, TAG_BIT_STRING).content; + const byte = bits[1 + (bit >> 3)]; + return byte != null && (byte & (0x80 >> (bit & 7))) !== 0; +} + +function extendedKeyUsages(certificate: ParsedCertificate): ReadonlyArray | null { + const extension = certificate.extensions.get(OID.extendedKeyUsage); + if (extension == null) return null; + return readNodes(only(extension.value, TAG_SEQUENCE).content).map((node) => decodeOid(expect(node, TAG_OID).content)); +} + +function allowsServerAuth(certificate: ParsedCertificate): boolean { + const usages = extendedKeyUsages(certificate); + return usages == null || usages.includes(OID.serverAuth) || usages.includes(OID.anyExtendedKeyUsage); +} + +function hasAcceptableKey(certificate: ParsedCertificate): boolean { + const key = certificate.x509.publicKey; + const details = key.asymmetricKeyDetails ?? {}; + switch (key.asymmetricKeyType) { + case 'rsa': { + const bits = details.modulusLength ?? 0; + return bits >= MIN_RSA_BITS && bits <= MAX_RSA_BITS; + } + case 'ec': + return details.namedCurve != null && ALLOWED_EC_CURVES.has(details.namedCurve); + case 'ed25519': + return true; + default: + return false; + } +} + +function isBlocklisted(certificate: ParsedCertificate): boolean { + const spki = certificate.x509.publicKey.export({type: 'spki', format: 'der'}); + return CHROMIUM_SPKI_BLOCKLIST.has(createHash('sha256').update(spki).digest('hex')); +} + +function isCurrentlyValid(certificate: ParsedCertificate, now: number): boolean { + return Date.parse(certificate.x509.validFrom) <= now && now <= Date.parse(certificate.x509.validTo); +} + +function passesCommonChecks(certificate: ParsedCertificate, now: number): boolean { + for (const [oid, extension] of certificate.extensions) { + if (FORBIDDEN_EXTENSIONS.has(oid)) return false; + if (extension.critical && !ALLOWED_CRITICAL_EXTENSIONS.has(oid)) return false; + } + return isCurrentlyValid(certificate, now) && hasAcceptableKey(certificate) && !isBlocklisted(certificate); +} + +function isUsableAuthority(certificate: ParsedCertificate, now: number): boolean { + return ( + certificate.isCA && + keyUsageHas(certificate, KEY_USAGE_KEY_CERT_SIGN) !== false && + allowsServerAuth(certificate) && + passesCommonChecks(certificate, now) + ); +} + +function isUsableIntermediate(certificate: ParsedCertificate, now: number): boolean { + return ALLOWED_SIGNATURE_ALGORITHMS.has(certificate.signatureAlgorithm) && isUsableAuthority(certificate, now); +} + +function isUsableLeaf(certificate: ParsedCertificate, now: number): boolean { + if (certificate.isCA || !ALLOWED_SIGNATURE_ALGORITHMS.has(certificate.signatureAlgorithm)) return false; + const digitalSignature = keyUsageHas(certificate, KEY_USAGE_DIGITAL_SIGNATURE); + if (digitalSignature === false && keyUsageHas(certificate, KEY_USAGE_KEY_ENCIPHERMENT) === false) return false; + return allowsServerAuth(certificate) && passesCommonChecks(certificate, now); +} + +function normalizeHost(hostname: string): string { + return hostname + .replace(/^\[(.*)\]$/u, '$1') + .replace(/\.$/u, '') + .toLowerCase(); +} + +function ipBytes(host: string): Buffer | null { + if (net.isIPv4(host)) return Buffer.from(host.split('.').map(Number)); + if (!net.isIPv6(host)) return null; + const [head = '', tail = ''] = host.split('::'); + const words = (part: string) => (part === '' ? [] : part.split(':')); + const headWords = words(head); + const tailWords = words(tail); + const all = host.includes('::') + ? [...headWords, ...Array(8 - headWords.length - tailWords.length).fill('0'), ...tailWords] + : headWords; + if (all.length !== 8) return null; + return Buffer.from(all.flatMap((word) => [parseInt(word, 16) >> 8, parseInt(word, 16) & 0xff])); +} + +function matchesDnsName(pattern: string, host: string): boolean { + const name = pattern.replace(/\.$/u, '').toLowerCase(); + if (!name.includes('*')) return name === host; + if (!name.startsWith('*.') || name.indexOf('*', 1) !== -1) return false; + const base = name.slice(2); + if (base.split('.').length < MIN_WILDCARD_BASE_LABELS) return false; + const dot = host.indexOf('.'); + return dot > 0 && host.slice(dot + 1) === base; +} + +function matchesHost(leaf: ParsedCertificate, hostname: string): boolean { + const extension = leaf.extensions.get(OID.subjectAltName); + if (extension == null || typeof hostname !== 'string') return false; + const host = normalizeHost(hostname); + const address = ipBytes(host); + for (const name of readNodes(only(extension.value, TAG_SEQUENCE).content)) { + if (address != null && name.tag === TAG_SAN_IP && name.content.equals(address)) return true; + if (address == null && name.tag === TAG_SAN_DNS && matchesDnsName(name.content.toString('latin1'), host)) { + return true; + } + } + return false; +} + +interface PathSearch { + readonly intermediates: ReadonlyArray; + readonly anchors: DesktopTrustAnchors; + readonly now: number; + readonly signatures: Map>; + signatureChecks: number; +} + +function isIssuedBy(search: PathSearch, certificate: ParsedCertificate, issuer: ParsedCertificate): boolean { + if (!certificate.x509.checkIssued(issuer.x509)) return false; + let byIssuer = search.signatures.get(certificate); + if (byIssuer == null) { + byIssuer = new Map(); + search.signatures.set(certificate, byIssuer); + } + const cached = byIssuer.get(issuer); + if (cached != null) return cached; + if (search.signatureChecks >= MAX_SIGNATURE_CHECKS) return false; + search.signatureChecks++; + const verified = certificate.x509.verify(issuer.x509.publicKey); + byIssuer.set(issuer, verified); + return verified; +} + +function withinPathLength(authority: ParsedCertificate, intermediatesBelow: number): boolean { + return authority.pathLength == null || intermediatesBelow <= authority.pathLength; +} + +function buildsPath(search: PathSearch, current: ParsedCertificate, path: ReadonlyArray): boolean { + const below = path.length - 1; + for (const anchor of search.anchors.get(current.x509.issuer) ?? []) { + if ( + isCurrentlyValid(anchor, search.now) && + withinPathLength(anchor, below) && + isIssuedBy(search, current, anchor) + ) { + return true; + } + } + if (path.length >= MAX_CHAIN_LENGTH - 1) return false; + for (const candidate of search.intermediates) { + if (path.includes(candidate) || !withinPathLength(candidate, below)) continue; + if (isIssuedBy(search, current, candidate) && buildsPath(search, candidate, [...path, candidate])) return true; + } + return false; +} + +function presentedChain(certificate: Certificate): Array { + const chain: Array = []; + let current: Certificate | undefined = certificate; + while (current != null) { + if (chain.length >= MAX_CHAIN_LENGTH) throw new MalformedCertificateError(); + chain.push(new X509Certificate(current.data)); + current = current.issuerCert; + } + return chain; +} + +function chainsToDesktopTrustAnchor( + certificate: Certificate, + hostname: string, + anchors: DesktopTrustAnchors, + now: number, +): boolean { + const [leafX509, ...rest] = presentedChain(certificate); + if (leafX509 == null) return false; + const leaf = parseCertificate(leafX509); + if (!isUsableLeaf(leaf, now) || !matchesHost(leaf, hostname)) return false; + const intermediates = rest.map(parseCertificate).filter((candidate) => isUsableIntermediate(candidate, now)); + return buildsPath({intermediates, anchors, now, signatures: new Map(), signatureChecks: 0}, leaf, [leaf]); +} + +export function buildDesktopTrustAnchors( + certificates: ReadonlyArray, + now: number = Date.now(), +): DesktopTrustAnchors { + const anchors = new Map>(); + for (const pem of certificates) { + let anchor: ParsedCertificate; + try { + anchor = parseCertificate(new X509Certificate(pem)); + } catch { + continue; + } + if (!isUsableAuthority(anchor, now)) continue; + const bySubject = anchors.get(anchor.x509.subject); + if (bySubject == null) anchors.set(anchor.x509.subject, [anchor]); + else bySubject.push(anchor); + } + return anchors; +} + +export function verifyAgainstDesktopSystemTrust( + request: DesktopSystemTrustRequest, + loadAnchors: () => DesktopTrustAnchors, +): number { + if (request.errorCode !== CHROMIUM_CERT_AUTHORITY_INVALID) return CHROMIUM_DEFAULT_RESULT; + try { + const anchors = loadAnchors(); + if (anchors.size > 0 && chainsToDesktopTrustAnchor(request.certificate, request.hostname, anchors, Date.now())) { + logger.debug('Accepted a certificate that chains to a locally added CA', {hostname: request.hostname}); + return CHROMIUM_ACCEPT; + } + } catch (error) { + logger.warn('Could not check a certificate against locally added CAs', {hostname: request.hostname, error}); + } + return CHROMIUM_DEFAULT_RESULT; +} + +export function installDesktopSystemTrustVerifier(target: Session): void { + if (process.platform !== 'linux') return; + const anchors = buildDesktopTrustAnchors(resolveDesktopLocallyAddedCertificates()); + if (anchors.size === 0) return; + logger.info('Trusting locally added CAs for Chromium requests', { + count: anchors.size, + blocklist: CHROMIUM_SPKI_BLOCKLIST_SOURCE, + }); + target.setCertificateVerifyProc((request, callback) => { + callback(verifyAgainstDesktopSystemTrust(request, () => anchors)); + }); +} diff --git a/fluxer_desktop/src/main/DesktopTrustedCertificates.ts b/fluxer_desktop/src/main/DesktopTrustedCertificates.ts index 9bd39e93c..d387519cc 100644 --- a/fluxer_desktop/src/main/DesktopTrustedCertificates.ts +++ b/fluxer_desktop/src/main/DesktopTrustedCertificates.ts @@ -1,5 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import {X509Certificate} from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; import tls from 'node:tls'; import {createChildLogger} from '@electron/common/Logger'; @@ -25,3 +28,92 @@ export function resolveDesktopTrustedCertificates( for (const certificate of readStore(source, 'system')) merged.add(certificate); return [...merged]; } + +interface DistroTrustLayout { + readonly bundle: string; + readonly anchorDirectories: ReadonlyArray; +} + +const DISTRO_TRUST_LAYOUTS: ReadonlyArray = Object.freeze([ + {bundle: 'etc/ssl/certs/ca-certificates.crt', anchorDirectories: ['usr/local/share/ca-certificates']}, + { + bundle: 'etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem', + anchorDirectories: ['etc/pki/ca-trust/source/anchors', 'usr/share/pki/ca-trust-source/anchors'], + }, + { + bundle: 'etc/ca-certificates/extracted/tls-ca-bundle.pem', + anchorDirectories: ['etc/ca-certificates/trust-source/anchors', 'usr/share/ca-certificates/trust-source/anchors'], + }, + { + bundle: 'var/lib/ca-certificates/ca-bundle.pem', + anchorDirectories: ['etc/pki/trust/anchors', 'usr/share/pki/trust/anchors'], + }, +]); +const PEM_BLOCK = /-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/gu; +const MAX_ANCHOR_DEPTH = 4; +const MAX_ANCHOR_FILES = 512; +const MAX_ANCHOR_FILE_BYTES = 1024 * 1024; + +function pemBody(pem: string): string { + return pem.replace(/-----[^-]+-----|\s/gu, ''); +} + +function readBundle(file: string): ReadonlySet | null { + try { + return new Set((fs.readFileSync(file, 'utf8').match(PEM_BLOCK) ?? []).map(pemBody)); + } catch { + return null; + } +} + +function anchorFiles(directory: string, depth: number, files: Array): void { + let entries: Array; + try { + entries = fs.readdirSync(directory, {withFileTypes: true}); + } catch { + return; + } + for (const entry of entries) { + if (files.length >= MAX_ANCHOR_FILES) return; + const target = path.join(directory, entry.name); + if (entry.isDirectory()) { + if (depth < MAX_ANCHOR_DEPTH) anchorFiles(target, depth + 1, files); + } else if (entry.isFile() || entry.isSymbolicLink()) { + files.push(target); + } + } +} + +function readAnchorFile(file: string): ReadonlyArray { + try { + const stat = fs.statSync(file); + if (!stat.isFile() || stat.size > MAX_ANCHOR_FILE_BYTES) return []; + const content = fs.readFileSync(file); + const blocks = content.toString('latin1').match(PEM_BLOCK); + if (blocks == null) return [new X509Certificate(content)]; + return blocks.flatMap((block) => { + try { + return [new X509Certificate(block)]; + } catch { + return []; + } + }); + } catch { + return []; + } +} + +export function resolveDesktopLocallyAddedCertificates(root: string = '/'): ReadonlyArray { + const added = new Map(); + for (const layout of DISTRO_TRUST_LAYOUTS) { + const bundle = readBundle(path.join(root, layout.bundle)); + if (bundle == null) continue; + const files: Array = []; + for (const directory of layout.anchorDirectories) anchorFiles(path.join(root, directory), 0, files); + for (const certificate of files.flatMap(readAnchorFile)) { + const body = certificate.raw.toString('base64'); + if (bundle.has(body)) added.set(body, certificate.toString()); + } + } + return [...added.values()]; +} diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/bool_01_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/bool_01_leaf.pem new file mode 100644 index 000000000..0c82d303f --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/bool_01_leaf.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIBTjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9UcnVz +dCBUZXN0IFJvb3QwIhgPMjAyNTAxMDEwMDAwMDBaGA8yMTI1MDEwMTAwMDAwMFow +DDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALdv +Oze1slSycxDpCnpZYKClaHOXTRWnzAI8mHMhoiEpgjmXrbN1T75+aruMCQAr2VSB +1YOkxzf8Ntsb0ACfaSEJj2AwcCR6NfXoYbbSIE+V//1HkD/BbrOCUb81wubNFxjd +RZpJjhr6x6wb7DDM5rh8ly2t92N6r9Kh6il7Nssf27v2UZbb8XsjPgKxz2YmCtT8 +Ry5ZiwGes9e4qEzV650Fl4xVjOiKKTJMy7ByNnm7guqL8ALhyHoIeRZUmTF85D4I +Pp90AkkMv9qjYllv5pBDHMjj68VldwhTYRTGAvhZjy8eIXA0OQXbpySPL5i8TZVM +O4jLoJFm3Kn5WIvdWO8CAwEAAaNAMD4wDgYDVR0PAQEBBAQDAgWgMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMBcGA1UdEQQQMA6CDGhvc3QuZXhhbXBsZTANBgkqhkiG9w0B +AQsFAAOCAQEAftI9a2g+PexV+mSm/HHLxeGuWdK0IB5Dts/WhisGgAnxjabbZHJI +UZ6GoD5iQqX8RpZMqF2Cilq1oDfBUoWIujHG4JEzTj3WA0vQOE5wgcsmO4QcypNJ +cEn2KezBgDqzWbJ1hTRA3wwlzzOqJIHStt+4QjwetFvhM36R2o/6WzDlfyKmPSIi +1+eQYA7vl2DWr/j13+Oo3e4X/Uqr9KIVJPNYCdg73oRmi98gTi4aNvBcCb2Pz7ty +8lVgQ3iCysa2LYqk14pfGLm2Rs4QeYC0rRI0z3/Jbu5W81Y09FhW+5yyp9pJXmjO +ZxT7ZtgZsmmqp8iW7vpyQjQMhBA+HKtTBg== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/bool_ff_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/bool_ff_leaf.pem new file mode 100644 index 000000000..30db29594 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/bool_ff_leaf.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIBTTANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9UcnVz +dCBUZXN0IFJvb3QwIhgPMjAyNTAxMDEwMDAwMDBaGA8yMTI1MDEwMTAwMDAwMFow +DDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALdv +Oze1slSycxDpCnpZYKClaHOXTRWnzAI8mHMhoiEpgjmXrbN1T75+aruMCQAr2VSB +1YOkxzf8Ntsb0ACfaSEJj2AwcCR6NfXoYbbSIE+V//1HkD/BbrOCUb81wubNFxjd +RZpJjhr6x6wb7DDM5rh8ly2t92N6r9Kh6il7Nssf27v2UZbb8XsjPgKxz2YmCtT8 +Ry5ZiwGes9e4qEzV650Fl4xVjOiKKTJMy7ByNnm7guqL8ALhyHoIeRZUmTF85D4I +Pp90AkkMv9qjYllv5pBDHMjj68VldwhTYRTGAvhZjy8eIXA0OQXbpySPL5i8TZVM +O4jLoJFm3Kn5WIvdWO8CAwEAAaNAMD4wDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMBcGA1UdEQQQMA6CDGhvc3QuZXhhbXBsZTANBgkqhkiG9w0B +AQsFAAOCAQEAddtLsvQf8S/uuGyOMUgV8NKw4Ki1kX+BTr5xzsq1A01WgCfdYG5u +HL32V6uATwDzO3cH3piDoGLoXAF0sstnciBnfeibCgeBcOrj/8PTXGrRch5kkHnw +kK3OBZQSutT4BafIKoVIpiH95+3t/5sy2dWSkt1NGQN7noPBgddqSTmDiq4nxx+i +LQ+NhT5sX+AkWB6GZNyxnvEC1UtUJiY7k8DQIvV5vLPj4+oCa7XRiY/8rFzVoyBo +5Yq5FP5WgyGXKlWLhtwIeaD+7pAYjrUSnrTR9gWJsJ0l6/vCWhH3aT2vbPf9JUwS +3aHt4faDpfGbcvhlkXWyKHS7T3XYgnFf4A== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/crit_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/crit_leaf.pem new file mode 100644 index 000000000..d10165a88 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/crit_leaf.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaewwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NVoY +DzIxMjYwOTE0MTcxOTQ1WjAMMQowCAYDVQQDDAF4MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAvD4+ud9Fp9RwYMtvhL366FKGNhEL6Y6oTouFjU97eQ4a +jTBIgizBsc2CwOoFyNAIK5UDRw68Kvs3m417L07BiDoTh4Y8J/62CKAGsJ5S2KAw +xgZh3BIyvs0gLGa5CAy0FqZ5tzCe546XHZdeGg4ETW3zEQmkB1Zq1ZwtCPX86pr4 +N2MrKthotsaRug7ZQ5I8KC0XI819zdA2Bi6LvXIUCilDaWfZb9oeRUsrNCBzTvX4 +/uL2sMJDwuiP1Dfk7heqnjsvP2s9N+0k6uw3thIBisTy4F2yhCpfCi9WT+OJZoEH +UjLgOAR0H2fhAVPBR9YTPtVwy7di0PMWsYdfYGvB4QIDAQABo4GjMIGgMAwGA1Ud +EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8G +A1UdIwQYMBaAFDl9W8k1XKQCubIn46G/oYwjeDkqMBcGA1UdEQQQMA6CDGhvc3Qu +ZXhhbXBsZTASBgkrBgEEAYaNHwEBAf8EAgUAMB0GA1UdDgQWBBQmoqL8NAcX6wuB +1XmVPq0bFnxPKDANBgkqhkiG9w0BAQsFAAOCAQEAYZQW4q0zeprbMilnHRk6C6Td +sXOaOHhB5DiRZW1wjhe3LO1zPLe/nckzqFG+g+jTFa7nLuC6APRlj1yk0pCoyWiD +zkHtdPDy1VdkkIOMEcPdMVPOgEPcIZYFZY77sMz4Ac8d6qRlAcqhJDKwapaQYGZV +ddy1pwPNZxk3EL0DcXYRThD/VOk3FuxZRZseuFNUkdyQ8a14bv+2mrHCFHcYxH26 +Q73GvjMsyuL2oncG/ZhFza2kXoOUzi+ZHWh/KIDtWGruXLeFYDvEssaUUVykP2mV +0hy/XEGdOZmUP88GJ4N4CYu1SSn1shGiho42KLrXwpnDqOp43+bAUIOJAYnV1A== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/ec_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/ec_leaf.pem new file mode 100644 index 000000000..0d2542d8b --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/ec_leaf.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICezCCAWOgAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaecwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NFoY +DzIxMjYwOTE0MTcxOTQ0WjAMMQowCAYDVQQDDAF4MFkwEwYHKoZIzj0CAQYIKoZI +zj0DAQcDQgAEHHjSNNp5dsZfAnkKCGhzX70d/Ulaz8UFm9caIp6vOi2y1EXi10dZ +VAEgXal5HYc27/wbIFqLztnfofpu+0SlEqOBjzCBjDAMBgNVHRMBAf8EAjAAMA4G +A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBQ5 +fVvJNVykArmyJ+Ohv6GMI3g5KjAXBgNVHREEEDAOggxob3N0LmV4YW1wbGUwHQYD +VR0OBBYEFNjhzyL6G+did2jKx0TJnTj2NhWHMA0GCSqGSIb3DQEBCwUAA4IBAQCs +ITZEqDiKXMtJvSrnfJ6ZGwuQBy/AU3tbw/DlCvTr/UMfcZk8qJ92otWf3MRgKOU7 +XBgvCdruxCcG0ST3GqLq9PmGVt+fMwsx5FGF/qzWlDK8ZkFi0Adzsptw732v3/0H +BR8rh+59/NUmyLnag6Xw+nOY0boCVJ87CtNgBNsVmUL65YmVgCHEopen7Fv1q5ms +uGgi+HtWxfGnSiz+4Upw6RdcNmedH+F5M8wzZ4q4Iv4Wmupz3iaLdwGcucpuuC1R +6HIrDOEk+TOBofytCEd+iDorjjIXxNsgBDQf/gjKCvtHh7OVX0MFgQysgPNyIDC6 +9mhFYM4YwMfhsMauBm5x +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/eku_int.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/eku_int.pem new file mode 100644 index 000000000..d9e392c50 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/eku_int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaeowDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NFoY +DzIxMjYwOTE0MTcxOTQ0WjASMRAwDgYDVQQDDAdFS1UgSW50MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4v27QD9YFXG8+oPhwytCyErQCaV2PYeHGVm/ +l0D0zc+9EHQfI6UbKC/1KjRXgMjmsFNGpGEAj2xVwXMsN04QmsxBhSrrOqrH36Fw +adSj5ewBaKf5/jaFOkJ8O1t4NOl4Ki0Fle4Op6r6IJZwzGpy4qNqlYbgRoPj8H7J +R9BufEtoC18jXcQNlwQP/4go7sq4YwtbFjOJ9mK/mlaAeD9zCb3LApLcYyQyqQaQ +bFEOMifJhCNE6WxbrTXH/+nTEM7nmPaGFqzovAf+0PBNjTkYSd+NqZJDD/fvU3XF +VMiqlAWj8R/UP03KKoTemqey9rXxbocxLTh0wJr/gPjOt7/+VQIDAQABo3gwdjAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUMG5Sf79f +OgByO3UsgJsjlV8lvfEwHwYDVR0jBBgwFoAUOX1byTVcpAK5sifjob+hjCN4OSow +EwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAFprsUH/ZoMC +QgPZUnW33Tc5tnsEMBgREiqU5LDKdXAy9Qko1b/C2JaDIefYntBcu7eIlLVAfhSs +cBk+XhgditEjAG5yYjV/NPZRh/+L4OjVcVmFRtCtQ+z+DGwVWGn3PzbUL228izFK +djJOitXUPFGu8U1sbA/zv6Z+DpngnLkRWFwJz8cl84beyCnaExXh2MIg3AleDNdf +FoVU0lylC47nx9FHqEthOtGqRn7BHi49htqcCXd4E4OE3c8CLKU0WTRP8ofjK0FW +IdwXVsxWSheDVWRa1Gs3OOsv2TPWRyaRhEQ9mcCws7nVMbhZ94HIC3Rixy3YcLPY +vQXMYpMWrgo= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/eku_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/eku_leaf.pem new file mode 100644 index 000000000..aff345371 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/eku_leaf.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUOuSVRC3VFKpaTRwNlFx7hNY+hPUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHRUtVIEludDAgFw0yNjEwMDgxNzE5NDRaGA8yMTI2MDkx +NDE3MTk0NFowDDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMYnHmYegqC2h4F4iCFCMo/jGGtOLPmVj4QoX676VEq7Ilw1qMoLfKwe +neNYPt0odizU1wWGf0SuEZ3QrWT5kgh14yzu0AQPboYUpMeYwkIjSxclrMbKqN63 +bVT8BVYYuAnOV+4wGKLtSjZS2c3QcJKUijp+C50jyYdJ3DHYuiOviiaCSsCL7jo5 +W6I4q5GfyifGA+T089YnLtlQYljhsqz2CWRNsxObD0RcjiAls23ZUAARKVU5cZ/V +PO2H/zF7tSuRSA8nE3/HepSO5pOcAS0/Gz0AEqmr9FdGztixhJ55RLfMIAGDDM3G +DC1wzg/Q0iG53vuJpmIEVpfx3ED5i/sCAwEAAaOBjzCBjDAMBgNVHRMBAf8EAjAA +MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAW +gBQwblJ/v186AHI7dSyAmyOVXyW98TAXBgNVHREEEDAOggxob3N0LmV4YW1wbGUw +HQYDVR0OBBYEFNtHkj6LRNuSCFCEDvWcb/vaxmOKMA0GCSqGSIb3DQEBCwUAA4IB +AQCymlwRyp0JOXJltxNG5qHLpes+juIN9p5COTs9FhvAkpC58W+w1ynkN23J1UVk +WA5G1t5BOO/eyU7lZkdabDA/Mb0hvxdWIG4a028EUkd8vgkJEeDjPbjSZDPaIdL8 +RAq9lq88LcetWP9g8NOZRFBhDbigphqYmwGNzk/J1ZIYhOfsNr0SU5BU/xe4ogT1 +WmcBkaPw9g+7yPsevNXNmaMPlcKRiEL9AJA4rMZSU8aLnZ4+WXRleQnhSzHdBWPx +Li2jb41I39ECmY7gXPCJqRAORcaov4AO8WZCNVKqRLd/uFmOddpBABlPN9RyiyIn +pivGrcARZfTLYxHrOpQu74gz +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/int.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/int.pem new file mode 100644 index 000000000..cd2349dbd --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg6gAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaeYwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0M1oY +DzIxMjYwOTE0MTcxOTQzWjAZMRcwFQYDVQQDDA5UcnVzdCBUZXN0IEludDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTTaf/jUVe80O44xs2+jRQSnv7w +zKiGMUnDMTwLheS3NlOuXUJAPfggtOUmp8fWdLUi9tmvwO/jSjOZZLnQ2fz9bGiV +Oovs9y9TgywdxOH1nnCMQ+hKLw0cMdk8X2Pm8wGZdGEblEcPJBXFF09JX1t6y3h6 +cHlV5tpxdAUjNNdxjREnXclixWUPBDF4IziRrg4fOi+aB5FFREhhKLGlvJJ0NNq5 +t9N3quFHoQCAGvwrnQQXsey58zRF58yK1AS6VrNMvkYRhcs/N+5W8Cxb6hVhthhz +0n96GgJ1BcGwpSGPC/69WpZHQot9VrT6qUoKJHUg3fnTHyzodJcRkHyAsKUCAwEA +AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FGa9d7RPsqY3+fnUCK3+sbIHKdCZMB8GA1UdIwQYMBaAFDl9W8k1XKQCubIn46G/ +oYwjeDkqMA0GCSqGSIb3DQEBCwUAA4IBAQDJsifCCoydUHayqGMitWtCnAhts+hz +bOtYafchsnsmgn+LyetPC5ghdocn7QBHFZqmwoSfmZG2xrS5YfwSNJH5a65meFF1 +Ca0eqxo0KZcNt3YSMH5bEOf1aphw9ame/UqNB89ZjJjSoIF2/Us/Yr2uLO0LLBmK +01HF1JqWFIXUOZ7g0VPhR1ulV7apYFvgXUtj0A9PUWOcJb+lxrepU4uWbV4TN0BM +EveNKX91kIzujemL0L1LDKpqU76lUG9sPAVrareKBDsDP9h4xGOJLzsybK0tpFHS +5rXCepsRIh2h9liL4ofxyIrD3bMKlSd/mo5hC6EaaHCLh4XtRuw8Iw93 +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/kz_root.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/kz_root.pem new file mode 100644 index 000000000..8001e0de2 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/kz_root.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIUKH3ODOPG96qjP/ll526pjIJKWdswDQYJKoZIhvcNAQEL +BQAwVjE4MDYGA1UEAxMvSW5mb3JtYXRpb24gU2VjdXJpdHkgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkgQ0ExDTALBgNVBAoTBElTQ0ExCzAJBgNVBAYTAktaMB4XDTIw +MDIyODA0MDgwM1oXDTQwMDIyODA0MDgwM1owVjE4MDYGA1UEAxMvSW5mb3JtYXRp +b24gU2VjdXJpdHkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgQ0ExDTALBgNVBAoT +BElTQ0ExCzAJBgNVBAYTAktaMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA2Q8hjYT89iYfD+gdxiaKw5NNRq0sfKDj1xAXbtmhQh+tA5DhnVPehqFybVFH +ZBsyMwmL9SA4Bp/2ytE7CmnDefqg9xfRuNX2p6RzUgrsarYaZgXgaPW+g/TZ+nXU +uGgYb1I01XOg5xhFr65cjIM5DX5L9tr90tzRE1afjeUyvT0AYkSodQzJmweQG1nz +WQ9INEf//smQf6Dvguwe6pCZye8RcwbdH8P+1U5uHtmIKGSWVRzX347M2TGREtOe +arAblsfmB75t/eIracWIP0+goQSf8O942GrhBpqlMHYhPYn1ALYpgJVTp/mlIYtl +GtDDEeu8LHbF5z0orEBLp+x5aAbqbwIUXdvIejehFS669Mxb2p5K9XDbFWJJ5osn +6pAKFdTx7oo0HvGQP6vVEdsHkzZMenhj8U76jDlJKLAZi2Rww3Usfy0obssPT1Iu +R8JLjqpVgwXwKMaeLsGf4GUkqBLNsj72fNK5NGCJWeRged0G+jqaP2/Lf2UCbMxV +pAmoAciNdVexY9ytH+wPXLLKbGPIKAKPqepF3vhX4yHoL2Q+gR9Hx194r6hRdfHV +AKknDoG6/MWWzaqEieec28oXCNZwXdkPWJyssa1E6W1fojL/xhdvmiHUFUeR3rgs +xiMOdxvhFusKbuHjYpGwb9/D6+D7hUQGlSZ/8UMW3hfWiJcCAwEAAaOB2TCB1jAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUqH3ODOPG +96qjP/ll526pjIJKWdswgZMGA1UdIwSBizCBiIAUqH3ODOPG96qjP/ll526pjIJK +WduhWqRYMFYxODA2BgNVBAMTL0luZm9ybWF0aW9uIFNlY3VyaXR5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IENBMQ0wCwYDVQQKEwRJU0NBMQswCQYDVQQGEwJLWoIU +KH3ODOPG96qjP/ll526pjIJKWdswDQYJKoZIhvcNAQELBQADggIBAD3Qw2GXqOJ8 +BUqdN382O6KwdDljJzVhgxkOzcC6avfisoZ+Vhj74dy7qoMmQ84M+yXnA7BCCzHr +wBYsDKUwLT/WiHKcjToFtsejMteofiU/M0/ljigoI4Fbcl5w0tl8C47wAm5R2qAJ +sU4re9npst1z+AX4Ll7BurgsBKtTvA3PtZtRlsPm3zd7xS2xCGRaybXdMkLYWDRZ +J6R+A/iK1NM7UzAeEYpCyhDZo/OCrFgNWDpqwVTiOe3CPqM3aEBPPbohTbjMV9Gj +L0g7m1j2BI+X3ByHvTEYqZia36HOgmy4jrOuMsWeSqXw/RjTINBWtOzQDnm7Enrq +RpjR1kpugkAzNvGFSEUvkj7moKo++ixH46iOjSNGexPx21ktQijUXAvQ9ETO9EsJ +jmUNOiTd+iRjUEnACaGn+od99CsgEXBDq9EtP65KedzXIy5MTu6fMULSSLaQdzLh +Vd827PEzgMvNCj45pqVisVJ6l+N73J7yLrtq6Ad6BQ1N+jC0MMiiYn2r7E5Gt54j ++GzQMZgHgdoHbk6tiUw3UXrM8CGzaHJhSu/g/oUkGU0EDKlduHigTNCuHLX9uuvw +gNglHhejbQE8ai7ApOwoEmZMXBH9B+oFkwU5CSN1AoNDiQIUlzqS2mv41GU7q2iX +k3zu7DCQingYbxGab/J8R/e9aTMNhD8W +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/leaf.pem new file mode 100644 index 000000000..870b3623d --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/leaf.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIUEPlNJxZrwg60AMmYq4fl4iKEp6MwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVHJ1c3QgVGVzdCBJbnQwIBcNMjYxMDA4MTcxOTQ0WhgP +MjEyNjA5MTQxNzE5NDRaMAwxCjAIBgNVBAMMAXgwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDh/WlixnDuMipvbyvaXShC9Oa6b8fG7focttANGZtwwCpX ++TkEO6NTRvlwOBCdj1zGZEPuEQDZtbVgyz0DIxCuDK8sdlY7UgZjUY9ifThKhAmA +ux7CC2UcDLnr7P16ixVd3z1ev14zWqkyl0wZPG6udBoIyLUo/DzLj8j/YQQC0+Zt +JxGrtY2mwYbwyj0OFafkVrWGLe8EJZV8IrV7N0+OGGUi9ZHuvzbtgP4fc8xJj7Md +zQtxa2vA+Uq02PHfR+iYyAFow1taltelKV+mbfVJypy6RgQEnyIlEPpACMXD4HoU +QLG4dZAca0KFzdgI1IsxTSeC5SJxKk0RYp3ElyfJAgMBAAGjgacwgaQwDAYDVR0T +AQH/BAIwADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYD +VR0jBBgwFoAUZr13tE+ypjf5+dQIrf6xsgcp0JkwLwYDVR0RBCgwJoIMaG9zdC5l +eGFtcGxlhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMB0GA1UdDgQWBBRgGEvI6VZt +KCBl88e6Icmez0rXPjANBgkqhkiG9w0BAQsFAAOCAQEABG/ol4K9If/YAfPGGqfn +7FVzGQOjgviCaWpQEQueBAmSLDSjgCyN4pRoZuFwIjzc0m0UkL8fQdS2ypF9dtHq +dIFCZRlBugqpTwzLvuPwJk6pPcPkwqpBB3jIJo25PFo6LokH/sA9sNnndprLmlwA +6iBC8wh3Nn81ge9Go2tM/yueOHAlFkSIMUXlq2/qPkRPSk/I9S9K94ESML4mLVY3 +SQ/ysv6G3Djjucey2Nasm5JJukzjgcUd047Yrnw88SDpO/jcmpoGwuCfmqMTr5gS +pBo8L1D4yJaG1CQM/OLlOBnDQrAyCUZ696nVQH/U5zJhjTR3wdzt9UeyE9kQEOJr +RA== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/nc_int.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/nc_int.pem new file mode 100644 index 000000000..2f7d2cf41 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/nc_int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQzCCAiugAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaekwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NFoY +DzIxMjYwOTE0MTcxOTQ0WjARMQ8wDQYDVQQDDAZOQyBJbnQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDBpGTjp6pklNYbUn+TAOFFojcQOry16ECScxx7 +VGZKHMYxBa1/9LCoAeS/z81CaiPIK6dv6kHOvKh3OA4VJinfoT03MPFo77tBtgie +Fgyt7GgROHMQHjjnSHCeMrv4UgF7qRgUMDpBOa+mXHx+gw1hLGSajnHMByQYjPSn +FUdn99c3GfA435sInwsneK3Z6K6w9dnaGfa5/cNcGs/LdFRARuBzutVFm0ZFz44E +nVoMeHppw3OBb4ZEA18Gn8cERW06+yA4/De98dzo8gPVt3IMwjx4Y5TPX5xm8JeI +vofKiHPofvTHnBlqCzvUeOxUafQUUKaexyygooiiB4NEymwfAgMBAAGjgYcwgYQw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHWJVS3H +Wh0c4hnE52bOWg2s/aGvMB8GA1UdIwQYMBaAFDl9W8k1XKQCubIn46G/oYwjeDkq +MCEGA1UdHgEB/wQXMBWgEzARgg9hbGxvd2VkLmV4YW1wbGUwDQYJKoZIhvcNAQEL +BQADggEBAKkFGxFm6cibc6Y853pNWoDN30fvkbt1e8YGf/Ws+E7e18wf9JM+HxfU +cCF5NFI9rZAScaLPifcoewxRnO0lqMtkNYk52/iJYE8WHkcn0/sCxluuHpD5HOVI +7YEbniFcPGBhTM/62An1FGtsCFd02vjP6dZ1m79fxgONYVKsMpJoiGZsYeScFixE +J0qpqXsJ8cfvhH0FkxQeSX28PHRKV9cay2ElmP8yAelpA9DGeowcE67KeIa2GH0E +75DIZlqa8+HTYSXGZOBKlEdPtLWtluGS/ewhDNN8jTmWu4rxPLvUU4VcnoOxHWri +WUK2t8zRGPlReSvQhSwZC54hBJx4e+c= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/nc_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/nc_leaf.pem new file mode 100644 index 000000000..5c4c32ed0 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/nc_leaf.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIUetjuFkPGZNknh/9qYSrAMnZYVfAwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGTkMgSW50MCAXDTI2MTAwODE3MTk0NFoYDzIxMjYwOTE0 +MTcxOTQ0WjAMMQowCAYDVQQDDAF4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAyhDyS5OTWf9yoZbBFCY69Em5fa2AVKSXnjQsLn/LRSfPrMyXp0doKdmI +gmhNsaFcEFMxyavyD8V2uMfpgg7QMEoEvRXZXdQkNPpT1k2WRPtkkQReig9vOtsc +sKL4oK3uU099jFaVOC5CmDUDElHTdTK83/WP2x2cLoPi2cfj7vwrmc2y9x2LGkzC +pOoKsDYEFMRZ2cyffSiudC1uT8kYKI8c32AO9hDwJF1sEyaqIzTVBh4P3zOw/g6O +dsWSSxFIHd+pbFjMXQSIePIpMSMuYVs5Pgz8mMuEJSNnWsfr6a5phEiezyM4rcMs +MZ6NCUqK9XThsxLXGw1QVPatbyTXLQIDAQABo4GPMIGMMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaA +FHWJVS3HWh0c4hnE52bOWg2s/aGvMBcGA1UdEQQQMA6CDGhvc3QuZXhhbXBsZTAd +BgNVHQ4EFgQUqEPPZG734QvkFZT6gtaRMTCcK2owDQYJKoZIhvcNAQELBQADggEB +AEy+iqqtgRXNk2CCClBLi2HrU2dBjr6FdbYNWPyWZ2FrvQigiAsbkzxql4bKlE6Q +jRGhf57nELD3W5jVbkh57X6Km5cGQcyBhPvpZzYjbMk9dDOWeyd8zyxnrZsOaXoo +Q0djdYu+uyqcBMvz4OfZn+GDybXRdwzY5PgeSSjRMbDhR7XIIMOiBmOv1A6sJoGC +6qqoo4nQPKrCGHBBNVv8sy78ZUTgDs2vGX9+Sx0VUyrAlrXLDF/6vxgjhTCEED6p +FX3agZtNVgkbj/B3I3sML4DzDZ+SMtlyyeOhuJgdWkI5YnptfDfhtPG1G1SHTBvL +u03WVlBWeiYY6to1/OD7SGc= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int.pem new file mode 100644 index 000000000..5f9047c5f --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpaeswDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NFoY +DzIxMjYwOTE0MTcxOTQ0WjARMQ8wDQYDVQQDDAZQTCBJbnQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCvpCVepJ8mvuB1zxlU2n9jMSDCDEDydVkBvcKW +fQQr2e8OWKcQ6y86DQ8ZCyLNWe+L4pZTMyV1Wq/T0jIo7vEJ3PfJjzcjaiT6yW+k +ZhxuaA4bWtnt8OArTNXRThTavkw1Ef7euhYL1degRZUxDJEpm86zNnwfv6YBRwoF +y6F1oh4Z7nTJyPs9xc63MrgATOltJ3t2gHjAOXdRyWglUBYRae2IWofgQScSk7jT +0T1KwD2ce5Q6RvCNpuhyXlzvZ6y9YcnijY1EjV5I0rnFwIV3u1PQQJt5v6RxL4rL +g2uJrnAhnKGBGonhl4QcpUw0nazcGa5jMHh8iZv9p18qf23fAgMBAAGjZjBkMBIG +A1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ2CJRo +uL2JbMe/bo3463fl8YjK/zAfBgNVHSMEGDAWgBQ5fVvJNVykArmyJ+Ohv6GMI3g5 +KjANBgkqhkiG9w0BAQsFAAOCAQEAhyqPUkysJw0CV07uTU39sdYnYS6LyDqFKEwE +1ToZ+1u4pL5QZRo8yJ65psR0+9w8NTsSnmKS3bgkTqxq08VsC/P5x/wZFeL02JAg +4mzfDn8Xb/FxACQDs5QafRyU6MXHhHI0m6ndS5EhLnWu/IPKcoUAxPWstlLe6ixR +VXY7FXjiraiU1smT97tHxbd2woVwaoJxPlaK1NupLMYY8KGNTOHBn6gLMWspdl/J +bi/3JkNc5E9TCILFBAtWH9sWw3/PY8Mb7ir7k88DWHq3HJIDSYTDt0tOpdUfAke4 +M/QdhHDS2pFQYCZxtSwK3RZ3OQHTfcZY7L2ospNTIsjsujGLZw== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int2.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int2.pem new file mode 100644 index 000000000..84724d151 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_int2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf6gAwIBAgIUI9bf0eiAxYZ4G3OLjOVETtL3aOQwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGUEwgSW50MCAXDTI2MTAwODE3MTk0NVoYDzIxMjYwOTE0 +MTcxOTQ1WjASMRAwDgYDVQQDDAdQTCBJbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAzeWnMybz8DmgEmziIs39MNQsnWvmqnhh7q10kDdOZDwV0v7C +rdDCQ6vPf3jaLt79jMvWURAQz1zJU4bpNsYw53+yqrraNw999jPyKI8k6ZJw1QPs +Na3VBxnulZb4sc8HQYD1RMXDrGeJwE07+AVFw1ej8FrWRsERLd5O4/gY2+eW1Sxi +aXkjzgA/iYpZW3p4+KKHGT93sseU7N7Alm54DgcHiksRGoQPwBSempty0p17f/R5 +PlvQX4/MmmLcpreEcOAiVtJDTf6qq8zXaogaCGvyEjYb/m4wfdRkuPBp03T9JA1I +VWugtXPqp+2oR/XDF9O2ZD9VlysagJNctoY5OQIDAQABo2MwYTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUkR09mkxkUjE/r7WNfrt1 +T3fICNIwHwYDVR0jBBgwFoAUNgiUaLi9iWzHv26N+Ot35fGIyv8wDQYJKoZIhvcN +AQELBQADggEBAJXeXPehboZGaAV85eEfasMW9cd17zNXFh7/WWE+9b7Rwz+5q6RY +G4yMizRFlSqorBiCidN9lKBqmCEETEkMjD1UI8iXQWXcMBHSUI9xvfdJiZ+I7xrV +Cjq4A5KJeKhayjlMTb27GlUV1g+irdh7g/rCDtN84LRGOMhpKZTcd6DerQCx6zrA +QxCP3vMexoyYh9Rv/90K7CO7mSXuplPGUX2zV6TUhwTR09M4+J+quvA32aamc7Wc +mtqoRTnG8HPh5ey2hjKJAjrbAA2edGDWaQb+0uOQyFhtJAHRpoGu6Mv7bt4Kk5Jb +A/WlHsdIlt1q1lS0iOCSLOZVaiaJB9y2Ce4= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/pl_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_leaf.pem new file mode 100644 index 000000000..9807869a5 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/pl_leaf.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUTTXPR16Bluu+wyeTi8GeJHAm+4QwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHUEwgSW50MjAgFw0yNjEwMDgxNzE5NDVaGA8yMTI2MDkx +NDE3MTk0NVowDDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALXpnV/pQz+nAooMhg52ANUSOZup3lVVRoSoqGiEZRoBUqEM9tVRbd9W +u2ZlWGqdquvxmR1IZtqvgW3cjp1+Fr4eoi/GCbGPXgdiNMVnmjP54M+qY93hMriR +TYA3KHVXhYR/XUnVuXsgHRnIeYC2yPx/W+pn5A58tQqODvPp/AFMCi/nWlitCOI+ +/UpMzuYVBm+vzAxBBCY8t/7MnTp7IyccxIShrDf9AHcGG2FPm9ZHZMSUeL7Dqnx+ +OXxZcGGSZfOdJRfIqUoOkO6KJqnha34SMSke3pj35IeTS9FLGecGY1UaWnN44SlO +IJgKze7MNXNNxxCKONjsnGsYzSJg01kCAwEAAaOBjzCBjDAMBgNVHRMBAf8EAjAA +MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAW +gBSRHT2aTGRSMT+vtY1+u3VPd8gI0jAXBgNVHREEEDAOggxob3N0LmV4YW1wbGUw +HQYDVR0OBBYEFEJ84ALu2SsxcnbD5p7C4pLStNcVMA0GCSqGSIb3DQEBCwUAA4IB +AQC4O6dQxcm6Grf4Q//XMo4zMBI/HcosD7Pqt8ToMfOMlmcpV5y9iuWD04K4yrrJ +KqhNdzqtuIPw/tPwDXfFX/vw2n3wvUXx2W4AP2951FnC5dWuE+CxgQA9kXjiqOiw +pZIUAqO+hjXfIswOtocMxmwCKvCbibh6DS4p+GMhDXFYPiBx60155DenUtfdfxps +0xgs42n/+UzesZhF+cUqvEtF8VrfkP2SpHrJXwxaII/0Yc0yqxCfd5xMAUw+ccP2 +FWoBMm4QSPI62OmXSXk3lGjn8zZAABilPONqo2nsSv2HcOH82OqvleloRVXnVIMK +58Dib6o7IcPlgsnoH/tKoy7J +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/root.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/root.pem new file mode 100644 index 000000000..cb16e6b68 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/root.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBjCCAe6gAwIBAgIUU93kzExCdrzi3lnMnhSZgjnowIswDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0M1oY +DzIxMjYwOTE0MTcxOTQzWjAaMRgwFgYDVQQDDA9UcnVzdCBUZXN0IFJvb3QwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc4SkwOK60qqk09EjIPTRGvSnH +sOPJu0A1+IfRKsdfdMk6pTXL1Xm01nOLLqbsW4oz3rRfFQJyZPOSpPzzkCAdjKfp +y8KtKUZjzlnz8ADOoaeGLCnCyELw09anO/JsbnDv0snPMInYS5R2Onq5+M6qlEdH +iSe9uG0qiWx0OGXBkoDs+zF+Buc5ilYEKVNHZBho3V3qUoFjKKEE2O9DyKJ1qL+v +KgvTg0Z6KPjiyvlkkMRdn2UCHsJl5XTxU2dLLbs99F3/GSGbVjk+UXcUcJp4ZpA/ +/oQd99g4MYqKGDJIItFYQ0WQDTk1s2rEzqaOKS9DA83eXCwgvDBfOGaY+HCjAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW +BBQ5fVvJNVykArmyJ+Ohv6GMI3g5KjANBgkqhkiG9w0BAQsFAAOCAQEAZKD6bPnD +8l6xoyaai0AhqEx03MK1rBLiji2iK65FznWOFlRJCJX6MH5fJbGyafCHiM7fkTOw +BX2hY/hXC8Yg4AtsOvf6hRNYHEy0Z0Nj7qfCY9BpJXHzMvPLkJqqJB0UJisr5EDk +FKNiBiXftwbAUeUXuzncfviKbXroHlT5oLHBvApb6jhxIPhb7dBrbpN2urRfMzZu +ezbK+jWUB89h79xupK4ph7B8zFY5swiIZ3bjXDFqlNDzyksgzqqWOoZqyI3FoCJY +msORGKupBklLJgm78AjDJdu1/lhGfLflM9pspYi7A8Kct6fQerw2SJ+5xoFw9WKz +CUKllHzH9kJnew== +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/sha1_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/sha1_leaf.pem new file mode 100644 index 000000000..53f726c45 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/sha1_leaf.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRjCCAi6gAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpae0wDQYJKoZIhvcNAQEF +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NVoY +DzIxMjYwOTE0MTcxOTQ1WjAMMQowCAYDVQQDDAF4MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAj3JW39sTg/nPYlrrd1wcXpP4Ya2WmjizYVfXIujTj+ud +mOYFUM373ZCPo+VgyT4HP4DM6sq4p3vO6EuuVzyJ8soeFEnrDeikeQAnQbKw/2Zt +3S87iFMurZ34pMAWDauxUxVcONnwuf7meNME4aQoBWjPHbcGWke/Ri3xPNHKOODQ +3nt3HHr6wIBALOJXnUMWWRjovn4GcUxO0O1OGghr6taoI2MCsrBGbvv2BZ4TXtVd +anz5sQx1l9cAi9HlvnqpcIl07mkpvJ4nXf8wlmESZPpgrlKmI17R3CFhtoI0lhNW +WCx5KetPhgKYQmqHYCF5REdV0gjNbQqyyIv2KEnGTQIDAQABo4GPMIGMMAwGA1Ud +EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8G +A1UdIwQYMBaAFDl9W8k1XKQCubIn46G/oYwjeDkqMBcGA1UdEQQQMA6CDGhvc3Qu +ZXhhbXBsZTAdBgNVHQ4EFgQU0IoQbg1eN6pJMBqiJndYE2R3Z4gwDQYJKoZIhvcN +AQEFBQADggEBACgpJLT7wIynXT7UIO9ysQZZHICrTW92oopBh6CxnwzJuLsTjG4g +bQEnGO6NHQIBC3SCilyaEC9tDfDIpjJwfzyX4DuH/7UfAA6+xnJWxbaUFfAssiAG +DGTChKZlmZvRhf7V415QKKbEWeQz9I+j+X47at6aki/64BAmMw7ErDPHQukg74kB +zQvNFvkpSVcO6dgbYKP/+F/x3drAierIvJkfhcox/HoZSwcgKGDp2VFcfEKxUK91 +PkyDw78ONQANiM53PNSAjfSRVzRzW3PsPjNiF+OHGg+FNp6Cp8VbS6fSyhN6qf2q +RXlF1J0mj226t9l9v7JkWfjTkiktRBnJoXU= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/wc_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/wc_leaf.pem new file mode 100644 index 000000000..04723df0f --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/wc_leaf.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpae8wDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MjAyNFoY +DzIxMjYwOTE0MTcyMDI0WjAMMQowCAYDVQQDDAF4MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEApbYcbze7NDc8K8nCy4yoCy++oUFvoppPJpPaPb7SpRRD +0AHISMpE09/yXr2+NNVf80yzhmsSfuej7cq4TMYN2m6cZUVe9r+lCZC7QztfpZdO +9UZLWv/S53rWcLA/rtH2yg5Q1DRgt2uoY/FlCmMJt3cgrr3H7R9vCtQUrhSayGyY +PfPwyrwkL6Rja3ztkKPlco83CgqRnWMOwG6gpxcqTAcyzH1WAcyDkTWmhkr+1G50 +oL852GdVV+kO0rLNAI4+bPdsbPOKk4HikaTHHE0SQV78eb0Z5X/D0wFGu1iGopJ/ +BBGSym2LYibMbNLvkaWrnAT2vdVP1n/6afcJxAjj+wIDAQABo4GuMIGrMAwGA1Ud +EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8G +A1UdIwQYMBaAFDl9W8k1XKQCubIn46G/oYwjeDkqMDYGA1UdEQQvMC2CEioubGFu +LmhvbWUuZXhhbXBsZYIOKi5ob21lLmV4YW1wbGWCByouY28udWswHQYDVR0OBBYE +FNDwHsBO73UfLTCvRi/q/XHb0o6dMA0GCSqGSIb3DQEBCwUAA4IBAQDLXwJYrYI+ +efdLGjymEXT0CR/M67x6BIQKB8w0onIGyz26WedaTX+LKuji+WGgenY/AkIEC6AL +T4rv6dBVjxHv4+x8TgnzU+aWNOEEdDWNeaXc8sb+3ZZzm5mkPooVWfVdnej9i/G1 +WHjAFo/p0RHs613UuGRoZ6ZCmMomNYs9nwFoz6EmHUseARwj4dCAkdih+Z64j3NR +610hnoRsirKk/Ihjcn8RxUTVrBA+N6RkbIJByCeNzyhNzSmfNi8XvyvCqjjiUNon +b83rGCcF+V0px7NaZU8QwUJPDDekcUo/k8mQ+LjjLEAHByTJ9+Ap+3lhRuv21DWg +kJIAoFUaST7C +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/fixtures/desktop-trust/weak_leaf.pem b/fluxer_desktop/src/main/fixtures/desktop-trust/weak_leaf.pem new file mode 100644 index 000000000..d1c206f99 --- /dev/null +++ b/fluxer_desktop/src/main/fixtures/desktop-trust/weak_leaf.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwjCCAaqgAwIBAgIUA+GJ9S/l9MoO3gPga8JwUYNpae4wDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVHJ1c3QgVGVzdCBSb290MCAXDTI2MTAwODE3MTk0NVoY +DzIxMjYwOTE0MTcxOTQ1WjAMMQowCAYDVQQDDAF4MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDWzciJ+1PQ5RoweAE4xbNqaEnbwIyOR0+NwdUt02tcjezWlQfy +A9hWb/DkETcfw6LQx3u458vmBXM1YVmnYAhnd2P8OIwlQ0Se2xQ17iKJdpoa7IQ/ +aTkF1yjBvFxD8DoDRojpVupPI+mh5wg+wCCvgznX+fpZYkXEPorTFeDe2QIDAQAB +o4GPMIGMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoG +CCsGAQUFBwMBMB8GA1UdIwQYMBaAFDl9W8k1XKQCubIn46G/oYwjeDkqMBcGA1Ud +EQQQMA6CDGhvc3QuZXhhbXBsZTAdBgNVHQ4EFgQU/l8az3OuVEjRNlmpfraqM0+p +NT8wDQYJKoZIhvcNAQELBQADggEBANJhIs3MqR/U3CZshOZSduYdDz3xXUbqg5K6 +/z6EynXzF+DW26LiwZcWa3bJxfi15NbQ3urMu9UueyX2JJ1tffRNRnwWEPRG6qZ5 +oD4y7hyrPvbPSVMCGTZJPX1mBi1Fo0ijPNtrziujNw9xEuFL/3Exan3xelJJpg8J +jLdVYzvzgzqT/m0Q1gy9ceRb6VJhtUN1ingYLyUvRwiih64pLLslBwvluEGrHqZ8 +f6JmpvxKX5kjaWXH8M6ZjgJofmD2vaCDjnb3Y7dZAMNlxMpDXhW0hxQEjycnh3dZ +cpLB7DwofmR/ov/wE/tVmjA+lqR6Fp8fpyy5vtvGCeVMnJv32/I= +-----END CERTIFICATE----- diff --git a/fluxer_desktop/src/main/index.ts b/fluxer_desktop/src/main/index.ts index 7d8b494ea..913958d93 100644 --- a/fluxer_desktop/src/main/index.ts +++ b/fluxer_desktop/src/main/index.ts @@ -58,6 +58,7 @@ import { import {recordDesktopLastRoute} from '@electron/main/DesktopLastRoute'; import {cleanupDesktopOutboundHTTP} from '@electron/main/DesktopOutboundHTTP'; import {registerDesktopRuntimeConfigHandlers} from '@electron/main/DesktopRuntimeConfigIpc'; +import {installDesktopSystemTrustVerifier} from '@electron/main/DesktopSystemTrustVerifier'; import {destroyDesktopTray, hasActiveDesktopTray, initializeDesktopTray} from '@electron/main/DesktopTray'; import {registerDisplayMediaHandlers} from '@electron/main/DisplayMedia'; import {initializeDockMenu} from '@electron/main/DockMenu'; @@ -119,7 +120,7 @@ import { DesktopLegacyImportPhase, readDesktopLegacyImportPhase, } from '@fluxer/desktop_ipc/src/StorageContract'; -import {app, dialog, ipcMain, netLog, shell} from 'electron'; +import {app, dialog, ipcMain, netLog, session, shell} from 'electron'; import log from 'electron-log'; log.transports.file.level = 'info'; @@ -395,6 +396,11 @@ if (launchConfigurationError) { log.error('[Init] Failed to configure the host resolver:', error); } await runStartupPhaseAsync('launch-net-log', startLaunchNetLog); + try { + runStartupPhase('system-trust', () => installDesktopSystemTrustVerifier(session.defaultSession)); + } catch (error) { + log.error('[Init] Failed to install the system trust verifier:', error); + } try { await runStartupPhaseAsync('desktop-debug-info', async () => { logDesktopDebugInfo(await getDesktopDebugInfo(userDataConfig.base, {nativeProbes: false}));