Move test vectors to libaxolotl
This commit is contained in:
parent
7e3f1ef452
commit
298c8624b2
8 changed files with 404 additions and 217 deletions
43
libaxolotl/test/fake_api.js
Normal file
43
libaxolotl/test/fake_api.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
var testSessionMap = {};
|
||||
|
||||
;(function() {
|
||||
window.axolotl = window.axolotl || {};
|
||||
window.axolotl.api = {
|
||||
getMyRegistrationId: function() {
|
||||
return window.myRegistrationId;
|
||||
},
|
||||
storage: {
|
||||
put: function(key, value) {
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
localStorage.setItem(key, textsecure.utils.jsonThing(value));
|
||||
},
|
||||
get: function(key, defaultValue) {
|
||||
var value = localStorage.getItem(key);
|
||||
if (value === null)
|
||||
return defaultValue;
|
||||
return JSON.parse(value);
|
||||
},
|
||||
remove: function(key) {
|
||||
localStorage.removeItem(key);
|
||||
},
|
||||
|
||||
sessions: {
|
||||
get: function(identifier) {
|
||||
return testSessionMap[identifier];
|
||||
},
|
||||
put: function(identifier, record) {
|
||||
testSessionMap[identifier] = record;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateKeys: function(keys) {
|
||||
return textsecure.api.registerKeys(keys).catch(function(e) {
|
||||
//TODO: Notify the user somehow?
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
};
|
||||
})();
|
|
@ -29,12 +29,22 @@
|
|||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript" src="blanket_mocha.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../components.js"></script>
|
||||
<script type="text/javascript" src="../curve25519_concat.js"></script>
|
||||
<script type="text/javascript" src="../webcrypto_concat.js"></script>
|
||||
<script type="text/javascript" src="../components.js"></script>
|
||||
|
||||
<!-- TODO: Remove the following -->
|
||||
<script type="text/javascript" src="temp_helpers.js"></script>
|
||||
<script type="text/javascript" src="../../libtextsecure/protobufs.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../crypto.js" data-cover></script>
|
||||
<script type="text/javascript" src="../protocol.js" data-cover></script>
|
||||
<script type="text/javascript" src="../protobufs.js" data-cover></script>
|
||||
<script type="text/javascript" src="../session_storage.js" data-cover></script>
|
||||
|
||||
<script type="text/javascript" src="fake_api.js"></script>
|
||||
<script type="text/javascript" src="crypto_test.js"></script>
|
||||
<script type="text/javascript" src="testvectors.js"></script>
|
||||
<script type="text/javascript" src="protocol_test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
236
libaxolotl/test/protocol_test.js
Normal file
236
libaxolotl/test/protocol_test.js
Normal file
|
@ -0,0 +1,236 @@
|
|||
/* vim: ts=4:sw=4
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
describe('Protocol', function() {
|
||||
|
||||
describe("Identity and Pre Key Creation", function() {
|
||||
this.timeout(200000);
|
||||
before(function() { localStorage.clear(); });
|
||||
after(function() { localStorage.clear(); });
|
||||
it ('works', function(done) {
|
||||
localStorage.clear();
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeyidentityKey"));
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeysignedKey0"));
|
||||
for (var i = 0; i < 100; i++) {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeypreKey" + i));
|
||||
}
|
||||
var origIdentityKey = getString(axolotl.api.storage.get("25519KeyidentityKey").privKey);
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeyidentityKey"));
|
||||
assert.equal(getString(axolotl.api.storage.get("25519KeyidentityKey").privKey), origIdentityKey);
|
||||
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeysignedKey0"));
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeysignedKey1"));
|
||||
|
||||
for (var i = 0; i < 200; i++) {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeypreKey" + i));
|
||||
}
|
||||
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeyidentityKey"));
|
||||
assert.equal(getString(axolotl.api.storage.get("25519KeyidentityKey").privKey), origIdentityKey);
|
||||
|
||||
assert.isUndefined(axolotl.api.storage.get("25519KeysignedKey0"));
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeysignedKey1"));
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeysignedKey2"));
|
||||
|
||||
for (var i = 0; i < 300; i++) {
|
||||
assert.isDefined(axolotl.api.storage.get("25519KeypreKey" + i));
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(done).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Axolotl", function() {
|
||||
var runAxolotlTest = function(v) {
|
||||
var origCreateKeyPair = axolotl.crypto.createKeyPair;
|
||||
var doStep;
|
||||
var stepDone;
|
||||
|
||||
stepDone = function(res) {
|
||||
if (!res || privKeyQueue.length != 0) {
|
||||
axolotl.crypto.createKeyPair = origCreateKeyPair;
|
||||
return false;
|
||||
} else if (step == v.length) {
|
||||
axolotl.crypto.createKeyPair = origCreateKeyPair;
|
||||
return true;
|
||||
} else
|
||||
return doStep().then(stepDone);
|
||||
}
|
||||
|
||||
var privKeyQueue = [];
|
||||
axolotl.crypto.createKeyPair = function(privKey) {
|
||||
if (privKey !== undefined)
|
||||
return origCreateKeyPair(privKey);
|
||||
if (privKeyQueue.length == 0)
|
||||
throw new Error('Out of private keys');
|
||||
else {
|
||||
var privKey = privKeyQueue.shift();
|
||||
return axolotl.crypto.createKeyPair(privKey).then(function(keyPair) {
|
||||
var a = btoa(getString(keyPair.privKey)); var b = btoa(getString(privKey));
|
||||
if (getString(keyPair.privKey) != getString(privKey))
|
||||
throw new Error('Failed to rederive private key!');
|
||||
else
|
||||
return keyPair;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var deviceObject = {encodedNumber: "SNOWDEN.1"};
|
||||
|
||||
var step = 0;
|
||||
var doStep = function() {
|
||||
var data = v[step][1];
|
||||
|
||||
switch(v[step++][0]) {
|
||||
case "receiveMessage":
|
||||
var postLocalKeySetup = function() {
|
||||
if (data.newEphemeralKey !== undefined)
|
||||
privKeyQueue.push(data.newEphemeralKey);
|
||||
|
||||
try {
|
||||
var checkResult = function(res) {
|
||||
res = textsecure.protobuf.PushMessageContent.decode(res[0]);
|
||||
//TODO: Handle END_SESSION here (just like libtextsecure.protocol_wrapper
|
||||
if (data.expectTerminateSession)
|
||||
return res.flags == textsecure.protobuf.PushMessageContent.Flags.END_SESSION;
|
||||
return res.body == data.expectedSmsText;
|
||||
}
|
||||
var checkException = function(e) {
|
||||
if (data.expectException)
|
||||
return true;
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (data.type == textsecure.protobuf.IncomingPushMessageSignal.Type.CIPHERTEXT)
|
||||
return axolotl.protocol.decryptWhisperMessage("SNOWDEN.1", getString(data.message)).then(checkResult).catch(checkException);
|
||||
else if (data.type == textsecure.protobuf.IncomingPushMessageSignal.Type.PREKEY_BUNDLE) {
|
||||
if (getString(data.message).charCodeAt(0) != ((3 << 4) | 3))
|
||||
throw new Error("Bad version byte");
|
||||
return axolotl.protocol.handlePreKeyWhisperMessage("SNOWDEN.1", getString(data.message).substring(1)).then(checkResult).catch(checkException);
|
||||
} else
|
||||
return Promise.reject(new Error("Unknown data type in test vector"));
|
||||
} catch(e) {
|
||||
if (data.expectException)
|
||||
return Promise.resolve(true);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
|
||||
axolotl.api.storage.put("25519KeyidentityKey", keyPair);
|
||||
return axolotl.crypto.createKeyPair(data.ourSignedPreKey).then(function(keyPair) {
|
||||
axolotl.api.storage.put("25519KeysignedKey" + data.signedPreKeyId, keyPair);
|
||||
|
||||
if (data.ourPreKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourPreKey).then(function(keyPair) {
|
||||
axolotl.api.storage.put("25519KeypreKey" + data.preKeyId, keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
|
||||
case "sendMessage":
|
||||
var postLocalKeySetup = function() {
|
||||
if (data.registrationId !== undefined)
|
||||
window.myRegistrationId = data.registrationId;
|
||||
|
||||
if (data.getKeys !== undefined) {
|
||||
deviceObject = {encodedNumber: "SNOWDEN.1",
|
||||
identityKey: data.getKeys.identityKey,
|
||||
preKey: data.getKeys.devices[0].preKey.publicKey,
|
||||
preKeyId: data.getKeys.devices[0].preKey.keyId,
|
||||
signedKey: data.getKeys.devices[0].signedPreKey.publicKey,
|
||||
signedKeyId: data.getKeys.devices[0].signedPreKey.keyId,
|
||||
signedKeySignature: data.getKeys.devices[0].signedPreKey.signature,
|
||||
registrationId: data.getKeys.devices[0].signedPreKey.keyId
|
||||
};
|
||||
}
|
||||
|
||||
var checkMessage = function(msg) {
|
||||
//XXX: This should be all we do: isEqual(data.expectedCiphertext, encryptedMsg, false);
|
||||
var encryptedMsg = msg.body;
|
||||
if (msg.type == 1) {
|
||||
var expected = getString(data.expectedCiphertext);
|
||||
var decoded = axolotl.protobuf.WhisperMessage.decode(expected.substring(1, expected.length - 8), 'binary');
|
||||
var result = getString(encryptedMsg);
|
||||
return getString(decoded.encode()) == result.substring(1, result.length - 8);
|
||||
} else {
|
||||
var decoded = axolotl.protobuf.PreKeyWhisperMessage.decode(getString(data.expectedCiphertext).substr(1), 'binary');
|
||||
var result = getString(encryptedMsg).substring(1);
|
||||
return getString(decoded.encode()) == result;
|
||||
}
|
||||
}
|
||||
|
||||
var proto = new textsecure.protobuf.PushMessageContent();
|
||||
if (data.endSession) {
|
||||
proto.flags = textsecure.protobuf.PushMessageContent.Flags.END_SESSION;
|
||||
proto.body = "TERMINATE";
|
||||
} else
|
||||
proto.body = data.smsText;
|
||||
|
||||
return axolotl.protocol.encryptMessageFor(deviceObject, proto).then(checkMessage)
|
||||
.then(function(res) {
|
||||
if (data.endSession)
|
||||
axolotl.protocol.closeOpenSessionForDevice("SNOWDEN.1");
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
if (data.ourBaseKey !== undefined)
|
||||
privKeyQueue.push(data.ourBaseKey);
|
||||
if (data.ourEphemeralKey !== undefined)
|
||||
privKeyQueue.push(data.ourEphemeralKey);
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
|
||||
axolotl.api.storage.put("25519KeyidentityKey", keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
|
||||
default:
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
return doStep().then(stepDone);
|
||||
};
|
||||
|
||||
describe("test vectors", function() {
|
||||
function defineTest(i) {
|
||||
it(axolotlTestVectors[i].name, function(done) {
|
||||
localStorage.clear();
|
||||
testSessionMap = {};
|
||||
return runAxolotlTest(axolotlTestVectors[i].vectors).then(function(res) {
|
||||
assert(res);
|
||||
}).then(done).catch(done);
|
||||
});
|
||||
}
|
||||
for (var i in axolotlTestVectors)
|
||||
defineTest(i);
|
||||
});
|
||||
});
|
||||
});
|
1
libaxolotl/test/protos
Symbolic link
1
libaxolotl/test/protos
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../protos/
|
85
libaxolotl/test/temp_helpers.js
Normal file
85
libaxolotl/test/temp_helpers.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
var StaticByteBufferProto = new dcodeIO.ByteBuffer().__proto__;
|
||||
var StaticArrayBufferProto = new ArrayBuffer().__proto__;
|
||||
var StaticUint8ArrayProto = new Uint8Array().__proto__;
|
||||
function getString(thing) {
|
||||
if (thing === Object(thing)) {
|
||||
if (thing.__proto__ == StaticUint8ArrayProto)
|
||||
return String.fromCharCode.apply(null, thing);
|
||||
if (thing.__proto__ == StaticArrayBufferProto)
|
||||
return getString(new Uint8Array(thing));
|
||||
if (thing.__proto__ == StaticByteBufferProto)
|
||||
return thing.toString("binary");
|
||||
}
|
||||
return thing;
|
||||
}
|
||||
|
||||
function getStringable(thing) {
|
||||
return (typeof thing == "string" || typeof thing == "number" || typeof thing == "boolean" ||
|
||||
(thing === Object(thing) &&
|
||||
(thing.__proto__ == StaticArrayBufferProto ||
|
||||
thing.__proto__ == StaticUint8ArrayProto ||
|
||||
thing.__proto__ == StaticByteBufferProto)));
|
||||
}
|
||||
|
||||
function isEqual(a, b, mayBeShort) {
|
||||
// TODO: Special-case arraybuffers, etc
|
||||
if (a === undefined || b === undefined)
|
||||
return false;
|
||||
a = getString(a);
|
||||
b = getString(b);
|
||||
var maxLength = mayBeShort ? Math.min(a.length, b.length) : Math.max(a.length, b.length);
|
||||
if (maxLength < 5)
|
||||
throw new Error("a/b compare too short");
|
||||
return a.substring(0, Math.min(maxLength, a.length)) == b.substring(0, Math.min(maxLength, b.length));
|
||||
}
|
||||
|
||||
function toArrayBuffer(thing) {
|
||||
//TODO: Optimize this for specific cases
|
||||
if (thing === undefined)
|
||||
return undefined;
|
||||
if (thing === Object(thing) && thing.__proto__ == StaticArrayBufferProto)
|
||||
return thing;
|
||||
|
||||
if (thing instanceof Array) {
|
||||
// Assuming Uint16Array from curve25519
|
||||
var res = new ArrayBuffer(thing.length * 2);
|
||||
var uint = new Uint16Array(res);
|
||||
for (var i = 0; i < thing.length; i++)
|
||||
uint[i] = thing[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!getStringable(thing))
|
||||
throw new Error("Tried to convert a non-stringable thing of type " + typeof thing + " to an array buffer");
|
||||
var str = getString(thing);
|
||||
var res = new ArrayBuffer(str.length);
|
||||
var uint = new Uint8Array(res);
|
||||
for (var i = 0; i < str.length; i++)
|
||||
uint[i] = str.charCodeAt(i);
|
||||
return res;
|
||||
}
|
||||
|
||||
function ensureStringed(thing) {
|
||||
if (getStringable(thing))
|
||||
return getString(thing);
|
||||
else if (thing instanceof Array) {
|
||||
var res = [];
|
||||
for (var i = 0; i < thing.length; i++)
|
||||
res[i] = ensureStringed(thing[i]);
|
||||
return res;
|
||||
} else if (thing === Object(thing)) {
|
||||
var res = {};
|
||||
for (var key in thing)
|
||||
res[key] = ensureStringed(thing[key]);
|
||||
return res;
|
||||
}
|
||||
throw new Error("unsure of how to jsonify object of type " + typeof thing);
|
||||
}
|
||||
|
||||
window.textsecure = {
|
||||
utils: {
|
||||
jsonThing: function(thing) {
|
||||
return JSON.stringify(ensureStringed(thing));
|
||||
}
|
||||
}
|
||||
};
|
|
@ -11,42 +11,42 @@ axolotlTestVectors = function() {
|
|||
["sendMessage",
|
||||
{
|
||||
smsText: "A",
|
||||
ourBaseKey: hexToArrayBuffer('08474c43256fb3bde899d899c3e997b24b94839c9f55a1f55ea671e7cdc55f5c'),
|
||||
ourEphemeralKey: hexToArrayBuffer('e0a18f35a04b7cfd246f72f3c7fe0fc3b000f5d11fe548e818775b7e9d93a94c'),
|
||||
ourIdentityKey: hexToArrayBuffer('a0f1dcf3d76ce4b538684b3360039bfde3ce59bca74449a01276e3ec395f4060'),
|
||||
registrationId: 9784,
|
||||
getKeys: {identityKey: hexToArrayBuffer('05c7214f5c39c83ddf81c4d56e88a33285c95db5eb87eac67536003530f5d62628'),
|
||||
ourBaseKey: hexToArrayBuffer('2060fe31b041d28127ac35cbfe790e2a25f92d2e21eb2251690ae75e732f5c4d'),
|
||||
ourEphemeralKey: hexToArrayBuffer('082e6391deb7154bd0375df3fc07f87020a3b0fd7a8c6c90e73f0e054bc2bf5d'),
|
||||
ourIdentityKey: hexToArrayBuffer('d83d8141aad5f1d62d78a1af09ffbe61f2d3458eeb887a047a58a07565d24463'),
|
||||
registrationId: 10290,
|
||||
getKeys: {identityKey: hexToArrayBuffer('059c2197be51bae703ae2edd26b6ff2b03d589ef4851be33a3f8d923ad86a6b439'),
|
||||
devices: [{
|
||||
deviceId: 1,
|
||||
preKey: {keyId: 2803392, publicKey: hexToArrayBuffer('05a189dc5be02a35e32fafa5e8e4296ef74132e29d0033de26685f471301c80738')},
|
||||
signedPreKey: {keyId: 15452175, publicKey: hexToArrayBuffer('05e59ff855c698d58a3ff0dd04a925ebe1deffe276df623ddd873fb934b7314413')},
|
||||
registrationId: 42
|
||||
preKey: {keyId: 4611143, publicKey: hexToArrayBuffer('052cd5004a4c31dd7b89b7fc80cc3e62abcf9cf1af014c93ec4589f7ca3e79e65c')},
|
||||
signedPreKey: {keyId: 14983230, publicKey: hexToArrayBuffer('05a9ecf666ec55fc27988ecc417db0d62dd5e1fa751da1f7a2dd2eca0d14c8bd46'), signature: hexToArrayBuffer('0b46fdb238f1e2df7b28a94ba575e58b0aa1d377bb843602cc8c2a7cd33770fdd741f65a240f7c3086f00f31dc4f3b8ceeab498356f8d5e4bfe6f2dd3eeca98f')},
|
||||
registrationId: 0xd00d
|
||||
}]
|
||||
},
|
||||
expectedCiphertext: hexToArrayBuffer('3308c08dab01122105d51a5f0d744180bf49d1b71b5d77a66db9664a4806d8470b99bed6311b7ed1681a210596857fd3566a584bb7ff0664df4d11cfdba8e1a445e0930a527b7b139c6a897322d301330a210577874cb60271862f343d52984224e2558f828f336d68bd14fa4aaf5a1692be7d1000180022a001fa2af5c8688440c0bc45121ae2f6b9c6d5b8cf00acfee0d1a45f9e7b245636e1fa63b3062e2a6a9cd8be9096c375b413f71c2bb18054738c8440d1aa52997899d8bcedee6a93f6a295bdaf488e81188a9c88c4e841eb772b3194576c52bd8ef8fcbc5c29545fa38d2213c84d088f9843307f45c3254927f97c6f0afca9737a00d09146284f8948bbe69c755e47e6e571887bf57959b228ba9c2418f7bfc780b7bf1adbffd96276f328b84c308f90af07'),
|
||||
expectedCiphertext: hexToArrayBuffer('3308c7b899021221058a49fa8a94224aaa8f5873404e01710ff9ef02169a75f90af4fbbc600796e0521a21050a6cf5e075c9970f14862db8a703a6c761f50b5182d17874908940556a22372222d301330a2105883ab58b3eb6db93b32bf91899a5b5175e7b21e96fff2cec02c83dff16ba1b271000180022a0013c5d070d1b75c418cef769bd7378a58969537a00e0ff60cbb99defb486fcfb43384264da4ea9821c1336f02d988da38944453331c4b30181704cbcec5a792ab87c5ccff256e0b4d61ba6a30a6964783875018882e66bfbd9445ac44fee9dc67edc2ad9de78adbe0eb7e9cb990272183ce5fac682ee5106f67d732cd16dfb731239590ba67dc827e849c49a9fb5ed8eed41d85d5e6de3294e74f3524c6489c2f25482ff52f9ea29c928b25030bec09207'),
|
||||
}],
|
||||
["sendMessage",
|
||||
{
|
||||
smsText: "B",
|
||||
expectedCiphertext: hexToArrayBuffer('3308c08dab01122105d51a5f0d744180bf49d1b71b5d77a66db9664a4806d8470b99bed6311b7ed1681a210596857fd3566a584bb7ff0664df4d11cfdba8e1a445e0930a527b7b139c6a897322d301330a210577874cb60271862f343d52984224e2558f828f336d68bd14fa4aaf5a1692be7d1001180022a00138b6a0e9b02bd7347e7428cc443df228b7a58a28456812d0f100985937ac08cf729f8be6a38596d3611c035352845f9732901a42e3dd4761be43d231edba5a56bcd60f3534e8872816a1c9eed4383ec0cb958ce2e66f00f8e5c90c13ebe44af5516df5cb41dfb74818795881633e19fefe562d3e89013aafba0aa672dab3e418b02f3a5c4c28d1be1a47bf3a79a95cccf071debe38a093dab22027296bfb0caa892317d15c715b8c28b84c308f90af07'),
|
||||
expectedCiphertext: hexToArrayBuffer('3308c7b899021221058a49fa8a94224aaa8f5873404e01710ff9ef02169a75f90af4fbbc600796e0521a21050a6cf5e075c9970f14862db8a703a6c761f50b5182d17874908940556a22372222d301330a2105883ab58b3eb6db93b32bf91899a5b5175e7b21e96fff2cec02c83dff16ba1b271001180022a001256aae85babf8c0808f75e08bf10a63f7f3aea97324c2583d777f609df493d7d45232c8883c3e1118fbc29b6318a3091ae57fed4f1c54458c6bb832fbb35f24933cb79765d00f4a161e2877a5a21a26592cdb0aa8a2f70f5fbe8c601ecdff0bef1b733d7fd0cb7b7d8fc1e45f79c016c8f90449239ca1a04b374538f2760eef43127ddc9a6439c6ceca5faf5962fb26d7248257d4d5ee3fe4cf8795acc555718558e5317f618828328b25030bec09207'),
|
||||
}],
|
||||
["receiveMessage",
|
||||
{
|
||||
message: hexToArrayBuffer('330a210519549798b47a051f48291f03140179329c03de0243459c5283d7b31d65b3ec661000180022a001dce182f136cc10858ecb48cd3299882de15006b179626f13d85f9353f64782df6afafefee527bab4ad7aedeb5863fdd0641d3db8bed305b4b64df6d1d39fa262058066430ea1fdd019b76cfcef4ae412214dd37f5a3e4270d48e278455fe94e2bd99940ec562703e45bbeab9a0a147e6e66af6b8188cb8bf7eaf18d601eb7637055e5528afce2e4a48ac49915a15aa23750f24644777a4c609f0f2fb4cbe93934dc8144f2ea3c888'),
|
||||
message: hexToArrayBuffer('330a2105bc81f1348a1d065b2bd2776edb9f29bc4150399db35c1d87dc258b94894bc57a1000180022a001c93af1107634d9eaa1516a4f8e95c6a454c27313b38830709eb863608f08f2f3a598ff8f558645427f7b6ea8e182e40f7b4a92ce0325f2e22f76f36f6954f6f391dd21d2cad12e5b620e75b991e69df8821ab0e826e3cb2ae1c7a1fb8ed72213e36fc508ca1f0a92ebe2089535b5d5e1b34eae5f91497bd072de47de3291ba78a6fd67d3f8f3f20d04ab3a1159df8f36ef7e4696847e32ce6be07edb93763a2226c87feff8cc4827'),
|
||||
type: 1,
|
||||
newEphemeralKey: hexToArrayBuffer('d872c0de95e128656ddb3a2ac422ab9c5273415f6e55996a5dd395f915472052'),
|
||||
newEphemeralKey: hexToArrayBuffer('d04f334799ea1272eff64c5267e28274f54b91b3b11372879303eb7a8cd52763'),
|
||||
expectedSmsText: "C",
|
||||
}],
|
||||
["receiveMessage",
|
||||
{
|
||||
message: hexToArrayBuffer('330a210519549798b47a051f48291f03140179329c03de0243459c5283d7b31d65b3ec661001180022a0014428b3743a7be1682237400d3997a6ccccc7aecbed3192d819e05b5dad8bd91d3ca1fcb39a6187a8c9fe1e0216f37aecb0178cf0f2998a1177e611f0f0ab18a1d528541eda02137a45b388377a13387e65c4bbdd468fa2da77e4de567828914225de8d27ed62e05d2da32b9ae19ac37cf903990973eef8616d58ab2b67848526244980f3827aee4e56d715500adac8f6d93fd8dd24d00a3a3e001a1f4b86049195f2d93815efd3f3'),
|
||||
message: hexToArrayBuffer('330a2105bc81f1348a1d065b2bd2776edb9f29bc4150399db35c1d87dc258b94894bc57a1001180022a001eb52c72c7bb6b8878c96398cc05810382d29fc17644f88bdc8d57509e8a734626620ae243cb740466806ee3c64bbf12957d5ac0452a17aba6c0e10e2a82626a986df0c4e5cadebb9ce824f1af4fac85cf7d1b9b7cf37f5df06d77b901d0e2aaa772b49f838ec92a67d13b4d7908cf91f7e0a54ad031b2aa4a954180b652f0696350e4f286592e24cc83091b196f2d48397241e33acaf6f65be27af12f1a8af91fd1daf2c01bdfaaa'),
|
||||
type: 1,
|
||||
expectedSmsText: "D",
|
||||
}],
|
||||
["sendMessage",
|
||||
{
|
||||
smsText: "E",
|
||||
expectedCiphertext: hexToArrayBuffer('330a21052f7f7ab6e0d172b8fcab6f7e4b7adef1dc25205d3642e665f11f5681798d99451000180122a001e492d8b25eaec22f39ff1c8cac2e8ac164d0ebb5894c20330e20ebce6dc58ea0469b3e0075657eebc6e04c1da3aed6d8ab7631412a017cc20bf18b433d2ead4fd40320e9093b8be5565d581fd679a3c296edeb463638353422ead082239f7047537c79a749d4949e3a21d98ec873506d27c5f1abea28d2faddd1f5d4e26c1633eaa213af5372daf8d76308097d54a97cee1164f2302784f21f6808d031a5650f8598069de06473b1'),
|
||||
expectedCiphertext: hexToArrayBuffer('330a2105576f3c29717db75ffd19a37154d4d6beba8d796a26c4244793132f7e6cb180491000180122a001bd139a95021d34d9df74d99aa897981aa6718fd6b72d8567891afff92c6e3534ded0de80be7e7c58730a001f2acc1f1e6447f9ca0a99681f3f65d9a4072f3a1fb978740918d3db5c346170edb3bf8fec2b52362edf7138f93cb23a3f17b0f40bf9769e01273955b14c20b6212cbb1f665d1a7e5e770437a53b1727c13bcd639bf5beba71893b8de435244acddc42c3ba592b7debdacdc4dea12dc7e4e670753419be0455e0043f91'),
|
||||
}],
|
||||
];
|
||||
// Now change the order and make 2 tests out of them:
|
||||
|
@ -73,37 +73,37 @@ axolotlTestVectors = function() {
|
|||
var axolotlTwoPartyTestVectorsBob = [
|
||||
["receiveMessage",
|
||||
{
|
||||
message: hexToArrayBuffer('3308c08dab01122105d51a5f0d744180bf49d1b71b5d77a66db9664a4806d8470b99bed6311b7ed1681a210596857fd3566a584bb7ff0664df4d11cfdba8e1a445e0930a527b7b139c6a897322d301330a210577874cb60271862f343d52984224e2558f828f336d68bd14fa4aaf5a1692be7d1000180022a001fa2af5c8688440c0bc45121ae2f6b9c6d5b8cf00acfee0d1a45f9e7b245636e1fa63b3062e2a6a9cd8be9096c375b413f71c2bb18054738c8440d1aa52997899d8bcedee6a93f6a295bdaf488e81188a9c88c4e841eb772b3194576c52bd8ef8fcbc5c29545fa38d2213c84d088f9843307f45c3254927f97c6f0afca9737a00d09146284f8948bbe69c755e47e6e571887bf57959b228ba9c2418f7bfc780b7bf1adbffd96276f328b84c308f90af07'),
|
||||
message: hexToArrayBuffer('3308c7b899021221058a49fa8a94224aaa8f5873404e01710ff9ef02169a75f90af4fbbc600796e0521a21050a6cf5e075c9970f14862db8a703a6c761f50b5182d17874908940556a22372222d301330a2105883ab58b3eb6db93b32bf91899a5b5175e7b21e96fff2cec02c83dff16ba1b271000180022a0013c5d070d1b75c418cef769bd7378a58969537a00e0ff60cbb99defb486fcfb43384264da4ea9821c1336f02d988da38944453331c4b30181704cbcec5a792ab87c5ccff256e0b4d61ba6a30a6964783875018882e66bfbd9445ac44fee9dc67edc2ad9de78adbe0eb7e9cb990272183ce5fac682ee5106f67d732cd16dfb731239590ba67dc827e849c49a9fb5ed8eed41d85d5e6de3294e74f3524c6489c2f25482ff52f9ea29c928b25030bec09207'),
|
||||
type: 3,
|
||||
ourPreKey: hexToArrayBuffer('40a5ce4c6e21c2e686bed765c854b010117ea26fb08438994d84ffa516c7d84e'),
|
||||
preKeyId: 2803392,
|
||||
ourSignedPreKey: hexToArrayBuffer('280d9e0067b68c877c48120d400f5a16c0b3e74374149751777d1f3c49b2b355'),
|
||||
signedPreKeyId: 15452175,
|
||||
ourIdentityKey: hexToArrayBuffer('b8ee332fd87c5544ccd52afa8ce55140b25fd4ca4441a232799fe474ff4cae79'),
|
||||
newEphemeralKey: hexToArrayBuffer('400146d280077821aacaed96ad75b99ab665d2530ef5c061fad0e24bac285640'),
|
||||
ourPreKey: hexToArrayBuffer('88d9a12e7b03afdac42e49ec9d4e5488e1b1e6d48c6eef6029e45dec09a9d562'),
|
||||
preKeyId: 4611143,
|
||||
ourSignedPreKey: hexToArrayBuffer('888b3f14aff80e36bb2d2cc26a72da2e1a99330962f5066c7c1dded1262ca665'),
|
||||
signedPreKeyId: 14983230,
|
||||
ourIdentityKey: hexToArrayBuffer('58c9fb2ec2c6b13e279e7db57ce837c02aac1531504f71130d167cc8fb25a857'),
|
||||
newEphemeralKey: hexToArrayBuffer('f0b66ac79b6f4ae997636bc8ed622a184dbe00603b2c657ac18800122523d142'),
|
||||
expectedSmsText: "A",
|
||||
}],
|
||||
["receiveMessage",
|
||||
{
|
||||
message: hexToArrayBuffer('3308c08dab01122105d51a5f0d744180bf49d1b71b5d77a66db9664a4806d8470b99bed6311b7ed1681a210596857fd3566a584bb7ff0664df4d11cfdba8e1a445e0930a527b7b139c6a897322d301330a210577874cb60271862f343d52984224e2558f828f336d68bd14fa4aaf5a1692be7d1001180022a00138b6a0e9b02bd7347e7428cc443df228b7a58a28456812d0f100985937ac08cf729f8be6a38596d3611c035352845f9732901a42e3dd4761be43d231edba5a56bcd60f3534e8872816a1c9eed4383ec0cb958ce2e66f00f8e5c90c13ebe44af5516df5cb41dfb74818795881633e19fefe562d3e89013aafba0aa672dab3e418b02f3a5c4c28d1be1a47bf3a79a95cccf071debe38a093dab22027296bfb0caa892317d15c715b8c28b84c308f90af07'),
|
||||
message: hexToArrayBuffer('3308c7b899021221058a49fa8a94224aaa8f5873404e01710ff9ef02169a75f90af4fbbc600796e0521a21050a6cf5e075c9970f14862db8a703a6c761f50b5182d17874908940556a22372222d301330a2105883ab58b3eb6db93b32bf91899a5b5175e7b21e96fff2cec02c83dff16ba1b271001180022a001256aae85babf8c0808f75e08bf10a63f7f3aea97324c2583d777f609df493d7d45232c8883c3e1118fbc29b6318a3091ae57fed4f1c54458c6bb832fbb35f24933cb79765d00f4a161e2877a5a21a26592cdb0aa8a2f70f5fbe8c601ecdff0bef1b733d7fd0cb7b7d8fc1e45f79c016c8f90449239ca1a04b374538f2760eef43127ddc9a6439c6ceca5faf5962fb26d7248257d4d5ee3fe4cf8795acc555718558e5317f618828328b25030bec09207'),
|
||||
type: 3,
|
||||
expectedSmsText: "B",
|
||||
}],
|
||||
["sendMessage",
|
||||
{
|
||||
smsText: "C",
|
||||
expectedCiphertext: hexToArrayBuffer('330a210519549798b47a051f48291f03140179329c03de0243459c5283d7b31d65b3ec661000180022a001dce182f136cc10858ecb48cd3299882de15006b179626f13d85f9353f64782df6afafefee527bab4ad7aedeb5863fdd0641d3db8bed305b4b64df6d1d39fa262058066430ea1fdd019b76cfcef4ae412214dd37f5a3e4270d48e278455fe94e2bd99940ec562703e45bbeab9a0a147e6e66af6b8188cb8bf7eaf18d601eb7637055e5528afce2e4a48ac49915a15aa23750f24644777a4c609f0f2fb4cbe93934dc8144f2ea3c888'),
|
||||
expectedCiphertext: hexToArrayBuffer('330a2105bc81f1348a1d065b2bd2776edb9f29bc4150399db35c1d87dc258b94894bc57a1000180022a001c93af1107634d9eaa1516a4f8e95c6a454c27313b38830709eb863608f08f2f3a598ff8f558645427f7b6ea8e182e40f7b4a92ce0325f2e22f76f36f6954f6f391dd21d2cad12e5b620e75b991e69df8821ab0e826e3cb2ae1c7a1fb8ed72213e36fc508ca1f0a92ebe2089535b5d5e1b34eae5f91497bd072de47de3291ba78a6fd67d3f8f3f20d04ab3a1159df8f36ef7e4696847e32ce6be07edb93763a2226c87feff8cc4827'),
|
||||
}],
|
||||
["sendMessage",
|
||||
{
|
||||
smsText: "D",
|
||||
expectedCiphertext: hexToArrayBuffer('330a210519549798b47a051f48291f03140179329c03de0243459c5283d7b31d65b3ec661001180022a0014428b3743a7be1682237400d3997a6ccccc7aecbed3192d819e05b5dad8bd91d3ca1fcb39a6187a8c9fe1e0216f37aecb0178cf0f2998a1177e611f0f0ab18a1d528541eda02137a45b388377a13387e65c4bbdd468fa2da77e4de567828914225de8d27ed62e05d2da32b9ae19ac37cf903990973eef8616d58ab2b67848526244980f3827aee4e56d715500adac8f6d93fd8dd24d00a3a3e001a1f4b86049195f2d93815efd3f3'),
|
||||
expectedCiphertext: hexToArrayBuffer('330a2105bc81f1348a1d065b2bd2776edb9f29bc4150399db35c1d87dc258b94894bc57a1001180022a001eb52c72c7bb6b8878c96398cc05810382d29fc17644f88bdc8d57509e8a734626620ae243cb740466806ee3c64bbf12957d5ac0452a17aba6c0e10e2a82626a986df0c4e5cadebb9ce824f1af4fac85cf7d1b9b7cf37f5df06d77b901d0e2aaa772b49f838ec92a67d13b4d7908cf91f7e0a54ad031b2aa4a954180b652f0696350e4f286592e24cc83091b196f2d48397241e33acaf6f65be27af12f1a8af91fd1daf2c01bdfaaa'),
|
||||
}],
|
||||
["receiveMessage",
|
||||
{
|
||||
message: hexToArrayBuffer('330a21052f7f7ab6e0d172b8fcab6f7e4b7adef1dc25205d3642e665f11f5681798d99451000180122a001e492d8b25eaec22f39ff1c8cac2e8ac164d0ebb5894c20330e20ebce6dc58ea0469b3e0075657eebc6e04c1da3aed6d8ab7631412a017cc20bf18b433d2ead4fd40320e9093b8be5565d581fd679a3c296edeb463638353422ead082239f7047537c79a749d4949e3a21d98ec873506d27c5f1abea28d2faddd1f5d4e26c1633eaa213af5372daf8d76308097d54a97cee1164f2302784f21f6808d031a5650f8598069de06473b1'),
|
||||
message: hexToArrayBuffer('330a2105576f3c29717db75ffd19a37154d4d6beba8d796a26c4244793132f7e6cb180491000180122a001bd139a95021d34d9df74d99aa897981aa6718fd6b72d8567891afff92c6e3534ded0de80be7e7c58730a001f2acc1f1e6447f9ca0a99681f3f65d9a4072f3a1fb978740918d3db5c346170edb3bf8fec2b52362edf7138f93cb23a3f17b0f40bf9769e01273955b14c20b6212cbb1f665d1a7e5e770437a53b1727c13bcd639bf5beba71893b8de435244acddc42c3ba592b7debdacdc4dea12dc7e4e670753419be0455e0043f91'),
|
||||
type: 1,
|
||||
newEphemeralKey: hexToArrayBuffer('b89a87781558e4e9d19ebefa103c1ccdb20b573678f0753500376decfa975e71'),
|
||||
newEphemeralKey: hexToArrayBuffer('98bee5f861b528816888d45c2ca40125b111d2c03e483e57e6886c82dd758467'),
|
||||
expectedSmsText: "E",
|
||||
}],
|
||||
];
|
||||
|
@ -466,6 +466,7 @@ axolotlTestVectors = function() {
|
|||
*/
|
||||
|
||||
//TODO: GROUPS
|
||||
//TODO: Sender changes identity key?
|
||||
|
||||
return tests;
|
||||
}();
|
|
@ -46,7 +46,6 @@
|
|||
<script type="text/javascript" src="../sendmessage.js" data-cover></script>
|
||||
|
||||
<script type="text/javascript" src="fake_api.js"></script>
|
||||
<script type="text/javascript" src="testvectors.js"></script>
|
||||
<script type="text/javascript" src="helpers_test.js"></script>
|
||||
<script type="text/javascript" src="websocket-resources_test.js"></script>
|
||||
<script type="text/javascript" src="protocol_test.js"></script>
|
||||
|
|
|
@ -40,193 +40,5 @@ describe('Protocol', function() {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe("Identity and Pre Key Creation", function() {
|
||||
this.timeout(200000);
|
||||
before(function() { localStorage.clear(); });
|
||||
after(function() { localStorage.clear(); });
|
||||
it ('works', function(done) {
|
||||
localStorage.clear();
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeyidentityKey"));
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeysignedKey0"));
|
||||
for (var i = 0; i < 100; i++) {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeypreKey" + i));
|
||||
}
|
||||
var origIdentityKey = getString(textsecure.storage.getEncrypted("25519KeyidentityKey").privKey);
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeyidentityKey"));
|
||||
assert.equal(getString(textsecure.storage.getEncrypted("25519KeyidentityKey").privKey), origIdentityKey);
|
||||
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeysignedKey0"));
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeysignedKey1"));
|
||||
|
||||
for (var i = 0; i < 200; i++) {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeypreKey" + i));
|
||||
}
|
||||
|
||||
return axolotl.protocol.generateKeys().then(function() {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeyidentityKey"));
|
||||
assert.equal(getString(textsecure.storage.getEncrypted("25519KeyidentityKey").privKey), origIdentityKey);
|
||||
|
||||
assert.isUndefined(textsecure.storage.getEncrypted("25519KeysignedKey0"));
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeysignedKey1"));
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeysignedKey2"));
|
||||
|
||||
for (var i = 0; i < 300; i++) {
|
||||
assert.isDefined(textsecure.storage.getEncrypted("25519KeypreKey" + i));
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(done).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Axolotl", function() {
|
||||
var runAxolotlTest = function(v) {
|
||||
var origCreateKeyPair = axolotl.crypto.createKeyPair;
|
||||
var doStep;
|
||||
var stepDone;
|
||||
|
||||
stepDone = function(res) {
|
||||
if (!res || privKeyQueue.length != 0 || Object.keys(getKeysForNumberMap).length != 0 || Object.keys(messagesSentMap).length != 0) {
|
||||
axolotl.crypto.createKeyPair = origCreateKeyPair;
|
||||
return false;
|
||||
} else if (step == v.length) {
|
||||
axolotl.crypto.createKeyPair = origCreateKeyPair;
|
||||
return true;
|
||||
} else
|
||||
return doStep().then(stepDone);
|
||||
}
|
||||
|
||||
var privKeyQueue = [];
|
||||
axolotl.crypto.createKeyPair = function(privKey) {
|
||||
if (privKey !== undefined)
|
||||
return origCreateKeyPair(privKey);
|
||||
if (privKeyQueue.length == 0)
|
||||
throw new Error('Out of private keys');
|
||||
else {
|
||||
var privKey = privKeyQueue.shift();
|
||||
return axolotl.crypto.createKeyPair(privKey).then(function(keyPair) {
|
||||
var a = btoa(getString(keyPair.privKey)); var b = btoa(getString(privKey));
|
||||
if (getString(keyPair.privKey) != getString(privKey))
|
||||
throw new Error('Failed to rederive private key!');
|
||||
else
|
||||
return keyPair;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var step = 0;
|
||||
var doStep = function() {
|
||||
var data = v[step][1];
|
||||
|
||||
switch(v[step++][0]) {
|
||||
case "receiveMessage":
|
||||
var postLocalKeySetup = function() {
|
||||
if (data.newEphemeralKey !== undefined)
|
||||
privKeyQueue.push(data.newEphemeralKey);
|
||||
|
||||
var message = new textsecure.protobuf.IncomingPushMessageSignal();
|
||||
message.type = data.type;
|
||||
message.source = "SNOWDEN";
|
||||
message.message = data.message;
|
||||
message.sourceDevice = 1;
|
||||
try {
|
||||
var proto = textsecure.protobuf.IncomingPushMessageSignal.decode(message.encode());
|
||||
return textsecure.protocol_wrapper.handleIncomingPushMessageProto(proto).then(function(res) {
|
||||
if (data.expectTerminateSession)
|
||||
return res.flags == textsecure.protobuf.PushMessageContent.Flags.END_SESSION;
|
||||
return res.body == data.expectedSmsText;
|
||||
}).catch(function(e) {
|
||||
if (data.expectException)
|
||||
return true;
|
||||
throw e;
|
||||
});
|
||||
} catch(e) {
|
||||
if (data.expectException)
|
||||
return Promise.resolve(true);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
|
||||
textsecure.storage.putEncrypted("25519KeyidentityKey", keyPair);
|
||||
return axolotl.crypto.createKeyPair(data.ourSignedPreKey).then(function(keyPair) {
|
||||
textsecure.storage.putEncrypted("25519KeysignedKey" + data.signedPreKeyId, keyPair);
|
||||
|
||||
if (data.ourPreKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourPreKey).then(function(keyPair) {
|
||||
textsecure.storage.putEncrypted("25519KeypreKey" + data.preKeyId, keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
|
||||
case "sendMessage":
|
||||
var postLocalKeySetup = function() {
|
||||
if (data.registrationId !== undefined)
|
||||
textsecure.storage.putUnencrypted("registrationId", data.registrationId);
|
||||
|
||||
if (data.getKeys !== undefined)
|
||||
getKeysForNumberMap["SNOWDEN"] = data.getKeys;
|
||||
|
||||
var checkMessage = function() {
|
||||
var msg = messagesSentMap["SNOWDEN.1"];
|
||||
delete messagesSentMap["SNOWDEN.1"];
|
||||
//XXX: This should be all we do: isEqual(data.expectedCiphertext, msg.body, false);
|
||||
if (msg.type == 1) {
|
||||
var expected = getString(data.expectedCiphertext);
|
||||
var decoded = axolotl.protobuf.WhisperMessage.decode(expected.substring(1, expected.length - 8), 'binary');
|
||||
var result = getString(msg.body);
|
||||
return getString(decoded.encode()) == result.substring(1, result.length - 8);
|
||||
} else {
|
||||
var decoded = axolotl.protobuf.PreKeyWhisperMessage.decode(getString(data.expectedCiphertext).substr(1), 'binary');
|
||||
var result = getString(msg.body).substring(1);
|
||||
return getString(decoded.encode()) == result;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.endSession)
|
||||
return textsecure.messaging.closeSession("SNOWDEN").then(checkMessage);
|
||||
else
|
||||
return textsecure.messaging.sendMessageToNumber("SNOWDEN", data.smsText, [], Date.now()).then(checkMessage);
|
||||
}
|
||||
|
||||
if (data.ourBaseKey !== undefined)
|
||||
privKeyQueue.push(data.ourBaseKey);
|
||||
if (data.ourEphemeralKey !== undefined)
|
||||
privKeyQueue.push(data.ourEphemeralKey);
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
|
||||
textsecure.storage.putEncrypted("25519KeyidentityKey", keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
else
|
||||
return postLocalKeySetup();
|
||||
|
||||
default:
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
return doStep().then(stepDone);
|
||||
};
|
||||
|
||||
describe("test vectors", function() {
|
||||
for (var i in axolotlTestVectors) {
|
||||
it(axolotlTestVectors[i].name, function(done) {
|
||||
localStorage.clear();
|
||||
return runAxolotlTest(axolotlTestVectors[i].vectors).then(function(res) {
|
||||
assert(res);
|
||||
}).then(done).catch(done);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
// TODO: Use fake_api's hiding of api.sendMessage to test sendmessage.js' maze
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue