Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
14 lines
No EOL
3.1 KiB
JavaScript
14 lines
No EOL
3.1 KiB
JavaScript
|
|
(function(exports){'use strict';const SET_DIGEST_VALUE='lockscreen.passcode-lock.digest.value';const SET_DIGEST_SALT='lockscreen.passcode-lock.digest.salt';const SET_DIGEST_ITERATIONS='lockscreen.passcode-lock.digest.iterations';const SET_DIGEST_ALGORITHM='lockscreen.passcode-lock.digest.algorithm';const DEFAULT_ALGORITHM='SHA-1';const DEFAULT_ITERATIONS=1000;const PBKDF2_OUTPUT_LENGTH=160;function _encode(str){return new TextEncoder('utf-8').encode(str);}
|
|
function _toTypedArray(obj){var a=[];for(var key of Object.keys(obj)){a.push(obj[key]);}
|
|
return new Uint8Array(a);}
|
|
function _deriveBits(pwKey,salt,iterations,algorithm){var params={name:'PBKDF2',hash:algorithm,salt:salt,iterations:iterations};return crypto.subtle.deriveBits(params,pwKey,PBKDF2_OUTPUT_LENGTH);}
|
|
function _makeDigest(pass,salt,iterations,algorithm){var bytes=_encode(pass);var promise=crypto.subtle.importKey('raw',bytes,'PBKDF2',false,['deriveBits']);promise=promise.then((pwKey)=>{return _deriveBits(pwKey,salt,iterations,algorithm);});promise=promise.catch((error)=>{console.error('PasscodeHelper: _derive_bits() failed!',error);throw error;});return promise;}
|
|
function setPasscode(newPass){var salt=crypto.getRandomValues(new Uint8Array(8));var promise=_makeDigest(newPass,salt,DEFAULT_ITERATIONS,DEFAULT_ALGORITHM);promise=promise.then((digest)=>{return _storeNewPasscode(digest,salt);});promise=promise.catch((error)=>{console.error('PasscodeHelper: Could not make digest:',error);throw error;});return promise;}
|
|
function _storeNewPasscode(digest,salt){var digestUint8=new Uint8Array(digest);var newSettings={[SET_DIGEST_SALT]:salt,[SET_DIGEST_VALUE]:digestUint8,[SET_DIGEST_ITERATIONS]:DEFAULT_ITERATIONS,[SET_DIGEST_ALGORITHM]:DEFAULT_ALGORITHM,};var lock=navigator.mozSettings.createLock();var req=lock.set(newSettings);return req.then(()=>{return digestUint8;},(error)=>{console.error('PasscodeHelper: Couldnt store new digest',error);throw error;});}
|
|
function checkPasscode(testPass){var lock=navigator.mozSettings.createLock();var storedParams=Promise.all([lock.get(SET_DIGEST_SALT),lock.get(SET_DIGEST_ITERATIONS),lock.get(SET_DIGEST_ALGORITHM),lock.get(SET_DIGEST_VALUE)]);return storedParams.then((values)=>{return _makeAndCompare(...values,testPass);}).catch((error)=>{console.error('PasscodeHelper: Couldnt get digest Settings:',error);throw error;});}
|
|
function _makeAndCompare(salt,iterations,algorithm,storedDigest,testPass){var _salt=_toTypedArray(salt[SET_DIGEST_SALT]);var _iterations=iterations[SET_DIGEST_ITERATIONS];var _algorithm=algorithm[SET_DIGEST_ALGORITHM];var _storedDigest=_toTypedArray(storedDigest[SET_DIGEST_VALUE]);var promise=_makeDigest(testPass,_salt,_iterations,_algorithm);promise=promise.then((digest)=>{var typedDigest=new Uint8Array(digest);return _compareDigests(_storedDigest,typedDigest);});promise=promise.catch((error)=>{console.error('PasscodeHelper: Couldnt create digest',error);throw error;});return promise;}
|
|
function _compareDigests(buf1,buf2){if(buf1.byteLength!==buf2.byteLength){return false;}
|
|
for(var i=0;i<buf1.byteLength;i++){if(buf1[i]!==buf2[i]){return false;}}
|
|
return true;}
|
|
exports.PasscodeHelper={set:setPasscode,check:checkPasscode};})(this); |