UNPKG

1.69 kBPlain TextView Raw
1import { Hash, SourceData } from "@aws-sdk/types";
2import { isEmptyData, convertToBuffer } from "@aws-crypto/util";
3import {
4 EMPTY_DATA_SHA_256,
5 SHA_256_HASH,
6 SHA_256_HMAC_ALGO,
7} from "./constants";
8import { locateWindow } from "@aws-sdk/util-locate-window";
9
10export class Sha256 implements Hash {
11 private readonly key: Promise<CryptoKey> | undefined;
12 private toHash: Uint8Array = new Uint8Array(0);
13
14 constructor(secret?: SourceData) {
15 if (secret !== void 0) {
16 this.key = new Promise((resolve, reject) => {
17 locateWindow()
18 .crypto.subtle.importKey(
19 "raw",
20 convertToBuffer(secret),
21 SHA_256_HMAC_ALGO,
22 false,
23 ["sign"]
24 )
25 .then(resolve, reject);
26 });
27 this.key.catch(() => {});
28 }
29 }
30
31 update(data: SourceData): void {
32 if (isEmptyData(data)) {
33 return;
34 }
35
36 const update = convertToBuffer(data);
37 const typedArray = new Uint8Array(
38 this.toHash.byteLength + update.byteLength
39 );
40 typedArray.set(this.toHash, 0);
41 typedArray.set(update, this.toHash.byteLength);
42 this.toHash = typedArray;
43 }
44
45 digest(): Promise<Uint8Array> {
46 if (this.key) {
47 return this.key.then((key) =>
48 locateWindow()
49 .crypto.subtle.sign(SHA_256_HMAC_ALGO, key, this.toHash)
50 .then((data) => new Uint8Array(data))
51 );
52 }
53
54 if (isEmptyData(this.toHash)) {
55 return Promise.resolve(EMPTY_DATA_SHA_256);
56 }
57
58 return Promise.resolve()
59 .then(() =>
60 locateWindow().crypto.subtle.digest(SHA_256_HASH, this.toHash)
61 )
62 .then((data) => Promise.resolve(new Uint8Array(data)));
63 }
64}