@bananalink-sdk/protocol 1.2.7
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 +604 -0
- package/dist/chunk-32OWUOZ3.js +308 -0
- package/dist/chunk-32OWUOZ3.js.map +1 -0
- package/dist/chunk-65HNHRJK.cjs +123 -0
- package/dist/chunk-65HNHRJK.cjs.map +1 -0
- package/dist/chunk-7KYDLL3B.js +480 -0
- package/dist/chunk-7KYDLL3B.js.map +1 -0
- package/dist/chunk-A6FLEJ7R.cjs +62 -0
- package/dist/chunk-A6FLEJ7R.cjs.map +1 -0
- package/dist/chunk-CUJK7ZTS.js +217 -0
- package/dist/chunk-CUJK7ZTS.js.map +1 -0
- package/dist/chunk-GI3BUPIH.cjs +236 -0
- package/dist/chunk-GI3BUPIH.cjs.map +1 -0
- package/dist/chunk-JXHV66Q4.js +106 -0
- package/dist/chunk-JXHV66Q4.js.map +1 -0
- package/dist/chunk-KNGZKGRS.cjs +552 -0
- package/dist/chunk-KNGZKGRS.cjs.map +1 -0
- package/dist/chunk-LELPCIE7.js +840 -0
- package/dist/chunk-LELPCIE7.js.map +1 -0
- package/dist/chunk-MCZG7QEM.cjs +310 -0
- package/dist/chunk-MCZG7QEM.cjs.map +1 -0
- package/dist/chunk-TCVKC227.js +56 -0
- package/dist/chunk-TCVKC227.js.map +1 -0
- package/dist/chunk-VXLUSU5B.cjs +856 -0
- package/dist/chunk-VXLUSU5B.cjs.map +1 -0
- package/dist/chunk-WCQVDF3K.js +12 -0
- package/dist/chunk-WCQVDF3K.js.map +1 -0
- package/dist/chunk-WGEGR3DF.cjs +15 -0
- package/dist/chunk-WGEGR3DF.cjs.map +1 -0
- package/dist/client-session-claim-3QF3noOr.d.ts +197 -0
- package/dist/client-session-claim-C4lUik3b.d.cts +197 -0
- package/dist/core-DMhuNfoz.d.cts +62 -0
- package/dist/core-DMhuNfoz.d.ts +62 -0
- package/dist/crypto/providers/noble-provider.cjs +14 -0
- package/dist/crypto/providers/noble-provider.cjs.map +1 -0
- package/dist/crypto/providers/noble-provider.d.cts +30 -0
- package/dist/crypto/providers/noble-provider.d.ts +30 -0
- package/dist/crypto/providers/noble-provider.js +5 -0
- package/dist/crypto/providers/noble-provider.js.map +1 -0
- package/dist/crypto/providers/node-provider.cjs +308 -0
- package/dist/crypto/providers/node-provider.cjs.map +1 -0
- package/dist/crypto/providers/node-provider.d.cts +32 -0
- package/dist/crypto/providers/node-provider.d.ts +32 -0
- package/dist/crypto/providers/node-provider.js +306 -0
- package/dist/crypto/providers/node-provider.js.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs +339 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.d.cts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.d.ts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.js +337 -0
- package/dist/crypto/providers/quickcrypto-provider.js.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.cjs +310 -0
- package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.d.cts +30 -0
- package/dist/crypto/providers/webcrypto-provider.d.ts +30 -0
- package/dist/crypto/providers/webcrypto-provider.js +308 -0
- package/dist/crypto/providers/webcrypto-provider.js.map +1 -0
- package/dist/crypto-BUS06Qz-.d.cts +40 -0
- package/dist/crypto-BUS06Qz-.d.ts +40 -0
- package/dist/crypto-export.cjs +790 -0
- package/dist/crypto-export.cjs.map +1 -0
- package/dist/crypto-export.d.cts +257 -0
- package/dist/crypto-export.d.ts +257 -0
- package/dist/crypto-export.js +709 -0
- package/dist/crypto-export.js.map +1 -0
- package/dist/crypto-provider-deYoVIxi.d.cts +36 -0
- package/dist/crypto-provider-deYoVIxi.d.ts +36 -0
- package/dist/index.cjs +615 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +379 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.js +504 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas-export.cjs +294 -0
- package/dist/schemas-export.cjs.map +1 -0
- package/dist/schemas-export.d.cts +1598 -0
- package/dist/schemas-export.d.ts +1598 -0
- package/dist/schemas-export.js +5 -0
- package/dist/schemas-export.js.map +1 -0
- package/dist/siwe-export.cjs +237 -0
- package/dist/siwe-export.cjs.map +1 -0
- package/dist/siwe-export.d.cts +27 -0
- package/dist/siwe-export.d.ts +27 -0
- package/dist/siwe-export.js +228 -0
- package/dist/siwe-export.js.map +1 -0
- package/dist/testing.cjs +54 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +20 -0
- package/dist/testing.d.ts +20 -0
- package/dist/testing.js +51 -0
- package/dist/testing.js.map +1 -0
- package/dist/validation-export.cjs +359 -0
- package/dist/validation-export.cjs.map +1 -0
- package/dist/validation-export.d.cts +3 -0
- package/dist/validation-export.d.ts +3 -0
- package/dist/validation-export.js +6 -0
- package/dist/validation-export.js.map +1 -0
- package/dist/validators-export.cjs +73 -0
- package/dist/validators-export.cjs.map +1 -0
- package/dist/validators-export.d.cts +37 -0
- package/dist/validators-export.d.ts +37 -0
- package/dist/validators-export.js +4 -0
- package/dist/validators-export.js.map +1 -0
- package/package.json +140 -0
- package/src/constants/index.ts +205 -0
- package/src/crypto/context.ts +228 -0
- package/src/crypto/diagnostics.ts +772 -0
- package/src/crypto/errors.ts +114 -0
- package/src/crypto/index.ts +89 -0
- package/src/crypto/payload-handler.ts +102 -0
- package/src/crypto/providers/compliance-provider.ts +579 -0
- package/src/crypto/providers/factory.ts +204 -0
- package/src/crypto/providers/index.ts +44 -0
- package/src/crypto/providers/noble-provider.ts +392 -0
- package/src/crypto/providers/node-provider.ts +433 -0
- package/src/crypto/providers/quickcrypto-provider.ts +483 -0
- package/src/crypto/providers/registry.ts +129 -0
- package/src/crypto/providers/webcrypto-provider.ts +364 -0
- package/src/crypto/session-security.ts +185 -0
- package/src/crypto/types.ts +93 -0
- package/src/crypto/utils.ts +190 -0
- package/src/crypto-export.ts +21 -0
- package/src/index.ts +38 -0
- package/src/schemas/auth.ts +60 -0
- package/src/schemas/client-messages.ts +57 -0
- package/src/schemas/core.ts +144 -0
- package/src/schemas/crypto.ts +65 -0
- package/src/schemas/discovery.ts +79 -0
- package/src/schemas/index.ts +239 -0
- package/src/schemas/relay-messages.ts +45 -0
- package/src/schemas/wallet-messages.ts +177 -0
- package/src/schemas-export.ts +23 -0
- package/src/siwe-export.ts +27 -0
- package/src/testing.ts +71 -0
- package/src/types/auth.ts +60 -0
- package/src/types/client-messages.ts +84 -0
- package/src/types/core.ts +131 -0
- package/src/types/crypto-provider.ts +264 -0
- package/src/types/crypto.ts +90 -0
- package/src/types/discovery.ts +50 -0
- package/src/types/errors.ts +87 -0
- package/src/types/index.ts +197 -0
- package/src/types/post-auth-operations.ts +363 -0
- package/src/types/providers.ts +72 -0
- package/src/types/relay-messages.ts +60 -0
- package/src/types/request-lifecycle.ts +161 -0
- package/src/types/signing-operations.ts +99 -0
- package/src/types/wallet-messages.ts +251 -0
- package/src/utils/client-session-claim.ts +188 -0
- package/src/utils/index.ts +54 -0
- package/src/utils/public-keys.ts +49 -0
- package/src/utils/siwe.ts +362 -0
- package/src/utils/url-decoding.ts +126 -0
- package/src/utils/url-encoding.ts +144 -0
- package/src/utils/wallet-session-claim.ts +188 -0
- package/src/validation-export.ts +32 -0
- package/src/validators/index.ts +222 -0
- package/src/validators-export.ts +8 -0
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
import type { Logger } from '@bananalink-sdk/logger';
|
|
2
|
+
import type { CryptoProvider, CryptoKeyLike, ProviderKeyPair } from '../../types/crypto-provider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Compliance audit event types
|
|
6
|
+
*/
|
|
7
|
+
export type ComplianceEventType =
|
|
8
|
+
| 'key_generation'
|
|
9
|
+
| 'key_import'
|
|
10
|
+
| 'key_export'
|
|
11
|
+
| 'key_derivation'
|
|
12
|
+
| 'encryption'
|
|
13
|
+
| 'decryption'
|
|
14
|
+
| 'hmac_generation'
|
|
15
|
+
| 'hmac_verification'
|
|
16
|
+
| 'random_generation';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Compliance audit event
|
|
20
|
+
*/
|
|
21
|
+
export interface ComplianceAuditEvent {
|
|
22
|
+
eventType: ComplianceEventType;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
sessionId?: string;
|
|
25
|
+
keyUsage?: readonly string[];
|
|
26
|
+
dataSize?: number;
|
|
27
|
+
algorithm?: string;
|
|
28
|
+
success: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compliance audit logger interface
|
|
35
|
+
*/
|
|
36
|
+
export interface ComplianceAuditor {
|
|
37
|
+
logEvent(event: ComplianceAuditEvent): void;
|
|
38
|
+
getAuditLog(): ComplianceAuditEvent[];
|
|
39
|
+
clearAuditLog(): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Default compliance auditor implementation
|
|
44
|
+
*/
|
|
45
|
+
export class DefaultComplianceAuditor implements ComplianceAuditor {
|
|
46
|
+
private auditLog: ComplianceAuditEvent[] = [];
|
|
47
|
+
private readonly logger?: Logger;
|
|
48
|
+
|
|
49
|
+
constructor(logger?: Logger) {
|
|
50
|
+
this.logger = logger?.child({ component: 'ComplianceAuditor' });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
logEvent(event: ComplianceAuditEvent): void {
|
|
54
|
+
this.auditLog.push(event);
|
|
55
|
+
this.logger?.info('Compliance audit event', {
|
|
56
|
+
eventType: event.eventType,
|
|
57
|
+
success: event.success,
|
|
58
|
+
sessionId: event.sessionId,
|
|
59
|
+
timestamp: event.timestamp
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getAuditLog(): ComplianceAuditEvent[] {
|
|
64
|
+
return [...this.auditLog];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
clearAuditLog(): void {
|
|
68
|
+
this.auditLog = [];
|
|
69
|
+
this.logger?.debug('Compliance audit log cleared');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Key usage restrictions for compliance
|
|
75
|
+
*/
|
|
76
|
+
export interface KeyUsageRestrictions {
|
|
77
|
+
allowKeyExport?: boolean;
|
|
78
|
+
allowKeyImport?: boolean;
|
|
79
|
+
requiredKeyUsages?: string[];
|
|
80
|
+
forbiddenKeyUsages?: string[];
|
|
81
|
+
maxDataSize?: number;
|
|
82
|
+
requireSessionId?: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Compliance configuration
|
|
87
|
+
*/
|
|
88
|
+
export interface ComplianceConfig {
|
|
89
|
+
enabled?: boolean;
|
|
90
|
+
auditor?: ComplianceAuditor;
|
|
91
|
+
keyRestrictions?: KeyUsageRestrictions;
|
|
92
|
+
sessionId?: string;
|
|
93
|
+
enableStrictMode?: boolean;
|
|
94
|
+
strictMode?: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Compliance wrapper for CryptoProvider implementations
|
|
99
|
+
* Provides audit logging, key usage restrictions, and regulatory compliance features
|
|
100
|
+
*/
|
|
101
|
+
export class ComplianceCryptoProvider implements CryptoProvider {
|
|
102
|
+
public readonly name: string;
|
|
103
|
+
public readonly isAvailable: boolean;
|
|
104
|
+
|
|
105
|
+
private readonly underlyingProvider: CryptoProvider;
|
|
106
|
+
private readonly config: ComplianceConfig;
|
|
107
|
+
private readonly auditor: ComplianceAuditor;
|
|
108
|
+
private readonly logger?: Logger;
|
|
109
|
+
|
|
110
|
+
constructor(
|
|
111
|
+
underlyingProvider: CryptoProvider,
|
|
112
|
+
config: ComplianceConfig = {},
|
|
113
|
+
logger?: Logger
|
|
114
|
+
) {
|
|
115
|
+
this.underlyingProvider = underlyingProvider;
|
|
116
|
+
this.config = config;
|
|
117
|
+
this.auditor = config.auditor || new DefaultComplianceAuditor(logger);
|
|
118
|
+
this.logger = logger?.child({
|
|
119
|
+
component: 'ComplianceCryptoProvider',
|
|
120
|
+
underlyingProvider: underlyingProvider.name
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
this.name = `Compliance(${underlyingProvider.name})`;
|
|
124
|
+
this.isAvailable = underlyingProvider.isAvailable;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Create compliance audit event
|
|
129
|
+
*/
|
|
130
|
+
private createAuditEvent(
|
|
131
|
+
eventType: ComplianceEventType,
|
|
132
|
+
success: boolean,
|
|
133
|
+
metadata: Record<string, unknown> = {},
|
|
134
|
+
error?: string
|
|
135
|
+
): ComplianceAuditEvent {
|
|
136
|
+
return {
|
|
137
|
+
eventType,
|
|
138
|
+
timestamp: new Date().toISOString(),
|
|
139
|
+
sessionId: this.config.sessionId,
|
|
140
|
+
success,
|
|
141
|
+
error,
|
|
142
|
+
metadata,
|
|
143
|
+
...metadata
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Validate key usage restrictions
|
|
149
|
+
*/
|
|
150
|
+
private validateKeyUsage(operation: string, keyUsages?: readonly string[], dataSize?: number): void {
|
|
151
|
+
const restrictions = this.config.keyRestrictions;
|
|
152
|
+
if (!restrictions) return;
|
|
153
|
+
|
|
154
|
+
if (restrictions.requireSessionId && !this.config.sessionId) {
|
|
155
|
+
throw new Error('Session ID required for compliance but not provided');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (restrictions.maxDataSize && dataSize && dataSize > restrictions.maxDataSize) {
|
|
159
|
+
throw new Error(`Data size ${dataSize} exceeds maximum allowed ${restrictions.maxDataSize} bytes`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (keyUsages && restrictions.requiredKeyUsages) {
|
|
163
|
+
const hasRequiredUsage = restrictions.requiredKeyUsages.some(usage => keyUsages.includes(usage));
|
|
164
|
+
if (!hasRequiredUsage) {
|
|
165
|
+
throw new Error(`Key must have one of required usages: ${restrictions.requiredKeyUsages.join(', ')}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (keyUsages && restrictions.forbiddenKeyUsages) {
|
|
170
|
+
const hasForbiddenUsage = restrictions.forbiddenKeyUsages.some(usage => keyUsages.includes(usage));
|
|
171
|
+
if (hasForbiddenUsage) {
|
|
172
|
+
throw new Error(`Key has forbidden usage. Forbidden: ${restrictions.forbiddenKeyUsages.join(', ')}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Operation-specific restrictions
|
|
177
|
+
if (operation === 'export' && restrictions.allowKeyExport === false) {
|
|
178
|
+
throw new Error('Key export is forbidden by compliance policy');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (operation === 'import' && restrictions.allowKeyImport === false) {
|
|
182
|
+
throw new Error('Key import is forbidden by compliance policy');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generate ECDH P-256 key pair with compliance audit
|
|
188
|
+
*/
|
|
189
|
+
async generateKeyPair(): Promise<ProviderKeyPair> {
|
|
190
|
+
const startTime = Date.now();
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
this.logger?.debug('Generating key pair with compliance audit');
|
|
194
|
+
|
|
195
|
+
const keyPair = await this.underlyingProvider.generateKeyPair();
|
|
196
|
+
|
|
197
|
+
this.validateKeyUsage('generation', keyPair.privateKey.usages);
|
|
198
|
+
|
|
199
|
+
this.auditor.logEvent(this.createAuditEvent('key_generation', true, {
|
|
200
|
+
algorithm: keyPair.privateKey.algorithm,
|
|
201
|
+
keyUsage: keyPair.privateKey.usages,
|
|
202
|
+
duration: Date.now() - startTime
|
|
203
|
+
}));
|
|
204
|
+
|
|
205
|
+
return keyPair;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
this.auditor.logEvent(this.createAuditEvent('key_generation', false, {
|
|
208
|
+
duration: Date.now() - startTime
|
|
209
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
210
|
+
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Export public key with compliance audit
|
|
217
|
+
*/
|
|
218
|
+
async exportPublicKey(publicKey: CryptoKeyLike): Promise<ArrayBuffer> {
|
|
219
|
+
const startTime = Date.now();
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
this.validateKeyUsage('export', publicKey.usages);
|
|
223
|
+
|
|
224
|
+
const keyData = await this.underlyingProvider.exportPublicKey(publicKey);
|
|
225
|
+
|
|
226
|
+
this.auditor.logEvent(this.createAuditEvent('key_export', true, {
|
|
227
|
+
keyType: 'public',
|
|
228
|
+
algorithm: publicKey.algorithm,
|
|
229
|
+
keySize: keyData.byteLength,
|
|
230
|
+
duration: Date.now() - startTime
|
|
231
|
+
}));
|
|
232
|
+
|
|
233
|
+
return keyData;
|
|
234
|
+
} catch (error) {
|
|
235
|
+
this.auditor.logEvent(this.createAuditEvent('key_export', false, {
|
|
236
|
+
keyType: 'public',
|
|
237
|
+
algorithm: publicKey.algorithm,
|
|
238
|
+
duration: Date.now() - startTime
|
|
239
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
240
|
+
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Export private key with compliance audit
|
|
247
|
+
*/
|
|
248
|
+
async exportPrivateKey(privateKey: CryptoKeyLike): Promise<ArrayBuffer> {
|
|
249
|
+
const startTime = Date.now();
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
this.validateKeyUsage('export', privateKey.usages);
|
|
253
|
+
|
|
254
|
+
// Extra security check for private key export
|
|
255
|
+
if (this.config.enableStrictMode) {
|
|
256
|
+
this.logger?.warn('Private key export in strict compliance mode', {
|
|
257
|
+
sessionId: this.config.sessionId,
|
|
258
|
+
algorithm: privateKey.algorithm
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const keyData = await this.underlyingProvider.exportPrivateKey(privateKey);
|
|
263
|
+
|
|
264
|
+
this.auditor.logEvent(this.createAuditEvent('key_export', true, {
|
|
265
|
+
keyType: 'private',
|
|
266
|
+
algorithm: privateKey.algorithm,
|
|
267
|
+
keySize: keyData.byteLength,
|
|
268
|
+
strictMode: this.config.enableStrictMode,
|
|
269
|
+
duration: Date.now() - startTime
|
|
270
|
+
}));
|
|
271
|
+
|
|
272
|
+
return keyData;
|
|
273
|
+
} catch (error) {
|
|
274
|
+
this.auditor.logEvent(this.createAuditEvent('key_export', false, {
|
|
275
|
+
keyType: 'private',
|
|
276
|
+
algorithm: privateKey.algorithm,
|
|
277
|
+
strictMode: this.config.enableStrictMode,
|
|
278
|
+
duration: Date.now() - startTime
|
|
279
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
280
|
+
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Import public key with compliance audit
|
|
287
|
+
*/
|
|
288
|
+
async importPublicKey(keyData: ArrayBuffer): Promise<CryptoKeyLike> {
|
|
289
|
+
const startTime = Date.now();
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
this.validateKeyUsage('import');
|
|
293
|
+
|
|
294
|
+
const key = await this.underlyingProvider.importPublicKey(keyData);
|
|
295
|
+
|
|
296
|
+
this.auditor.logEvent(this.createAuditEvent('key_import', true, {
|
|
297
|
+
keyType: 'public',
|
|
298
|
+
algorithm: key.algorithm,
|
|
299
|
+
keySize: keyData.byteLength,
|
|
300
|
+
keyUsage: key.usages,
|
|
301
|
+
duration: Date.now() - startTime
|
|
302
|
+
}));
|
|
303
|
+
|
|
304
|
+
return key;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
this.auditor.logEvent(this.createAuditEvent('key_import', false, {
|
|
307
|
+
keyType: 'public',
|
|
308
|
+
keySize: keyData.byteLength,
|
|
309
|
+
duration: Date.now() - startTime
|
|
310
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
311
|
+
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Import private key with compliance audit
|
|
318
|
+
*/
|
|
319
|
+
async importPrivateKey(keyData: ArrayBuffer): Promise<CryptoKeyLike> {
|
|
320
|
+
const startTime = Date.now();
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
this.validateKeyUsage('import');
|
|
324
|
+
|
|
325
|
+
const key = await this.underlyingProvider.importPrivateKey(keyData);
|
|
326
|
+
|
|
327
|
+
this.auditor.logEvent(this.createAuditEvent('key_import', true, {
|
|
328
|
+
keyType: 'private',
|
|
329
|
+
algorithm: key.algorithm,
|
|
330
|
+
keySize: keyData.byteLength,
|
|
331
|
+
keyUsage: key.usages,
|
|
332
|
+
duration: Date.now() - startTime
|
|
333
|
+
}));
|
|
334
|
+
|
|
335
|
+
return key;
|
|
336
|
+
} catch (error) {
|
|
337
|
+
this.auditor.logEvent(this.createAuditEvent('key_import', false, {
|
|
338
|
+
keyType: 'private',
|
|
339
|
+
keySize: keyData.byteLength,
|
|
340
|
+
duration: Date.now() - startTime
|
|
341
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
342
|
+
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Derive shared secret with compliance audit
|
|
349
|
+
*/
|
|
350
|
+
async deriveSharedSecret(privateKey: CryptoKeyLike, publicKey: CryptoKeyLike): Promise<CryptoKeyLike> {
|
|
351
|
+
const startTime = Date.now();
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
this.validateKeyUsage('derivation', privateKey.usages);
|
|
355
|
+
|
|
356
|
+
const sharedSecret = await this.underlyingProvider.deriveSharedSecret(privateKey, publicKey);
|
|
357
|
+
|
|
358
|
+
this.auditor.logEvent(this.createAuditEvent('key_derivation', true, {
|
|
359
|
+
operation: 'ECDH',
|
|
360
|
+
algorithm: privateKey.algorithm,
|
|
361
|
+
duration: Date.now() - startTime
|
|
362
|
+
}));
|
|
363
|
+
|
|
364
|
+
return sharedSecret;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
this.auditor.logEvent(this.createAuditEvent('key_derivation', false, {
|
|
367
|
+
operation: 'ECDH',
|
|
368
|
+
algorithm: privateKey.algorithm,
|
|
369
|
+
duration: Date.now() - startTime
|
|
370
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
371
|
+
|
|
372
|
+
throw error;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Derive encryption key with compliance audit
|
|
378
|
+
*/
|
|
379
|
+
async deriveEncryptionKey(sharedSecret: CryptoKeyLike, salt: ArrayBuffer, info: ArrayBuffer): Promise<CryptoKeyLike> {
|
|
380
|
+
const startTime = Date.now();
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
const encryptionKey = await this.underlyingProvider.deriveEncryptionKey(sharedSecret, salt, info);
|
|
384
|
+
|
|
385
|
+
this.auditor.logEvent(this.createAuditEvent('key_derivation', true, {
|
|
386
|
+
operation: 'HKDF',
|
|
387
|
+
algorithm: 'HKDF-SHA256',
|
|
388
|
+
saltSize: salt.byteLength,
|
|
389
|
+
infoSize: info.byteLength,
|
|
390
|
+
duration: Date.now() - startTime
|
|
391
|
+
}));
|
|
392
|
+
|
|
393
|
+
return encryptionKey;
|
|
394
|
+
} catch (error) {
|
|
395
|
+
this.auditor.logEvent(this.createAuditEvent('key_derivation', false, {
|
|
396
|
+
operation: 'HKDF',
|
|
397
|
+
algorithm: 'HKDF-SHA256',
|
|
398
|
+
saltSize: salt.byteLength,
|
|
399
|
+
infoSize: info.byteLength,
|
|
400
|
+
duration: Date.now() - startTime
|
|
401
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
402
|
+
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Generate random bytes with compliance audit
|
|
409
|
+
*/
|
|
410
|
+
randomBytes(length: number): ArrayBuffer {
|
|
411
|
+
const startTime = Date.now();
|
|
412
|
+
|
|
413
|
+
try {
|
|
414
|
+
const randomData = this.underlyingProvider.randomBytes(length);
|
|
415
|
+
|
|
416
|
+
this.auditor.logEvent(this.createAuditEvent('random_generation', true, {
|
|
417
|
+
length,
|
|
418
|
+
duration: Date.now() - startTime
|
|
419
|
+
}));
|
|
420
|
+
|
|
421
|
+
return randomData;
|
|
422
|
+
} catch (error) {
|
|
423
|
+
this.auditor.logEvent(this.createAuditEvent('random_generation', false, {
|
|
424
|
+
length,
|
|
425
|
+
duration: Date.now() - startTime
|
|
426
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
427
|
+
|
|
428
|
+
throw error;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Encrypt data with compliance audit
|
|
434
|
+
*/
|
|
435
|
+
async encrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {
|
|
436
|
+
const startTime = Date.now();
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
this.validateKeyUsage('encryption', key.usages, data.byteLength);
|
|
440
|
+
|
|
441
|
+
const ciphertext = await this.underlyingProvider.encrypt(key, data, iv);
|
|
442
|
+
|
|
443
|
+
this.auditor.logEvent(this.createAuditEvent('encryption', true, {
|
|
444
|
+
algorithm: key.algorithm,
|
|
445
|
+
dataSize: data.byteLength,
|
|
446
|
+
ivSize: iv.byteLength,
|
|
447
|
+
ciphertextSize: ciphertext.byteLength,
|
|
448
|
+
duration: Date.now() - startTime
|
|
449
|
+
}));
|
|
450
|
+
|
|
451
|
+
return ciphertext;
|
|
452
|
+
} catch (error) {
|
|
453
|
+
this.auditor.logEvent(this.createAuditEvent('encryption', false, {
|
|
454
|
+
algorithm: key.algorithm,
|
|
455
|
+
dataSize: data.byteLength,
|
|
456
|
+
ivSize: iv.byteLength,
|
|
457
|
+
duration: Date.now() - startTime
|
|
458
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
459
|
+
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Decrypt data with compliance audit
|
|
466
|
+
*/
|
|
467
|
+
async decrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {
|
|
468
|
+
const startTime = Date.now();
|
|
469
|
+
|
|
470
|
+
try {
|
|
471
|
+
this.validateKeyUsage('decryption', key.usages, data.byteLength);
|
|
472
|
+
|
|
473
|
+
const plaintext = await this.underlyingProvider.decrypt(key, data, iv);
|
|
474
|
+
|
|
475
|
+
this.auditor.logEvent(this.createAuditEvent('decryption', true, {
|
|
476
|
+
algorithm: key.algorithm,
|
|
477
|
+
dataSize: data.byteLength,
|
|
478
|
+
ivSize: iv.byteLength,
|
|
479
|
+
plaintextSize: plaintext.byteLength,
|
|
480
|
+
duration: Date.now() - startTime
|
|
481
|
+
}));
|
|
482
|
+
|
|
483
|
+
return plaintext;
|
|
484
|
+
} catch (error) {
|
|
485
|
+
this.auditor.logEvent(this.createAuditEvent('decryption', false, {
|
|
486
|
+
algorithm: key.algorithm,
|
|
487
|
+
dataSize: data.byteLength,
|
|
488
|
+
ivSize: iv.byteLength,
|
|
489
|
+
duration: Date.now() - startTime
|
|
490
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
491
|
+
|
|
492
|
+
throw error;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Generate HMAC with compliance audit
|
|
498
|
+
*/
|
|
499
|
+
async generateHMAC(key: CryptoKeyLike, data: ArrayBuffer): Promise<ArrayBuffer> {
|
|
500
|
+
const startTime = Date.now();
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
this.validateKeyUsage('hmac', key.usages, data.byteLength);
|
|
504
|
+
|
|
505
|
+
const mac = await this.underlyingProvider.generateHMAC(key, data);
|
|
506
|
+
|
|
507
|
+
this.auditor.logEvent(this.createAuditEvent('hmac_generation', true, {
|
|
508
|
+
algorithm: 'HMAC-SHA256',
|
|
509
|
+
dataSize: data.byteLength,
|
|
510
|
+
macSize: mac.byteLength,
|
|
511
|
+
duration: Date.now() - startTime
|
|
512
|
+
}));
|
|
513
|
+
|
|
514
|
+
return mac;
|
|
515
|
+
} catch (error) {
|
|
516
|
+
this.auditor.logEvent(this.createAuditEvent('hmac_generation', false, {
|
|
517
|
+
algorithm: 'HMAC-SHA256',
|
|
518
|
+
dataSize: data.byteLength,
|
|
519
|
+
duration: Date.now() - startTime
|
|
520
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
521
|
+
|
|
522
|
+
throw error;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Verify HMAC with compliance audit
|
|
528
|
+
*/
|
|
529
|
+
async verifyHMAC(key: CryptoKeyLike, data: ArrayBuffer, mac: ArrayBuffer): Promise<boolean> {
|
|
530
|
+
const startTime = Date.now();
|
|
531
|
+
|
|
532
|
+
try {
|
|
533
|
+
this.validateKeyUsage('hmac', key.usages, data.byteLength);
|
|
534
|
+
|
|
535
|
+
const isValid = await this.underlyingProvider.verifyHMAC(key, data, mac);
|
|
536
|
+
|
|
537
|
+
this.auditor.logEvent(this.createAuditEvent('hmac_verification', true, {
|
|
538
|
+
algorithm: 'HMAC-SHA256',
|
|
539
|
+
dataSize: data.byteLength,
|
|
540
|
+
macSize: mac.byteLength,
|
|
541
|
+
verified: isValid,
|
|
542
|
+
duration: Date.now() - startTime
|
|
543
|
+
}));
|
|
544
|
+
|
|
545
|
+
return isValid;
|
|
546
|
+
} catch (error) {
|
|
547
|
+
this.auditor.logEvent(this.createAuditEvent('hmac_verification', false, {
|
|
548
|
+
algorithm: 'HMAC-SHA256',
|
|
549
|
+
dataSize: data.byteLength,
|
|
550
|
+
macSize: mac.byteLength,
|
|
551
|
+
duration: Date.now() - startTime
|
|
552
|
+
}, error instanceof Error ? error.message : String(error)));
|
|
553
|
+
|
|
554
|
+
throw error;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Get compliance auditor for external access
|
|
560
|
+
*/
|
|
561
|
+
getAuditor(): ComplianceAuditor {
|
|
562
|
+
return this.auditor;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Update compliance configuration
|
|
567
|
+
*/
|
|
568
|
+
updateConfig(newConfig: Partial<ComplianceConfig>): void {
|
|
569
|
+
Object.assign(this.config, newConfig);
|
|
570
|
+
this.logger?.debug('Compliance configuration updated', newConfig);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Get underlying provider (for debugging/testing)
|
|
575
|
+
*/
|
|
576
|
+
getUnderlyingProvider(): CryptoProvider {
|
|
577
|
+
return this.underlyingProvider;
|
|
578
|
+
}
|
|
579
|
+
}
|