@vizamodo/aws-sts-core 0.2.34 → 0.2.39
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/sts/issue.js +66 -41
- package/package.json +1 -1
package/dist/sts/issue.js
CHANGED
|
@@ -20,22 +20,18 @@ const DEFAULT_TTL = 2 * 60 * 60;
|
|
|
20
20
|
let cachedSigningKey = null;
|
|
21
21
|
let cachedCertBase64 = null;
|
|
22
22
|
let cachedPrivateKeyBase64 = null;
|
|
23
|
-
// ---- shared encoder +
|
|
23
|
+
// ---- shared encoder + payload hash cache ----
|
|
24
24
|
const textEncoder = new TextEncoder();
|
|
25
|
-
let lastCanonicalRequestKey = null;
|
|
26
|
-
let lastCanonicalRequest = null;
|
|
27
|
-
let lastCanonicalRequestHash = null;
|
|
28
25
|
let lastBody = null;
|
|
29
26
|
let lastPayloadHash = null;
|
|
30
|
-
let lastBaseHeadersKey = null;
|
|
31
|
-
let lastCanonicalHeaders = null;
|
|
32
|
-
let lastSignedHeaders = null;
|
|
33
27
|
async function getSigningMaterial(input) {
|
|
34
28
|
if (cachedSigningKey &&
|
|
35
29
|
cachedCertBase64 === input.certBase64 &&
|
|
36
30
|
cachedPrivateKeyBase64 === input.privateKeyPkcs8Base64) {
|
|
31
|
+
console.debug("[sts-cache] signingKey HIT");
|
|
37
32
|
return { signingKey: cachedSigningKey, certBase64: cachedCertBase64 };
|
|
38
33
|
}
|
|
34
|
+
console.debug("[sts-cache] signingKey MISS → importing key");
|
|
39
35
|
try {
|
|
40
36
|
const keyBuffer = base64ToArrayBuffer(input.privateKeyPkcs8Base64);
|
|
41
37
|
cachedSigningKey = await crypto.subtle.importKey("pkcs8", keyBuffer, { name: "ECDSA", namedCurve: "P-256" }, false, ["sign"]);
|
|
@@ -137,21 +133,56 @@ export async function issueAwsCredentials(input) {
|
|
|
137
133
|
signedHeaders,
|
|
138
134
|
payloadHash,
|
|
139
135
|
});
|
|
136
|
+
console.debug("[sts-debug] canonicalRequest", {
|
|
137
|
+
amzDate,
|
|
138
|
+
signedHeaders,
|
|
139
|
+
payloadHash,
|
|
140
|
+
canonicalHeadersPreview: canonicalHeaders.slice(0, 120),
|
|
141
|
+
canonicalRequestPreview: canonicalRequest.slice(0, 200)
|
|
142
|
+
});
|
|
140
143
|
const canonicalRequestHash = await getCanonicalRequestHash(canonicalRequest);
|
|
144
|
+
console.debug("[sts-debug] canonicalRequestHash", canonicalRequestHash);
|
|
141
145
|
const stringToSign = buildStringToSign({
|
|
142
146
|
algorithm: ALGORITHM,
|
|
143
147
|
amzDate,
|
|
144
148
|
credentialScope,
|
|
145
149
|
canonicalRequestHash,
|
|
146
150
|
});
|
|
151
|
+
console.debug("[sts-debug] stringToSign", {
|
|
152
|
+
credentialScope,
|
|
153
|
+
stringPreview: stringToSign.slice(0, 200)
|
|
154
|
+
});
|
|
147
155
|
const signatureHex = await signStringToSign(stringToSign, signingKey);
|
|
156
|
+
console.debug("[sts-debug] signature", {
|
|
157
|
+
length: signatureHex.length,
|
|
158
|
+
prefix: signatureHex.slice(0, 32)
|
|
159
|
+
});
|
|
148
160
|
// 5. Build Authorization Header với số Serial (DECIMAL)
|
|
149
161
|
const finalHeaders = new Headers({
|
|
150
162
|
"Content-Type": "application/json",
|
|
163
|
+
"Host": host,
|
|
151
164
|
"X-Amz-Date": amzDate,
|
|
152
165
|
"X-Amz-X509": normalizedCert,
|
|
153
166
|
"Authorization": `AWS4-X509-ECDSA-SHA256 Credential=${certSerialDec}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signatureHex}`
|
|
154
167
|
});
|
|
168
|
+
console.debug("[sts-debug] requestHeaders", {
|
|
169
|
+
host,
|
|
170
|
+
amzDate,
|
|
171
|
+
signedHeaders,
|
|
172
|
+
certLen: normalizedCert.length
|
|
173
|
+
});
|
|
174
|
+
console.debug("[sts-request] issuing rolesanywhere session", {
|
|
175
|
+
region,
|
|
176
|
+
profile,
|
|
177
|
+
roleArn,
|
|
178
|
+
profileArn,
|
|
179
|
+
trustAnchorArn,
|
|
180
|
+
amzDate,
|
|
181
|
+
cacheState: {
|
|
182
|
+
hasSigningKey: !!cachedSigningKey,
|
|
183
|
+
cachedCertMatch: cachedCertBase64 === certBase64,
|
|
184
|
+
}
|
|
185
|
+
});
|
|
155
186
|
// 6. Execution
|
|
156
187
|
try {
|
|
157
188
|
const res = await fetch(`https://${host}${path}`, {
|
|
@@ -164,7 +195,10 @@ export async function issueAwsCredentials(input) {
|
|
|
164
195
|
// Debug logs
|
|
165
196
|
console.error("[aws-rejected] Request details", {
|
|
166
197
|
status: res.status,
|
|
167
|
-
response: errorBody
|
|
198
|
+
response: errorBody,
|
|
199
|
+
region,
|
|
200
|
+
profile,
|
|
201
|
+
amzDate
|
|
168
202
|
});
|
|
169
203
|
throw new InternalError("aws_rejected");
|
|
170
204
|
}
|
|
@@ -178,6 +212,14 @@ export async function issueAwsCredentials(input) {
|
|
|
178
212
|
};
|
|
179
213
|
}
|
|
180
214
|
catch (e) {
|
|
215
|
+
console.error("[sts-debug] fetch failure", {
|
|
216
|
+
error: String(e),
|
|
217
|
+
region,
|
|
218
|
+
roleArn,
|
|
219
|
+
profileArn,
|
|
220
|
+
trustAnchorArn,
|
|
221
|
+
amzDate
|
|
222
|
+
});
|
|
181
223
|
if (e instanceof InternalError)
|
|
182
224
|
throw e;
|
|
183
225
|
throw new InternalError("aws_unreachable");
|
|
@@ -202,52 +244,35 @@ async function sha256Hex(input) {
|
|
|
202
244
|
return hex.join("");
|
|
203
245
|
}
|
|
204
246
|
async function getCanonicalRequestHash(canonicalRequest) {
|
|
205
|
-
|
|
206
|
-
return lastCanonicalRequestHash;
|
|
207
|
-
}
|
|
208
|
-
const hash = await sha256Hex(canonicalRequest);
|
|
209
|
-
lastCanonicalRequest = canonicalRequest;
|
|
210
|
-
lastCanonicalRequestHash = hash;
|
|
211
|
-
return hash;
|
|
247
|
+
return sha256Hex(canonicalRequest);
|
|
212
248
|
}
|
|
213
249
|
async function getPayloadHash(body) {
|
|
214
250
|
if (lastBody === body && lastPayloadHash) {
|
|
251
|
+
console.debug("[sts-cache] payloadHash HIT");
|
|
215
252
|
return lastPayloadHash;
|
|
216
253
|
}
|
|
254
|
+
console.debug("[sts-cache] payloadHash MISS");
|
|
217
255
|
const hash = await sha256Hex(body);
|
|
218
256
|
lastBody = body;
|
|
219
257
|
lastPayloadHash = hash;
|
|
220
258
|
return hash;
|
|
221
259
|
}
|
|
222
260
|
function getCanonicalizedHeaders(baseHeaders) {
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
baseHeaders
|
|
226
|
-
baseHeaders
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return { canonicalHeaders, signedHeaders };
|
|
261
|
+
// Debug input headers before canonicalization
|
|
262
|
+
console.debug("[sts-debug] canonicalizeHeaders input", {
|
|
263
|
+
headers: baseHeaders,
|
|
264
|
+
keys: Object.keys(baseHeaders),
|
|
265
|
+
});
|
|
266
|
+
const result = canonicalizeHeaders(baseHeaders);
|
|
267
|
+
// Debug canonicalization result
|
|
268
|
+
console.debug("[sts-debug] canonicalizeHeaders output", {
|
|
269
|
+
canonicalHeaders: result.canonicalHeaders,
|
|
270
|
+
signedHeaders: result.signedHeaders,
|
|
271
|
+
});
|
|
272
|
+
return result;
|
|
236
273
|
}
|
|
237
274
|
function getCanonicalRequest(input) {
|
|
238
|
-
|
|
239
|
-
input.canonicalUri + "|" +
|
|
240
|
-
input.query + "|" +
|
|
241
|
-
input.canonicalHeaders + "|" +
|
|
242
|
-
input.signedHeaders + "|" +
|
|
243
|
-
input.payloadHash;
|
|
244
|
-
if (lastCanonicalRequestKey === key && lastCanonicalRequest) {
|
|
245
|
-
return lastCanonicalRequest;
|
|
246
|
-
}
|
|
247
|
-
const req = buildCanonicalRequest(input);
|
|
248
|
-
lastCanonicalRequestKey = key;
|
|
249
|
-
lastCanonicalRequest = req;
|
|
250
|
-
return req;
|
|
275
|
+
return buildCanonicalRequest(input);
|
|
251
276
|
}
|
|
252
277
|
function base64ToArrayBuffer(base64) {
|
|
253
278
|
const binary = atob(base64);
|