Index: build/chrome/cackey.js ================================================================== --- build/chrome/cackey.js +++ build/chrome/cackey.js @@ -34,10 +34,11 @@ /* * Stored PIN for a given certificate */ var cackeyCertificateToPINMap = {}; +var cackeyCertificateToPINMapLastUsedRunner = false; /* * Callbacks to perform after PCSC comes online */ cackeyCallbackAfterInit = []; @@ -107,10 +108,57 @@ chromeCallback(payload); return; } + +/* + * Update the time a PIN was last used for a certificate + */ +function cackeyCertificateToPINMapUpdateLastUsed(id) { + if (id != null) { + cackeyCertificateToPINMap[id].lastUsed = (new Date()).getTime(); + } + + if (!cackeyCertificateToPINMapLastUsedRunner) { + cackeyCertificateToPINMapLastUsedRunner = true; + + setTimeout(function() { + var currentTime; + var certificates, certificate; + var idx; + + currentTime = (new Date()).getTime(); + + certificates = Object.keys(cackeyCertificateToPINMap); + + console.log("Looking for PINs to clear"); + + for (idx = 0; idx < certificates.length; idx++) { + certificate = certificates[idx]; + + if ((cackeyCertificateToPINMap[certificate].lastUsed + 900000) > currentTime) { + continue; + } + + console.log("Deleteting " + certificate); + + delete cackeyCertificateToPINMap[certificate]; + } + + certificates = Object.keys(cackeyCertificateToPINMap); + + cackeyCertificateToPINMapLastUsedRunner = false; + + if (certificates.length == 0) { + return; + } + + cackeyCertificateToPINMapUpdateLastUsed(null); + }, 900000); + } +} /* * Handle an incoming message from the NaCl side and pass it off to * one of the handlers above for actual formatting and passing to * the callback @@ -246,11 +294,14 @@ cackeyMessageIncoming(tmpMessageEvent); } else { tmpMessageEvent.data.originalrequest.pin = pinWindowPINValue; - cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)] = pinWindowPINValue; + cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)] = {} + cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)].pin = pinWindowPINValue; + + cackeyCertificateToPINMapUpdateLastUsed(cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)); chromeCallback = null; if (tmpMessageEvent.data.id) { if (cackeyOutstandingCallbacks) { chromeCallback = cackeyOutstandingCallbacks[tmpMessageEvent.data.id]; @@ -407,12 +458,14 @@ 'data': digest.buffer }; certificateId = cackeyCertificateToPINID(command.certificate); - if (cackeyCertificateToPINMap[certificateId]) { - command.pin = cackeyCertificateToPINMap[certificateId]; + if (cackeyCertificateToPINMap[certificateId] && cackeyCertificateToPINMap[certificateId].pin) { + command.pin = cackeyCertificateToPINMap[certificateId].pin; + + cackeyCertificateToPINMapUpdateLastUsed(certificateId); } cackeyInitPCSC(function() { cackeyHandle.postMessage(command);