@metalabel/dfos-protocol 0.51.0 → 0.52.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/chain/index.d.ts +16 -4
- package/dist/chain/index.js +7 -5
- package/dist/{chunk-JVSC67DC.js → chunk-BMIOY5W5.js} +4 -9
- package/dist/{chunk-IDVYITX7.js → chunk-F7RHI2CK.js} +9 -1
- package/dist/{chunk-T2YR5KWQ.js → chunk-FZHHSC5N.js} +13 -8
- package/dist/{chunk-4LG2GEB2.js → chunk-KAW4MT4P.js} +140 -25
- package/dist/{chunk-LMAPBTDW.js → chunk-Q7FREWMY.js} +36 -26
- package/dist/credentials/index.d.ts +21 -20
- package/dist/credentials/index.js +3 -3
- package/dist/crypto/index.d.ts +27 -3
- package/dist/crypto/index.js +3 -1
- package/dist/{dfos-credential-CtG0_n4P.d.ts → dfos-credential-j-kHtFvG.d.ts} +2 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +9 -5
- package/dist/key-proof/index.d.ts +15 -14
- package/dist/key-proof/index.js +3 -3
- package/package.json +1 -1
package/dist/chain/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IdentityOperation, v as Signer, x as VerifiedIdentity, S as ServiceEntry, c as ContentOperation, R as ResolvedIdentity, r as RevocationChecker, d as CountersignPayload, a as ArtifactPayload } from '../dfos-credential-
|
|
2
|
-
export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, f as CreditClaimPayload, g as DeclaredKeyState, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_KEY_PROOFS, l as MAX_OPERATION_SIZE, m as MAX_SERVICES_ENTRIES, n as MAX_SERVICES_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_PAYLOAD_SIZE, p as MAX_SIGN_REQUEST_SIZE, q as MultikeyPublicKey, s as RevocationPayload, t as ServicesArray, u as SignRequestPayload, y as VoidKeyMembership, G as parseProtocolTimestampUnix } from '../dfos-credential-
|
|
1
|
+
import { I as IdentityOperation, v as Signer, x as VerifiedIdentity, S as ServiceEntry, c as ContentOperation, R as ResolvedIdentity, r as RevocationChecker, d as CountersignPayload, a as ArtifactPayload } from '../dfos-credential-j-kHtFvG.js';
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, f as CreditClaimPayload, g as DeclaredKeyState, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_KEY_PROOFS, l as MAX_OPERATION_SIZE, m as MAX_SERVICES_ENTRIES, n as MAX_SERVICES_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_PAYLOAD_SIZE, p as MAX_SIGN_REQUEST_SIZE, q as MultikeyPublicKey, s as RevocationPayload, t as ServicesArray, u as SignRequestPayload, y as VoidKeyMembership, G as parseProtocolTimestampUnix } from '../dfos-credential-j-kHtFvG.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/** Ed25519 public key multicodec value */
|
|
@@ -22,6 +22,17 @@ declare const decodeMultikey: (multibase: string) => {
|
|
|
22
22
|
keyBytes: Uint8Array;
|
|
23
23
|
codec: number;
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Decode a Multikey multibase string that MUST carry an Ed25519 PUBLIC key
|
|
27
|
+
*
|
|
28
|
+
* `decodeMultikey` also accepts the `ed25519-priv` prefix and reports it in
|
|
29
|
+
* `codec`, which a caller that destructures only `{ keyBytes }` silently
|
|
30
|
+
* discards — so a private-key-tagged multibase string would verify as if it were
|
|
31
|
+
* a public key, where the Go reference (DecodeMultikey) accepts the 0xed01
|
|
32
|
+
* prefix and nothing else. This is the decode every signature path takes, so the
|
|
33
|
+
* codec assertion cannot be forgotten at the next call site.
|
|
34
|
+
*/
|
|
35
|
+
declare const decodeEd25519PublicMultikey: (multibase: string) => Uint8Array;
|
|
25
36
|
|
|
26
37
|
/**
|
|
27
38
|
* Derive a prefixed chain identifier from CID bytes
|
|
@@ -529,7 +540,8 @@ declare const buildSignRequest: (input: {
|
|
|
529
540
|
requestCID: string;
|
|
530
541
|
}>;
|
|
531
542
|
/**
|
|
532
|
-
* Verify a sign-request envelope in
|
|
543
|
+
* Verify a sign-request envelope in RELAY.md, Envelope verification's exact 1–9
|
|
544
|
+
* order.
|
|
533
545
|
*
|
|
534
546
|
* `resolveIdentity` supplies CURRENT identity state. A missing identity or
|
|
535
547
|
* resolver failure is `unverifiable`; a deleted identity, missing current key,
|
|
@@ -548,4 +560,4 @@ declare const assertCanonicalSignRequestPayload: (payloadTyp: string, payloadByt
|
|
|
548
560
|
subject: string;
|
|
549
561
|
}) => void;
|
|
550
562
|
|
|
551
|
-
export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, type CreditClaimFailureReason, CreditClaimVerifyError, type CreditEntry, type CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, type SignRequestFailureReason, SignRequestVerifyError, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, type VerifiedCreditClaim, type VerifiedCreditEntry, VerifiedIdentity, type VerifiedRevocation, type VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest };
|
|
563
|
+
export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, type CreditClaimFailureReason, CreditClaimVerifyError, type CreditEntry, type CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, type SignRequestFailureReason, SignRequestVerifyError, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, type VerifiedCreditClaim, type VerifiedCreditEntry, VerifiedIdentity, type VerifiedRevocation, type VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeEd25519PublicMultikey, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest };
|
package/dist/chain/index.js
CHANGED
|
@@ -52,16 +52,17 @@ import {
|
|
|
52
52
|
verifyIdentityExtensionFromTrustedState,
|
|
53
53
|
verifyRevocation,
|
|
54
54
|
verifySignRequest
|
|
55
|
-
} from "../chunk-
|
|
56
|
-
import "../chunk-
|
|
57
|
-
import "../chunk-
|
|
55
|
+
} from "../chunk-Q7FREWMY.js";
|
|
56
|
+
import "../chunk-FZHHSC5N.js";
|
|
57
|
+
import "../chunk-BMIOY5W5.js";
|
|
58
58
|
import {
|
|
59
59
|
ED25519_PRIV_MULTICODEC,
|
|
60
60
|
ED25519_PUB_MULTICODEC,
|
|
61
|
+
decodeEd25519PublicMultikey,
|
|
61
62
|
decodeMultikey,
|
|
62
63
|
encodeEd25519Multikey
|
|
63
|
-
} from "../chunk-
|
|
64
|
-
import "../chunk-
|
|
64
|
+
} from "../chunk-F7RHI2CK.js";
|
|
65
|
+
import "../chunk-KAW4MT4P.js";
|
|
65
66
|
export {
|
|
66
67
|
ARTIFACT_CID_ANCHOR_RE,
|
|
67
68
|
ArtifactPayload,
|
|
@@ -97,6 +98,7 @@ export {
|
|
|
97
98
|
assertServicesWithinCap,
|
|
98
99
|
buildSignRequest,
|
|
99
100
|
classifyAnchor,
|
|
101
|
+
decodeEd25519PublicMultikey,
|
|
100
102
|
decodeMultikey,
|
|
101
103
|
deriveChainIdentifier,
|
|
102
104
|
deriveContentId,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
decodeMultikey,
|
|
2
|
+
decodeEd25519PublicMultikey,
|
|
4
3
|
encodeEd25519Multikey
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-F7RHI2CK.js";
|
|
6
5
|
import {
|
|
7
6
|
base64urlDecode,
|
|
8
7
|
base64urlEncode,
|
|
@@ -10,7 +9,7 @@ import {
|
|
|
10
9
|
isValidEd25519Signature,
|
|
11
10
|
sha256,
|
|
12
11
|
signPayloadEd25519
|
|
13
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KAW4MT4P.js";
|
|
14
13
|
|
|
15
14
|
// src/key-proof/role-set.ts
|
|
16
15
|
var KEY_ROLES = ["auth", "assert", "controller"];
|
|
@@ -205,11 +204,7 @@ var decodeKeyProof = (jws, expectedTyp) => {
|
|
|
205
204
|
var verifyKeyProofSignature = (decoded) => {
|
|
206
205
|
let keyBytes;
|
|
207
206
|
try {
|
|
208
|
-
|
|
209
|
-
if (key.codec !== ED25519_PUB_MULTICODEC) {
|
|
210
|
-
throw new Error("publicKeyMultibase is not an Ed25519 public key");
|
|
211
|
-
}
|
|
212
|
-
keyBytes = key.keyBytes;
|
|
207
|
+
keyBytes = decodeEd25519PublicMultikey(decoded.payload.publicKeyMultibase);
|
|
213
208
|
} catch (err) {
|
|
214
209
|
throw invalid(
|
|
215
210
|
"signature",
|
|
@@ -36,10 +36,18 @@ var decodeMultikey = (multibase) => {
|
|
|
36
36
|
`unsupported multikey codec: [0x${bytes[0]?.toString(16)}, 0x${bytes[1]?.toString(16)}]`
|
|
37
37
|
);
|
|
38
38
|
};
|
|
39
|
+
var decodeEd25519PublicMultikey = (multibase) => {
|
|
40
|
+
const { keyBytes, codec } = decodeMultikey(multibase);
|
|
41
|
+
if (codec !== ED25519_PUB_MULTICODEC) {
|
|
42
|
+
throw new Error("publicKeyMultibase is not an Ed25519 public key");
|
|
43
|
+
}
|
|
44
|
+
return keyBytes;
|
|
45
|
+
};
|
|
39
46
|
|
|
40
47
|
export {
|
|
41
48
|
ED25519_PUB_MULTICODEC,
|
|
42
49
|
ED25519_PRIV_MULTICODEC,
|
|
43
50
|
encodeEd25519Multikey,
|
|
44
|
-
decodeMultikey
|
|
51
|
+
decodeMultikey,
|
|
52
|
+
decodeEd25519PublicMultikey
|
|
45
53
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
decodeEd25519PublicMultikey
|
|
3
|
+
} from "./chunk-F7RHI2CK.js";
|
|
4
4
|
import {
|
|
5
5
|
assertJwsProfile,
|
|
6
6
|
base64urlDecode,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
decodeJwsUnsafe,
|
|
11
11
|
sha256,
|
|
12
12
|
verifyJws
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KAW4MT4P.js";
|
|
14
14
|
|
|
15
15
|
// src/credentials/schemas.ts
|
|
16
16
|
import { z } from "zod";
|
|
@@ -355,7 +355,10 @@ var verifyProofEnvelope = async (input, shape, resolvePresenter) => {
|
|
|
355
355
|
const key = state.keys.find((candidate) => candidate.id === presenterKeyId);
|
|
356
356
|
if (!key) throw invalidProof(`${shape.label} signing key is not a current key of the presenter`);
|
|
357
357
|
try {
|
|
358
|
-
verifyJws({
|
|
358
|
+
verifyJws({
|
|
359
|
+
token: input.proof,
|
|
360
|
+
publicKey: decodeEd25519PublicMultikey(key.publicKeyMultibase)
|
|
361
|
+
});
|
|
359
362
|
} catch (err) {
|
|
360
363
|
throw invalidProof(err instanceof Error ? err.message : `invalid ${shape.label} signature`);
|
|
361
364
|
}
|
|
@@ -382,7 +385,7 @@ var resolveKeyFromIdentity = (identity, kid, determinate) => {
|
|
|
382
385
|
);
|
|
383
386
|
throw determinate ? miss : markDependencyMissing(miss);
|
|
384
387
|
}
|
|
385
|
-
const
|
|
388
|
+
const keyBytes = decodeEd25519PublicMultikey(key.publicKeyMultibase);
|
|
386
389
|
return keyBytes;
|
|
387
390
|
};
|
|
388
391
|
var basisUnixSeconds = (basis) => {
|
|
@@ -435,6 +438,7 @@ var verifyDFOSCredential = async (jwsToken, options) => {
|
|
|
435
438
|
}
|
|
436
439
|
const payload = result.data;
|
|
437
440
|
const kid = decoded.header.kid;
|
|
441
|
+
if (kid === void 0) throw new CredentialVerificationError("credential kid must be present");
|
|
438
442
|
const hashIdx = kid.indexOf("#");
|
|
439
443
|
if (hashIdx < 0) throw new CredentialVerificationError("credential kid must be a DID URL");
|
|
440
444
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -456,7 +460,7 @@ var verifyDFOSCredential = async (jwsToken, options) => {
|
|
|
456
460
|
} catch {
|
|
457
461
|
throw new CredentialVerificationError("invalid credential signature");
|
|
458
462
|
}
|
|
459
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
463
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
460
464
|
const credentialCID = encoded.cid.toString();
|
|
461
465
|
if (!decoded.header.cid) {
|
|
462
466
|
throw new CredentialVerificationError("missing cid in credential header");
|
|
@@ -534,8 +538,9 @@ var parseResource = (resource) => {
|
|
|
534
538
|
if (colonIdx < 0) return null;
|
|
535
539
|
return { type: resource.substring(0, colonIdx), id: resource.substring(colonIdx + 1) };
|
|
536
540
|
};
|
|
541
|
+
var ASCII_TRIM_RE = /^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g;
|
|
537
542
|
var parseActions = (action) => new Set(
|
|
538
|
-
action.split(",").map((a) => a.
|
|
543
|
+
action.split(",").map((a) => a.replace(ASCII_TRIM_RE, "")).filter((a) => a !== "")
|
|
539
544
|
);
|
|
540
545
|
var isAttenuated = (parentAtt, childAtt) => {
|
|
541
546
|
return childAtt.every((childEntry) => {
|
|
@@ -592,7 +597,7 @@ var matchesResource = async (att, resource, action) => {
|
|
|
592
597
|
};
|
|
593
598
|
var decodeDFOSCredentialUnsafe = (jwsToken) => {
|
|
594
599
|
const decoded = decodeJwsUnsafe(jwsToken);
|
|
595
|
-
if (!decoded) return null;
|
|
600
|
+
if (!decoded || decoded.header.kid === void 0) return null;
|
|
596
601
|
const result = DFOSCredentialPayload.safeParse(decoded.payload);
|
|
597
602
|
if (!result.success) return null;
|
|
598
603
|
return {
|
|
@@ -79,6 +79,68 @@ var normalizedId = (prefix, id) => {
|
|
|
79
79
|
return `${prefixLowered}_${idLowered}`;
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
// src/crypto/json-scan.ts
|
|
83
|
+
var assertCanonicalJsonText = (text) => {
|
|
84
|
+
const frames = [];
|
|
85
|
+
let i = 0;
|
|
86
|
+
while (i < text.length) {
|
|
87
|
+
const ch = text[i];
|
|
88
|
+
if (ch === '"') {
|
|
89
|
+
const end = scanStringToken(text, i);
|
|
90
|
+
if (end < 0) return;
|
|
91
|
+
const value = decodeStringToken(text.slice(i, end));
|
|
92
|
+
if (value === null) return;
|
|
93
|
+
if (LONE_SURROGATE_RE.test(value)) {
|
|
94
|
+
throw new Error("string with an unpaired surrogate is not canonicalizable");
|
|
95
|
+
}
|
|
96
|
+
const frame = frames[frames.length - 1];
|
|
97
|
+
if (frame && frame.isObject && frame.awaitingKey) {
|
|
98
|
+
if (frame.keys.has(value)) {
|
|
99
|
+
throw new Error(`duplicate JSON key is malformed: ${JSON.stringify(value)}`);
|
|
100
|
+
}
|
|
101
|
+
frame.keys.add(value);
|
|
102
|
+
frame.awaitingKey = false;
|
|
103
|
+
}
|
|
104
|
+
i = end;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (ch === "{") {
|
|
108
|
+
frames.push({ isObject: true, keys: /* @__PURE__ */ new Set(), awaitingKey: true });
|
|
109
|
+
} else if (ch === "[") {
|
|
110
|
+
frames.push({ isObject: false, keys: /* @__PURE__ */ new Set(), awaitingKey: false });
|
|
111
|
+
} else if (ch === "}" || ch === "]") {
|
|
112
|
+
frames.pop();
|
|
113
|
+
} else if (ch === ",") {
|
|
114
|
+
const frame = frames[frames.length - 1];
|
|
115
|
+
if (frame && frame.isObject) frame.awaitingKey = true;
|
|
116
|
+
}
|
|
117
|
+
i++;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var scanStringToken = (text, start) => {
|
|
121
|
+
let i = start + 1;
|
|
122
|
+
while (i < text.length) {
|
|
123
|
+
const ch = text[i];
|
|
124
|
+
if (ch === "\\") {
|
|
125
|
+
i += 2;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (ch === '"') return i + 1;
|
|
129
|
+
i++;
|
|
130
|
+
}
|
|
131
|
+
return -1;
|
|
132
|
+
};
|
|
133
|
+
var decodeStringToken = (raw) => {
|
|
134
|
+
if (!raw.includes("\\")) return raw.slice(1, -1);
|
|
135
|
+
try {
|
|
136
|
+
const value = JSON.parse(raw);
|
|
137
|
+
return typeof value === "string" ? value : null;
|
|
138
|
+
} catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
var LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
143
|
+
|
|
82
144
|
// src/crypto/jws-profile.ts
|
|
83
145
|
var assertJwsProfile = (header, makeError) => {
|
|
84
146
|
if (header.alg !== "EdDSA") {
|
|
@@ -96,6 +158,30 @@ var assertJwsProfile = (header, makeError) => {
|
|
|
96
158
|
};
|
|
97
159
|
|
|
98
160
|
// src/crypto/jws.ts
|
|
161
|
+
var decodeJwsSegment = (segmentB64) => {
|
|
162
|
+
let text;
|
|
163
|
+
try {
|
|
164
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(base64urlDecode(segmentB64));
|
|
165
|
+
} catch {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
assertCanonicalJsonText(text);
|
|
169
|
+
let value;
|
|
170
|
+
try {
|
|
171
|
+
value = JSON.parse(text);
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
176
|
+
return value;
|
|
177
|
+
};
|
|
178
|
+
var asJwsHeader = (raw) => {
|
|
179
|
+
if (typeof raw["alg"] !== "string") return null;
|
|
180
|
+
if (typeof raw["typ"] !== "string") return null;
|
|
181
|
+
if ("kid" in raw && typeof raw["kid"] !== "string") return null;
|
|
182
|
+
if ("cid" in raw && typeof raw["cid"] !== "string") return null;
|
|
183
|
+
return raw;
|
|
184
|
+
};
|
|
99
185
|
var createJws = async (options) => {
|
|
100
186
|
const headerB64 = base64urlEncode(JSON.stringify(options.header));
|
|
101
187
|
const payloadB64 = base64urlEncode(JSON.stringify(options.payload));
|
|
@@ -111,18 +197,22 @@ var verifyJws = (options) => {
|
|
|
111
197
|
throw new JwsVerificationError("Invalid token format");
|
|
112
198
|
}
|
|
113
199
|
const [headerB64, payloadB64, signatureB64] = parts;
|
|
114
|
-
let
|
|
200
|
+
let rawHeader;
|
|
115
201
|
let payload;
|
|
116
202
|
try {
|
|
117
|
-
|
|
118
|
-
payload =
|
|
119
|
-
} catch {
|
|
203
|
+
rawHeader = decodeJwsSegment(headerB64);
|
|
204
|
+
payload = decodeJwsSegment(payloadB64);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
throw new JwsVerificationError(e.message);
|
|
207
|
+
}
|
|
208
|
+
if (!rawHeader || !payload) {
|
|
120
209
|
throw new JwsVerificationError("Failed to decode token");
|
|
121
210
|
}
|
|
122
|
-
assertJwsProfile(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
211
|
+
assertJwsProfile(rawHeader, (m) => new JwsVerificationError(m));
|
|
212
|
+
const header = asJwsHeader(rawHeader);
|
|
213
|
+
if (!header) {
|
|
214
|
+
throw new JwsVerificationError("Invalid protected header");
|
|
215
|
+
}
|
|
126
216
|
const signingInput = `${headerB64}.${payloadB64}`;
|
|
127
217
|
const signingInputBytes = new TextEncoder().encode(signingInput);
|
|
128
218
|
const signatureBytes = base64urlDecode(signatureB64);
|
|
@@ -135,14 +225,19 @@ var verifyJws = (options) => {
|
|
|
135
225
|
var decodeJwsUnsafe = (token) => {
|
|
136
226
|
const parts = token.split(".");
|
|
137
227
|
if (parts.length !== 3) return null;
|
|
228
|
+
const [headerB64, payloadB64] = parts;
|
|
229
|
+
let rawHeader;
|
|
230
|
+
let payload;
|
|
138
231
|
try {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const payload = JSON.parse(new TextDecoder().decode(base64urlDecode(payloadB64)));
|
|
142
|
-
return { header, payload };
|
|
232
|
+
rawHeader = decodeJwsSegment(headerB64);
|
|
233
|
+
payload = decodeJwsSegment(payloadB64);
|
|
143
234
|
} catch {
|
|
144
235
|
return null;
|
|
145
236
|
}
|
|
237
|
+
if (!rawHeader || !payload) return null;
|
|
238
|
+
const header = asJwsHeader(rawHeader);
|
|
239
|
+
if (!header) return null;
|
|
240
|
+
return { header, payload };
|
|
146
241
|
};
|
|
147
242
|
var JwsVerificationError = class extends Error {
|
|
148
243
|
constructor(message) {
|
|
@@ -203,7 +298,7 @@ var verifyJwt = (options) => {
|
|
|
203
298
|
const isValid = isValidEd25519Signature(signingInputBytes, signatureBytes, options.publicKey);
|
|
204
299
|
if (!isValid) throw new JwtVerificationError("Invalid signature");
|
|
205
300
|
const currentTime = options.currentTime ?? Math.floor(Date.now() / 1e3);
|
|
206
|
-
if (payload.exp <= currentTime) {
|
|
301
|
+
if (!Number.isSafeInteger(payload.exp) || payload.exp <= currentTime) {
|
|
207
302
|
throw new JwtVerificationError("Token expired");
|
|
208
303
|
}
|
|
209
304
|
if (options.issuer !== void 0 && payload.iss !== options.issuer) {
|
|
@@ -231,20 +326,25 @@ import * as Block from "multiformats/block";
|
|
|
231
326
|
import { CID } from "multiformats/cid";
|
|
232
327
|
import { sha256 as sha2562 } from "multiformats/hashes/sha2";
|
|
233
328
|
var dagCborCanonicalEncode = async (value) => {
|
|
234
|
-
|
|
329
|
+
assertCanonicalValue(value);
|
|
235
330
|
const serialized = JSON.parse(JSON.stringify(value));
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
331
|
+
assertCanonicalValue(serialized);
|
|
332
|
+
try {
|
|
333
|
+
return await Block.encode({
|
|
334
|
+
// removes any undefineds or other non-serializable values (and normalizes
|
|
335
|
+
// -0 to 0)
|
|
336
|
+
value: serialized,
|
|
337
|
+
codec: dagCborCodec,
|
|
338
|
+
hasher: sha2562
|
|
339
|
+
});
|
|
340
|
+
} catch (e) {
|
|
341
|
+
throw new Error(`value is not canonically encodable: ${e.message}`);
|
|
342
|
+
}
|
|
244
343
|
};
|
|
245
344
|
var MAX_SAFE_CANONICAL_INTEGER = 9007199254740991;
|
|
246
345
|
var MAX_CANONICAL_DEPTH = 1024;
|
|
247
|
-
var
|
|
346
|
+
var LONE_SURROGATE_RE2 = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
347
|
+
var assertCanonicalValue = (value, depth = 0) => {
|
|
248
348
|
if (depth > MAX_CANONICAL_DEPTH) {
|
|
249
349
|
throw new Error(`value nesting exceeds max depth ${MAX_CANONICAL_DEPTH}`);
|
|
250
350
|
}
|
|
@@ -264,12 +364,26 @@ var assertCanonicalNumbers = (value, depth = 0) => {
|
|
|
264
364
|
}
|
|
265
365
|
return;
|
|
266
366
|
}
|
|
367
|
+
if (typeof value === "string") {
|
|
368
|
+
if (LONE_SURROGATE_RE2.test(value)) {
|
|
369
|
+
throw new Error("string with an unpaired surrogate is not canonicalizable");
|
|
370
|
+
}
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
267
373
|
if (Array.isArray(value)) {
|
|
268
|
-
for (const entry of value)
|
|
374
|
+
for (const entry of value) assertCanonicalValue(entry, depth + 1);
|
|
269
375
|
return;
|
|
270
376
|
}
|
|
271
377
|
if (value !== null && typeof value === "object") {
|
|
272
|
-
|
|
378
|
+
if ("/" in value && "bytes" in value) {
|
|
379
|
+
throw new Error('object carrying both "/" and "bytes" members is not canonicalizable');
|
|
380
|
+
}
|
|
381
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
382
|
+
if (LONE_SURROGATE_RE2.test(key)) {
|
|
383
|
+
throw new Error("string with an unpaired surrogate is not canonicalizable");
|
|
384
|
+
}
|
|
385
|
+
assertCanonicalValue(entry, depth + 1);
|
|
386
|
+
}
|
|
273
387
|
}
|
|
274
388
|
};
|
|
275
389
|
var parseDagCborCID = (cid) => {
|
|
@@ -293,6 +407,7 @@ export {
|
|
|
293
407
|
generateId,
|
|
294
408
|
isValidId,
|
|
295
409
|
normalizedId,
|
|
410
|
+
assertCanonicalJsonText,
|
|
296
411
|
assertJwsProfile,
|
|
297
412
|
createJws,
|
|
298
413
|
verifyJws,
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
matchesResource,
|
|
7
7
|
verifyDFOSCredential,
|
|
8
8
|
verifyDelegationChain
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FZHHSC5N.js";
|
|
10
10
|
import {
|
|
11
11
|
KEY_ADD_JWS_TYP,
|
|
12
12
|
KEY_ROLES,
|
|
13
13
|
unsafeKeyProofSubject,
|
|
14
14
|
verifyChainKeyProof
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BMIOY5W5.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
} from "./chunk-
|
|
17
|
+
decodeEd25519PublicMultikey
|
|
18
|
+
} from "./chunk-F7RHI2CK.js";
|
|
19
19
|
import {
|
|
20
20
|
assertJwsProfile,
|
|
21
21
|
base64urlDecode,
|
|
@@ -25,13 +25,13 @@ import {
|
|
|
25
25
|
decodeJwsUnsafe,
|
|
26
26
|
generateIdNoPrefix,
|
|
27
27
|
verifyJws
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-KAW4MT4P.js";
|
|
29
29
|
|
|
30
30
|
// src/chain/schemas.ts
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
var MAX_KEYS_PER_ROLE = 256;
|
|
33
33
|
var MAX_KEY_PROOFS = 256;
|
|
34
|
-
var
|
|
34
|
+
var MAX_RELATION_BYTES = 64;
|
|
35
35
|
var MAX_SERVICES_ENTRIES = 256;
|
|
36
36
|
var MAX_SERVICES_PAYLOAD_SIZE = 32768;
|
|
37
37
|
var MAX_OPERATION_SIZE = 65536;
|
|
@@ -78,7 +78,7 @@ var parseProtocolTimestampUnix = (value) => {
|
|
|
78
78
|
const ms = Date.parse(value);
|
|
79
79
|
return Number.isFinite(ms) ? Math.floor(ms / 1e3) : null;
|
|
80
80
|
};
|
|
81
|
-
var CIDString = z.string();
|
|
81
|
+
var CIDString = z.string().min(1, "CID must not be empty");
|
|
82
82
|
var IdentityCreate = z.looseObject({
|
|
83
83
|
version: z.literal(1),
|
|
84
84
|
type: z.literal("create"),
|
|
@@ -261,7 +261,9 @@ var CountersignPayload = z.looseObject({
|
|
|
261
261
|
type: z.literal("countersign"),
|
|
262
262
|
did: z.string(),
|
|
263
263
|
targetCID: CIDString,
|
|
264
|
-
relation: z.string().min(1).
|
|
264
|
+
relation: z.string().min(1).refine((value) => new TextEncoder().encode(value).length <= MAX_RELATION_BYTES, {
|
|
265
|
+
message: `relation exceeds ${MAX_RELATION_BYTES} bytes`
|
|
266
|
+
}).optional(),
|
|
265
267
|
createdAt: Iso8601
|
|
266
268
|
});
|
|
267
269
|
var RevocationPayload = z.looseObject({
|
|
@@ -544,7 +546,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
544
546
|
}
|
|
545
547
|
}
|
|
546
548
|
}
|
|
547
|
-
const encoded = await dagCborCanonicalEncode(
|
|
549
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
548
550
|
if (encoded.bytes.length > MAX_OPERATION_SIZE) {
|
|
549
551
|
throw new Error(
|
|
550
552
|
`log[${idx}]: operation exceeds max size: ${encoded.bytes.length} > ${MAX_OPERATION_SIZE}`
|
|
@@ -558,6 +560,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
558
560
|
throw new Error(`log[${idx}]: cid mismatch in protected header`);
|
|
559
561
|
}
|
|
560
562
|
const kid = decoded.header.kid;
|
|
563
|
+
if (kid === void 0) throw new Error(`log[${idx}]: kid must be present`);
|
|
561
564
|
let signingKeyId;
|
|
562
565
|
if (kid.includes("#")) {
|
|
563
566
|
const hashIdx = kid.indexOf("#");
|
|
@@ -575,7 +578,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
575
578
|
if (!signingKey) {
|
|
576
579
|
throw new Error(`log[${idx}]: kid references unknown key: ${signingKeyId}`);
|
|
577
580
|
}
|
|
578
|
-
const
|
|
581
|
+
const keyBytes = decodeEd25519PublicMultikey(signingKey.publicKeyMultibase);
|
|
579
582
|
try {
|
|
580
583
|
verifyJws({ token: jwsToken, publicKey: keyBytes });
|
|
581
584
|
} catch {
|
|
@@ -694,7 +697,7 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
694
697
|
if (op.createdAt <= lastCreatedAt) {
|
|
695
698
|
throw new Error("createdAt must be after last op");
|
|
696
699
|
}
|
|
697
|
-
const encoded = await dagCborCanonicalEncode(
|
|
700
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
698
701
|
if (encoded.bytes.length > MAX_OPERATION_SIZE) {
|
|
699
702
|
throw new Error(`operation exceeds max size: ${encoded.bytes.length} > ${MAX_OPERATION_SIZE}`);
|
|
700
703
|
}
|
|
@@ -702,6 +705,7 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
702
705
|
if (!decoded.header.cid) throw new Error("missing cid in protected header");
|
|
703
706
|
if (decoded.header.cid !== operationCID) throw new Error("cid mismatch in protected header");
|
|
704
707
|
const kid = decoded.header.kid;
|
|
708
|
+
if (kid === void 0) throw new Error("kid must be present");
|
|
705
709
|
if (!kid.includes("#")) {
|
|
706
710
|
throw new Error("non-genesis op kid must be DID URL, got bare key ID");
|
|
707
711
|
}
|
|
@@ -715,7 +719,7 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
715
719
|
if (!signingKey) {
|
|
716
720
|
throw new Error(`kid references unknown key: ${signingKeyId}`);
|
|
717
721
|
}
|
|
718
|
-
const
|
|
722
|
+
const keyBytes = decodeEd25519PublicMultikey(signingKey.publicKeyMultibase);
|
|
719
723
|
try {
|
|
720
724
|
verifyJws({ token: newOp, publicKey: keyBytes });
|
|
721
725
|
} catch {
|
|
@@ -791,11 +795,13 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
791
795
|
|
|
792
796
|
// src/chain/content-chain.ts
|
|
793
797
|
var operationSizeForCap = async (op, fullByteLength) => {
|
|
798
|
+
if (op.type === "create") return fullByteLength;
|
|
794
799
|
const auth = op.authorization;
|
|
795
800
|
if (typeof auth !== "string") return fullByteLength;
|
|
796
|
-
|
|
801
|
+
const authByteLength = new TextEncoder().encode(auth).length;
|
|
802
|
+
if (authByteLength > MAX_CREDENTIAL_SIZE) {
|
|
797
803
|
throw new Error(
|
|
798
|
-
`authorization credential exceeds max size: ${
|
|
804
|
+
`authorization credential exceeds max size: ${authByteLength} > ${MAX_CREDENTIAL_SIZE}`
|
|
799
805
|
);
|
|
800
806
|
}
|
|
801
807
|
const { authorization: _omit, ...rest } = op;
|
|
@@ -888,6 +894,7 @@ var verifyContentChain = async (input) => {
|
|
|
888
894
|
}
|
|
889
895
|
}
|
|
890
896
|
const kid = decoded.header.kid;
|
|
897
|
+
if (kid === void 0) throw new Error(`log[${idx}]: kid must be present`);
|
|
891
898
|
const hashIdx = kid.indexOf("#");
|
|
892
899
|
if (hashIdx < 0) throw new Error(`log[${idx}]: kid must be a DID URL`);
|
|
893
900
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -927,8 +934,8 @@ var verifyContentChain = async (input) => {
|
|
|
927
934
|
);
|
|
928
935
|
}
|
|
929
936
|
}
|
|
930
|
-
const encoded = await dagCborCanonicalEncode(
|
|
931
|
-
const opSize = await operationSizeForCap(
|
|
937
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
938
|
+
const opSize = await operationSizeForCap(decoded.payload, encoded.bytes.length);
|
|
932
939
|
if (opSize > MAX_OPERATION_SIZE) {
|
|
933
940
|
throw new Error(`operation exceeds max size: ${opSize} > ${MAX_OPERATION_SIZE}`);
|
|
934
941
|
}
|
|
@@ -998,6 +1005,7 @@ var verifyContentExtensionFromTrustedState = async (input) => {
|
|
|
998
1005
|
throw new Error("createdAt must be after last op");
|
|
999
1006
|
}
|
|
1000
1007
|
const kid = decoded.header.kid;
|
|
1008
|
+
if (kid === void 0) throw new Error("kid must be present");
|
|
1001
1009
|
const hashIdx = kid.indexOf("#");
|
|
1002
1010
|
if (hashIdx < 0) throw new Error("kid must be a DID URL");
|
|
1003
1011
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -1032,8 +1040,8 @@ var verifyContentExtensionFromTrustedState = async (input) => {
|
|
|
1032
1040
|
throw carryDependencyMissing(err, new Error(`authorization verification failed: ${message}`));
|
|
1033
1041
|
}
|
|
1034
1042
|
}
|
|
1035
|
-
const encoded = await dagCborCanonicalEncode(
|
|
1036
|
-
const opSize = await operationSizeForCap(
|
|
1043
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1044
|
+
const opSize = await operationSizeForCap(decoded.payload, encoded.bytes.length);
|
|
1037
1045
|
if (opSize > MAX_OPERATION_SIZE) {
|
|
1038
1046
|
throw new Error(`operation exceeds max size: ${opSize} > ${MAX_OPERATION_SIZE}`);
|
|
1039
1047
|
}
|
|
@@ -1076,6 +1084,7 @@ var verifyCountersignature = async (input) => {
|
|
|
1076
1084
|
}
|
|
1077
1085
|
const payload = result.data;
|
|
1078
1086
|
const kid = decoded.header.kid;
|
|
1087
|
+
if (kid === void 0) throw new Error("kid must be present");
|
|
1079
1088
|
const hashIdx = kid.indexOf("#");
|
|
1080
1089
|
if (hashIdx < 0) throw new Error("countersignature kid must be a DID URL");
|
|
1081
1090
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -1129,6 +1138,7 @@ var verifyArtifact = async (input) => {
|
|
|
1129
1138
|
throw new Error(`invalid artifact typ: ${decoded.header.typ}`);
|
|
1130
1139
|
}
|
|
1131
1140
|
const kid = decoded.header.kid;
|
|
1141
|
+
if (kid === void 0) throw new Error("kid must be present");
|
|
1132
1142
|
const hashIdx = kid.indexOf("#");
|
|
1133
1143
|
if (hashIdx < 0) throw new Error("artifact kid must be a DID URL");
|
|
1134
1144
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -1186,6 +1196,7 @@ var verifyRevocation = async (input) => {
|
|
|
1186
1196
|
throw new Error(`invalid revocation typ: ${decoded.header.typ}`);
|
|
1187
1197
|
}
|
|
1188
1198
|
const kid = decoded.header.kid;
|
|
1199
|
+
if (kid === void 0) throw new Error("kid must be present");
|
|
1189
1200
|
const hashIdx = kid.indexOf("#");
|
|
1190
1201
|
if (hashIdx < 0) throw new Error("revocation kid must be a DID URL");
|
|
1191
1202
|
const kidDid = kid.substring(0, hashIdx);
|
|
@@ -1198,7 +1209,7 @@ var verifyRevocation = async (input) => {
|
|
|
1198
1209
|
} catch {
|
|
1199
1210
|
throw new Error("invalid revocation signature");
|
|
1200
1211
|
}
|
|
1201
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
1212
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1202
1213
|
const revocationCID = encoded.cid.toString();
|
|
1203
1214
|
if (!decoded.header.cid) throw new Error("missing cid in revocation header");
|
|
1204
1215
|
if (decoded.header.cid !== revocationCID) throw new Error("revocation cid mismatch");
|
|
@@ -1231,7 +1242,7 @@ var resolveKeyFromIdentity = (identity, kid) => {
|
|
|
1231
1242
|
if (!key) {
|
|
1232
1243
|
throw markDependencyMissing(invalid(`key ${keyId} not found on identity ${identity.did}`));
|
|
1233
1244
|
}
|
|
1234
|
-
const
|
|
1245
|
+
const keyBytes = decodeEd25519PublicMultikey(key.publicKeyMultibase);
|
|
1235
1246
|
return keyBytes;
|
|
1236
1247
|
};
|
|
1237
1248
|
var normalizeClaimCreatedAt = (createdAt) => {
|
|
@@ -1291,8 +1302,7 @@ var verifyCreditClaim = async (jwsToken, options) => {
|
|
|
1291
1302
|
}
|
|
1292
1303
|
const decoded = decodeJwsUnsafe(jwsToken);
|
|
1293
1304
|
if (!decoded) throw invalid("failed to decode credit claim JWS");
|
|
1294
|
-
|
|
1295
|
-
if (typeof rawHeader["typ"] !== "string" || typeof rawHeader["kid"] !== "string") {
|
|
1305
|
+
if (typeof decoded.header.kid !== "string") {
|
|
1296
1306
|
throw invalid("credit claim header must carry a string typ and kid");
|
|
1297
1307
|
}
|
|
1298
1308
|
if (decoded.header.typ !== "did:dfos:credit-claim") {
|
|
@@ -1327,7 +1337,7 @@ var verifyCreditClaim = async (jwsToken, options) => {
|
|
|
1327
1337
|
} catch {
|
|
1328
1338
|
throw invalid("invalid credit claim signature");
|
|
1329
1339
|
}
|
|
1330
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
1340
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1331
1341
|
const claimCID = encoded.cid.toString();
|
|
1332
1342
|
if (!decoded.header.cid) throw invalid("missing cid in credit claim header");
|
|
1333
1343
|
if (decoded.header.cid !== claimCID) throw invalid("credit claim cid mismatch");
|
|
@@ -1454,7 +1464,7 @@ var resolveCurrentKey = (identity, kid) => {
|
|
|
1454
1464
|
);
|
|
1455
1465
|
if (!key) throw invalid2(`key ${keyId} not found on current identity ${identity.did}`);
|
|
1456
1466
|
try {
|
|
1457
|
-
return
|
|
1467
|
+
return decodeEd25519PublicMultikey(key.publicKeyMultibase);
|
|
1458
1468
|
} catch {
|
|
1459
1469
|
throw invalid2(`key ${keyId} on identity ${identity.did} is not a valid Ed25519 multikey`);
|
|
1460
1470
|
}
|
|
@@ -1518,7 +1528,7 @@ var verifySignRequest = async (jwsToken, options) => {
|
|
|
1518
1528
|
throw invalid2("sign request protected header must be an object");
|
|
1519
1529
|
}
|
|
1520
1530
|
assertJwsProfile(rawHeader, invalid2);
|
|
1521
|
-
if (typeof rawHeader["typ"] !== "string" || typeof
|
|
1531
|
+
if (typeof rawHeader["typ"] !== "string" || typeof decoded.header.kid !== "string") {
|
|
1522
1532
|
throw invalid2("sign request header must carry a string typ and kid");
|
|
1523
1533
|
}
|
|
1524
1534
|
if (decoded.header.typ !== "did:dfos:sign-request") {
|
|
@@ -1554,7 +1564,7 @@ var verifySignRequest = async (jwsToken, options) => {
|
|
|
1554
1564
|
}
|
|
1555
1565
|
let encoded;
|
|
1556
1566
|
try {
|
|
1557
|
-
encoded = await dagCborCanonicalEncode(payload);
|
|
1567
|
+
encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1558
1568
|
} catch (error) {
|
|
1559
1569
|
const detail = error instanceof Error ? error.message : String(error);
|
|
1560
1570
|
throw invalid2(`failed to derive sign request CID: ${detail}`);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
export { b as Attenuation, e as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as ResolvedIdentity, r as RevocationChecker, V as VerifiedDFOSCredential, w as VerifiedDelegationChain, z as createDFOSCredential, B as decodeDFOSCredentialUnsafe, E as isAttenuated, F as matchesResource, H as verifyDFOSCredential, J as verifyDelegationChain } from '../dfos-credential-
|
|
1
|
+
export { b as Attenuation, e as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as ResolvedIdentity, r as RevocationChecker, V as VerifiedDFOSCredential, w as VerifiedDelegationChain, z as createDFOSCredential, B as decodeDFOSCredentialUnsafe, E as isAttenuated, F as matchesResource, H as verifyDFOSCredential, J as verifyDelegationChain } from '../dfos-credential-j-kHtFvG.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* The normative JWS header `typ` for a request proof (
|
|
6
|
-
* set it; the request-proof verifier rejects
|
|
7
|
-
* typ-routing dispatchers tell a proof
|
|
5
|
+
* The normative JWS header `typ` for a request proof (INTEGRATIONS.md, The
|
|
6
|
+
* request proof). Signers MUST set it; the request-proof verifier rejects
|
|
7
|
+
* anything else — it is also what lets typ-routing dispatchers tell a proof
|
|
8
|
+
* apart from credentials and chain ops.
|
|
8
9
|
*/
|
|
9
10
|
declare const REQUEST_PROOF_JWS_TYP = "did:dfos:request-proof";
|
|
10
11
|
/**
|
|
11
|
-
* The normative JWS header `typ` for an identity proof (
|
|
12
|
-
* request proof's credential-less sibling.
|
|
12
|
+
* The normative JWS header `typ` for an identity proof (INTEGRATIONS.md, The
|
|
13
|
+
* identity proof) — the request proof's credential-less sibling.
|
|
13
14
|
*
|
|
14
15
|
* THE TYP GATE IS ABSOLUTE, IN BOTH DIRECTIONS. "Possession of a grant's
|
|
15
16
|
* audience key" and "possession of a bare identity's key" are different claims,
|
|
@@ -84,10 +85,10 @@ interface IdentityProofPayload {
|
|
|
84
85
|
/**
|
|
85
86
|
* ADDITIVE MEMBERS, appended AFTER the canonical order.
|
|
86
87
|
*
|
|
87
|
-
*
|
|
88
|
-
* envelope: "additional members register
|
|
89
|
-
* order". `jti` — the per-request
|
|
90
|
-
* requires — is the named one.
|
|
88
|
+
* INTEGRATIONS.md, One envelope, optional credential's growth rule is additive
|
|
89
|
+
* members on this envelope, never a new envelope: "additional members register
|
|
90
|
+
* additively, appended to the canonical order". `jti` — the per-request
|
|
91
|
+
* uniqueness member a write-gating deployment requires — is the named one.
|
|
91
92
|
*
|
|
92
93
|
* TWO RULES MAKE THIS A BYTE-TWIN. (1) Extra members are emitted AFTER every
|
|
93
94
|
* canonical member, so a verifier that ignores them still reconstructs the same
|
|
@@ -173,7 +174,7 @@ interface SignApiRequestInput {
|
|
|
173
174
|
/**
|
|
174
175
|
* ADDITIVE members, appended after the canonical order in lexicographic name
|
|
175
176
|
* order. `{ jti }` is the registered one — required by a deployment that gates
|
|
176
|
-
* WRITES with this envelope (
|
|
177
|
+
* WRITES with this envelope (INTEGRATIONS.md, API security notes).
|
|
177
178
|
*/
|
|
178
179
|
extraMembers?: ProofExtraMembers;
|
|
179
180
|
}
|
|
@@ -211,7 +212,7 @@ interface SignApiIdentityRequestInput {
|
|
|
211
212
|
/**
|
|
212
213
|
* ADDITIVE members, appended after the canonical order in lexicographic name
|
|
213
214
|
* order. `{ jti }` is the registered one, and a WRITE-SHAPED surface — relay
|
|
214
|
-
* ingestion, blob upload — REQUIRES it (
|
|
215
|
+
* ingestion, blob upload — REQUIRES it (INTEGRATIONS.md, API security notes).
|
|
215
216
|
*/
|
|
216
217
|
extraMembers?: ProofExtraMembers;
|
|
217
218
|
}
|
|
@@ -247,8 +248,8 @@ declare const buildApiAuthHeaders: (input: {
|
|
|
247
248
|
* On an `api:<host>` surface an accompanying `X-Credential` is MALFORMED: the
|
|
248
249
|
* two headers would assert two different claims at once. A relay content-plane
|
|
249
250
|
* read is NOT that case — there the identity proof is the AuthN half and a DFOS
|
|
250
|
-
* credential presentation is a separate authorization artifact (
|
|
251
|
-
*
|
|
251
|
+
* credential presentation is a separate authorization artifact (RELAY.md,
|
|
252
|
+
* Access) — so that refusal belongs to the middleware of the surface
|
|
252
253
|
* being served, never to this builder.
|
|
253
254
|
*/
|
|
254
255
|
declare const buildApiIdentityHeaders: (input: {
|
|
@@ -317,7 +318,7 @@ interface ProofPresenterState {
|
|
|
317
318
|
type ResolveProofPresenter = (did: string) => Promise<ProofPresenterState | null>;
|
|
318
319
|
/**
|
|
319
320
|
* What the PROOF PHASE reads — the subset of a verifier's inputs that
|
|
320
|
-
*
|
|
321
|
+
* INTEGRATIONS.md, Verification algorithm steps 1–7 touch.
|
|
321
322
|
*/
|
|
322
323
|
interface ProofEnvelopeInput {
|
|
323
324
|
/** The proof JWS — the `Authorization: DFOS <token>` token, scheme stripped. */
|
|
@@ -346,8 +347,8 @@ interface ProofEnvelopeInput {
|
|
|
346
347
|
now?: () => number;
|
|
347
348
|
}
|
|
348
349
|
/**
|
|
349
|
-
*
|
|
350
|
-
* request-dependent gate.
|
|
350
|
+
* INTEGRATIONS.md, Verification algorithm step 4's freshness configuration,
|
|
351
|
+
* hoisted so a caller can run it BEFORE any request-dependent gate.
|
|
351
352
|
*
|
|
352
353
|
* ORDER IS LOAD-BEARING. A deployment whose freshness span is out of bounds must
|
|
353
354
|
* never verify anything, and its misconfiguration must never be REPORTED as a
|
|
@@ -399,9 +400,9 @@ interface VerifiedProofEnvelope {
|
|
|
399
400
|
*/
|
|
400
401
|
declare const verifyIdentityProofEnvelope: (input: ProofEnvelopeInput, resolvePresenter: ResolveProofPresenter) => Promise<VerifiedProofEnvelope>;
|
|
401
402
|
/**
|
|
402
|
-
* Verify a REQUEST proof's envelope —
|
|
403
|
-
* `typ`. The caller then performs steps 8–11 (the
|
|
404
|
-
* verified proof signature is the gate.
|
|
403
|
+
* Verify a REQUEST proof's envelope — INTEGRATIONS.md, Verification algorithm
|
|
404
|
+
* steps 1–7 with the request `typ`. The caller then performs steps 8–11 (the
|
|
405
|
+
* credential walk), for which a verified proof signature is the gate.
|
|
405
406
|
*/
|
|
406
407
|
declare const verifyRequestProofEnvelope: (input: ProofEnvelopeInput, resolvePresenter: ResolveProofPresenter) => Promise<VerifiedProofEnvelope>;
|
|
407
408
|
|
|
@@ -34,9 +34,9 @@ import {
|
|
|
34
34
|
verifyDelegationChain,
|
|
35
35
|
verifyIdentityProofEnvelope,
|
|
36
36
|
verifyRequestProofEnvelope
|
|
37
|
-
} from "../chunk-
|
|
38
|
-
import "../chunk-
|
|
39
|
-
import "../chunk-
|
|
37
|
+
} from "../chunk-FZHHSC5N.js";
|
|
38
|
+
import "../chunk-F7RHI2CK.js";
|
|
39
|
+
import "../chunk-KAW4MT4P.js";
|
|
40
40
|
export {
|
|
41
41
|
ApiRequestVerifyError,
|
|
42
42
|
Attenuation,
|
package/dist/crypto/index.d.ts
CHANGED
|
@@ -85,7 +85,7 @@ declare const normalizedId: <T extends string>(prefix: T, id: string) => `${T}_$
|
|
|
85
85
|
interface JwsHeader {
|
|
86
86
|
alg: 'EdDSA';
|
|
87
87
|
typ: string;
|
|
88
|
-
kid
|
|
88
|
+
kid?: string;
|
|
89
89
|
/** CIDv1 of the operation payload (dag-cbor + SHA-256), signed in the protected header */
|
|
90
90
|
cid?: string;
|
|
91
91
|
}
|
|
@@ -96,7 +96,9 @@ interface JwsHeader {
|
|
|
96
96
|
* signature (64 bytes)
|
|
97
97
|
*/
|
|
98
98
|
declare const createJws: (options: {
|
|
99
|
-
header: JwsHeader
|
|
99
|
+
header: JwsHeader & {
|
|
100
|
+
kid: string;
|
|
101
|
+
};
|
|
100
102
|
payload: Record<string, unknown>;
|
|
101
103
|
sign: (message: Uint8Array) => Promise<Uint8Array>;
|
|
102
104
|
}) => Promise<string>;
|
|
@@ -128,6 +130,28 @@ declare class JwsVerificationError extends Error {
|
|
|
128
130
|
constructor(message: string);
|
|
129
131
|
}
|
|
130
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Reject a signed JSON document whose raw text carries something its decoded
|
|
135
|
+
* value can no longer show:
|
|
136
|
+
*
|
|
137
|
+
* 1. DUPLICATE KEYS — PROTOCOL: "A payload containing duplicate keys is
|
|
138
|
+
* malformed: the signature commits to the raw payload bytes while the CID
|
|
139
|
+
* derives from the decoded value." Every JSON parser silently resolves a
|
|
140
|
+
* duplicate (last wins), so the only place to see one is the text.
|
|
141
|
+
* 2. LONE SURROGATE ESCAPES — a `\uD800`-class escape with no pair. TypeScript
|
|
142
|
+
* keeps it; Go's decoder replaces it with U+FFFD. Two verifiers would derive
|
|
143
|
+
* two different CIDs from the same signed bytes, so refusing the escape is
|
|
144
|
+
* the one verdict both can reach.
|
|
145
|
+
*
|
|
146
|
+
* This is a tokenizer, not a parser: it does not validate the grammar — the
|
|
147
|
+
* caller's `JSON.parse` is the grammar judge, and this walk simply stops at the
|
|
148
|
+
* first thing it cannot read. It tracks only enough structure to know which
|
|
149
|
+
* strings are member names of which object.
|
|
150
|
+
*
|
|
151
|
+
* MUST match the Go reference (AssertCanonicalJSONText in json_scan.go).
|
|
152
|
+
*/
|
|
153
|
+
declare const assertCanonicalJsonText: (text: string) => void;
|
|
154
|
+
|
|
131
155
|
/**
|
|
132
156
|
* Apply the DFOS signature verification profile to a decoded protected header.
|
|
133
157
|
*
|
|
@@ -214,4 +238,4 @@ declare const parseDagCborCID: (cid: string) => CID<unknown, number, number, mul
|
|
|
214
238
|
*/
|
|
215
239
|
declare const isCanonicallyEqual: (data1: unknown, data2: unknown) => Promise<boolean>;
|
|
216
240
|
|
|
217
|
-
export { type JwsHeader, JwsVerificationError, type JwtClaims, type JwtCreateOptions, type JwtHeader, JwtVerificationError, type JwtVerifyOptions, type PrefixedID, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, sha256, signPayloadEd25519, verifyJws, verifyJwt };
|
|
241
|
+
export { type JwsHeader, JwsVerificationError, type JwtClaims, type JwtCreateOptions, type JwtHeader, JwtVerificationError, type JwtVerifyOptions, type PrefixedID, assertCanonicalJsonText, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, sha256, signPayloadEd25519, verifyJws, verifyJwt };
|
package/dist/crypto/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JwsVerificationError,
|
|
3
3
|
JwtVerificationError,
|
|
4
|
+
assertCanonicalJsonText,
|
|
4
5
|
assertJwsProfile,
|
|
5
6
|
base64urlDecode,
|
|
6
7
|
base64urlEncode,
|
|
@@ -22,10 +23,11 @@ import {
|
|
|
22
23
|
signPayloadEd25519,
|
|
23
24
|
verifyJws,
|
|
24
25
|
verifyJwt
|
|
25
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-KAW4MT4P.js";
|
|
26
27
|
export {
|
|
27
28
|
JwsVerificationError,
|
|
28
29
|
JwtVerificationError,
|
|
30
|
+
assertCanonicalJsonText,
|
|
29
31
|
assertJwsProfile,
|
|
30
32
|
base64urlDecode,
|
|
31
33
|
base64urlEncode,
|
|
@@ -440,7 +440,8 @@ declare const MAX_SIGN_REQUEST_PAYLOAD_SIZE = 4096;
|
|
|
440
440
|
*
|
|
441
441
|
* Unknown envelope fields are preserved-and-ignored, matching every other wire
|
|
442
442
|
* payload in this file. The signer-side target-payload check is deliberately
|
|
443
|
-
* strict instead: a signer refuses fields it cannot render (see
|
|
443
|
+
* strict instead: a signer refuses fields it cannot render (see RELAY.md,
|
|
444
|
+
* Signer obligations).
|
|
444
445
|
*/
|
|
445
446
|
declare const SignRequestPayload: z.ZodObject<{
|
|
446
447
|
version: z.ZodLiteral<1>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { JwsHeader, JwsVerificationError, JwtClaims, JwtCreateOptions, JwtHeader, JwtVerificationError, JwtVerifyOptions, PrefixedID, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, sha256, signPayloadEd25519, verifyJws, verifyJwt } from './crypto/index.js';
|
|
2
|
-
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, C as CONTENT_ID_ANCHOR_RE, c as ContentOperation, d as CountersignPayload, e as CredentialVerificationError, f as CreditClaimPayload, D as DFOSCredentialPayload, g as DeclaredKeyState, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_KEY_PROOFS, l as MAX_OPERATION_SIZE, m as MAX_SERVICES_ENTRIES, n as MAX_SERVICES_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_PAYLOAD_SIZE, p as MAX_SIGN_REQUEST_SIZE, q as MultikeyPublicKey, R as ResolvedIdentity, r as RevocationChecker, s as RevocationPayload, S as ServiceEntry, t as ServicesArray, u as SignRequestPayload, v as Signer, V as VerifiedDFOSCredential, w as VerifiedDelegationChain, x as VerifiedIdentity, y as VoidKeyMembership, z as createDFOSCredential, B as decodeDFOSCredentialUnsafe, E as isAttenuated, F as matchesResource, G as parseProtocolTimestampUnix, H as verifyDFOSCredential, J as verifyDelegationChain } from './dfos-credential-
|
|
3
|
-
export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, SignRequestFailureReason, SignRequestVerifyError, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest } from './chain/index.js';
|
|
1
|
+
export { JwsHeader, JwsVerificationError, JwtClaims, JwtCreateOptions, JwtHeader, JwtVerificationError, JwtVerifyOptions, PrefixedID, assertCanonicalJsonText, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, sha256, signPayloadEd25519, verifyJws, verifyJwt } from './crypto/index.js';
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, C as CONTENT_ID_ANCHOR_RE, c as ContentOperation, d as CountersignPayload, e as CredentialVerificationError, f as CreditClaimPayload, D as DFOSCredentialPayload, g as DeclaredKeyState, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_KEY_PROOFS, l as MAX_OPERATION_SIZE, m as MAX_SERVICES_ENTRIES, n as MAX_SERVICES_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_PAYLOAD_SIZE, p as MAX_SIGN_REQUEST_SIZE, q as MultikeyPublicKey, R as ResolvedIdentity, r as RevocationChecker, s as RevocationPayload, S as ServiceEntry, t as ServicesArray, u as SignRequestPayload, v as Signer, V as VerifiedDFOSCredential, w as VerifiedDelegationChain, x as VerifiedIdentity, y as VoidKeyMembership, z as createDFOSCredential, B as decodeDFOSCredentialUnsafe, E as isAttenuated, F as matchesResource, G as parseProtocolTimestampUnix, H as verifyDFOSCredential, J as verifyDelegationChain } from './dfos-credential-j-kHtFvG.js';
|
|
3
|
+
export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, SignRequestFailureReason, SignRequestVerifyError, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeEd25519PublicMultikey, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest } from './chain/index.js';
|
|
4
4
|
export { ApiRequestVerifyError, DEFAULT_PROOF_SKEW_SECONDS, DEFAULT_PROOF_WINDOW_SECONDS, DFOS_AUTH_SCHEME, EMPTY_BODY_SHA256, IDENTITY_PROOF_JWS_TYP, IdentityProofPayload, MAX_BODY_BYTES, MAX_PROOF_FRESHNESS_SPAN_SECONDS, MAX_REQUEST_PROOF_SIZE, ParsedProofPayload, ProofEnvelopeInput, ProofExtraMembers, ProofPresenterState, REQUEST_PROOF_JWS_TYP, RequestProofFailurePhase, RequestProofFailureReason, RequestProofPayload, ResolveProofPresenter, SignApiIdentityRequestInput, SignApiRequestInput, VerifiedProofEnvelope, apiIdentitySigningInput, apiRequestSigningInput, assertProofVerifierConfig, buildApiAuthHeaders, buildApiIdentityHeaders, canonicalExtraMembers, invalidProof, misconfiguredProof, parseDfosAuthorization, sha256BodyHash, signApiIdentityRequest, signApiRequest, unverifiableProof, verifyIdentityProofEnvelope, verifyRequestProofEnvelope } from './credentials/index.js';
|
|
5
5
|
export { DEFAULT_KEY_PROOF_SKEW_SECONDS, KEY_ADD_JWS_TYP, KEY_ROLES, KeyProofFailureReason, KeyProofPayload, KeyProofVerifyError, KeyRole, MAX_KEY_PROOF_SIZE, SignKeyProofInput, VerifiedKeyProof, VerifyChainKeyProofOptions, VerifyKeyProofOptions, isCanonicalRoleSet, keyProofSigningInput, keyWordFingerprint, parseRoleSet, roleSetCovers, serializeRoleSet, signKeyProof, unsafeKeyProofSubject, verifyChainKeyProof, verifyKeyProof } from './key-proof/index.js';
|
|
6
6
|
export { FoldOperation, INDEX_V1_SCHEMA, IndexDelta, IndexDocument, IndexEntry, LwwDelta, OrderKey, byteCompare, compareHeadPreference, compareLinear, foldIndexV1, foldLwwMap, linearize } from './fold/index.js';
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
verifyIdentityExtensionFromTrustedState,
|
|
53
53
|
verifyRevocation,
|
|
54
54
|
verifySignRequest
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-Q7FREWMY.js";
|
|
56
56
|
import {
|
|
57
57
|
ApiRequestVerifyError,
|
|
58
58
|
Attenuation,
|
|
@@ -92,7 +92,7 @@ import {
|
|
|
92
92
|
verifyDelegationChain,
|
|
93
93
|
verifyIdentityProofEnvelope,
|
|
94
94
|
verifyRequestProofEnvelope
|
|
95
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-FZHHSC5N.js";
|
|
96
96
|
import {
|
|
97
97
|
DEFAULT_KEY_PROOF_SKEW_SECONDS,
|
|
98
98
|
KEY_ADD_JWS_TYP,
|
|
@@ -109,16 +109,18 @@ import {
|
|
|
109
109
|
unsafeKeyProofSubject,
|
|
110
110
|
verifyChainKeyProof,
|
|
111
111
|
verifyKeyProof
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-BMIOY5W5.js";
|
|
113
113
|
import {
|
|
114
114
|
ED25519_PRIV_MULTICODEC,
|
|
115
115
|
ED25519_PUB_MULTICODEC,
|
|
116
|
+
decodeEd25519PublicMultikey,
|
|
116
117
|
decodeMultikey,
|
|
117
118
|
encodeEd25519Multikey
|
|
118
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-F7RHI2CK.js";
|
|
119
120
|
import {
|
|
120
121
|
JwsVerificationError,
|
|
121
122
|
JwtVerificationError,
|
|
123
|
+
assertCanonicalJsonText,
|
|
122
124
|
assertJwsProfile,
|
|
123
125
|
base64urlDecode,
|
|
124
126
|
base64urlEncode,
|
|
@@ -140,7 +142,7 @@ import {
|
|
|
140
142
|
signPayloadEd25519,
|
|
141
143
|
verifyJws,
|
|
142
144
|
verifyJwt
|
|
143
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-KAW4MT4P.js";
|
|
144
146
|
import {
|
|
145
147
|
INDEX_V1_SCHEMA,
|
|
146
148
|
byteCompare,
|
|
@@ -205,6 +207,7 @@ export {
|
|
|
205
207
|
anchorsByLabel,
|
|
206
208
|
apiIdentitySigningInput,
|
|
207
209
|
apiRequestSigningInput,
|
|
210
|
+
assertCanonicalJsonText,
|
|
208
211
|
assertCanonicalSignRequestPayload,
|
|
209
212
|
assertJwsProfile,
|
|
210
213
|
assertProofVerifierConfig,
|
|
@@ -226,6 +229,7 @@ export {
|
|
|
226
229
|
createNewEd25519Keypair,
|
|
227
230
|
dagCborCanonicalEncode,
|
|
228
231
|
decodeDFOSCredentialUnsafe,
|
|
232
|
+
decodeEd25519PublicMultikey,
|
|
229
233
|
decodeJwsUnsafe,
|
|
230
234
|
decodeJwtUnsafe,
|
|
231
235
|
decodeMultikey,
|
|
@@ -43,7 +43,7 @@ declare const isCanonicalRoleSet: (value: string) => boolean;
|
|
|
43
43
|
declare const roleSetCovers: (value: string, role: KeyRole) => boolean;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* The
|
|
46
|
+
* The registered key-proof purpose in PROTOCOL.md, The envelope: the candidate
|
|
47
47
|
* key presents for addition to a ceremony-named identity's `authKeys`/
|
|
48
48
|
* `assertKeys` sets.
|
|
49
49
|
*
|
|
@@ -57,7 +57,7 @@ declare const KEY_ADD_JWS_TYP = "did:dfos:key-add";
|
|
|
57
57
|
declare const MAX_KEY_PROOF_SIZE = 4096;
|
|
58
58
|
/**
|
|
59
59
|
* RECOMMENDED acceptance window, in seconds, EITHER SIDE of the verifier's clock
|
|
60
|
-
* — matching a ceremony's own lifetime (
|
|
60
|
+
* — matching a ceremony's own lifetime (INTEGRATIONS.md, Presentation verification).
|
|
61
61
|
*/
|
|
62
62
|
declare const DEFAULT_KEY_PROOF_SKEW_SECONDS = 300;
|
|
63
63
|
/**
|
|
@@ -143,11 +143,11 @@ interface SignKeyProofInput {
|
|
|
143
143
|
* The protected header is EXACTLY `{"alg":"EdDSA","typ":"<purpose>"}` — two
|
|
144
144
|
* members, no `kid` (the key is in no chain and rides in the payload) and no
|
|
145
145
|
* `cid` (there is no operation to bind). It is assembled by hand rather than
|
|
146
|
-
* through `createJws`, whose
|
|
146
|
+
* through `createJws`, whose header input requires a `kid` this envelope must not
|
|
147
147
|
* carry.
|
|
148
148
|
*
|
|
149
|
-
* HOLDER OBLIGATIONS THIS FUNCTION CANNOT DISCHARGE (
|
|
150
|
-
*
|
|
149
|
+
* HOLDER OBLIGATIONS THIS FUNCTION CANNOT DISCHARGE (INTEGRATIONS.md, Holder
|
|
150
|
+
* obligations). A holder MUST show its human — before calling this — the
|
|
151
151
|
* audience, the purpose, the adopting identity, and the roles. A proof is
|
|
152
152
|
* consent, and consent that was never displayed was never given.
|
|
153
153
|
*
|
|
@@ -210,10 +210,10 @@ interface VerifyKeyProofOptions {
|
|
|
210
210
|
/** What a verified key proof hands back. */
|
|
211
211
|
interface VerifiedKeyProof {
|
|
212
212
|
/**
|
|
213
|
-
* The validated payload. THE CALLER MUST NOW RUN
|
|
214
|
-
* check that it is a nonce this verifier minted, for this
|
|
215
|
-
* consumed, and consume it ATOMICALLY (check-and-delete) so
|
|
216
|
-
* completions cannot both pass.
|
|
213
|
+
* The validated payload. THE CALLER MUST NOW RUN THE NONCE CHECK against
|
|
214
|
+
* `payload.nonce`: check that it is a nonce this verifier minted, for this
|
|
215
|
+
* ceremony, not yet consumed, and consume it ATOMICALLY (check-and-delete) so
|
|
216
|
+
* two racing completions cannot both pass.
|
|
217
217
|
*/
|
|
218
218
|
payload: KeyProofPayload;
|
|
219
219
|
/** The header `typ` — equal to `expectedTyp`, since anything else rejected. */
|
|
@@ -222,17 +222,18 @@ interface VerifiedKeyProof {
|
|
|
222
222
|
now: number;
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
|
-
* Verify a key proof AT PRESENTATION TIME —
|
|
226
|
-
*
|
|
227
|
-
* CANONICAL bytes, the four expectation arms (audience,
|
|
228
|
-
* freshness, and the signature against the payload's
|
|
225
|
+
* Verify a key proof AT PRESENTATION TIME — INTEGRATIONS.md, Presentation
|
|
226
|
+
* verification except its nonce check: size cap, header gates, the closed
|
|
227
|
+
* payload schema over CANONICAL bytes, the four expectation arms (audience,
|
|
228
|
+
* did, roleSet, prevCID), freshness, and the signature against the payload's
|
|
229
|
+
* OWN `publicKeyMultibase`.
|
|
229
230
|
*
|
|
230
231
|
* EVERY EXPECTATION IS THE DEPLOYMENT'S OWN VALUE. There is no arm here that
|
|
231
232
|
* compares the envelope to itself. `expectedDid`, `expectedRoleSet` and
|
|
232
233
|
* `expectedPrevCID` are the position the completing authority is about to WRITE;
|
|
233
234
|
* if the envelope names a different one, the holder consented to something else.
|
|
234
235
|
*
|
|
235
|
-
*
|
|
236
|
+
* THE NONCE CHECK IS THE CALLER'S, and this function cannot stand in for it. The
|
|
236
237
|
* nonce MUST be one this verifier minted, for this ceremony, not yet consumed,
|
|
237
238
|
* checked and consumed ATOMICALLY — a check-and-delete against the verifier's
|
|
238
239
|
* own store, which is state this pure function does not hold. It is returned on
|
package/dist/key-proof/index.js
CHANGED
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
unsafeKeyProofSubject,
|
|
15
15
|
verifyChainKeyProof,
|
|
16
16
|
verifyKeyProof
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-BMIOY5W5.js";
|
|
18
|
+
import "../chunk-F7RHI2CK.js";
|
|
19
|
+
import "../chunk-KAW4MT4P.js";
|
|
20
20
|
export {
|
|
21
21
|
DEFAULT_KEY_PROOF_SKEW_SECONDS,
|
|
22
22
|
KEY_ADD_JWS_TYP,
|