Fix crashes when no preKey is present
Adds a test identical to the 'basic prekey v3' test with the addition of `delete preKeyBundle.preKey` where appropriate.
This commit is contained in:
parent
8334fa5699
commit
538c7aecce
15
dist/libsignal-protocol.js
vendored
15
dist/libsignal-protocol.js
vendored
@ -35845,15 +35845,20 @@ SessionBuilder.prototype = {
|
||||
}).then(function() {
|
||||
return Internal.crypto.createKeyPair();
|
||||
}).then(function(baseKey) {
|
||||
var devicePreKey = (device.preKey.publicKey);
|
||||
var devicePreKey;
|
||||
if (device.preKey) {
|
||||
devicePreKey = device.preKey.publicKey;
|
||||
}
|
||||
return this.initSession(true, baseKey, undefined, device.identityKey,
|
||||
devicePreKey, device.signedPreKey.publicKey, device.registrationId
|
||||
).then(function(session) {
|
||||
session.pendingPreKey = {
|
||||
preKeyId : device.preKey.keyId,
|
||||
signedKeyId : device.signedPreKey.keyId,
|
||||
baseKey : baseKey.pubKey
|
||||
};
|
||||
if (device.preKey) {
|
||||
session.pendingPreKey.preKeyId = device.preKey.keyId;
|
||||
}
|
||||
return session;
|
||||
});
|
||||
}.bind(this)).then(function(session) {
|
||||
@ -36136,7 +36141,9 @@ SessionCipher.prototype = {
|
||||
preKeyMsg.registrationId = myRegistrationId;
|
||||
|
||||
preKeyMsg.baseKey = util.toArrayBuffer(session.pendingPreKey.baseKey);
|
||||
preKeyMsg.preKeyId = session.pendingPreKey.preKeyId;
|
||||
if (session.pendingPreKey.preKeyId) {
|
||||
preKeyMsg.preKeyId = session.pendingPreKey.preKeyId;
|
||||
}
|
||||
preKeyMsg.signedPreKeyId = session.pendingPreKey.signedKeyId;
|
||||
|
||||
preKeyMsg.message = message;
|
||||
@ -36219,7 +36226,7 @@ SessionCipher.prototype = {
|
||||
).then(function(plaintext) {
|
||||
record.updateSessionState(session);
|
||||
return this.storage.storeSession(address, record.serialize()).then(function() {
|
||||
if (preKeyId !== undefined) {
|
||||
if (preKeyId !== undefined && preKeyId !== null) {
|
||||
return this.storage.removePreKey(preKeyId);
|
||||
}
|
||||
}.bind(this)).then(function() {
|
||||
|
||||
@ -21,15 +21,20 @@ SessionBuilder.prototype = {
|
||||
}).then(function() {
|
||||
return Internal.crypto.createKeyPair();
|
||||
}).then(function(baseKey) {
|
||||
var devicePreKey = (device.preKey.publicKey);
|
||||
var devicePreKey;
|
||||
if (device.preKey) {
|
||||
devicePreKey = device.preKey.publicKey;
|
||||
}
|
||||
return this.initSession(true, baseKey, undefined, device.identityKey,
|
||||
devicePreKey, device.signedPreKey.publicKey, device.registrationId
|
||||
).then(function(session) {
|
||||
session.pendingPreKey = {
|
||||
preKeyId : device.preKey.keyId,
|
||||
signedKeyId : device.signedPreKey.keyId,
|
||||
baseKey : baseKey.pubKey
|
||||
};
|
||||
if (device.preKey) {
|
||||
session.pendingPreKey.preKeyId = device.preKey.keyId;
|
||||
}
|
||||
return session;
|
||||
});
|
||||
}.bind(this)).then(function(session) {
|
||||
|
||||
@ -89,7 +89,9 @@ SessionCipher.prototype = {
|
||||
preKeyMsg.registrationId = myRegistrationId;
|
||||
|
||||
preKeyMsg.baseKey = util.toArrayBuffer(session.pendingPreKey.baseKey);
|
||||
preKeyMsg.preKeyId = session.pendingPreKey.preKeyId;
|
||||
if (session.pendingPreKey.preKeyId) {
|
||||
preKeyMsg.preKeyId = session.pendingPreKey.preKeyId;
|
||||
}
|
||||
preKeyMsg.signedPreKeyId = session.pendingPreKey.signedKeyId;
|
||||
|
||||
preKeyMsg.message = message;
|
||||
@ -172,7 +174,7 @@ SessionCipher.prototype = {
|
||||
).then(function(plaintext) {
|
||||
record.updateSessionState(session);
|
||||
return this.storage.storeSession(address, record.serialize()).then(function() {
|
||||
if (preKeyId !== undefined) {
|
||||
if (preKeyId !== undefined && preKeyId !== null) {
|
||||
return this.storage.removePreKey(preKeyId);
|
||||
}
|
||||
}.bind(this)).then(function() {
|
||||
|
||||
@ -142,4 +142,99 @@ describe('SessionBuilder', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("basic v3 NO PREKEY", function() {
|
||||
var aliceStore = new SignalProtocolStore();
|
||||
|
||||
var bobStore = new SignalProtocolStore();
|
||||
var bobPreKeyId = 1337;
|
||||
var bobSignedKeyId = 1;
|
||||
|
||||
var Curve = libsignal.Curve;
|
||||
|
||||
before(function(done) {
|
||||
Promise.all([
|
||||
generateIdentity(aliceStore),
|
||||
generateIdentity(bobStore),
|
||||
]).then(function() {
|
||||
return generatePreKeyBundle(bobStore, bobPreKeyId, bobSignedKeyId);
|
||||
}).then(function(preKeyBundle) {
|
||||
delete preKeyBundle.preKey;
|
||||
var builder = new libsignal.SessionBuilder(aliceStore, BOB_ADDRESS);
|
||||
return builder.processPreKey(preKeyBundle).then(function() {
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
var originalMessage = util.toArrayBuffer("L'homme est condamné à être libre");
|
||||
var aliceSessionCipher = new libsignal.SessionCipher(aliceStore, BOB_ADDRESS);
|
||||
var bobSessionCipher = new libsignal.SessionCipher(bobStore, ALICE_ADDRESS);
|
||||
|
||||
it('creates a session', function(done) {
|
||||
return aliceStore.loadSession(BOB_ADDRESS.toString()).then(function(record) {
|
||||
assert.isDefined(record);
|
||||
var sessionRecord = Internal.SessionRecord.deserialize(record);
|
||||
assert.isTrue(sessionRecord.haveOpenSession());
|
||||
assert.isDefined(sessionRecord.getOpenSession());
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
it('the session can encrypt', function(done) {
|
||||
aliceSessionCipher.encrypt(originalMessage).then(function(ciphertext) {
|
||||
|
||||
assert.strictEqual(ciphertext.type, 3); // PREKEY_BUNDLE
|
||||
|
||||
return bobSessionCipher.decryptPreKeyWhisperMessage(ciphertext.body, 'binary');
|
||||
|
||||
}).then(function(plaintext) {
|
||||
|
||||
assertEqualArrayBuffers(plaintext, originalMessage);
|
||||
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
it('the session can decrypt', function(done) {
|
||||
bobSessionCipher.encrypt(originalMessage).then(function(ciphertext) {
|
||||
|
||||
return aliceSessionCipher.decryptWhisperMessage(ciphertext.body, 'binary');
|
||||
|
||||
}).then(function(plaintext) {
|
||||
|
||||
assertEqualArrayBuffers(plaintext, originalMessage);
|
||||
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
it('accepts a new preKey with the same identity', function(done) {
|
||||
generatePreKeyBundle(bobStore, bobPreKeyId + 1, bobSignedKeyId + 1).then(function(preKeyBundle) {
|
||||
delete preKeyBundle.preKey;
|
||||
var builder = new libsignal.SessionBuilder(aliceStore, BOB_ADDRESS);
|
||||
return builder.processPreKey(preKeyBundle).then(function() {
|
||||
return aliceStore.loadSession(BOB_ADDRESS.toString()).then(function(record) {
|
||||
assert.isDefined(record);
|
||||
var sessionRecord = Internal.SessionRecord.deserialize(record);
|
||||
assert.isTrue(sessionRecord.haveOpenSession());
|
||||
assert.isDefined(sessionRecord.getOpenSession());
|
||||
done();
|
||||
});
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('rejects untrusted identity keys', function(done) {
|
||||
KeyHelper.generateIdentityKeyPair().then(function(newIdentity) {
|
||||
var builder = new libsignal.SessionBuilder(aliceStore, BOB_ADDRESS);
|
||||
return builder.processPreKey({
|
||||
identityKey: newIdentity.pubKey,
|
||||
registrationId : 12356
|
||||
}).then(function(e) {
|
||||
assert.fail('should not be trusted');
|
||||
}).catch(function(e) {
|
||||
assert.strictEqual(e.message, 'Identity key changed');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user