import test from 'node:test'; import assert from 'node:assert/strict'; import {EventEmitter} from 'node:events'; import {generateKeyPairSync,randomUUID} from 'node:crypto'; import {createRequire} from 'node:module'; import {defaultPolicy,signPolicy} from '../packages/core/policy.mjs'; const require=createRequire(import.meta.url),{runServiceProcess}=require('../apps/network-broker/service-entry.cjs'); const {signManifest,verifyReleaseEnvelope,verifyDeploymentEnvelope}=require('../packages/core/windows-trust.cjs'); const {acceptanceStateDigest}=require('../apps/network-broker/service-acceptance.cjs'); const pub=k=>k.publicKey.export({type:'spki',format:'pem'}),priv=k=>k.privateKey.export({type:'pkcs8',format:'pem'}); function fixture(){ const vendor=generateKeyPairSync('ec',{namedCurve:'prime256v1'}),customer=generateKeyPairSync('ec',{namedCurve:'prime256v1'}),key=generateKeyPairSync('ed25519'),sid='S-1-12-1-1-2-3-4'; const release={format:'safetynet-windows-release-v1',releaseId:'12345678-1234-1234-1234-123456789abc',releaseSequence:1,serviceName:'SafetyNetNetworkBroker',deploymentTenant:'22345678-1234-1234-1234-123456789abc',deploymentPublicKey:pub(customer),files:['SafetyNet.exe','resources/app.asar','resources/broker/node.exe','resources/inspector/server.py','resources/python/python.exe','resources/semantic/model.bin','safetynet-service-host.exe'].map(path=>({path,bytes:1,sha256:'a'.repeat(64)}))}; const releaseEnvelope=signManifest(release,priv(vendor),'release'),r=verifyReleaseEnvelope(releaseEnvelope,{publicKey:pub(vendor)}); const deployment={format:'safetynet-windows-deployment-v1',releaseId:release.releaseId,deploymentTenant:release.deploymentTenant,deploymentSequence:1,policyPublicKey:pub(key),expiresAt:Date.now()+60000,users:[{sid,deviceId:'device',minimumPolicyVersion:7}]}; const deploymentEnvelope=signManifest(deployment,priv(customer),'deployment'),d=verifyDeploymentEnvelope(deploymentEnvelope,{release:r,authenticatedSid:sid}); const policy=defaultPolicy();policy.version=7;policy.assignment={deviceId:'device',groups:[]}; const snapshot={version:1,authenticatedSid:sid,releaseAnchor:pub(vendor),acceptanceState:{format:'safetynet-service-floors-v1',release:{minimumSequence:1,acceptedDigest:r.digest},deployment:{tenant:release.deploymentTenant,minimumSequence:1,acceptedDigest:d.digest},policies:[]}}; return {snapshot,envelopes:{releaseEnvelope,deploymentEnvelope},config:{publicKey:pub(key),deviceId:'device',minimumVersion:7,envelope:signPolicy(policy,priv(key)),brokerPort:43120,network:{mode:'direct',dns:'system'}}}; } function channel(){const c=new EventEmitter();c.connected=true;c.send=(v,callback)=>{c.emit('sent',v);callback?.();};c.disconnect=()=>{if(c.connected){c.connected=false;c.emit('disconnect');}};return c;} const verifiedTopology=async()=>({bfeRunning:true,ownedSublayer:'ours',enumerationComplete:true,allObjectsReadable:true,sublayers:[{key:'ours',weight:65535}],filters:Array.from({length:8},(_,i)=>({key:String(i),sublayer:'ours',layer:'c38d57d1-05a7-4c33-904f-7fbceee60e82',ownedVerified:true}))}); test('default unavailable native topology constructs no factory and opens no listener',async()=>{ const f=fixture(),c=channel();let factories=0; const store={async snapshot(){return f.snapshot;},async envelopes(){return f.envelopes;},async commit(value){return {persisted:true,stateSha256:acceptanceStateDigest(value.candidateState)};}}; const sent=new Promise(resolve=>{c.once('sent',resolve);c.once('disconnect',()=>resolve({type:'quarantined'}));}); const handle=runServiceProcess({channel:c,store,factory:async()=>{factories++;throw Error('must not construct');}}); c.emit('message',{type:'start',version:1,generation:randomUUID(),policyVersion:7,config:f.config}); assert.ok(['startup-fault','quarantined'].includes((await sent).type));assert.equal(factories,0);await handle.close();assert.equal(c.connected,false); }); test('runtime topology change waits original broker cleanup before disconnect',async()=>{ const f=fixture(),c=channel();let checks=0,closeCalls=0,releaseClose,closeStarted; const started=new Promise(resolve=>{closeStarted=resolve;}); const cleanup=new Promise(resolve=>{releaseClose=resolve;}); const store={async snapshot(){return f.snapshot;},async envelopes(){return f.envelopes;},async commit(value){return {persisted:true,stateSha256:acceptanceStateDigest(value.candidateState)};}}; const ready=new Promise(resolve=>c.once('sent',resolve)); const handle=runServiceProcess({channel:c,store,readTopology:async()=>({...await verifiedTopology(),bfeRunning:++checks===1}),factory:async()=>({authMode:'basic',credentials:{username:'safetynet-'+'a'.repeat(32),password:'a'.repeat(43)},async listen(){return 43120;},close(){closeCalls++;closeStarted();return cleanup;}})}); c.emit('message',{type:'start',version:1,generation:randomUUID(),policyVersion:7,config:f.config}); assert.equal((await ready).type,'ready'); await started;assert.equal(closeCalls,1);assert.equal(c.connected,true); const original=handle.close();assert.equal(handle.close(),original); releaseClose();await original;assert.equal(c.connected,false);assert.equal(closeCalls,1); }); test('signed service entry commits exact verified state before factory or listener',async()=>{ const f=fixture(),c=channel(),order=[];let request; const store={async snapshot(){order.push('snapshot');return f.snapshot;},async envelopes(){order.push('files');return f.envelopes;},async commit(value){order.push('commit');request=value;return {persisted:true,stateSha256:acceptanceStateDigest(value.candidateState)};}}; const finished=new Promise(resolve=>c.once('sent',resolve));const handle=runServiceProcess({channel:c,store,readTopology:verifiedTopology,factory:async(config)=>{order.push('factory');assert.equal(config.minimumVersion,7);return {authMode:'basic',credentials:{username:'safetynet-'+'a'.repeat(32),password:'a'.repeat(43)},async listen(){order.push('listen');return 43120;},async close(){order.push('close');}};}}); c.emit('message',{type:'start',version:1,generation:randomUUID(),policyVersion:7,config:f.config});assert.equal((await finished).type,'ready');assert.deepEqual(order,['snapshot','files','commit','factory','listen']);assert.equal(request.expectedPreviousSHA,acceptanceStateDigest(f.snapshot.acceptanceState));await handle.close();assert.equal(c.connected,false); }); test('failed durable commit and modified policy cannot construct the real factory',async()=>{ for(const tamper of [false,true]){const f=fixture(),c=channel();let called=0,commits=0;if(tamper)f.config.envelope.payload+=' '; const sent=new Promise(resolve=>c.once('sent',resolve));const handle=runServiceProcess({channel:c,store:{async snapshot(){return f.snapshot;},async envelopes(){return f.envelopes;},async commit(){commits++;throw Error('sensitive native error');}},factory:async()=>{called++;}}); c.emit('message',{type:'start',version:1,generation:randomUUID(),policyVersion:7,config:f.config});const result=await sent;assert.equal(result.type,'startup-fault');assert.equal(result.code,'broker-bootstrap-invalid');assert.equal(called,0);assert.equal(commits,tamper?0:1);await handle.close(); } });