feat: add remote trust and server identity pinning
Testing / remote-protocol-compat (0.16.0) (push) Successful in 1m1s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 1m3s
Testing / test (push) Failing after 1m15s
Build & Publish Package / publish (push) Successful in 51s
Package Extension / package-extension (push) Successful in 1m6s
Testing / remote-protocol-compat (0.16.0) (push) Successful in 1m1s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 1m3s
Testing / test (push) Failing after 1m15s
Build & Publish Package / publish (push) Successful in 51s
Package Extension / package-extension (push) Successful in 1m6s
- Add SSH-style server identity keys and known-host verification for remote serve endpoints. - Add remote add/list/remove commands for explicit endpoint persistence. - Fix remote clients listing to fan out through target discovery instead of ambiguous auto-routing. - Add URL glob matching for tabs filter and count with extension tests. - Add n8n credential pinning for server public keys or SHA256 fingerprints. - Remove obsolete compat shim behavior while keeping empty compat seams for future protocol changes. - Bump browser-cli to 0.16.4 and n8n node to 0.3.1. - Cover known-hosts, remote registry, compat seams, n8n protocol verification, and URL matching with tests.
This commit is contained in:
@@ -11,7 +11,10 @@ import {
|
||||
pqDecrypt,
|
||||
pqEncrypt,
|
||||
pqTransportKey,
|
||||
serverFingerprint,
|
||||
signAuth,
|
||||
verifyServerChallengeSignature,
|
||||
verifyServerIdentity,
|
||||
} from '../nodes/BrowserCli/protocol';
|
||||
|
||||
// Known-answer vectors produced by the real Python implementation
|
||||
@@ -49,6 +52,19 @@ const DECRYPT_ENV = {
|
||||
ciphertext: '7e4f75fa68098ea9a162dfd49af7824526186b77e9ac346b58f30d73df2bef88d5e6cd',
|
||||
};
|
||||
const DECRYPT_PLAIN = 'hello world payload';
|
||||
const SERVER_PUB_HEX = '982c13bda72ef7b2bf4a8cd9756e4f283faaf4a34f9dec8e6c65585b64d9a902';
|
||||
const SERVER_SIG =
|
||||
'fa6897bb7f00f711ee8af151384eda736a503008f8b8e11b972cfea46a0366d5' +
|
||||
'3127c2f1e9ba01e72805b267d023c552756645ae7d95fd00fa277ed20a43ee09';
|
||||
const SERVER_FP = 'SHA256:wsYDqD4OnF/Sfvr3RKvVCOW8ET802H2qHSvWfnQwQrs';
|
||||
const SERVER_CHALLENGE = {
|
||||
type: 'challenge',
|
||||
nonce: NONCE_HEX,
|
||||
server_version: '0.16.4',
|
||||
min_client_version: '0.9.0',
|
||||
server_pubkey: SERVER_PUB_HEX,
|
||||
server_sig: SERVER_SIG,
|
||||
};
|
||||
|
||||
test('canonicalJson matches Python json.dumps(sort_keys, ensure_ascii)', () => {
|
||||
assert.equal(canonicalJson(MSG), CANON);
|
||||
@@ -139,3 +155,26 @@ test('decodeResponse parses plain JSON and decrypts PQ envelopes', () => {
|
||||
const raw = Buffer.from(JSON.stringify({ encrypted: env }));
|
||||
assert.deepEqual(decodeResponse(raw, secret), { success: true, data: 1 });
|
||||
});
|
||||
|
||||
test('server identity fingerprint and signature match Python challenge signing', () => {
|
||||
assert.equal(serverFingerprint(SERVER_PUB_HEX), SERVER_FP);
|
||||
assert.equal(verifyServerChallengeSignature(SERVER_CHALLENGE), true);
|
||||
assert.equal(verifyServerChallengeSignature({ ...SERVER_CHALLENGE, nonce: '22'.repeat(32) }), false);
|
||||
});
|
||||
|
||||
test('verifyServerIdentity accepts pinned pubkey or fingerprint', () => {
|
||||
assert.doesNotThrow(() => verifyServerIdentity(SERVER_CHALLENGE, SERVER_PUB_HEX, 'browser-host.example:8765', false));
|
||||
assert.doesNotThrow(() => verifyServerIdentity(SERVER_CHALLENGE, SERVER_FP, 'browser-host.example:8765', false));
|
||||
});
|
||||
|
||||
test('verifyServerIdentity rejects unknown and changed identities', () => {
|
||||
assert.throws(
|
||||
() => verifyServerIdentity(SERVER_CHALLENGE, null, 'browser-host.example:8765', false),
|
||||
/Unknown browser-cli server identity/,
|
||||
);
|
||||
assert.throws(
|
||||
() => verifyServerIdentity(SERVER_CHALLENGE, '00'.repeat(32), 'browser-host.example:8765', false),
|
||||
/REMOTE SERVER IDENTITY CHANGED/,
|
||||
);
|
||||
assert.doesNotThrow(() => verifyServerIdentity(SERVER_CHALLENGE, null, 'browser-host.example:8765', true));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user