@smithy/signature-v4 5.3.14 → 5.4.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 +167 -170
- package/dist-es/HeaderFormatter.js +1 -2
- package/dist-es/SignatureV4.js +3 -4
- package/dist-es/SignatureV4Base.js +3 -4
- package/dist-es/credentialDerivation.js +1 -2
- package/dist-es/getCanonicalQuery.js +1 -1
- package/dist-es/getPayloadHash.js +1 -3
- package/dist-es/moveHeadersToQuery.js +1 -1
- package/dist-es/prepareRequest.js +1 -1
- package/dist-types/SignatureV4.d.ts +1 -2
- package/dist-types/index.d.ts +1 -1
- package/package.json +2 -7
package/dist-cjs/index.js
CHANGED
|
@@ -1,129 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var protocolHttp = require('@smithy/protocol-http');
|
|
7
|
-
var utilMiddleware = require('@smithy/util-middleware');
|
|
8
|
-
var utilUriEscape = require('@smithy/util-uri-escape');
|
|
9
|
-
|
|
10
|
-
const ALGORITHM_QUERY_PARAM = "X-Amz-Algorithm";
|
|
11
|
-
const CREDENTIAL_QUERY_PARAM = "X-Amz-Credential";
|
|
12
|
-
const AMZ_DATE_QUERY_PARAM = "X-Amz-Date";
|
|
13
|
-
const SIGNED_HEADERS_QUERY_PARAM = "X-Amz-SignedHeaders";
|
|
14
|
-
const EXPIRES_QUERY_PARAM = "X-Amz-Expires";
|
|
15
|
-
const SIGNATURE_QUERY_PARAM = "X-Amz-Signature";
|
|
16
|
-
const TOKEN_QUERY_PARAM = "X-Amz-Security-Token";
|
|
17
|
-
const REGION_SET_PARAM = "X-Amz-Region-Set";
|
|
18
|
-
const AUTH_HEADER = "authorization";
|
|
19
|
-
const AMZ_DATE_HEADER = AMZ_DATE_QUERY_PARAM.toLowerCase();
|
|
20
|
-
const DATE_HEADER = "date";
|
|
21
|
-
const GENERATED_HEADERS = [AUTH_HEADER, AMZ_DATE_HEADER, DATE_HEADER];
|
|
22
|
-
const SIGNATURE_HEADER = SIGNATURE_QUERY_PARAM.toLowerCase();
|
|
23
|
-
const SHA256_HEADER = "x-amz-content-sha256";
|
|
24
|
-
const TOKEN_HEADER = TOKEN_QUERY_PARAM.toLowerCase();
|
|
25
|
-
const HOST_HEADER = "host";
|
|
26
|
-
const ALWAYS_UNSIGNABLE_HEADERS = {
|
|
27
|
-
authorization: true,
|
|
28
|
-
"cache-control": true,
|
|
29
|
-
connection: true,
|
|
30
|
-
expect: true,
|
|
31
|
-
from: true,
|
|
32
|
-
"keep-alive": true,
|
|
33
|
-
"max-forwards": true,
|
|
34
|
-
pragma: true,
|
|
35
|
-
referer: true,
|
|
36
|
-
te: true,
|
|
37
|
-
trailer: true,
|
|
38
|
-
"transfer-encoding": true,
|
|
39
|
-
upgrade: true,
|
|
40
|
-
"user-agent": true,
|
|
41
|
-
"x-amzn-trace-id": true,
|
|
42
|
-
};
|
|
43
|
-
const PROXY_HEADER_PATTERN = /^proxy-/;
|
|
44
|
-
const SEC_HEADER_PATTERN = /^sec-/;
|
|
45
|
-
const UNSIGNABLE_PATTERNS = [/^proxy-/i, /^sec-/i];
|
|
46
|
-
const ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256";
|
|
47
|
-
const ALGORITHM_IDENTIFIER_V4A = "AWS4-ECDSA-P256-SHA256";
|
|
48
|
-
const EVENT_ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256-PAYLOAD";
|
|
49
|
-
const UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
|
50
|
-
const MAX_CACHE_SIZE = 50;
|
|
51
|
-
const KEY_TYPE_IDENTIFIER = "aws4_request";
|
|
52
|
-
const MAX_PRESIGNED_TTL = 60 * 60 * 24 * 7;
|
|
53
|
-
|
|
54
|
-
const signingKeyCache = {};
|
|
55
|
-
const cacheQueue = [];
|
|
56
|
-
const createScope = (shortDate, region, service) => `${shortDate}/${region}/${service}/${KEY_TYPE_IDENTIFIER}`;
|
|
57
|
-
const getSigningKey = async (sha256Constructor, credentials, shortDate, region, service) => {
|
|
58
|
-
const credsHash = await hmac(sha256Constructor, credentials.secretAccessKey, credentials.accessKeyId);
|
|
59
|
-
const cacheKey = `${shortDate}:${region}:${service}:${utilHexEncoding.toHex(credsHash)}:${credentials.sessionToken}`;
|
|
60
|
-
if (cacheKey in signingKeyCache) {
|
|
61
|
-
return signingKeyCache[cacheKey];
|
|
62
|
-
}
|
|
63
|
-
cacheQueue.push(cacheKey);
|
|
64
|
-
while (cacheQueue.length > MAX_CACHE_SIZE) {
|
|
65
|
-
delete signingKeyCache[cacheQueue.shift()];
|
|
66
|
-
}
|
|
67
|
-
let key = `AWS4${credentials.secretAccessKey}`;
|
|
68
|
-
for (const signable of [shortDate, region, service, KEY_TYPE_IDENTIFIER]) {
|
|
69
|
-
key = await hmac(sha256Constructor, key, signable);
|
|
70
|
-
}
|
|
71
|
-
return (signingKeyCache[cacheKey] = key);
|
|
72
|
-
};
|
|
73
|
-
const clearCredentialCache = () => {
|
|
74
|
-
cacheQueue.length = 0;
|
|
75
|
-
Object.keys(signingKeyCache).forEach((cacheKey) => {
|
|
76
|
-
delete signingKeyCache[cacheKey];
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
const hmac = (ctor, secret, data) => {
|
|
80
|
-
const hash = new ctor(secret);
|
|
81
|
-
hash.update(utilUtf8.toUint8Array(data));
|
|
82
|
-
return hash.digest();
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const getCanonicalHeaders = ({ headers }, unsignableHeaders, signableHeaders) => {
|
|
86
|
-
const canonical = {};
|
|
87
|
-
for (const headerName of Object.keys(headers).sort()) {
|
|
88
|
-
if (headers[headerName] == undefined) {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const canonicalHeaderName = headerName.toLowerCase();
|
|
92
|
-
if (canonicalHeaderName in ALWAYS_UNSIGNABLE_HEADERS ||
|
|
93
|
-
unsignableHeaders?.has(canonicalHeaderName) ||
|
|
94
|
-
PROXY_HEADER_PATTERN.test(canonicalHeaderName) ||
|
|
95
|
-
SEC_HEADER_PATTERN.test(canonicalHeaderName)) {
|
|
96
|
-
if (!signableHeaders || (signableHeaders && !signableHeaders.has(canonicalHeaderName))) {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
canonical[canonicalHeaderName] = headers[headerName].trim().replace(/\s+/g, " ");
|
|
101
|
-
}
|
|
102
|
-
return canonical;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const getPayloadHash = async ({ headers, body }, hashConstructor) => {
|
|
106
|
-
for (const headerName of Object.keys(headers)) {
|
|
107
|
-
if (headerName.toLowerCase() === SHA256_HEADER) {
|
|
108
|
-
return headers[headerName];
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (body == undefined) {
|
|
112
|
-
return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
113
|
-
}
|
|
114
|
-
else if (typeof body === "string" || ArrayBuffer.isView(body) || isArrayBuffer.isArrayBuffer(body)) {
|
|
115
|
-
const hashCtor = new hashConstructor();
|
|
116
|
-
hashCtor.update(utilUtf8.toUint8Array(body));
|
|
117
|
-
return utilHexEncoding.toHex(await hashCtor.digest());
|
|
118
|
-
}
|
|
119
|
-
return UNSIGNED_PAYLOAD;
|
|
120
|
-
};
|
|
3
|
+
var serde = require('@smithy/core/serde');
|
|
4
|
+
var client = require('@smithy/core/client');
|
|
5
|
+
var protocols = require('@smithy/core/protocols');
|
|
121
6
|
|
|
122
7
|
class HeaderFormatter {
|
|
123
8
|
format(headers) {
|
|
124
9
|
const chunks = [];
|
|
125
10
|
for (const headerName of Object.keys(headers)) {
|
|
126
|
-
const bytes =
|
|
11
|
+
const bytes = serde.fromUtf8(headerName);
|
|
127
12
|
chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName]));
|
|
128
13
|
}
|
|
129
14
|
const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
|
|
@@ -163,7 +48,7 @@ class HeaderFormatter {
|
|
|
163
48
|
binBytes.set(header.value, 3);
|
|
164
49
|
return binBytes;
|
|
165
50
|
case "string":
|
|
166
|
-
const utf8Bytes =
|
|
51
|
+
const utf8Bytes = serde.fromUtf8(header.value);
|
|
167
52
|
const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength));
|
|
168
53
|
strView.setUint8(0, 7);
|
|
169
54
|
strView.setUint16(1, utf8Bytes.byteLength, false);
|
|
@@ -181,7 +66,7 @@ class HeaderFormatter {
|
|
|
181
66
|
}
|
|
182
67
|
const uuidBytes = new Uint8Array(17);
|
|
183
68
|
uuidBytes[0] = 9;
|
|
184
|
-
uuidBytes.set(
|
|
69
|
+
uuidBytes.set(serde.fromHex(header.value.replace(/\-/g, "")), 1);
|
|
185
70
|
return uuidBytes;
|
|
186
71
|
}
|
|
187
72
|
}
|
|
@@ -227,7 +112,7 @@ class Int64 {
|
|
|
227
112
|
if (negative) {
|
|
228
113
|
negate(bytes);
|
|
229
114
|
}
|
|
230
|
-
return parseInt(
|
|
115
|
+
return parseInt(serde.toHex(bytes), 16) * (negative ? -1 : 1);
|
|
231
116
|
}
|
|
232
117
|
toString() {
|
|
233
118
|
return String(this.valueOf());
|
|
@@ -244,42 +129,49 @@ function negate(bytes) {
|
|
|
244
129
|
}
|
|
245
130
|
}
|
|
246
131
|
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return request;
|
|
132
|
+
const ALGORITHM_QUERY_PARAM = "X-Amz-Algorithm";
|
|
133
|
+
const CREDENTIAL_QUERY_PARAM = "X-Amz-Credential";
|
|
134
|
+
const AMZ_DATE_QUERY_PARAM = "X-Amz-Date";
|
|
135
|
+
const SIGNED_HEADERS_QUERY_PARAM = "X-Amz-SignedHeaders";
|
|
136
|
+
const EXPIRES_QUERY_PARAM = "X-Amz-Expires";
|
|
137
|
+
const SIGNATURE_QUERY_PARAM = "X-Amz-Signature";
|
|
138
|
+
const TOKEN_QUERY_PARAM = "X-Amz-Security-Token";
|
|
139
|
+
const REGION_SET_PARAM = "X-Amz-Region-Set";
|
|
140
|
+
const AUTH_HEADER = "authorization";
|
|
141
|
+
const AMZ_DATE_HEADER = AMZ_DATE_QUERY_PARAM.toLowerCase();
|
|
142
|
+
const DATE_HEADER = "date";
|
|
143
|
+
const GENERATED_HEADERS = [AUTH_HEADER, AMZ_DATE_HEADER, DATE_HEADER];
|
|
144
|
+
const SIGNATURE_HEADER = SIGNATURE_QUERY_PARAM.toLowerCase();
|
|
145
|
+
const SHA256_HEADER = "x-amz-content-sha256";
|
|
146
|
+
const TOKEN_HEADER = TOKEN_QUERY_PARAM.toLowerCase();
|
|
147
|
+
const HOST_HEADER = "host";
|
|
148
|
+
const ALWAYS_UNSIGNABLE_HEADERS = {
|
|
149
|
+
authorization: true,
|
|
150
|
+
"cache-control": true,
|
|
151
|
+
connection: true,
|
|
152
|
+
expect: true,
|
|
153
|
+
from: true,
|
|
154
|
+
"keep-alive": true,
|
|
155
|
+
"max-forwards": true,
|
|
156
|
+
pragma: true,
|
|
157
|
+
referer: true,
|
|
158
|
+
te: true,
|
|
159
|
+
trailer: true,
|
|
160
|
+
"transfer-encoding": true,
|
|
161
|
+
upgrade: true,
|
|
162
|
+
"user-agent": true,
|
|
163
|
+
"x-amzn-trace-id": true,
|
|
282
164
|
};
|
|
165
|
+
const PROXY_HEADER_PATTERN = /^proxy-/;
|
|
166
|
+
const SEC_HEADER_PATTERN = /^sec-/;
|
|
167
|
+
const UNSIGNABLE_PATTERNS = [/^proxy-/i, /^sec-/i];
|
|
168
|
+
const ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256";
|
|
169
|
+
const ALGORITHM_IDENTIFIER_V4A = "AWS4-ECDSA-P256-SHA256";
|
|
170
|
+
const EVENT_ALGORITHM_IDENTIFIER = "AWS4-HMAC-SHA256-PAYLOAD";
|
|
171
|
+
const UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
|
172
|
+
const MAX_CACHE_SIZE = 50;
|
|
173
|
+
const KEY_TYPE_IDENTIFIER = "aws4_request";
|
|
174
|
+
const MAX_PRESIGNED_TTL = 60 * 60 * 24 * 7;
|
|
283
175
|
|
|
284
176
|
const getCanonicalQuery = ({ query = {} }) => {
|
|
285
177
|
const keys = [];
|
|
@@ -288,16 +180,16 @@ const getCanonicalQuery = ({ query = {} }) => {
|
|
|
288
180
|
if (key.toLowerCase() === SIGNATURE_HEADER) {
|
|
289
181
|
continue;
|
|
290
182
|
}
|
|
291
|
-
const encodedKey =
|
|
183
|
+
const encodedKey = protocols.escapeUri(key);
|
|
292
184
|
keys.push(encodedKey);
|
|
293
185
|
const value = query[key];
|
|
294
186
|
if (typeof value === "string") {
|
|
295
|
-
serialized[encodedKey] = `${encodedKey}=${
|
|
187
|
+
serialized[encodedKey] = `${encodedKey}=${protocols.escapeUri(value)}`;
|
|
296
188
|
}
|
|
297
189
|
else if (Array.isArray(value)) {
|
|
298
190
|
serialized[encodedKey] = value
|
|
299
191
|
.slice(0)
|
|
300
|
-
.reduce((encoded, value) => encoded.concat([`${encodedKey}=${
|
|
192
|
+
.reduce((encoded, value) => encoded.concat([`${encodedKey}=${protocols.escapeUri(value)}`]), [])
|
|
301
193
|
.sort()
|
|
302
194
|
.join("&");
|
|
303
195
|
}
|
|
@@ -337,8 +229,8 @@ class SignatureV4Base {
|
|
|
337
229
|
this.sha256 = sha256;
|
|
338
230
|
this.uriEscapePath = uriEscapePath;
|
|
339
231
|
this.applyChecksum = typeof applyChecksum === "boolean" ? applyChecksum : true;
|
|
340
|
-
this.regionProvider =
|
|
341
|
-
this.credentialProvider =
|
|
232
|
+
this.regionProvider = client.normalizeProvider(region);
|
|
233
|
+
this.credentialProvider = client.normalizeProvider(credentials);
|
|
342
234
|
}
|
|
343
235
|
createCanonicalRequest(request, canonicalHeaders, payloadHash) {
|
|
344
236
|
const sortedHeaders = Object.keys(canonicalHeaders).sort();
|
|
@@ -352,12 +244,12 @@ ${payloadHash}`;
|
|
|
352
244
|
}
|
|
353
245
|
async createStringToSign(longDate, credentialScope, canonicalRequest, algorithmIdentifier) {
|
|
354
246
|
const hash = new this.sha256();
|
|
355
|
-
hash.update(
|
|
247
|
+
hash.update(serde.toUint8Array(canonicalRequest));
|
|
356
248
|
const hashedRequest = await hash.digest();
|
|
357
249
|
return `${algorithmIdentifier}
|
|
358
250
|
${longDate}
|
|
359
251
|
${credentialScope}
|
|
360
|
-
${
|
|
252
|
+
${serde.toHex(hashedRequest)}`;
|
|
361
253
|
}
|
|
362
254
|
getCanonicalPath({ path }) {
|
|
363
255
|
if (this.uriEscapePath) {
|
|
@@ -375,7 +267,7 @@ ${utilHexEncoding.toHex(hashedRequest)}`;
|
|
|
375
267
|
}
|
|
376
268
|
}
|
|
377
269
|
const normalizedPath = `${path?.startsWith("/") ? "/" : ""}${normalizedPathSegments.join("/")}${normalizedPathSegments.length > 0 && path?.endsWith("/") ? "/" : ""}`;
|
|
378
|
-
const doubleEncoded =
|
|
270
|
+
const doubleEncoded = protocols.escapeUri(normalizedPath);
|
|
379
271
|
return doubleEncoded.replace(/%2F/g, "/");
|
|
380
272
|
}
|
|
381
273
|
return path;
|
|
@@ -399,6 +291,111 @@ ${utilHexEncoding.toHex(hashedRequest)}`;
|
|
|
399
291
|
}
|
|
400
292
|
}
|
|
401
293
|
|
|
294
|
+
const signingKeyCache = {};
|
|
295
|
+
const cacheQueue = [];
|
|
296
|
+
const createScope = (shortDate, region, service) => `${shortDate}/${region}/${service}/${KEY_TYPE_IDENTIFIER}`;
|
|
297
|
+
const getSigningKey = async (sha256Constructor, credentials, shortDate, region, service) => {
|
|
298
|
+
const credsHash = await hmac(sha256Constructor, credentials.secretAccessKey, credentials.accessKeyId);
|
|
299
|
+
const cacheKey = `${shortDate}:${region}:${service}:${serde.toHex(credsHash)}:${credentials.sessionToken}`;
|
|
300
|
+
if (cacheKey in signingKeyCache) {
|
|
301
|
+
return signingKeyCache[cacheKey];
|
|
302
|
+
}
|
|
303
|
+
cacheQueue.push(cacheKey);
|
|
304
|
+
while (cacheQueue.length > MAX_CACHE_SIZE) {
|
|
305
|
+
delete signingKeyCache[cacheQueue.shift()];
|
|
306
|
+
}
|
|
307
|
+
let key = `AWS4${credentials.secretAccessKey}`;
|
|
308
|
+
for (const signable of [shortDate, region, service, KEY_TYPE_IDENTIFIER]) {
|
|
309
|
+
key = await hmac(sha256Constructor, key, signable);
|
|
310
|
+
}
|
|
311
|
+
return (signingKeyCache[cacheKey] = key);
|
|
312
|
+
};
|
|
313
|
+
const clearCredentialCache = () => {
|
|
314
|
+
cacheQueue.length = 0;
|
|
315
|
+
Object.keys(signingKeyCache).forEach((cacheKey) => {
|
|
316
|
+
delete signingKeyCache[cacheKey];
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
const hmac = (ctor, secret, data) => {
|
|
320
|
+
const hash = new ctor(secret);
|
|
321
|
+
hash.update(serde.toUint8Array(data));
|
|
322
|
+
return hash.digest();
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const getCanonicalHeaders = ({ headers }, unsignableHeaders, signableHeaders) => {
|
|
326
|
+
const canonical = {};
|
|
327
|
+
for (const headerName of Object.keys(headers).sort()) {
|
|
328
|
+
if (headers[headerName] == undefined) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const canonicalHeaderName = headerName.toLowerCase();
|
|
332
|
+
if (canonicalHeaderName in ALWAYS_UNSIGNABLE_HEADERS ||
|
|
333
|
+
unsignableHeaders?.has(canonicalHeaderName) ||
|
|
334
|
+
PROXY_HEADER_PATTERN.test(canonicalHeaderName) ||
|
|
335
|
+
SEC_HEADER_PATTERN.test(canonicalHeaderName)) {
|
|
336
|
+
if (!signableHeaders || (signableHeaders && !signableHeaders.has(canonicalHeaderName))) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
canonical[canonicalHeaderName] = headers[headerName].trim().replace(/\s+/g, " ");
|
|
341
|
+
}
|
|
342
|
+
return canonical;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const getPayloadHash = async ({ headers, body }, hashConstructor) => {
|
|
346
|
+
for (const headerName of Object.keys(headers)) {
|
|
347
|
+
if (headerName.toLowerCase() === SHA256_HEADER) {
|
|
348
|
+
return headers[headerName];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (body == undefined) {
|
|
352
|
+
return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
353
|
+
}
|
|
354
|
+
else if (typeof body === "string" || ArrayBuffer.isView(body) || serde.isArrayBuffer(body)) {
|
|
355
|
+
const hashCtor = new hashConstructor();
|
|
356
|
+
hashCtor.update(serde.toUint8Array(body));
|
|
357
|
+
return serde.toHex(await hashCtor.digest());
|
|
358
|
+
}
|
|
359
|
+
return UNSIGNED_PAYLOAD;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const hasHeader = (soughtHeader, headers) => {
|
|
363
|
+
soughtHeader = soughtHeader.toLowerCase();
|
|
364
|
+
for (const headerName of Object.keys(headers)) {
|
|
365
|
+
if (soughtHeader === headerName.toLowerCase()) {
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return false;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const moveHeadersToQuery = (request, options = {}) => {
|
|
373
|
+
const { headers, query = {} } = protocols.HttpRequest.clone(request);
|
|
374
|
+
for (const name of Object.keys(headers)) {
|
|
375
|
+
const lname = name.toLowerCase();
|
|
376
|
+
if ((lname.slice(0, 6) === "x-amz-" && !options.unhoistableHeaders?.has(lname)) ||
|
|
377
|
+
options.hoistableHeaders?.has(lname)) {
|
|
378
|
+
query[name] = headers[name];
|
|
379
|
+
delete headers[name];
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
...request,
|
|
384
|
+
headers,
|
|
385
|
+
query,
|
|
386
|
+
};
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const prepareRequest = (request) => {
|
|
390
|
+
request = protocols.HttpRequest.clone(request);
|
|
391
|
+
for (const headerName of Object.keys(request.headers)) {
|
|
392
|
+
if (GENERATED_HEADERS.indexOf(headerName.toLowerCase()) > -1) {
|
|
393
|
+
delete request.headers[headerName];
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return request;
|
|
397
|
+
};
|
|
398
|
+
|
|
402
399
|
class SignatureV4 extends SignatureV4Base {
|
|
403
400
|
headerFormatter = new HeaderFormatter();
|
|
404
401
|
constructor({ applyChecksum, credentials, region, service, sha256, uriEscapePath = true, }) {
|
|
@@ -455,7 +452,7 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
455
452
|
const hashedPayload = await getPayloadHash({ headers: {}, body: payload }, this.sha256);
|
|
456
453
|
const hash = new this.sha256();
|
|
457
454
|
hash.update(headers);
|
|
458
|
-
const hashedHeaders =
|
|
455
|
+
const hashedHeaders = serde.toHex(await hash.digest());
|
|
459
456
|
const stringToSign = [
|
|
460
457
|
EVENT_ALGORITHM_IDENTIFIER,
|
|
461
458
|
longDate,
|
|
@@ -492,8 +489,8 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
492
489
|
const region = signingRegion ?? (await this.regionProvider());
|
|
493
490
|
const { shortDate } = this.formatDate(signingDate);
|
|
494
491
|
const hash = new this.sha256(await this.getSigningKey(credentials, region, shortDate, signingService));
|
|
495
|
-
hash.update(
|
|
496
|
-
return
|
|
492
|
+
hash.update(serde.toUint8Array(stringToSign));
|
|
493
|
+
return serde.toHex(await hash.digest());
|
|
497
494
|
}
|
|
498
495
|
async signRequest(requestToSign, { signingDate = new Date(), signableHeaders, unsignableHeaders, signingRegion, signingService, } = {}) {
|
|
499
496
|
const credentials = await this.credentialProvider();
|
|
@@ -522,8 +519,8 @@ class SignatureV4 extends SignatureV4Base {
|
|
|
522
519
|
async getSignature(longDate, credentialScope, keyPromise, canonicalRequest) {
|
|
523
520
|
const stringToSign = await this.createStringToSign(longDate, credentialScope, canonicalRequest, ALGORITHM_IDENTIFIER);
|
|
524
521
|
const hash = new this.sha256(await keyPromise);
|
|
525
|
-
hash.update(
|
|
526
|
-
return
|
|
522
|
+
hash.update(serde.toUint8Array(stringToSign));
|
|
523
|
+
return serde.toHex(await hash.digest());
|
|
527
524
|
}
|
|
528
525
|
getSigningKey(credentials, region, shortDate, service) {
|
|
529
526
|
return getSigningKey(this.sha256, credentials, shortDate, region, service || this.service);
|
package/dist-es/SignatureV4.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { toHex } from "@smithy/
|
|
2
|
-
import {
|
|
1
|
+
import { toHex, toUint8Array } from "@smithy/core/serde";
|
|
2
|
+
import { HeaderFormatter } from "./HeaderFormatter";
|
|
3
|
+
import { SignatureV4Base } from "./SignatureV4Base";
|
|
3
4
|
import { ALGORITHM_IDENTIFIER, ALGORITHM_QUERY_PARAM, AMZ_DATE_HEADER, AMZ_DATE_QUERY_PARAM, AUTH_HEADER, CREDENTIAL_QUERY_PARAM, EVENT_ALGORITHM_IDENTIFIER, EXPIRES_QUERY_PARAM, MAX_PRESIGNED_TTL, SHA256_HEADER, SIGNATURE_QUERY_PARAM, SIGNED_HEADERS_QUERY_PARAM, TOKEN_HEADER, TOKEN_QUERY_PARAM, } from "./constants";
|
|
4
5
|
import { createScope, getSigningKey } from "./credentialDerivation";
|
|
5
6
|
import { getCanonicalHeaders } from "./getCanonicalHeaders";
|
|
6
7
|
import { getPayloadHash } from "./getPayloadHash";
|
|
7
|
-
import { HeaderFormatter } from "./HeaderFormatter";
|
|
8
8
|
import { hasHeader } from "./headerUtil";
|
|
9
9
|
import { moveHeadersToQuery } from "./moveHeadersToQuery";
|
|
10
10
|
import { prepareRequest } from "./prepareRequest";
|
|
11
|
-
import { SignatureV4Base } from "./SignatureV4Base";
|
|
12
11
|
export class SignatureV4 extends SignatureV4Base {
|
|
13
12
|
headerFormatter = new HeaderFormatter();
|
|
14
13
|
constructor({ applyChecksum, credentials, region, service, sha256, uriEscapePath = true, }) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { toUint8Array } from "@smithy/util-utf8";
|
|
1
|
+
import { normalizeProvider } from "@smithy/core/client";
|
|
2
|
+
import { escapeUri } from "@smithy/core/protocols";
|
|
3
|
+
import { toHex, toUint8Array } from "@smithy/core/serde";
|
|
5
4
|
import { getCanonicalQuery } from "./getCanonicalQuery";
|
|
6
5
|
import { iso8601 } from "./utilDate";
|
|
7
6
|
export class SignatureV4Base {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { toHex } from "@smithy/
|
|
2
|
-
import { toUint8Array } from "@smithy/util-utf8";
|
|
1
|
+
import { toHex, toUint8Array } from "@smithy/core/serde";
|
|
3
2
|
import { KEY_TYPE_IDENTIFIER, MAX_CACHE_SIZE } from "./constants";
|
|
4
3
|
const signingKeyCache = {};
|
|
5
4
|
const cacheQueue = [];
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { isArrayBuffer } from "@smithy/
|
|
2
|
-
import { toHex } from "@smithy/util-hex-encoding";
|
|
3
|
-
import { toUint8Array } from "@smithy/util-utf8";
|
|
1
|
+
import { isArrayBuffer, toHex, toUint8Array } from "@smithy/core/serde";
|
|
4
2
|
import { SHA256_HEADER, UNSIGNED_PAYLOAD } from "./constants";
|
|
5
3
|
export const getPayloadHash = async ({ headers, body }, hashConstructor) => {
|
|
6
4
|
for (const headerName of Object.keys(headers)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpRequest } from "@smithy/
|
|
1
|
+
import { HttpRequest } from "@smithy/core/protocols";
|
|
2
2
|
export const moveHeadersToQuery = (request, options = {}) => {
|
|
3
3
|
const { headers, query = {} } = HttpRequest.clone(request);
|
|
4
4
|
for (const name of Object.keys(headers)) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { EventSigner, EventSigningArguments, FormattedEvent, HttpRequest, MessageSigner, MessageSigningArguments, RequestPresigner, RequestPresigningArguments, RequestSigner, RequestSigningArguments, SignableMessage, SignedMessage, SigningArguments, StringSigner } from "@smithy/types";
|
|
2
|
-
import type
|
|
3
|
-
import { SignatureV4Base } from "./SignatureV4Base";
|
|
2
|
+
import { SignatureV4Base, type SignatureV4CryptoInit, type SignatureV4Init } from "./SignatureV4Base";
|
|
4
3
|
/**
|
|
5
4
|
* @public
|
|
6
5
|
*/
|
package/dist-types/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export { getPayloadHash } from "./getPayloadHash";
|
|
|
6
6
|
export { moveHeadersToQuery } from "./moveHeadersToQuery";
|
|
7
7
|
export { prepareRequest } from "./prepareRequest";
|
|
8
8
|
export * from "./credentialDerivation";
|
|
9
|
-
export { SignatureV4Init, SignatureV4CryptoInit
|
|
9
|
+
export { SignatureV4Base, type SignatureV4Init, type SignatureV4CryptoInit } from "./SignatureV4Base";
|
|
10
10
|
export { hasHeader } from "./headerUtil";
|
|
11
11
|
export * from "./signature-v4a-container";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithy/signature-v4",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.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",
|
|
@@ -25,13 +25,8 @@
|
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@smithy/
|
|
29
|
-
"@smithy/protocol-http": "^5.3.14",
|
|
28
|
+
"@smithy/core": "^3.24.0",
|
|
30
29
|
"@smithy/types": "^4.14.1",
|
|
31
|
-
"@smithy/util-hex-encoding": "^4.2.2",
|
|
32
|
-
"@smithy/util-middleware": "^4.2.14",
|
|
33
|
-
"@smithy/util-uri-escape": "^4.2.2",
|
|
34
|
-
"@smithy/util-utf8": "^4.2.2",
|
|
35
30
|
"tslib": "^2.6.2"
|
|
36
31
|
},
|
|
37
32
|
"devDependencies": {
|