mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-03-30 15:08:32 +00:00
Compare commits
No commits in common. "main" and "v6.0.1" have entirely different histories.
@ -1,10 +1,6 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
# The redundant target-branch directive is needed to set two different update schedules for npm,
|
|
||||||
# working around a dependabot limitation:
|
|
||||||
# see https://github.com/dependabot/dependabot-core/issues/1778#issuecomment-1988140219 .
|
|
||||||
target-branch: main
|
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
@ -30,4 +26,4 @@ updates:
|
|||||||
- "@noble*"
|
- "@noble*"
|
||||||
update-types:
|
update-types:
|
||||||
- "minor"
|
- "minor"
|
||||||
- "patch"
|
- "patch"
|
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@ -106,7 +106,6 @@ jobs:
|
|||||||
npx playwright install --with-deps firefox
|
npx playwright install --with-deps firefox
|
||||||
|
|
||||||
- name: Install WebKit # caching not possible, external shared libraries required
|
- name: Install WebKit # caching not possible, external shared libraries required
|
||||||
if: ${{ matrix.runner == 'macos-latest' }} # do not install on ubuntu, since the X25519 WebCrypto implementation has issues
|
|
||||||
run: npx playwright install --with-deps webkit
|
run: npx playwright install --with-deps webkit
|
||||||
|
|
||||||
- name: Run browser tests
|
- name: Run browser tests
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
439
docs/module-crypto_mode.html
Normal file
439
docs/module-crypto_mode.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
openpgp.d.ts
vendored
2
openpgp.d.ts
vendored
@ -916,8 +916,6 @@ export namespace enums {
|
|||||||
export enum aead {
|
export enum aead {
|
||||||
eax = 1,
|
eax = 1,
|
||||||
ocb = 2,
|
ocb = 2,
|
||||||
gcm = 3,
|
|
||||||
/** @deprecated use `gcm` instead */
|
|
||||||
experimentalGCM = 100 // Private algorithm
|
experimentalGCM = 100 // Private algorithm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
560
package-lock.json
generated
560
package-lock.json
generated
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "openpgp",
|
"name": "openpgp",
|
||||||
"version": "6.1.0",
|
"version": "6.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "openpgp",
|
"name": "openpgp",
|
||||||
"version": "6.1.0",
|
"version": "6.0.1",
|
||||||
"license": "LGPL-3.0+",
|
"license": "LGPL-3.0+",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@noble/ciphers": "^1.2.1",
|
"@noble/ciphers": "^1.0.0",
|
||||||
"@noble/curves": "^1.8.1",
|
"@noble/curves": "^1.6.0",
|
||||||
"@noble/hashes": "^1.5.0",
|
"@noble/hashes": "^1.5.0",
|
||||||
"@openpgp/jsdoc": "^3.6.11",
|
"@openpgp/jsdoc": "^3.6.11",
|
||||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||||
@ -45,9 +45,9 @@
|
|||||||
"eslint-plugin-chai-friendly": "^0.7.4",
|
"eslint-plugin-chai-friendly": "^0.7.4",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-unicorn": "^48.0.1",
|
"eslint-plugin-unicorn": "^48.0.1",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.7.4",
|
||||||
"mocha": "^10.7.3",
|
"mocha": "^10.7.3",
|
||||||
"playwright": "^1.51.1",
|
"playwright": "^1.48.2",
|
||||||
"rollup": "^4.24.2",
|
"rollup": "^4.24.2",
|
||||||
"sinon": "^18.0.1",
|
"sinon": "^18.0.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
@ -929,9 +929,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@noble/ciphers": {
|
"node_modules/@noble/ciphers": {
|
||||||
"version": "1.2.1",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.0.0.tgz",
|
||||||
"integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==",
|
"integrity": "sha512-wH5EHOmLi0rEazphPbecAzmjd12I6/Yv/SiHdkA9LSycsQk7RuuTp7am5/o62qYr0RScE7Pc9icXGBbsr6cesA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -942,13 +942,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@noble/curves": {
|
"node_modules/@noble/curves": {
|
||||||
"version": "1.8.1",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz",
|
||||||
"integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==",
|
"integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "1.7.1"
|
"@noble/hashes": "1.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.21.3 || >=16"
|
"node": "^14.21.3 || >=16"
|
||||||
@ -958,11 +957,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@noble/hashes": {
|
"node_modules/@noble/hashes": {
|
||||||
"version": "1.7.1",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz",
|
||||||
"integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==",
|
"integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.21.3 || >=16"
|
"node": "^14.21.3 || >=16"
|
||||||
},
|
},
|
||||||
@ -2763,85 +2761,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-chrome/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-chrome/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-chrome/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-chrome/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-commands": {
|
"node_modules/@web/test-runner-commands": {
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz",
|
||||||
@ -2856,11 +2775,10 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-commands/node_modules/@web/test-runner-core": {
|
"node_modules/@web/test-runner-core": {
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
"version": "0.13.3",
|
||||||
"version": "0.13.4-patch.0",
|
"resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.3.tgz",
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
"integrity": "sha512-ilDqF/v2sj0sD69FNSIDT7uw4M1yTVedLBt32/lXy3MMi6suCM7m/ZlhsBy8PXhf879WMvzBOl/vhJBpEMB9vA==",
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2872,8 +2790,8 @@
|
|||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
"@types/istanbul-lib-coverage": "^2.0.3",
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
"@types/istanbul-reports": "^3.0.0",
|
||||||
"@web/browser-logs": "^0.4.0",
|
"@web/browser-logs": "^0.4.0",
|
||||||
"@web/dev-server-core": "^0.7.3",
|
"@web/dev-server-core": "^0.7.2",
|
||||||
"chokidar": "^4.0.1",
|
"chokidar": "^3.4.3",
|
||||||
"cli-cursor": "^3.1.0",
|
"cli-cursor": "^3.1.0",
|
||||||
"co-body": "^6.1.0",
|
"co-body": "^6.1.0",
|
||||||
"convert-source-map": "^2.0.0",
|
"convert-source-map": "^2.0.0",
|
||||||
@ -2895,11 +2813,11 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-commands/node_modules/chokidar": {
|
"node_modules/@web/test-runner-core/node_modules/@web/dev-server-core/node_modules/chokidar": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
"integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
|
||||||
"dev": true,
|
"extraneous": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readdirp": "^4.0.1"
|
"readdirp": "^4.0.1"
|
||||||
@ -2911,21 +2829,7 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-commands/node_modules/readdirp": {
|
"node_modules/@web/test-runner-core/node_modules/source-map": {
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-commands/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
"version": "0.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||||
@ -2952,85 +2856,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-coverage-v8/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-coverage-v8/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-coverage-v8/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-coverage-v8/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-mocha": {
|
"node_modules/@web/test-runner-mocha": {
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz",
|
||||||
@ -3044,85 +2869,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-mocha/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-mocha/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-mocha/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-mocha/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-playwright": {
|
"node_modules/@web/test-runner-playwright": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz",
|
||||||
@ -3138,85 +2884,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-playwright/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-playwright/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-playwright/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-playwright/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-webdriver": {
|
"node_modules/@web/test-runner-webdriver": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@web/test-runner-webdriver/-/test-runner-webdriver-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@web/test-runner-webdriver/-/test-runner-webdriver-0.8.0.tgz",
|
||||||
@ -3231,154 +2898,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@web/test-runner-webdriver/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-webdriver/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-webdriver/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner-webdriver/node_modules/source-map": {
|
|
||||||
"version": "0.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
|
||||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner/node_modules/@web/test-runner-core": {
|
|
||||||
"name": "@openpgp/wtr-test-runner-core",
|
|
||||||
"version": "0.13.4-patch.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openpgp/wtr-test-runner-core/-/wtr-test-runner-core-0.13.4-patch.0.tgz",
|
|
||||||
"integrity": "sha512-vcQXfDvDyVhQo4IpqHk/ksNayC/hKNjaN7ykXygtrGmOSdsVs1IGopNVzOgjjeISpZUytHnivJNEMtNWNPGgrg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.12.11",
|
|
||||||
"@types/babel__code-frame": "^7.0.2",
|
|
||||||
"@types/co-body": "^6.1.0",
|
|
||||||
"@types/convert-source-map": "^2.0.0",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/istanbul-lib-coverage": "^2.0.3",
|
|
||||||
"@types/istanbul-reports": "^3.0.0",
|
|
||||||
"@web/browser-logs": "^0.4.0",
|
|
||||||
"@web/dev-server-core": "^0.7.3",
|
|
||||||
"chokidar": "^4.0.1",
|
|
||||||
"cli-cursor": "^3.1.0",
|
|
||||||
"co-body": "^6.1.0",
|
|
||||||
"convert-source-map": "^2.0.0",
|
|
||||||
"debounce": "^1.2.0",
|
|
||||||
"dependency-graph": "^0.11.0",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"internal-ip": "^6.2.0",
|
|
||||||
"istanbul-lib-coverage": "^3.0.0",
|
|
||||||
"istanbul-lib-report": "^3.0.1",
|
|
||||||
"istanbul-reports": "^3.0.2",
|
|
||||||
"log-update": "^4.0.0",
|
|
||||||
"nanocolors": "^0.2.1",
|
|
||||||
"nanoid": "^3.1.25",
|
|
||||||
"open": "^8.0.2",
|
|
||||||
"picomatch": "^2.2.2",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner/node_modules/chokidar": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.16.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner/node_modules/readdirp": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.18.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@web/test-runner/node_modules/source-map": {
|
"node_modules/@web/test-runner/node_modules/source-map": {
|
||||||
"version": "0.7.4",
|
"version": "0.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||||
@ -6554,11 +6073,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fflate": {
|
"node_modules/fflate": {
|
||||||
"version": "0.8.2",
|
"version": "0.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
|
||||||
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
|
"integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
@ -9995,13 +9513,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/playwright": {
|
"node_modules/playwright": {
|
||||||
"version": "1.51.1",
|
"version": "1.48.2",
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz",
|
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz",
|
||||||
"integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==",
|
"integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.51.1"
|
"playwright-core": "1.48.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
@ -10014,9 +9532,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/playwright-core": {
|
"node_modules/playwright-core": {
|
||||||
"version": "1.51.1",
|
"version": "1.48.2",
|
||||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz",
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz",
|
||||||
"integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==",
|
"integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
15
package.json
15
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "openpgp",
|
"name": "openpgp",
|
||||||
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
||||||
"version": "6.1.0",
|
"version": "6.0.1",
|
||||||
"license": "LGPL-3.0+",
|
"license": "LGPL-3.0+",
|
||||||
"homepage": "https://openpgpjs.org/",
|
"homepage": "https://openpgpjs.org/",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -59,11 +59,11 @@
|
|||||||
"docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME",
|
"docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME",
|
||||||
"preversion": "rm -rf dist docs node_modules && npm ci && npm test",
|
"preversion": "rm -rf dist docs node_modules && npm ci && npm test",
|
||||||
"version": "npm run docs && git add -A docs",
|
"version": "npm run docs && git add -A docs",
|
||||||
"postversion": "git push --follow-tags && npm publish"
|
"postversion": "git push && git push --tags && npm publish"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@noble/ciphers": "^1.2.1",
|
"@noble/ciphers": "^1.0.0",
|
||||||
"@noble/curves": "^1.8.1",
|
"@noble/curves": "^1.6.0",
|
||||||
"@noble/hashes": "^1.5.0",
|
"@noble/hashes": "^1.5.0",
|
||||||
"@openpgp/jsdoc": "^3.6.11",
|
"@openpgp/jsdoc": "^3.6.11",
|
||||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||||
@ -98,9 +98,9 @@
|
|||||||
"eslint-plugin-chai-friendly": "^0.7.4",
|
"eslint-plugin-chai-friendly": "^0.7.4",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-unicorn": "^48.0.1",
|
"eslint-plugin-unicorn": "^48.0.1",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.7.4",
|
||||||
"mocha": "^10.7.3",
|
"mocha": "^10.7.3",
|
||||||
"playwright": "^1.51.1",
|
"playwright": "^1.48.2",
|
||||||
"rollup": "^4.24.2",
|
"rollup": "^4.24.2",
|
||||||
"sinon": "^18.0.1",
|
"sinon": "^18.0.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
@ -110,8 +110,7 @@
|
|||||||
"web-streams-polyfill": "^4.0.0"
|
"web-streams-polyfill": "^4.0.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@web/dev-server-core": "npm:@openpgp/wtr-dev-server-core@0.7.3-patch.1",
|
"@web/dev-server-core": "npm:@openpgp/wtr-dev-server-core@0.7.3-patch.1"
|
||||||
"@web/test-runner-core": "npm:@openpgp/wtr-test-runner-core@0.13.4-patch.0"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -11,8 +11,7 @@ export async function getLegacyCipher(algo) {
|
|||||||
case enums.symmetric.twofish:
|
case enums.symmetric.twofish:
|
||||||
case enums.symmetric.tripledes: {
|
case enums.symmetric.tripledes: {
|
||||||
const { legacyCiphers } = await import('./legacy_ciphers');
|
const { legacyCiphers } = await import('./legacy_ciphers');
|
||||||
const algoName = enums.read(enums.symmetric, algo);
|
const cipher = legacyCiphers.get(algo);
|
||||||
const cipher = legacyCiphers.get(algoName);
|
|
||||||
if (!cipher) {
|
if (!cipher) {
|
||||||
throw new Error('Unsupported cipher algorithm');
|
throw new Error('Unsupported cipher algorithm');
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,15 @@
|
|||||||
* Separate dynamic imports are not convenient as they result in multiple chunks.
|
* Separate dynamic imports are not convenient as they result in multiple chunks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TripleDES as tripledes } from './des';
|
import { TripleDES } from './des';
|
||||||
import cast5 from './cast5';
|
import CAST5 from './cast5';
|
||||||
import twofish from './twofish';
|
import TwoFish from './twofish';
|
||||||
import blowfish from './blowfish';
|
import BlowFish from './blowfish';
|
||||||
|
import enums from '../../enums';
|
||||||
|
|
||||||
// We avoid importing 'enums' as this module is lazy loaded, and doing so could mess up
|
export const legacyCiphers = new Map([
|
||||||
// chunking for the lightweight build
|
[enums.symmetric.tripledes, TripleDES],
|
||||||
export const legacyCiphers = new Map(Object.entries({
|
[enums.symmetric.cast5, CAST5],
|
||||||
tripledes,
|
[enums.symmetric.blowfish, BlowFish],
|
||||||
cast5,
|
[enums.symmetric.twofish, TwoFish]
|
||||||
twofish,
|
]);
|
||||||
blowfish
|
|
||||||
}));
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* @fileoverview Cipher modes
|
|
||||||
* @module crypto/cipherMode
|
|
||||||
*/
|
|
||||||
|
|
||||||
export * as cfb from './cfb';
|
|
||||||
import eax from './eax';
|
|
||||||
import ocb from './ocb';
|
|
||||||
import gcm from './gcm';
|
|
||||||
import enums from '../../enums';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get implementation of the given AEAD mode
|
|
||||||
* @param {enums.aead} algo
|
|
||||||
* @param {Boolean} [acceptExperimentalGCM] - whether to allow the non-standard, legacy `experimentalGCM` algo
|
|
||||||
* @returns {Object}
|
|
||||||
* @throws {Error} on invalid algo
|
|
||||||
*/
|
|
||||||
export function getAEADMode(algo, acceptExperimentalGCM = false) {
|
|
||||||
switch (algo) {
|
|
||||||
case enums.aead.eax:
|
|
||||||
return eax;
|
|
||||||
case enums.aead.ocb:
|
|
||||||
return ocb;
|
|
||||||
case enums.aead.gcm:
|
|
||||||
return gcm;
|
|
||||||
case enums.aead.experimentalGCM:
|
|
||||||
if (!acceptExperimentalGCM) {
|
|
||||||
throw new Error('Unexpected non-standard `experimentalGCM` AEAD algorithm provided in `config.preferredAEADAlgorithm`: use `gcm` instead');
|
|
||||||
}
|
|
||||||
return gcm;
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported AEAD mode');
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,7 +23,8 @@
|
|||||||
* @module crypto/crypto
|
* @module crypto/crypto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { rsa, elliptic, elgamal, dsa } from './public_key';
|
import publicKey from './public_key';
|
||||||
|
import mode from './mode';
|
||||||
import { getRandomBytes } from './random';
|
import { getRandomBytes } from './random';
|
||||||
import { getCipherParams } from './cipher';
|
import { getCipherParams } from './cipher';
|
||||||
import ECDHSymkey from '../type/ecdh_symkey';
|
import ECDHSymkey from '../type/ecdh_symkey';
|
||||||
@ -50,16 +51,16 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat
|
|||||||
case enums.publicKey.rsaEncrypt:
|
case enums.publicKey.rsaEncrypt:
|
||||||
case enums.publicKey.rsaEncryptSign: {
|
case enums.publicKey.rsaEncryptSign: {
|
||||||
const { n, e } = publicParams;
|
const { n, e } = publicParams;
|
||||||
const c = await rsa.encrypt(data, n, e);
|
const c = await publicKey.rsa.encrypt(data, n, e);
|
||||||
return { c };
|
return { c };
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal: {
|
case enums.publicKey.elgamal: {
|
||||||
const { p, g, y } = publicParams;
|
const { p, g, y } = publicParams;
|
||||||
return elgamal.encrypt(data, p, g, y);
|
return publicKey.elgamal.encrypt(data, p, g, y);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ecdh: {
|
case enums.publicKey.ecdh: {
|
||||||
const { oid, Q, kdfParams } = publicParams;
|
const { oid, Q, kdfParams } = publicParams;
|
||||||
const { publicKey: V, wrappedKey: C } = await elliptic.ecdh.encrypt(
|
const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
|
||||||
oid, kdfParams, data, Q, fingerprint);
|
oid, kdfParams, data, Q, fingerprint);
|
||||||
return { V, C: new ECDHSymkey(C) };
|
return { V, C: new ECDHSymkey(C) };
|
||||||
}
|
}
|
||||||
@ -70,7 +71,7 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat
|
|||||||
throw new Error('X25519 and X448 keys can only encrypt AES session keys');
|
throw new Error('X25519 and X448 keys can only encrypt AES session keys');
|
||||||
}
|
}
|
||||||
const { A } = publicParams;
|
const { A } = publicParams;
|
||||||
const { ephemeralPublicKey, wrappedKey } = await elliptic.ecdhX.encrypt(
|
const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
|
||||||
keyAlgo, data, A);
|
keyAlgo, data, A);
|
||||||
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
||||||
return { ephemeralPublicKey, C };
|
return { ephemeralPublicKey, C };
|
||||||
@ -101,19 +102,19 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams,
|
|||||||
const { c } = sessionKeyParams;
|
const { c } = sessionKeyParams;
|
||||||
const { n, e } = publicKeyParams;
|
const { n, e } = publicKeyParams;
|
||||||
const { d, p, q, u } = privateKeyParams;
|
const { d, p, q, u } = privateKeyParams;
|
||||||
return rsa.decrypt(c, n, e, d, p, q, u, randomPayload);
|
return publicKey.rsa.decrypt(c, n, e, d, p, q, u, randomPayload);
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal: {
|
case enums.publicKey.elgamal: {
|
||||||
const { c1, c2 } = sessionKeyParams;
|
const { c1, c2 } = sessionKeyParams;
|
||||||
const p = publicKeyParams.p;
|
const p = publicKeyParams.p;
|
||||||
const x = privateKeyParams.x;
|
const x = privateKeyParams.x;
|
||||||
return elgamal.decrypt(c1, c2, p, x, randomPayload);
|
return publicKey.elgamal.decrypt(c1, c2, p, x, randomPayload);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ecdh: {
|
case enums.publicKey.ecdh: {
|
||||||
const { oid, Q, kdfParams } = publicKeyParams;
|
const { oid, Q, kdfParams } = publicKeyParams;
|
||||||
const { d } = privateKeyParams;
|
const { d } = privateKeyParams;
|
||||||
const { V, C } = sessionKeyParams;
|
const { V, C } = sessionKeyParams;
|
||||||
return elliptic.ecdh.decrypt(
|
return publicKey.elliptic.ecdh.decrypt(
|
||||||
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
||||||
}
|
}
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519:
|
||||||
@ -124,7 +125,7 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams,
|
|||||||
if (C.algorithm !== null && !util.isAES(C.algorithm)) {
|
if (C.algorithm !== null && !util.isAES(C.algorithm)) {
|
||||||
throw new Error('AES session key expected');
|
throw new Error('AES session key expected');
|
||||||
}
|
}
|
||||||
return elliptic.ecdhX.decrypt(
|
return publicKey.elliptic.ecdhX.decrypt(
|
||||||
algo, ephemeralPublicKey, C.wrappedKey, A, k);
|
algo, ephemeralPublicKey, C.wrappedKey, A, k);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -337,22 +338,22 @@ export function generateParams(algo, bits, oid) {
|
|||||||
case enums.publicKey.rsaEncrypt:
|
case enums.publicKey.rsaEncrypt:
|
||||||
case enums.publicKey.rsaEncryptSign:
|
case enums.publicKey.rsaEncryptSign:
|
||||||
case enums.publicKey.rsaSign:
|
case enums.publicKey.rsaSign:
|
||||||
return rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
|
return publicKey.rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
|
||||||
privateParams: { d, p, q, u },
|
privateParams: { d, p, q, u },
|
||||||
publicParams: { n, e }
|
publicParams: { n, e }
|
||||||
}));
|
}));
|
||||||
case enums.publicKey.ecdsa:
|
case enums.publicKey.ecdsa:
|
||||||
return elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||||
privateParams: { d: secret },
|
privateParams: { d: secret },
|
||||||
publicParams: { oid: new OID(oid), Q }
|
publicParams: { oid: new OID(oid), Q }
|
||||||
}));
|
}));
|
||||||
case enums.publicKey.eddsaLegacy:
|
case enums.publicKey.eddsaLegacy:
|
||||||
return elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||||
privateParams: { seed: secret },
|
privateParams: { seed: secret },
|
||||||
publicParams: { oid: new OID(oid), Q }
|
publicParams: { oid: new OID(oid), Q }
|
||||||
}));
|
}));
|
||||||
case enums.publicKey.ecdh:
|
case enums.publicKey.ecdh:
|
||||||
return elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
|
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
|
||||||
privateParams: { d: secret },
|
privateParams: { d: secret },
|
||||||
publicParams: {
|
publicParams: {
|
||||||
oid: new OID(oid),
|
oid: new OID(oid),
|
||||||
@ -362,13 +363,13 @@ export function generateParams(algo, bits, oid) {
|
|||||||
}));
|
}));
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448:
|
case enums.publicKey.ed448:
|
||||||
return elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
||||||
privateParams: { seed },
|
privateParams: { seed },
|
||||||
publicParams: { A }
|
publicParams: { A }
|
||||||
}));
|
}));
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519:
|
||||||
case enums.publicKey.x448:
|
case enums.publicKey.x448:
|
||||||
return elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
||||||
privateParams: { k },
|
privateParams: { k },
|
||||||
publicParams: { A }
|
publicParams: { A }
|
||||||
}));
|
}));
|
||||||
@ -398,21 +399,21 @@ export async function validateParams(algo, publicParams, privateParams) {
|
|||||||
case enums.publicKey.rsaSign: {
|
case enums.publicKey.rsaSign: {
|
||||||
const { n, e } = publicParams;
|
const { n, e } = publicParams;
|
||||||
const { d, p, q, u } = privateParams;
|
const { d, p, q, u } = privateParams;
|
||||||
return rsa.validateParams(n, e, d, p, q, u);
|
return publicKey.rsa.validateParams(n, e, d, p, q, u);
|
||||||
}
|
}
|
||||||
case enums.publicKey.dsa: {
|
case enums.publicKey.dsa: {
|
||||||
const { p, q, g, y } = publicParams;
|
const { p, q, g, y } = publicParams;
|
||||||
const { x } = privateParams;
|
const { x } = privateParams;
|
||||||
return dsa.validateParams(p, q, g, y, x);
|
return publicKey.dsa.validateParams(p, q, g, y, x);
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal: {
|
case enums.publicKey.elgamal: {
|
||||||
const { p, g, y } = publicParams;
|
const { p, g, y } = publicParams;
|
||||||
const { x } = privateParams;
|
const { x } = privateParams;
|
||||||
return elgamal.validateParams(p, g, y, x);
|
return publicKey.elgamal.validateParams(p, g, y, x);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ecdsa:
|
case enums.publicKey.ecdsa:
|
||||||
case enums.publicKey.ecdh: {
|
case enums.publicKey.ecdh: {
|
||||||
const algoModule = elliptic[enums.read(enums.publicKey, algo)];
|
const algoModule = publicKey.elliptic[enums.read(enums.publicKey, algo)];
|
||||||
const { oid, Q } = publicParams;
|
const { oid, Q } = publicParams;
|
||||||
const { d } = privateParams;
|
const { d } = privateParams;
|
||||||
return algoModule.validateParams(oid, Q, d);
|
return algoModule.validateParams(oid, Q, d);
|
||||||
@ -420,25 +421,39 @@ export async function validateParams(algo, publicParams, privateParams) {
|
|||||||
case enums.publicKey.eddsaLegacy: {
|
case enums.publicKey.eddsaLegacy: {
|
||||||
const { Q, oid } = publicParams;
|
const { Q, oid } = publicParams;
|
||||||
const { seed } = privateParams;
|
const { seed } = privateParams;
|
||||||
return elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448: {
|
case enums.publicKey.ed448: {
|
||||||
const { A } = publicParams;
|
const { A } = publicParams;
|
||||||
const { seed } = privateParams;
|
const { seed } = privateParams;
|
||||||
return elliptic.eddsa.validateParams(algo, A, seed);
|
return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519:
|
||||||
case enums.publicKey.x448: {
|
case enums.publicKey.x448: {
|
||||||
const { A } = publicParams;
|
const { A } = publicParams;
|
||||||
const { k } = privateParams;
|
const { k } = privateParams;
|
||||||
return elliptic.ecdhX.validateParams(algo, A, k);
|
return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown public key algorithm.');
|
throw new Error('Unknown public key algorithm.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random byte prefix for the specified algorithm
|
||||||
|
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
||||||
|
* @param {module:enums.symmetric} algo - Symmetric encryption algorithm
|
||||||
|
* @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
|
||||||
|
* @async
|
||||||
|
*/
|
||||||
|
export async function getPrefixRandom(algo) {
|
||||||
|
const { blockSize } = getCipherParams(algo);
|
||||||
|
const prefixrandom = await getRandomBytes(blockSize);
|
||||||
|
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
||||||
|
return util.concat([prefixrandom, repeat]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generating a session key for the specified symmetric algorithm
|
* Generating a session key for the specified symmetric algorithm
|
||||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
||||||
@ -450,6 +465,17 @@ export function generateSessionKey(algo) {
|
|||||||
return getRandomBytes(keySize);
|
return getRandomBytes(keySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get implementation of the given AEAD mode
|
||||||
|
* @param {enums.aead} algo
|
||||||
|
* @returns {Object}
|
||||||
|
* @throws {Error} on invalid algo
|
||||||
|
*/
|
||||||
|
export function getAEADMode(algo) {
|
||||||
|
const algoName = enums.read(enums.aead, algo);
|
||||||
|
return mode[algoName];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the given curve OID is supported
|
* Check whether the given curve OID is supported
|
||||||
* @param {module:type/oid} oid - EC object identifier
|
* @param {module:type/oid} oid - EC object identifier
|
||||||
@ -473,13 +499,13 @@ export function getCurvePayloadSize(algo, oid) {
|
|||||||
case enums.publicKey.ecdsa:
|
case enums.publicKey.ecdsa:
|
||||||
case enums.publicKey.ecdh:
|
case enums.publicKey.ecdh:
|
||||||
case enums.publicKey.eddsaLegacy:
|
case enums.publicKey.eddsaLegacy:
|
||||||
return new elliptic.CurveWithOID(oid).payloadSize;
|
return new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448:
|
case enums.publicKey.ed448:
|
||||||
return elliptic.eddsa.getPayloadSize(algo);
|
return publicKey.elliptic.eddsa.getPayloadSize(algo);
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519:
|
||||||
case enums.publicKey.x448:
|
case enums.publicKey.x448:
|
||||||
return elliptic.ecdhX.getPayloadSize(algo);
|
return publicKey.elliptic.ecdhX.getPayloadSize(algo);
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown elliptic algo');
|
throw new Error('Unknown elliptic algo');
|
||||||
}
|
}
|
||||||
@ -494,12 +520,14 @@ export function getPreferredCurveHashAlgo(algo, oid) {
|
|||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.ecdsa:
|
case enums.publicKey.ecdsa:
|
||||||
case enums.publicKey.eddsaLegacy:
|
case enums.publicKey.eddsaLegacy:
|
||||||
return elliptic.getPreferredHashAlgo(oid);
|
return publicKey.elliptic.getPreferredHashAlgo(oid);
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448:
|
case enums.publicKey.ed448:
|
||||||
return elliptic.eddsa.getPreferredHashAlgo(algo);
|
return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo);
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown elliptic signing algo');
|
throw new Error('Unknown elliptic signing algo');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { getCipherParams };
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
* @module crypto/hash
|
* @module crypto/hash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { transform as streamTransform, isArrayStream, readToEnd as streamReadToEnd } from '@openpgp/web-stream-tools';
|
import * as stream from '@openpgp/web-stream-tools';
|
||||||
|
import md5 from './md5';
|
||||||
import util from '../../util';
|
import util from '../../util';
|
||||||
import enums from '../../enums';
|
import enums from '../../enums';
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ function nodeHash(type) {
|
|||||||
}
|
}
|
||||||
return async function (data) {
|
return async function (data) {
|
||||||
const shasum = nodeCrypto.createHash(type);
|
const shasum = nodeCrypto.createHash(type);
|
||||||
return streamTransform(data, value => {
|
return stream.transform(data, value => {
|
||||||
shasum.update(value);
|
shasum.update(value);
|
||||||
}, () => new Uint8Array(shasum.digest()));
|
}, () => new Uint8Array(shasum.digest()));
|
||||||
};
|
};
|
||||||
@ -34,14 +35,14 @@ function nobleHash(nobleHashName, webCryptoHashName) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return async function(data) {
|
return async function(data) {
|
||||||
if (isArrayStream(data)) {
|
if (stream.isArrayStream(data)) {
|
||||||
data = await streamReadToEnd(data);
|
data = await stream.readToEnd(data);
|
||||||
}
|
}
|
||||||
if (util.isStream(data)) {
|
if (util.isStream(data)) {
|
||||||
const hash = await getNobleHash();
|
const hash = await getNobleHash();
|
||||||
|
|
||||||
const hashInstance = hash.create();
|
const hashInstance = hash.create();
|
||||||
return streamTransform(data, value => {
|
return stream.transform(data, value => {
|
||||||
hashInstance.update(value);
|
hashInstance.update(value);
|
||||||
}, () => hashInstance.digest());
|
}, () => hashInstance.digest());
|
||||||
} else if (webCrypto && webCryptoHashName) {
|
} else if (webCrypto && webCryptoHashName) {
|
||||||
@ -54,72 +55,76 @@ function nobleHash(nobleHashName, webCryptoHashName) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const md5 = nodeHash('md5') || nobleHash('md5');
|
export default {
|
||||||
const sha1 = nodeHash('sha1') || nobleHash('sha1', 'SHA-1');
|
|
||||||
const sha224 = nodeHash('sha224') || nobleHash('sha224');
|
|
||||||
const sha256 = nodeHash('sha256') || nobleHash('sha256', 'SHA-256');
|
|
||||||
const sha384 = nodeHash('sha384') || nobleHash('sha384', 'SHA-384');
|
|
||||||
const sha512 = nodeHash('sha512') || nobleHash('sha512', 'SHA-512');
|
|
||||||
const ripemd = nodeHash('ripemd160') || nobleHash('ripemd160');
|
|
||||||
const sha3_256 = nodeHash('sha3-256') || nobleHash('sha3_256');
|
|
||||||
const sha3_512 = nodeHash('sha3-512') || nobleHash('sha3_512');
|
|
||||||
|
|
||||||
/**
|
/** @see module:md5 */
|
||||||
* Create a hash on the specified data using the specified algorithm
|
md5: nodeHash('md5') || md5,
|
||||||
* @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
sha1: nodeHash('sha1') || nobleHash('sha1', 'SHA-1'),
|
||||||
* @param {Uint8Array} data - Data to be hashed
|
sha224: nodeHash('sha224') || nobleHash('sha224'),
|
||||||
* @returns {Promise<Uint8Array>} Hash value.
|
sha256: nodeHash('sha256') || nobleHash('sha256', 'SHA-256'),
|
||||||
*/
|
sha384: nodeHash('sha384') || nobleHash('sha384', 'SHA-384'),
|
||||||
export function computeDigest(algo, data) {
|
sha512: nodeHash('sha512') || nobleHash('sha512', 'SHA-512'),
|
||||||
switch (algo) {
|
ripemd: nodeHash('ripemd160') || nobleHash('ripemd160'),
|
||||||
case enums.hash.md5:
|
sha3_256: nodeHash('sha3-256') || nobleHash('sha3_256'),
|
||||||
return md5(data);
|
sha3_512: nodeHash('sha3-512') || nobleHash('sha3_512'),
|
||||||
case enums.hash.sha1:
|
|
||||||
return sha1(data);
|
|
||||||
case enums.hash.ripemd:
|
|
||||||
return ripemd(data);
|
|
||||||
case enums.hash.sha256:
|
|
||||||
return sha256(data);
|
|
||||||
case enums.hash.sha384:
|
|
||||||
return sha384(data);
|
|
||||||
case enums.hash.sha512:
|
|
||||||
return sha512(data);
|
|
||||||
case enums.hash.sha224:
|
|
||||||
return sha224(data);
|
|
||||||
case enums.hash.sha3_256:
|
|
||||||
return sha3_256(data);
|
|
||||||
case enums.hash.sha3_512:
|
|
||||||
return sha3_512(data);
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported hash function');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the hash size in bytes of the specified hash algorithm type
|
* Create a hash on the specified data using the specified algorithm
|
||||||
* @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
* @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||||
* @returns {Integer} Size in bytes of the resulting hash.
|
* @param {Uint8Array} data - Data to be hashed
|
||||||
*/
|
* @returns {Promise<Uint8Array>} Hash value.
|
||||||
export function getHashByteLength(algo) {
|
*/
|
||||||
switch (algo) {
|
digest: function(algo, data) {
|
||||||
case enums.hash.md5:
|
switch (algo) {
|
||||||
return 16;
|
case enums.hash.md5:
|
||||||
case enums.hash.sha1:
|
return this.md5(data);
|
||||||
case enums.hash.ripemd:
|
case enums.hash.sha1:
|
||||||
return 20;
|
return this.sha1(data);
|
||||||
case enums.hash.sha256:
|
case enums.hash.ripemd:
|
||||||
return 32;
|
return this.ripemd(data);
|
||||||
case enums.hash.sha384:
|
case enums.hash.sha256:
|
||||||
return 48;
|
return this.sha256(data);
|
||||||
case enums.hash.sha512:
|
case enums.hash.sha384:
|
||||||
return 64;
|
return this.sha384(data);
|
||||||
case enums.hash.sha224:
|
case enums.hash.sha512:
|
||||||
return 28;
|
return this.sha512(data);
|
||||||
case enums.hash.sha3_256:
|
case enums.hash.sha224:
|
||||||
return 32;
|
return this.sha224(data);
|
||||||
case enums.hash.sha3_512:
|
case enums.hash.sha3_256:
|
||||||
return 64;
|
return this.sha3_256(data);
|
||||||
default:
|
case enums.hash.sha3_512:
|
||||||
throw new Error('Invalid hash algorithm.');
|
return this.sha3_512(data);
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported hash function');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash size in bytes of the specified hash algorithm type
|
||||||
|
* @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||||
|
* @returns {Integer} Size in bytes of the resulting hash.
|
||||||
|
*/
|
||||||
|
getHashByteLength: function(algo) {
|
||||||
|
switch (algo) {
|
||||||
|
case enums.hash.md5:
|
||||||
|
return 16;
|
||||||
|
case enums.hash.sha1:
|
||||||
|
case enums.hash.ripemd:
|
||||||
|
return 20;
|
||||||
|
case enums.hash.sha256:
|
||||||
|
return 32;
|
||||||
|
case enums.hash.sha384:
|
||||||
|
return 48;
|
||||||
|
case enums.hash.sha512:
|
||||||
|
return 64;
|
||||||
|
case enums.hash.sha224:
|
||||||
|
return 28;
|
||||||
|
case enums.hash.sha3_256:
|
||||||
|
return 32;
|
||||||
|
case enums.hash.sha3_512:
|
||||||
|
return 64;
|
||||||
|
default:
|
||||||
|
throw new Error('Invalid hash algorithm.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
201
src/crypto/hash/md5.js
Normal file
201
src/crypto/hash/md5.js
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/**
|
||||||
|
* A fast MD5 JavaScript implementation
|
||||||
|
* Copyright (c) 2012 Joseph Myers
|
||||||
|
* http://www.myersdaily.org/joseph/javascript/md5-text.html
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software
|
||||||
|
* and its documentation for any purposes and without
|
||||||
|
* fee is hereby granted provided that this copyright notice
|
||||||
|
* appears in all copies.
|
||||||
|
*
|
||||||
|
* Of course, this soft is provided "as is" without express or implied
|
||||||
|
* warranty of any kind.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import util from '../../util';
|
||||||
|
|
||||||
|
// MD5 Digest
|
||||||
|
async function md5(entree) {
|
||||||
|
const digest = md51(util.uint8ArrayToString(entree));
|
||||||
|
return util.hexToUint8Array(hex(digest));
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5cycle(x, k) {
|
||||||
|
let a = x[0];
|
||||||
|
let b = x[1];
|
||||||
|
let c = x[2];
|
||||||
|
let d = x[3];
|
||||||
|
|
||||||
|
a = ff(a, b, c, d, k[0], 7, -680876936);
|
||||||
|
d = ff(d, a, b, c, k[1], 12, -389564586);
|
||||||
|
c = ff(c, d, a, b, k[2], 17, 606105819);
|
||||||
|
b = ff(b, c, d, a, k[3], 22, -1044525330);
|
||||||
|
a = ff(a, b, c, d, k[4], 7, -176418897);
|
||||||
|
d = ff(d, a, b, c, k[5], 12, 1200080426);
|
||||||
|
c = ff(c, d, a, b, k[6], 17, -1473231341);
|
||||||
|
b = ff(b, c, d, a, k[7], 22, -45705983);
|
||||||
|
a = ff(a, b, c, d, k[8], 7, 1770035416);
|
||||||
|
d = ff(d, a, b, c, k[9], 12, -1958414417);
|
||||||
|
c = ff(c, d, a, b, k[10], 17, -42063);
|
||||||
|
b = ff(b, c, d, a, k[11], 22, -1990404162);
|
||||||
|
a = ff(a, b, c, d, k[12], 7, 1804603682);
|
||||||
|
d = ff(d, a, b, c, k[13], 12, -40341101);
|
||||||
|
c = ff(c, d, a, b, k[14], 17, -1502002290);
|
||||||
|
b = ff(b, c, d, a, k[15], 22, 1236535329);
|
||||||
|
|
||||||
|
a = gg(a, b, c, d, k[1], 5, -165796510);
|
||||||
|
d = gg(d, a, b, c, k[6], 9, -1069501632);
|
||||||
|
c = gg(c, d, a, b, k[11], 14, 643717713);
|
||||||
|
b = gg(b, c, d, a, k[0], 20, -373897302);
|
||||||
|
a = gg(a, b, c, d, k[5], 5, -701558691);
|
||||||
|
d = gg(d, a, b, c, k[10], 9, 38016083);
|
||||||
|
c = gg(c, d, a, b, k[15], 14, -660478335);
|
||||||
|
b = gg(b, c, d, a, k[4], 20, -405537848);
|
||||||
|
a = gg(a, b, c, d, k[9], 5, 568446438);
|
||||||
|
d = gg(d, a, b, c, k[14], 9, -1019803690);
|
||||||
|
c = gg(c, d, a, b, k[3], 14, -187363961);
|
||||||
|
b = gg(b, c, d, a, k[8], 20, 1163531501);
|
||||||
|
a = gg(a, b, c, d, k[13], 5, -1444681467);
|
||||||
|
d = gg(d, a, b, c, k[2], 9, -51403784);
|
||||||
|
c = gg(c, d, a, b, k[7], 14, 1735328473);
|
||||||
|
b = gg(b, c, d, a, k[12], 20, -1926607734);
|
||||||
|
|
||||||
|
a = hh(a, b, c, d, k[5], 4, -378558);
|
||||||
|
d = hh(d, a, b, c, k[8], 11, -2022574463);
|
||||||
|
c = hh(c, d, a, b, k[11], 16, 1839030562);
|
||||||
|
b = hh(b, c, d, a, k[14], 23, -35309556);
|
||||||
|
a = hh(a, b, c, d, k[1], 4, -1530992060);
|
||||||
|
d = hh(d, a, b, c, k[4], 11, 1272893353);
|
||||||
|
c = hh(c, d, a, b, k[7], 16, -155497632);
|
||||||
|
b = hh(b, c, d, a, k[10], 23, -1094730640);
|
||||||
|
a = hh(a, b, c, d, k[13], 4, 681279174);
|
||||||
|
d = hh(d, a, b, c, k[0], 11, -358537222);
|
||||||
|
c = hh(c, d, a, b, k[3], 16, -722521979);
|
||||||
|
b = hh(b, c, d, a, k[6], 23, 76029189);
|
||||||
|
a = hh(a, b, c, d, k[9], 4, -640364487);
|
||||||
|
d = hh(d, a, b, c, k[12], 11, -421815835);
|
||||||
|
c = hh(c, d, a, b, k[15], 16, 530742520);
|
||||||
|
b = hh(b, c, d, a, k[2], 23, -995338651);
|
||||||
|
|
||||||
|
a = ii(a, b, c, d, k[0], 6, -198630844);
|
||||||
|
d = ii(d, a, b, c, k[7], 10, 1126891415);
|
||||||
|
c = ii(c, d, a, b, k[14], 15, -1416354905);
|
||||||
|
b = ii(b, c, d, a, k[5], 21, -57434055);
|
||||||
|
a = ii(a, b, c, d, k[12], 6, 1700485571);
|
||||||
|
d = ii(d, a, b, c, k[3], 10, -1894986606);
|
||||||
|
c = ii(c, d, a, b, k[10], 15, -1051523);
|
||||||
|
b = ii(b, c, d, a, k[1], 21, -2054922799);
|
||||||
|
a = ii(a, b, c, d, k[8], 6, 1873313359);
|
||||||
|
d = ii(d, a, b, c, k[15], 10, -30611744);
|
||||||
|
c = ii(c, d, a, b, k[6], 15, -1560198380);
|
||||||
|
b = ii(b, c, d, a, k[13], 21, 1309151649);
|
||||||
|
a = ii(a, b, c, d, k[4], 6, -145523070);
|
||||||
|
d = ii(d, a, b, c, k[11], 10, -1120210379);
|
||||||
|
c = ii(c, d, a, b, k[2], 15, 718787259);
|
||||||
|
b = ii(b, c, d, a, k[9], 21, -343485551);
|
||||||
|
|
||||||
|
x[0] = add32(a, x[0]);
|
||||||
|
x[1] = add32(b, x[1]);
|
||||||
|
x[2] = add32(c, x[2]);
|
||||||
|
x[3] = add32(d, x[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cmn(q, a, b, x, s, t) {
|
||||||
|
a = add32(add32(a, q), add32(x, t));
|
||||||
|
return add32((a << s) | (a >>> (32 - s)), b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ff(a, b, c, d, x, s, t) {
|
||||||
|
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
function gg(a, b, c, d, x, s, t) {
|
||||||
|
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hh(a, b, c, d, x, s, t) {
|
||||||
|
return cmn(b ^ c ^ d, a, b, x, s, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ii(a, b, c, d, x, s, t) {
|
||||||
|
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
function md51(s) {
|
||||||
|
const n = s.length;
|
||||||
|
const state = [1732584193, -271733879, -1732584194, 271733878];
|
||||||
|
let i;
|
||||||
|
for (i = 64; i <= s.length; i += 64) {
|
||||||
|
md5cycle(state, md5blk(s.substring(i - 64, i)));
|
||||||
|
}
|
||||||
|
s = s.substring(i - 64);
|
||||||
|
const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
for (i = 0; i < s.length; i++) {
|
||||||
|
tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
|
||||||
|
}
|
||||||
|
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
|
||||||
|
if (i > 55) {
|
||||||
|
md5cycle(state, tail);
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
tail[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tail[14] = n * 8;
|
||||||
|
md5cycle(state, tail);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* there needs to be support for Unicode here,
|
||||||
|
* unless we pretend that we can redefine the MD-5
|
||||||
|
* algorithm for multi-byte characters (perhaps
|
||||||
|
* by adding every four 16-bit characters and
|
||||||
|
* shortening the sum to 32 bits). Otherwise
|
||||||
|
* I suggest performing MD-5 as if every character
|
||||||
|
* was two bytes--e.g., 0040 0025 = @%--but then
|
||||||
|
* how will an ordinary MD-5 sum be matched?
|
||||||
|
* There is no way to standardize text to something
|
||||||
|
* like UTF-8 before transformation; speed cost is
|
||||||
|
* utterly prohibitive. The JavaScript standard
|
||||||
|
* itself needs to look at this: it should start
|
||||||
|
* providing access to strings as preformed UTF-8
|
||||||
|
* 8-bit unsigned value arrays.
|
||||||
|
*/
|
||||||
|
function md5blk(s) { /* I figured global was faster. */
|
||||||
|
const md5blks = [];
|
||||||
|
let i; /* Andy King said do it this way. */
|
||||||
|
for (i = 0; i < 64; i += 4) {
|
||||||
|
md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) <<
|
||||||
|
24);
|
||||||
|
}
|
||||||
|
return md5blks;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hex_chr = '0123456789abcdef'.split('');
|
||||||
|
|
||||||
|
function rhex(n) {
|
||||||
|
let s = '';
|
||||||
|
let j = 0;
|
||||||
|
for (; j < 4; j++) {
|
||||||
|
s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hex(x) {
|
||||||
|
for (let i = 0; i < x.length; i++) {
|
||||||
|
x[i] = rhex(x[i]);
|
||||||
|
}
|
||||||
|
return x.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function is much faster,
|
||||||
|
so if possible we use it. Some IEs
|
||||||
|
are the only ones I know of that
|
||||||
|
need the idiotic second function,
|
||||||
|
generated by an if clause. */
|
||||||
|
|
||||||
|
function add32(a, b) {
|
||||||
|
return (a + b) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default md5;
|
@ -1,80 +0,0 @@
|
|||||||
// Copied from https://github.com/paulmillr/noble-hashes/blob/main/test/misc/md5.ts
|
|
||||||
|
|
||||||
import { HashMD } from '@noble/hashes/_md';
|
|
||||||
import { rotl, wrapConstructor } from '@noble/hashes/utils';
|
|
||||||
|
|
||||||
// Per-round constants
|
|
||||||
const K = Array.from({ length: 64 }, (_, i) => Math.floor(2 ** 32 * Math.abs(Math.sin(i + 1))));
|
|
||||||
// Choice: a ? b : c
|
|
||||||
const Chi = (a: number, b: number, c: number) => (a & b) ^ (~a & c);
|
|
||||||
// Initial state (same as sha1, but 4 u32 instead of 5)
|
|
||||||
const IV = /* @__PURE__ */ new Uint32Array([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
|
|
||||||
// Temporary buffer, not used to store anything between runs
|
|
||||||
// Named this way for SHA1 compat
|
|
||||||
const MD5_W = /* @__PURE__ */ new Uint32Array(16);
|
|
||||||
class MD5 extends HashMD<MD5> {
|
|
||||||
private A = IV[0] | 0;
|
|
||||||
private B = IV[1] | 0;
|
|
||||||
private C = IV[2] | 0;
|
|
||||||
private D = IV[3] | 0;
|
|
||||||
constructor() {
|
|
||||||
super(64, 16, 8, true);
|
|
||||||
}
|
|
||||||
protected get(): [number, number, number, number] {
|
|
||||||
const { A, B, C, D } = this;
|
|
||||||
return [A, B, C, D];
|
|
||||||
}
|
|
||||||
protected set(A: number, B: number, C: number, D: number) {
|
|
||||||
this.A = A | 0;
|
|
||||||
this.B = B | 0;
|
|
||||||
this.C = C | 0;
|
|
||||||
this.D = D | 0;
|
|
||||||
}
|
|
||||||
protected process(view: DataView, offset: number): void {
|
|
||||||
for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true);
|
|
||||||
// Compression function main loop, 64 rounds
|
|
||||||
let { A, B, C, D } = this;
|
|
||||||
for (let i = 0; i < 64; i++) {
|
|
||||||
// eslint-disable-next-line one-var, one-var-declaration-per-line
|
|
||||||
let F, g, s;
|
|
||||||
if (i < 16) {
|
|
||||||
// eslint-disable-next-line new-cap
|
|
||||||
F = Chi(B, C, D);
|
|
||||||
g = i;
|
|
||||||
s = [7, 12, 17, 22];
|
|
||||||
} else if (i < 32) {
|
|
||||||
// eslint-disable-next-line new-cap
|
|
||||||
F = Chi(D, B, C);
|
|
||||||
g = (5 * i + 1) % 16;
|
|
||||||
s = [5, 9, 14, 20];
|
|
||||||
} else if (i < 48) {
|
|
||||||
F = B ^ C ^ D;
|
|
||||||
g = (3 * i + 5) % 16;
|
|
||||||
s = [4, 11, 16, 23];
|
|
||||||
} else {
|
|
||||||
F = C ^ (B | ~D);
|
|
||||||
g = (7 * i) % 16;
|
|
||||||
s = [6, 10, 15, 21];
|
|
||||||
}
|
|
||||||
F = F + A + K[i] + MD5_W[g];
|
|
||||||
A = D;
|
|
||||||
D = C;
|
|
||||||
C = B;
|
|
||||||
B = B + rotl(F, s[i % 4]);
|
|
||||||
}
|
|
||||||
// Add the compressed chunk to the current hash value
|
|
||||||
A = (A + this.A) | 0;
|
|
||||||
B = (B + this.B) | 0;
|
|
||||||
C = (C + this.C) | 0;
|
|
||||||
D = (D + this.D) | 0;
|
|
||||||
this.set(A, B, C, D);
|
|
||||||
}
|
|
||||||
protected roundClean() {
|
|
||||||
MD5_W.fill(0);
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
this.set(0, 0, 0, 0);
|
|
||||||
this.buffer.fill(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const md5 = /* @__PURE__ */ wrapConstructor(() => new MD5());
|
|
@ -9,10 +9,8 @@ import { sha224, sha256 } from '@noble/hashes/sha256';
|
|||||||
import { sha384, sha512 } from '@noble/hashes/sha512';
|
import { sha384, sha512 } from '@noble/hashes/sha512';
|
||||||
import { sha3_256, sha3_512 } from '@noble/hashes/sha3';
|
import { sha3_256, sha3_512 } from '@noble/hashes/sha3';
|
||||||
import { ripemd160 } from '@noble/hashes/ripemd160';
|
import { ripemd160 } from '@noble/hashes/ripemd160';
|
||||||
import { md5 } from './md5';
|
|
||||||
|
|
||||||
export const nobleHashes = new Map(Object.entries({
|
export const nobleHashes = new Map(Object.entries({
|
||||||
md5,
|
|
||||||
sha1,
|
sha1,
|
||||||
sha224,
|
sha224,
|
||||||
sha256,
|
sha256,
|
||||||
|
@ -9,10 +9,39 @@
|
|||||||
* @module crypto
|
* @module crypto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './crypto';
|
import * as cipher from './cipher';
|
||||||
export { getCipherParams } from './cipher';
|
import hash from './hash';
|
||||||
export * from './hash';
|
import mode from './mode';
|
||||||
export * as cipherMode from './cipherMode';
|
import publicKey from './public_key';
|
||||||
export * as publicKey from './public_key';
|
import * as signature from './signature';
|
||||||
export * as signature from './signature';
|
import * as random from './random';
|
||||||
export { getRandomBytes } from './random';
|
import * as pkcs1 from './pkcs1';
|
||||||
|
import * as pkcs5 from './pkcs5';
|
||||||
|
import * as crypto from './crypto';
|
||||||
|
import * as aesKW from './aes_kw';
|
||||||
|
|
||||||
|
// TODO move cfb and gcm to cipher
|
||||||
|
const mod = {
|
||||||
|
/** @see module:crypto/cipher */
|
||||||
|
cipher: cipher,
|
||||||
|
/** @see module:crypto/hash */
|
||||||
|
hash: hash,
|
||||||
|
/** @see module:crypto/mode */
|
||||||
|
mode: mode,
|
||||||
|
/** @see module:crypto/public_key */
|
||||||
|
publicKey: publicKey,
|
||||||
|
/** @see module:crypto/signature */
|
||||||
|
signature: signature,
|
||||||
|
/** @see module:crypto/random */
|
||||||
|
random: random,
|
||||||
|
/** @see module:crypto/pkcs1 */
|
||||||
|
pkcs1: pkcs1,
|
||||||
|
/** @see module:crypto/pkcs5 */
|
||||||
|
pkcs5: pkcs5,
|
||||||
|
/** @see module:crypto/aes_kw */
|
||||||
|
aesKW: aesKW
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(mod, crypto);
|
||||||
|
|
||||||
|
export default mod;
|
||||||
|
@ -23,11 +23,10 @@
|
|||||||
|
|
||||||
import { cfb as nobleAesCfb, unsafe as nobleAesHelpers } from '@noble/ciphers/aes';
|
import { cfb as nobleAesCfb, unsafe as nobleAesHelpers } from '@noble/ciphers/aes';
|
||||||
|
|
||||||
import { transform as streamTransform } from '@openpgp/web-stream-tools';
|
import * as stream from '@openpgp/web-stream-tools';
|
||||||
import util from '../../util';
|
import util from '../../util';
|
||||||
import enums from '../../enums';
|
import enums from '../../enums';
|
||||||
import { getLegacyCipher, getCipherParams } from '../cipher';
|
import { getLegacyCipher, getCipherParams } from '../cipher';
|
||||||
import { getRandomBytes } from '../random';
|
|
||||||
|
|
||||||
const webCrypto = util.getWebCrypto();
|
const webCrypto = util.getWebCrypto();
|
||||||
const nodeCrypto = util.getNodeCrypto();
|
const nodeCrypto = util.getNodeCrypto();
|
||||||
@ -44,20 +43,6 @@ const nodeAlgos = {
|
|||||||
/* twofish is not implemented in OpenSSL */
|
/* twofish is not implemented in OpenSSL */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a random byte prefix for the specified algorithm
|
|
||||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
|
||||||
* @param {module:enums.symmetric} algo - Symmetric encryption algorithm
|
|
||||||
* @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
|
|
||||||
* @async
|
|
||||||
*/
|
|
||||||
export async function getPrefixRandom(algo) {
|
|
||||||
const { blockSize } = getCipherParams(algo);
|
|
||||||
const prefixrandom = await getRandomBytes(blockSize);
|
|
||||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
|
||||||
return util.concat([prefixrandom, repeat]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CFB encryption
|
* CFB encryption
|
||||||
* @param {enums.symmetric} algo - block cipher algorithm
|
* @param {enums.symmetric} algo - block cipher algorithm
|
||||||
@ -99,7 +84,7 @@ export async function encrypt(algo, key, plaintext, iv, config) {
|
|||||||
}
|
}
|
||||||
return ciphertext.subarray(0, j);
|
return ciphertext.subarray(0, j);
|
||||||
};
|
};
|
||||||
return streamTransform(plaintext, process, process);
|
return stream.transform(plaintext, process, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,7 +127,7 @@ export async function decrypt(algo, key, ciphertext, iv) {
|
|||||||
}
|
}
|
||||||
return plaintext.subarray(0, j);
|
return plaintext.subarray(0, j);
|
||||||
};
|
};
|
||||||
return streamTransform(ciphertext, process, process);
|
return stream.transform(ciphertext, process, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebCryptoEncryptor {
|
class WebCryptoEncryptor {
|
||||||
@ -346,10 +331,10 @@ class NobleStreamProcessor {
|
|||||||
async function aesEncrypt(algo, key, pt, iv) {
|
async function aesEncrypt(algo, key, pt, iv) {
|
||||||
if (webCrypto && await WebCryptoEncryptor.isSupported(algo)) { // Chromium does not implement AES with 192-bit keys
|
if (webCrypto && await WebCryptoEncryptor.isSupported(algo)) { // Chromium does not implement AES with 192-bit keys
|
||||||
const cfb = new WebCryptoEncryptor(algo, key, iv);
|
const cfb = new WebCryptoEncryptor(algo, key, iv);
|
||||||
return util.isStream(pt) ? streamTransform(pt, value => cfb.encryptChunk(value), () => cfb.finish()) : cfb.encrypt(pt);
|
return util.isStream(pt) ? stream.transform(pt, value => cfb.encryptChunk(value), () => cfb.finish()) : cfb.encrypt(pt);
|
||||||
} else if (util.isStream(pt)) { // async callbacks are not accepted by streamTransform unless the input is a stream
|
} else if (util.isStream(pt)) { // async callbacks are not accepted by stream.transform unless the input is a stream
|
||||||
const cfb = new NobleStreamProcessor(true, algo, key, iv);
|
const cfb = new NobleStreamProcessor(true, algo, key, iv);
|
||||||
return streamTransform(pt, value => cfb.processChunk(value), () => cfb.finish());
|
return stream.transform(pt, value => cfb.processChunk(value), () => cfb.finish());
|
||||||
}
|
}
|
||||||
return nobleAesCfb(key, iv).encrypt(pt);
|
return nobleAesCfb(key, iv).encrypt(pt);
|
||||||
}
|
}
|
||||||
@ -357,7 +342,7 @@ async function aesEncrypt(algo, key, pt, iv) {
|
|||||||
async function aesDecrypt(algo, key, ct, iv) {
|
async function aesDecrypt(algo, key, ct, iv) {
|
||||||
if (util.isStream(ct)) {
|
if (util.isStream(ct)) {
|
||||||
const cfb = new NobleStreamProcessor(false, algo, key, iv);
|
const cfb = new NobleStreamProcessor(false, algo, key, iv);
|
||||||
return streamTransform(ct, value => cfb.processChunk(value), () => cfb.finish());
|
return stream.transform(ct, value => cfb.processChunk(value), () => cfb.finish());
|
||||||
}
|
}
|
||||||
return nobleAesCfb(key, iv).decrypt(ct);
|
return nobleAesCfb(key, iv).decrypt(ct);
|
||||||
}
|
}
|
||||||
@ -374,11 +359,11 @@ const getUint32Array = arr => new Uint32Array(arr.buffer, arr.byteOffset, Math.f
|
|||||||
function nodeEncrypt(algo, key, pt, iv) {
|
function nodeEncrypt(algo, key, pt, iv) {
|
||||||
const algoName = enums.read(enums.symmetric, algo);
|
const algoName = enums.read(enums.symmetric, algo);
|
||||||
const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algoName], key, iv);
|
const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algoName], key, iv);
|
||||||
return streamTransform(pt, value => new Uint8Array(cipherObj.update(value)));
|
return stream.transform(pt, value => new Uint8Array(cipherObj.update(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeDecrypt(algo, key, ct, iv) {
|
function nodeDecrypt(algo, key, ct, iv) {
|
||||||
const algoName = enums.read(enums.symmetric, algo);
|
const algoName = enums.read(enums.symmetric, algo);
|
||||||
const decipherObj = new nodeCrypto.createDecipheriv(nodeAlgos[algoName], key, iv);
|
const decipherObj = new nodeCrypto.createDecipheriv(nodeAlgos[algoName], key, iv);
|
||||||
return streamTransform(ct, value => new Uint8Array(decipherObj.update(value)));
|
return stream.transform(ct, value => new Uint8Array(decipherObj.update(value)));
|
||||||
}
|
}
|
21
src/crypto/mode/index.js
Normal file
21
src/crypto/mode/index.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Cipher modes
|
||||||
|
* @module crypto/mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as cfb from './cfb';
|
||||||
|
import eax from './eax';
|
||||||
|
import ocb from './ocb';
|
||||||
|
import gcm from './gcm';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/** @see module:crypto/mode/cfb */
|
||||||
|
cfb: cfb,
|
||||||
|
/** @see module:crypto/mode/gcm */
|
||||||
|
gcm: gcm,
|
||||||
|
experimentalGCM: gcm,
|
||||||
|
/** @see module:crypto/mode/eax */
|
||||||
|
eax: eax,
|
||||||
|
/** @see module:crypto/mode/ocb */
|
||||||
|
ocb: ocb
|
||||||
|
};
|
@ -73,8 +73,9 @@ async function OCB(cipher, key) {
|
|||||||
// `encipher` and `decipher` cannot be async, since `crypt` shares state across calls,
|
// `encipher` and `decipher` cannot be async, since `crypt` shares state across calls,
|
||||||
// hence its execution cannot be broken up.
|
// hence its execution cannot be broken up.
|
||||||
// As a result, WebCrypto cannot currently be used for `encipher`.
|
// As a result, WebCrypto cannot currently be used for `encipher`.
|
||||||
const encipher = block => nobleAesCbc(key, zeroBlock, { disablePadding: true }).encrypt(block);
|
const aes = nobleAesCbc(key, zeroBlock, { disablePadding: true });
|
||||||
const decipher = block => nobleAesCbc(key, zeroBlock, { disablePadding: true }).decrypt(block);
|
const encipher = block => aes.encrypt(block);
|
||||||
|
const decipher = block => aes.decrypt(block);
|
||||||
let mask;
|
let mask;
|
||||||
|
|
||||||
constructKeyVariables(cipher, key);
|
constructKeyVariables(cipher, key);
|
@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { getRandomBytes } from './random';
|
import { getRandomBytes } from './random';
|
||||||
import { getHashByteLength } from './hash';
|
import hash from './hash';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,7 +134,7 @@ export function emeDecode(encoded, randomPayload) {
|
|||||||
*/
|
*/
|
||||||
export function emsaEncode(algo, hashed, emLen) {
|
export function emsaEncode(algo, hashed, emLen) {
|
||||||
let i;
|
let i;
|
||||||
if (hashed.length !== getHashByteLength(algo)) {
|
if (hashed.length !== hash.getHashByteLength(algo)) {
|
||||||
throw new Error('Invalid hash length');
|
throw new Error('Invalid hash length');
|
||||||
}
|
}
|
||||||
// produce an ASN.1 DER value for the hash function used.
|
// produce an ASN.1 DER value for the hash function used.
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding } from './oid_curves';
|
import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding } from './oid_curves';
|
||||||
import * as aesKW from '../../aes_kw';
|
import * as aesKW from '../../aes_kw';
|
||||||
import { computeDigest } from '../../hash';
|
import hash from '../../hash';
|
||||||
import enums from '../../../enums';
|
import enums from '../../../enums';
|
||||||
import util from '../../../util';
|
import util from '../../../util';
|
||||||
import { b64ToUint8Array } from '../../../encoding/base64';
|
import { b64ToUint8Array } from '../../../encoding/base64';
|
||||||
@ -72,7 +72,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
|
|||||||
for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
|
for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
|
||||||
X = X.subarray(0, i + 1);
|
X = X.subarray(0, i + 1);
|
||||||
}
|
}
|
||||||
const digest = await computeDigest(hashAlgo, util.concatUint8Array([
|
const digest = await hash.digest(hashAlgo, util.concatUint8Array([
|
||||||
new Uint8Array([0, 0, 0, 1]),
|
new Uint8Array([0, 0, 0, 1]),
|
||||||
X,
|
X,
|
||||||
param
|
param
|
||||||
|
@ -11,7 +11,6 @@ import enums from '../../../enums';
|
|||||||
import util from '../../../util';
|
import util from '../../../util';
|
||||||
import computeHKDF from '../../hkdf';
|
import computeHKDF from '../../hkdf';
|
||||||
import { getCipherParams } from '../../cipher';
|
import { getCipherParams } from '../../cipher';
|
||||||
import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64';
|
|
||||||
|
|
||||||
const HKDF_INFO = {
|
const HKDF_INFO = {
|
||||||
x25519: util.encodeUTF8('OpenPGP X25519'),
|
x25519: util.encodeUTF8('OpenPGP X25519'),
|
||||||
@ -25,27 +24,12 @@ const HKDF_INFO = {
|
|||||||
*/
|
*/
|
||||||
export async function generate(algo) {
|
export async function generate(algo) {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519: {
|
||||||
try {
|
// k stays in little-endian, unlike legacy ECDH over curve25519
|
||||||
const webCrypto = util.getWebCrypto();
|
const k = getRandomBytes(32);
|
||||||
const webCryptoKey = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']);
|
const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k);
|
||||||
|
return { A, k };
|
||||||
const privateKey = await webCrypto.exportKey('jwk', webCryptoKey.privateKey);
|
}
|
||||||
const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey);
|
|
||||||
|
|
||||||
return {
|
|
||||||
A: new Uint8Array(b64ToUint8Array(publicKey.x)),
|
|
||||||
k: b64ToUint8Array(privateKey.d)
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
if (err.name !== 'NotSupportedError') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
// k stays in little-endian, unlike legacy ECDH over curve25519
|
|
||||||
const k = getRandomBytes(32);
|
|
||||||
const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k);
|
|
||||||
return { A, k };
|
|
||||||
}
|
|
||||||
|
|
||||||
case enums.publicKey.x448: {
|
case enums.publicKey.x448: {
|
||||||
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
||||||
@ -187,32 +171,13 @@ export function getPayloadSize(algo) {
|
|||||||
*/
|
*/
|
||||||
export async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
export async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519: {
|
||||||
try {
|
const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo));
|
||||||
const webCrypto = util.getWebCrypto();
|
const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA);
|
||||||
const jwk = publicKeyToJWK(algo, recipientA);
|
assertNonZeroArray(sharedSecret);
|
||||||
const ephemeralKeyPair = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']);
|
const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
||||||
const recipientPublicKey = await webCrypto.importKey('jwk', jwk, 'X25519', false, []);
|
return { ephemeralPublicKey, sharedSecret };
|
||||||
const sharedSecretBuffer = await webCrypto.deriveBits(
|
}
|
||||||
{ name: 'X25519', public: recipientPublicKey },
|
|
||||||
ephemeralKeyPair.privateKey,
|
|
||||||
getPayloadSize(algo) * 8 // in bits
|
|
||||||
);
|
|
||||||
const ephemeralPublicKeyJwt = await webCrypto.exportKey('jwk', ephemeralKeyPair.publicKey);
|
|
||||||
return {
|
|
||||||
sharedSecret: new Uint8Array(sharedSecretBuffer),
|
|
||||||
ephemeralPublicKey: new Uint8Array(b64ToUint8Array(ephemeralPublicKeyJwt.x))
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
if (err.name !== 'NotSupportedError') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo));
|
|
||||||
const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA);
|
|
||||||
assertNonZeroArray(sharedSecret);
|
|
||||||
const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
|
||||||
return { ephemeralPublicKey, sharedSecret };
|
|
||||||
}
|
|
||||||
case enums.publicKey.x448: {
|
case enums.publicKey.x448: {
|
||||||
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
||||||
const ephemeralSecretKey = x448.utils.randomPrivateKey();
|
const ephemeralSecretKey = x448.utils.randomPrivateKey();
|
||||||
@ -228,27 +193,11 @@ export async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
|||||||
|
|
||||||
export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) {
|
export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.x25519:
|
case enums.publicKey.x25519: {
|
||||||
try {
|
const sharedSecret = x25519.scalarMult(k, ephemeralPublicKey);
|
||||||
const webCrypto = util.getWebCrypto();
|
assertNonZeroArray(sharedSecret);
|
||||||
const privateKeyJWK = privateKeyToJWK(algo, A, k);
|
return sharedSecret;
|
||||||
const ephemeralPublicKeyJWK = publicKeyToJWK(algo, ephemeralPublicKey);
|
}
|
||||||
const privateKey = await webCrypto.importKey('jwk', privateKeyJWK, 'X25519', false, ['deriveKey', 'deriveBits']);
|
|
||||||
const ephemeralPublicKeyReference = await webCrypto.importKey('jwk', ephemeralPublicKeyJWK, 'X25519', false, []);
|
|
||||||
const sharedSecretBuffer = await webCrypto.deriveBits(
|
|
||||||
{ name: 'X25519', public: ephemeralPublicKeyReference },
|
|
||||||
privateKey,
|
|
||||||
getPayloadSize(algo) * 8 // in bits
|
|
||||||
);
|
|
||||||
return new Uint8Array(sharedSecretBuffer);
|
|
||||||
} catch (err) {
|
|
||||||
if (err.name !== 'NotSupportedError') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
const sharedSecret = x25519.scalarMult(k, ephemeralPublicKey);
|
|
||||||
assertNonZeroArray(sharedSecret);
|
|
||||||
return sharedSecret;
|
|
||||||
}
|
|
||||||
case enums.publicKey.x448: {
|
case enums.publicKey.x448: {
|
||||||
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
||||||
const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey);
|
const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey);
|
||||||
@ -275,32 +224,3 @@ function assertNonZeroArray(sharedSecret) {
|
|||||||
throw new Error('Unexpected low order point');
|
throw new Error('Unexpected low order point');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function publicKeyToJWK(algo, publicKey) {
|
|
||||||
switch (algo) {
|
|
||||||
case enums.publicKey.x25519: {
|
|
||||||
const jwk = {
|
|
||||||
kty: 'OKP',
|
|
||||||
crv: 'X25519',
|
|
||||||
x: uint8ArrayToB64(publicKey, true),
|
|
||||||
ext: true
|
|
||||||
};
|
|
||||||
return jwk;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported ECDH algorithm');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function privateKeyToJWK(algo, publicKey, privateKey) {
|
|
||||||
switch (algo) {
|
|
||||||
case enums.publicKey.x25519: {
|
|
||||||
const jwk = publicKeyToJWK(algo, publicKey);
|
|
||||||
jwk.d = uint8ArrayToB64(privateKey, true);
|
|
||||||
return jwk;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported ECDH algorithm');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import enums from '../../../enums';
|
import enums from '../../../enums';
|
||||||
import util from '../../../util';
|
import util from '../../../util';
|
||||||
import { getRandomBytes } from '../../random';
|
import { getRandomBytes } from '../../random';
|
||||||
import { computeDigest } from '../../hash';
|
import hash from '../../hash';
|
||||||
import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves, checkPublicPointEnconding } from './oid_curves';
|
import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves, checkPublicPointEnconding } from './oid_curves';
|
||||||
import { bigIntToUint8Array } from '../../biginteger';
|
import { bigIntToUint8Array } from '../../biginteger';
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ export async function validateParams(oid, Q, d) {
|
|||||||
case 'node': {
|
case 'node': {
|
||||||
const message = getRandomBytes(8);
|
const message = getRandomBytes(8);
|
||||||
const hashAlgo = enums.hash.sha256;
|
const hashAlgo = enums.hash.sha256;
|
||||||
const hashed = await computeDigest(hashAlgo, message);
|
const hashed = await hash.digest(hashAlgo, message);
|
||||||
try {
|
try {
|
||||||
const signature = await sign(oid, hashAlgo, message, Q, d, hashed);
|
const signature = await sign(oid, hashAlgo, message, Q, d, hashed);
|
||||||
// eslint-disable-next-line @typescript-eslint/return-await
|
// eslint-disable-next-line @typescript-eslint/return-await
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import ed25519 from '@openpgp/tweetnacl';
|
import ed25519 from '@openpgp/tweetnacl';
|
||||||
import util from '../../../util';
|
import util from '../../../util';
|
||||||
import enums from '../../../enums';
|
import enums from '../../../enums';
|
||||||
import { getHashByteLength } from '../../hash';
|
import hash from '../../hash';
|
||||||
import { getRandomBytes } from '../../random';
|
import { getRandomBytes } from '../../random';
|
||||||
import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64';
|
import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64';
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ export async function generate(algo) {
|
|||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
||||||
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo(algo))) {
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||||
// Enforce digest sizes:
|
// Enforce digest sizes:
|
||||||
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
||||||
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
||||||
@ -131,7 +131,7 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe
|
|||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
||||||
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo(algo))) {
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||||
// Enforce digest sizes:
|
// Enforce digest sizes:
|
||||||
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
||||||
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
import nacl from '@openpgp/tweetnacl';
|
import nacl from '@openpgp/tweetnacl';
|
||||||
import util from '../../../util';
|
import util from '../../../util';
|
||||||
import enums from '../../../enums';
|
import enums from '../../../enums';
|
||||||
import { getHashByteLength } from '../../hash';
|
import hash from '../../hash';
|
||||||
import { CurveWithOID, checkPublicPointEnconding } from './oid_curves';
|
import { CurveWithOID, checkPublicPointEnconding } from './oid_curves';
|
||||||
import { sign as eddsaSign, verify as eddsaVerify } from './eddsa';
|
import { sign as eddsaSign, verify as eddsaVerify } from './eddsa';
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ import { sign as eddsaSign, verify as eddsaVerify } from './eddsa';
|
|||||||
export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
||||||
const curve = new CurveWithOID(oid);
|
const curve = new CurveWithOID(oid);
|
||||||
checkPublicPointEnconding(curve, publicKey);
|
checkPublicPointEnconding(curve, publicKey);
|
||||||
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
||||||
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
||||||
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
||||||
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
||||||
@ -74,7 +74,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
|
|||||||
export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
||||||
const curve = new CurveWithOID(oid);
|
const curve = new CurveWithOID(oid);
|
||||||
checkPublicPointEnconding(curve, publicKey);
|
checkPublicPointEnconding(curve, publicKey);
|
||||||
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
||||||
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
||||||
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
||||||
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
||||||
|
@ -3,7 +3,18 @@
|
|||||||
* @module crypto/public_key
|
* @module crypto/public_key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * as rsa from './rsa';
|
import * as rsa from './rsa';
|
||||||
export * as elgamal from './elgamal';
|
import * as elgamal from './elgamal';
|
||||||
export * as elliptic from './elliptic';
|
import * as elliptic from './elliptic';
|
||||||
export * as dsa from './dsa';
|
import * as dsa from './dsa';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/** @see module:crypto/public_key/rsa */
|
||||||
|
rsa: rsa,
|
||||||
|
/** @see module:crypto/public_key/elgamal */
|
||||||
|
elgamal: elgamal,
|
||||||
|
/** @see module:crypto/public_key/elliptic */
|
||||||
|
elliptic: elliptic,
|
||||||
|
/** @see module:crypto/public_key/dsa */
|
||||||
|
dsa: dsa
|
||||||
|
};
|
||||||
|
@ -26,7 +26,7 @@ import { uint8ArrayToB64, b64ToUint8Array } from '../../encoding/base64';
|
|||||||
import { emsaEncode, emeEncode, emeDecode } from '../pkcs1';
|
import { emsaEncode, emeEncode, emeDecode } from '../pkcs1';
|
||||||
import enums from '../../enums';
|
import enums from '../../enums';
|
||||||
import { bigIntToNumber, bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger';
|
import { bigIntToNumber, bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger';
|
||||||
import { getHashByteLength } from '../hash';
|
import hash from '../hash';
|
||||||
|
|
||||||
const webCrypto = util.getWebCrypto();
|
const webCrypto = util.getWebCrypto();
|
||||||
const nodeCrypto = util.getNodeCrypto();
|
const nodeCrypto = util.getNodeCrypto();
|
||||||
@ -46,7 +46,7 @@ const _1n = BigInt(1);
|
|||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
||||||
if (getHashByteLength(hashAlgo) >= n.length) {
|
if (hash.getHashByteLength(hashAlgo) >= n.length) {
|
||||||
// Throw here instead of `emsaEncode` below, to provide a clearer and consistent error
|
// Throw here instead of `emsaEncode` below, to provide a clearer and consistent error
|
||||||
// e.g. if a 512-bit RSA key is used with a SHA-512 digest.
|
// e.g. if a 512-bit RSA key is used with a SHA-512 digest.
|
||||||
// The size limit is actually slightly different but here we only care about throwing
|
// The size limit is actually slightly different but here we only care about throwing
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @module crypto/signature
|
* @module crypto/signature
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { elliptic, rsa, dsa } from './public_key';
|
import publicKey from './public_key';
|
||||||
import enums from '../enums';
|
import enums from '../enums';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
import { UnsupportedError } from '../packet/packet';
|
import { UnsupportedError } from '../packet/packet';
|
||||||
@ -61,7 +61,7 @@ export function parseSignatureParams(algo, signature) {
|
|||||||
// - 114 octets of the native signature
|
// - 114 octets of the native signature
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448: {
|
case enums.publicKey.ed448: {
|
||||||
const rsSize = 2 * elliptic.eddsa.getPayloadSize(algo);
|
const rsSize = 2 * publicKey.elliptic.eddsa.getPayloadSize(algo);
|
||||||
const RS = util.readExactSubarray(signature, read, read + rsSize); read += RS.length;
|
const RS = util.readExactSubarray(signature, read, read + rsSize); read += RS.length;
|
||||||
return { read, signatureParams: { RS } };
|
return { read, signatureParams: { RS } };
|
||||||
}
|
}
|
||||||
@ -92,34 +92,34 @@ export async function verify(algo, hashAlgo, signature, publicParams, data, hash
|
|||||||
case enums.publicKey.rsaSign: {
|
case enums.publicKey.rsaSign: {
|
||||||
const { n, e } = publicParams;
|
const { n, e } = publicParams;
|
||||||
const s = util.leftPad(signature.s, n.length); // padding needed for webcrypto and node crypto
|
const s = util.leftPad(signature.s, n.length); // padding needed for webcrypto and node crypto
|
||||||
return rsa.verify(hashAlgo, data, s, n, e, hashed);
|
return publicKey.rsa.verify(hashAlgo, data, s, n, e, hashed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.dsa: {
|
case enums.publicKey.dsa: {
|
||||||
const { g, p, q, y } = publicParams;
|
const { g, p, q, y } = publicParams;
|
||||||
const { r, s } = signature; // no need to pad, since we always handle them as BigIntegers
|
const { r, s } = signature; // no need to pad, since we always handle them as BigIntegers
|
||||||
return dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
|
return publicKey.dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ecdsa: {
|
case enums.publicKey.ecdsa: {
|
||||||
const { oid, Q } = publicParams;
|
const { oid, Q } = publicParams;
|
||||||
const curveSize = new elliptic.CurveWithOID(oid).payloadSize;
|
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||||
// padding needed for webcrypto
|
// padding needed for webcrypto
|
||||||
const r = util.leftPad(signature.r, curveSize);
|
const r = util.leftPad(signature.r, curveSize);
|
||||||
const s = util.leftPad(signature.s, curveSize);
|
const s = util.leftPad(signature.s, curveSize);
|
||||||
return elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.eddsaLegacy: {
|
case enums.publicKey.eddsaLegacy: {
|
||||||
const { oid, Q } = publicParams;
|
const { oid, Q } = publicParams;
|
||||||
const curveSize = new elliptic.CurveWithOID(oid).payloadSize;
|
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||||
// When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
// When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
||||||
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
||||||
const r = util.leftPad(signature.r, curveSize);
|
const r = util.leftPad(signature.r, curveSize);
|
||||||
const s = util.leftPad(signature.s, curveSize);
|
const s = util.leftPad(signature.s, curveSize);
|
||||||
return elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448: {
|
case enums.publicKey.ed448: {
|
||||||
const { A } = publicParams;
|
const { A } = publicParams;
|
||||||
return elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown signature algorithm.');
|
throw new Error('Unknown signature algorithm.');
|
||||||
@ -150,31 +150,31 @@ export async function sign(algo, hashAlgo, publicKeyParams, privateKeyParams, da
|
|||||||
case enums.publicKey.rsaSign: {
|
case enums.publicKey.rsaSign: {
|
||||||
const { n, e } = publicKeyParams;
|
const { n, e } = publicKeyParams;
|
||||||
const { d, p, q, u } = privateKeyParams;
|
const { d, p, q, u } = privateKeyParams;
|
||||||
const s = await rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
|
const s = await publicKey.rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
|
||||||
return { s };
|
return { s };
|
||||||
}
|
}
|
||||||
case enums.publicKey.dsa: {
|
case enums.publicKey.dsa: {
|
||||||
const { g, p, q } = publicKeyParams;
|
const { g, p, q } = publicKeyParams;
|
||||||
const { x } = privateKeyParams;
|
const { x } = privateKeyParams;
|
||||||
return dsa.sign(hashAlgo, hashed, g, p, q, x);
|
return publicKey.dsa.sign(hashAlgo, hashed, g, p, q, x);
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal:
|
case enums.publicKey.elgamal:
|
||||||
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
|
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
|
||||||
case enums.publicKey.ecdsa: {
|
case enums.publicKey.ecdsa: {
|
||||||
const { oid, Q } = publicKeyParams;
|
const { oid, Q } = publicKeyParams;
|
||||||
const { d } = privateKeyParams;
|
const { d } = privateKeyParams;
|
||||||
return elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.eddsaLegacy: {
|
case enums.publicKey.eddsaLegacy: {
|
||||||
const { oid, Q } = publicKeyParams;
|
const { oid, Q } = publicKeyParams;
|
||||||
const { seed } = privateKeyParams;
|
const { seed } = privateKeyParams;
|
||||||
return elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
||||||
}
|
}
|
||||||
case enums.publicKey.ed25519:
|
case enums.publicKey.ed25519:
|
||||||
case enums.publicKey.ed448: {
|
case enums.publicKey.ed448: {
|
||||||
const { A } = publicKeyParams;
|
const { A } = publicKeyParams;
|
||||||
const { seed } = privateKeyParams;
|
const { seed } = privateKeyParams;
|
||||||
return elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown signature algorithm.');
|
throw new Error('Unknown signature algorithm.');
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
import { transform as streamTransform, transformPair as streamTransformPair, getReader as streamGetReader, getWriter as streamGetWriter, isArrayStream, readToEnd as streamReadToEnd, passiveClone as streamPassiveClone } from '@openpgp/web-stream-tools';
|
import * as stream from '@openpgp/web-stream-tools';
|
||||||
import { encode as encodeBase64, decode as decodeBase64 } from './base64';
|
import * as base64 from './base64';
|
||||||
import enums from '../enums';
|
import enums from '../enums';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
import defaultConfig from '../config';
|
import defaultConfig from '../config';
|
||||||
@ -115,7 +115,7 @@ function addheader(customComment, config) {
|
|||||||
*/
|
*/
|
||||||
function getCheckSum(data) {
|
function getCheckSum(data) {
|
||||||
const crc = createcrc24(data);
|
const crc = createcrc24(data);
|
||||||
return encodeBase64(crc);
|
return base64.encode(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview
|
// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview
|
||||||
@ -163,7 +163,7 @@ const isLittleEndian = (function() {
|
|||||||
*/
|
*/
|
||||||
function createcrc24(input) {
|
function createcrc24(input) {
|
||||||
let crc = 0xCE04B7;
|
let crc = 0xCE04B7;
|
||||||
return streamTransform(input, value => {
|
return stream.transform(input, value => {
|
||||||
const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0;
|
const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0;
|
||||||
const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32);
|
const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32);
|
||||||
for (let i = 0; i < len32; i++) {
|
for (let i = 0; i < len32; i++) {
|
||||||
@ -239,8 +239,8 @@ export function unarmor(input) {
|
|||||||
let headersDone;
|
let headersDone;
|
||||||
let text = [];
|
let text = [];
|
||||||
let textDone;
|
let textDone;
|
||||||
const data = decodeBase64(streamTransformPair(input, async (readable, writable) => {
|
const data = base64.decode(stream.transformPair(input, async (readable, writable) => {
|
||||||
const reader = streamGetReader(readable);
|
const reader = stream.getReader(readable);
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
let line = await reader.readLine();
|
let line = await reader.readLine();
|
||||||
@ -284,7 +284,7 @@ export function unarmor(input) {
|
|||||||
reject(e);
|
reject(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const writer = streamGetWriter(writable);
|
const writer = stream.getWriter(writable);
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
await writer.ready;
|
await writer.ready;
|
||||||
@ -319,8 +319,8 @@ export function unarmor(input) {
|
|||||||
reject(e);
|
reject(e);
|
||||||
}
|
}
|
||||||
}).then(async result => {
|
}).then(async result => {
|
||||||
if (isArrayStream(result.data)) {
|
if (stream.isArrayStream(result.data)) {
|
||||||
result.data = await streamReadToEnd(result.data);
|
result.data = await stream.readToEnd(result.data);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -350,21 +350,21 @@ export function armor(messageType, body, partIndex, partTotal, customComment, em
|
|||||||
}
|
}
|
||||||
// unless explicitly forbidden by the spec, we need to include the checksum to work around a GnuPG bug
|
// unless explicitly forbidden by the spec, we need to include the checksum to work around a GnuPG bug
|
||||||
// where data fails to be decoded if the base64 ends with no padding chars (=) (see https://dev.gnupg.org/T7071)
|
// where data fails to be decoded if the base64 ends with no padding chars (=) (see https://dev.gnupg.org/T7071)
|
||||||
const maybeBodyClone = emitChecksum && streamPassiveClone(body);
|
const maybeBodyClone = emitChecksum && stream.passiveClone(body);
|
||||||
|
|
||||||
const result = [];
|
const result = [];
|
||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
case enums.armor.multipartSection:
|
case enums.armor.multipartSection:
|
||||||
result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
|
result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
|
result.push('-----END PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
|
||||||
break;
|
break;
|
||||||
case enums.armor.multipartLast:
|
case enums.armor.multipartLast:
|
||||||
result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '-----\n');
|
result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP MESSAGE, PART ' + partIndex + '-----\n');
|
result.push('-----END PGP MESSAGE, PART ' + partIndex + '-----\n');
|
||||||
break;
|
break;
|
||||||
@ -374,35 +374,35 @@ export function armor(messageType, body, partIndex, partTotal, customComment, em
|
|||||||
result.push(text.replace(/^-/mg, '- -'));
|
result.push(text.replace(/^-/mg, '- -'));
|
||||||
result.push('\n-----BEGIN PGP SIGNATURE-----\n');
|
result.push('\n-----BEGIN PGP SIGNATURE-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP SIGNATURE-----\n');
|
result.push('-----END PGP SIGNATURE-----\n');
|
||||||
break;
|
break;
|
||||||
case enums.armor.message:
|
case enums.armor.message:
|
||||||
result.push('-----BEGIN PGP MESSAGE-----\n');
|
result.push('-----BEGIN PGP MESSAGE-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP MESSAGE-----\n');
|
result.push('-----END PGP MESSAGE-----\n');
|
||||||
break;
|
break;
|
||||||
case enums.armor.publicKey:
|
case enums.armor.publicKey:
|
||||||
result.push('-----BEGIN PGP PUBLIC KEY BLOCK-----\n');
|
result.push('-----BEGIN PGP PUBLIC KEY BLOCK-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP PUBLIC KEY BLOCK-----\n');
|
result.push('-----END PGP PUBLIC KEY BLOCK-----\n');
|
||||||
break;
|
break;
|
||||||
case enums.armor.privateKey:
|
case enums.armor.privateKey:
|
||||||
result.push('-----BEGIN PGP PRIVATE KEY BLOCK-----\n');
|
result.push('-----BEGIN PGP PRIVATE KEY BLOCK-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP PRIVATE KEY BLOCK-----\n');
|
result.push('-----END PGP PRIVATE KEY BLOCK-----\n');
|
||||||
break;
|
break;
|
||||||
case enums.armor.signature:
|
case enums.armor.signature:
|
||||||
result.push('-----BEGIN PGP SIGNATURE-----\n');
|
result.push('-----BEGIN PGP SIGNATURE-----\n');
|
||||||
result.push(addheader(customComment, config));
|
result.push(addheader(customComment, config));
|
||||||
result.push(encodeBase64(body));
|
result.push(base64.encode(body));
|
||||||
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone));
|
||||||
result.push('-----END PGP SIGNATURE-----\n');
|
result.push('-----END PGP SIGNATURE-----\n');
|
||||||
break;
|
break;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user