Skip to content

Commit

Permalink
feat: electron >=12.0.0 is now supported (and tested on ci)
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Mar 2, 2021
1 parent 433f020 commit 8fffd3e
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 100 deletions.
44 changes: 42 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ jobs:
with:
path: dist
key: dist-${{ hashFiles('src/**/*.ts') }}-${{ hashFiles('tsconfig/*.json') }}
- run: npm install
working-directory: ./test
- name: Test Node.js crypto
run: npm run test
- name: Test Node.js crypto w/ CryptoKey
Expand All @@ -99,6 +97,48 @@ jobs:
if: ${{ !startsWith(matrix.node-version, '14') && !startsWith(matrix.node-version, '12') }}
- run: git reset HEAD --hard

test-electron:
needs:
- build
strategy:
matrix:
electron-version:
- 12.0.0
- latest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: 14
check-latest: true
- name: Store node version variable
id: node
run: |
echo "::set-output name=version::$(node -v)"
- name: Cache node_modules
uses: actions/cache@v2
id: node_modules
with:
path: node_modules
key: ${{ runner.os }}-node_modules-${{ hashFiles('package.json') }}-${{ steps.node.outputs.version }}
- name: Install dependencies
run: npx panva/npm-install-retry
if: ${{ steps.node_modules.outputs.cache-hit != 'true' }}
- name: Load cached dist
uses: actions/cache@v2
id: dist
with:
path: dist
key: dist-${{ hashFiles('src/**/*.ts') }}-${{ hashFiles('tsconfig/*.json') }}
- name: Install Electron
run: npm install --global xvfb-maybe electron@${{ matrix.electron-version }}
- name: Test Electron crypto
run: xvfb-maybe electron ./test/.electron
- run: git reset HEAD --hard

browserstack:
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Legend:
| Platform | supported versions | caveats |
| -- | -- | -- |
| Node.js | LTS ^12.19.0 || ^14.15.0 | |
| Electron | `process.version` must match<br> the Node.js supported versions. So 12+</sup> | see <sup>[1]</sup> |
| Electron | ^12.0.0 | see <sup>[1]</sup> |
| Deno || needs [Web Cryptography API integration](https://github.com/denoland/deno/issues/1891) first |
| React Native || has no available and usable crypto runtime |
| IE || implements old version of the Web Cryptography API specification |
Expand All @@ -129,7 +129,7 @@ Legend:

<sup>1</sup> Due to its use of BoringSSL the following is not supported in Electron
- A128KW, A192KW, A256KW, and all composite algorithms utilizing those
- secp256k1 EC curves
- secp256k1 EC curve
- Ed448, X25519, and X448 OKP Sub Types

<sup>2</sup> RSA1_5, OKP JWK Key Type, and secp256k1 EC curve is not supported in [Web Cryptography API][webcrypto].
Expand Down
4 changes: 4 additions & 0 deletions test/.electron.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const { app } = require('electron');

const exit = () => app.exit(process.exitCode);
require('ava/lib/cli').run().then(exit, exit);
27 changes: 20 additions & 7 deletions test/jwe/cookbook.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.1 - Key Encryption using RSA v1.5 and AES-HMAC-SHA2',
webcrypto: false,
electron: true,
reproducible: false,
input: {
plaintext:
Expand Down Expand Up @@ -246,6 +247,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.2 - Key Encryption using RSA-OAEP with AES-GCM',
webcrypto: true,
electron: true,
input: {
plaintext:
'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',
Expand Down Expand Up @@ -319,6 +321,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.3 - Key Wrap using PBES2-AES-KeyWrap with AES-CBC-HMAC-SHA2',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -375,6 +378,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.4 - Key Agreement with Key Wrapping using ECDH-ES and AES-KeyWrap with AES-GCM',
webcrypto: true,
electron: false,
input: {
plaintext:
'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',
Expand Down Expand Up @@ -448,6 +452,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.5 - Key Agreement using ECDH-ES with AES-CBC-HMAC-SHA2',
webcrypto: true,
electron: true,
input: {
plaintext:
'You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.',
Expand Down Expand Up @@ -515,6 +520,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.6 - Direction Encryption using AES-GCM',
webcrypto: true,
electron: true,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -565,6 +571,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.6 - Key Wrap using AES-GCM KeyWrap with AES-CBC-HMAC-SHA2',
webcrypto: true,
electron: true,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -628,6 +635,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.8 - Key Wrap using AES-KeyWrap with AES-GCM',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -685,6 +693,7 @@ Promise.all([
{
title: 'https://tools.ietf.org/html/rfc7520#section-5.9 - Compressed Content',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -747,6 +756,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.10 - Including Additional Authenticated Data',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -811,6 +821,7 @@ Promise.all([
title:
'https://tools.ietf.org/html/rfc7520#section-5.11 - Protecting Specific Header Fields',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -874,6 +885,7 @@ Promise.all([
{
title: 'https://tools.ietf.org/html/rfc7520#section-5.12 - Protecting Content Only',
webcrypto: true,
electron: false,
reproducible: true,
input: {
plaintext:
Expand Down Expand Up @@ -935,22 +947,23 @@ Promise.all([
];

for (const vector of vectors) {
let conditional;
let run = test;
if (
('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) &&
vector.webcrypto === false
) {
conditional = test.failing;
} else {
conditional = test;
run = run.failing;
}
if ('electron' in process.versions && vector.electron === false) {
run = run.failing;
}
if (vector.skip) {
conditional = test.skip;
run = run.skip;
}
if (vector.only) {
conditional = test.only;
run = run.only;
}
conditional(testCookbook, vector);
run(testCookbook, vector);
}
},
);
99 changes: 70 additions & 29 deletions test/jwe/smoke.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,40 @@ Promise.all([
algs: ['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
generate: { crv: 'X448' },
},
p256: {
p256kw: {
public: pubjwk(p256),
private: p256,
algs: ['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
algs: ['ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
generate: { crv: 'P-256' },
},
p256dir: {
public: pubjwk(p256),
private: p256,
algs: ['ECDH-ES'],
generate: { crv: 'P-256' },
},
p384: {
p384kw: {
public: pubjwk(p384),
private: p384,
algs: ['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
algs: ['ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
generate: { crv: 'P-384' },
},
p521: {
p384dir: {
public: pubjwk(p384),
private: p384,
algs: ['ECDH-ES'],
generate: { crv: 'P-384' },
},
p521kw: {
public: pubjwk(p521),
private: p521,
algs: ['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
algs: ['ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW'],
generate: { crv: 'P-521' },
},
p521dir: {
public: pubjwk(p521),
private: p521,
algs: ['ECDH-ES'],
generate: { crv: 'P-521' },
},
octAny: {
Expand Down Expand Up @@ -276,40 +294,63 @@ Promise.all([
test(smoke, 'rsa');
test('with wrap ops', smoke, 'rsa', ['wrapKey'], ['unwrapKey']);
test('with enc ops', smoke, 'rsa', ['encrypt'], ['decrypt']);
test(smoke, 'p256');
test(smoke, 'p384');
test(smoke, 'p521');
test(smoke, 'oct128');
test('as keyobject', smoke, 'oct128', ['wrapKey'], ['unwrapKey'], true);
test(smoke, 'p256dir');
test(smoke, 'p384dir');
test(smoke, 'p521dir');
test(smoke, 'oct128gcm');
test('as keyobject', smoke, 'oct128gcm', ['encrypt'], ['decrypt'], true);
test(smoke, 'oct192');
test('as keyobject', smoke, 'oct192', ['wrapKey'], ['unwrapKey'], true);
test(smoke, 'oct192gcm');
test('as keyobject', smoke, 'oct192gcm', ['encrypt'], ['decrypt'], true);
test(smoke, 'oct256');
test('as keyobject', smoke, 'oct256', ['wrapKey'], ['unwrapKey'], true);
test(smoke, 'oct256gcm');
test('as keyobject', smoke, 'oct256gcm', ['encrypt'], ['decrypt'], true);
test(smoke, 'oct256c');
test(smoke, 'oct384c');
test(smoke, 'oct512c');
test(smoke, 'octAny');
test('as keyobject (deriveBits)', smoke, 'octAny', ['deriveBits'], ['deriveBits'], true);
test('as keyobject (deriveKey)', smoke, 'octAny', ['deriveKey'], ['deriveKey'], true);

let conditional;
if ('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) {
conditional = test.failing;
} else {
conditional = test;
function conditional({ webcrypto = 1, electron = 1 } = {}, ...args) {
let run = test;
if ((!webcrypto && 'WEBCRYPTO' in process.env)) {
run = run.failing;
}

if (!electron && 'electron' in process.versions) {
run = run.failing;
}
return run;
}
conditional(smoke, 'rsa1_5');
conditional(smoke, 'x25519');
conditional(smoke, 'x448');
conditional('as keyobject', smoke, 'oct256c', undefined, undefined, true);
conditional('as keyobject', smoke, 'oct384c', undefined, undefined, true);
conditional('as keyobject', smoke, 'oct512c', undefined, undefined, true);

conditional({ webcrypto: 0 }, smoke, 'rsa1_5');
conditional({ webcrypto: 0, electron: 0 }, smoke, 'x25519');
conditional({ webcrypto: 0, electron: 0 }, smoke, 'x448');
conditional({ webcrypto: 0 }, 'as keyobject', smoke, 'oct256c', undefined, undefined, true);
conditional({ webcrypto: 0 }, 'as keyobject', smoke, 'oct384c', undefined, undefined, true);
conditional({ webcrypto: 0 }, 'as keyobject', smoke, 'oct512c', undefined, undefined, true);
conditional({ electron: 0 })(smoke, 'octAny');
conditional({ electron: 0 })(
'as keyobject (deriveBits)',
smoke,
'octAny',
['deriveBits'],
['deriveBits'],
true,
);
conditional({ electron: 0 })(
'as keyobject (deriveKey)',
smoke,
'octAny',
['deriveKey'],
['deriveKey'],
true,
);
conditional({ electron: 0 })(smoke, 'oct128');
conditional({ electron: 0 })('as keyobject', smoke, 'oct128', ['wrapKey'], ['unwrapKey'], true);
conditional({ electron: 0 })(smoke, 'oct192');
conditional({ electron: 0 })('as keyobject', smoke, 'oct192', ['wrapKey'], ['unwrapKey'], true);
conditional({ electron: 0 })(smoke, 'oct256');
conditional({ electron: 0 })('as keyobject', smoke, 'oct256', ['wrapKey'], ['unwrapKey'], true);
conditional({ electron: 0 }, smoke, 'p256kw');
conditional({ electron: 0 }, smoke, 'p384kw');
conditional({ electron: 0 }, smoke, 'p521kw');
},
(err) => {
test('failed to import', (t) => {
Expand Down
Loading

0 comments on commit 8fffd3e

Please sign in to comment.