@@ -35679,6 +35679,26 @@ Internal.SessionRecord = function() {
35679
35679
throw new Error("Had open sessions on a record that had no registrationId set");
35680
35680
}
35681
35681
},
35682
+ getSessions: function() {
35683
+ // return an array of sessions ordered by time closed,
35684
+ // followed by the open session
35685
+ var list = [];
35686
+ var openSession;
35687
+ for (var k in this._sessions) {
35688
+ if (this._sessions[k].indexInfo.closed === -1) {
35689
+ openSession = this._sessions[k];
35690
+ } else {
35691
+ list.push(this._sessions[k]);
35692
+ }
35693
+ }
35694
+ list = list.sort(function(s1, s2) {
35695
+ return s1.indexInfo.closed - s2.indexInfo.closed;
35696
+ });
35697
+ if (openSession) {
35698
+ list.push(openSession);
35699
+ }
35700
+ return list;
35701
+ },
35682
35702
archiveCurrentState: function() {
35683
35703
var open_session = this.getOpenSession();
35684
35704
if (open_session !== undefined) {
@@ -35690,6 +35710,7 @@ Internal.SessionRecord = function() {
35690
35710
if (session.indexInfo.closed > -1) {
35691
35711
return;
35692
35712
}
35713
+ console.log('closing session', session.indexInfo.baseKey);
35693
35714
35694
35715
// After this has run, we can still receive messages on ratchet chains which
35695
35716
// were already open (unless we know we dont need them),
@@ -36110,6 +36131,22 @@ SessionCipher.prototype = {
36110
36131
});
36111
36132
}.bind(this));
36112
36133
},
36134
+ decryptWithSessionList: function(buffer, sessionList, errors) {
36135
+ // Iterate recursively through the list, attempting to decrypt
36136
+ // using each one at a time. Stop and return the result if we get
36137
+ // a valid result
36138
+ if (sessionList.length === 0) {
36139
+ return Promise.reject(errors[0]);
36140
+ }
36141
+
36142
+ var session = sessionList.pop();
36143
+ return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
36144
+ return { plaintext: plaintext, session: session };
36145
+ }).catch(function(e) {
36146
+ errors.push(e);
36147
+ return this.decryptWithSessionList(buffer, sessionList, errors);
36148
+ }.bind(this));
36149
+ },
36113
36150
decryptWhisperMessage: function(buffer, encoding) {
36114
36151
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding).toArrayBuffer();
36115
36152
return Internal.SessionLock.queueJobForNumber(this.remoteAddress.toString(), function() {
@@ -36118,15 +36155,14 @@ SessionCipher.prototype = {
36118
36155
if (!record) {
36119
36156
throw new Error("No record for device " + address);
36120
36157
}
36121
- var messageProto = buffer.slice(1, buffer.byteLength - 8);
36122
- var message = Internal.protobuf.WhisperMessage.decode(messageProto);
36123
- var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
36124
- var session = record.getSessionByRemoteEphemeralKey(remoteEphemeralKey);
36125
- return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
36126
- record.updateSessionState(session);
36127
- return this.storage.storeSession(address, record.serialize()).then(function() {
36128
- return plaintext;
36129
- });
36158
+ var errors = [];
36159
+ return this.decryptWithSessionList(buffer, record.getSessions(), errors).then(function(result) {
36160
+ return this.getRecord(address).then(function(record) {
36161
+ record.updateSessionState(result.session);
36162
+ return this.storage.storeSession(address, record.serialize()).then(function() {
36163
+ return result.plaintext;
36164
+ });
36165
+ }.bind(this));
36130
36166
}.bind(this));
36131
36167
}.bind(this));
36132
36168
}.bind(this));
@@ -36184,7 +36220,7 @@ SessionCipher.prototype = {
36184
36220
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
36185
36221
36186
36222
if (session === undefined) {
36187
- throw new Error("No session found to decrypt message from " + this.remoteAddress.toString());
36223
+ return Promise.reject( new Error("No session found to decrypt message from " + this.remoteAddress.toString() ));
36188
36224
}
36189
36225
if (session.indexInfo.closed != -1) {
36190
36226
console.log('decrypting message for closed session');
0 commit comments