From d9c0a660efc9b6bcece30a10dec37717ad95390b Mon Sep 17 00:00:00 2001 From: Sebastian Niemann Date: Sun, 27 Oct 2019 12:56:12 +0100 Subject: [PATCH] Updates crypto library --- LICENSE.md | 77 +++++++++++++++------------------------- browser/crypto.ts | 49 +++++++++++++++++++++++++ package-lock.json | 22 ++++-------- package.json | 2 +- rollup.config.js | 3 +- src/Chunk.ts | 6 ++-- src/utils/FileEmitter.ts | 4 +-- src/utils/crypto.ts | 1 + typings/Chunk.d.ts | 6 ---- 9 files changed, 92 insertions(+), 78 deletions(-) create mode 100644 browser/crypto.ts create mode 100644 src/utils/crypto.ts delete mode 100644 typings/Chunk.d.ts diff --git a/LICENSE.md b/LICENSE.md index 9f1eeef1d01..49dbf9e53a7 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -82,6 +82,34 @@ Repository: https://github.com/acornjs/acorn.git --------------------------------------- +## asmcrypto.js +License: MIT +By: Ádám Lippai, Artem S Vybornov, Ximin Luo +Repository: git+https://github.com/asmcrypto/asmcrypto.js.git + +> The MIT License (MIT) +> +> Copyright (c) 2013 Artem S Vybornov +> +> Permission is hereby granted, free of charge, to any person obtaining a copy of +> this software and associated documentation files (the "Software"), to deal in +> the Software without restriction, including without limitation the rights to +> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +> the Software, and to permit persons to whom the Software is furnished to do so, +> subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------- + ## braces License: MIT By: Jon Schlinkert, Brian Woodward, Elan Shanker, Eugene Sharygin, hemanth.hm @@ -147,35 +175,6 @@ Repository: jonschlinkert/fill-range --------------------------------------- -## hash.js -License: MIT -By: Fedor Indutny -Repository: git@github.com:indutny/hash.js - ---------------------------------------- - -## inherits -License: ISC -Repository: git://github.com/isaacs/inherits - -> The ISC License -> -> Copyright (c) Isaac Z. Schlueter -> -> Permission to use, copy, modify, and/or distribute this software for any -> purpose with or without fee is hereby granted, provided that the above -> copyright notice and this permission notice appear in all copies. -> -> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -> REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -> FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -> INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -> LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -> OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -> PERFORMANCE OF THIS SOFTWARE. - ---------------------------------------- - ## is-number License: MIT By: Jon Schlinkert, Olsten Larck, Rouven Weßling @@ -263,26 +262,6 @@ Repository: micromatch/micromatch --------------------------------------- -## minimalistic-assert -License: ISC -Repository: https://github.com/calvinmetcalf/minimalistic-assert.git - -> Copyright 2015 Calvin Metcalf -> -> Permission to use, copy, modify, and/or distribute this software for any purpose -> with or without fee is hereby granted, provided that the above copyright notice -> and this permission notice appear in all copies. -> -> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -> REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -> FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -> INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -> LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -> OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -> PERFORMANCE OF THIS SOFTWARE. - ---------------------------------------- - ## minimist License: MIT By: James Halliday diff --git a/browser/crypto.ts b/browser/crypto.ts new file mode 100644 index 00000000000..fdb2e8b2200 --- /dev/null +++ b/browser/crypto.ts @@ -0,0 +1,49 @@ +import * as asmCrypto from 'asmcrypto.js'; + +function createHash(algorithm: string) { + return new Hasher(algorithm); +} + +class Hasher { + hasher: asmCrypto.Sha256; + + constructor(algorithm: string) { + switch (algorithm) { + case 'sha256': + this.hasher = new asmCrypto.Sha256(); + break; + default: + throw new Error(`Unsupported algorithm: '${algorithm}'.`); + } + } + + digest(encoding: string) { + this.hasher.finish(); + // The type of '.result' is always 'Uint8Array' after calling 'finish()'. Before that, it could also be 'null'. Casting + // is necessary to avoid type errors when encoding the hash. + const hash = this.hasher.result as Uint8Array; + + let encoded: string; + switch (encoding) { + case 'hex': + encoded = asmCrypto.bytes_to_hex(hash); + break; + default: + throw new Error(`Unsupported encoding: '${encoding}'.`); + } + + return encoded; + } + + update(data: string | Buffer) { + if (typeof data === 'string') { + this.hasher.process(new TextEncoder().encode(data)); + } else { + this.hasher.process(data); + } + + return this; + } +} + +export { createHash }; diff --git a/package-lock.json b/package-lock.json index ad5d9b94a83..c31fa59f2c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -503,6 +503,12 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "asmcrypto.js": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/asmcrypto.js/-/asmcrypto.js-2.3.2.tgz", + "integrity": "sha512-3FgFARf7RupsZETQ1nHnhLUUvpcttcCq1iZCaVAbJZbCZ5VNRrNyvpDyHTOb0KC3llFcsyOT/a99NZcCbeiEsA==", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -2539,16 +2545,6 @@ } } }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", @@ -3943,12 +3939,6 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", diff --git a/package.json b/package.json index fa5e7e38791..fa026dca2ed 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "acorn-import-meta": "^1.0.0", "acorn-jsx": "^5.1.0", "acorn-walk": "^7.0.0", + "asmcrypto.js": "^2.3.2", "buble": "^0.19.8", "chokidar": "^2.1.8", "codecov": "^3.6.1", @@ -88,7 +89,6 @@ "eslint-plugin-import": "^2.18.2", "execa": "^3.2.0", "fixturify": "^1.2.0", - "hash.js": "^1.1.7", "husky": "^3.0.9", "is-reference": "^1.1.4", "lint-staged": "^9.4.2", diff --git a/rollup.config.js b/rollup.config.js index 16171315e91..74cc004878c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -171,7 +171,7 @@ export default command => { !command.configTest && license({ thirdParty: generateLicenseFile }) ], // acorn needs to be external as some plugins rely on a shared acorn instance - external: ['acorn', 'assert', 'events', 'fs', 'module', 'path', 'util'], + external: ['acorn', 'assert', 'crypto', 'events', 'fs', 'module', 'path', 'util'], treeshake, output: { banner, @@ -205,6 +205,7 @@ export default command => { json(), { load: id => { + if (~id.indexOf('crypto.ts')) return fs.readFileSync('browser/crypto.ts', 'utf-8'); if (~id.indexOf('fs.ts')) return fs.readFileSync('browser/fs.ts', 'utf-8'); if (~id.indexOf('path.ts')) return fs.readFileSync('browser/path.ts', 'utf-8'); } diff --git a/src/Chunk.ts b/src/Chunk.ts index beb66769f48..938fd64a834 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -1,5 +1,5 @@ -import sha256 from 'hash.js/lib/hash/sha/256'; import MagicString, { Bundle as MagicStringBundle, SourceMap } from 'magic-string'; +import { createHash } from '../browser/crypto'; import { relative } from '../browser/path'; import { createInclusionContext } from './ast/ExecutionContext'; import ExportDefaultDeclaration from './ast/nodes/ExportDefaultDeclaration'; @@ -366,7 +366,7 @@ export default class Chunk { getRenderedHash(): string { if (this.renderedHash) return this.renderedHash; if (!this.renderedSource) return ''; - const hash = sha256(); + const hash = createHash('sha256'); const hashAugmentation = this.calculateHashAugmentation(); hash.update(hashAugmentation); hash.update(this.renderedSource.toString()); @@ -860,7 +860,7 @@ export default class Chunk { options: OutputOptions, existingNames: Record ): string { - const hash = sha256(); + const hash = createHash('sha256'); hash.update( [addons.intro, addons.outro, addons.banner, addons.footer].map(addon => addon || '').join(':') ); diff --git a/src/utils/FileEmitter.ts b/src/utils/FileEmitter.ts index c6196285fc0..f18d87c8882 100644 --- a/src/utils/FileEmitter.ts +++ b/src/utils/FileEmitter.ts @@ -1,9 +1,9 @@ -import sha256 from 'hash.js/lib/hash/sha/256'; import Chunk from '../Chunk'; import Graph from '../Graph'; import Module from '../Module'; import { FilePlaceholder, OutputBundleWithPlaceholders } from '../rollup/types'; import { BuildPhase } from './buildPhase'; +import { createHash } from './crypto'; import { errAssetNotFinalisedForFileName, errAssetReferenceIdNotFoundForSetSource, @@ -33,7 +33,7 @@ function generateAssetFileName( return makeUnique( renderNamePattern(output.assetFileNames, 'output.assetFileNames', { hash() { - const hash = sha256(); + const hash = createHash('sha256'); hash.update(emittedName); hash.update(':'); hash.update(source); diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts new file mode 100644 index 00000000000..825256e0b8e --- /dev/null +++ b/src/utils/crypto.ts @@ -0,0 +1 @@ +export { createHash } from 'crypto'; diff --git a/typings/Chunk.d.ts b/typings/Chunk.d.ts deleted file mode 100644 index 5928d560977..00000000000 --- a/typings/Chunk.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module 'hash.js/lib/hash/sha/256' { - export default function sha256(): { - update: (data: any) => void; - digest: (format: string) => string; - }; -}