Merge branch 'master' of soutade.fr:gpass

This commit is contained in:
Grégory Soutadé 2013-10-24 19:25:32 +02:00
commit 0991f1be69
7 changed files with 920 additions and 159 deletions

BIN
ressources/usage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
ressources/usage.xcf Normal file

Binary file not shown.

View File

@ -171,28 +171,28 @@ function load_database($user)
return $db;
}
function add_entry($user, $mkey, $url, $login, $password)
function add_entry($user, $login, $password)
{
$db = load_database($user);
if ($db == null) return false;
$password = encrypt($mkey, trim($password), true);
$login = encrypt($mkey, "@@" . trim($url) . ";" . trim($login), false);
if ($password == null || $login == null)
if ($db == null)
{
echo "Unknown user";
return false;
}
$count = $db->querySingle("SELECT COUNT(*) FROM gpass WHERE login='" . $login . "'");
if ($count != 0)
{
echo "<div class=\"error\">Entry already exists</div>";
echo "Entry already exists";
return false;
}
$result = $db->query("INSERT INTO gpass ('login', 'password') VALUES ('" . $login . "', '" . $password . "')");
echo "OK";
return true;
}
@ -200,10 +200,16 @@ function delete_entry($user, $login)
{
$db = load_database($user);
if ($db == null) return false;
if ($db == null)
{
echo "Unknown user";
return false;
}
$db->query("DELETE FROM gpass WHERE login='" . $login . "'");
echo "OK";
return true;
}
@ -215,7 +221,7 @@ function update_entry($user, $mkey, $old_login, $url, $login, $password)
return false;
}
function list_entries($user, $mkey)
function list_entries($user)
{
$db = load_database($user);
@ -223,46 +229,12 @@ function list_entries($user, $mkey)
$result = $db->query("SELECT * FROM gpass");
$res = array();
$valid_accounts = 0;
$total_accounts = 0;
while ($row = $result->fetchArray())
echo "entries\n";
while (($row = $result->fetchArray()))
{
$total_accounts++;
if ($mkey != "")
$login = decrypt($mkey, $row['login'], false);
else
$login = "";
if ($login[0] != '@' && $login[1] != '@')
{
$subres = array('login_ciph' => $row['login'],
'url' => '', 'login' => '',
'password' => $row['password'],
'ciphered' => 1);
array_push($res, $subres);
continue;
}
$login = substr($login, 2);
$sep = strpos($login, ';');
$url = substr($login, 0, $sep);
$login = substr($login, $sep+1);
$password = decrypt($mkey, $row['password'], true);
$subres = array('login_ciph' => $row['login'],
'url' => $url, 'login' => $login,
'password' => $password,
'ciphered' => 0);
array_push($res, $subres);
$valid_accounts++;
echo $row['login'] . ";" . $row['password'] . "\n";
}
return array($total_accounts-$valid_accounts, $res);
}
?>

145
server/index.php Executable file → Normal file
View File

@ -24,31 +24,8 @@ session_start();
$VIEW_CIPHERED_PASSWORDS=true;
$ADMIN_MODE=true;
$user = "";
$mkey = (isset($_POST['mkey'])) ? $_POST['mkey'] : "";
$user = (isset($_POST['user'])) ? $_POST['user'] : "";
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<link rel="stylesheet" type="text/css" href="ressources/gpass.css" />
<script src="ressources/jssha256.js"></script>
<script src="ressources/hmac.js"></script>
<script src="ressources/pkdbf2.js"></script>
<script src="ressources/gpass.js"></script>
<?php
global $user;
if ($user == "")
echo "<title>gPass : global Password</title>\n";
else
echo "<title>gPass : global Password - $user</title>\n";
?>
</head>
<body>
<?php
global $mkey;
if ($ADMIN_MODE && isset($_POST['create_user']))
{
if (create_user($_POST['user']))
@ -56,31 +33,44 @@ if ($ADMIN_MODE && isset($_POST['create_user']))
}
else
{
if (isset($_POST['add']))
add_entry($user, $mkey, $_POST['url'], $_POST['login'], $_POST['pwd']);
else if (isset($_POST['delete']))
delete_entry($user, $_POST['login_ciph']);
else if (isset($_POST['update']))
update_entry($user, $mkey, $_POST['login_ciph'], $_POST['url'], $_POST['login'], $_POST['pwd']);
}
?>
if (isset($_POST['get_passwords']) && isset($_POST['user']))
return list_entries($_POST['user']);
<div id="logo">
<a href="http://indefero.soutade.fr/p/gpass"><img src="ressources/gpass.png" alt="logo"/></a>
</div>
if (isset($_POST['add_entry']) && isset($_POST['user']) &&
isset($_POST['login']) && isset($_POST['password']))
return add_entry($_POST['user'], $_POST['login'], $_POST['password']);
if (isset($_POST['delete_entry']) && isset($_POST['user']) &&
isset($_POST['login']))
return delete_entry($_POST['user'], $_POST['login']);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<link rel="stylesheet" type="text/css" href="ressources/gpass.css" />
<script src="ressources/jsaes.js"></script>
<script src="ressources/jssha256.js"></script>
<script src="ressources/hmac.js"></script>
<script src="ressources/pkdbf2.js"></script>
<script src="ressources/gpass.js"></script>
<title>gPass : global Password</title>
</head>
<body onload="start();">
<div id="logo">
<a href="http://indefero.soutade.fr/p/gpass"><img src="ressources/gpass.png" alt="logo"/></a>
</div>
<div id="admin" <?php if (!$ADMIN_MODE) echo "style=\"display:none\"";?> >
<form method="post">
<input type="text" name="user"/> <input type="submit" name="create_user" value="Create user" onclick="return confirm('Are you sure want to create this user ?');"/>
</form>
</div>
<form method="post">
<input type="text" name="user"/> <input type="submit" name="create_user" value="Create user" onclick="return confirm('Are you sure want to create this user ?');"/>
</form>
</div>
<div id="user">
<form method="post" id="select_user">
<?php
global $user;
global $mkey;
$users = scandir("./users/");
$count = 0;
foreach($users as $u)
@ -93,7 +83,7 @@ if ($count == 0)
echo "<b>No user found</b><br/>\n";
else
{
echo '<b>User</b> <select id="selected_user" name="user">' . "\n";
echo "<b>User</b> <select id=\"selected_user\" name=\"user\" onchange=\"document.getElementById('master_key').value = ''\">" . "\n";
foreach($users as $u)
{
if (is_dir("./users/" . $u) && $u[0] != '_' && $u[0] != '.')
@ -106,56 +96,16 @@ else
}
}
echo "</select>\n";
echo ' <b>Master key </b> <input id="see_password" type="password" name="mkey"/>';
echo "<input name=\"see\" type=\"submit\" value=\"See\" onclick=\"if (document.getElementById('see_password').value == '') return true; a=document.getElementById('selected_user') ; return derive_mkey(a.options[a.selectedIndex].value, 'see_password') ;\"/>" . "\n";
echo ' <b>Master key </b> <input id="master_key" type="password" onkeypress="if (event.keyCode == 13) update_master_key();"/>';
echo "<input type=\"button\" value=\"See\" onclick=\"update_master_key();\" />" . "\n";
if (!isset($_SERVER['HTTPS']))
echo "<div id=\"addon_address\">Current addon address is : http://" . $_SERVER['SERVER_NAME'] . "/" . $user . "</div>\n";
else
echo "<div id=\"addon_address\">Current addon address is : https://" . $_SERVER['SERVER_NAME'] . "/" . $user . "</div>\n";
}
?>
</form>
<div id="passwords">
<?php
global $user;
global $mkey;
global $VIEW_UNCIPHERED_PASSWORDS;
if ($user != "")
{
$nb_unciphered = 0;
list($nb_ciphered, $entries) = list_entries($user, $mkey);
echo "<b>" . (count($entries) - $nb_ciphered) . " unciphered password(s)</b><br/>\n";
foreach($entries as $entry)
{
if ($entry['ciphered'] == 1) continue;
echo '<form method="post">' . "\n";
echo '<input type="hidden" name="user" value="' . $user . '"/>';
echo '<input type="hidden" name="mkey" value="' . $mkey . '"/>';
echo '<input type="hidden" name="login_ciph" value="' . $entry['login_ciph'] . '"/>';
echo 'URL <input type="text" name="url" value="' . $entry['url'] . '"/>';
echo 'login <input type="text" name="login" value="' . $entry['login'] . '"/>';
echo 'password <input type="text" name="pwd" value="' . $entry['password'] . '"/>';
echo '<input type="submit" name="delete" value="Delete" onclick="return confirm(\'Are you sure want to delete this password ?\');"/>';
echo '<input type="submit" name="update" value="Update" onclick="return confirm(\'Are you sure want to update this password ?\');"/>';
echo '</form>' . "\n";
}
echo "<br/><br/>\n";
echo "<b>$nb_ciphered ciphered password(s)</b><br/>\n";
if ($VIEW_CIPHERED_PASSWORDS)
{
foreach($entries as $entry)
{
if ($entry['ciphered'] == 0) continue;
echo '<form method="post">' . "\n";
echo '<input type="hidden" name="user" value="' . $user . '"/>';
echo '<input type="hidden" name="mkey" value="' . $mkey . '"/>';
echo '<input class="hash" type="text" name="login_ciph" value="' . $entry['login_ciph'] . '"/>';
echo '<input class="hash" type="text" name="pwd" value="' . $entry['password'] . '"/>';
echo '<input type="submit" name="delete" value="Delete" onclick="return confirm(\'Are you sure want to delete this password ?\');"/>';
echo '</form>' . "\n";
}
}
}
?>
</div>
<div id="add_new_password">
<?php
@ -164,19 +114,16 @@ if ($user != "")
if ($user != "")
{
echo "<b>Add a new password</b><br/>\n";
echo '<form method="post">' . "\n";
echo '<input type="hidden" name="user" value="' . $user . '"/>';
echo 'URL <input id="new_url" type="text" name="url"/>';
echo 'URL <input type="text" name="url"/>';
echo 'login <input type="text" name="login" />';
echo 'password <input id="new_password" type="text" name="pwd"/>';
echo 'master key <input id="new_mkey" type="password" name="mkey"/>';
echo 'password <input id="new_password" type="text" name="password"/>';
echo 'master key <input type="password" name="mkey" onkeypress="if (event.keyCode == 13) add_password();"/>';
echo '<input type="button" value="Generate password" onClick="generate_password();"/>';
echo "<input type=\"submit\" name=\"add\" value=\"Add\" onclick=\"a = document.getElementById('new_url') ; a.value = url_domain(a.value); return derive_mkey('$user', 'new_mkey') ;\"/>";
echo '</form>' . "\n";
echo "<input type=\"button\" name=\"add\" value=\"Add\" onclick=\"add_password();\"/>";
}
?>
</div>
</div>
</body>
</html>
</html>

View File

@ -31,9 +31,11 @@ body {
border-color:green;
padding : 15px;
margin : 15px;
text-align:center;
}
#user input {
margin-left : 15px;
margin-right : 30px;
margin-top : 10px;
margin-bottom : 10px;
@ -51,6 +53,12 @@ body {
margin : 15px;
}
#addon_address {
padding:10px;
text-align:center;
font-size:xx-large;
}
.hash {
width : 700px;
}

View File

@ -31,6 +31,26 @@ parseUri.options = {
}
};
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, "");
};
}
// Array Remove - By John Resig (MIT Licensed)
// http://stackoverflow.com/questions/500606/javascript-array-delete-elements
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
Element.prototype.removeAllChilds = function() {
while (this.hasChildNodes())
this.removeChild(this.childNodes[0]);
};
function generate_password()
{
// symbols 32 - 47 / 58 - 64 / 91 - 96 / 123 - 126
@ -72,20 +92,543 @@ function a2hex(str) {
return hex;
}
function derive_mkey(user, mkey_target)
function derive_mkey(user, mkey)
{
mkey_target = document.getElementById(mkey_target) ;
mkey = mkey_target.value;
if (mkey.length == 0)
{
alert('Empty master key');
return false;
}
url = url_domain(document.URL) + "/" + user;
mkey = a2hex(pkdbf2(mkey, url, 1000, 256/8));
mkey_target.value = mkey;
return mkey;
}
var passwords;
var current_user = "";
var current_mkey = "";
function PasswordEntry (ciphered_login="", ciphered_password="") {
this.ciphered_login = ciphered_login;
this.ciphered_password = ciphered_password;
this.unciphered = false;
this.clear_url = "";
this.clear_login = "";
this.clear_password = "";
this.masterkey = "";
this.decrypt = function(masterkey)
{
if (masterkey == this.masterkey && this.unciphered == true)
return true;
if (masterkey == "" || this.unciphered == true)
return false;
aes = new AES();
a_masterkey = aes.init(hex2a(masterkey));
login = aes.decryptLongString(hex2a(this.ciphered_login), a_masterkey);
login = login.replace(/\0*$/, "");
if (login.indexOf("@@") != 0)
{
aes.finish();
return false;
}
// Remove @@
login = login.substring(2);
infos = login.split(";");
this.clear_url = infos[0];
this.clear_login = infos[1];
this.clear_password = aes.decryptLongString(hex2a(this.ciphered_password), a_masterkey);
this.unciphered = true;
this.masterkey = masterkey;
aes.finish();
// Remove salt
this.clear_password = this.clear_password.replace(/\0*$/, "");
this.clear_password = this.clear_password.substr(0, this.clear_password.length-3);
return true;
}
this.isUnciphered = function(masterkey)
{
return (this.unciphered == true && masterkey == this.masterkey && masterkey != "")
}
this.isCiphered = function(masterkey)
{
return !(this.isUnciphered(masterkey));
}
}
function list_all_entries(user)
{
passwords = new Array();
req = new XMLHttpRequest();
req.addEventListener("load", function(evt) {
entries = this.responseText.split("\n");
if (entries[0] == "entries")
{
for(i=1; i<entries.length; i++)
{
if (entries[i] == "") continue;
entry = entries[i].split(";");
passwords.push(new PasswordEntry(entry[0], entry[1]));
}
}
}, false);
req.open("POST", document.documentURI, false);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send("get_passwords=1&user=" + user);
}
function update_stats()
{
nb_ciphered_passwords = 0;
nb_unciphered_passwords = 0;
for(i=0; i<passwords.length; i++)
{
if (passwords[i].isUnciphered(current_mkey))
nb_unciphered_passwords++;
else
nb_ciphered_passwords++;
}
div = document.getElementById("nb_unciphered_passwords");
div.removeAllChilds();
text = document.createElement("b");
text.appendChild(document.createTextNode(nb_unciphered_passwords + " unciphered password(s)"));
div.appendChild(text);
div.appendChild(document.createElement("br"));
div.appendChild(document.createElement("br"));
div = document.getElementById("nb_ciphered_passwords");
div.removeAllChilds();
text = document.createElement("b");
text.appendChild(document.createTextNode(nb_ciphered_passwords + " ciphered password(s)"));
div.appendChild(text);
div.appendChild(document.createElement("br"));
div.appendChild(document.createElement("br"));
}
function change_master_key()
{
for(i=0; i<passwords.length; i++)
passwords[i].decrypt(current_mkey);
password_div = document.getElementById("passwords");
password_div.removeAllChilds();
div = document.createElement("div");
div.setAttribute("id", "nb_unciphered_passwords");
password_div.appendChild(div);
for(i=0; i<passwords.length; i++)
{
if (passwords[i].isUnciphered(current_mkey))
{
div = document.createElement("div");
div.setAttribute("id", "unciph_entry_" + i);
div.setAttribute("class", "password");
ciph_login = document.createElement("input");
ciph_login.setAttribute("name", "ciphered_login");
ciph_login.setAttribute("type", "hidden");
ciph_login.setAttribute("login", passwords[i].ciphered_login);
div.appendChild(ciph_login);
div.appendChild(document.createTextNode("URL"));
url = document.createElement("input");
url.setAttribute("type", "text");
url.setAttribute("name", "url");
url.setAttribute("value", passwords[i].clear_url);
div.appendChild(url);
div.appendChild(document.createTextNode("login"));
login = document.createElement("input");
login.setAttribute("type", "text");
login.setAttribute("name", "login");
login.setAttribute("value", passwords[i].clear_login);
div.appendChild(login);
div.appendChild(document.createTextNode("password"));
password = document.createElement("input");
password.setAttribute("type", "text");
password.setAttribute("name", "password");
password.setAttribute("value", passwords[i].clear_password);
div.appendChild(password);
delete_button = document.createElement("input");
delete_button.setAttribute("type", "button");
delete_button.setAttribute("value", "Delete");
delete_button.setAttribute("onclick", "delete_entry(\"unciph_entry_" + i + "\");");
div.appendChild(delete_button);
update_button = document.createElement("input");
update_button.setAttribute("type", "button");
update_button.setAttribute("value", "Update");
update_button.setAttribute("onclick", "update_entry(\"unciph_entry_" + i + "\");");
div.appendChild(update_button);
password_div.appendChild(div);
}
}
div = document.createElement("div");
div.setAttribute("id", "nb_ciphered_passwords");
password_div.appendChild(div);
for(i=0; i<passwords.length; i++)
{
if (passwords[i].isCiphered(current_mkey))
{
div = document.createElement("div");
div.setAttribute("id", "ciph_entry_" + i);
div.setAttribute("class", "password");
ciph_login = document.createElement("input");
ciph_login.setAttribute("name", "ciphered_login");
ciph_login.setAttribute("type", "hidden");
ciph_login.setAttribute("login", passwords[i].ciphered_login);
div.appendChild(ciph_login);
div.appendChild(document.createTextNode("URL"));
url = document.createElement("input");
url.setAttribute("class", "hash");
url.setAttribute("type", "text");
url.setAttribute("name", "URL");
url.setAttribute("value", passwords[i].ciphered_login);
div.appendChild(url);
div.appendChild(document.createTextNode("password"));
password = document.createElement("input");
password.setAttribute("class", "hash");
password.setAttribute("type", "text");
password.setAttribute("name", "password");
password.setAttribute("value", passwords[i].ciphered_password);
div.appendChild(password);
delete_button = document.createElement("input");
delete_button.setAttribute("type", "button");
delete_button.setAttribute("value", "Delete");
delete_button.setAttribute("onclick", "delete_entry(\"ciph_entry_" + i + "\");");
div.appendChild(delete_button);
password_div.appendChild(div);
}
}
update_stats();
}
function update_master_key()
{
user = select_widget.options[select_widget.selectedIndex].value;
if (user != current_user)
{
current_user = user;
document.title = "gPass : global Password - " + current_user;
list_all_entries(current_user);
addon_address = document.getElementById("addon_address");
addon_address.removeAllChilds();
addon_address.appendChild(document.createTextNode("Current addon address is : " + document.documentURI + current_user));
}
current_mkey = document.getElementById("master_key").value;
if (current_mkey != "")
current_mkey = derive_mkey(current_user, current_mkey);
change_master_key();
}
function start()
{
select_widget = document.getElementById('selected_user') ;
if (select_widget == null) return;
return update_master_key();
}
function add_password_server(user, pentry)
{
var ok = false;
req = new XMLHttpRequest();
req.addEventListener("load", function(evt) {
resp = this.responseText;
if (resp == "OK")
ok = true;
else
alert(resp);
}, false);
req.open("POST", document.documentURI, false);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send("add_entry=1&user=" + user + "&login=" + pentry.ciphered_login + "&password=" + pentry.ciphered_password);
return ok;
}
function construct_pentry(user, url, password, login, mkey, derive_masterkey)
{
var ret = null;
if (url == "")
{
alert("URL is empty");
return ret;
}
if (login == "")
{
alert("Login is empty");
return ret;
}
if (password == "")
{
alert("Password is empty");
return ret;
}
if (mkey == "")
{
alert("Master key is empty");
return ret;
}
if (derive_masterkey)
mkey = derive_mkey(current_user, mkey);
for(i=0; i<passwords.length; i++)
{
p = passwords[i];
if (p.clear_url == url &&
p.clear_password == password &&
p.clear_login == login &&
p.masterkey == mkey)
{
alert("Entry already exists");
return ret;
}
}
ciphered_login = "@@" + url + ";" + login;
// Add salt
for(i=0; i<3; i++)
{
password += String.fromCharCode((Math.random() * 128)+1);
}
ciphered_password = password;
aes = new AES();
a_masterkey = aes.init(hex2a(mkey));
ciphered_login = a2hex(aes.encryptLongString(ciphered_login, a_masterkey));
ciphered_password = a2hex(aes.encryptLongString(ciphered_password, a_masterkey));
pentry = new PasswordEntry(ciphered_login, ciphered_password);
pentry.unciphered = true;
pentry.clear_url = url;
pentry.clear_login = login;
pentry.clear_password = password.substr(0, password.length-3);
pentry.masterkey = mkey;
return pentry;
}
function remove_password_server(user, login)
{
var ok = false;
req = new XMLHttpRequest();
req.addEventListener("load", function(evt) {
resp = this.responseText;
if (resp == "OK")
ok = true;
else
alert(resp);
}, false);
req.open("POST", document.documentURI, false);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send("delete_entry=1&user=" + user + "&login=" + login);
return ok;
}
function add_password()
{
var url = "";
var login = "";
var password = "";
var mkey = "";
div = document.getElementById("add_new_password");
inputs = div.getElementsByTagName("input");
for(i=0; i<inputs.length; i++)
{
if (inputs[i].getAttribute("name") == "url")
url = url_domain(inputs[i].value);
else if (inputs[i].getAttribute("name") == "login")
login = inputs[i].value.trim();
else if (inputs[i].getAttribute("name") == "password")
password = inputs[i].value.trim();
else if (inputs[i].getAttribute("name") == "mkey")
mkey = inputs[i].value;
}
pentry = construct_pentry(current_user, url, password, login, mkey, true)
if (pentry == null) return;
res = add_password_server(current_user, pentry);
if (!res) return false;
current_mkey = pentry.masterkey;
passwords.push(pentry);
change_master_key();
for(i=0; i<inputs.length; i++)
{
if (inputs[i].getAttribute("type") == "text" ||
inputs[i].getAttribute("type") == "password")
inputs[i].value = "";
}
return true;
}
}
function delete_entry(entry_number)
{
entry = document.getElementById(entry_number);
if (entry == null) {
alert(entry_number + " not found");
return;
}
inputs = entry.getElementsByTagName("input");
var ciphered_login = null;
for(i=0; i<inputs.length; i++)
{
if (inputs[i].getAttribute("name") == "ciphered_login")
{
ciphered_login = inputs[i];
break;
}
}
if (ciphered_login == null)
{
alert("Widget not found");
return;
}
var found = -1;
for(i=0; i<passwords.length; i++)
{
if (passwords[i].ciphered_login == ciphered_login.getAttribute("login"))
{
found = i;
break;
}
}
if (found == -1)
{
alert("Password not found int database");
return;
}
if(!confirm("Are you sure want to delete this entry ?"))
return;
ok = remove_password_server(current_user, ciphered_login.getAttribute("login"));
if (!ok) return;
parent = ciphered_login.parentNode;
parent.removeAllChilds();
passwords.remove(found);
update_stats();
}
function update_entry(entry_number)
{
var url = "";
var login = "";
var password = "";
var mkey = "";
var ciphered_login;
entry = document.getElementById(entry_number);
if (entry == null) {
alert(entry_number + " not found");
return;
}
inputs = entry.getElementsByTagName("input");
var ciphered_login = null;
for(i=0; i<inputs.length; i++)
{
if (inputs[i].getAttribute("name") == "url")
url = url_domain(inputs[i].value);
else if (inputs[i].getAttribute("name") == "login")
login = inputs[i].value.trim();
else if (inputs[i].getAttribute("name") == "password")
password = inputs[i].value.trim();
else if (inputs[i].getAttribute("name") == "ciphered_login")
ciphered_login = inputs[i];
}
var found = -1;
for(i=0; i<passwords.length; i++)
{
if (passwords[i].ciphered_login == ciphered_login.getAttribute("login"))
{
found = i;
break;
}
}
if (found == -1)
{
alert("Password not found int database");
return;
}
if(!confirm("Are you sure want to update this entry ?"))
return;
pentry = construct_pentry(current_user, url, password, login, current_mkey, false);
if (pentry == null) return;
ok = remove_password_server(current_user, passwords[found].ciphered_login);
if (!ok) return;
ok = add_password_server(current_user, pentry);
if (!ok) return;
passwords[found] = pentry;
ciphered_login.setAttribute("login", pentry.ciphered_login);
alert("Entry updated");
}

291
server/ressources/jsaes.js Normal file
View File

@ -0,0 +1,291 @@
/*
* jsaes version 0.1 - Copyright 2006 B. Poettering
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
/*
* http://point-at-infinity.org/jsaes/
*
* This is a javascript implementation of the AES block cipher. Key lengths
* of 128, 192 and 256 bits are supported.
*
* The well-functioning of the encryption/decryption routines has been
* verified for different key lengths with the test vectors given in
* FIPS-197, Appendix C.
*
* The following code example enciphers the plaintext block '00 11 22 .. EE FF'
* with the 256 bit key '00 01 02 .. 1E 1F'.
*
* AES_Init();
*
* var block = new Array(16);
* for(var i = 0; i < 16; i++)
* block[i] = 0x11 * i;
*
* var key = new Array(32);
* for(var i = 0; i < 32; i++)
* key[i] = i;
*
* AES_ExpandKey(key);
* AES_Encrypt(block, key);
*
* AES_Done();
*
* Report bugs to: jsaes AT point-at-infinity.org
*
*/
/******************************************************************************/
/*
AES_Init: initialize the tables needed at runtime. Call this function
before the (first) key expansion.
*/
function AES_Init() {
AES_Sbox_Inv = new Array(256);
for(var i = 0; i < 256; i++)
AES_Sbox_Inv[AES_Sbox[i]] = i;
AES_ShiftRowTab_Inv = new Array(16);
for(var i = 0; i < 16; i++)
AES_ShiftRowTab_Inv[AES_ShiftRowTab[i]] = i;
AES_xtime = new Array(256);
for(var i = 0; i < 128; i++) {
AES_xtime[i] = i << 1;
AES_xtime[128 + i] = (i << 1) ^ 0x1b;
}
}
/*
AES_Done: release memory reserved by AES_Init. Call this function after
the last encryption/decryption operation.
*/
function AES_Done() {
delete AES_Sbox_Inv;
delete AES_ShiftRowTab_Inv;
delete AES_xtime;
}
/*
AES_ExpandKey: expand a cipher key. Depending on the desired encryption
strength of 128, 192 or 256 bits 'key' has to be a byte array of length
16, 24 or 32, respectively. The key expansion is done "in place", meaning
that the array 'key' is modified.
*/
function AES_ExpandKey(key) {
var kl = key.length, ks, Rcon = 1;
switch (kl) {
case 16: ks = 16 * (10 + 1); break;
case 24: ks = 16 * (12 + 1); break;
case 32: ks = 16 * (14 + 1); break;
default:
alert("AES_ExpandKey: Only key lengths of 16, 24 or 32 bytes allowed!");
}
for(var i = kl; i < ks; i += 4) {
var temp = key.slice(i - 4, i);
if (i % kl == 0) {
temp = new Array(AES_Sbox[temp[1]] ^ Rcon, AES_Sbox[temp[2]],
AES_Sbox[temp[3]], AES_Sbox[temp[0]]);
if ((Rcon <<= 1) >= 256)
Rcon ^= 0x11b;
}
else if ((kl > 24) && (i % kl == 16))
temp = new Array(AES_Sbox[temp[0]], AES_Sbox[temp[1]],
AES_Sbox[temp[2]], AES_Sbox[temp[3]]);
for(var j = 0; j < 4; j++)
key[i + j] = key[i + j - kl] ^ temp[j];
}
}
/*
AES_Encrypt: encrypt the 16 byte array 'block' with the previously
expanded key 'key'.
*/
function AES_Encrypt(block, key) {
var l = key.length;
AES_AddRoundKey(block, key.slice(0, 16));
for(var i = 16; i < l - 16; i += 16) {
AES_SubBytes(block, AES_Sbox);
AES_ShiftRows(block, AES_ShiftRowTab);
AES_MixColumns(block);
AES_AddRoundKey(block, key.slice(i, i + 16));
}
AES_SubBytes(block, AES_Sbox);
AES_ShiftRows(block, AES_ShiftRowTab);
AES_AddRoundKey(block, key.slice(i, l));
}
/*
AES_Decrypt: decrypt the 16 byte array 'block' with the previously
expanded key 'key'.
*/
function AES_Decrypt(block, key) {
var l = key.length;
AES_AddRoundKey(block, key.slice(l - 16, l));
AES_ShiftRows(block, AES_ShiftRowTab_Inv);
AES_SubBytes(block, AES_Sbox_Inv);
for(var i = l - 32; i >= 16; i -= 16) {
AES_AddRoundKey(block, key.slice(i, i + 16));
AES_MixColumns_Inv(block);
AES_ShiftRows(block, AES_ShiftRowTab_Inv);
AES_SubBytes(block, AES_Sbox_Inv);
}
AES_AddRoundKey(block, key.slice(0, 16));
}
/******************************************************************************/
/* The following lookup tables and functions are for internal use only! */
AES_Sbox = new Array(99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,
118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,
147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,
7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,
47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,
251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,
188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,
100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,
50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,
78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,
116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,
158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,
137,13,191,230,66,104,65,153,45,15,176,84,187,22);
AES_ShiftRowTab = new Array(0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11);
function AES_SubBytes(state, sbox) {
for(var i = 0; i < 16; i++)
state[i] = sbox[state[i]];
}
function AES_AddRoundKey(state, rkey) {
for(var i = 0; i < 16; i++)
state[i] ^= rkey[i];
}
function AES_ShiftRows(state, shifttab) {
var h = new Array().concat(state);
for(var i = 0; i < 16; i++)
state[i] = h[shifttab[i]];
}
function AES_MixColumns(state) {
for(var i = 0; i < 16; i += 4) {
var s0 = state[i + 0], s1 = state[i + 1];
var s2 = state[i + 2], s3 = state[i + 3];
var h = s0 ^ s1 ^ s2 ^ s3;
state[i + 0] ^= h ^ AES_xtime[s0 ^ s1];
state[i + 1] ^= h ^ AES_xtime[s1 ^ s2];
state[i + 2] ^= h ^ AES_xtime[s2 ^ s3];
state[i + 3] ^= h ^ AES_xtime[s3 ^ s0];
}
}
function AES_MixColumns_Inv(state) {
for(var i = 0; i < 16; i += 4) {
var s0 = state[i + 0], s1 = state[i + 1];
var s2 = state[i + 2], s3 = state[i + 3];
var h = s0 ^ s1 ^ s2 ^ s3;
var xh = AES_xtime[h];
var h1 = AES_xtime[AES_xtime[xh ^ s0 ^ s2]] ^ h;
var h2 = AES_xtime[AES_xtime[xh ^ s1 ^ s3]] ^ h;
state[i + 0] ^= h1 ^ AES_xtime[s0 ^ s1];
state[i + 1] ^= h2 ^ AES_xtime[s1 ^ s2];
state[i + 2] ^= h1 ^ AES_xtime[s2 ^ s3];
state[i + 3] ^= h2 ^ AES_xtime[s3 ^ s0];
}
}
function bin2String (array) {
var result = "";
for (var i = 0; i < array.length; i++) {
result += String.fromCharCode(parseInt(array[i], 2));
}
return result;
}
function string2Bin (str) {
var result = [];
for (var i = 0; i < str.length; i++) {
result.push(str.charCodeAt(i));
}
while ((result.length % 16))
result.push(0);
return result;
}
function bin2String (array) {
return String.fromCharCode.apply(String, array);
}
// http://osama-oransa.blogspot.fr/2012/03/using-aes-encrypting-in-java-script.html
function AES(a) {
this.init = function (myKey){
AES_Init();
var key = string2Bin(myKey);
AES_ExpandKey(key);
return key;
}
this.encrypt = function ( inputStr,key ) {
var block = string2Bin(inputStr);
AES_Encrypt(block, key);
var data=bin2String(block);
return data;
}
this.decrypt = function ( inputStr,key ) {
block = string2Bin(inputStr);
AES_Decrypt(block, key);
var data=bin2String(block);
return data;
}
this.encryptLongString = function( myString,key ) {
if(myString.length>16){
var data='';
for(var i=0;i<myString.length;i=i+16){
data+=this.encrypt(myString.substr(i,16),key);
}
return data;
}else{
return this.encrypt(myString,key);
}
}
this.decryptLongString = function ( myString,key ) {
if(myString.length>16){
var data='';
for(var i=0;i<myString.length;i=i+16){
data+=this.decrypt(myString.substr(i,16),key);
}
return data;
}else{
return this.decrypt(myString,key);
}
}
this.finish = function(){
AES_Done();
}
}