Put a signature on sent group messages

It's important that group messages be signed by the sender, rather than by a
secret derived from the shared secret.
release-v1.0.0
Richard van der Hoff 2016-05-26 18:01:02 +01:00
parent 7c5ab63fd8
commit 803672931a
1 changed files with 69 additions and 20 deletions

View File

@ -2,12 +2,23 @@
* browser.
*/
function buttonAndTextElement(buttonLabel, textContent, clickHandler) {
var el = document.createElement("div");
function buttonElement(buttonLabel, clickHandler) {
var button = document.createElement("button");
el.appendChild(button);
button.appendChild(document.createTextNode(buttonLabel));
button.addEventListener("click", clickHandler, false);
return button;
}
function buttonsAndText(textContent, buttonLabelToHandlerMap) {
var el = document.createElement("div");
for (var label in buttonLabelToHandlerMap) {
if (!buttonLabelToHandlerMap.hasOwnProperty(label)) {
continue;
}
var handler = buttonLabelToHandlerMap[label];
var button = buttonElement(label, handler);
el.appendChild(button);
}
var message_element = document.createElement("tt");
el.appendChild(message_element);
@ -15,22 +26,33 @@ function buttonAndTextElement(buttonLabel, textContent, clickHandler) {
var content = document.createTextNode(textContent);
message_element.appendChild(content);
el.addEventListener("click", clickHandler, false);
return el;
}
function buttonAndTextElement(buttonLabel, textContent, clickHandler) {
var buttonMap = {};
buttonMap[buttonLabel] = clickHandler;
return buttonsAndText(textContent, buttonMap);
}
function DemoUser(name) {
this.name = name;
this.olmAccount = new Olm.Account();
this.olmAccount.create();
this.idKey = this.getIdKeys()["curve25519"];
/* the people in our chat, indexed by their Curve25519 identity key.
*/
this.peers = {};
/* the Ed25519 signing key for each peer, indexed by their Curve25519 id key
*/
this.peerSigningKeys = {};
/* for each peer, a one-to-one session - indexed by id key and created on
* demand */
this.peerSessions = {}
this.peerSessions = {};
/* for each peer, info on their sender session - indexed by id key and
* session id */
@ -45,7 +67,7 @@ function DemoUser(name) {
/* the operations our peers are allowed to do on us */
var publicOps = [
"getIdKey", "getOneTimeKey",
"getIdKeys", "getOneTimeKey",
"receiveOneToOne", "receiveGroup",
];
@ -135,13 +157,14 @@ DemoUser.prototype.addTask = function(description, task, callback) {
};
DemoUser.prototype.addPeer = function(peerOps) {
var id = peerOps.getIdKey();
var keys = peerOps.getIdKeys();
var id = keys["curve25519"];
this.peers[id] = peerOps;
this.peerSigningKeys[id] = keys["ed25519"];
};
DemoUser.prototype.getIdKey = function() {
var keys = JSON.parse(this.olmAccount.identity_keys());
return keys.curve25519;
DemoUser.prototype.getIdKeys = function() {
return JSON.parse(this.olmAccount.identity_keys());
};
DemoUser.prototype.generateKeys = function(callback) {
@ -203,7 +226,7 @@ DemoUser.prototype.sendToPeer = function(peerId, message, callback) {
self.addTask("encrypt one-to-one message", function(done) {
var encrypted = session.encrypt(message);
var packet = {
sender_key: self.getIdKey(),
sender_key: self.idKey,
ciphertext: encrypted,
};
var json = JSON.stringify(packet);
@ -357,6 +380,16 @@ DemoUser.prototype.decryptGroup = function(jsonpacket, callback) {
var sender = packet.sender_key;
var session_id = packet.session_id;
var sender_signing_key = self.peerSigningKeys[sender];
if (!sender_signing_key) {
throw new Error("No known signing key for sender "+sender);
}
var olmUtility = new Olm.Utility();
olmUtility.ed25519_verify(
sender_signing_key, packet.body, packet.signature
);
var peer_sessions = self.peerGroupSessions[sender];
if (!peer_sessions) {
throw new Error("No sessions for sender "+sender);
@ -383,22 +416,37 @@ DemoUser.prototype.encrypt = function(message) {
var self = this;
var session = this.getGroupSession();
function sendJsonToPeers(json) {
for (var peer in self.peers) {
if (!self.peers.hasOwnProperty(peer)) {
continue;
}
self.peers[peer].receiveGroup(json);
}
}
self.addTask("encrypt group message", function(done) {
var encrypted = session.encrypt(message);
var signature = self.olmAccount.sign(encrypted);
var packet = {
sender_key: self.getIdKey(),
sender_key: self.idKey,
session_id: session.session_id(),
body: encrypted,
signature: signature,
};
var json = JSON.stringify(packet);
var el = buttonAndTextElement("send", json, function(ev) {
for (var peer in self.peers) {
if (!self.peers.hasOwnProperty(peer)) {
continue;
}
self.peers[peer].receiveGroup(json);
}
var el = buttonsAndText(json, {
send: function(ev) {
sendJsonToPeers(json);
},
"send corrupted": function(ev) {
var p = JSON.parse(json);
p.body += " ";
sendJsonToPeers(JSON.stringify(p));
},
});
self.groupOutputDiv.appendChild(el);
done();
@ -406,6 +454,7 @@ DemoUser.prototype.encrypt = function(message) {
};
/* ************************************************************************** */
function initUserDiv(demoUser, div) {
demoUser.progressElement = div.getElementsByClassName("user_progress")[0];