Naively move textsecure.crypto into axolotl.crypto

This commit is contained in:
Matt Corallo 2015-01-14 13:55:30 -10:00 committed by lilia
parent 849fdb7ae4
commit 66cf5b08db
13 changed files with 16433 additions and 65 deletions

View file

@ -109,6 +109,14 @@ module.exports = function(grunt) {
'libtextsecure/test/_test.js'
],
dest: 'libtextsecure/test/test.js',
},
libaxolotltest: {
src: [
'components/mocha/mocha.js',
'components/chai/chai.js',
'libaxolotl/test/_test.js'
],
dest: 'libaxolotl/test/test.js',
}
},
sass: {
@ -167,7 +175,7 @@ module.exports = function(grunt) {
'saucelabs-mocha': {
all: {
options: {
urls: ['http://127.0.0.1:9999/test/index.html', 'http://127.0.0.1:9999/libtextsecure/test/index.html'],
urls: ['http://127.0.0.1:9999/test/index.html', 'http://127.0.0.1:9999/libtextsecure/test/index.html', 'http://127.0.0.1:9999/libaxolotl/test/index.html'],
build: process.env.TRAVIS_JOB_ID,
browsers: [{ browserName: 'chrome', version: '38' }, { browserName: 'firefox', version: '34' }],
testname: 'TextSecure-Browser Tests'

View file

@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
;(function() {
window.textsecure = window.textsecure || {};
window.axolotl = window.axolotl || {};
/*
* textsecure.crypto
@ -22,7 +22,7 @@
* for all low-level crypto operations,
*/
window.textsecure.crypto = {
window.axolotl.crypto = {
getRandomBytes: function(size) {
// At some point we might consider XORing in hashes of random
// UI events to strengthen ourselves against RNG flaws in crypto.getRandomValues
@ -50,18 +50,18 @@
HKDF: function(input, salt, info) {
// Specific implementation of RFC 5869 that only returns the first 3 32-byte chunks
// TODO: We dont always need the third chunk, we might skip it
return window.textsecure.crypto.sign(salt, input).then(function(PRK) {
return window.axolotl.crypto.sign(salt, input).then(function(PRK) {
var infoBuffer = new ArrayBuffer(info.byteLength + 1 + 32);
var infoArray = new Uint8Array(infoBuffer);
infoArray.set(new Uint8Array(info), 32);
infoArray[infoArray.length - 1] = 1;
return window.textsecure.crypto.sign(PRK, infoBuffer.slice(32)).then(function(T1) {
return window.axolotl.crypto.sign(PRK, infoBuffer.slice(32)).then(function(T1) {
infoArray.set(new Uint8Array(T1));
infoArray[infoArray.length - 1] = 2;
return window.textsecure.crypto.sign(PRK, infoBuffer).then(function(T2) {
return window.axolotl.crypto.sign(PRK, infoBuffer).then(function(T2) {
infoArray.set(new Uint8Array(T2));
infoArray[infoArray.length - 1] = 3;
return window.textsecure.crypto.sign(PRK, infoBuffer).then(function(T3) {
return window.axolotl.crypto.sign(PRK, infoBuffer).then(function(T3) {
return [ T1, T2, T3 ];
});
});
@ -72,7 +72,7 @@
// Curve 25519 crypto
createKeyPair: function(privKey) {
if (privKey === undefined) {
privKey = textsecure.crypto.getRandomBytes(32);
privKey = axolotl.crypto.getRandomBytes(32);
}
if (privKey.byteLength != 32) {
throw new Error("Invalid private key");

View file

@ -47,7 +47,7 @@ window.textsecure.protocol = function() {
}
crypto_storage.getNewStoredKeyPair = function(keyName) {
return textsecure.crypto.createKeyPair().then(function(keyPair) {
return axolotl.crypto.createKeyPair().then(function(keyPair) {
crypto_storage.putKeyPair(keyName, keyPair);
return keyPair;
});
@ -191,11 +191,11 @@ window.textsecure.protocol = function() {
info = toArrayBuffer(info); // TODO: maybe convert calls?
return textsecure.crypto.HKDF(input, salt, info);
return axolotl.crypto.HKDF(input, salt, info);
}
var verifyMAC = function(data, key, mac) {
return textsecure.crypto.sign(key, data).then(function(calculated_mac) {
return axolotl.crypto.sign(key, data).then(function(calculated_mac) {
if (!isEqual(calculated_mac, mac, true))
throw new Error("Bad MAC");
});
@ -207,7 +207,7 @@ window.textsecure.protocol = function() {
var calculateRatchet = function(session, remoteKey, sending) {
var ratchet = session.currentRatchet;
return textsecure.crypto.ECDHE(remoteKey, toArrayBuffer(ratchet.ephemeralKeyPair.privKey)).then(function(sharedSecret) {
return axolotl.crypto.ECDHE(remoteKey, toArrayBuffer(ratchet.ephemeralKeyPair.privKey)).then(function(sharedSecret) {
return HKDF(sharedSecret, toArrayBuffer(ratchet.rootKey), "WhisperRatchet").then(function(masterKey) {
if (sending)
session[getString(ratchet.ephemeralKeyPair.pubKey)] = { messageKeys: {}, chainKey: { counter: -1, key: masterKey[1] } };
@ -240,9 +240,9 @@ window.textsecure.protocol = function() {
for (var i = 0; i < 32; i++)
sharedSecret[i] = 0xff;
return textsecure.crypto.ECDHE(theirSignedPubKey, ourIdentityKey.privKey).then(function(ecRes1) {
return axolotl.crypto.ECDHE(theirSignedPubKey, ourIdentityKey.privKey).then(function(ecRes1) {
function finishInit() {
return textsecure.crypto.ECDHE(theirSignedPubKey, ourSignedKey.privKey).then(function(ecRes) {
return axolotl.crypto.ECDHE(theirSignedPubKey, ourSignedKey.privKey).then(function(ecRes) {
sharedSecret.set(new Uint8Array(ecRes), 32 * 3);
return HKDF(sharedSecret.buffer, '', "WhisperText").then(function(masterKey) {
@ -258,7 +258,7 @@ window.textsecure.protocol = function() {
// If we're initiating we go ahead and set our first sending ephemeral key now,
// otherwise we figure it out when we first maybeStepRatchet with the remote's ephemeral key
if (isInitiator) {
return textsecure.crypto.createKeyPair().then(function(ourSendingEphemeralKey) {
return axolotl.crypto.createKeyPair().then(function(ourSendingEphemeralKey) {
session.currentRatchet.ephemeralKeyPair = ourSendingEphemeralKey;
return calculateRatchet(session, theirSignedPubKey, true).then(function() {
return session;
@ -276,17 +276,17 @@ window.textsecure.protocol = function() {
if (ourEphemeralKey === undefined || theirEphemeralPubKey === undefined)
promise = Promise.resolve(new ArrayBuffer(0));
else
promise = textsecure.crypto.ECDHE(theirEphemeralPubKey, ourEphemeralKey.privKey);
promise = axolotl.crypto.ECDHE(theirEphemeralPubKey, ourEphemeralKey.privKey);
return promise.then(function(ecRes4) {
sharedSecret.set(new Uint8Array(ecRes4), 32 * 4);
if (isInitiator)
return textsecure.crypto.ECDHE(theirIdentityPubKey, ourSignedKey.privKey).then(function(ecRes2) {
return axolotl.crypto.ECDHE(theirIdentityPubKey, ourSignedKey.privKey).then(function(ecRes2) {
sharedSecret.set(new Uint8Array(ecRes1), 32);
sharedSecret.set(new Uint8Array(ecRes2), 32 * 2);
}).then(finishInit);
else
return textsecure.crypto.ECDHE(theirIdentityPubKey, ourSignedKey.privKey).then(function(ecRes2) {
return axolotl.crypto.ECDHE(theirIdentityPubKey, ourSignedKey.privKey).then(function(ecRes2) {
sharedSecret.set(new Uint8Array(ecRes1), 32 * 2);
sharedSecret.set(new Uint8Array(ecRes2), 32)
}).then(finishInit);
@ -430,9 +430,9 @@ window.textsecure.protocol = function() {
var key = toArrayBuffer(chain.chainKey.key);
var byteArray = new Uint8Array(1);
byteArray[0] = 1;
return textsecure.crypto.sign(key, byteArray.buffer).then(function(mac) {
return axolotl.crypto.sign(key, byteArray.buffer).then(function(mac) {
byteArray[0] = 2;
return textsecure.crypto.sign(key, byteArray.buffer).then(function(key) {
return axolotl.crypto.sign(key, byteArray.buffer).then(function(key) {
chain.messageKeys[chain.chainKey.counter + 1] = mac;
chain.chainKey.key = key
chain.chainKey.counter += 1;
@ -456,7 +456,7 @@ window.textsecure.protocol = function() {
delete session[previousRatchet];
}
return textsecure.crypto.createKeyPair().then(function(keyPair) {
return axolotl.crypto.createKeyPair().then(function(keyPair) {
ratchet.ephemeralKeyPair = keyPair;
return calculateRatchet(session, remoteKey, true).then(function() {
ratchet.lastRemoteEphemeralKey = remoteKey;
@ -510,7 +510,7 @@ window.textsecure.protocol = function() {
macInput.set(new Uint8Array(messageProtoArray), 33*2 + 1);
return verifyMAC(macInput.buffer, keys[1], mac).then(function() {
return window.textsecure.crypto.decrypt(keys[0], toArrayBuffer(message.ciphertext), keys[2].slice(0, 16))
return window.axolotl.crypto.decrypt(keys[0], toArrayBuffer(message.ciphertext), keys[2].slice(0, 16))
.then(function(paddedPlaintext) {
paddedPlaintext = new Uint8Array(paddedPlaintext);
@ -563,7 +563,7 @@ window.textsecure.protocol = function() {
var mac = decodedMessage.slice(decodedMessage.byteLength - 10, decodedMessage.byteLength);
return verifyMAC(ivAndCiphertext, mac_key, mac).then(function() {
return window.textsecure.crypto.decrypt(aes_key, ciphertext, iv);
return window.axolotl.crypto.decrypt(aes_key, ciphertext, iv);
});
};
@ -577,7 +577,7 @@ window.textsecure.protocol = function() {
var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength);
return verifyMAC(ivAndCiphertext, mac_key, mac).then(function() {
return window.textsecure.crypto.decrypt(aes_key, ciphertext, iv);
return window.axolotl.crypto.decrypt(aes_key, ciphertext, iv);
});
};
@ -585,12 +585,12 @@ window.textsecure.protocol = function() {
var aes_key = keys.slice(0, 32);
var mac_key = keys.slice(32, 64);
return window.textsecure.crypto.encrypt(aes_key, plaintext, iv).then(function(ciphertext) {
return window.axolotl.crypto.encrypt(aes_key, plaintext, iv).then(function(ciphertext) {
var ivAndCiphertext = new Uint8Array(16 + ciphertext.byteLength);
ivAndCiphertext.set(new Uint8Array(iv));
ivAndCiphertext.set(new Uint8Array(ciphertext), 16);
return textsecure.crypto.sign(mac_key, ivAndCiphertext.buffer).then(function(mac) {
return axolotl.crypto.sign(mac_key, ivAndCiphertext.buffer).then(function(mac) {
var encryptedBin = new Uint8Array(16 + ciphertext.byteLength + 32);
encryptedBin.set(ivAndCiphertext);
encryptedBin.set(new Uint8Array(mac), 16 + ciphertext.byteLength);
@ -639,7 +639,7 @@ window.textsecure.protocol = function() {
msg.counter = chain.chainKey.counter;
msg.previousCounter = session.currentRatchet.previousCounter;
return window.textsecure.crypto.encrypt(keys[0], paddedPlaintext.buffer, keys[2].slice(0, 16)).then(function(ciphertext) {
return window.axolotl.crypto.encrypt(keys[0], paddedPlaintext.buffer, keys[2].slice(0, 16)).then(function(ciphertext) {
msg.ciphertext = ciphertext;
var encodedMsg = toArrayBuffer(msg.encode());
@ -649,7 +649,7 @@ window.textsecure.protocol = function() {
macInput[33*2] = (3 << 4) | 3;
macInput.set(new Uint8Array(encodedMsg), 33*2 + 1);
return textsecure.crypto.sign(keys[1], macInput.buffer).then(function(mac) {
return axolotl.crypto.sign(keys[1], macInput.buffer).then(function(mac) {
var result = new Uint8Array(encodedMsg.byteLength + 9);
result[0] = (3 << 4) | 3;
result.set(new Uint8Array(encodedMsg), 1);
@ -677,7 +677,7 @@ window.textsecure.protocol = function() {
preKeyMsg.registrationId = textsecure.storage.getUnencrypted("registrationId");
if (session === undefined) {
return textsecure.crypto.createKeyPair().then(function(baseKey) {
return axolotl.crypto.createKeyPair().then(function(baseKey) {
preKeyMsg.preKeyId = deviceObject.preKeyId;
preKeyMsg.signedPreKeyId = deviceObject.signedKeyId;
preKeyMsg.baseKey = toArrayBuffer(baseKey.pubKey);
@ -733,7 +733,7 @@ window.textsecure.protocol = function() {
promises[i] = generateKey(i);
promises[firstPreKeyId + GENERATE_KEYS_KEYS_GENERATED] = crypto_storage.getNewStoredKeyPair("signedKey" + signedKeyId).then(function(keyPair) {
return textsecure.crypto.Ed25519Sign(identityKeyPair.privKey, keyPair.pubKey).then(function(sig) {
return axolotl.crypto.Ed25519Sign(identityKeyPair.privKey, keyPair.pubKey).then(function(sig) {
keys.signedPreKey = {keyId: signedKeyId, publicKey: keyPair.pubKey, signature: sig};
});
});
@ -766,7 +766,7 @@ window.textsecure.protocol = function() {
var masterEphemeral = toArrayBuffer(deviceInit.publicKey);
var message = toArrayBuffer(deviceInit.body);
return textsecure.crypto.ECDHE(masterEphemeral, keyPair.privKey).then(function(ecRes) {
return axolotl.crypto.ECDHE(masterEphemeral, keyPair.privKey).then(function(ecRes) {
return HKDF(ecRes, '', "TextSecure Provisioning Message").then(function(keys) {
if (new Uint8Array(message)[0] != 1)
throw new Error("Bad version number on ProvisioningMessage");
@ -777,10 +777,10 @@ window.textsecure.protocol = function() {
var ciphertext = message.slice(16 + 1, message.byteLength - 32);
return verifyMAC(ivAndCiphertext, keys[1], mac).then(function() {
return window.textsecure.crypto.decrypt(keys[0], ciphertext, iv).then(function(plaintext) {
return window.axolotl.crypto.decrypt(keys[0], ciphertext, iv).then(function(plaintext) {
var identityKeyMsg = textsecure.protobuf.ProvisionMessage.decode(plaintext);
return textsecure.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKeyPrivate)).then(function(identityKeyPair) {
return axolotl.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKeyPrivate)).then(function(identityKeyPair) {
crypto_storage.putKeyPair("identityKey", identityKeyPair);
identityKeyMsg.identityKeyPrivate = null;
@ -792,7 +792,7 @@ window.textsecure.protocol = function() {
});
}
return textsecure.crypto.createKeyPair().then(function(newKeyPair) {
return axolotl.crypto.createKeyPair().then(function(newKeyPair) {
keyPair = newKeyPair;
socketInfo.pubKey = keyPair.pubKey;
return socketInfo;

69
libaxolotl/test/_test.js Normal file
View file

@ -0,0 +1,69 @@
/*
* 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/>.
*/
mocha.setup("bdd");
window.assert = chai.assert;
(function() {
var OriginalReporter = mocha._reporter;
var SauceReporter = function(runner) {
var failedTests = [];
runner.on('end', function() {
window.mochaResults = runner.stats;
window.mochaResults.reports = failedTests;
});
runner.on('fail', function(test, err) {
var flattenTitles = function(test) {
var titles = [];
while (test.parent.title) {
titles.push(test.parent.title);
test = test.parent;
}
return titles.reverse();
};
failedTests.push({
name: test.title,
result: false,
message: err.message,
stack: err.stack,
titles: flattenTitles(test)
});
});
new OriginalReporter(runner);
};
SauceReporter.prototype = OriginalReporter.prototype;
mocha.reporter(SauceReporter);
}());
/*
* global helpers for tests
*/
function assertEqualArrayBuffers(ab1, ab2) {
assert.deepEqual(new Uint8Array(ab1), new Uint8Array(ab2));
};
function hexToArrayBuffer(str) {
var ret = new ArrayBuffer(str.length / 2);
var array = new Uint8Array(ret);
for (var i = 0; i < str.length/2; i++)
array[i] = parseInt(str.substr(i*2, 2), 16);
return ret;
};

File diff suppressed because one or more lines are too long

View file

@ -24,7 +24,7 @@ describe("Crypto", function() {
var iv = hexToArrayBuffer('000102030405060708090a0b0c0d0e0f');
var plaintext = hexToArrayBuffer('6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710');
var ciphertext = hexToArrayBuffer('f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644');
window.textsecure.crypto.encrypt(key, plaintext, iv).then(function(result) {
window.axolotl.crypto.encrypt(key, plaintext, iv).then(function(result) {
assertEqualArrayBuffers(result, ciphertext);
}).then(done).catch(done);
});
@ -36,7 +36,7 @@ describe("Crypto", function() {
var iv = hexToArrayBuffer('000102030405060708090a0b0c0d0e0f');
var plaintext = hexToArrayBuffer('6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710');
var ciphertext = hexToArrayBuffer('f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644');
window.textsecure.crypto.decrypt(key, ciphertext, iv).then(function(result) {
window.axolotl.crypto.decrypt(key, ciphertext, iv).then(function(result) {
assertEqualArrayBuffers(result, plaintext);
}).then(done).catch(done);
});
@ -47,7 +47,7 @@ describe("Crypto", function() {
var key = hexToArrayBuffer('6f35628d65813435534b5d67fbdb54cb33403d04e843103e6399f806cb5df95febbdd61236f33245');
var input = hexToArrayBuffer('752cff52e4b90768558e5369e75d97c69643509a5e5904e0a386cbe4d0970ef73f918f675945a9aefe26daea27587e8dc909dd56fd0468805f834039b345f855cfe19c44b55af241fff3ffcd8045cd5c288e6c4e284c3720570b58e4d47b8feeedc52fd1401f698a209fccfa3b4c0d9a797b046a2759f82a54c41ccd7b5f592b');
var mac = hexToArrayBuffer('05d1243e6465ed9620c9aec1c351a186');
window.textsecure.crypto.sign(key, input).then(function(result) {
window.axolotl.crypto.sign(key, input).then(function(result) {
assertEqualArrayBuffers(result.slice(0, mac.byteLength), mac);
}).then(done).catch(done);
});
@ -71,7 +71,7 @@ describe("Crypto", function() {
for (var i = 0; i < 10; i++)
info[i] = 240 + i;
return textsecure.crypto.HKDF(IKM.buffer, salt.buffer, info.buffer).then(function(OKM){
return axolotl.crypto.HKDF(IKM.buffer, salt.buffer, info.buffer).then(function(OKM){
assertEqualArrayBuffers(OKM[0], T1);
assertEqualArrayBuffers(OKM[1].slice(0, 10), T2);
}).then(done).catch(done);
@ -88,21 +88,21 @@ describe("Crypto", function() {
describe("createKeyPair", function() {
it ('converts alice private keys to a keypair', function(done) {
textsecure.crypto.createKeyPair(alice_bytes).then(function(keypair) {
axolotl.crypto.createKeyPair(alice_bytes).then(function(keypair) {
assertEqualArrayBuffers(keypair.privKey, alice_priv);
assertEqualArrayBuffers(keypair.pubKey, alice_pub);
done();
}).catch(done);
});
it ('converts bob private keys to a keypair', function(done) {
textsecure.crypto.createKeyPair(bob_bytes).then(function(keypair) {
axolotl.crypto.createKeyPair(bob_bytes).then(function(keypair) {
assertEqualArrayBuffers(keypair.privKey, bob_priv);
assertEqualArrayBuffers(keypair.pubKey, bob_pub);
done();
}).catch(done);
});
it ('generates a key if one is not provided', function(done) {
textsecure.crypto.createKeyPair().then(function(keypair) {
axolotl.crypto.createKeyPair().then(function(keypair) {
assert.strictEqual(keypair.privKey.byteLength, 32);
assert.strictEqual(keypair.pubKey.byteLength, 33);
assert.strictEqual(new Uint8Array(keypair.pubKey)[0], 5);
@ -113,13 +113,13 @@ describe("Crypto", function() {
describe("ECDHE", function() {
it("computes the shared secret for alice", function(done) {
textsecure.crypto.ECDHE(bob_pub, alice_priv).then(function(secret) {
axolotl.crypto.ECDHE(bob_pub, alice_priv).then(function(secret) {
assertEqualArrayBuffers(shared_sec, secret);
done();
}).catch(done);
});
it("computes the shared secret for bob", function(done) {
textsecure.crypto.ECDHE(alice_pub, bob_priv).then(function(secret) {
axolotl.crypto.ECDHE(alice_pub, bob_priv).then(function(secret) {
assertEqualArrayBuffers(shared_sec, secret);
done();
}).catch(done);
@ -133,7 +133,7 @@ describe("Crypto", function() {
describe("Ed25519Sign", function() {
// Some self-generated test vectors
it('works', function(done) {
return textsecure.crypto.Ed25519Sign(priv, msg).then(function(sigCalc) {
return axolotl.crypto.Ed25519Sign(priv, msg).then(function(sigCalc) {
assertEqualArrayBuffers(sig, sigCalc);
}).then(done).catch(done);
});
@ -144,7 +144,7 @@ describe("Crypto", function() {
var badsig = sig.slice(0);
new Uint8Array(badsig).set([0], 0);
textsecure.crypto.Ed25519Verify(pub, msg, badsig).catch(function(e) {
axolotl.crypto.Ed25519Verify(pub, msg, badsig).catch(function(e) {
if (e.message === 'Invalid signature') {
done();
} else { throw e; }
@ -152,7 +152,7 @@ describe("Crypto", function() {
});
it("does not throw on good signature", function(done) {
return textsecure.crypto.Ed25519Verify(pub, msg, sig).then(done).catch(done);
return axolotl.crypto.Ed25519Verify(pub, msg, sig).then(done).catch(done);
});
});
});

View file

@ -0,0 +1,40 @@
<!--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/>.
-->
<html>
<head>
<title>libTextSecure test runner</title>
<link rel="stylesheet" href="../../components/mocha/mocha.css" />
</head>
<body>
<h2>Run this out of the chrome-plugin:// namespace (and expect plugin state to be cleared/corrupted), not file://</h2>
<div id="mocha">
</div>
<div id="tests">
</div>
<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="../crypto.js" data-cover></script>
<script type="text/javascript" src="crypto_test.js"></script>
</body>
</html>

10943
libaxolotl/test/test.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -196,7 +196,7 @@ window.textsecure.api = function () {
for (var i = 0; i < res.devices.length; i++) {
res.devices[i].signedPreKey.publicKey = StringView.base64ToBytes(res.devices[i].signedPreKey.publicKey);
res.devices[i].signedPreKey.signature = StringView.base64ToBytes(res.devices[i].signedPreKey.signature);
promises[i] = window.textsecure.crypto.Ed25519Verify(res.identityKey, res.devices[i].signedPreKey.publicKey, res.devices[i].signedPreKey.signature);
promises[i] = window.axolotl.crypto.Ed25519Verify(res.identityKey, res.devices[i].signedPreKey.publicKey, res.devices[i].signedPreKey.signature);
res.devices[i].preKey.publicKey = StringView.base64ToBytes(res.devices[i].preKey.publicKey);
//TODO: Is this still needed?
//if (res.devices[i].keyId === undefined)

View file

@ -242,14 +242,14 @@ textsecure.processDecrypted = function(decrypted, source) {
}
window.textsecure.registerSingleDevice = function(number, verificationCode, stepDone) {
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
var signalingKey = axolotl.crypto.getRandomBytes(32 + 20);
textsecure.storage.putEncrypted('signaling_key', signalingKey);
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
var password = btoa(getString(axolotl.crypto.getRandomBytes(16)));
password = password.substring(0, password.length - 2);
textsecure.storage.putEncrypted("password", password);
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
var registrationId = new Uint16Array(axolotl.crypto.getRandomBytes(2))[0];
registrationId = registrationId & 0x3fff;
textsecure.storage.putUnencrypted("registrationId", registrationId);
@ -273,14 +273,14 @@ window.textsecure.registerSecondDevice = function(encodedProvisionEnvelope, cryp
return cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(identityKey) {
stepDone(1);
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
var signalingKey = axolotl.crypto.getRandomBytes(32 + 20);
textsecure.storage.putEncrypted('signaling_key', signalingKey);
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
var password = btoa(getString(axolotl.crypto.getRandomBytes(16)));
password = password.substring(0, password.length - 2);
textsecure.storage.putEncrypted("password", password);
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
var registrationId = new Uint16Array(axolotl.crypto.getRandomBytes(2))[0];
registrationId = registrationId & 0x3fff;
textsecure.storage.putUnencrypted("registrationId", registrationId);

View file

@ -231,9 +231,9 @@ window.textsecure.messaging = function() {
makeAttachmentPointer = function(attachment) {
var proto = new textsecure.protobuf.PushMessageContent.AttachmentPointer();
proto.key = textsecure.crypto.getRandomBytes(64);
proto.key = axolotl.crypto.getRandomBytes(64);
var iv = textsecure.crypto.getRandomBytes(16);
var iv = axolotl.crypto.getRandomBytes(16);
return textsecure.protocol.encryptAttachment(attachment.data, proto.key, iv).then(function(encryptedBin) {
return textsecure.api.putAttachment(encryptedBin).then(function(id) {
proto.id = id;

View file

@ -47,7 +47,6 @@
<script type="text/javascript" src="fake_api.js"></script>
<script type="text/javascript" src="testvectors.js"></script>
<script type="text/javascript" src="crypto_test.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>

View file

@ -84,30 +84,30 @@ describe('Protocol', function() {
describe("Axolotl", function() {
var runAxolotlTest = function(v) {
var origCreateKeyPair = textsecure.crypto.createKeyPair;
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) {
textsecure.crypto.createKeyPair = origCreateKeyPair;
axolotl.crypto.createKeyPair = origCreateKeyPair;
return false;
} else if (step == v.length) {
textsecure.crypto.createKeyPair = origCreateKeyPair;
axolotl.crypto.createKeyPair = origCreateKeyPair;
return true;
} else
return doStep().then(stepDone);
}
var privKeyQueue = [];
textsecure.crypto.createKeyPair = function(privKey) {
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 textsecure.crypto.createKeyPair(privKey).then(function(keyPair) {
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!');
@ -151,13 +151,13 @@ describe('Protocol', function() {
}
if (data.ourIdentityKey !== undefined)
return textsecure.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
textsecure.storage.putEncrypted("25519KeyidentityKey", keyPair);
return textsecure.crypto.createKeyPair(data.ourSignedPreKey).then(function(keyPair) {
return axolotl.crypto.createKeyPair(data.ourSignedPreKey).then(function(keyPair) {
textsecure.storage.putEncrypted("25519KeysignedKey" + data.signedPreKeyId, keyPair);
if (data.ourPreKey !== undefined)
return textsecure.crypto.createKeyPair(data.ourPreKey).then(function(keyPair) {
return axolotl.crypto.createKeyPair(data.ourPreKey).then(function(keyPair) {
textsecure.storage.putEncrypted("25519KeypreKey" + data.preKeyId, keyPair);
return postLocalKeySetup();
});
@ -204,7 +204,7 @@ describe('Protocol', function() {
privKeyQueue.push(data.ourEphemeralKey);
if (data.ourIdentityKey !== undefined)
return textsecure.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
return axolotl.crypto.createKeyPair(data.ourIdentityKey).then(function(keyPair) {
textsecure.storage.putEncrypted("25519KeyidentityKey", keyPair);
return postLocalKeySetup();
});