@vizamodo/aws-sts-core 0.4.5 → 0.4.7
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 +60 -11
- package/package.json +1 -1
package/dist/sts/issue.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { getCachedOrFetch, wrapResult } from "@vizamodo/edge-cache-core";
|
|
2
1
|
import { canonicalizeHeaders } from "../sigv4/headers";
|
|
3
2
|
import { buildCanonicalRequest } from "../sigv4/canonical";
|
|
4
3
|
import { buildStringToSign } from "../sigv4/string-to-sign";
|
|
5
4
|
import { signStringToSign } from "./signer";
|
|
6
5
|
import { InternalError } from "./errors";
|
|
7
6
|
import { sha256Hex } from "../crypto/sha256";
|
|
7
|
+
import { getCachedOrFetch, wrapResult } from "@vizamodo/edge-cache-core";
|
|
8
8
|
// ── Constants ──────────────────────────────────────────────────────────────
|
|
9
9
|
const ALGORITHM = "AWS4-X509-ECDSA-SHA256";
|
|
10
10
|
const SERVICE = "rolesanywhere";
|
|
@@ -30,6 +30,10 @@ let signingKeyPromise = null;
|
|
|
30
30
|
let cachedSigningKey = null;
|
|
31
31
|
let cachedCertBase64 = null;
|
|
32
32
|
let cachedPrivateKeyBase64 = null;
|
|
33
|
+
// ── Isolate-level cert-serial cache ───────────────────────────────────────
|
|
34
|
+
// DER walk is CPU-bound; the cert rarely rotates within an isolate lifetime.
|
|
35
|
+
let cachedCertSerialDec = null;
|
|
36
|
+
let cachedCertSerialSource = null;
|
|
33
37
|
// ── Test utilities ─────────────────────────────────────────────────────────
|
|
34
38
|
/**
|
|
35
39
|
* Reset isolate-level signing material and cert serial caches.
|
|
@@ -43,6 +47,8 @@ export function resetIsolateCache() {
|
|
|
43
47
|
cachedSigningKey = null;
|
|
44
48
|
cachedCertBase64 = null;
|
|
45
49
|
cachedPrivateKeyBase64 = null;
|
|
50
|
+
cachedCertSerialDec = null;
|
|
51
|
+
cachedCertSerialSource = null;
|
|
46
52
|
}
|
|
47
53
|
// ── Signing material ───────────────────────────────────────────────────────
|
|
48
54
|
async function getSigningMaterial(certBase64, privateKeyPkcs8Base64) {
|
|
@@ -129,6 +135,35 @@ async function fetchCredentials(input) {
|
|
|
129
135
|
});
|
|
130
136
|
const signatureHex = await signStringToSign(stringToSign, signingKey);
|
|
131
137
|
const certSerialDec = getCertSerialDec(normalizedCert);
|
|
138
|
+
// 🔍 Deep debug helper (compare with working version)
|
|
139
|
+
function debugAwsSigning() {
|
|
140
|
+
try {
|
|
141
|
+
console.debug("[aws-debug][input]", {
|
|
142
|
+
roleArn,
|
|
143
|
+
profileArn,
|
|
144
|
+
trustAnchorArn,
|
|
145
|
+
region,
|
|
146
|
+
sessionTtl,
|
|
147
|
+
});
|
|
148
|
+
console.debug("[aws-debug][cert]", {
|
|
149
|
+
length: normalizedCert.length,
|
|
150
|
+
preview: normalizedCert.slice(0, 30),
|
|
151
|
+
});
|
|
152
|
+
console.debug("[aws-debug][serial]", {
|
|
153
|
+
serialDec: certSerialDec,
|
|
154
|
+
serialHex: BigInt(certSerialDec).toString(16),
|
|
155
|
+
});
|
|
156
|
+
console.debug("[aws-debug][headers]", baseHeaders);
|
|
157
|
+
console.debug("[aws-debug][signedHeaders]", signedHeaders);
|
|
158
|
+
console.debug("[aws-debug][canonicalRequest]", canonicalRequest);
|
|
159
|
+
console.debug("[aws-debug][stringToSign]", stringToSign);
|
|
160
|
+
console.debug("[aws-debug][signatureHex]", signatureHex);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
console.warn("[aws-debug][error]", e);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
debugAwsSigning();
|
|
132
167
|
const finalHeaders = new Headers({
|
|
133
168
|
"Content-Type": "application/json",
|
|
134
169
|
"X-Amz-Date": amzDate,
|
|
@@ -148,7 +183,12 @@ async function fetchCredentials(input) {
|
|
|
148
183
|
throw new InternalError("aws_unreachable");
|
|
149
184
|
}
|
|
150
185
|
if (!res.ok) {
|
|
151
|
-
|
|
186
|
+
const text = await res.text().catch(() => "<no-body>");
|
|
187
|
+
console.error("[aws-rejected]", {
|
|
188
|
+
status: res.status,
|
|
189
|
+
body: text,
|
|
190
|
+
region,
|
|
191
|
+
});
|
|
152
192
|
throw new InternalError("aws_rejected");
|
|
153
193
|
}
|
|
154
194
|
const json = await res.json();
|
|
@@ -183,9 +223,15 @@ function normalizeCert(raw) {
|
|
|
183
223
|
}
|
|
184
224
|
return raw.replace(/\s+/g, "");
|
|
185
225
|
}
|
|
186
|
-
/**
|
|
226
|
+
/** Return cert serial as decimal string, using isolate-level cache. */
|
|
187
227
|
function getCertSerialDec(normalizedCert) {
|
|
188
|
-
|
|
228
|
+
if (cachedCertSerialDec && cachedCertSerialSource === normalizedCert) {
|
|
229
|
+
return cachedCertSerialDec;
|
|
230
|
+
}
|
|
231
|
+
const serial = parseCertSerialDec(normalizedCert);
|
|
232
|
+
cachedCertSerialDec = serial;
|
|
233
|
+
cachedCertSerialSource = normalizedCert;
|
|
234
|
+
return serial;
|
|
189
235
|
}
|
|
190
236
|
/**
|
|
191
237
|
* Minimal DER walk to extract the certificate serial number as a decimal string.
|
|
@@ -209,24 +255,27 @@ function parseCertSerialDec(normalizedCertBase64) {
|
|
|
209
255
|
len = (len << 8) | der[offset++];
|
|
210
256
|
return len;
|
|
211
257
|
}
|
|
258
|
+
// Certificate ::= SEQUENCE
|
|
212
259
|
if (der[offset++] !== 0x30)
|
|
213
260
|
throw new Error("bad cert");
|
|
214
261
|
readLen();
|
|
262
|
+
// tbsCertificate ::= SEQUENCE
|
|
215
263
|
if (der[offset++] !== 0x30)
|
|
216
264
|
throw new Error("bad tbs");
|
|
217
265
|
readLen();
|
|
218
|
-
//
|
|
266
|
+
// Optional version [0] EXPLICIT
|
|
219
267
|
if (der[offset] === 0xa0) {
|
|
220
|
-
offset++;
|
|
221
|
-
offset += readLen();
|
|
268
|
+
offset++; // tag
|
|
269
|
+
offset += readLen(); // skip content
|
|
222
270
|
}
|
|
271
|
+
// 👉 SERIAL MUST be the next INTEGER after optional version
|
|
223
272
|
if (der[offset++] !== 0x02)
|
|
224
273
|
throw new Error("bad serial tag");
|
|
225
|
-
const
|
|
226
|
-
if (offset +
|
|
274
|
+
const len = readLen();
|
|
275
|
+
if (offset + len > der.length)
|
|
227
276
|
throw new Error("DER overflow");
|
|
228
|
-
let serial = der.slice(offset, offset +
|
|
229
|
-
// Strip
|
|
277
|
+
let serial = der.slice(offset, offset + len);
|
|
278
|
+
// Strip leading 0x00 only if it's padding for signed INTEGER
|
|
230
279
|
if (serial.length > 1 && serial[0] === 0x00) {
|
|
231
280
|
serial = serial.slice(1);
|
|
232
281
|
}
|