Remove old v1 crypto functions & compatibility

This commit is contained in:
Grégory Soutadé 2020-08-29 17:10:47 +02:00
parent 5b9640e8cb
commit 4e7f5bc75c
7 changed files with 33 additions and 129 deletions

View File

@ -82,11 +82,7 @@ A sample configuration file is available _gpass.ini.sample_
Version Information Version Information
------------------- -------------------
Current version is 0.9. **(not compatible with 0.7)** Current version is 0.9.
Firefox will remove support for addons, so the gPass addon code is not supported since v0.8, please migrate to webextension.
Transition from v0.7 to v0.8 : **Please update your masterkey (even with the same one) to gain a security level of your passwords's wallet.**
License License

View File

@ -20,7 +20,6 @@
var browser = browser || chrome; var browser = browser || chrome;
var protocol_version = 4; var protocol_version = 4;
var account_url = null; var account_url = null;
var crypto_v2_logins_size = 0;
function _notification(message, data) function _notification(message, data)
{ {
@ -39,24 +38,16 @@ function _notification(message, data)
window.setTimeout(function() {browser.notifications.clear("gPass", function(){})}, 2000); window.setTimeout(function() {browser.notifications.clear("gPass", function(){})}, 2000);
} }
async function generate_request(domain, login, mkey, iv, old) async function generate_request(domain, login, mkey, iv)
{ {
if (old) var v = domain + ";" + login;
{ debug("will encrypt " + v);
var v = "@@" + domain + ";" + login; while ((v.length % 16))
debug("will encrypt " + v); v += "\0";
enc = encrypt_ecb(mkey, v); hash = await digest(v);
} v += hash.slice(8, 24);
else enc = encrypt_cbc(mkey, iv, v);
{
var v = domain + ";" + login;
debug("will encrypt " + v);
while ((v.length % 16))
v += "\0";
hash = await digest(v);
v += hash.slice(8, 24);
enc = encrypt_cbc(mkey, iv, v);
}
return enc; return enc;
} }
@ -80,35 +71,18 @@ async function ask_server(logins, domain, wdomain, mkey, sendResponse, options)
keys = ""; keys = "";
for(key_index=0, a=0; a<logins.length; a++, key_index++) for(key_index=0, a=0; a<logins.length; a++, key_index++)
{ {
enc = await generate_request(domain, logins[a], mkey, global_iv, 0); enc = await generate_request(domain, logins[a], mkey, global_iv);
keys += (keys.length != 0) ? "&" : ""; keys += (keys.length != 0) ? "&" : "";
keys += "k" + key_index + "=" + a2hex(enc); keys += "k" + key_index + "=" + a2hex(enc);
if (wdomain != "") if (wdomain != "")
{ {
enc = await generate_request(wdomain, logins[a], mkey, global_iv, 0); enc = await generate_request(wdomain, logins[a], mkey, global_iv);
keys += (keys.length != 0) ? "&" : ""; keys += (keys.length != 0) ? "&" : "";
keys += "k" + (++key_index) + "=" + a2hex(enc); keys += "k" + (++key_index) + "=" + a2hex(enc);
} }
} }
crypto_v2_logins_size = key_index;
if (await get_preference("crypto_v1_compatible"))
{
for(a=0; a<logins.length; a++, key_index++)
{
enc = await generate_request(domain, logins[a], mkey, global_iv, 1);
keys += (keys.length != 0) ? "&" : "";
keys += "k" + key_index + "=" + a2hex(enc);
if (wdomain != "")
{
enc = await generate_request(wdomain, logins[a], mkey, global_iv, 1);
keys += (keys.length != 0) ? "&" : "";
keys += "k" + (++key_index) + "=" + a2hex(enc);
}
}
}
debug("Keys " + keys); debug("Keys " + keys);
var gPassRequest = new XMLHttpRequest(); var gPassRequest = new XMLHttpRequest();
@ -213,20 +187,9 @@ async function ask_server(logins, domain, wdomain, mkey, sendResponse, options)
if (ciphered_password != "") if (ciphered_password != "")
{ {
debug("Ciphered password : " + ciphered_password); debug("Ciphered password : " + ciphered_password);
if (matched_key >= crypto_v2_logins_size) clear_password = await decrypt_cbc(mkey, global_iv, hex2a(ciphered_password));
// Crypto v1 clear_password = clear_password.replace(/\0*$/, "");
{ clear_password = clear_password.substr(3, clear_password.length);
clear_password = await decrypt_ecb(mkey, hex2a(ciphered_password));
// Remove trailing \0 and salt
clear_password = clear_password.replace(/\0*$/, "");
clear_password = clear_password.substr(0, clear_password.length-3);
}
else
{
clear_password = await decrypt_cbc(mkey, global_iv, hex2a(ciphered_password));
clear_password = clear_password.replace(/\0*$/, "");
clear_password = clear_password.substr(3, clear_password.length);
}
debug("Clear password " + clear_password); debug("Clear password " + clear_password);
} }
else else

View File

@ -11,8 +11,6 @@
<b>PBKDF2 level</b> Number of iterations used to derivate master key <input id="pbkdf2" type="number"/><br /> <b>PBKDF2 level</b> Number of iterations used to derivate master key <input id="pbkdf2" type="number"/><br />
<br/> <br/>
<br/> <br/>
<b>Crypto v1 compatible </b> Compatible with old crypto schema (AES ECB). Use it for encrypted passwords with server <= 0.7 <input id="crypto_v1_compatible" type="checkbox"/><br />
<br/>
<input type="button" id="save" value="Save"/> <input type="button" id="save" value="Save"/>
<script type="text/javascript" src="options.js"> <script type="text/javascript" src="options.js">

View File

@ -1,16 +1,14 @@
var default_preferences = {"pbkdf2_level": 1000, var default_preferences = {"pbkdf2_level": 1000,
"account_url": "https://gpass-demo.soutade.fr/demo", "account_url": "https://gpass-demo.soutade.fr/demo"
"crypto_v1_compatible": true}; };
function save() { function save() {
var account_url = document.getElementById('account_url').value; var account_url = document.getElementById('account_url').value;
var pbkdf2 = document.getElementById('pbkdf2').value; var pbkdf2 = document.getElementById('pbkdf2').value;
var crypto_v1_compatible = document.getElementById('crypto_v1_compatible').checked;
chrome.storage.local.set({ chrome.storage.local.set({
'account_url': account_url, 'account_url': account_url,
'pbkdf2': pbkdf2, 'pbkdf2': pbkdf2,
'crypto_v1_compatible': crypto_v1_compatible,
}, function() { }, function() {
alert('Saved'); alert('Saved');
}); });
@ -27,14 +25,8 @@ chrome.storage.local.get(null, function(prefs) {
else else
pbkdf2 = prefs['pbkdf2_level']; pbkdf2 = prefs['pbkdf2_level'];
if (!prefs.hasOwnProperty("crypto_v1_compatible"))
crypto_v1_compatible = default_preferences['crypto_v1_compatible'];
else
crypto_v1_compatible = prefs['crypto_v1_compatible'];
document.getElementById('account_url').value = account_url; document.getElementById('account_url').value = account_url;
document.getElementById('pbkdf2').value = pbkdf2; document.getElementById('pbkdf2').value = pbkdf2;
document.getElementById('crypto_v1_compatible').checked = crypto_v1_compatible;
}); });
document.getElementById('save').addEventListener("click", save); document.getElementById('save').addEventListener("click", save);

View File

@ -20,7 +20,6 @@
var browser = browser || chrome; var browser = browser || chrome;
var protocol_version = 4; var protocol_version = 4;
var account_url = null; var account_url = null;
var crypto_v2_logins_size = 0;
function _notification(message, data) function _notification(message, data)
{ {
@ -39,24 +38,16 @@ function _notification(message, data)
window.setTimeout(function() {browser.notifications.clear("gPass", function(){})}, 2000); window.setTimeout(function() {browser.notifications.clear("gPass", function(){})}, 2000);
} }
async function generate_request(domain, login, mkey, iv, old) async function generate_request(domain, login, mkey, iv)
{ {
if (old) var v = domain + ";" + login;
{ debug("will encrypt " + v);
var v = "@@" + domain + ";" + login; while ((v.length % 16))
debug("will encrypt " + v); v += "\0";
enc = encrypt_ecb(mkey, v); hash = await digest(v);
} v += hash.slice(8, 24);
else enc = encrypt_cbc(mkey, iv, v);
{
var v = domain + ";" + login;
debug("will encrypt " + v);
while ((v.length % 16))
v += "\0";
hash = await digest(v);
v += hash.slice(8, 24);
enc = encrypt_cbc(mkey, iv, v);
}
return enc; return enc;
} }
@ -80,35 +71,18 @@ async function ask_server(logins, domain, wdomain, mkey, sendResponse, options)
keys = ""; keys = "";
for(key_index=0, a=0; a<logins.length; a++, key_index++) for(key_index=0, a=0; a<logins.length; a++, key_index++)
{ {
enc = await generate_request(domain, logins[a], mkey, global_iv, 0); enc = await generate_request(domain, logins[a], mkey, global_iv);
keys += (keys.length != 0) ? "&" : ""; keys += (keys.length != 0) ? "&" : "";
keys += "k" + key_index + "=" + a2hex(enc); keys += "k" + key_index + "=" + a2hex(enc);
if (wdomain != "") if (wdomain != "")
{ {
enc = await generate_request(wdomain, logins[a], mkey, global_iv, 0); enc = await generate_request(wdomain, logins[a], mkey, global_iv);
keys += (keys.length != 0) ? "&" : ""; keys += (keys.length != 0) ? "&" : "";
keys += "k" + (++key_index) + "=" + a2hex(enc); keys += "k" + (++key_index) + "=" + a2hex(enc);
} }
} }
crypto_v2_logins_size = key_index;
if (await get_preference("crypto_v1_compatible"))
{
for(a=0; a<logins.length; a++, key_index++)
{
enc = await generate_request(domain, logins[a], mkey, global_iv, 1);
keys += (keys.length != 0) ? "&" : "";
keys += "k" + key_index + "=" + a2hex(enc);
if (wdomain != "")
{
enc = await generate_request(wdomain, logins[a], mkey, global_iv, 1);
keys += (keys.length != 0) ? "&" : "";
keys += "k" + (++key_index) + "=" + a2hex(enc);
}
}
}
debug("Keys " + keys); debug("Keys " + keys);
var gPassRequest = new XMLHttpRequest(); var gPassRequest = new XMLHttpRequest();
@ -213,20 +187,9 @@ async function ask_server(logins, domain, wdomain, mkey, sendResponse, options)
if (ciphered_password != "") if (ciphered_password != "")
{ {
debug("Ciphered password : " + ciphered_password); debug("Ciphered password : " + ciphered_password);
if (matched_key >= crypto_v2_logins_size) clear_password = await decrypt_cbc(mkey, global_iv, hex2a(ciphered_password));
// Crypto v1 clear_password = clear_password.replace(/\0*$/, "");
{ clear_password = clear_password.substr(3, clear_password.length);
clear_password = await decrypt_ecb(mkey, hex2a(ciphered_password));
// Remove trailing \0 and salt
clear_password = clear_password.replace(/\0*$/, "");
clear_password = clear_password.substr(0, clear_password.length-3);
}
else
{
clear_password = await decrypt_cbc(mkey, global_iv, hex2a(ciphered_password));
clear_password = clear_password.replace(/\0*$/, "");
clear_password = clear_password.substr(3, clear_password.length);
}
debug("Clear password " + clear_password); debug("Clear password " + clear_password);
} }
else else

View File

@ -11,8 +11,6 @@
<b>PBKDF2 level</b> Number of iterations used to derivate master key <input id="pbkdf2" type="number"/><br /> <b>PBKDF2 level</b> Number of iterations used to derivate master key <input id="pbkdf2" type="number"/><br />
<br/> <br/>
<br/> <br/>
<b>Crypto v1 compatible </b> Compatible with old crypto schema (AES ECB). Use it for encrypted passwords with server <= 0.7 <input id="crypto_v1_compatible" type="checkbox"/><br />
<br/>
<input type="button" id="save" value="Save"/> <input type="button" id="save" value="Save"/>
<script type="text/javascript" src="options.js"> <script type="text/javascript" src="options.js">

View File

@ -1,16 +1,14 @@
var default_preferences = {"pbkdf2_level": 1000, var default_preferences = {"pbkdf2_level": 1000,
"account_url": "https://gpass-demo.soutade.fr/demo", "account_url": "https://gpass-demo.soutade.fr/demo"
"crypto_v1_compatible": true}; };
function save() { function save() {
var account_url = document.getElementById('account_url').value; var account_url = document.getElementById('account_url').value;
var pbkdf2 = document.getElementById('pbkdf2').value; var pbkdf2 = document.getElementById('pbkdf2').value;
var crypto_v1_compatible = document.getElementById('crypto_v1_compatible').checked;
browser.storage.local.set({ browser.storage.local.set({
"account_url":account_url, "account_url":account_url,
"pbkdf2_level":pbkdf2, "pbkdf2_level":pbkdf2,
"crypto_v1_compatible": crypto_v1_compatible,
}) })
.then(function ok() { alert("Saved"); }, .then(function ok() { alert("Saved"); },
function err() { alert("Cannot save your preferences");} function err() { alert("Cannot save your preferences");}
@ -21,7 +19,6 @@ function restoreOptions()
{ {
document.getElementById('account_url').value = default_preferences['account_url']; document.getElementById('account_url').value = default_preferences['account_url'];
document.getElementById('pbkdf2').value = default_preferences['pbkdf2_level']; document.getElementById('pbkdf2').value = default_preferences['pbkdf2_level'];
document.getElementById('crypto_v1_compatible').checked = default_preferences["crypto_v1_compatible"];
browser.storage.local.get().then( browser.storage.local.get().then(
function(prefs) function(prefs)
@ -31,9 +28,6 @@ function restoreOptions()
if (prefs.hasOwnProperty("pbkdf2_level")) if (prefs.hasOwnProperty("pbkdf2_level"))
document.getElementById('pbkdf2').value = prefs["pbkdf2_level"]; document.getElementById('pbkdf2').value = prefs["pbkdf2_level"];
if (prefs.hasOwnProperty("crypto_v1_compatible"))
document.getElementById('crypto_v1_compatible').checked = prefs["crypto_v1_compatible"];
} }
); );
} }