-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: CDK does not work in FIPS-restricted environments
In an environment where node is compiled with FIPS restrictions in mind, `crypto.createHash('md5')` does not work, for fear of MD5 being used for crypto purposes. We do not use it for crypto purposes, just to come up with unique identifiers for certain constructs. Nevertheless, CDK cannot work if `md5` is not available from the Node standard library. Fall back to a pure JavaScript implementation if the built-in MD5 hash does not work, so that we produce equivalent templates.
- Loading branch information
Showing
17 changed files
with
244 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
export * from './cfn-parse'; | ||
export * from './cfn-parse'; | ||
|
||
// Other libraries are going to need this as well | ||
export { md5hash } from '../private/md5'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
/** | ||
* md5 hashing | ||
* | ||
* Uses the built-in 'crypto' library by default for a C implementation | ||
* of md5, but in case the crypto library has been compiled to disable | ||
* FIPS-noncompliant hash suites, fall back to a pure JS implementation of | ||
* md5. | ||
*/ | ||
import * as crypto from 'crypto'; | ||
|
||
let _impl: undefined | ((x: string) => string); | ||
|
||
/** | ||
* Return a hash of the given input string, in hex format | ||
*/ | ||
export function md5hash(x: string) { | ||
if (!_impl) { | ||
try { | ||
crypto.createHash('md5'); | ||
_impl = cryptoMd5; | ||
} catch (e) { | ||
_impl = jsMd5; | ||
} | ||
} | ||
return _impl(x); | ||
} | ||
|
||
/* eslint-disable no-bitwise */ | ||
/* eslint-disable no-restricted-syntax */ | ||
|
||
export function cryptoMd5(x: string) { | ||
const hash = crypto.createHash('md5'); | ||
hash.update(x); | ||
return hash.digest('hex'); | ||
} | ||
|
||
export function jsMd5(s: string) { | ||
return hex(md51(s)); | ||
} | ||
|
||
function md5cycle(x: number[], k: number[]) { | ||
let a = x[0], b = x[1], c = x[2], 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: number, a: number, b: number, x: number, s: number, t: number) { | ||
a = add32(add32(a, q), add32(x, t)); | ||
return add32((a << s) | (a >>> (32 - s)), b); | ||
} | ||
|
||
function ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { | ||
return cmn((b & c) | (~b & d), a, b, x, s, t); | ||
} | ||
|
||
function gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { | ||
return cmn((b & d) | (c & ~d), a, b, x, s, t); | ||
} | ||
|
||
function hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { | ||
return cmn(b ^ c ^ d, a, b, x, s, t); | ||
} | ||
|
||
function ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { | ||
return cmn(c ^ (b | ~d), a, b, x, s, t); | ||
} | ||
|
||
function md51(s: string) { | ||
let n = s.length, | ||
state = [1732584193, -271733879, -1732584194, 271733878], | ||
i; | ||
for (i = 64; i <= s.length; i += 64) { | ||
md5cycle(state, md5blk(s.substring(i - 64, i))); | ||
} | ||
s = s.substring(i - 64); | ||
let 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; | ||
} | ||
|
||
function md5blk(s: string) { | ||
let md5blks = [], i; | ||
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; | ||
} | ||
|
||
let hex_chr = '0123456789abcdef'.split(''); | ||
|
||
function rhex(n: number) { | ||
let s = '', 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: number[]) { | ||
const ret = new Array<string>(x.length); | ||
for (let i = 0; i < x.length; i++) ret[i] = rhex(x[i]); | ||
return ret.join(''); | ||
} | ||
|
||
function add32(a: number, b: number) { | ||
return (a + b) & 0xffffffff; | ||
} |
Oops, something went wrong.