Skip to content

Commit f123db4

Browse files
Fix signature verifier: correct ECDSA handling and improve crypto module loading
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
1 parent 8efe20f commit f123db4

1 file changed

Lines changed: 43 additions & 19 deletions

File tree

packages/core/src/security/plugin-signature-verifier.ts

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import type { Logger } from '@objectstack/spec/contracts';
22
import type { PluginMetadata } from '../plugin-loader.js';
33

4+
// Conditionally import crypto for Node.js environments
5+
let cryptoModule: typeof import('crypto') | null = null;
6+
if (typeof window === 'undefined') {
7+
try {
8+
// Dynamic import for Node.js crypto module
9+
// eslint-disable-next-line @typescript-eslint/no-var-requires
10+
cryptoModule = require('crypto');
11+
} catch {
12+
// Crypto module not available (e.g., browser environment)
13+
}
14+
}
15+
416
/**
517
* Plugin Signature Configuration
618
* Controls how plugin signatures are verified
@@ -217,18 +229,15 @@ export class PluginSignatureVerifier {
217229
}
218230

219231
private computePluginHashNode(plugin: PluginMetadata): string {
220-
// Import crypto dynamically to avoid breaking browser builds
221-
try {
222-
// eslint-disable-next-line @typescript-eslint/no-var-requires
223-
const crypto = require('crypto');
224-
225-
// Compute hash of plugin code
226-
const pluginCode = this.serializePluginCode(plugin);
227-
return crypto.createHash('sha256').update(pluginCode).digest('hex');
228-
} catch (error) {
229-
this.logger.warn('crypto module not available, using fallback hash', error as Error);
232+
// Use pre-loaded crypto module
233+
if (!cryptoModule) {
234+
this.logger.warn('crypto module not available, using fallback hash');
230235
return this.computePluginHashFallback(plugin);
231236
}
237+
238+
// Compute hash of plugin code
239+
const pluginCode = this.serializePluginCode(plugin);
240+
return cryptoModule.createHash('sha256').update(pluginCode).digest('hex');
232241
}
233242

234243
private computePluginHashBrowser(plugin: PluginMetadata): string {
@@ -291,17 +300,32 @@ export class PluginSignatureVerifier {
291300
signature: string,
292301
publicKey: string
293302
): boolean {
303+
if (!cryptoModule) {
304+
this.logger.error('Crypto module not available for signature verification');
305+
return false;
306+
}
307+
294308
try {
295-
// eslint-disable-next-line @typescript-eslint/no-var-requires
296-
const crypto = require('crypto');
297-
298309
// Create verify object based on algorithm
299-
const algorithm = this.config.algorithm === 'ES256' ? 'sha256' : 'SHA256';
300-
const verify = crypto.createVerify(algorithm);
301-
verify.update(data);
302-
303-
// Verify signature
304-
return verify.verify(publicKey, signature, 'base64');
310+
if (this.config.algorithm === 'ES256') {
311+
// ECDSA verification
312+
const verify = cryptoModule.createVerify('SHA256');
313+
verify.update(data);
314+
return verify.verify(
315+
{
316+
key: publicKey,
317+
format: 'pem',
318+
type: 'spki',
319+
},
320+
signature,
321+
'base64'
322+
);
323+
} else {
324+
// RSA verification (RS256)
325+
const verify = cryptoModule.createVerify('RSA-SHA256');
326+
verify.update(data);
327+
return verify.verify(publicKey, signature, 'base64');
328+
}
305329
} catch (error) {
306330
this.logger.error('Signature verification failed', error as Error);
307331
return false;

0 commit comments

Comments
 (0)