Files
safetynet/tests/broker-management-credential-lifecycle.test.mjs

19 lines
2.3 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {spawn} from 'node:child_process';
import {createRequire} from 'node:module';
const require=createRequire(import.meta.url);
const {createNativeManagementCredentialLoader}=require('../apps/network-broker/management-credential.cjs');
const current={deviceId:'device',origin:'https://management.example',policyVersion:8,policyKeySha256:'a'.repeat(64),policyDigest:'b'.repeat(64)};
// Synthetic stdio fixture exercises the real JS consumer only. Native selector,
// registry and DPAPI execution are separate gates; this is not their proof.
function client(stale=false){return createNativeManagementCredentialLoader({expectedBinding:current,current:()=>true,launch:()=>spawn(process.execPath,['-e',`let bytes=Buffer.alloc(0);process.stdin.on('data',part=>bytes=Buffer.concat([bytes,part]));process.stdin.on('end',()=>{const request=JSON.parse(bytes.subarray(4));const reply={...request,token:'synthetic_token_0123456789'};${stale?"reply.policyVersion=7;reply.policyDigest='c'.repeat(64);":""}const body=Buffer.from(JSON.stringify(reply)),header=Buffer.alloc(4);header.writeUInt32LE(body.length);process.stdout.write(Buffer.concat([header,body]));});`],{windowsHide:true,stdio:['pipe','pipe','ignore']})});}
test('current request echo accepts a reused private credential without claiming stored old metadata is current',async()=>{
const previous=process.env.SAFETYNET_SERVICE_CLIENT_SID;process.env.SAFETYNET_SERVICE_CLIENT_SID='S-1-5-21-1-2-3-1001';
const loader=client();try{const value=await loader.load(current);assert.equal(value.token.toString(),'synthetic_token_0123456789');assert.equal(value.deviceId,current.deviceId);value.token.fill(0);}finally{await loader.close();if(previous===undefined)delete process.env.SAFETYNET_SERVICE_CLIENT_SID;else process.env.SAFETYNET_SERVICE_CLIENT_SID=previous;}
});
test('echoing the credential record older policy binding instead of current request is rejected',async()=>{
const previous=process.env.SAFETYNET_SERVICE_CLIENT_SID;process.env.SAFETYNET_SERVICE_CLIENT_SID='S-1-5-21-1-2-3-1001';
const loader=client(true);try{await assert.rejects(loader.load(current),{message:'broker-management-refused'});}finally{await loader.close();if(previous===undefined)delete process.env.SAFETYNET_SERVICE_CLIENT_SID;else process.env.SAFETYNET_SERVICE_CLIENT_SID=previous;}
});