Update libsignal-protocol v1.1.3
// FREEBIE
This commit is contained in:
parent
186c597e24
commit
4c0ed76909
2 changed files with 92 additions and 26 deletions
|
@ -35803,6 +35803,26 @@ Internal.SessionRecord = function() {
|
||||||
throw new Error("Had open sessions on a record that had no registrationId set");
|
throw new Error("Had open sessions on a record that had no registrationId set");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getSessions: function() {
|
||||||
|
// return an array of sessions ordered by time closed,
|
||||||
|
// followed by the open session
|
||||||
|
var list = [];
|
||||||
|
var openSession;
|
||||||
|
for (var k in this._sessions) {
|
||||||
|
if (this._sessions[k].indexInfo.closed === -1) {
|
||||||
|
openSession = this._sessions[k];
|
||||||
|
} else {
|
||||||
|
list.push(this._sessions[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = list.sort(function(s1, s2) {
|
||||||
|
return s1.indexInfo.closed - s2.indexInfo.closed;
|
||||||
|
});
|
||||||
|
if (openSession) {
|
||||||
|
list.push(openSession);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
archiveCurrentState: function() {
|
archiveCurrentState: function() {
|
||||||
var open_session = this.getOpenSession();
|
var open_session = this.getOpenSession();
|
||||||
if (open_session !== undefined) {
|
if (open_session !== undefined) {
|
||||||
|
@ -35814,6 +35834,7 @@ Internal.SessionRecord = function() {
|
||||||
if (session.indexInfo.closed > -1) {
|
if (session.indexInfo.closed > -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log('closing session', session.indexInfo.baseKey);
|
||||||
|
|
||||||
// After this has run, we can still receive messages on ratchet chains which
|
// After this has run, we can still receive messages on ratchet chains which
|
||||||
// were already open (unless we know we dont need them),
|
// were already open (unless we know we dont need them),
|
||||||
|
@ -35829,9 +35850,6 @@ Internal.SessionRecord = function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delete current root key and our ephemeral key pair to disallow ratchet stepping
|
|
||||||
delete session.currentRatchet.rootKey;
|
|
||||||
delete session.currentRatchet.ephemeralKeyPair;
|
|
||||||
session.indexInfo.closed = Date.now();
|
session.indexInfo.closed = Date.now();
|
||||||
this.removeOldChains(session);
|
this.removeOldChains(session);
|
||||||
},
|
},
|
||||||
|
@ -36237,6 +36255,22 @@ SessionCipher.prototype = {
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
decryptWithSessionList: function(buffer, sessionList, errors) {
|
||||||
|
// Iterate recursively through the list, attempting to decrypt
|
||||||
|
// using each one at a time. Stop and return the result if we get
|
||||||
|
// a valid result
|
||||||
|
if (sessionList.length === 0) {
|
||||||
|
return Promise.reject(errors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var session = sessionList.pop();
|
||||||
|
return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
|
||||||
|
return { plaintext: plaintext, session: session };
|
||||||
|
}).catch(function(e) {
|
||||||
|
errors.push(e);
|
||||||
|
return this.decryptWithSessionList(buffer, sessionList, errors);
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
decryptWhisperMessage: function(buffer, encoding) {
|
decryptWhisperMessage: function(buffer, encoding) {
|
||||||
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding).toArrayBuffer();
|
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding).toArrayBuffer();
|
||||||
return Internal.SessionLock.queueJobForNumber(this.remoteAddress.toString(), function() {
|
return Internal.SessionLock.queueJobForNumber(this.remoteAddress.toString(), function() {
|
||||||
|
@ -36245,18 +36279,17 @@ SessionCipher.prototype = {
|
||||||
if (!record) {
|
if (!record) {
|
||||||
throw new Error("No record for device " + address);
|
throw new Error("No record for device " + address);
|
||||||
}
|
}
|
||||||
var messageProto = buffer.slice(1, buffer.byteLength - 8);
|
var errors = [];
|
||||||
var message = Internal.protobuf.WhisperMessage.decode(messageProto);
|
return this.decryptWithSessionList(buffer, record.getSessions(), errors).then(function(result) {
|
||||||
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
return this.getRecord(address).then(function(record) {
|
||||||
var session = record.getSessionByRemoteEphemeralKey(remoteEphemeralKey);
|
record.updateSessionState(result.session);
|
||||||
return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
|
|
||||||
record.updateSessionState(session);
|
|
||||||
return this.storage.storeSession(address, record.serialize()).then(function() {
|
return this.storage.storeSession(address, record.serialize()).then(function() {
|
||||||
return plaintext;
|
return result.plaintext;
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
}.bind(this));
|
||||||
},
|
},
|
||||||
decryptPreKeyWhisperMessage: function(buffer, encoding) {
|
decryptPreKeyWhisperMessage: function(buffer, encoding) {
|
||||||
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding);
|
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding);
|
||||||
|
@ -36311,7 +36344,7 @@ SessionCipher.prototype = {
|
||||||
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
||||||
|
|
||||||
if (session === undefined) {
|
if (session === undefined) {
|
||||||
throw new Error("No session found to decrypt message from " + this.remoteAddress.toString());
|
return Promise.reject(new Error("No session found to decrypt message from " + this.remoteAddress.toString()));
|
||||||
}
|
}
|
||||||
if (session.indexInfo.closed != -1) {
|
if (session.indexInfo.closed != -1) {
|
||||||
console.log('decrypting message for closed session');
|
console.log('decrypting message for closed session');
|
||||||
|
|
|
@ -35679,6 +35679,26 @@ Internal.SessionRecord = function() {
|
||||||
throw new Error("Had open sessions on a record that had no registrationId set");
|
throw new Error("Had open sessions on a record that had no registrationId set");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getSessions: function() {
|
||||||
|
// return an array of sessions ordered by time closed,
|
||||||
|
// followed by the open session
|
||||||
|
var list = [];
|
||||||
|
var openSession;
|
||||||
|
for (var k in this._sessions) {
|
||||||
|
if (this._sessions[k].indexInfo.closed === -1) {
|
||||||
|
openSession = this._sessions[k];
|
||||||
|
} else {
|
||||||
|
list.push(this._sessions[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = list.sort(function(s1, s2) {
|
||||||
|
return s1.indexInfo.closed - s2.indexInfo.closed;
|
||||||
|
});
|
||||||
|
if (openSession) {
|
||||||
|
list.push(openSession);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
archiveCurrentState: function() {
|
archiveCurrentState: function() {
|
||||||
var open_session = this.getOpenSession();
|
var open_session = this.getOpenSession();
|
||||||
if (open_session !== undefined) {
|
if (open_session !== undefined) {
|
||||||
|
@ -35690,6 +35710,7 @@ Internal.SessionRecord = function() {
|
||||||
if (session.indexInfo.closed > -1) {
|
if (session.indexInfo.closed > -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log('closing session', session.indexInfo.baseKey);
|
||||||
|
|
||||||
// After this has run, we can still receive messages on ratchet chains which
|
// After this has run, we can still receive messages on ratchet chains which
|
||||||
// were already open (unless we know we dont need them),
|
// were already open (unless we know we dont need them),
|
||||||
|
@ -35705,9 +35726,6 @@ Internal.SessionRecord = function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delete current root key and our ephemeral key pair to disallow ratchet stepping
|
|
||||||
delete session.currentRatchet.rootKey;
|
|
||||||
delete session.currentRatchet.ephemeralKeyPair;
|
|
||||||
session.indexInfo.closed = Date.now();
|
session.indexInfo.closed = Date.now();
|
||||||
this.removeOldChains(session);
|
this.removeOldChains(session);
|
||||||
},
|
},
|
||||||
|
@ -36113,6 +36131,22 @@ SessionCipher.prototype = {
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
decryptWithSessionList: function(buffer, sessionList, errors) {
|
||||||
|
// Iterate recursively through the list, attempting to decrypt
|
||||||
|
// using each one at a time. Stop and return the result if we get
|
||||||
|
// a valid result
|
||||||
|
if (sessionList.length === 0) {
|
||||||
|
return Promise.reject(errors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var session = sessionList.pop();
|
||||||
|
return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
|
||||||
|
return { plaintext: plaintext, session: session };
|
||||||
|
}).catch(function(e) {
|
||||||
|
errors.push(e);
|
||||||
|
return this.decryptWithSessionList(buffer, sessionList, errors);
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
decryptWhisperMessage: function(buffer, encoding) {
|
decryptWhisperMessage: function(buffer, encoding) {
|
||||||
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding).toArrayBuffer();
|
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding).toArrayBuffer();
|
||||||
return Internal.SessionLock.queueJobForNumber(this.remoteAddress.toString(), function() {
|
return Internal.SessionLock.queueJobForNumber(this.remoteAddress.toString(), function() {
|
||||||
|
@ -36121,18 +36155,17 @@ SessionCipher.prototype = {
|
||||||
if (!record) {
|
if (!record) {
|
||||||
throw new Error("No record for device " + address);
|
throw new Error("No record for device " + address);
|
||||||
}
|
}
|
||||||
var messageProto = buffer.slice(1, buffer.byteLength - 8);
|
var errors = [];
|
||||||
var message = Internal.protobuf.WhisperMessage.decode(messageProto);
|
return this.decryptWithSessionList(buffer, record.getSessions(), errors).then(function(result) {
|
||||||
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
return this.getRecord(address).then(function(record) {
|
||||||
var session = record.getSessionByRemoteEphemeralKey(remoteEphemeralKey);
|
record.updateSessionState(result.session);
|
||||||
return this.doDecryptWhisperMessage(buffer, session).then(function(plaintext) {
|
|
||||||
record.updateSessionState(session);
|
|
||||||
return this.storage.storeSession(address, record.serialize()).then(function() {
|
return this.storage.storeSession(address, record.serialize()).then(function() {
|
||||||
return plaintext;
|
return result.plaintext;
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
}.bind(this));
|
||||||
},
|
},
|
||||||
decryptPreKeyWhisperMessage: function(buffer, encoding) {
|
decryptPreKeyWhisperMessage: function(buffer, encoding) {
|
||||||
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding);
|
buffer = dcodeIO.ByteBuffer.wrap(buffer, encoding);
|
||||||
|
@ -36187,7 +36220,7 @@ SessionCipher.prototype = {
|
||||||
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
var remoteEphemeralKey = message.ephemeralKey.toArrayBuffer();
|
||||||
|
|
||||||
if (session === undefined) {
|
if (session === undefined) {
|
||||||
throw new Error("No session found to decrypt message from " + this.remoteAddress.toString());
|
return Promise.reject(new Error("No session found to decrypt message from " + this.remoteAddress.toString()));
|
||||||
}
|
}
|
||||||
if (session.indexInfo.closed != -1) {
|
if (session.indexInfo.closed != -1) {
|
||||||
console.log('decrypting message for closed session');
|
console.log('decrypting message for closed session');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue