floDapps, floCloudAPI: Secure private key

- Store AES-encrypted private key in memory. (exploring memory of browser will not have raw private key)
- floDapps lock/unlock (in user): locks or unlock the private key (ie, lock= Password required, unlock= password not required in returning private key)
- floDapps.launchStartUp now accepts options object
- to lock the private key on startup, pass {lock_key: true} in options objects of launchStartUp
This commit is contained in:
sairajzero 2022-07-17 17:02:27 +05:30
parent 5ab0bc36f0
commit b80bd43313
3 changed files with 34 additions and 20 deletions

View File

@ -1,4 +1,4 @@
(function(EXPORTS) { //floCloudAPI v2.4.0 (function(EXPORTS) { //floCloudAPI v2.4.1
/* FLO Cloud operations to send/request application data*/ /* FLO Cloud operations to send/request application data*/
'use strict'; 'use strict';
const floCloudAPI = EXPORTS; const floCloudAPI = EXPORTS;
@ -10,7 +10,7 @@
callback: (d, e) => console.debug(d, e) callback: (d, e) => console.debug(d, e)
}; };
var user_id, user_public, user_private; var user_id, user_public, user_private, aes_key;
const user = { const user = {
get id() { get id() {
if (!user_id) if (!user_id)
@ -25,10 +25,10 @@
sign(msg) { sign(msg) {
if (!user_private) if (!user_private)
throw "User not set"; throw "User not set";
return floCrypto.signData(msg, user_private); return floCrypto.signData(msg, Crypto.AES.decrypt(user_private, aes_key));
}, },
clear() { clear() {
user_id = user_public = user_private = undefined; user_id = user_public = user_private = aes_key = undefined;
} }
} }
@ -45,14 +45,17 @@
user: { user: {
set: priv => { set: priv => {
if (!priv) if (!priv)
user_id = user_public = user_private = undefined; user_id = user_public = user_private = aes_key = undefined;
else { else {
user_public = floCrypto.getPubKeyHex(priv); user_public = floCrypto.getPubKeyHex(priv);
user_id = floCrypto.getFloID(user_public); user_id = floCrypto.getFloID(user_public);
if (!user_public || !user_id || !floCrypto.verifyPrivKey(priv, user_id)) if (!user_public || !user_id || !floCrypto.verifyPrivKey(priv, user_id))
user_id = user_public = user_private = undefined; user_id = user_public = user_private = aes_key = undefined;
else else {
user_private = priv; let n = floCrypto.randInt(12, 20);
aes_key = floCrypto.randString(n);
user_private = Crypto.AES.encrypt(priv, aes_key);
}
} }
}, },
get: () => user get: () => user

View File

@ -1,4 +1,4 @@
(function(EXPORTS) { //floDapps v2.3.0 (function(EXPORTS) { //floDapps v2.3.1
/* General functions for FLO Dapps*/ /* General functions for FLO Dapps*/
'use strict'; 'use strict';
const floDapps = EXPORTS; const floDapps = EXPORTS;
@ -11,12 +11,12 @@
adminID: floGlobals.adminID adminID: floGlobals.adminID
}; };
var raw_user_private; //private variable inside capsule var user_priv_raw, aes_key, user_priv_wrap; //private variable inside capsule
const raw_user = { const raw_user = {
get private() { get private() {
if (!raw_user_private) if (!user_priv_raw)
throw "User not logged in"; throw "User not logged in";
return raw_user_private; return Crypto.AES.decrypt(user_priv_raw, aes_key);
} }
} }
@ -38,14 +38,21 @@
else if (user_private instanceof Function) else if (user_private instanceof Function)
return user_private(); return user_private();
else else
return user_private; return Crypto.AES.decrypt(user_private, aes_key);
}, },
get db_name() { get db_name() {
return "floDapps#" + user.id; return "floDapps#" + user.id;
}, },
lock() {
user_private = user_priv_wrap;
},
async unlock() {
if (await user.private === raw_user.private)
user_private = user_priv_raw;
},
clear() { clear() {
user_id = user_public = user_private = undefined; user_id = user_public = user_private = undefined;
raw_user_private = undefined; user_priv_raw = aes_key = undefined;
delete user.contacts; delete user.contacts;
delete user.pubKeys; delete user.pubKeys;
delete user.messages; delete user.messages;
@ -233,7 +240,7 @@
resolve(inputVal) resolve(inputVal)
}); });
function getCredentials(invisible_key) { function getCredentials(lock_key) {
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => { const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
var promises = [] var promises = []
@ -325,10 +332,14 @@
user_public = floCrypto.getPubKeyHex(privKey); user_public = floCrypto.getPubKeyHex(privKey);
user_id = floCrypto.getFloID(privKey); user_id = floCrypto.getFloID(privKey);
floCloudAPI.user = privKey; //Set user for floCloudAPI floCloudAPI.user = privKey; //Set user for floCloudAPI
if (!invisible_key) user_priv_wrap = () => checkIfPinRequired(key);
user_private = privKey; let n = floCrypto.randInt(12, 20);
aes_key = floCrypto.randString(n);
user_priv_raw = Crypto.AES.encrypt(privKey, aes_key);
if (!lock_key)
user_private = user_priv_raw;
else else
user_private = () => checkIfPinRequired(key); user_private = user_priv_wrap;
resolve('Login Credentials loaded successful') resolve('Login Credentials loaded successful')
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -388,7 +399,7 @@
}) })
}); });
let p2 = new Promise((res, rej) => { let p2 = new Promise((res, rej) => {
callAndLog(getCredentials(options.invisible_key)).then(r => { callAndLog(getCredentials(options.lock_key)).then(r => {
callAndLog(initUserDB()).then(r => { callAndLog(initUserDB()).then(r => {
callAndLog(loadUserDB()) callAndLog(loadUserDB())
.then(r => res(true)) .then(r => res(true))

View File

@ -24,7 +24,7 @@
//floDapps.addStartUpFunction('Sample', Promised Function) //floDapps.addStartUpFunction('Sample', Promised Function)
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}}) //floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } ) //floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
floDapps.launchStartUp( /*{invisible_key: true}*/ ).then(result => { floDapps.launchStartUp( /*{lock_key: true}*/ ).then(result => {
console.log(result) console.log(result)
alert(`Welcome FLO_ID: ${myFloID}`) alert(`Welcome FLO_ID: ${myFloID}`)
//App functions.... //App functions....