@storacha/encrypt-upload-client 1.1.65 → 1.1.67
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/README.md +1 -1
- package/dist/config/constants.d.ts +1 -1
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -2
- package/dist/config/env.d.ts +0 -1
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +0 -7
- package/dist/core/client.js +1 -1
- package/dist/crypto/adapters/lit-crypto-adapter.d.ts +35 -4
- package/dist/crypto/adapters/lit-crypto-adapter.d.ts.map +1 -1
- package/dist/crypto/adapters/lit-crypto-adapter.js +38 -41
- package/dist/crypto/factories.node.d.ts +4 -10
- package/dist/crypto/factories.node.d.ts.map +1 -1
- package/dist/crypto/factories.node.js +6 -16
- package/dist/protocols/lit.d.ts +13 -18
- package/dist/protocols/lit.d.ts.map +1 -1
- package/dist/protocols/lit.js +67 -88
- package/dist/types.d.ts +24 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/file-metadata.d.ts.map +1 -1
- package/dist/utils/file-metadata.js +39 -14
- package/package.json +12 -11
- package/dist/test/cid-verification.spec.d.ts +0 -2
- package/dist/test/cid-verification.spec.d.ts.map +0 -1
- package/dist/test/cid-verification.spec.js +0 -314
- package/dist/test/crypto-compatibility.spec.d.ts +0 -2
- package/dist/test/crypto-compatibility.spec.d.ts.map +0 -1
- package/dist/test/crypto-compatibility.spec.js +0 -124
- package/dist/test/crypto-counter-security.spec.d.ts +0 -2
- package/dist/test/crypto-counter-security.spec.d.ts.map +0 -1
- package/dist/test/crypto-counter-security.spec.js +0 -147
- package/dist/test/crypto-streaming.spec.d.ts +0 -2
- package/dist/test/crypto-streaming.spec.d.ts.map +0 -1
- package/dist/test/crypto-streaming.spec.js +0 -129
- package/dist/test/crypto-streaming.spec.js.map +0 -1
- package/dist/test/encrypted-metadata.spec.d.ts +0 -2
- package/dist/test/encrypted-metadata.spec.d.ts.map +0 -1
- package/dist/test/encrypted-metadata.spec.js +0 -68
- package/dist/test/encrypted-metadata.spec.js.map +0 -1
- package/dist/test/factories.spec.d.ts +0 -2
- package/dist/test/factories.spec.d.ts.map +0 -1
- package/dist/test/factories.spec.js +0 -142
- package/dist/test/factories.spec.js.map +0 -1
- package/dist/test/file-metadata.spec.d.ts +0 -2
- package/dist/test/file-metadata.spec.d.ts.map +0 -1
- package/dist/test/file-metadata.spec.js +0 -433
- package/dist/test/file-metadata.spec.js.map +0 -1
- package/dist/test/helpers/test-file-utils.d.ts +0 -60
- package/dist/test/helpers/test-file-utils.d.ts.map +0 -1
- package/dist/test/helpers/test-file-utils.js +0 -139
- package/dist/test/setup.d.ts +0 -2
- package/dist/test/setup.d.ts.map +0 -1
- package/dist/test/setup.js +0 -12
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Wallet } from 'ethers';
|
|
2
1
|
import { UnknownLink } from 'multiformats';
|
|
3
2
|
import { Client as StorachaClient } from '@storacha/client';
|
|
4
3
|
import { Result, Failure, Block, Proof } from '@ucanto/interface';
|
|
5
|
-
import {
|
|
4
|
+
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
|
|
5
|
+
import { AccessControlConditions } from '@lit-protocol/access-control-conditions';
|
|
6
6
|
import type { BlobLike, AnyLink, Signer, DID, SigAlg, UploadOptions } from '@storacha/client/types';
|
|
7
|
+
import type { AuthData } from '@lit-protocol/schemas';
|
|
7
8
|
export type { IPLDBlock } from '@ucanto/interface';
|
|
8
9
|
export type { SpaceDID } from '@storacha/capabilities/types';
|
|
9
10
|
export type { UnknownFormat } from '@storacha/capabilities/types';
|
|
@@ -11,6 +12,12 @@ export type { Result, UnknownLink };
|
|
|
11
12
|
export type { BlobLike, AnyLink };
|
|
12
13
|
export type { UploadOptions } from '@storacha/client/types';
|
|
13
14
|
import type { SpaceDID } from '@storacha/capabilities/types';
|
|
15
|
+
import { Account } from 'viem';
|
|
16
|
+
import { createAuthManager } from '@lit-protocol/auth';
|
|
17
|
+
export type AuthManager = ReturnType<typeof createAuthManager>;
|
|
18
|
+
export type EoaAuthContext = Awaited<ReturnType<AuthManager['createEoaAuthContext']>>;
|
|
19
|
+
export type PkpAuthContext = Awaited<ReturnType<AuthManager['createPkpAuthContext']>>;
|
|
20
|
+
export type AuthenticationContext = EoaAuthContext | PkpAuthContext;
|
|
14
21
|
export interface FileMetadata {
|
|
15
22
|
name: string;
|
|
16
23
|
type: string;
|
|
@@ -98,10 +105,10 @@ export interface DecryptionConfig {
|
|
|
98
105
|
* Proofs to access the space
|
|
99
106
|
*/
|
|
100
107
|
proofs?: Proof[];
|
|
101
|
-
wallet?:
|
|
108
|
+
wallet?: Account;
|
|
102
109
|
sessionSigs?: SessionSigsMap;
|
|
103
110
|
pkpPublicKey?: string;
|
|
104
|
-
|
|
111
|
+
authData?: AuthData;
|
|
105
112
|
}
|
|
106
113
|
export interface EncryptedKeyResult {
|
|
107
114
|
strategy: EncryptionStrategy;
|
|
@@ -173,28 +180,21 @@ export interface KMSMetadataView extends KMSMetadata {
|
|
|
173
180
|
export interface DecodeFailure extends Failure {
|
|
174
181
|
name: 'DecodeFailure';
|
|
175
182
|
}
|
|
176
|
-
export interface
|
|
177
|
-
wallet:
|
|
183
|
+
export interface EoaAuthContextOptions {
|
|
184
|
+
wallet: Account;
|
|
178
185
|
accessControlConditions: AccessControlConditions;
|
|
179
186
|
dataToEncryptHash: string;
|
|
180
187
|
expiration?: string;
|
|
181
188
|
capabilityAuthSigs?: AuthSig[];
|
|
182
189
|
}
|
|
183
|
-
export interface
|
|
190
|
+
export interface PkpAuthContextOptions {
|
|
184
191
|
pkpPublicKey: string;
|
|
185
|
-
|
|
192
|
+
authData: AuthData;
|
|
186
193
|
accessControlConditions: AccessControlConditions;
|
|
187
194
|
dataToEncryptHash: string;
|
|
188
195
|
expiration?: string;
|
|
189
196
|
capabilityAuthSigs?: AuthSig[];
|
|
190
197
|
}
|
|
191
|
-
export interface LitPkpSigner {
|
|
192
|
-
pkpPublicKey: string;
|
|
193
|
-
authMethod: AuthMethod;
|
|
194
|
-
}
|
|
195
|
-
export interface LitWalletSigner {
|
|
196
|
-
wallet: Wallet;
|
|
197
|
-
}
|
|
198
198
|
export interface CreateDecryptWrappedInvocationOptions {
|
|
199
199
|
decryptDelegation: Proof;
|
|
200
200
|
issuer: Signer<DID, SigAlg>;
|
|
@@ -211,6 +211,15 @@ export interface ExecuteUcanValidationOptions {
|
|
|
211
211
|
accessControlConditions: AccessControlConditions;
|
|
212
212
|
wrappedInvocationJSON: string;
|
|
213
213
|
}
|
|
214
|
+
export type AuthContext = EoaAuthContext | PkpAuthContext;
|
|
215
|
+
export interface ExecuteUcanValidationActionOptions {
|
|
216
|
+
authContext: AuthContext;
|
|
217
|
+
spaceDID: `did:key:${string}`;
|
|
218
|
+
identityBoundCiphertext: string;
|
|
219
|
+
plaintextKeyHash: string;
|
|
220
|
+
accessControlConditions: AccessControlConditions;
|
|
221
|
+
wrappedInvocationJSON: string;
|
|
222
|
+
}
|
|
214
223
|
export type ExtractedMetadata = LitExtractedMetadata | KMSExtractedMetadata;
|
|
215
224
|
export interface LitExtractedMetadata {
|
|
216
225
|
strategy: 'lit';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-metadata.d.ts","sourceRoot":"","sources":["../../src/utils/file-metadata.js"],"names":[],"mappings":"AAUA;;;;;YAKE;AASK,6CAJI,IAAI,CAAC,QAAQ,aACb,IAAI,CAAC,YAAY,GACf,IAAI,CAmDhB;AAQM,qDAHI,cAAc,GACZ,OAAO,CAAC;IAAC,UAAU,EAAE,cAAc,CAAC;IAAC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAA;CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"file-metadata.d.ts","sourceRoot":"","sources":["../../src/utils/file-metadata.js"],"names":[],"mappings":"AAUA;;;;;YAKE;AASK,6CAJI,IAAI,CAAC,QAAQ,aACb,IAAI,CAAC,YAAY,GACf,IAAI,CAmDhB;AAQM,qDAHI,cAAc,GACZ,OAAO,CAAC;IAAC,UAAU,EAAE,cAAc,CAAC;IAAC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAA;CAAC,CAAC,CA8FnF;uBA5KsB,cAAc;sBADf,aAAa"}
|
|
@@ -73,30 +73,55 @@ export const extractFileMetadata = async (decryptedStream) => {
|
|
|
73
73
|
// Read metadata length from first 4 bytes
|
|
74
74
|
const lengthView = new DataView(header.buffer, 0, 4);
|
|
75
75
|
const metadataLength = lengthView.getUint32(0, true);
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
76
|
+
// Detect if this is a valid metadata header or raw file content
|
|
77
|
+
// Valid metadata length should be 0-1020, anything else indicates no metadata header
|
|
78
|
+
const hasValidMetadataHeader = metadataLength >= 0 && metadataLength <= METADATA_HEADER_SIZE - 4;
|
|
80
79
|
let fileMetadata = undefined;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
let headerBytesToInclude = null;
|
|
81
|
+
if (hasValidMetadataHeader) {
|
|
82
|
+
// Valid metadata header detected
|
|
83
|
+
if (metadataLength > 0) {
|
|
84
|
+
try {
|
|
85
|
+
// Extract and parse metadata
|
|
86
|
+
const metadataBytes = header.slice(4, 4 + metadataLength);
|
|
87
|
+
const metadataJson = new TextDecoder('utf-8', { fatal: true }).decode(metadataBytes);
|
|
88
|
+
const parsedMetadata = secureJsonParse(metadataJson);
|
|
89
|
+
// Use existing validation - if it throws, treat as no metadata
|
|
90
|
+
validateMetadataStructure(parsedMetadata);
|
|
91
|
+
fileMetadata = parsedMetadata;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// JSON parsing or validation failed - treat as no metadata
|
|
95
|
+
console.warn('Metadata parsing/validation failed - treating as file without metadata:', error);
|
|
96
|
+
headerBytesToInclude = header;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// If metadataLength is 0, header is consumed normally (no metadata but valid header)
|
|
87
100
|
}
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
else {
|
|
102
|
+
// Invalid metadata length - treat entire stream as file content without metadata
|
|
103
|
+
console.warn(`Detected file without metadata header (apparent length: ${metadataLength})`);
|
|
104
|
+
// Include the "header" bytes as part of file content
|
|
105
|
+
headerBytesToInclude = header;
|
|
106
|
+
}
|
|
107
|
+
// Create file stream (reusing logic for both cases)
|
|
90
108
|
let remainderEnqueued = false;
|
|
109
|
+
let headerEnqueued = !headerBytesToInclude; // Skip header injection if no header to include
|
|
91
110
|
const fileStream = new ReadableStream({
|
|
92
111
|
async pull(controller) {
|
|
93
|
-
// First, enqueue
|
|
112
|
+
// First, enqueue header bytes if this file has no metadata header
|
|
113
|
+
if (!headerEnqueued && headerBytesToInclude) {
|
|
114
|
+
controller.enqueue(headerBytesToInclude);
|
|
115
|
+
headerEnqueued = true;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Then, enqueue any remainder bytes from the header read
|
|
94
119
|
if (!remainderEnqueued && remainder) {
|
|
95
120
|
controller.enqueue(remainder);
|
|
96
121
|
remainderEnqueued = true;
|
|
97
122
|
return;
|
|
98
123
|
}
|
|
99
|
-
//
|
|
124
|
+
// Finally, continue with the reader
|
|
100
125
|
const { done, value } = await reader.read();
|
|
101
126
|
if (done) {
|
|
102
127
|
controller.close();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storacha/encrypt-upload-client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.67",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"description": "Client for upload and download encrypted files",
|
|
7
7
|
"author": "Storacha",
|
|
@@ -61,12 +61,12 @@
|
|
|
61
61
|
"@ipld/dag-json": "^10.2.3",
|
|
62
62
|
"@ipld/dag-ucan": "^3.4.5",
|
|
63
63
|
"@ipld/schema": "^6.0.6",
|
|
64
|
-
"@lit-protocol/
|
|
65
|
-
"@lit-protocol/
|
|
66
|
-
"@lit-protocol/
|
|
67
|
-
"@lit-protocol/
|
|
68
|
-
"@lit-protocol/lit-
|
|
69
|
-
"@lit-protocol/
|
|
64
|
+
"@lit-protocol/access-control-conditions": "^8.0.2",
|
|
65
|
+
"@lit-protocol/auth": "^8.1.2",
|
|
66
|
+
"@lit-protocol/auth-helpers": "^8.1.1",
|
|
67
|
+
"@lit-protocol/constants": "^8.0.8",
|
|
68
|
+
"@lit-protocol/lit-client": "^8.2.3",
|
|
69
|
+
"@lit-protocol/networks": "8.3.1",
|
|
70
70
|
"@ucanto/client": "^9.0.2",
|
|
71
71
|
"@ucanto/core": "^10.4.5",
|
|
72
72
|
"@ucanto/interface": "^11.0.1",
|
|
@@ -76,16 +76,17 @@
|
|
|
76
76
|
"@ucanto/validator": "^10.0.1",
|
|
77
77
|
"blockstore-core": "^3.0.0",
|
|
78
78
|
"carstream": "^2.1.0",
|
|
79
|
-
"dotenv": "^
|
|
80
|
-
"ethers": "5.7.1",
|
|
79
|
+
"dotenv": "^17.2.3",
|
|
81
80
|
"ipfs-unixfs-exporter": "^10.0.0",
|
|
82
81
|
"multiformats": "^13.3.6",
|
|
82
|
+
"viem": "^2.39.0",
|
|
83
83
|
"@storacha/capabilities": "^1.12.0",
|
|
84
|
-
"@storacha/client": "^1.8.
|
|
84
|
+
"@storacha/client": "^1.8.24",
|
|
85
85
|
"@storacha/upload-client": "^1.3.6"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@lit-protocol/
|
|
88
|
+
"@lit-protocol/schemas": "^8.0.2",
|
|
89
|
+
"@lit-protocol/types": "^8.0.2",
|
|
89
90
|
"@playwright/test": "^1.29.2",
|
|
90
91
|
"esbuild": "^0.25.1",
|
|
91
92
|
"mkcert": "^3.2.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cid-verification.spec.d.ts","sourceRoot":"","sources":["../../test/cid-verification.spec.js"],"names":[],"mappings":""}
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert';
|
|
2
|
-
import { describe, test } from 'node:test';
|
|
3
|
-
import { getCarFileFromPublicGateway } from '../src/handlers/decrypt-handler.js';
|
|
4
|
-
import { createTestCar } from './helpers/test-file-utils.js';
|
|
5
|
-
await describe('CID Verification', async () => {
|
|
6
|
-
await describe('getCarFileFromPublicGateway', async () => {
|
|
7
|
-
await test('should construct correct gateway URL format', async () => {
|
|
8
|
-
// This is a basic test to verify the function exists and can be called
|
|
9
|
-
// Integration tests with real network calls would test full functionality
|
|
10
|
-
const gatewayURL = new URL('https://example.com');
|
|
11
|
-
const testCID = 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq';
|
|
12
|
-
// Mock fetch to avoid network calls in unit tests
|
|
13
|
-
const originalFetch = globalThis.fetch;
|
|
14
|
-
let capturedURL = '';
|
|
15
|
-
// @ts-ignore - Mock fetch for testing
|
|
16
|
-
globalThis.fetch = async (url) => {
|
|
17
|
-
capturedURL = url.toString();
|
|
18
|
-
// Return a mock response that looks like a failed fetch
|
|
19
|
-
return {
|
|
20
|
-
ok: false,
|
|
21
|
-
status: 404,
|
|
22
|
-
statusText: 'Not Found',
|
|
23
|
-
arrayBuffer: async () => {
|
|
24
|
-
throw new Error('Mock 404');
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
try {
|
|
29
|
-
await getCarFileFromPublicGateway(gatewayURL, testCID);
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
// We expect this to fail with our mock, that's fine
|
|
33
|
-
}
|
|
34
|
-
finally {
|
|
35
|
-
globalThis.fetch = originalFetch;
|
|
36
|
-
}
|
|
37
|
-
// Verify the URL was constructed correctly
|
|
38
|
-
const expectedURL = `https://example.com/ipfs/${testCID}?format=car`;
|
|
39
|
-
assert.strictEqual(capturedURL, expectedURL, 'Should construct correct gateway URL');
|
|
40
|
-
});
|
|
41
|
-
await test('should be exported and callable', async () => {
|
|
42
|
-
// Basic smoke test
|
|
43
|
-
assert.strictEqual(typeof getCarFileFromPublicGateway, 'function', 'Should be a function');
|
|
44
|
-
// Verify it requires proper parameters
|
|
45
|
-
try {
|
|
46
|
-
// @ts-ignore - intentionally testing invalid input
|
|
47
|
-
await getCarFileFromPublicGateway(null, 'test');
|
|
48
|
-
assert.fail('Should throw error for null gateway URL');
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
// Expected to fail - good
|
|
52
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
await test('should validate CID format', async () => {
|
|
56
|
-
const gatewayURL = new URL('https://example.com');
|
|
57
|
-
// Mock fetch to return valid CAR response
|
|
58
|
-
const originalFetch = globalThis.fetch;
|
|
59
|
-
// @ts-ignore - Mock fetch for testing
|
|
60
|
-
globalThis.fetch = async (url) => ({
|
|
61
|
-
ok: true,
|
|
62
|
-
status: 200,
|
|
63
|
-
statusText: 'OK',
|
|
64
|
-
arrayBuffer: async () => new ArrayBuffer(100), // Mock CAR data
|
|
65
|
-
});
|
|
66
|
-
try {
|
|
67
|
-
await getCarFileFromPublicGateway(gatewayURL, 'invalid-cid');
|
|
68
|
-
assert.fail('Should throw error for invalid CID');
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
// Expected to fail due to invalid CID format
|
|
72
|
-
assert(error instanceof Error, 'Should throw an Error for invalid CID');
|
|
73
|
-
}
|
|
74
|
-
finally {
|
|
75
|
-
globalThis.fetch = originalFetch;
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
await test('should accept valid CAR file with matching root CID', async () => {
|
|
79
|
-
const gatewayURL = new URL('https://example.com');
|
|
80
|
-
// Create a valid KMS metadata CAR file
|
|
81
|
-
const testContent = {
|
|
82
|
-
encryptedDataCID: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq',
|
|
83
|
-
encryptedSymmetricKey: 'test-encrypted-key',
|
|
84
|
-
space: 'did:key:z6MkwDK3M4PxU1FqcSt6quBH1xRBSGnPRdQYP9B13h3Wq5X1',
|
|
85
|
-
kms: {
|
|
86
|
-
provider: 'google-kms',
|
|
87
|
-
keyId: 'test-key-id',
|
|
88
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
const { car, actualRootCID } = await createTestCar(testContent);
|
|
92
|
-
// Mock fetch to return the valid CAR
|
|
93
|
-
const originalFetch = globalThis.fetch;
|
|
94
|
-
// @ts-ignore - Mock fetch for testing
|
|
95
|
-
globalThis.fetch = async (url) => ({
|
|
96
|
-
ok: true,
|
|
97
|
-
status: 200,
|
|
98
|
-
statusText: 'OK',
|
|
99
|
-
arrayBuffer: async () => car.buffer,
|
|
100
|
-
});
|
|
101
|
-
try {
|
|
102
|
-
const result = await getCarFileFromPublicGateway(gatewayURL, actualRootCID.toString());
|
|
103
|
-
assert(result instanceof Uint8Array, 'Should return Uint8Array');
|
|
104
|
-
assert.deepStrictEqual(result, car, 'Should return the exact CAR file');
|
|
105
|
-
}
|
|
106
|
-
finally {
|
|
107
|
-
globalThis.fetch = originalFetch;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
await test('should reject CAR file with wrong root CID (tampering detection)', async () => {
|
|
111
|
-
const gatewayURL = new URL('https://example.com');
|
|
112
|
-
// Create a CAR file with content A
|
|
113
|
-
const originalContent = {
|
|
114
|
-
encryptedDataCID: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq',
|
|
115
|
-
encryptedSymmetricKey: 'original-encrypted-key',
|
|
116
|
-
space: 'did:key:z6MkwDK3M4PxU1FqcSt6quBH1xRBSGnPRdQYP9B13h3Wq5X1',
|
|
117
|
-
kms: {
|
|
118
|
-
provider: 'google-kms',
|
|
119
|
-
keyId: 'original-key-id',
|
|
120
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
const { actualRootCID: originalCID } = await createTestCar(originalContent);
|
|
124
|
-
// Create a different CAR file with content B
|
|
125
|
-
const tamperedContent = {
|
|
126
|
-
encryptedDataCID: 'bafkreidb6v6sjfnpnf6lqkh7p4w7zfzqfuzn2lqhp5x6zkojfuzwzlhpny',
|
|
127
|
-
encryptedSymmetricKey: 'tampered-encrypted-key',
|
|
128
|
-
space: 'did:key:z6MkMaliciousSpaceDIDThatShouldNotBeAccepted',
|
|
129
|
-
kms: {
|
|
130
|
-
provider: 'google-kms',
|
|
131
|
-
keyId: 'tampered-key-id',
|
|
132
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
const { car: tamperedCar } = await createTestCar(tamperedContent);
|
|
136
|
-
// Mock fetch to return the tampered CAR when requesting the original CID
|
|
137
|
-
const originalFetch = globalThis.fetch;
|
|
138
|
-
// @ts-ignore - Mock fetch for testing
|
|
139
|
-
globalThis.fetch = async (url) => ({
|
|
140
|
-
ok: true,
|
|
141
|
-
status: 200,
|
|
142
|
-
statusText: 'OK',
|
|
143
|
-
arrayBuffer: async () => tamperedCar.buffer, // Return wrong CAR!
|
|
144
|
-
});
|
|
145
|
-
try {
|
|
146
|
-
await getCarFileFromPublicGateway(gatewayURL, originalCID.toString());
|
|
147
|
-
assert.fail('Should throw error for CID verification failure');
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
151
|
-
assert(error.message.includes('CID verification failed'), `Should mention CID verification failure. Got: ${error.message}`);
|
|
152
|
-
}
|
|
153
|
-
finally {
|
|
154
|
-
globalThis.fetch = originalFetch;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
await test('should detect when malicious gateway serves completely different CAR', async () => {
|
|
158
|
-
const gatewayURL = new URL('https://example.com');
|
|
159
|
-
// CID we're requesting
|
|
160
|
-
const requestedCID = 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq';
|
|
161
|
-
// Create a completely different CAR file
|
|
162
|
-
const maliciousContent = {
|
|
163
|
-
encryptedDataCID: 'bafkreig6h5fimhfvj3wmlsf4fzj2d2ndqxd7qnugcgcmkn6dcqzxcq5zdu',
|
|
164
|
-
encryptedSymmetricKey: 'malicious-encrypted-key',
|
|
165
|
-
space: 'did:key:z6MkMaliciousSpaceDIDControlledByAttacker',
|
|
166
|
-
kms: {
|
|
167
|
-
provider: 'google-kms',
|
|
168
|
-
keyId: 'attacker-controlled-key',
|
|
169
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
const { car: maliciousCar } = await createTestCar(maliciousContent);
|
|
173
|
-
// Mock fetch to return the malicious CAR
|
|
174
|
-
const originalFetch = globalThis.fetch;
|
|
175
|
-
// @ts-ignore - Mock fetch for testing
|
|
176
|
-
globalThis.fetch = async (url) => ({
|
|
177
|
-
ok: true,
|
|
178
|
-
status: 200,
|
|
179
|
-
statusText: 'OK',
|
|
180
|
-
arrayBuffer: async () => maliciousCar.buffer,
|
|
181
|
-
});
|
|
182
|
-
try {
|
|
183
|
-
await getCarFileFromPublicGateway(gatewayURL, requestedCID);
|
|
184
|
-
assert.fail('Should throw error when gateway serves wrong CAR');
|
|
185
|
-
}
|
|
186
|
-
catch (error) {
|
|
187
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
188
|
-
assert(error.message.includes('CID verification failed'), `Should mention CID verification failure. Got: ${error.message}`);
|
|
189
|
-
}
|
|
190
|
-
finally {
|
|
191
|
-
globalThis.fetch = originalFetch;
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
await test('should handle network errors gracefully', async () => {
|
|
195
|
-
const gatewayURL = new URL('https://example.com');
|
|
196
|
-
const testCID = 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq';
|
|
197
|
-
// Mock fetch to return network error
|
|
198
|
-
const originalFetch = globalThis.fetch;
|
|
199
|
-
// @ts-ignore - Mock fetch for testing
|
|
200
|
-
globalThis.fetch = async (url) => ({
|
|
201
|
-
ok: false,
|
|
202
|
-
status: 500,
|
|
203
|
-
statusText: 'Internal Server Error',
|
|
204
|
-
arrayBuffer: async () => {
|
|
205
|
-
throw new Error('Network error');
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
try {
|
|
209
|
-
await getCarFileFromPublicGateway(gatewayURL, testCID);
|
|
210
|
-
assert.fail('Should throw error for network errors');
|
|
211
|
-
}
|
|
212
|
-
catch (error) {
|
|
213
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
214
|
-
assert(error.message.includes('Failed to fetch'), `Should mention fetch failure. Got: ${error.message}`);
|
|
215
|
-
}
|
|
216
|
-
finally {
|
|
217
|
-
globalThis.fetch = originalFetch;
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
await describe('Metadata Tampering Detection', async () => {
|
|
222
|
-
await test('should prevent modification of space DID in metadata', async () => {
|
|
223
|
-
const gatewayURL = new URL('https://example.com');
|
|
224
|
-
// Original metadata with legitimate space DID
|
|
225
|
-
const originalMetadata = {
|
|
226
|
-
encryptedDataCID: 'bafkreie2hvzhqzj3ixnmjh7h3nkhdyp6qxhqltkq6qxf3wxq7hqxd6nzde',
|
|
227
|
-
encryptedSymmetricKey: 'encrypted-key-data',
|
|
228
|
-
space: 'did:key:z6MkwDK3M4PxU1FqcSt6quBH1xRBSGnPRdQYP9B13h3Wq5X1', // Original space
|
|
229
|
-
kms: {
|
|
230
|
-
provider: 'google-kms',
|
|
231
|
-
keyId: 'test-key-id',
|
|
232
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
233
|
-
},
|
|
234
|
-
};
|
|
235
|
-
// Tampered metadata with different space DID
|
|
236
|
-
const tamperedMetadata = {
|
|
237
|
-
...originalMetadata,
|
|
238
|
-
space: 'did:key:z6MkMaliciousSpaceDIDThatShouldNotBeAccepted', // Malicious space!
|
|
239
|
-
};
|
|
240
|
-
// Create CAR files for both
|
|
241
|
-
const { actualRootCID: originalCID } = await createTestCar(originalMetadata);
|
|
242
|
-
const { car: tamperedCar } = await createTestCar(tamperedMetadata);
|
|
243
|
-
// Mock fetch to return tampered CAR when requesting original CID
|
|
244
|
-
const originalFetch = globalThis.fetch;
|
|
245
|
-
// @ts-ignore - Mock fetch for testing
|
|
246
|
-
globalThis.fetch = async (url) => ({
|
|
247
|
-
ok: true,
|
|
248
|
-
status: 200,
|
|
249
|
-
statusText: 'OK',
|
|
250
|
-
arrayBuffer: async () => tamperedCar.buffer, // Returns tampered metadata!
|
|
251
|
-
});
|
|
252
|
-
try {
|
|
253
|
-
await getCarFileFromPublicGateway(gatewayURL, originalCID.toString());
|
|
254
|
-
assert.fail('Should detect space DID tampering via CID verification');
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
258
|
-
assert(error.message.includes('CID verification failed'), `Should catch tampering via CID verification. Got: ${error.message}`);
|
|
259
|
-
}
|
|
260
|
-
finally {
|
|
261
|
-
globalThis.fetch = originalFetch;
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
await test('should prevent complete metadata substitution attacks', async () => {
|
|
265
|
-
const gatewayURL = new URL('https://example.com');
|
|
266
|
-
// Original legitimate metadata
|
|
267
|
-
const originalMetadata = {
|
|
268
|
-
encryptedDataCID: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq',
|
|
269
|
-
encryptedSymmetricKey: 'original-encrypted-key',
|
|
270
|
-
space: 'did:key:z6MkwDK3M4PxU1FqcSt6quBH1xRBSGnPRdQYP9B13h3Wq5X1',
|
|
271
|
-
kms: {
|
|
272
|
-
provider: 'google-kms',
|
|
273
|
-
keyId: 'legitimate-key-id',
|
|
274
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
275
|
-
},
|
|
276
|
-
};
|
|
277
|
-
// Completely different malicious metadata (using same CID but different content)
|
|
278
|
-
const maliciousMetadata = {
|
|
279
|
-
encryptedDataCID: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7z3aldwdht2oqadq',
|
|
280
|
-
encryptedSymmetricKey: 'malicious-encrypted-key',
|
|
281
|
-
space: 'did:key:z6MkMaliciousSpaceDIDControlledByAttacker',
|
|
282
|
-
kms: {
|
|
283
|
-
provider: 'google-kms',
|
|
284
|
-
keyId: 'attacker-controlled-key',
|
|
285
|
-
algorithm: 'RSA-OAEP-2048-SHA256',
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
// Create CAR files for both
|
|
289
|
-
const { actualRootCID: originalCID } = await createTestCar(originalMetadata);
|
|
290
|
-
const { car: maliciousCar } = await createTestCar(maliciousMetadata);
|
|
291
|
-
// Mock fetch to return completely different metadata
|
|
292
|
-
const originalFetch = globalThis.fetch;
|
|
293
|
-
// @ts-ignore - Mock fetch for testing
|
|
294
|
-
globalThis.fetch = async (url) => ({
|
|
295
|
-
ok: true,
|
|
296
|
-
status: 200,
|
|
297
|
-
statusText: 'OK',
|
|
298
|
-
arrayBuffer: async () => maliciousCar.buffer, // Complete substitution attack!
|
|
299
|
-
});
|
|
300
|
-
try {
|
|
301
|
-
await getCarFileFromPublicGateway(gatewayURL, originalCID.toString());
|
|
302
|
-
assert.fail('Should detect complete metadata substitution via CID verification');
|
|
303
|
-
}
|
|
304
|
-
catch (error) {
|
|
305
|
-
assert(error instanceof Error, 'Should throw an Error');
|
|
306
|
-
assert(error.message.includes('CID verification failed'), `Should catch complete substitution via CID verification. Got: ${error.message}`);
|
|
307
|
-
}
|
|
308
|
-
finally {
|
|
309
|
-
globalThis.fetch = originalFetch;
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
//# sourceMappingURL=cid-verification.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-compatibility.spec.d.ts","sourceRoot":"","sources":["../../test/crypto-compatibility.spec.js"],"names":[],"mappings":""}
|