@learncard/sss-key-manager 0.2.1 → 0.2.2
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/escrow-attestation.d.ts +2 -9
- package/dist/escrow-attestation.d.ts.map +1 -1
- package/dist/escrow-authority.d.ts +112 -0
- package/dist/escrow-authority.d.ts.map +1 -0
- package/dist/escrow-authority.types.d.ts +51 -0
- package/dist/escrow-authority.types.d.ts.map +1 -0
- package/dist/escrow-crypto.d.ts +9 -1
- package/dist/escrow-crypto.d.ts.map +1 -1
- package/dist/escrow-enrollment-intent.d.ts +13 -0
- package/dist/escrow-enrollment-intent.d.ts.map +1 -0
- package/dist/escrow-enrollment-intent.types.d.ts +28 -0
- package/dist/escrow-enrollment-intent.types.d.ts.map +1 -0
- package/dist/escrow-nitro-attestation.d.ts +2 -0
- package/dist/escrow-nitro-attestation.d.ts.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/sss-key-manager.cjs.development.js +1592 -213
- package/dist/sss-key-manager.cjs.development.js.map +4 -4
- package/dist/sss-key-manager.cjs.production.min.js +28 -23
- package/dist/sss-key-manager.cjs.production.min.js.map +4 -4
- package/dist/sss-key-manager.esm.js +1107 -163
- package/dist/sss-key-manager.esm.js.map +4 -4
- package/dist/sss-strategy.d.ts.map +1 -1
- package/dist/types.d.ts +16 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__fixtures__/escrow-authority-v1.json +96 -0
- package/src/__fixtures__/escrow-carry-contact-contract-v1.json +33 -0
- package/src/__fixtures__/escrow-enrollment-intent-v1.json +26 -0
- package/src/__fixtures__/nitro-attestation-real/staging-nsm-document.json +16 -0
- package/src/escrow-attestation.ts +10 -9
- package/src/escrow-authority.test.ts +643 -0
- package/src/escrow-authority.ts +597 -0
- package/src/escrow-authority.types.ts +56 -0
- package/src/escrow-crypto.ts +39 -1
- package/src/escrow-enrollment-intent.test.ts +224 -0
- package/src/escrow-enrollment-intent.ts +236 -0
- package/src/escrow-enrollment-intent.types.ts +28 -0
- package/src/escrow-nitro-attestation.test.ts +72 -0
- package/src/escrow-nitro-attestation.ts +34 -3
- package/src/index.ts +27 -0
- package/src/sss-authority.test.ts +889 -0
- package/src/sss-strategy.ts +479 -38
- package/src/types.ts +22 -3
|
@@ -41,12 +41,18 @@ const bytes = (value: unknown, reason: NitroAttestationReason): Uint8Array =>
|
|
|
41
41
|
value instanceof Uint8Array && value.length > 0 ? value : fail(reason);
|
|
42
42
|
const map = (value: unknown, reason: NitroAttestationReason): Map<unknown, unknown> =>
|
|
43
43
|
value instanceof Map ? value : fail(reason);
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* `allowIndefinite` is only for the signed NSM payload: real AWS Nitro documents
|
|
46
|
+
* encode it as an indefinite-length map (0xbf). That is safe because the COSE
|
|
47
|
+
* signature below is verified over the original payload bytes, not a re-encoding.
|
|
48
|
+
* Everything else (COSE envelope, protected header, user_data) stays definite-only.
|
|
49
|
+
*/
|
|
50
|
+
const decodeCbor = (value: Uint8Array, { allowIndefinite = false } = {}): unknown => {
|
|
45
51
|
try {
|
|
46
52
|
return decode(value, {
|
|
47
53
|
useMaps: true,
|
|
48
54
|
rejectDuplicateMapKeys: true,
|
|
49
|
-
allowIndefinite
|
|
55
|
+
allowIndefinite,
|
|
50
56
|
allowUndefined: false,
|
|
51
57
|
allowNaN: false,
|
|
52
58
|
allowInfinity: false,
|
|
@@ -131,6 +137,8 @@ export const verifyNitroAttestationDocument = async (
|
|
|
131
137
|
pcrs: Record<number, string>;
|
|
132
138
|
timestamp: number;
|
|
133
139
|
moduleId: string;
|
|
140
|
+
ledgerPublicKey?: string;
|
|
141
|
+
measurementHash?: string;
|
|
134
142
|
}> => {
|
|
135
143
|
let document: Uint8Array;
|
|
136
144
|
try {
|
|
@@ -155,7 +163,7 @@ export const verifyNitroAttestationDocument = async (
|
|
|
155
163
|
const payloadBytes = bytes(payloadValue, 'cose');
|
|
156
164
|
const signature = bytes(signatureValue, 'signature');
|
|
157
165
|
if (signature.length !== 96) fail('signature');
|
|
158
|
-
const payload = map(decodeCbor(payloadBytes), 'cbor');
|
|
166
|
+
const payload = map(decodeCbor(payloadBytes, { allowIndefinite: true }), 'cbor');
|
|
159
167
|
const moduleId = payload.get('module_id');
|
|
160
168
|
const timestamp = payload.get('timestamp');
|
|
161
169
|
if (typeof moduleId !== 'string' || !moduleId || payload.get('digest') !== 'SHA384')
|
|
@@ -275,6 +283,28 @@ export const verifyNitroAttestationDocument = async (
|
|
|
275
283
|
} catch {
|
|
276
284
|
return fail('user-data');
|
|
277
285
|
}
|
|
286
|
+
const rawLedgerKey = payload.get('public_key');
|
|
287
|
+
let ledgerPublicKey: string | undefined;
|
|
288
|
+
let measurementHash: string | undefined;
|
|
289
|
+
if (rawLedgerKey !== undefined && rawLedgerKey !== null) {
|
|
290
|
+
const ledger = new Uint8Array(bytes(rawLedgerKey, 'user-data'));
|
|
291
|
+
if (ledger.length !== 65 || ledger[0] !== 4) fail('user-data');
|
|
292
|
+
try {
|
|
293
|
+
await crypto.subtle.importKey(
|
|
294
|
+
'raw',
|
|
295
|
+
ledger,
|
|
296
|
+
{ name: 'ECDSA', namedCurve: 'P-256' },
|
|
297
|
+
false,
|
|
298
|
+
['verify']
|
|
299
|
+
);
|
|
300
|
+
} catch {
|
|
301
|
+
return fail('user-data');
|
|
302
|
+
}
|
|
303
|
+
const tuple = new Uint8Array(144);
|
|
304
|
+
for (let i = 0; i < 3; i++) tuple.set(bytes(rawPcrs.get(i), 'pcr'), i * 48);
|
|
305
|
+
measurementHash = hex(new Uint8Array(await crypto.subtle.digest('SHA-256', tuple)));
|
|
306
|
+
ledgerPublicKey = bufferToBase64(ledger.buffer);
|
|
307
|
+
}
|
|
278
308
|
return {
|
|
279
309
|
escrowPublicKeySpkiB64: bufferToBase64(new Uint8Array(spki).buffer),
|
|
280
310
|
keyId: newFormat?.keyId,
|
|
@@ -282,5 +312,6 @@ export const verifyNitroAttestationDocument = async (
|
|
|
282
312
|
pcrs,
|
|
283
313
|
timestamp,
|
|
284
314
|
moduleId,
|
|
315
|
+
...(ledgerPublicKey ? { ledgerPublicKey, measurementHash } : {}),
|
|
285
316
|
};
|
|
286
317
|
};
|
package/src/index.ts
CHANGED
|
@@ -76,7 +76,34 @@ export {
|
|
|
76
76
|
} from './escrow-crypto';
|
|
77
77
|
|
|
78
78
|
export type { EscrowEnvelope, EscrowBlobPlaintext, EscrowReleasePlaintext } from './escrow-crypto';
|
|
79
|
+
export {
|
|
80
|
+
encodeEscrowEnrollmentIntent,
|
|
81
|
+
signEscrowEnrollmentIntent,
|
|
82
|
+
getEscrowBlobIdentity,
|
|
83
|
+
ESCROW_ENROLLMENT_INTENT_DOMAIN,
|
|
84
|
+
} from './escrow-enrollment-intent';
|
|
85
|
+
export type {
|
|
86
|
+
EscrowEnrollmentIntent,
|
|
87
|
+
SignedEscrowEnrollmentIntent,
|
|
88
|
+
} from './escrow-enrollment-intent.types';
|
|
79
89
|
export { verifyEnclaveAttestation } from './escrow-attestation';
|
|
90
|
+
export { EscrowEvidenceError } from './escrow-authority.types';
|
|
91
|
+
export type { HistoricalEscrowEvidence } from './escrow-authority.types';
|
|
92
|
+
export type { EscrowRecoveryExpectations } from '@learncard/types';
|
|
93
|
+
export {
|
|
94
|
+
verifyEscrowAuthorityState,
|
|
95
|
+
verifyEscrowEnrollmentCommit,
|
|
96
|
+
createEscrowEnrollmentIntent,
|
|
97
|
+
resolveEscrowEnrollmentAction,
|
|
98
|
+
violatesCarryContactRule,
|
|
99
|
+
} from './escrow-authority';
|
|
100
|
+
export type { EscrowEnrollmentActionInput } from './escrow-authority';
|
|
101
|
+
export type {
|
|
102
|
+
VerifiedEnclaveIdentity,
|
|
103
|
+
EscrowAuthorityRecord,
|
|
104
|
+
EscrowAuthorityState,
|
|
105
|
+
VerifiedEscrowMutation,
|
|
106
|
+
} from './escrow-authority.types';
|
|
80
107
|
export { verifyNitroAttestationDocument, NitroAttestationError } from './escrow-nitro-attestation';
|
|
81
108
|
export type { NitroAttestationReason } from './escrow-nitro-attestation';
|
|
82
109
|
export type { EscrowAttestationPolicy, EscrowHoldStatus, EscrowRecoveryStart } from './types';
|