@metalabel/dfos-protocol 0.51.0 → 0.52.0
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-IDVYITX7.js → chunk-F7RHI2CK.js} +9 -1
- package/dist/{chunk-T2YR5KWQ.js → chunk-IV3TIYKP.js} +11 -7
- package/dist/{chunk-LMAPBTDW.js → chunk-OU2DPHCN.js} +27 -23
- package/dist/{chunk-JVSC67DC.js → chunk-QRCOMLAP.js} +4 -9
- package/dist/{chunk-4LG2GEB2.js → chunk-QTJZGXMH.js} +140 -25
- package/dist/credentials/index.d.ts +21 -20
- package/dist/credentials/index.js +3 -3
- package/dist/crypto/index.d.ts +23 -1
- 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 +14 -13
- 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-OU2DPHCN.js";
|
|
56
|
+
import "../chunk-IV3TIYKP.js";
|
|
57
|
+
import "../chunk-QRCOMLAP.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-QTJZGXMH.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,
|
|
@@ -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-QTJZGXMH.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) => {
|
|
@@ -456,7 +459,7 @@ var verifyDFOSCredential = async (jwsToken, options) => {
|
|
|
456
459
|
} catch {
|
|
457
460
|
throw new CredentialVerificationError("invalid credential signature");
|
|
458
461
|
}
|
|
459
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
462
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
460
463
|
const credentialCID = encoded.cid.toString();
|
|
461
464
|
if (!decoded.header.cid) {
|
|
462
465
|
throw new CredentialVerificationError("missing cid in credential header");
|
|
@@ -534,8 +537,9 @@ var parseResource = (resource) => {
|
|
|
534
537
|
if (colonIdx < 0) return null;
|
|
535
538
|
return { type: resource.substring(0, colonIdx), id: resource.substring(colonIdx + 1) };
|
|
536
539
|
};
|
|
540
|
+
var ASCII_TRIM_RE = /^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g;
|
|
537
541
|
var parseActions = (action) => new Set(
|
|
538
|
-
action.split(",").map((a) => a.
|
|
542
|
+
action.split(",").map((a) => a.replace(ASCII_TRIM_RE, "")).filter((a) => a !== "")
|
|
539
543
|
);
|
|
540
544
|
var isAttenuated = (parentAtt, childAtt) => {
|
|
541
545
|
return childAtt.every((childEntry) => {
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
matchesResource,
|
|
7
7
|
verifyDFOSCredential,
|
|
8
8
|
verifyDelegationChain
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IV3TIYKP.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-QRCOMLAP.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-QTJZGXMH.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}`
|
|
@@ -575,7 +577,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
575
577
|
if (!signingKey) {
|
|
576
578
|
throw new Error(`log[${idx}]: kid references unknown key: ${signingKeyId}`);
|
|
577
579
|
}
|
|
578
|
-
const
|
|
580
|
+
const keyBytes = decodeEd25519PublicMultikey(signingKey.publicKeyMultibase);
|
|
579
581
|
try {
|
|
580
582
|
verifyJws({ token: jwsToken, publicKey: keyBytes });
|
|
581
583
|
} catch {
|
|
@@ -694,7 +696,7 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
694
696
|
if (op.createdAt <= lastCreatedAt) {
|
|
695
697
|
throw new Error("createdAt must be after last op");
|
|
696
698
|
}
|
|
697
|
-
const encoded = await dagCborCanonicalEncode(
|
|
699
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
698
700
|
if (encoded.bytes.length > MAX_OPERATION_SIZE) {
|
|
699
701
|
throw new Error(`operation exceeds max size: ${encoded.bytes.length} > ${MAX_OPERATION_SIZE}`);
|
|
700
702
|
}
|
|
@@ -715,7 +717,7 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
715
717
|
if (!signingKey) {
|
|
716
718
|
throw new Error(`kid references unknown key: ${signingKeyId}`);
|
|
717
719
|
}
|
|
718
|
-
const
|
|
720
|
+
const keyBytes = decodeEd25519PublicMultikey(signingKey.publicKeyMultibase);
|
|
719
721
|
try {
|
|
720
722
|
verifyJws({ token: newOp, publicKey: keyBytes });
|
|
721
723
|
} catch {
|
|
@@ -791,11 +793,13 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
791
793
|
|
|
792
794
|
// src/chain/content-chain.ts
|
|
793
795
|
var operationSizeForCap = async (op, fullByteLength) => {
|
|
796
|
+
if (op.type === "create") return fullByteLength;
|
|
794
797
|
const auth = op.authorization;
|
|
795
798
|
if (typeof auth !== "string") return fullByteLength;
|
|
796
|
-
|
|
799
|
+
const authByteLength = new TextEncoder().encode(auth).length;
|
|
800
|
+
if (authByteLength > MAX_CREDENTIAL_SIZE) {
|
|
797
801
|
throw new Error(
|
|
798
|
-
`authorization credential exceeds max size: ${
|
|
802
|
+
`authorization credential exceeds max size: ${authByteLength} > ${MAX_CREDENTIAL_SIZE}`
|
|
799
803
|
);
|
|
800
804
|
}
|
|
801
805
|
const { authorization: _omit, ...rest } = op;
|
|
@@ -927,8 +931,8 @@ var verifyContentChain = async (input) => {
|
|
|
927
931
|
);
|
|
928
932
|
}
|
|
929
933
|
}
|
|
930
|
-
const encoded = await dagCborCanonicalEncode(
|
|
931
|
-
const opSize = await operationSizeForCap(
|
|
934
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
935
|
+
const opSize = await operationSizeForCap(decoded.payload, encoded.bytes.length);
|
|
932
936
|
if (opSize > MAX_OPERATION_SIZE) {
|
|
933
937
|
throw new Error(`operation exceeds max size: ${opSize} > ${MAX_OPERATION_SIZE}`);
|
|
934
938
|
}
|
|
@@ -1032,8 +1036,8 @@ var verifyContentExtensionFromTrustedState = async (input) => {
|
|
|
1032
1036
|
throw carryDependencyMissing(err, new Error(`authorization verification failed: ${message}`));
|
|
1033
1037
|
}
|
|
1034
1038
|
}
|
|
1035
|
-
const encoded = await dagCborCanonicalEncode(
|
|
1036
|
-
const opSize = await operationSizeForCap(
|
|
1039
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1040
|
+
const opSize = await operationSizeForCap(decoded.payload, encoded.bytes.length);
|
|
1037
1041
|
if (opSize > MAX_OPERATION_SIZE) {
|
|
1038
1042
|
throw new Error(`operation exceeds max size: ${opSize} > ${MAX_OPERATION_SIZE}`);
|
|
1039
1043
|
}
|
|
@@ -1198,7 +1202,7 @@ var verifyRevocation = async (input) => {
|
|
|
1198
1202
|
} catch {
|
|
1199
1203
|
throw new Error("invalid revocation signature");
|
|
1200
1204
|
}
|
|
1201
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
1205
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1202
1206
|
const revocationCID = encoded.cid.toString();
|
|
1203
1207
|
if (!decoded.header.cid) throw new Error("missing cid in revocation header");
|
|
1204
1208
|
if (decoded.header.cid !== revocationCID) throw new Error("revocation cid mismatch");
|
|
@@ -1231,7 +1235,7 @@ var resolveKeyFromIdentity = (identity, kid) => {
|
|
|
1231
1235
|
if (!key) {
|
|
1232
1236
|
throw markDependencyMissing(invalid(`key ${keyId} not found on identity ${identity.did}`));
|
|
1233
1237
|
}
|
|
1234
|
-
const
|
|
1238
|
+
const keyBytes = decodeEd25519PublicMultikey(key.publicKeyMultibase);
|
|
1235
1239
|
return keyBytes;
|
|
1236
1240
|
};
|
|
1237
1241
|
var normalizeClaimCreatedAt = (createdAt) => {
|
|
@@ -1327,7 +1331,7 @@ var verifyCreditClaim = async (jwsToken, options) => {
|
|
|
1327
1331
|
} catch {
|
|
1328
1332
|
throw invalid("invalid credit claim signature");
|
|
1329
1333
|
}
|
|
1330
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
1334
|
+
const encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1331
1335
|
const claimCID = encoded.cid.toString();
|
|
1332
1336
|
if (!decoded.header.cid) throw invalid("missing cid in credit claim header");
|
|
1333
1337
|
if (decoded.header.cid !== claimCID) throw invalid("credit claim cid mismatch");
|
|
@@ -1454,7 +1458,7 @@ var resolveCurrentKey = (identity, kid) => {
|
|
|
1454
1458
|
);
|
|
1455
1459
|
if (!key) throw invalid2(`key ${keyId} not found on current identity ${identity.did}`);
|
|
1456
1460
|
try {
|
|
1457
|
-
return
|
|
1461
|
+
return decodeEd25519PublicMultikey(key.publicKeyMultibase);
|
|
1458
1462
|
} catch {
|
|
1459
1463
|
throw invalid2(`key ${keyId} on identity ${identity.did} is not a valid Ed25519 multikey`);
|
|
1460
1464
|
}
|
|
@@ -1554,7 +1558,7 @@ var verifySignRequest = async (jwsToken, options) => {
|
|
|
1554
1558
|
}
|
|
1555
1559
|
let encoded;
|
|
1556
1560
|
try {
|
|
1557
|
-
encoded = await dagCborCanonicalEncode(payload);
|
|
1561
|
+
encoded = await dagCborCanonicalEncode(decoded.payload);
|
|
1558
1562
|
} catch (error) {
|
|
1559
1563
|
const detail = error instanceof Error ? error.message : String(error);
|
|
1560
1564
|
throw invalid2(`failed to derive sign request CID: ${detail}`);
|
|
@@ -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-QTJZGXMH.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",
|
|
@@ -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 (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,
|
|
@@ -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-IV3TIYKP.js";
|
|
38
|
+
import "../chunk-F7RHI2CK.js";
|
|
39
|
+
import "../chunk-QTJZGXMH.js";
|
|
40
40
|
export {
|
|
41
41
|
ApiRequestVerifyError,
|
|
42
42
|
Attenuation,
|
package/dist/crypto/index.d.ts
CHANGED
|
@@ -128,6 +128,28 @@ declare class JwsVerificationError extends Error {
|
|
|
128
128
|
constructor(message: string);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Reject a signed JSON document whose raw text carries something its decoded
|
|
133
|
+
* value can no longer show:
|
|
134
|
+
*
|
|
135
|
+
* 1. DUPLICATE KEYS — PROTOCOL: "A payload containing duplicate keys is
|
|
136
|
+
* malformed: the signature commits to the raw payload bytes while the CID
|
|
137
|
+
* derives from the decoded value." Every JSON parser silently resolves a
|
|
138
|
+
* duplicate (last wins), so the only place to see one is the text.
|
|
139
|
+
* 2. LONE SURROGATE ESCAPES — a `\uD800`-class escape with no pair. TypeScript
|
|
140
|
+
* keeps it; Go's decoder replaces it with U+FFFD. Two verifiers would derive
|
|
141
|
+
* two different CIDs from the same signed bytes, so refusing the escape is
|
|
142
|
+
* the one verdict both can reach.
|
|
143
|
+
*
|
|
144
|
+
* This is a tokenizer, not a parser: it does not validate the grammar — the
|
|
145
|
+
* caller's `JSON.parse` is the grammar judge, and this walk simply stops at the
|
|
146
|
+
* first thing it cannot read. It tracks only enough structure to know which
|
|
147
|
+
* strings are member names of which object.
|
|
148
|
+
*
|
|
149
|
+
* MUST match the Go reference (AssertCanonicalJSONText in json_scan.go).
|
|
150
|
+
*/
|
|
151
|
+
declare const assertCanonicalJsonText: (text: string) => void;
|
|
152
|
+
|
|
131
153
|
/**
|
|
132
154
|
* Apply the DFOS signature verification profile to a decoded protected header.
|
|
133
155
|
*
|
|
@@ -214,4 +236,4 @@ declare const parseDagCborCID: (cid: string) => CID<unknown, number, number, mul
|
|
|
214
236
|
*/
|
|
215
237
|
declare const isCanonicallyEqual: (data1: unknown, data2: unknown) => Promise<boolean>;
|
|
216
238
|
|
|
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 };
|
|
239
|
+
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-QTJZGXMH.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-OU2DPHCN.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-IV3TIYKP.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-QRCOMLAP.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-QTJZGXMH.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
|
/**
|
|
@@ -146,8 +146,8 @@ interface SignKeyProofInput {
|
|
|
146
146
|
* through `createJws`, whose `JwsHeader` 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-QRCOMLAP.js";
|
|
18
|
+
import "../chunk-F7RHI2CK.js";
|
|
19
|
+
import "../chunk-QTJZGXMH.js";
|
|
20
20
|
export {
|
|
21
21
|
DEFAULT_KEY_PROOF_SKEW_SECONDS,
|
|
22
22
|
KEY_ADD_JWS_TYP,
|