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:
lilia 2017-02-08 22:00:53 -08:00
parent 8334fa5699
commit 538c7aecce
4 changed files with 117 additions and 8 deletions

View File

@ -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() {

View File

@ -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) {

View File

@ -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() {

View File

@ -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);
});
});
});
});