diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..09e23fb --- /dev/null +++ b/.eslintrc @@ -0,0 +1,50 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-style": "warn", + "indent": ["error", 2], + "multiline-comment-style": "off", + "sort-keys": "off", + }, + + "overrides": [ + { + "files": "browser/index.js", + "rules": { + "func-name-matching": "off", + "max-statements-per-line": "off", + "no-underscore-dangle": "warn", + }, + }, + { + "files": "browser/verify.js", + "rules": { + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "off", + "no-param-reassign": "warn", + "no-plusplus": "warn", + "no-use-before-define": "warn", + } + }, + { + "files": "browser/sign.js", + "rules": { + "max-params": "off", + "max-statements-per-line": "off", + "no-param-reassign": "warn", + "no-plusplus": "warn", + "no-use-before-define": "warn", + } + }, + { + "files": "test/*.js", + "rules": { + "max-lines-per-function": "off", + }, + }, + ], +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8cf3067 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/browserify-sign +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/node-aught.yml b/.github/workflows/node-aught.yml new file mode 100644 index 0000000..3b7e794 --- /dev/null +++ b/.github/workflows/node-aught.yml @@ -0,0 +1,18 @@ +name: 'Tests: node.js 0.12 - 10' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 0.12 < 10' + type: minors + command: npm run tests-only + + node: + name: 'node 0.12 - 10' + needs: [tests] + runs-on: ubuntu-latest + steps: + - run: true diff --git a/.github/workflows/node-pretest.yml b/.github/workflows/node-pretest.yml new file mode 100644 index 0000000..765edf7 --- /dev/null +++ b/.github/workflows/node-pretest.yml @@ -0,0 +1,7 @@ +name: 'Tests: pretest/posttest' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/pretest.yml@main diff --git a/.github/workflows/node-tens.yml b/.github/workflows/node-tens.yml new file mode 100644 index 0000000..70f55da --- /dev/null +++ b/.github/workflows/node-tens.yml @@ -0,0 +1,18 @@ +name: 'Tests: node.js >= 10' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 10' + type: minors + command: npm run tests-only + + node: + name: 'node >= 10' + needs: [tests] + runs-on: ubuntu-latest + steps: + - run: true diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml new file mode 100644 index 0000000..b9e1712 --- /dev/null +++ b/.github/workflows/rebase.yml @@ -0,0 +1,9 @@ +name: Automatic Rebase + +on: [pull_request_target] + +jobs: + _: + uses: ljharb/actions/.github/workflows/rebase.yml@main + secrets: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/require-allow-edits.yml b/.github/workflows/require-allow-edits.yml new file mode 100644 index 0000000..7b842f8 --- /dev/null +++ b/.github/workflows/require-allow-edits.yml @@ -0,0 +1,12 @@ +name: Require “Allow Edits” + +on: [pull_request_target] + +jobs: + _: + name: "Require “Allow Edits”" + + runs-on: ubuntu-latest + + steps: + - uses: ljharb/require-allow-edits@main diff --git a/.gitignore b/.gitignore index e4df30e..e1e972d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,12 @@ +# gitignore .nyc_output node_modules npm-debug.log + +# Only apps should have lockfiles +npm-shrinkwrap.json +package-lock.json +yarn.lock + +.npmignore diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..eacea13 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +package-lock=false +allow-same-version=true +message=v%s diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fc40b1c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -sudo: false -language: node_js -node_js: - - "0.11" - - "0.12" - - "4" - - "5" - - "6" - - "7" -matrix: - include: - - node_js: "4" - env: TEST_SUITE=lint -env: - - TEST_SUITE=unit -script: npm run-script $TEST_SUITE diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b3a8ad4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,316 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v4.2.3](https://github.com/browserify/browserify-sign/compare/v4.2.2...v4.2.3) - 2024-03-05 + +### Commits + +- [patch] widen support to 0.12 [`9247adf`](https://github.com/browserify/browserify-sign/commit/9247adfd261ededfec1c036c9d8f36c4e9f87c0e) +- [patch] drop minimum node support to v1 [`4d0ee49`](https://github.com/browserify/browserify-sign/commit/4d0ee49ae2dc238b877dce9aed7e23fb4cb5088d) +- [Dev Deps] update `aud`, `npmignore`, `tape` [`87f3a35`](https://github.com/browserify/browserify-sign/commit/87f3a35a587b377da2c1987af8d41c57b5afe0a5) +- [actions] remove redundant finisher [`37a4758`](https://github.com/browserify/browserify-sign/commit/37a475856843b7d1b2403fdafac0024ba252e579) +- [Deps] pin `hash-base` to ~3.0, due to a breaking change [`9e2bf12`](https://github.com/browserify/browserify-sign/commit/9e2bf122b70970cb92f69d53e963f18299f14d66) +- [Deps] update `parse-asn1 [`f427270`](https://github.com/browserify/browserify-sign/commit/f427270ac11dc6be29f87d7afb046c16376a5a9c) +- [Deps] update `elliptic` [`fb261ce`](https://github.com/browserify/browserify-sign/commit/fb261cea57f92b3d98bc4d8bc6228c43a5de2e91) +- [Deps] pin `elliptic` due to a breaking change [`168e16f`](https://github.com/browserify/browserify-sign/commit/168e16fcb54886a0281b0c983e1482a097042684) + +## [v4.2.2](https://github.com/browserify/browserify-sign/compare/v4.2.1...v4.2.2) - 2023-10-25 + +### Fixed + +- [Tests] log when openssl doesn't support cipher [`#37`](https://github.com/browserify/browserify-sign/issues/37) + +### Commits + +- Only apps should have lockfiles [`09a8995`](https://github.com/browserify/browserify-sign/commit/09a89959393b3c89fedd4f7f3bafa4fec44371d7) +- [eslint] switch to eslint [`83fe463`](https://github.com/browserify/browserify-sign/commit/83fe46374b819e959d56d2c0b931308f7451a664) +- [meta] add `npmignore` and `auto-changelog` [`4418183`](https://github.com/browserify/browserify-sign/commit/44181838e7dcc4d5d0c568f74312ea28f0bcdfd5) +- [meta] fix package.json indentation [`9ac5a5e`](https://github.com/browserify/browserify-sign/commit/9ac5a5eaaac8a11eb70ec2febd13745c8764ae02) +- [Tests] migrate from travis to github actions [`d845d85`](https://github.com/browserify/browserify-sign/commit/d845d855def38e2085d5a21e447a48300f99fa60) +- [Fix] `sign`: throw on unsupported padding scheme [`8767739`](https://github.com/browserify/browserify-sign/commit/8767739a4516289568bcce9fed8a3b7e23478de9) +- [Fix] properly check the upper bound for DSA signatures [`85994cd`](https://github.com/browserify/browserify-sign/commit/85994cd6348b50f2fd1b73c54e20881416f44a30) +- [Tests] handle openSSL not supporting a scheme [`f5f17c2`](https://github.com/browserify/browserify-sign/commit/f5f17c27f9824de40b5ce8ebd8502111203fd6af) +- [Deps] update `bn.js`, `browserify-rsa`, `elliptic`, `parse-asn1`, `readable-stream`, `safe-buffer` [`a67d0eb`](https://github.com/browserify/browserify-sign/commit/a67d0eb4ffceabb366b69da69ce9a223e9d5e96b) +- [Dev Deps] update `nyc`, `standard`, `tape` [`cc5350b`](https://github.com/browserify/browserify-sign/commit/cc5350b96702fcba930e0662cf763844fd2f59bf) +- [Tests] always run coverage; downgrade `nyc` [`75ce1d5`](https://github.com/browserify/browserify-sign/commit/75ce1d5c49a6591dd13422016c07f8f9cae13371) +- [meta] add `safe-publish-latest` [`dcf49ce`](https://github.com/browserify/browserify-sign/commit/dcf49ce85a1a66a6fb31689508d916d7894286a9) +- [Tests] add `npm run posttest` [`75dd8fd`](https://github.com/browserify/browserify-sign/commit/75dd8fd6ce56eb37b12e30807e5f913867b21733) +- [Dev Deps] update `tape` [`3aec038`](https://github.com/browserify/browserify-sign/commit/3aec0386dc8dfba8698be756ec770df863867c84) +- [Tests] skip unsupported schemes [`703c83e`](https://github.com/browserify/browserify-sign/commit/703c83ea72db2f45714fe749c6f04b05243ca9a8) +- [Tests] node < 6 lacks array `includes` [`3aa43cf`](https://github.com/browserify/browserify-sign/commit/3aa43cfbc1fdde8481bcdd3bff581574159b869a) +- [Dev Deps] fix eslint range [`98d4e0d`](https://github.com/browserify/browserify-sign/commit/98d4e0d7ff18871b0ca07415f758a610ccf8ebbe) + +## [v4.2.1](https://github.com/browserify/browserify-sign/compare/v4.2.0...v4.2.1) - 2020-08-04 + +### Merged + +- bump elliptic [`#58`](https://github.com/browserify/browserify-sign/pull/58) + +## [v4.2.0](https://github.com/browserify/browserify-sign/compare/v4.1.0...v4.2.0) - 2020-05-18 + +### Merged + +- switch to safe buffer [`#53`](https://github.com/browserify/browserify-sign/pull/53) + +## [v4.1.0](https://github.com/browserify/browserify-sign/compare/v4.0.4...v4.1.0) - 2020-05-05 + +### Merged + +- update deps, modernise usage, use readable-stream [`#49`](https://github.com/browserify/browserify-sign/pull/49) + +## [v4.0.4](https://github.com/browserify/browserify-sign/compare/v4.0.3...v4.0.4) - 2017-03-28 + +### Merged + +- Fix algorithms require path, add the extension [`#36`](https://github.com/browserify/browserify-sign/pull/36) + +### Commits + +- extranious semi-colon [`bf59e00`](https://github.com/browserify/browserify-sign/commit/bf59e00d0370a53876597be91a8ff7bfe855e0fc) + +## [v4.0.3](https://github.com/browserify/browserify-sign/compare/v4.0.2...v4.0.3) - 2017-03-27 + +### Commits + +- files key in the package.json [`1e0bea0`](https://github.com/browserify/browserify-sign/commit/1e0bea0e263e81b89bf564d7e0c7bddd3b7278f9) + +## [v4.0.2](https://github.com/browserify/browserify-sign/compare/v4.0.1...v4.0.2) - 2017-03-27 + +### Commits + +- put back in algos [`fd27cd3`](https://github.com/browserify/browserify-sign/commit/fd27cd3e6346c054dec937ae53f341740888e03f) + +## [v4.0.1](https://github.com/browserify/browserify-sign/compare/v4.0.0...v4.0.1) - 2017-03-27 + +### Merged + +- add support for calling ECDSA signatures RSA signatures, cuz node allows it [`#33`](https://github.com/browserify/browserify-sign/pull/33) +- don't generate a new key in ecSign [`#30`](https://github.com/browserify/browserify-sign/pull/30) +- more ecdsa [`#29`](https://github.com/browserify/browserify-sign/pull/29) +- use json files [`#26`](https://github.com/browserify/browserify-sign/pull/26) +- renaming files [`#25`](https://github.com/browserify/browserify-sign/pull/25) + +### Commits + +- algorithms as JSON file [`c41a01b`](https://github.com/browserify/browserify-sign/commit/c41a01bcb477df1ab20f6d3a311b7801a3da9ff6) +- add new fixtures [`16edebd`](https://github.com/browserify/browserify-sign/commit/16edebde35421ff376aeb7e8e62cfe5a3c1ffbee) +- curves as JSON file [`f40f060`](https://github.com/browserify/browserify-sign/commit/f40f0602f8dc6c2db8c9c1c02dc095a1e4837b89) +- update tests and travis [`9f6e80b`](https://github.com/browserify/browserify-sign/commit/9f6e80b4e1d748958bf46f7ddcb09bd38e8c3a21) +- remove unused files [`9a76f12`](https://github.com/browserify/browserify-sign/commit/9a76f12f6e673c0e9e87aed0d52f13f0ce644865) +- update package.json [`13f7b67`](https://github.com/browserify/browserify-sign/commit/13f7b67e78584a66d2275fc58978bdf59d365b03) +- update README.md [`b03de58`](https://github.com/browserify/browserify-sign/commit/b03de586a090c38e993f5e20ab94edbaa9b87b88) +- nits [`be99732`](https://github.com/browserify/browserify-sign/commit/be99732907b8ae2ea58b8935b6b33e58502239b2) +- we aparently no longer support 0.10 [`aec5180`](https://github.com/browserify/browserify-sign/commit/aec51801103b2755fc4127d2633a1c4369b3f427) +- better message [`06d76ed`](https://github.com/browserify/browserify-sign/commit/06d76ed4abb2094d8f86c395282ba53f1ffe47a6) +- move browser files to folder [`b648108`](https://github.com/browserify/browserify-sign/commit/b64810806e6f6c9c93624f1faa878ad5750a2e18) + +## [v4.0.0](https://github.com/browserify/browserify-sign/compare/v3.0.8...v4.0.0) - 2015-11-02 + +### Merged + +- upgrade bn and add 2 curves [`#22`](https://github.com/browserify/browserify-sign/pull/22) +- Add LICENSE file. [`#21`](https://github.com/browserify/browserify-sign/pull/21) + +### Commits + +- Revert "remove p521" [`0ad9f5c`](https://github.com/browserify/browserify-sign/commit/0ad9f5c5b2bed736a254722d3cd7eb779c4b45b7) +- remove p521 [`352ea17`](https://github.com/browserify/browserify-sign/commit/352ea1757d7bbcf1877757c5dc0101a7903c510c) +- add pack in p521 and update deps [`6e58dc4`](https://github.com/browserify/browserify-sign/commit/6e58dc410fa923344b9b1c7863fbf5c5f8f4f731) +- Create LICENSE [`e31c4a1`](https://github.com/browserify/browserify-sign/commit/e31c4a1e3c66a6124191e52052cadb4710814d71) +- update deps [`7ca87bc`](https://github.com/browserify/browserify-sign/commit/7ca87bc5465a9d19b4a01542eb99d70d97e84c6f) +- patch bn to 4.1.1 [`bd8dc2e`](https://github.com/browserify/browserify-sign/commit/bd8dc2e9eb8bd5cd4b7b255c1914c2f34f594ace) +- LICENSE: add @calvinmetcalf [`153a93f`](https://github.com/browserify/browserify-sign/commit/153a93f0f05c4368c76789df2df4a09ea455a8a9) +- package: adds description [`555b793`](https://github.com/browserify/browserify-sign/commit/555b79372cc4e8c29049e7f2b027f2694f7c7dd5) + +## [v3.0.8](https://github.com/browserify/browserify-sign/compare/v3.0.3...v3.0.8) - 2015-09-05 + +### Merged + +- Format [`#20`](https://github.com/browserify/browserify-sign/pull/20) +- Fixes unreachable return error [`#19`](https://github.com/browserify/browserify-sign/pull/19) + +### Fixed + +- adds standard (resolves #15) [`#15`](https://github.com/browserify/browserify-sign/issues/15) + +### Commits + +- add dsa back in [`1b8014d`](https://github.com/browserify/browserify-sign/commit/1b8014d8edfc228dc1f21e2b98442d1d297be458) +- merge [`6ada8de`](https://github.com/browserify/browserify-sign/commit/6ada8de15ebe83cedbaa2242409dbb1de441b5ed) +- standard format [`4f8a8e9`](https://github.com/browserify/browserify-sign/commit/4f8a8e90122eb1fab9be86cdfdf697989e51a507) +- comment unused functions [`2c68e08`](https://github.com/browserify/browserify-sign/commit/2c68e0828fe5c494ee5b75742bef549171404eea) +- fix use of lowercase constructor [`5032abe`](https://github.com/browserify/browserify-sign/commit/5032abe9eaaef64546f9ed085f9cf23f96eabe9a) +- README: remove TODOs [`dd76c98`](https://github.com/browserify/browserify-sign/commit/dd76c988ce7d1a6ff24e5ea55408d1771aa62380) +- algos: use 2 spaces, not tabs [`7097997`](https://github.com/browserify/browserify-sign/commit/709799742c576a57ead7d3686f00ad21de78112d) +- .travis.yml: update to new targets [`668ab5b`](https://github.com/browserify/browserify-sign/commit/668ab5b2f656854098c95d0f82b4b3b9da9e5c39) +- rm unused exports [`ddc0820`](https://github.com/browserify/browserify-sign/commit/ddc0820c766ceda98dcaf8d8bb99647d86b2fb0b) +- Rename readme.md to README.md [`557119b`](https://github.com/browserify/browserify-sign/commit/557119b51a6f8373bdededdedbd9d86be7801646) +- package: fix bad JSON [`b25808b`](https://github.com/browserify/browserify-sign/commit/b25808bea4860136edd87ced17d6bb6ccc6e143a) + +## [v3.0.3](https://github.com/browserify/browserify-sign/compare/v3.0.2...v3.0.3) - 2015-08-07 + +### Merged + +- add npmignore [`#17`](https://github.com/browserify/browserify-sign/pull/17) + +## [v3.0.2](https://github.com/browserify/browserify-sign/compare/v3.0.1...v3.0.2) - 2015-05-20 + +### Merged + +- correct error message [`#12`](https://github.com/browserify/browserify-sign/pull/12) + +### Commits + +- failing test [`93be166`](https://github.com/browserify/browserify-sign/commit/93be16675c1b276b5aae918d9cdf5825dc47cd4a) +- update deps, fixutres, and verify [`ef78685`](https://github.com/browserify/browserify-sign/commit/ef78685c39f9e234208a96488bdb845ea7ddaa18) +- test our own sigs [`2ea39b2`](https://github.com/browserify/browserify-sign/commit/2ea39b275415bf246ff0521e3a1f1fe99f91c3b5) +- update elleptic all the way [`525ea93`](https://github.com/browserify/browserify-sign/commit/525ea93f74e1543e722c6f967cb394e4b71fbd75) + +## [v3.0.1](https://github.com/browserify/browserify-sign/compare/v3.0.0...v3.0.1) - 2015-03-11 + +### Commits + +- tests: move all pre-produced data to fixtures, tests only test [`578bd27`](https://github.com/browserify/browserify-sign/commit/578bd275edb23e07d7a2e378d9f4442f29237970) +- inline fixtures [`c7fd8eb`](https://github.com/browserify/browserify-sign/commit/c7fd8eba2e58ccca5b2ba11c9a6cb447ec9b6a58) +- fixtures: convert to pure JSON [`1695735`](https://github.com/browserify/browserify-sign/commit/16957358f2026687035a999e56fcccc7e12c656d) +- passes standard [`2ba9c4c`](https://github.com/browserify/browserify-sign/commit/2ba9c4ce4b3a2fde1252da3b73f9c5dc3fedd491) +- rm node11 attribute [`456236d`](https://github.com/browserify/browserify-sign/commit/456236d0bab2d0f1aa3c365447ff6e6165c2c45e) +- check sign type [`af82685`](https://github.com/browserify/browserify-sign/commit/af826857539b1abf7075d65b21784cfabeff8d2c) +- tests/fixtures: re-compute signatures and assert equality [`69c0dd3`](https://github.com/browserify/browserify-sign/commit/69c0dd307251727c1d0db05868458451961b0215) +- fix tests in node 10 and 3 formatting issues [`a8796b0`](https://github.com/browserify/browserify-sign/commit/a8796b01dc99bbe393be49a1c5d74b71a385e7c3) +- tests: sort requires [`33591b9`](https://github.com/browserify/browserify-sign/commit/33591b9af8307f27178138271d26c020e72c6033) +- more tests [`3db65cf`](https://github.com/browserify/browserify-sign/commit/3db65cf75e990b0bc3f7a6fa1599197977c0a4c8) +- propper node10 test [`b0aa652`](https://github.com/browserify/browserify-sign/commit/b0aa65210afcb299e9a945fdf82a068a4821f5e8) +- fix typo in travis.yml [`4e42f0a`](https://github.com/browserify/browserify-sign/commit/4e42f0ac4c7b9a3cb751f41126b26749354b105d) + +## [v3.0.0](https://github.com/browserify/browserify-sign/compare/v2.8.0...v3.0.0) - 2015-03-10 + +### Merged + +- Modularize [`#8`](https://github.com/browserify/browserify-sign/pull/8) + +### Commits + +- modularize format [`d2a3f77`](https://github.com/browserify/browserify-sign/commit/d2a3f77b244ce8e967bd2b3067cdfaee670dfecf) +- better [`5077b98`](https://github.com/browserify/browserify-sign/commit/5077b984edc44440b65579fe100d74ca3e91a823) +- properly check signatures and test for it [`48f8881`](https://github.com/browserify/browserify-sign/commit/48f888175d1c1ab727cebba73def1dec48769375) +- other 3 curves [`b78737b`](https://github.com/browserify/browserify-sign/commit/b78737b27e1bcaae3f771caa89f7161bdc17c1f3) +- determanistic k [`2e1bf48`](https://github.com/browserify/browserify-sign/commit/2e1bf48e180d2ea699225b6e584e3a30c90ba312) +- formatting [`07a8727`](https://github.com/browserify/browserify-sign/commit/07a87278e6eb13539ee0a58262df3213e8cea4da) +- fixed bug with hash shorter then q [`438717a`](https://github.com/browserify/browserify-sign/commit/438717a2f00efbae18ba158b436555d56f2c9bbd) +- sign: s/getKay/getKey [`cec421c`](https://github.com/browserify/browserify-sign/commit/cec421c69d563f4cc51df5d0c323ed294e0df33e) +- make sure everything is strict [`3f10450`](https://github.com/browserify/browserify-sign/commit/3f1045017b95fdb0a0da87fe57b467705edbafdf) + +## [v2.8.0](https://github.com/browserify/browserify-sign/compare/v2.7.5...v2.8.0) - 2015-01-12 + +### Commits + +- better [`18b953c`](https://github.com/browserify/browserify-sign/commit/18b953c021e88ccdcdab809f93a1d5d2a42d3ea0) +- determanistic k [`9f1c348`](https://github.com/browserify/browserify-sign/commit/9f1c348009475ac7872e9f4e0f014bb15b88101f) +- fixed bug with hash shorter then q [`222dc8e`](https://github.com/browserify/browserify-sign/commit/222dc8ecb01f01999f69634af57ae9e64489dfb0) + +## [v2.7.5](https://github.com/browserify/browserify-sign/compare/v2.7.4...v2.7.5) - 2015-01-06 + +### Commits + +- update eliptic [`e4e5b42`](https://github.com/browserify/browserify-sign/commit/e4e5b427f7c3be3c1ded12147a66b134ae31eb0c) + +## [v2.7.4](https://github.com/browserify/browserify-sign/compare/v2.7.3...v2.7.4) - 2015-01-06 + +### Commits + +- update parse-asn1 [`22a3f57`](https://github.com/browserify/browserify-sign/commit/22a3f57340c08211547f14b63ab0cc9ab5d97dc9) + +## [v2.7.3](https://github.com/browserify/browserify-sign/compare/v2.7.2...v2.7.3) - 2015-01-06 + +### Commits + +- Update bn.js [`4519962`](https://github.com/browserify/browserify-sign/commit/4519962b2d2b73a9a118296de98280411f07fd2d) + +## [v2.7.2](https://github.com/browserify/browserify-sign/compare/v2.7.1...v2.7.2) - 2015-01-05 + +### Commits + +- aliases for sign and verify [`fcc366f`](https://github.com/browserify/browserify-sign/commit/fcc366ffe2f60e9c20d9b62b2321a96f7e9445d6) + +## [v2.7.1](https://github.com/browserify/browserify-sign/compare/v2.7.0...v2.7.1) - 2015-01-03 + +### Commits + +- Update bn.js [`c55b4aa`](https://github.com/browserify/browserify-sign/commit/c55b4aa577ef6a9414c366c760206434f97e3cce) + +## [v2.7.0](https://github.com/browserify/browserify-sign/compare/v2.6.1...v2.7.0) - 2014-12-22 + +### Commits + +- pull out rsa stuff [`0c076ff`](https://github.com/browserify/browserify-sign/commit/0c076ff1ff2aa4b626cdf25911200090a60d86c4) + +## [v2.6.1](https://github.com/browserify/browserify-sign/compare/v2.6.0...v2.6.1) - 2014-12-19 + +### Commits + +- just use regular stream not readable [`dfdd33d`](https://github.com/browserify/browserify-sign/commit/dfdd33d4bfd4823aa0308aa8215d6a32dfc210e9) + +## [v2.6.0](https://github.com/browserify/browserify-sign/compare/v2.5.2...v2.6.0) - 2014-12-18 + +### Commits + +- dsa [`e01ff39`](https://github.com/browserify/browserify-sign/commit/e01ff3987ecf80670bb6e5d38ad7a1dc08a429b0) +- varient encoding of password protected keys [`eaaf2d5`](https://github.com/browserify/browserify-sign/commit/eaaf2d53a385d6b13fcff33734675c3d886b5b51) + +## [v2.5.2](https://github.com/browserify/browserify-sign/compare/v2.5.1...v2.5.2) - 2014-12-17 + +### Commits + +- pull out parseKey [`b25775e`](https://github.com/browserify/browserify-sign/commit/b25775e1f4ed1b3df3ed776f3d0a352f2fa338cf) + +## [v2.5.1](https://github.com/browserify/browserify-sign/compare/v2.5.0...v2.5.1) - 2014-12-09 + +### Commits + +- circular dependancy [`1c15e75`](https://github.com/browserify/browserify-sign/commit/1c15e75b27a20b34bb7dd32eb833beb57716f69c) + +## [v2.5.0](https://github.com/browserify/browserify-sign/compare/v2.4.0...v2.5.0) - 2014-11-25 + +### Commits + +- add md5 and ripemd160 also make sure to include algorythm id when verifying [`da03fb0`](https://github.com/browserify/browserify-sign/commit/da03fb07ad10b61f4386560503802e16af8fa80e) +- cross off ecdsa [`1a3e3f3`](https://github.com/browserify/browserify-sign/commit/1a3e3f3e466c3de43ff02fd5434922e3b19fe77b) + +## [v2.4.0](https://github.com/browserify/browserify-sign/compare/v2.3.0...v2.4.0) - 2014-11-16 + +### Commits + +- eliptical curves [`17745d2`](https://github.com/browserify/browserify-sign/commit/17745d23773baad7b1ec1289d86ac46e87da9323) +- ecdsa with password [`2186465`](https://github.com/browserify/browserify-sign/commit/2186465dab56a1468d13964a3c6b3ef7b2b44437) +- encryption is out of scope [`f975416`](https://github.com/browserify/browserify-sign/commit/f97541615c9853b276a33cf40f394e079f3988b9) + +## [v2.3.0](https://github.com/browserify/browserify-sign/compare/v2.2.0...v2.3.0) - 2014-11-15 + +### Commits + +- Chinese remainder algorithm [`140a41f`](https://github.com/browserify/browserify-sign/commit/140a41fb482e02716e0d7b79ae390f6979cab031) + +## [v2.2.0](https://github.com/browserify/browserify-sign/compare/v2.1.0...v2.2.0) - 2014-11-15 + +### Commits + +- passwords! [`8c95b09`](https://github.com/browserify/browserify-sign/commit/8c95b09e5ba43d041f6527e3d62e7e216ec1d5ae) + +## v2.1.0 - 2014-11-15 + +### Commits + +- in prog [`d55225f`](https://github.com/browserify/browserify-sign/commit/d55225f0c3bd669ad616481dbc347fcab6654db1) +- working! [`130b1e2`](https://github.com/browserify/browserify-sign/commit/130b1e2703f807ff58ebf26612487a9a4d1e875c) +- generic key files [`7bd3f91`](https://github.com/browserify/browserify-sign/commit/7bd3f91d99b79a6077efb7c2239fcde5e2ebe95c) +- node stuff [`342c74f`](https://github.com/browserify/browserify-sign/commit/342c74f0db7ae0ae071f898f1cd8fcce3170b851) +- repo [`7e9b914`](https://github.com/browserify/browserify-sign/commit/7e9b91446c335d41e9e53466f8b4e07b697570ac) +- todo [`15410f2`](https://github.com/browserify/browserify-sign/commit/15410f260d813e07213b4bb51a2d2a747a8fd82a) +- test messages [`735a056`](https://github.com/browserify/browserify-sign/commit/735a056eb785387510bb9f0624ea6528447c4b8b) +- travis .yml file [`173fd78`](https://github.com/browserify/browserify-sign/commit/173fd7806d63d9808a2b1a7167b1fd3780f34a0d) +- travis [`9b562e6`](https://github.com/browserify/browserify-sign/commit/9b562e633e26e266153756cc70e0ba90284a0b3b) diff --git a/algos.js b/algos.js index dff5b78..060d8dc 100644 --- a/algos.js +++ b/algos.js @@ -1 +1,3 @@ -module.exports = require('./browser/algorithms.json') +'use strict'; + +module.exports = require('./browser/algorithms.json'); diff --git a/browser/index.js b/browser/index.js index eef91fb..ce228c4 100644 --- a/browser/index.js +++ b/browser/index.js @@ -1,86 +1,87 @@ -var createHash = require('create-hash') -var stream = require('stream') -var inherits = require('inherits') -var sign = require('./sign') -var verify = require('./verify') +'use strict'; -var algorithms = require('./algorithms.json') +var Buffer = require('safe-buffer').Buffer; +var createHash = require('create-hash'); +var stream = require('readable-stream'); +var inherits = require('inherits'); +var sign = require('./sign'); +var verify = require('./verify'); + +var algorithms = require('./algorithms.json'); Object.keys(algorithms).forEach(function (key) { - algorithms[key].id = new Buffer(algorithms[key].id, 'hex') - algorithms[key.toLowerCase()] = algorithms[key] -}) + algorithms[key].id = Buffer.from(algorithms[key].id, 'hex'); + algorithms[key.toLowerCase()] = algorithms[key]; +}); -function Sign (algorithm) { - stream.Writable.call(this) +function Sign(algorithm) { + stream.Writable.call(this); - var data = algorithms[algorithm] - if (!data) throw new Error('Unknown message digest') + var data = algorithms[algorithm]; + if (!data) { throw new Error('Unknown message digest'); } - this._hashType = data.hash - this._hash = createHash(data.hash) - this._tag = data.id - this._signType = data.sign + this._hashType = data.hash; + this._hash = createHash(data.hash); + this._tag = data.id; + this._signType = data.sign; } -inherits(Sign, stream.Writable) +inherits(Sign, stream.Writable); -Sign.prototype._write = function _write (data, _, done) { - this._hash.update(data) - done() -} +Sign.prototype._write = function _write(data, _, done) { + this._hash.update(data); + done(); +}; -Sign.prototype.update = function update (data, enc) { - if (typeof data === 'string') data = new Buffer(data, enc) +Sign.prototype.update = function update(data, enc) { + this._hash.update(typeof data === 'string' ? Buffer.from(data, enc) : data); - this._hash.update(data) - return this -} + return this; +}; -Sign.prototype.sign = function signMethod (key, enc) { - this.end() - var hash = this._hash.digest() - var sig = sign(hash, key, this._hashType, this._signType, this._tag) +Sign.prototype.sign = function signMethod(key, enc) { + this.end(); + var hash = this._hash.digest(); + var sig = sign(hash, key, this._hashType, this._signType, this._tag); - return enc ? sig.toString(enc) : sig -} + return enc ? sig.toString(enc) : sig; +}; -function Verify (algorithm) { - stream.Writable.call(this) +function Verify(algorithm) { + stream.Writable.call(this); - var data = algorithms[algorithm] - if (!data) throw new Error('Unknown message digest') + var data = algorithms[algorithm]; + if (!data) { throw new Error('Unknown message digest'); } - this._hash = createHash(data.hash) - this._tag = data.id - this._signType = data.sign + this._hash = createHash(data.hash); + this._tag = data.id; + this._signType = data.sign; } -inherits(Verify, stream.Writable) +inherits(Verify, stream.Writable); -Verify.prototype._write = function _write (data, _, done) { - this._hash.update(data) - done() -} +Verify.prototype._write = function _write(data, _, done) { + this._hash.update(data); + done(); +}; -Verify.prototype.update = function update (data, enc) { - if (typeof data === 'string') data = new Buffer(data, enc) +Verify.prototype.update = function update(data, enc) { + this._hash.update(typeof data === 'string' ? Buffer.from(data, enc) : data); - this._hash.update(data) - return this -} + return this; +}; -Verify.prototype.verify = function verifyMethod (key, sig, enc) { - if (typeof sig === 'string') sig = new Buffer(sig, enc) +Verify.prototype.verify = function verifyMethod(key, sig, enc) { + var sigBuffer = typeof sig === 'string' ? Buffer.from(sig, enc) : sig; - this.end() - var hash = this._hash.digest() - return verify(sig, hash, key, this._signType, this._tag) -} + this.end(); + var hash = this._hash.digest(); + return verify(sigBuffer, hash, key, this._signType, this._tag); +}; -function createSign (algorithm) { - return new Sign(algorithm) +function createSign(algorithm) { + return new Sign(algorithm); } -function createVerify (algorithm) { - return new Verify(algorithm) +function createVerify(algorithm) { + return new Verify(algorithm); } module.exports = { @@ -88,4 +89,4 @@ module.exports = { Verify: createVerify, createSign: createSign, createVerify: createVerify -} +}; diff --git a/browser/sign.js b/browser/sign.js index d2be0d2..f581825 100644 --- a/browser/sign.js +++ b/browser/sign.js @@ -1,145 +1,150 @@ +'use strict'; + // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js -var createHmac = require('create-hmac') -var crt = require('browserify-rsa') -var EC = require('elliptic').ec -var BN = require('bn.js') -var parseKeys = require('parse-asn1') -var curves = require('./curves.json') - -function sign (hash, key, hashType, signType, tag) { - var priv = parseKeys(key) +var Buffer = require('safe-buffer').Buffer; +var createHmac = require('create-hmac'); +var crt = require('browserify-rsa'); +var EC = require('elliptic').ec; +var BN = require('bn.js'); +var parseKeys = require('parse-asn1'); +var curves = require('./curves.json'); + +var RSA_PKCS1_PADDING = 1; + +function sign(hash, key, hashType, signType, tag) { + var priv = parseKeys(key); if (priv.curve) { // rsa keys can be interpreted as ecdsa ones in openssl - if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type') - return ecSign(hash, priv) + if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong private key type'); } + return ecSign(hash, priv); } else if (priv.type === 'dsa') { - if (signType !== 'dsa') throw new Error('wrong private key type') - return dsaSign(hash, priv, hashType) - } else { - if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type') + if (signType !== 'dsa') { throw new Error('wrong private key type'); } + return dsaSign(hash, priv, hashType); } - hash = Buffer.concat([tag, hash]) - var len = priv.modulus.byteLength() - var pad = [ 0, 1 ] - while (hash.length + pad.length + 1 < len) pad.push(0xff) - pad.push(0x00) - var i = -1 - while (++i < hash.length) pad.push(hash[i]) - - var out = crt(pad, priv) - return out + if (signType !== 'rsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong private key type'); } + if (key.padding !== undefined && key.padding !== RSA_PKCS1_PADDING) { throw new Error('illegal or unsupported padding mode'); } + + hash = Buffer.concat([tag, hash]); + var len = priv.modulus.byteLength(); + var pad = [0, 1]; + while (hash.length + pad.length + 1 < len) { pad.push(0xff); } + pad.push(0x00); + var i = -1; + while (++i < hash.length) { pad.push(hash[i]); } + + var out = crt(pad, priv); + return out; } -function ecSign (hash, priv) { - var curveId = curves[priv.curve.join('.')] - if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.')) +function ecSign(hash, priv) { + var curveId = curves[priv.curve.join('.')]; + if (!curveId) { throw new Error('unknown curve ' + priv.curve.join('.')); } - var curve = new EC(curveId) - var key = curve.keyFromPrivate(priv.privateKey) - var out = key.sign(hash) + var curve = new EC(curveId); + var key = curve.keyFromPrivate(priv.privateKey); + var out = key.sign(hash); - return new Buffer(out.toDER()) + return Buffer.from(out.toDER()); } -function dsaSign (hash, priv, algo) { - var x = priv.params.priv_key - var p = priv.params.p - var q = priv.params.q - var g = priv.params.g - var r = new BN(0) - var k - var H = bits2int(hash, q).mod(q) - var s = false - var kv = getKey(x, q, hash, algo) +function dsaSign(hash, priv, algo) { + var x = priv.params.priv_key; + var p = priv.params.p; + var q = priv.params.q; + var g = priv.params.g; + var r = new BN(0); + var k; + var H = bits2int(hash, q).mod(q); + var s = false; + var kv = getKey(x, q, hash, algo); while (s === false) { - k = makeKey(q, kv, algo) - r = makeR(g, k, p, q) - s = k.invm(q).imul(H.add(x.mul(r))).mod(q) + k = makeKey(q, kv, algo); + r = makeR(g, k, p, q); + s = k.invm(q).imul(H.add(x.mul(r))).mod(q); if (s.cmpn(0) === 0) { - s = false - r = new BN(0) + s = false; + r = new BN(0); } } - return toDER(r, s) + return toDER(r, s); } -function toDER (r, s) { - r = r.toArray() - s = s.toArray() +function toDER(r, s) { + r = r.toArray(); + s = s.toArray(); // Pad values - if (r[0] & 0x80) r = [ 0 ].concat(r) - if (s[0] & 0x80) s = [ 0 ].concat(s) - - var total = r.length + s.length + 4 - var res = [ 0x30, total, 0x02, r.length ] - res = res.concat(r, [ 0x02, s.length ], s) - return new Buffer(res) + if (r[0] & 0x80) { r = [0].concat(r); } + if (s[0] & 0x80) { s = [0].concat(s); } + + var total = r.length + s.length + 4; + var res = [ + 0x30, total, 0x02, r.length + ]; + res = res.concat(r, [0x02, s.length], s); + return Buffer.from(res); } -function getKey (x, q, hash, algo) { - x = new Buffer(x.toArray()) +function getKey(x, q, hash, algo) { + x = Buffer.from(x.toArray()); if (x.length < q.byteLength()) { - var zeros = new Buffer(q.byteLength() - x.length) - zeros.fill(0) - x = Buffer.concat([ zeros, x ]) + var zeros = Buffer.alloc(q.byteLength() - x.length); + x = Buffer.concat([zeros, x]); } - var hlen = hash.length - var hbits = bits2octets(hash, q) - var v = new Buffer(hlen) - v.fill(1) - var k = new Buffer(hlen) - k.fill(0) - k = createHmac(algo, k).update(v).update(new Buffer([ 0 ])).update(x).update(hbits).digest() - v = createHmac(algo, k).update(v).digest() - k = createHmac(algo, k).update(v).update(new Buffer([ 1 ])).update(x).update(hbits).digest() - v = createHmac(algo, k).update(v).digest() - return { k: k, v: v } + var hlen = hash.length; + var hbits = bits2octets(hash, q); + var v = Buffer.alloc(hlen); + v.fill(1); + var k = Buffer.alloc(hlen); + k = createHmac(algo, k).update(v).update(Buffer.from([0])).update(x).update(hbits).digest(); + v = createHmac(algo, k).update(v).digest(); + k = createHmac(algo, k).update(v).update(Buffer.from([1])).update(x).update(hbits).digest(); + v = createHmac(algo, k).update(v).digest(); + return { k: k, v: v }; } -function bits2int (obits, q) { - var bits = new BN(obits) - var shift = (obits.length << 3) - q.bitLength() - if (shift > 0) bits.ishrn(shift) - return bits +function bits2int(obits, q) { + var bits = new BN(obits); + var shift = (obits.length << 3) - q.bitLength(); + if (shift > 0) { bits.ishrn(shift); } + return bits; } -function bits2octets (bits, q) { - bits = bits2int(bits, q) - bits = bits.mod(q) - var out = new Buffer(bits.toArray()) +function bits2octets(bits, q) { + bits = bits2int(bits, q); + bits = bits.mod(q); + var out = Buffer.from(bits.toArray()); if (out.length < q.byteLength()) { - var zeros = new Buffer(q.byteLength() - out.length) - zeros.fill(0) - out = Buffer.concat([ zeros, out ]) + var zeros = Buffer.alloc(q.byteLength() - out.length); + out = Buffer.concat([zeros, out]); } - return out + return out; } -function makeKey (q, kv, algo) { - var t - var k +function makeKey(q, kv, algo) { + var t; + var k; do { - t = new Buffer(0) + t = Buffer.alloc(0); while (t.length * 8 < q.bitLength()) { - kv.v = createHmac(algo, kv.k).update(kv.v).digest() - t = Buffer.concat([ t, kv.v ]) + kv.v = createHmac(algo, kv.k).update(kv.v).digest(); + t = Buffer.concat([t, kv.v]); } - k = bits2int(t, q) - kv.k = createHmac(algo, kv.k).update(kv.v).update(new Buffer([ 0 ])).digest() - kv.v = createHmac(algo, kv.k).update(kv.v).digest() - } while (k.cmp(q) !== -1) + k = bits2int(t, q); + kv.k = createHmac(algo, kv.k).update(kv.v).update(Buffer.from([0])).digest(); + kv.v = createHmac(algo, kv.k).update(kv.v).digest(); + } while (k.cmp(q) !== -1); - return k + return k; } -function makeR (g, k, p, q) { - return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q) +function makeR(g, k, p, q) { + return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q); } -module.exports = sign -module.exports.getKey = getKey -module.exports.makeKey = makeKey +module.exports = sign; +module.exports.getKey = getKey; +module.exports.makeKey = makeKey; diff --git a/browser/verify.js b/browser/verify.js index 4c24091..5a18080 100644 --- a/browser/verify.js +++ b/browser/verify.js @@ -1,83 +1,86 @@ +'use strict'; + // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js -var BN = require('bn.js') -var EC = require('elliptic').ec -var parseKeys = require('parse-asn1') -var curves = require('./curves.json') +var Buffer = require('safe-buffer').Buffer; +var BN = require('bn.js'); +var EC = require('elliptic').ec; +var parseKeys = require('parse-asn1'); +var curves = require('./curves.json'); -function verify (sig, hash, key, signType, tag) { - var pub = parseKeys(key) +function verify(sig, hash, key, signType, tag) { + var pub = parseKeys(key); if (pub.type === 'ec') { // rsa keys can be interpreted as ecdsa ones in openssl - if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type') - return ecVerify(sig, hash, pub) + if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong public key type'); } + return ecVerify(sig, hash, pub); } else if (pub.type === 'dsa') { - if (signType !== 'dsa') throw new Error('wrong public key type') - return dsaVerify(sig, hash, pub) - } else { - if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type') + if (signType !== 'dsa') { throw new Error('wrong public key type'); } + return dsaVerify(sig, hash, pub); } - hash = Buffer.concat([tag, hash]) - var len = pub.modulus.byteLength() - var pad = [ 1 ] - var padNum = 0 + if (signType !== 'rsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong public key type'); } + + hash = Buffer.concat([tag, hash]); + var len = pub.modulus.byteLength(); + var pad = [1]; + var padNum = 0; while (hash.length + pad.length + 2 < len) { - pad.push(0xff) - padNum++ + pad.push(0xff); + padNum += 1; } - pad.push(0x00) - var i = -1 + pad.push(0x00); + var i = -1; while (++i < hash.length) { - pad.push(hash[i]) + pad.push(hash[i]); } - pad = new Buffer(pad) - var red = BN.mont(pub.modulus) - sig = new BN(sig).toRed(red) + pad = Buffer.from(pad); + var red = BN.mont(pub.modulus); + sig = new BN(sig).toRed(red); - sig = sig.redPow(new BN(pub.publicExponent)) - sig = new Buffer(sig.fromRed().toArray()) - var out = padNum < 8 ? 1 : 0 - len = Math.min(sig.length, pad.length) - if (sig.length !== pad.length) out = 1 + sig = sig.redPow(new BN(pub.publicExponent)); + sig = Buffer.from(sig.fromRed().toArray()); + var out = padNum < 8 ? 1 : 0; + len = Math.min(sig.length, pad.length); + if (sig.length !== pad.length) { out = 1; } - i = -1 - while (++i < len) out |= sig[i] ^ pad[i] - return out === 0 + i = -1; + while (++i < len) { out |= sig[i] ^ pad[i]; } + return out === 0; } -function ecVerify (sig, hash, pub) { - var curveId = curves[pub.data.algorithm.curve.join('.')] - if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.')) +function ecVerify(sig, hash, pub) { + var curveId = curves[pub.data.algorithm.curve.join('.')]; + if (!curveId) { throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.')); } - var curve = new EC(curveId) - var pubkey = pub.data.subjectPrivateKey.data + var curve = new EC(curveId); + var pubkey = pub.data.subjectPrivateKey.data; - return curve.verify(hash, sig, pubkey) + return curve.verify(hash, sig, pubkey); } -function dsaVerify (sig, hash, pub) { - var p = pub.data.p - var q = pub.data.q - var g = pub.data.g - var y = pub.data.pub_key - var unpacked = parseKeys.signature.decode(sig, 'der') - var s = unpacked.s - var r = unpacked.r - checkValue(s, q) - checkValue(r, q) - var montp = BN.mont(p) - var w = s.invm(q) +function dsaVerify(sig, hash, pub) { + var p = pub.data.p; + var q = pub.data.q; + var g = pub.data.g; + var y = pub.data.pub_key; + var unpacked = parseKeys.signature.decode(sig, 'der'); + var s = unpacked.s; + var r = unpacked.r; + checkValue(s, q); + checkValue(r, q); + var montp = BN.mont(p); + var w = s.invm(q); var v = g.toRed(montp) .redPow(new BN(hash).mul(w).mod(q)) .fromRed() .mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed()) .mod(p) - .mod(q) - return v.cmp(r) === 0 + .mod(q); + return v.cmp(r) === 0; } -function checkValue (b, q) { - if (b.cmpn(0) <= 0) throw new Error('invalid sig') - if (b.cmp(q) >= q) throw new Error('invalid sig') +function checkValue(b, q) { + if (b.cmpn(0) <= 0) { throw new Error('invalid sig'); } + if (b.cmp(q) >= 0) { throw new Error('invalid sig'); } } -module.exports = verify +module.exports = verify; diff --git a/index.js b/index.js index dafa0bc..40281f6 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,9 @@ -var crypto = require('crypto') +'use strict'; -exports.createSign = crypto.createSign -exports.Sign = crypto.Sign +var crypto = require('crypto'); -exports.createVerify = crypto.createVerify -exports.Verify = crypto.Verify +exports.createSign = crypto.createSign; +exports.Sign = crypto.Sign; + +exports.createVerify = crypto.createVerify; +exports.Verify = crypto.Verify; diff --git a/package.json b/package.json index bb3dc44..d0ca089 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,72 @@ { - "name": "browserify-sign", - "version": "4.0.4", - "description": "adds node crypto signing for browsers", - "bugs": { - "url": "https://github.com/crypto-browserify/browserify-sign/issues" - }, - "license": "ISC", - "files": [ - "browser", - "index.js", - "algos.js" - ], - "main": "index.js", - "repository": { - "type": "git", - "url": "https://github.com/crypto-browserify/browserify-sign.git" - }, - "scripts": { - "coverage": "nyc npm run unit", - "lint": "standard", - "test": "npm run lint && npm run unit", - "unit": "tape test/*.js" - }, - "dependencies": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - }, - "devDependencies": { - "nyc": "^6.1.1", - "standard": "^6.0.8", - "tape": "^4.5.1" - }, - "browser": "browser/index.js" + "name": "browserify-sign", + "version": "4.2.3", + "description": "adds node crypto signing for browsers", + "bugs": { + "url": "https://github.com/crypto-browserify/browserify-sign/issues" + }, + "license": "ISC", + "files": [ + "browser", + "index.js", + "algos.js" + ], + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/crypto-browserify/browserify-sign.git" + }, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "lint": "eslint --ext=js,mjs .", + "tests-only": "nyc tape 'test/**/*.js'", + "pretest": "npm run lint", + "test": "npm run tests-only", + "posttest": "aud --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.5", + "hash-base": "~3.0", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "eslint": "=8.8.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "semver": "^6.3.1", + "tape": "^5.7.5" + }, + "browser": "browser/index.js", + "engines": { + "node": ">= 0.12" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } } diff --git a/test/index.js b/test/index.js index dcfd303..f94f932 100644 --- a/test/index.js +++ b/test/index.js @@ -1,131 +1,218 @@ -var asn1 = require('parse-asn1/asn1') -var test = require('tape').test -var nCrypto = require('crypto') -var bCrypto = require('../browser') -var fixtures = require('./fixtures') +'use strict'; -function isNode10 () { - return parseInt(process.version.split('.')[1], 10) <= 10 -} +var Buffer = require('safe-buffer').Buffer; +var asn1 = require('parse-asn1/asn1'); +var test = require('tape').test; +var nCrypto = require('crypto'); +var semver = require('semver'); +var BN = require('bn.js'); +var parseKeys = require('parse-asn1'); -fixtures.valid.rsa.forEach(function (f) { - var message = new Buffer(f.message) - var pub = new Buffer(f.public, 'base64') - var priv +var bCrypto = require('../browser'); +var fixtures = require('./fixtures'); - // skip passphrase tests in node 10 - if (f.passphrase && isNode10()) return +fixtures.valid.rsa.forEach(function (f) { + var message = Buffer.from(f.message); + var pub = Buffer.from(f['public'], 'base64'); + var priv; if (f.passphrase) { priv = { - key: new Buffer(f.private, 'base64'), + key: Buffer.from(f['private'], 'base64'), passphrase: f.passphrase - } + }; } else { - priv = new Buffer(f.private, 'base64') + priv = Buffer.from(f['private'], 'base64'); } - test(f.message, function (t) { - var bSign = bCrypto.createSign(f.scheme) - var nSign = nCrypto.createSign(f.scheme) - var bSig = bSign.update(message).sign(priv) - var nSig = nSign.update(message).sign(priv) - - t.equals(bSig.length, nSig.length, 'correct length') - t.equals(bSig.toString('hex'), nSig.toString('hex'), 'equal sigs') - t.equals(bSig.toString('hex'), f.signature, 'compare to known') - - t.ok(nCrypto.createVerify(f.scheme).update(message).verify(pub, nSig), 'node validate node sig') - t.ok(nCrypto.createVerify(f.scheme).update(message).verify(pub, bSig), 'node validate browser sig') + (nCrypto.getHashes().indexOf(f.scheme) >= 0 ? test : test.skip)(f.message, function (t) { + var bSign; + try { + bSign = bCrypto.createSign(f.scheme); + } catch (e) { + console.info('skipping unsupported browserify-sign scheme', f.scheme); + t.end(); + return; + } - t.ok(bCrypto.createVerify(f.scheme).update(message).verify(pub, nSig), 'browser validate node sig') - t.ok(bCrypto.createVerify(f.scheme).update(message).verify(pub, bSig), 'browser validate browser sig') + try { + var nSign = nCrypto.createSign(f.scheme); + } catch (e) { + console.info('skipping unsupported node scheme', f.scheme); + t.end(); + return; + } - t.end() - }) -}) + var bSig = bSign.update(message).sign(priv); + var nSig = nSign.update(message).sign(priv); + + t.equals(bSig.length, nSig.length, 'correct length'); + t.equals(bSig.toString('hex'), nSig.toString('hex'), 'equal sigs'); + t.equals(bSig.toString('hex'), f.signature, 'compare to known'); + + t.ok(nCrypto.createVerify(f.scheme).update(message).verify(pub, nSig), 'node validate node sig'); + t.ok(nCrypto.createVerify(f.scheme).update(message).verify(pub, bSig), 'node validate browser sig'); + + t.ok(bCrypto.createVerify(f.scheme).update(message).verify(pub, nSig), 'browser validate node sig'); + t.ok(bCrypto.createVerify(f.scheme).update(message).verify(pub, bSig), 'browser validate browser sig'); + + t.end(); + }); +}); + +// node has padding support since 8.0 +// TODO: figure out why node v8.0 - v8.6 is broken +(semver.satisfies(process.versions.node, '>= 8.6') ? test : test.skip)('padding option', function (t) { + var f = fixtures.valid.rsa[0]; + var message = Buffer.from(f.message); + var priv = { + key: Buffer.from(f['private'], 'base64'), + padding: 11646841 // Some invalid value + }; + + t.test('invalid padding option', function (st) { + var bSign = bCrypto.createSign(f.scheme); + var nSign = nCrypto.createSign(f.scheme); + st['throws']( + function () { bSign.update(message).sign(priv); }, + /illegal or unsupported padding mode/, + 'browser throws exception with proper message' + ); + st['throws']( + function () { nSign.update(message).sign(priv); }, + /illegal or unsupported padding mode/, + 'node throws exception with proper message' + ); + + st.end(); + }); + + t.end(); +}); fixtures.valid.ec.forEach(function (f) { - var message = new Buffer(f.message) - var pub = new Buffer(f.public, 'base64') - var priv - - // skip passphrase tests in node 10 - if (f.passphrase && isNode10()) return + var message = Buffer.from(f.message); + var pub = Buffer.from(f['public'], 'base64'); + var priv; if (f.passphrase) { priv = { - key: new Buffer(f.private, 'base64'), + key: Buffer.from(f['private'], 'base64'), passphrase: f.passphrase - } + }; } else { - priv = new Buffer(f.private, 'base64') + priv = Buffer.from(f['private'], 'base64'); } - test(f.message, function (t) { - var nSign = nCrypto.createSign(f.scheme) - var bSign = bCrypto.createSign(f.scheme) + (nCrypto.getHashes().indexOf(f.scheme) >= 0 ? test : test.skip)(f.message, function (t) { + var nSign; + try { + nSign = nCrypto.createSign(f.scheme); + } catch (e) { + console.info('skipping unsupported browserify-sign scheme', f.scheme); + t.end(); + return; + } + + var bSign; + try { + bSign = bCrypto.createSign(f.scheme); + } catch (e) { + console.info('skipping unsupported node scheme', f.scheme); + t.end(); + return; + } - var bSig = bSign.update(message).sign(priv) - var nSig = nSign.update(message).sign(priv) - t.notEqual(bSig.toString('hex'), nSig.toString('hex'), 'not equal sigs') - t.equals(bSig.toString('hex'), f.signature, 'sig is determanistic') + var bSig = bSign.update(message).sign(priv); + var nSig = nSign.update(message).sign(priv); + t.notEqual(bSig.toString('hex'), nSig.toString('hex'), 'not equal sigs'); + t.equals(bSig.toString('hex'), f.signature, 'sig is determanistic'); - var nVer = nCrypto.createVerify(f.scheme) - t.ok(nVer.update(message).verify(pub, bSig), 'node validate browser sig') + var nVer = nCrypto.createVerify(f.scheme); + t.ok(nVer.update(message).verify(pub, bSig), 'node validate browser sig'); - var bVer = bCrypto.createVerify(f.scheme) - t.ok(bVer.update(message).verify(pub, nSig), 'browser validate node sig') + var bVer = bCrypto.createVerify(f.scheme); + t.ok(bVer.update(message).verify(pub, nSig), 'browser validate node sig'); + + t.end(); + }); - t.end() - }) if (f.scheme !== 'DSA' && f.scheme.toLowerCase().indexOf('dsa') === -1) { test(f.message + ' named rsa through', function (t) { - var scheme = 'RSA-' + f.scheme.toUpperCase() - var nSign = nCrypto.createSign(scheme) - var bSign = bCrypto.createSign(scheme) + var scheme = 'RSA-' + f.scheme.toUpperCase(); + var nSign = nCrypto.createSign(scheme); + var bSign = bCrypto.createSign(scheme); - var bSig = bSign.update(message).sign(priv) - var nSig = nSign.update(message).sign(priv) - t.notEqual(bSig.toString('hex'), nSig.toString('hex'), 'not equal sigs') - t.equals(bSig.toString('hex'), f.signature, 'sig is determanistic') + var bSig = bSign.update(message).sign(priv); + var nSig = nSign.update(message).sign(priv); + t.notEqual(bSig.toString('hex'), nSig.toString('hex'), 'not equal sigs'); + t.equals(bSig.toString('hex'), f.signature, 'sig is determanistic'); - var nVer = nCrypto.createVerify(f.scheme) - t.ok(nVer.update(message).verify(pub, bSig), 'node validate browser sig') + var nVer = nCrypto.createVerify(f.scheme); + t.ok(nVer.update(message).verify(pub, bSig), 'node validate browser sig'); - var bVer = bCrypto.createVerify(f.scheme) - t.ok(bVer.update(message).verify(pub, nSig), 'browser validate node sig') + var bVer = bCrypto.createVerify(f.scheme); + t.ok(bVer.update(message).verify(pub, nSig), 'browser validate node sig'); - t.end() - }) + t.end(); + }); } -}) + + var s = parseKeys(pub).data.q; + test( + f.message + ' against a fake signature', + { skip: !s || '(this test only applies to DSA signatures and not EC signatures, this is ' + f.scheme + ')' }, + function (t) { + var messageBase64 = Buffer.from(f.message, 'base64'); + + // forge a fake signature + var r = new BN('1'); + + try { + var fakeSig = asn1.signature.encode({ r: r, s: s }, 'der'); + } catch (e) { + t.ifError(e); + t.end(); + return; + } + + var bVer = bCrypto.createVerify(f.scheme); + t['throws']( + function () { bVer.update(messageBase64).verify(pub, fakeSig); }, + Error, + 'fake signature is invalid' + ); + + t.end(); + } + ); +}); fixtures.valid.kvectors.forEach(function (f) { test('kvector algo: ' + f.algo + ' key len: ' + f.key.length + ' msg: ' + f.msg, function (t) { - var key = new Buffer(f.key, 'base64') + var key = Buffer.from(f.key, 'base64'); - var bSig = bCrypto.createSign(f.algo).update(f.msg).sign(key) - var bRS = asn1.signature.decode(bSig, 'der') - t.equals(bRS.r.toString(16), f.r.toLowerCase(), 'r') - t.equals(bRS.s.toString(16), f.s.toLowerCase(), 's') + var bSig = bCrypto.createSign(f.algo).update(f.msg).sign(key); + var bRS = asn1.signature.decode(bSig, 'der'); + t.equals(bRS.r.toString(16), f.r.toLowerCase(), 'r'); + t.equals(bRS.s.toString(16), f.s.toLowerCase(), 's'); - t.end() - }) -}) + t.end(); + }); +}); fixtures.invalid.verify.forEach(function (f) { test(f.description, function (t) { - var sign = new Buffer(f.signature, 'hex') - var pub = new Buffer(f.public, 'base64') - var message = new Buffer(f.message) + var sign = Buffer.from(f.signature, 'hex'); + var pub = Buffer.from(f['public'], 'base64'); + var message = Buffer.from(f.message); - var nVerify = nCrypto.createVerify(f.scheme).update(message).verify(pub, sign) - t.notOk(nVerify, 'node rejects it') + var nVerify = nCrypto.createVerify(f.scheme).update(message).verify(pub, sign); + t.notOk(nVerify, 'node rejects it'); - var bVerify = bCrypto.createVerify(f.scheme).update(message).verify(pub, sign) - t.notOk(bVerify, 'We reject it') + var bVerify = bCrypto.createVerify(f.scheme).update(message).verify(pub, sign); + t.notOk(bVerify, 'We reject it'); - t.end() - }) -}) + t.end(); + }); +});