@smithy/signature-v4 5.4.7 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.js +27 -29
- package/package.json +6 -6
package/dist-cjs/index.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var client = require('@smithy/core/client');
|
|
5
|
-
var protocols = require('@smithy/core/protocols');
|
|
1
|
+
const { fromUtf8, fromHex, toHex, toUint8Array, isArrayBuffer } = require("@smithy/core/serde");
|
|
2
|
+
const { normalizeProvider } = require("@smithy/core/client");
|
|
3
|
+
const { escapeUri, HttpRequest } = require("@smithy/core/protocols");
|
|
6
4
|
|
|
7
5
|
class HeaderFormatter {
|
|
8
6
|
format(headers) {
|
|
9
7
|
const chunks = [];
|
|
10
8
|
for (const headerName of Object.keys(headers)) {
|
|
11
|
-
const bytes =
|
|
9
|
+
const bytes = fromUtf8(headerName);
|
|
12
10
|
chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName]));
|
|
13
11
|
}
|
|
14
12
|
const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
|
|
@@ -48,7 +46,7 @@ class HeaderFormatter {
|
|
|
48
46
|
binBytes.set(header.value, 3);
|
|
49
47
|
return binBytes;
|
|
50
48
|
case "string":
|
|
51
|
-
const utf8Bytes =
|
|
49
|
+
const utf8Bytes = fromUtf8(header.value);
|
|
52
50
|
const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength));
|
|
53
51
|
strView.setUint8(0, 7);
|
|
54
52
|
strView.setUint16(1, utf8Bytes.byteLength, false);
|
|
@@ -66,7 +64,7 @@ class HeaderFormatter {
|
|
|
66
64
|
}
|
|
67
65
|
const uuidBytes = new Uint8Array(17);
|
|
68
66
|
uuidBytes[0] = 9;
|
|
69
|
-
uuidBytes.set(
|
|
67
|
+
uuidBytes.set(fromHex(header.value.replace(/\-/g, "")), 1);
|
|
70
68
|
return uuidBytes;
|
|
71
69
|
}
|
|
72
70
|
}
|
|
@@ -112,7 +110,7 @@ class Int64 {
|
|
|
112
110
|
if (negative) {
|
|
113
111
|
negate(bytes);
|
|
114
112
|
}
|
|
115
|
-
return parseInt(
|
|
113
|
+
return parseInt(toHex(bytes), 16) * (negative ? -1 : 1);
|
|
116
114
|
}
|
|
117
115
|
toString() {
|
|
118
116
|
return String(this.valueOf());
|
|
@@ -180,16 +178,16 @@ const getCanonicalQuery = ({ query = {} }) => {
|
|
|
180
178
|
if (key.toLowerCase() === SIGNATURE_HEADER) {
|
|
181
179
|
continue;
|
|
182
180
|
}
|
|
183
|
-
const encodedKey =
|
|
181
|
+
const encodedKey = escapeUri(key);
|
|
184
182
|
keys.push(encodedKey);
|
|
185
183
|
const value = query[key];
|
|
186
184
|
if (typeof value === "string") {
|
|
187
|
-
serialized[encodedKey] = `${encodedKey}=${
|
|
185
|
+
serialized[encodedKey] = `${encodedKey}=${escapeUri(value)}`;
|
|
188
186
|
}
|
|
189
187
|
else if (Array.isArray(value)) {
|
|
190
188
|
serialized[encodedKey] = value
|
|
191
189
|
.slice(0)
|
|
192
|
-
.reduce((encoded, value) => encoded.concat([`${encodedKey}=${
|
|
190
|
+
.reduce((encoded, value) => encoded.concat([`${encodedKey}=${escapeUri(value)}`]), [])
|
|
193
191
|
.sort()
|
|
194
192
|
.join("&");
|
|
195
193
|
}
|
|
@@ -229,8 +227,8 @@ class SignatureV4Base {
|
|
|
229
227
|
this.sha256 = sha256;
|
|
230
228
|
this.uriEscapePath = uriEscapePath;
|
|
231
229
|
this.applyChecksum = typeof applyChecksum === "boolean" ? applyChecksum : true;
|
|
232
|
-
this.regionProvider =
|
|
233
|
-
this.credentialProvider =
|
|
230
|
+
this.regionProvider = normalizeProvider(region);
|
|
231
|
+
this.credentialProvider = normalizeProvider(credentials);
|
|
234
232
|
}
|
|
235
233
|
createCanonicalRequest(request, canonicalHeaders, payloadHash) {
|
|
236
234
|
const sortedHeaders = Object.keys(canonicalHeaders).sort();
|
|
@@ -244,12 +242,12 @@ ${payloadHash}`;
|
|
|
244
242
|
}
|
|
245
243
|
async createStringToSign(longDate, credentialScope, canonicalRequest, algorithmIdentifier) {
|
|
246
244
|
const hash = new this.sha256();
|
|
247
|
-
hash.update(
|
|
245
|
+
hash.update(toUint8Array(canonicalRequest));
|
|
248
246
|
const hashedRequest = await hash.digest();
|
|
249
247
|
return `${algorithmIdentifier}
|
|
250
248
|
${longDate}
|
|
251
249
|
${credentialScope}
|
|
252
|
-
${
|
|
250
|
+
${toHex(hashedRequest)}`;
|
|
253
251
|
}
|
|
254
252
|
getCanonicalPath({ path }) {
|
|
255
253
|
if (this.uriEscapePath) {
|
|
@@ -267,7 +265,7 @@ ${serde.toHex(hashedRequest)}`;
|
|
|
267
265
|
}
|
|
268
266
|
}
|
|
269
267
|
const normalizedPath = `${path?.startsWith("/") ? "/" : ""}${normalizedPathSegments.join("/")}${normalizedPathSegments.length > 0 && path?.endsWith("/") ? "/" : ""}`;
|
|
270
|
-
const doubleEncoded =
|
|
268
|
+
const doubleEncoded = escapeUri(normalizedPath);
|
|
271
269
|
return doubleEncoded.replace(/%2F/g, "/");
|
|
272
270
|
}
|
|
273
271
|
return path;
|
|
@@ -296,7 +294,7 @@ const cacheQueue = [];
|
|
|
296
294
|
const createScope = (shortDate, region, service) => `${shortDate}/${region}/${service}/${KEY_TYPE_IDENTIFIER}`;
|
|
297
295
|
const getSigningKey = async (sha256Constructor, credentials, shortDate, region, service) => {
|
|
298
296
|
const credsHash = await hmac(sha256Constructor, credentials.secretAccessKey, credentials.accessKeyId);
|
|
299
|
-
const cacheKey = `${shortDate}:${region}:${service}:${
|
|
297
|
+
const cacheKey = `${shortDate}:${region}:${service}:${toHex(credsHash)}:${credentials.sessionToken}`;
|
|
300
298
|
if (cacheKey in signingKeyCache) {
|
|
301
299
|
return signingKeyCache[cacheKey];
|
|
302
300
|
}
|
|
@@ -318,7 +316,7 @@ const clearCredentialCache = () => {
|
|
|
318
316
|
};
|
|
319
317
|
const hmac = (ctor, secret, data) => {
|
|
320
318
|
const hash = new ctor(secret);
|
|
321
|
-
hash.update(
|
|
319
|
+
hash.update(toUint8Array(data));
|
|
322
320
|
return hash.digest();
|
|
323
321
|
};
|
|
324
322
|
|
|
@@ -351,10 +349,10 @@ const getPayloadHash = async ({ headers, body }, hashConstructor) => {
|
|
|
351
349
|
if (body == undefined) {
|
|
352
350
|
return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
353
351
|
}
|
|
354
|
-
else if (typeof body === "string" || ArrayBuffer.isView(body) ||
|
|
352
|
+
else if (typeof body === "string" || ArrayBuffer.isView(body) || isArrayBuffer(body)) {
|
|
355
353
|
const hashCtor = new hashConstructor();
|
|
356
|
-
hashCtor.update(
|
|
357
|
-
return
|
|
354
|
+
hashCtor.update(toUint8Array(body));
|
|
355
|
+
return toHex(await hashCtor.digest());
|
|
358
356
|
}
|
|
359
357
|
return UNSIGNED_PAYLOAD;
|
|
360
358
|
};
|
|
@@ -370,7 +368,7 @@ const hasHeader = (soughtHeader, headers) => {
|
|
|
370
368
|
};
|
|
371
369
|
|
|
372
370
|
const moveHeadersToQuery = (request, options = {}) => {
|
|
373
|
-
const { headers, query = {} } =
|
|
371
|
+
const { headers, query = {} } = HttpRequest.clone(request);
|
|
374
372
|
for (const name of Object.keys(headers)) {
|
|
375
373
|
const lname = name.toLowerCase();
|
|
376
374
|
if ((lname.slice(0, 6) === "x-amz-" && !options.unhoistableHeaders?.has(lname)) ||
|
|
@@ -387,7 +385,7 @@ const moveHeadersToQuery = (request, options = {}) => {
|
|
|
387
385
|
};
|
|
388
386
|
|
|
389
387
|
const prepareRequest = (request) => {
|
|
390
|
-
request =
|
|
388
|
+
request = HttpRequest.clone(request);
|
|
391
389
|
for (const headerName of Object.keys(request.headers)) {
|
|
392
390
|
if (GENERATED_HEADERS.indexOf(headerName.toLowerCase()) > -1) {
|
|
393
391
|
delete request.headers[headerName];
|
|
@@ -452,7 +450,7 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
452
450
|
const hashedPayload = await getPayloadHash({ headers: {}, body: payload }, this.sha256);
|
|
453
451
|
const hash = new this.sha256();
|
|
454
452
|
hash.update(headers);
|
|
455
|
-
const hashedHeaders =
|
|
453
|
+
const hashedHeaders = toHex(await hash.digest());
|
|
456
454
|
const stringToSign = [
|
|
457
455
|
EVENT_ALGORITHM_IDENTIFIER,
|
|
458
456
|
longDate,
|
|
@@ -489,8 +487,8 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
489
487
|
const region = signingRegion ?? (await this.regionProvider());
|
|
490
488
|
const { shortDate } = this.formatDate(signingDate);
|
|
491
489
|
const hash = new this.sha256(await this.getSigningKey(credentials, region, shortDate, signingService));
|
|
492
|
-
hash.update(
|
|
493
|
-
return
|
|
490
|
+
hash.update(toUint8Array(stringToSign));
|
|
491
|
+
return toHex(await hash.digest());
|
|
494
492
|
}
|
|
495
493
|
async signRequest(requestToSign, { signingDate = new Date(), signableHeaders, unsignableHeaders, signingRegion, signingService, } = {}) {
|
|
496
494
|
const credentials = await this.credentialProvider();
|
|
@@ -519,8 +517,8 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
519
517
|
async getSignature(longDate, credentialScope, keyPromise, canonicalRequest) {
|
|
520
518
|
const stringToSign = await this.createStringToSign(longDate, credentialScope, canonicalRequest, ALGORITHM_IDENTIFIER);
|
|
521
519
|
const hash = new this.sha256(await keyPromise);
|
|
522
|
-
hash.update(
|
|
523
|
-
return
|
|
520
|
+
hash.update(toUint8Array(stringToSign));
|
|
521
|
+
return toHex(await hash.digest());
|
|
524
522
|
}
|
|
525
523
|
getSigningKey(credentials, region, shortDate, service) {
|
|
526
524
|
return getSigningKey(this.sha256, credentials, shortDate, region, service || this.service);
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithy/signature-v4",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "A standalone implementation of the AWS Signature V4 request signing algorithm",
|
|
5
5
|
"main": "./dist-cjs/index.js",
|
|
6
6
|
"module": "./dist-es/index.js",
|
|
7
7
|
"types": "./dist-types/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "concurrently 'yarn:build:types' 'yarn:build:es:cjs'",
|
|
10
|
-
"build:es:cjs": "yarn g:tsc -p tsconfig.es.json && node ../../scripts/inline",
|
|
11
|
-
"build:types": "yarn g:tsc -p tsconfig.types.json",
|
|
10
|
+
"build:es:cjs": "premove dist-es && yarn g:tsc -p tsconfig.es.json && node ../../scripts/inline",
|
|
11
|
+
"build:types": "premove dist-types && yarn g:tsc -p tsconfig.types.json",
|
|
12
12
|
"build:types:downlevel": "premove dist-types/ts3.4 && downlevel-dts dist-types dist-types/ts3.4",
|
|
13
|
-
"clean": "premove dist-cjs dist-es dist-types
|
|
13
|
+
"clean": "premove dist-cjs dist-es dist-types",
|
|
14
14
|
"extract:docs": "api-extractor run --local",
|
|
15
15
|
"format": "prettier --config ../../prettier.config.js --ignore-path ../../.prettierignore --write \"**/*.{ts,md,json}\"",
|
|
16
16
|
"lint": "eslint -c ../../.eslintrc.js \"src/**/*.ts\"",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@smithy/core": "^3.
|
|
29
|
-
"@smithy/types": "^4.
|
|
28
|
+
"@smithy/core": "^3.25.0",
|
|
29
|
+
"@smithy/types": "^4.15.0",
|
|
30
30
|
"tslib": "^2.6.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|