@kya-os/mcp-i 1.7.7 → 1.7.9
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.
|
@@ -77,9 +77,13 @@ export interface VerifyOrHintsResult {
|
|
|
77
77
|
user_did: string;
|
|
78
78
|
scopes: string[];
|
|
79
79
|
authorization: {
|
|
80
|
-
type: "oauth" | "credential" | "none";
|
|
80
|
+
type: "oauth" | "oauth2" | "password" | "credential" | "webauthn" | "siwe" | "none";
|
|
81
81
|
provider?: string;
|
|
82
82
|
credentialType?: string;
|
|
83
|
+
rpId?: string;
|
|
84
|
+
userVerification?: "required" | "preferred" | "discouraged";
|
|
85
|
+
chainId?: number;
|
|
86
|
+
domain?: string;
|
|
83
87
|
};
|
|
84
88
|
[key: string]: unknown;
|
|
85
89
|
};
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Related Spec: MCP-I §4.3, W3C VC Data Model 1.1
|
|
12
12
|
* Python Reference: Edge-Delegation-Verification.md
|
|
13
13
|
*/
|
|
14
|
-
import { JWK } from 'jose';
|
|
14
|
+
import type { JWK } from 'jose';
|
|
15
15
|
import { DelegationCredential } from '@kya-os/contracts/delegation';
|
|
16
16
|
import { CredentialStatus } from '@kya-os/contracts/vc';
|
|
17
17
|
/**
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.DelegationCredentialVerifier = void 0;
|
|
17
17
|
exports.createDelegationVerifier = createDelegationVerifier;
|
|
18
|
-
const jose_1 = require("jose");
|
|
19
18
|
const crypto_1 = require("crypto");
|
|
20
19
|
const json_canonicalize_1 = require("json-canonicalize");
|
|
21
20
|
const delegation_1 = require("@kya-os/contracts/delegation");
|
|
@@ -239,34 +238,72 @@ class DelegationCredentialVerifier {
|
|
|
239
238
|
durationMs: Date.now() - startTime,
|
|
240
239
|
};
|
|
241
240
|
}
|
|
242
|
-
// Verify signature
|
|
243
|
-
//
|
|
241
|
+
// Verify Ed25519 signature
|
|
242
|
+
// For Ed25519Signature2020:
|
|
243
|
+
// 1. The signing input is the canonicalized VC (without proofValue)
|
|
244
|
+
// 2. The proofValue is the base64url-encoded Ed25519 signature
|
|
244
245
|
const vcWithoutProof = { ...vc };
|
|
245
246
|
delete vcWithoutProof.proof;
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
// We need to verify it
|
|
251
|
-
const proofValue = vc.proof?.proofValue || vc.proof?.jws;
|
|
252
|
-
if (!proofValue) {
|
|
247
|
+
// The proof.proofValue is base64url-encoded Ed25519 signature
|
|
248
|
+
// The proof.jws is an alternative JWS-based signature format (header.payload.signature)
|
|
249
|
+
const rawProofValue = vc.proof?.proofValue || vc.proof?.jws;
|
|
250
|
+
if (!rawProofValue) {
|
|
253
251
|
return {
|
|
254
252
|
valid: false,
|
|
255
253
|
reason: 'Proof missing proofValue or jws',
|
|
256
254
|
durationMs: Date.now() - startTime,
|
|
257
255
|
};
|
|
258
256
|
}
|
|
259
|
-
//
|
|
260
|
-
//
|
|
257
|
+
// Extract signature bytes - handle JWS format (header.payload.signature)
|
|
258
|
+
// JWS compact serialization splits into 3 parts; only the 3rd is the signature
|
|
259
|
+
let signatureBase64url;
|
|
260
|
+
if (rawProofValue.includes('.')) {
|
|
261
|
+
// JWS format: extract the signature (third segment)
|
|
262
|
+
const jwsParts = rawProofValue.split('.');
|
|
263
|
+
if (jwsParts.length !== 3) {
|
|
264
|
+
return {
|
|
265
|
+
valid: false,
|
|
266
|
+
reason: `Invalid JWS format: expected 3 parts, got ${jwsParts.length}`,
|
|
267
|
+
durationMs: Date.now() - startTime,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
signatureBase64url = jwsParts[2];
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// proofValue is raw base64url signature
|
|
274
|
+
signatureBase64url = rawProofValue;
|
|
275
|
+
}
|
|
261
276
|
try {
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
277
|
+
// For Ed25519Signature2020, we need to:
|
|
278
|
+
// 1. Canonicalize the VC without proofValue
|
|
279
|
+
// 2. Canonicalize the proof options
|
|
280
|
+
// 3. Hash both and concatenate
|
|
281
|
+
// 4. Verify the signature
|
|
282
|
+
// Construct proof options (everything in proof except proofValue)
|
|
283
|
+
const proofOptions = { ...vc.proof };
|
|
284
|
+
delete proofOptions.proofValue;
|
|
285
|
+
delete proofOptions.jws;
|
|
286
|
+
delete proofOptions.signatureValue;
|
|
287
|
+
// Create signing input: hash(canonicalize(document)) + hash(canonicalize(proofOptions))
|
|
288
|
+
const canonicalDoc = (0, json_canonicalize_1.canonicalize)(vcWithoutProof);
|
|
289
|
+
const canonicalProof = (0, json_canonicalize_1.canonicalize)(proofOptions);
|
|
290
|
+
// For Ed25519Signature2020, signing input is:
|
|
291
|
+
// SHA-256(canonicalize(proofOptions)) || SHA-256(canonicalize(document))
|
|
292
|
+
const docHash = (0, crypto_1.createHash)('sha256').update(canonicalDoc, 'utf8').digest();
|
|
293
|
+
const proofHash = (0, crypto_1.createHash)('sha256').update(canonicalProof, 'utf8').digest();
|
|
294
|
+
const signingInput = Buffer.concat([proofHash, docHash]);
|
|
295
|
+
// Decode the base64url signature
|
|
296
|
+
const signatureBytes = Buffer.from(signatureBase64url, 'base64url');
|
|
297
|
+
// Use subtle crypto for Ed25519 verification
|
|
298
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey('jwk', publicKeyJwk, { name: 'Ed25519' }, false, ['verify']);
|
|
299
|
+
const isValid = await globalThis.crypto.subtle.verify({ name: 'Ed25519' }, cryptoKey, signatureBytes, signingInput);
|
|
300
|
+
if (!isValid) {
|
|
301
|
+
return {
|
|
302
|
+
valid: false,
|
|
303
|
+
reason: 'Ed25519 signature verification failed',
|
|
304
|
+
durationMs: Date.now() - startTime,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
270
307
|
return {
|
|
271
308
|
valid: true,
|
|
272
309
|
durationMs: Date.now() - startTime,
|
|
@@ -27,9 +27,13 @@ export interface VerifyDelegationResult {
|
|
|
27
27
|
user_did: string;
|
|
28
28
|
scopes: string[];
|
|
29
29
|
authorization: {
|
|
30
|
-
type: 'oauth' | 'credential' | 'none';
|
|
30
|
+
type: 'oauth' | 'oauth2' | 'password' | 'credential' | 'webauthn' | 'siwe' | 'none';
|
|
31
31
|
provider?: string;
|
|
32
32
|
credentialType?: string;
|
|
33
|
+
rpId?: string;
|
|
34
|
+
userVerification?: 'required' | 'preferred' | 'discouraged';
|
|
35
|
+
chainId?: number;
|
|
36
|
+
domain?: string;
|
|
33
37
|
};
|
|
34
38
|
[key: string]: unknown;
|
|
35
39
|
};
|
|
@@ -23,9 +23,13 @@ export interface ToolProtectionConfig {
|
|
|
23
23
|
authorizationUrl?: string;
|
|
24
24
|
/** Authorization method required for this tool */
|
|
25
25
|
authorization?: {
|
|
26
|
-
type: 'oauth' | 'credential' | 'none';
|
|
26
|
+
type: 'oauth' | 'oauth2' | 'password' | 'credential' | 'webauthn' | 'siwe' | 'none';
|
|
27
27
|
provider?: string;
|
|
28
28
|
credentialType?: string;
|
|
29
|
+
rpId?: string;
|
|
30
|
+
userVerification?: 'required' | 'preferred' | 'discouraged';
|
|
31
|
+
chainId?: number;
|
|
32
|
+
domain?: string;
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
35
|
/**
|