Clean up session retreival (fixes #30)
This commit is contained in:
parent
8d408e6d8f
commit
76e7dcb77d
1 changed files with 41 additions and 19 deletions
60
js/crypto.js
60
js/crypto.js
|
@ -147,18 +147,27 @@ window.crypto = (function() {
|
||||||
storage.putEncrypted("session" + getEncodedNumber(encodedNumber), sessions);
|
storage.putEncrypted("session" + getEncodedNumber(encodedNumber), sessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_storage.getSession = function(encodedNumber, remoteEphemeralKey) {
|
crypto_storage.getOpenSession = function(encodedNumber) {
|
||||||
var sessions = storage.getEncrypted("session" + getEncodedNumber(encodedNumber));
|
var sessions = storage.getEncrypted("session" + getEncodedNumber(encodedNumber));
|
||||||
if (sessions === undefined)
|
if (sessions === undefined)
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
||||||
var searchKey = "NOTAKEY";
|
for (key in sessions) {
|
||||||
if (remoteEphemeralKey !== undefined)
|
if (key == "identityKey")
|
||||||
searchKey = getString(remoteEphemeralKey);
|
continue;
|
||||||
|
|
||||||
var preferredSession = sessions[searchKey];
|
if (sessions[key].indexInfo.closed == -1)
|
||||||
if (preferredSession !== undefined)
|
return sessions[key];
|
||||||
return preferredSession;
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_storage.getSessionByRemoteEphemeralKey = function(encodedNumber, remoteEphemeralKey) {
|
||||||
|
var sessions = storage.getEncrypted("session" + getEncodedNumber(encodedNumber));
|
||||||
|
if (sessions === undefined)
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
var searchKey = getString(remoteEphemeralKey);
|
||||||
|
|
||||||
var openSession = undefined;
|
var openSession = undefined;
|
||||||
for (key in sessions) {
|
for (key in sessions) {
|
||||||
|
@ -176,12 +185,26 @@ window.crypto = (function() {
|
||||||
if (openSession !== undefined)
|
if (openSession !== undefined)
|
||||||
return openSession;
|
return openSession;
|
||||||
|
|
||||||
if (sessions.identityKey !== undefined && searchKey != "NOTAKEY")
|
|
||||||
return { indexInfo: { remoteIdentityKey: sessions.identityKey } };
|
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
crypto_storage.getSessionOrIdentityKeyByBaseKey = function(encodedNumber, baseKey) {
|
||||||
|
var sessions = storage.getEncrypted("session" + getEncodedNumber(encodedNumber));
|
||||||
|
if (sessions === undefined)
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
var preferredSession = sessions[getString(baseKey)];
|
||||||
|
if (preferredSession !== undefined)
|
||||||
|
return preferredSession;
|
||||||
|
|
||||||
|
if (sessions.identityKey !== undefined)
|
||||||
|
return { indexInfo: { remoteIdentityKey: sessions.identityKey } };
|
||||||
|
|
||||||
|
throw new Error("Datastore inconsistency: session was stored without identity key");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
*** Internal Crypto stuff ***
|
*** Internal Crypto stuff ***
|
||||||
*****************************/
|
*****************************/
|
||||||
|
@ -336,7 +359,8 @@ window.crypto = (function() {
|
||||||
|
|
||||||
var initSessionFromPreKeyWhisperMessage = function(encodedNumber, message) {
|
var initSessionFromPreKeyWhisperMessage = function(encodedNumber, message) {
|
||||||
var preKeyPair = crypto_storage.getAndRemovePreKeyPair(message.preKeyId);
|
var preKeyPair = crypto_storage.getAndRemovePreKeyPair(message.preKeyId);
|
||||||
var session = crypto_storage.getSession(encodedNumber, toArrayBuffer(message.baseKey));
|
var session = crypto_storage.getSessionOrIdentityKeyByBaseKey(encodedNumber, toArrayBuffer(message.baseKey));
|
||||||
|
var open_session = crypto_storage.getOpenSession(encodedNumber);
|
||||||
if (preKeyPair === undefined) {
|
if (preKeyPair === undefined) {
|
||||||
// Session may or may not be the correct one, but if its not, we can't do anything about it
|
// Session may or may not be the correct one, but if its not, we can't do anything about it
|
||||||
// ...fall through and let decryptWhisperMessage handle that case
|
// ...fall through and let decryptWhisperMessage handle that case
|
||||||
|
@ -346,13 +370,11 @@ window.crypto = (function() {
|
||||||
throw new Error("Missing preKey for PreKeyWhisperMessage");
|
throw new Error("Missing preKey for PreKeyWhisperMessage");
|
||||||
}
|
}
|
||||||
if (session !== undefined) {
|
if (session !== undefined) {
|
||||||
// We already had a session:
|
// We already had a session/known identity key:
|
||||||
if (getString(session.indexInfo.remoteIdentityKey) == getString(message.identityKey)) {
|
if (getString(session.indexInfo.remoteIdentityKey) == getString(message.identityKey)) {
|
||||||
// If the identity key matches the previous one, close the previous one and use the new one
|
// If the identity key matches the previous one, close the previous one and use the new one
|
||||||
if (session.currentRatchet !== undefined)
|
if (open_session !== undefined)
|
||||||
closeSession(session); // To be returned and saved later
|
closeSession(open_session); // To be returned and saved later
|
||||||
else
|
|
||||||
session = undefined; // Don't return an identityKey-only "session"
|
|
||||||
} else {
|
} else {
|
||||||
// ...otherwise create an error that the UI will pick up and ask the user if they want to re-negotiate
|
// ...otherwise create an error that the UI will pick up and ask the user if they want to re-negotiate
|
||||||
// TODO: Save the message for possible later renegotiation
|
// TODO: Save the message for possible later renegotiation
|
||||||
|
@ -367,7 +389,7 @@ window.crypto = (function() {
|
||||||
// Note that the session is not actually saved until the very end of decryptWhisperMessage
|
// Note that the session is not actually saved until the very end of decryptWhisperMessage
|
||||||
// ... to ensure that the sender actually holds the private keys for all reported pubkeys
|
// ... to ensure that the sender actually holds the private keys for all reported pubkeys
|
||||||
new_session.indexInfo.baseKey = message.baseKey;
|
new_session.indexInfo.baseKey = message.baseKey;
|
||||||
return [new_session, session];
|
return [new_session, open_session];
|
||||||
});;
|
});;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +488,7 @@ window.crypto = (function() {
|
||||||
var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey);
|
var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey);
|
||||||
|
|
||||||
if (session === undefined) {
|
if (session === undefined) {
|
||||||
var session = crypto_storage.getSession(encodedNumber, remoteEphemeralKey);
|
var session = crypto_storage.getSessionByRemoteEphemeralKey(encodedNumber, remoteEphemeralKey);
|
||||||
if (session === undefined)
|
if (session === undefined)
|
||||||
throw new Error("No session found to decrypt message from " + encodedNumber);
|
throw new Error("No session found to decrypt message from " + encodedNumber);
|
||||||
}
|
}
|
||||||
|
@ -547,7 +569,7 @@ window.crypto = (function() {
|
||||||
|
|
||||||
// return Promise(encoded [PreKey]WhisperMessage)
|
// return Promise(encoded [PreKey]WhisperMessage)
|
||||||
crypto.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
crypto.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
||||||
var session = crypto_storage.getSession(deviceObject.encodedNumber);
|
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
||||||
|
|
||||||
var doEncryptPushMessageContent = function() {
|
var doEncryptPushMessageContent = function() {
|
||||||
var msg = new WhisperMessageProtobuf();
|
var msg = new WhisperMessageProtobuf();
|
||||||
|
|
Loading…
Reference in a new issue