@enactprotocol/trust 2.0.0 → 2.0.1
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/hash.d.ts +53 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +104 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +41 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +130 -0
- package/dist/keys.js.map +1 -0
- package/dist/sigstore/attestation.d.ts +245 -0
- package/dist/sigstore/attestation.d.ts.map +1 -0
- package/dist/sigstore/attestation.js +324 -0
- package/dist/sigstore/attestation.js.map +1 -0
- package/dist/sigstore/cosign.d.ts +90 -0
- package/dist/sigstore/cosign.d.ts.map +1 -0
- package/dist/sigstore/cosign.js +457 -0
- package/dist/sigstore/cosign.js.map +1 -0
- package/dist/sigstore/index.d.ts +17 -0
- package/dist/sigstore/index.d.ts.map +1 -0
- package/dist/sigstore/index.js +21 -0
- package/dist/sigstore/index.js.map +1 -0
- package/dist/sigstore/oauth/client.d.ts +38 -0
- package/dist/sigstore/oauth/client.d.ts.map +1 -0
- package/dist/sigstore/oauth/client.js +71 -0
- package/dist/sigstore/oauth/client.js.map +1 -0
- package/dist/sigstore/oauth/index.d.ts +47 -0
- package/dist/sigstore/oauth/index.d.ts.map +1 -0
- package/dist/sigstore/oauth/index.js +66 -0
- package/dist/sigstore/oauth/index.js.map +1 -0
- package/dist/sigstore/oauth/server.d.ts +29 -0
- package/dist/sigstore/oauth/server.d.ts.map +1 -0
- package/dist/sigstore/oauth/server.js +145 -0
- package/dist/sigstore/oauth/server.js.map +1 -0
- package/dist/sigstore/policy.d.ts +85 -0
- package/dist/sigstore/policy.d.ts.map +1 -0
- package/dist/sigstore/policy.js +351 -0
- package/dist/sigstore/policy.js.map +1 -0
- package/dist/sigstore/signing.d.ts +94 -0
- package/dist/sigstore/signing.d.ts.map +1 -0
- package/dist/sigstore/signing.js +477 -0
- package/dist/sigstore/signing.js.map +1 -0
- package/dist/sigstore/types.d.ts +541 -0
- package/dist/sigstore/types.d.ts.map +1 -0
- package/dist/sigstore/types.js +5 -0
- package/dist/sigstore/types.js.map +1 -0
- package/dist/sigstore/verification.d.ts +66 -0
- package/dist/sigstore/verification.d.ts.map +1 -0
- package/dist/sigstore/verification.js +317 -0
- package/dist/sigstore/verification.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC-based keyless signing using Sigstore
|
|
3
|
+
*
|
|
4
|
+
* This module provides keyless signing capabilities using OIDC identity tokens.
|
|
5
|
+
* It integrates with Fulcio for certificate issuance and Rekor for transparency logging.
|
|
6
|
+
*
|
|
7
|
+
* For CI environments (GitHub Actions, GitLab CI, etc.), the sigstore library's
|
|
8
|
+
* native OIDC support is used. For interactive local signing, we use a native
|
|
9
|
+
* OAuth implementation that opens a browser for authentication.
|
|
10
|
+
*/
|
|
11
|
+
import { attest, sign } from "sigstore";
|
|
12
|
+
import { attestWithCosign, isCosignAvailable, signWithCosign } from "./cosign";
|
|
13
|
+
import { OAuthIdentityProvider } from "./oauth";
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Constants
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/** Public Sigstore Fulcio URL */
|
|
18
|
+
export const FULCIO_PUBLIC_URL = "https://fulcio.sigstore.dev";
|
|
19
|
+
/** Public Sigstore Rekor URL */
|
|
20
|
+
export const REKOR_PUBLIC_URL = "https://rekor.sigstore.dev";
|
|
21
|
+
/** Public Sigstore TSA URL */
|
|
22
|
+
export const TSA_PUBLIC_URL = "https://timestamp.sigstore.dev";
|
|
23
|
+
/** OIDC issuer URLs for known providers */
|
|
24
|
+
export const OIDC_ISSUERS = {
|
|
25
|
+
github: "https://token.actions.githubusercontent.com",
|
|
26
|
+
google: "https://accounts.google.com",
|
|
27
|
+
microsoft: "https://login.microsoftonline.com",
|
|
28
|
+
gitlab: "https://gitlab.com",
|
|
29
|
+
custom: "",
|
|
30
|
+
};
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// OIDC Identity Extraction
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Decode a JWT token without verification (for extracting claims)
|
|
36
|
+
*/
|
|
37
|
+
function decodeJWT(token) {
|
|
38
|
+
const parts = token.split(".");
|
|
39
|
+
if (parts.length !== 3) {
|
|
40
|
+
throw new Error("Invalid JWT format");
|
|
41
|
+
}
|
|
42
|
+
const payloadPart = parts[1];
|
|
43
|
+
if (!payloadPart) {
|
|
44
|
+
throw new Error("Invalid JWT: missing payload");
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
// Use standard base64 decoding with URL-safe character replacement
|
|
48
|
+
const base64 = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
49
|
+
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
|
|
50
|
+
const payload = Buffer.from(padded, "base64").toString("utf8");
|
|
51
|
+
return JSON.parse(payload);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw new Error("Failed to decode JWT payload");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Detect OIDC provider from issuer URL
|
|
59
|
+
*/
|
|
60
|
+
export function detectOIDCProvider(issuer) {
|
|
61
|
+
for (const [provider, url] of Object.entries(OIDC_ISSUERS)) {
|
|
62
|
+
if (url && issuer.startsWith(url)) {
|
|
63
|
+
return provider;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return "custom";
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extract identity information from an OIDC token
|
|
70
|
+
*
|
|
71
|
+
* @param token - The OIDC identity token
|
|
72
|
+
* @returns Extracted identity information
|
|
73
|
+
*/
|
|
74
|
+
export function extractOIDCIdentity(token) {
|
|
75
|
+
const claims = decodeJWT(token);
|
|
76
|
+
const issuer = claims.iss;
|
|
77
|
+
const provider = detectOIDCProvider(issuer);
|
|
78
|
+
const identity = {
|
|
79
|
+
provider,
|
|
80
|
+
subject: claims.sub,
|
|
81
|
+
issuer,
|
|
82
|
+
claims,
|
|
83
|
+
};
|
|
84
|
+
// Extract email if present
|
|
85
|
+
if (claims.email) {
|
|
86
|
+
identity.email = claims.email;
|
|
87
|
+
}
|
|
88
|
+
// Extract GitHub-specific claims
|
|
89
|
+
if (provider === "github") {
|
|
90
|
+
if (claims.repository) {
|
|
91
|
+
identity.workflowRepository = claims.repository;
|
|
92
|
+
}
|
|
93
|
+
if (claims.ref) {
|
|
94
|
+
identity.workflowRef = claims.ref;
|
|
95
|
+
}
|
|
96
|
+
if (claims.event_name) {
|
|
97
|
+
identity.workflowTrigger = claims.event_name;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return identity;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get OIDC token from environment (for CI/CD environments)
|
|
104
|
+
*
|
|
105
|
+
* @param provider - The OIDC provider
|
|
106
|
+
* @returns The OIDC token if available
|
|
107
|
+
*/
|
|
108
|
+
export function getOIDCTokenFromEnvironment(provider) {
|
|
109
|
+
switch (provider) {
|
|
110
|
+
case "github":
|
|
111
|
+
// GitHub Actions provides OIDC tokens via ACTIONS_ID_TOKEN_REQUEST_URL
|
|
112
|
+
return process.env.ACTIONS_ID_TOKEN;
|
|
113
|
+
case "gitlab":
|
|
114
|
+
return process.env.CI_JOB_JWT_V2 || process.env.CI_JOB_JWT;
|
|
115
|
+
default:
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// Environment Detection
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* Check if we're running in a CI environment with native OIDC support
|
|
124
|
+
*/
|
|
125
|
+
function isInCIEnvironment() {
|
|
126
|
+
// GitHub Actions
|
|
127
|
+
if (process.env.GITHUB_ACTIONS && process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
// GitLab CI
|
|
131
|
+
if (process.env.GITLAB_CI && (process.env.CI_JOB_JWT_V2 || process.env.CI_JOB_JWT)) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
// Generic CI detection with token
|
|
135
|
+
if (process.env.CI && process.env.SIGSTORE_ID_TOKEN) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if we're in an interactive terminal environment
|
|
142
|
+
*/
|
|
143
|
+
function isInteractiveEnvironment() {
|
|
144
|
+
return process.stdout.isTTY === true;
|
|
145
|
+
}
|
|
146
|
+
// ============================================================================
|
|
147
|
+
// Signing Functions
|
|
148
|
+
// ============================================================================
|
|
149
|
+
/**
|
|
150
|
+
* Sign an artifact using keyless (OIDC) signing
|
|
151
|
+
*
|
|
152
|
+
* In CI environments with native OIDC support (GitHub Actions, GitLab CI),
|
|
153
|
+
* uses the sigstore library directly. For interactive local signing,
|
|
154
|
+
* uses native OAuth implementation that opens browser for authentication.
|
|
155
|
+
*
|
|
156
|
+
* @param artifact - The artifact to sign (as a Buffer)
|
|
157
|
+
* @param options - Signing options
|
|
158
|
+
* @returns The signing result including the Sigstore bundle
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* const artifact = Buffer.from(JSON.stringify(manifest));
|
|
163
|
+
* const result = await signArtifact(artifact, {
|
|
164
|
+
* oidc: { provider: "github" }
|
|
165
|
+
* });
|
|
166
|
+
* console.log(result.bundle);
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export async function signArtifact(artifact, options = {}) {
|
|
170
|
+
const { fulcioURL, rekorURL, timeout = 30000 } = options;
|
|
171
|
+
// Create sigstore sign options
|
|
172
|
+
const signOptions = {
|
|
173
|
+
fulcioURL: fulcioURL || FULCIO_PUBLIC_URL,
|
|
174
|
+
rekorURL: rekorURL || REKOR_PUBLIC_URL,
|
|
175
|
+
timeout,
|
|
176
|
+
};
|
|
177
|
+
// If we have an explicit OIDC token, use it directly
|
|
178
|
+
if (options.oidc?.token) {
|
|
179
|
+
signOptions.identityToken = options.oidc.token;
|
|
180
|
+
}
|
|
181
|
+
// If we're in a CI environment, sigstore library will handle OIDC
|
|
182
|
+
else if (isInCIEnvironment()) {
|
|
183
|
+
// No additional config needed - sigstore will use CI provider
|
|
184
|
+
}
|
|
185
|
+
// Interactive environment - try native OAuth first, fall back to cosign
|
|
186
|
+
else if (isInteractiveEnvironment()) {
|
|
187
|
+
// Try native OAuth with sigstore-js first
|
|
188
|
+
try {
|
|
189
|
+
const provider = new OAuthIdentityProvider();
|
|
190
|
+
signOptions.identityProvider = provider;
|
|
191
|
+
const bundle = await sign(artifact, signOptions);
|
|
192
|
+
const sigstoreBundle = bundle;
|
|
193
|
+
const certificate = extractCertificateFromBundle(sigstoreBundle);
|
|
194
|
+
const result = {
|
|
195
|
+
bundle: sigstoreBundle,
|
|
196
|
+
timestamp: new Date(),
|
|
197
|
+
};
|
|
198
|
+
if (certificate) {
|
|
199
|
+
result.certificate = certificate;
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
catch (nativeError) {
|
|
204
|
+
// Check if this is a BoringSSL/crypto compatibility issue
|
|
205
|
+
const errorMessage = nativeError instanceof Error ? nativeError.message : String(nativeError);
|
|
206
|
+
const isCryptoError = errorMessage.includes("NO_DEFAULT_DIGEST") || errorMessage.includes("public key routines");
|
|
207
|
+
if (isCryptoError && isCosignAvailable()) {
|
|
208
|
+
// Fall back to cosign CLI
|
|
209
|
+
const result = await signWithCosign(artifact, {
|
|
210
|
+
timeout,
|
|
211
|
+
verbose: false,
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
bundle: result.bundle,
|
|
215
|
+
timestamp: new Date(),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// If cosign is not available and we hit a crypto error, give helpful message
|
|
219
|
+
if (isCryptoError) {
|
|
220
|
+
throw new Error("Signing failed due to a crypto compatibility issue with Bun's BoringSSL.\n" +
|
|
221
|
+
"Install cosign CLI for local signing: brew install cosign\n" +
|
|
222
|
+
"Or run with Node.js instead of Bun.\n" +
|
|
223
|
+
"See: https://docs.sigstore.dev/cosign/system_config/installation/");
|
|
224
|
+
}
|
|
225
|
+
// Re-throw other errors
|
|
226
|
+
throw nativeError;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Non-interactive, non-CI - error
|
|
230
|
+
else {
|
|
231
|
+
throw new Error("No OIDC token available and not in an interactive environment.\n" +
|
|
232
|
+
"Provide an OIDC token via options.oidc.token or run in a CI environment with OIDC support.");
|
|
233
|
+
}
|
|
234
|
+
const bundle = await sign(artifact, signOptions);
|
|
235
|
+
// Parse the result
|
|
236
|
+
const sigstoreBundle = bundle;
|
|
237
|
+
const certificate = extractCertificateFromBundle(sigstoreBundle);
|
|
238
|
+
const result = {
|
|
239
|
+
bundle: sigstoreBundle,
|
|
240
|
+
timestamp: new Date(),
|
|
241
|
+
};
|
|
242
|
+
if (certificate) {
|
|
243
|
+
result.certificate = certificate;
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Sign an in-toto attestation using keyless signing
|
|
249
|
+
*
|
|
250
|
+
* In CI environments with native OIDC support, uses the sigstore library.
|
|
251
|
+
* For interactive local signing, uses native OAuth with browser authentication.
|
|
252
|
+
*
|
|
253
|
+
* @param attestation - The attestation to sign (in-toto statement)
|
|
254
|
+
* @param options - Signing options
|
|
255
|
+
* @returns The signing result including the Sigstore bundle
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```ts
|
|
259
|
+
* const statement = {
|
|
260
|
+
* _type: "https://in-toto.io/Statement/v1",
|
|
261
|
+
* subject: [{ name: "tool.yaml", digest: { sha256: "abc123..." } }],
|
|
262
|
+
* predicateType: "https://slsa.dev/provenance/v1",
|
|
263
|
+
* predicate: { ... }
|
|
264
|
+
* };
|
|
265
|
+
* const result = await signAttestation(statement, { oidc: { provider: "github" } });
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
export async function signAttestation(attestation, options = {}) {
|
|
269
|
+
const { fulcioURL, rekorURL, timeout = 30000 } = options;
|
|
270
|
+
// Serialize attestation
|
|
271
|
+
const payload = Buffer.from(JSON.stringify(attestation));
|
|
272
|
+
// Create sigstore attest options
|
|
273
|
+
const attestOptions = {
|
|
274
|
+
fulcioURL: fulcioURL || FULCIO_PUBLIC_URL,
|
|
275
|
+
rekorURL: rekorURL || REKOR_PUBLIC_URL,
|
|
276
|
+
timeout,
|
|
277
|
+
};
|
|
278
|
+
// If we have an explicit OIDC token, use it directly
|
|
279
|
+
if (options.oidc?.token) {
|
|
280
|
+
attestOptions.identityToken = options.oidc.token;
|
|
281
|
+
}
|
|
282
|
+
// If we're in a CI environment, sigstore library will handle OIDC
|
|
283
|
+
else if (isInCIEnvironment()) {
|
|
284
|
+
// No additional config needed - sigstore will use CI provider
|
|
285
|
+
}
|
|
286
|
+
// Interactive environment - try native OAuth first, fall back to cosign
|
|
287
|
+
else if (isInteractiveEnvironment()) {
|
|
288
|
+
// Try native OAuth with sigstore-js first
|
|
289
|
+
try {
|
|
290
|
+
const provider = new OAuthIdentityProvider();
|
|
291
|
+
attestOptions.identityProvider = provider;
|
|
292
|
+
const bundle = await attest(payload, "application/vnd.in-toto+json", attestOptions);
|
|
293
|
+
const sigstoreBundle = bundle;
|
|
294
|
+
const certificate = extractCertificateFromBundle(sigstoreBundle);
|
|
295
|
+
const result = {
|
|
296
|
+
bundle: sigstoreBundle,
|
|
297
|
+
timestamp: new Date(),
|
|
298
|
+
};
|
|
299
|
+
if (certificate) {
|
|
300
|
+
result.certificate = certificate;
|
|
301
|
+
}
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
catch (nativeError) {
|
|
305
|
+
// Check if this is a BoringSSL/crypto compatibility issue
|
|
306
|
+
const errorMessage = nativeError instanceof Error ? nativeError.message : String(nativeError);
|
|
307
|
+
const isCryptoError = errorMessage.includes("NO_DEFAULT_DIGEST") || errorMessage.includes("public key routines");
|
|
308
|
+
if (isCryptoError && isCosignAvailable()) {
|
|
309
|
+
// Fall back to cosign CLI
|
|
310
|
+
const result = await attestWithCosign(attestation, {
|
|
311
|
+
timeout,
|
|
312
|
+
verbose: false,
|
|
313
|
+
});
|
|
314
|
+
return {
|
|
315
|
+
bundle: result.bundle,
|
|
316
|
+
timestamp: new Date(),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// If cosign is not available and we hit a crypto error, give helpful message
|
|
320
|
+
if (isCryptoError) {
|
|
321
|
+
throw new Error("Signing failed due to a crypto compatibility issue with Bun's BoringSSL.\n" +
|
|
322
|
+
"Install cosign CLI for local signing: brew install cosign\n" +
|
|
323
|
+
"Or run with Node.js instead of Bun.\n" +
|
|
324
|
+
"See: https://docs.sigstore.dev/cosign/system_config/installation/");
|
|
325
|
+
}
|
|
326
|
+
// Re-throw other errors
|
|
327
|
+
throw nativeError;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Non-interactive, non-CI - error
|
|
331
|
+
else {
|
|
332
|
+
throw new Error("No OIDC token available and not in an interactive environment.\n" +
|
|
333
|
+
"Provide an OIDC token via options.oidc.token or run in a CI environment with OIDC support.");
|
|
334
|
+
}
|
|
335
|
+
const bundle = await attest(payload, "application/vnd.in-toto+json", attestOptions);
|
|
336
|
+
// Parse the result
|
|
337
|
+
const sigstoreBundle = bundle;
|
|
338
|
+
const certificate = extractCertificateFromBundle(sigstoreBundle);
|
|
339
|
+
const result = {
|
|
340
|
+
bundle: sigstoreBundle,
|
|
341
|
+
timestamp: new Date(),
|
|
342
|
+
};
|
|
343
|
+
if (certificate) {
|
|
344
|
+
result.certificate = certificate;
|
|
345
|
+
}
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// Certificate Extraction
|
|
350
|
+
// ============================================================================
|
|
351
|
+
/**
|
|
352
|
+
* Extract the signer email from a certificate's raw bytes
|
|
353
|
+
* Uses simple regex matching on the DER-encoded certificate
|
|
354
|
+
*/
|
|
355
|
+
function extractEmailFromCertificate(rawBytes) {
|
|
356
|
+
try {
|
|
357
|
+
const certStr = rawBytes.toString("latin1");
|
|
358
|
+
// Look for email pattern in the SAN extension
|
|
359
|
+
const emailMatch = certStr.match(/[\w.+-]+@[\w.-]+\.[a-zA-Z]{2,}/);
|
|
360
|
+
return emailMatch?.[0];
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Extract GitHub username from certificate extensions
|
|
368
|
+
* GitHub OAuth includes the username in the certificate
|
|
369
|
+
*/
|
|
370
|
+
function extractGitHubUsernameFromCertificate(rawBytes) {
|
|
371
|
+
try {
|
|
372
|
+
const certStr = rawBytes.toString("latin1");
|
|
373
|
+
// GitHub username is stored in a custom extension
|
|
374
|
+
// Look for pattern like "login" followed by the username
|
|
375
|
+
// The OID 1.3.6.1.4.1.57264.1.8 contains GitHub username
|
|
376
|
+
// For now, try to find it via common patterns
|
|
377
|
+
// Try to find GitHub user ID pattern (numeric)
|
|
378
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: We need to match control chars in cert strings
|
|
379
|
+
const userIdMatch = certStr.match(/github\.com[^\x00-\x1f]*?(\d{5,10})/i);
|
|
380
|
+
if (userIdMatch) {
|
|
381
|
+
// We found a user ID but need the username
|
|
382
|
+
// This would require an API call, which we handle elsewhere
|
|
383
|
+
}
|
|
384
|
+
return undefined;
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Extract the OIDC issuer from a certificate's raw bytes
|
|
392
|
+
* Looks for common issuer URLs in the certificate extensions
|
|
393
|
+
*/
|
|
394
|
+
function extractIssuerFromCertificate(rawBytes) {
|
|
395
|
+
try {
|
|
396
|
+
const certStr = rawBytes.toString("latin1");
|
|
397
|
+
// Look for common OIDC issuer patterns
|
|
398
|
+
const issuerPatterns = [
|
|
399
|
+
/https:\/\/accounts\.google\.com/,
|
|
400
|
+
/https:\/\/github\.com\/login\/oauth/,
|
|
401
|
+
/https:\/\/token\.actions\.githubusercontent\.com/,
|
|
402
|
+
/https:\/\/gitlab\.com/,
|
|
403
|
+
/https:\/\/login\.microsoftonline\.com\/[\w-]+\/v2\.0/,
|
|
404
|
+
];
|
|
405
|
+
for (const pattern of issuerPatterns) {
|
|
406
|
+
const match = certStr.match(pattern);
|
|
407
|
+
if (match) {
|
|
408
|
+
return match[0];
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
return undefined;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Extract certificate information from a Sigstore bundle
|
|
419
|
+
*/
|
|
420
|
+
export function extractCertificateFromBundle(bundle) {
|
|
421
|
+
if (!bundle.verificationMaterial?.certificate?.rawBytes) {
|
|
422
|
+
return undefined;
|
|
423
|
+
}
|
|
424
|
+
const rawBytes = Buffer.from(bundle.verificationMaterial.certificate.rawBytes, "base64");
|
|
425
|
+
// Extract email and issuer from certificate
|
|
426
|
+
const email = extractEmailFromCertificate(rawBytes);
|
|
427
|
+
const issuer = extractIssuerFromCertificate(rawBytes);
|
|
428
|
+
// Try to extract GitHub username (if GitHub OAuth)
|
|
429
|
+
const username = extractGitHubUsernameFromCertificate(rawBytes);
|
|
430
|
+
// Parse certificate (simplified - in production would use a proper X.509 parser)
|
|
431
|
+
const pem = `-----BEGIN CERTIFICATE-----\n${rawBytes
|
|
432
|
+
.toString("base64")
|
|
433
|
+
.match(/.{1,64}/g)
|
|
434
|
+
?.join("\n")}\n-----END CERTIFICATE-----`;
|
|
435
|
+
// Build identity object, only including email if present
|
|
436
|
+
const identity = {
|
|
437
|
+
provider: issuer?.includes("google")
|
|
438
|
+
? "google"
|
|
439
|
+
: issuer?.includes("github")
|
|
440
|
+
? "github"
|
|
441
|
+
: issuer?.includes("gitlab")
|
|
442
|
+
? "gitlab"
|
|
443
|
+
: issuer?.includes("microsoft")
|
|
444
|
+
? "microsoft"
|
|
445
|
+
: "custom",
|
|
446
|
+
subject: email || "unknown",
|
|
447
|
+
issuer: issuer || "https://fulcio.sigstore.dev",
|
|
448
|
+
};
|
|
449
|
+
if (email) {
|
|
450
|
+
identity.email = email;
|
|
451
|
+
}
|
|
452
|
+
if (username) {
|
|
453
|
+
identity.username = username;
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
certificateChain: [pem],
|
|
457
|
+
serialNumber: "unknown", // Would need X.509 parsing
|
|
458
|
+
notBefore: new Date(),
|
|
459
|
+
notAfter: new Date(Date.now() + 10 * 60 * 1000), // Fulcio certs are valid for 10 minutes
|
|
460
|
+
subject: email || "unknown",
|
|
461
|
+
issuer: "sigstore",
|
|
462
|
+
identity,
|
|
463
|
+
raw: rawBytes,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Extract identity from a signing certificate in a bundle
|
|
468
|
+
*
|
|
469
|
+
* @param bundle - The Sigstore bundle
|
|
470
|
+
* @returns The OIDC identity if it can be extracted
|
|
471
|
+
*/
|
|
472
|
+
export function extractIdentityFromBundle(bundle) {
|
|
473
|
+
// Parse the X.509 certificate and extract identity from SAN extension
|
|
474
|
+
const certificate = extractCertificateFromBundle(bundle);
|
|
475
|
+
return certificate?.identity;
|
|
476
|
+
}
|
|
477
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/sigstore/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAoB,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAahD,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,iCAAiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;AAE/D,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AAE7D,8BAA8B;AAC9B,MAAM,CAAC,MAAM,cAAc,GAAG,gCAAgC,CAAC;AAE/D,2CAA2C;AAC3C,MAAM,CAAC,MAAM,YAAY,GAAiC;IACxD,MAAM,EAAE,6CAA6C;IACrD,MAAM,EAAE,6BAA6B;IACrC,SAAS,EAAE,mCAAmC;IAC9C,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;GAEG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,CAAC;QACH,mEAAmE;QACnE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3D,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,QAAwB,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAa,CAAC;IACpC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,QAAQ,GAAiB;QAC7B,QAAQ;QACR,OAAO,EAAE,MAAM,CAAC,GAAa;QAC7B,MAAM;QACN,MAAM;KACP,CAAC;IAEF,2BAA2B;IAC3B,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC,KAAe,CAAC;IAC1C,CAAC;IAED,iCAAiC;IACjC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,QAAQ,CAAC,kBAAkB,GAAG,MAAM,CAAC,UAAoB,CAAC;QAC5D,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;YACf,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,GAAa,CAAC;QAC9C,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,QAAQ,CAAC,eAAe,GAAG,MAAM,CAAC,UAAoB,CAAC;QACzD,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAsB;IAChE,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,uEAAuE;YACvE,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACtC,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAC7D;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,iBAAiB;IACxB,iBAAiB;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,YAAY;IACZ,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kCAAkC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB;IAC/B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,UAA+B,EAAE;IAEjC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzD,+BAA+B;IAC/B,MAAM,WAAW,GAAgB;QAC/B,SAAS,EAAE,SAAS,IAAI,iBAAiB;QACzC,QAAQ,EAAE,QAAQ,IAAI,gBAAgB;QACtC,OAAO;KACR,CAAC;IAEF,qDAAqD;IACrD,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QACxB,WAAW,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IACjD,CAAC;IACD,kEAAkE;SAC7D,IAAI,iBAAiB,EAAE,EAAE,CAAC;QAC7B,8DAA8D;IAChE,CAAC;IACD,wEAAwE;SACnE,IAAI,wBAAwB,EAAE,EAAE,CAAC;QACpC,0CAA0C;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;YAC7C,WAAW,CAAC,gBAAgB,GAAG,QAAQ,CAAC;YAExC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACjD,MAAM,cAAc,GAAG,MAAmC,CAAC;YAC3D,MAAM,WAAW,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;YAEjE,MAAM,MAAM,GAAkB;gBAC5B,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC;YAEF,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;YACnC,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,WAAW,EAAE,CAAC;YACrB,0DAA0D;YAC1D,MAAM,YAAY,GAAG,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC9F,MAAM,aAAa,GACjB,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;YAE7F,IAAI,aAAa,IAAI,iBAAiB,EAAE,EAAE,CAAC;gBACzC,0BAA0B;gBAC1B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE;oBAC5C,OAAO;oBACP,OAAO,EAAE,KAAK;iBACf,CAAC,CAAC;gBAEH,OAAO;oBACL,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC;YACJ,CAAC;YAED,6EAA6E;YAC7E,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,4EAA4E;oBAC1E,6DAA6D;oBAC7D,uCAAuC;oBACvC,mEAAmE,CACtE,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,MAAM,WAAW,CAAC;QACpB,CAAC;IACH,CAAC;IACD,kCAAkC;SAC7B,CAAC;QACJ,MAAM,IAAI,KAAK,CACb,kEAAkE;YAChE,4FAA4F,CAC/F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEjD,mBAAmB;IACnB,MAAM,cAAc,GAAG,MAAmC,CAAC;IAC3D,MAAM,WAAW,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAkB;QAC5B,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC;IAEF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAoC,EACpC,UAA+B,EAAE;IAEjC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzD,wBAAwB;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAEzD,iCAAiC;IACjC,MAAM,aAAa,GAAgB;QACjC,SAAS,EAAE,SAAS,IAAI,iBAAiB;QACzC,QAAQ,EAAE,QAAQ,IAAI,gBAAgB;QACtC,OAAO;KACR,CAAC;IAEF,qDAAqD;IACrD,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QACxB,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IACnD,CAAC;IACD,kEAAkE;SAC7D,IAAI,iBAAiB,EAAE,EAAE,CAAC;QAC7B,8DAA8D;IAChE,CAAC;IACD,wEAAwE;SACnE,IAAI,wBAAwB,EAAE,EAAE,CAAC;QACpC,0CAA0C;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;YAC7C,aAAa,CAAC,gBAAgB,GAAG,QAAQ,CAAC;YAE1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,8BAA8B,EAAE,aAAa,CAAC,CAAC;YACpF,MAAM,cAAc,GAAG,MAAmC,CAAC;YAC3D,MAAM,WAAW,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;YAEjE,MAAM,MAAM,GAAkB;gBAC5B,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC;YAEF,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;YACnC,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,WAAW,EAAE,CAAC;YACrB,0DAA0D;YAC1D,MAAM,YAAY,GAAG,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC9F,MAAM,aAAa,GACjB,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;YAE7F,IAAI,aAAa,IAAI,iBAAiB,EAAE,EAAE,CAAC;gBACzC,0BAA0B;gBAC1B,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,WAAW,EAAE;oBACjD,OAAO;oBACP,OAAO,EAAE,KAAK;iBACf,CAAC,CAAC;gBAEH,OAAO;oBACL,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC;YACJ,CAAC;YAED,6EAA6E;YAC7E,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,4EAA4E;oBAC1E,6DAA6D;oBAC7D,uCAAuC;oBACvC,mEAAmE,CACtE,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,MAAM,WAAW,CAAC;QACpB,CAAC;IACH,CAAC;IACD,kCAAkC;SAC7B,CAAC;QACJ,MAAM,IAAI,KAAK,CACb,kEAAkE;YAChE,4FAA4F,CAC/F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,8BAA8B,EAAE,aAAa,CAAC,CAAC;IAEpF,mBAAmB;IACnB,MAAM,cAAc,GAAG,MAAmC,CAAC;IAC3D,MAAM,WAAW,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAkB;QAC5B,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC;IAEF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,2BAA2B,CAAC,QAAgB;IACnD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5C,8CAA8C;QAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnE,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,oCAAoC,CAAC,QAAgB;IAC5D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5C,kDAAkD;QAClD,yDAAyD;QACzD,yDAAyD;QACzD,8CAA8C;QAE9C,+CAA+C;QAC/C,0GAA0G;QAC1G,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1E,IAAI,WAAW,EAAE,CAAC;YAChB,2CAA2C;YAC3C,4DAA4D;QAC9D,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,4BAA4B,CAAC,QAAgB;IACpD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5C,uCAAuC;QACvC,MAAM,cAAc,GAAG;YACrB,iCAAiC;YACjC,qCAAqC;YACrC,kDAAkD;YAClD,uBAAuB;YACvB,sDAAsD;SACvD,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAsB;IAEtB,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAEzF,4CAA4C;IAC5C,MAAM,KAAK,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IAEtD,mDAAmD;IACnD,MAAM,QAAQ,GAAG,oCAAoC,CAAC,QAAQ,CAAC,CAAC;IAEhE,iFAAiF;IACjF,MAAM,GAAG,GAAG,gCAAgC,QAAQ;SACjD,QAAQ,CAAC,QAAQ,CAAC;SAClB,KAAK,CAAC,UAAU,CAAC;QAClB,EAAE,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC;IAE5C,yDAAyD;IACzD,MAAM,QAAQ,GAAiB;QAC7B,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;YAClC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAC1B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;oBAC1B,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC;wBAC7B,CAAC,CAAC,WAAW;wBACb,CAAC,CAAC,QAAQ;QAClB,OAAO,EAAE,KAAK,IAAI,SAAS;QAC3B,MAAM,EAAE,MAAM,IAAI,6BAA6B;KAChD,CAAC;IACF,IAAI,KAAK,EAAE,CAAC;QACV,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,gBAAgB,EAAE,CAAC,GAAG,CAAC;QACvB,YAAY,EAAE,SAAS,EAAE,2BAA2B;QACpD,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,QAAQ,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,wCAAwC;QACzF,OAAO,EAAE,KAAK,IAAI,SAAS;QAC3B,MAAM,EAAE,UAAU;QAClB,QAAQ;QACR,GAAG,EAAE,QAAQ;KACd,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAsB;IAC9D,sEAAsE;IACtE,MAAM,WAAW,GAAG,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACzD,OAAO,WAAW,EAAE,QAAQ,CAAC;AAC/B,CAAC"}
|