Some initial helpers.js namespaceing
This commit is contained in:
parent
07a23f0759
commit
05101b69b0
5 changed files with 154 additions and 137 deletions
64
js/crypto.js
64
js/crypto.js
|
@ -14,14 +14,19 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// functions exposed for replacement and direct calling in test code
|
||||
var crypto_tests = {};
|
||||
var textsecure = textsecure || {};
|
||||
|
||||
window.crypto = (function() {
|
||||
textsecure.crypto = new function() {
|
||||
// functions exposed for replacement and direct calling in test code
|
||||
var testing_only = {};
|
||||
|
||||
/******************************
|
||||
*** Random constants/utils ***
|
||||
******************************/
|
||||
// We consider messages lost after a week and might throw away keys at that point
|
||||
var MESSAGE_LOST_THRESHOLD_MS = 1000*60*60*24*7;
|
||||
|
||||
crypto.getRandomBytes = function(size) {
|
||||
var getRandomBytes = function(size) {
|
||||
//TODO: Better random (https://www.grc.com/r&d/js.htm?)
|
||||
try {
|
||||
var buffer = new ArrayBuffer(size);
|
||||
|
@ -33,13 +38,23 @@ window.crypto = (function() {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
this.getRandomBytes = getRandomBytes;
|
||||
|
||||
function intToArrayBuffer(nInt) {
|
||||
var res = new ArrayBuffer(16);
|
||||
var thing = new Uint8Array(res);
|
||||
thing[0] = (nInt >> 24) & 0xff;
|
||||
thing[1] = (nInt >> 16) & 0xff;
|
||||
thing[2] = (nInt >> 8 ) & 0xff;
|
||||
thing[3] = (nInt >> 0 ) & 0xff;
|
||||
return res;
|
||||
}
|
||||
|
||||
function HmacSHA256(key, input) {
|
||||
return window.crypto.subtle.sign({name: "HMAC", hash: "SHA-256"}, key, input);
|
||||
}
|
||||
|
||||
|
||||
crypto_tests.privToPub = function(privKey, isIdentity) {
|
||||
testing_only.privToPub = function(privKey, isIdentity) {
|
||||
if (privKey.byteLength != 32)
|
||||
throw new Error("Invalid private key");
|
||||
|
||||
|
@ -75,13 +90,16 @@ window.crypto = (function() {
|
|||
}
|
||||
|
||||
}
|
||||
var privToPub = function(privKey, isIdentity) { return crypto_tests.privToPub(privKey, isIdentity); }
|
||||
var privToPub = function(privKey, isIdentity) { return testing_only.privToPub(privKey, isIdentity); }
|
||||
|
||||
crypto_tests.createNewKeyPair = function(isIdentity) {
|
||||
return privToPub(crypto.getRandomBytes(32), isIdentity);
|
||||
testing_only.createNewKeyPair = function(isIdentity) {
|
||||
return privToPub(getRandomBytes(32), isIdentity);
|
||||
}
|
||||
var createNewKeyPair = function(isIdentity) { return crypto_tests.createNewKeyPair(isIdentity); }
|
||||
var createNewKeyPair = function(isIdentity) { return testing_only.createNewKeyPair(isIdentity); }
|
||||
|
||||
/***************************
|
||||
*** Key/session storage ***
|
||||
***************************/
|
||||
var crypto_storage = {};
|
||||
|
||||
crypto_storage.getNewPubKeySTORINGPrivKey = function(keyName, isIdentity) {
|
||||
|
@ -208,9 +226,7 @@ window.crypto = (function() {
|
|||
/*****************************
|
||||
*** Internal Crypto stuff ***
|
||||
*****************************/
|
||||
//TODO: Think about replacing CryptoJS stuff with optional NaCL-based implementations
|
||||
// Probably means all of the low-level crypto stuff here needs pulled out into its own file
|
||||
crypto_tests.ECDHE = function(pubKey, privKey) {
|
||||
testing_only.ECDHE = function(pubKey, privKey) {
|
||||
if (privKey === undefined || privKey.byteLength != 32)
|
||||
throw new Error("Invalid private key");
|
||||
|
||||
|
@ -231,9 +247,9 @@ window.crypto = (function() {
|
|||
}
|
||||
});
|
||||
}
|
||||
var ECDHE = function(pubKey, privKey) { return crypto_tests.ECDHE(pubKey, privKey); }
|
||||
var ECDHE = function(pubKey, privKey) { return testing_only.ECDHE(pubKey, privKey); }
|
||||
|
||||
crypto_tests.HKDF = function(input, salt, info) {
|
||||
testing_only.HKDF = function(input, salt, info) {
|
||||
// Specific implementation of RFC 5869 that only returns exactly 64 bytes
|
||||
return HmacSHA256(salt, input).then(function(PRK) {
|
||||
var infoBuffer = new ArrayBuffer(info.byteLength + 1 + 32);
|
||||
|
@ -260,7 +276,7 @@ window.crypto = (function() {
|
|||
|
||||
info = toArrayBuffer(info); // TODO: maybe convert calls?
|
||||
|
||||
return crypto_tests.HKDF(input, salt, info);
|
||||
return testing_only.HKDF(input, salt, info);
|
||||
}
|
||||
|
||||
var calculateMACWithVersionByte = function(data, key, version) {
|
||||
|
@ -363,7 +379,7 @@ window.crypto = (function() {
|
|||
// Lock down current receive ratchet
|
||||
// TODO: Some kind of delete chainKey['key']
|
||||
// Delete current sending ratchet
|
||||
delete session[getString(ratchet.ephemeralKeyPair.pubKey)];
|
||||
delete session[getString(session.currentRatchet.ephemeralKeyPair.pubKey)];
|
||||
// Delete current root key and our ephemeral key pair
|
||||
delete session.currentRatchet['rootKey'];
|
||||
delete session.currentRatchet['ephemeralKeyPair'];
|
||||
|
@ -540,7 +556,7 @@ window.crypto = (function() {
|
|||
*** Public crypto API ***
|
||||
*************************/
|
||||
// Decrypts message into a raw string
|
||||
crypto.decryptWebsocketMessage = function(message) {
|
||||
this.decryptWebsocketMessage = function(message) {
|
||||
var signaling_key = storage.getEncrypted("signaling_key"); //TODO: in crypto_storage
|
||||
var aes_key = toArrayBuffer(signaling_key.substring(0, 32));
|
||||
var mac_key = toArrayBuffer(signaling_key.substring(32, 32 + 20));
|
||||
|
@ -559,7 +575,7 @@ window.crypto = (function() {
|
|||
});
|
||||
};
|
||||
|
||||
crypto.decryptAttachment = function(encryptedBin, keys) {
|
||||
this.decryptAttachment = function(encryptedBin, keys) {
|
||||
var aes_key = keys.slice(0, 32);
|
||||
var mac_key = keys.slice(32, 64);
|
||||
|
||||
|
@ -573,7 +589,7 @@ window.crypto = (function() {
|
|||
});
|
||||
};
|
||||
|
||||
crypto.handleIncomingPushMessageProto = function(proto) {
|
||||
this.handleIncomingPushMessageProto = function(proto) {
|
||||
switch(proto.type) {
|
||||
case 0: //TYPE_MESSAGE_PLAINTEXT
|
||||
return Promise.resolve({message: decodePushMessageContentProtobuf(getString(proto.message)), pushMessage:proto});
|
||||
|
@ -596,7 +612,7 @@ window.crypto = (function() {
|
|||
}
|
||||
|
||||
// return Promise(encoded [PreKey]WhisperMessage)
|
||||
crypto.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
||||
this.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
||||
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
||||
|
||||
var doEncryptPushMessageContent = function() {
|
||||
|
@ -663,7 +679,7 @@ window.crypto = (function() {
|
|||
}
|
||||
|
||||
var GENERATE_KEYS_KEYS_GENERATED = 100;
|
||||
crypto.generateKeys = function() {
|
||||
this.generateKeys = function() {
|
||||
var identityKey = crypto_storage.getStoredPubKey("identityKey");
|
||||
var identityKeyCalculated = function(pubKey) {
|
||||
identityKey = pubKey;
|
||||
|
@ -704,4 +720,6 @@ window.crypto = (function() {
|
|||
else
|
||||
return identityKeyCalculated(identityKey);
|
||||
}
|
||||
})();
|
||||
|
||||
this.testing_only = testing_only;
|
||||
}();
|
||||
|
|
181
js/helpers.js
181
js/helpers.js
|
@ -95,16 +95,6 @@ function base64EncArr (aBytes) {
|
|||
/*********************************
|
||||
*** Type conversion utilities ***
|
||||
*********************************/
|
||||
function intToArrayBuffer(nInt) {
|
||||
var res = new ArrayBuffer(16);
|
||||
var thing = new Uint8Array(res);
|
||||
thing[0] = (nInt >> 24) & 0xff;
|
||||
thing[1] = (nInt >> 16) & 0xff;
|
||||
thing[2] = (nInt >> 8 ) & 0xff;
|
||||
thing[3] = (nInt >> 0 ) & 0xff;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Strings/arrays
|
||||
//TODO: Throw all this shit in favor of consistent types
|
||||
var StaticByteBufferProto = new dcodeIO.ByteBuffer().__proto__;
|
||||
|
@ -261,43 +251,95 @@ function objectContainsKeys(object) {
|
|||
/************************************************
|
||||
*** Utilities to store data in local storage ***
|
||||
************************************************/
|
||||
var storage = {};
|
||||
var storage = new function() {
|
||||
/*****************************
|
||||
*** Base Storage Routines ***
|
||||
*****************************/
|
||||
this.putEncrypted = function(key, value) {
|
||||
//TODO
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
localStorage.setItem("e" + key, jsonThing(value));
|
||||
}
|
||||
|
||||
storage.putEncrypted = function(key, value) {
|
||||
this.getEncrypted = function(key, defaultValue) {
|
||||
//TODO
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
localStorage.setItem("e" + key, jsonThing(value));
|
||||
}
|
||||
var value = localStorage.getItem("e" + key);
|
||||
if (value === null)
|
||||
return defaultValue;
|
||||
return JSON.parse(value);
|
||||
}
|
||||
|
||||
storage.getEncrypted = function(key, defaultValue) {
|
||||
//TODO
|
||||
var value = localStorage.getItem("e" + key);
|
||||
if (value === null)
|
||||
return defaultValue;
|
||||
return JSON.parse(value);
|
||||
}
|
||||
this.removeEncrypted = function(key) {
|
||||
localStorage.removeItem("e" + key);
|
||||
}
|
||||
|
||||
storage.removeEncrypted = function(key) {
|
||||
localStorage.removeItem("e" + key);
|
||||
}
|
||||
this.putUnencrypted = function(key, value) {
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
localStorage.setItem("u" + key, jsonThing(value));
|
||||
}
|
||||
|
||||
storage.putUnencrypted = function(key, value) {
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
localStorage.setItem("u" + key, jsonThing(value));
|
||||
}
|
||||
this.getUnencrypted = function(key, defaultValue) {
|
||||
var value = localStorage.getItem("u" + key);
|
||||
if (value === null)
|
||||
return defaultValue;
|
||||
return JSON.parse(value);
|
||||
}
|
||||
|
||||
storage.getUnencrypted = function(key, defaultValue) {
|
||||
var value = localStorage.getItem("u" + key);
|
||||
if (value === null)
|
||||
return defaultValue;
|
||||
return JSON.parse(value);
|
||||
}
|
||||
this.removeUnencrypted = function(key) {
|
||||
localStorage.removeItem("u" + key);
|
||||
}
|
||||
|
||||
storage.removeUnencrypted = function(key) {
|
||||
localStorage.removeItem("u" + key);
|
||||
}
|
||||
/**********************
|
||||
*** Device Storage ***
|
||||
**********************/
|
||||
this.devices = new function() {
|
||||
this.getDeviceObject = function(encodedNumber) {
|
||||
return storage.getEncrypted("deviceObject" + getEncodedNumber(encodedNumber));
|
||||
}
|
||||
|
||||
this.getDeviceIdListFromNumber = function(number) {
|
||||
return storage.getEncrypted("deviceIdList" + getNumberFromString(number), []);
|
||||
}
|
||||
|
||||
this.addDeviceIdForNumber = function(number, deviceId) {
|
||||
var deviceIdList = this.getDeviceIdListFromNumber(getNumberFromString(number));
|
||||
for (var i = 0; i < deviceIdList.length; i++) {
|
||||
if (deviceIdList[i] == deviceId)
|
||||
return;
|
||||
}
|
||||
deviceIdList[deviceIdList.length] = deviceId;
|
||||
storage.putEncrypted("deviceIdList" + getNumberFromString(number), deviceIdList);
|
||||
}
|
||||
|
||||
// throws "Identity key mismatch"
|
||||
this.saveDeviceObject = function(deviceObject) {
|
||||
var existing = this.getDeviceObject(deviceObject.encodedNumber);
|
||||
if (existing === undefined)
|
||||
existing = {encodedNumber: getEncodedNumber(deviceObject.encodedNumber)};
|
||||
for (key in deviceObject) {
|
||||
if (key == "encodedNumber")
|
||||
continue;
|
||||
|
||||
if (key == "identityKey" && deviceObject.identityKey != deviceObject.identityKey)
|
||||
throw new Error("Identity key mismatch");
|
||||
|
||||
existing[key] = deviceObject[key];
|
||||
}
|
||||
storage.putEncrypted("deviceObject" + getEncodedNumber(deviceObject.encodedNumber), existing);
|
||||
this.addDeviceIdForNumber(deviceObject.encodedNumber, getDeviceId(deviceObject.encodedNumber));
|
||||
}
|
||||
|
||||
this.getDeviceObjectListFromNumber = function(number) {
|
||||
var deviceObjectList = [];
|
||||
var deviceIdList = this.getDeviceIdListFromNumber(number);
|
||||
for (var i = 0; i < deviceIdList.length; i++)
|
||||
deviceObjectList[deviceObjectList.length] = this.getDeviceObject(getNumberFromString(number) + "." + deviceIdList[i]);
|
||||
return deviceObjectList;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function registrationDone() {
|
||||
storage.putUnencrypted("registration_done", "");
|
||||
|
@ -328,49 +370,6 @@ function storeMessage(messageObject) {
|
|||
chrome.runtime.sendMessage(conversation[conversation.length - 1]);
|
||||
}
|
||||
|
||||
function getDeviceObject(encodedNumber) {
|
||||
return storage.getEncrypted("deviceObject" + getEncodedNumber(encodedNumber));
|
||||
}
|
||||
|
||||
function getDeviceIdListFromNumber(number) {
|
||||
return storage.getEncrypted("deviceIdList" + getNumberFromString(number), []);
|
||||
}
|
||||
|
||||
function addDeviceIdForNumber(number, deviceId) {
|
||||
var deviceIdList = getDeviceIdListFromNumber(getNumberFromString(number));
|
||||
for (var i = 0; i < deviceIdList.length; i++) {
|
||||
if (deviceIdList[i] == deviceId)
|
||||
return;
|
||||
}
|
||||
deviceIdList[deviceIdList.length] = deviceId;
|
||||
storage.putEncrypted("deviceIdList" + getNumberFromString(number), deviceIdList);
|
||||
}
|
||||
|
||||
// throws "Identity key mismatch"
|
||||
function saveDeviceObject(deviceObject) {
|
||||
var existing = getDeviceObject(deviceObject.encodedNumber);
|
||||
if (existing === undefined)
|
||||
existing = {encodedNumber: getEncodedNumber(deviceObject.encodedNumber)};
|
||||
for (key in deviceObject) {
|
||||
if (key == "encodedNumber")
|
||||
continue;
|
||||
|
||||
if (key == "identityKey" && deviceObject.identityKey != deviceObject.identityKey)
|
||||
throw new Error("Identity key mismatch");
|
||||
|
||||
existing[key] = deviceObject[key];
|
||||
}
|
||||
storage.putEncrypted("deviceObject" + getEncodedNumber(deviceObject.encodedNumber), existing);
|
||||
addDeviceIdForNumber(deviceObject.encodedNumber, getDeviceId(deviceObject.encodedNumber));
|
||||
}
|
||||
|
||||
function getDeviceObjectListFromNumber(number) {
|
||||
var deviceObjectList = [];
|
||||
var deviceIdList = getDeviceIdListFromNumber(number);
|
||||
for (var i = 0; i < deviceIdList.length; i++)
|
||||
deviceObjectList[deviceObjectList.length] = getDeviceObject(getNumberFromString(number) + "." + deviceIdList[i]);
|
||||
return deviceObjectList;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** NaCL Interface ***
|
||||
|
@ -456,16 +455,16 @@ function subscribeToPush(message_callback) {
|
|||
if (message.type == 3) {
|
||||
console.log("Got pong message");
|
||||
} else if (message.type === undefined && message.id !== undefined) {
|
||||
crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
||||
textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
||||
var proto = decodeIncomingPushMessageProtobuf(getString(plaintext));
|
||||
// After this point, a) decoding errors are not the server's fault, and
|
||||
// b) we should handle them gracefully and tell the user they received an invalid message
|
||||
console.log("Successfully decoded message with id: " + message.id);
|
||||
socket.send(JSON.stringify({type: 1, id: message.id}));
|
||||
return crypto.handleIncomingPushMessageProto(proto).then(function(decrypted) {
|
||||
return textsecure.crypto.handleIncomingPushMessageProto(proto).then(function(decrypted) {
|
||||
var handleAttachment = function(attachment) {
|
||||
return API.getAttachment(attachment.id).then(function(encryptedBin) {
|
||||
return crypto.decryptAttachment(encryptedBin, toArrayBuffer(attachment.key)).then(function(decryptedBin) {
|
||||
return textsecure.crypto.decryptAttachment(encryptedBin, toArrayBuffer(attachment.key)).then(function(decryptedBin) {
|
||||
attachment.decrypted = decryptedBin;
|
||||
});
|
||||
});
|
||||
|
@ -492,7 +491,7 @@ function subscribeToPush(message_callback) {
|
|||
function getKeysForNumber(number) {
|
||||
return API.getKeysForNumber(number).then(function(response) {
|
||||
for (var i = 0; i < response.length; i++) {
|
||||
saveDeviceObject({
|
||||
storage.devices.saveDeviceObject({
|
||||
encodedNumber: number + "." + response[i].deviceId,
|
||||
identityKey: response[i].identityKey,
|
||||
publicKey: response[i].publicKey,
|
||||
|
@ -512,7 +511,7 @@ function sendMessageToDevices(number, deviceObjectList, message, success_callbac
|
|||
var promises = [];
|
||||
|
||||
var addEncryptionFor = function(i) {
|
||||
return crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) {
|
||||
return textsecure.crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) {
|
||||
jsonData[i] = {
|
||||
type: encryptedMsg.type,
|
||||
destination: deviceObjectList[i].encodedNumber,
|
||||
|
@ -574,11 +573,11 @@ function sendMessageToNumbers(numbers, message, callback) {
|
|||
|
||||
for (var i = 0; i < numbers.length; i++) {
|
||||
var number = numbers[i];
|
||||
var devicesForNumber = getDeviceObjectListFromNumber(number);
|
||||
var devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
||||
|
||||
if (devicesForNumber.length == 0) {
|
||||
getKeysForNumber(number).then(function(identity_key) {
|
||||
devicesForNumber = getDeviceObjectListFromNumber(number);
|
||||
devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
||||
if (devicesForNumber.length == 0)
|
||||
registerError(number, "Failed to retreive new device keys for number " + number, null);
|
||||
else
|
||||
|
@ -592,7 +591,7 @@ function sendMessageToNumbers(numbers, message, callback) {
|
|||
}
|
||||
|
||||
function requestIdentityPrivKeyFromMasterDevice(number, identityKey) {
|
||||
sendMessageToDevices([getDeviceObject(getNumberFromString(number)) + ".1"],
|
||||
sendMessageToDevices([storage.devices.getDeviceObject(getNumberFromString(number)) + ".1"],
|
||||
{message: "Identity Key request"}, function() {}, function() {});//TODO
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ $('#number').on('change', function() {//TODO
|
|||
});
|
||||
|
||||
var single_device = false;
|
||||
var signaling_key = window.crypto.getRandomBytes(32 + 20);
|
||||
var password = btoa(getString(window.crypto.getRandomBytes(16)));
|
||||
var signaling_key = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
|
||||
password = password.substring(0, password.length - 2);
|
||||
var registrationId = new Uint16Array(window.crypto.getRandomBytes(2))[0];
|
||||
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
|
||||
registrationId = registrationId & 0x3fff;
|
||||
|
||||
$('#init-go-single-client').click(function() {
|
||||
|
@ -89,7 +89,7 @@ $('#init-go').click(function() {
|
|||
|
||||
var register_keys_func = function() {
|
||||
$('#verify2done').html('done');
|
||||
crypto.generateKeys().then(function(keys) {
|
||||
textsecure.crypto.generateKeys().then(function(keys) {
|
||||
$('#verify3done').html('done');
|
||||
API.registerKeys(keys,
|
||||
function(response) {
|
||||
|
|
34
js/test.js
34
js/test.js
|
@ -122,7 +122,7 @@ registerOnLoadFunction(function() {
|
|||
var server_message = {type: 0, // unencrypted
|
||||
source: "+19999999999", timestamp: 42, message: text_message.encode() };
|
||||
|
||||
return crypto.handleIncomingPushMessageProto(server_message).then(function(message) {
|
||||
return textsecure.crypto.handleIncomingPushMessageProto(server_message).then(function(message) {
|
||||
return (message.message.body == text_message.body &&
|
||||
message.message.attachments.length == text_message.attachments.length &&
|
||||
text_message.attachments.length == 0);
|
||||
|
@ -130,7 +130,7 @@ registerOnLoadFunction(function() {
|
|||
}, 'Unencrypted PushMessageProto "decrypt"', true);
|
||||
|
||||
TEST(function() {
|
||||
return crypto.generateKeys().then(function() {
|
||||
return textsecure.crypto.generateKeys().then(function() {
|
||||
if (storage.getEncrypted("25519KeyidentityKey") === undefined)
|
||||
return false;
|
||||
if (storage.getEncrypted("25519KeypreKey16777215") === undefined)
|
||||
|
@ -152,7 +152,7 @@ registerOnLoadFunction(function() {
|
|||
var bob_pub = hexToArrayBuffer("05de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f");
|
||||
var shared_sec = hexToArrayBuffer("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742");
|
||||
|
||||
return crypto_tests.privToPub(alice_priv, true).then(function(aliceKeyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(alice_priv, true).then(function(aliceKeyPair) {
|
||||
var target = new Uint8Array(alice_priv.slice(0));
|
||||
target[0] &= 248;
|
||||
target[31] &= 127;
|
||||
|
@ -160,7 +160,7 @@ registerOnLoadFunction(function() {
|
|||
if (String.fromCharCode.apply(null, new Uint8Array(aliceKeyPair.privKey)) != String.fromCharCode.apply(null, target))
|
||||
return false;
|
||||
|
||||
return crypto_tests.privToPub(bob_priv, true).then(function(bobKeyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(bob_priv, true).then(function(bobKeyPair) {
|
||||
var target = new Uint8Array(bob_priv.slice(0));
|
||||
target[0] &= 248;
|
||||
target[31] &= 127;
|
||||
|
@ -174,11 +174,11 @@ registerOnLoadFunction(function() {
|
|||
if (String.fromCharCode.apply(null, new Uint8Array(bobKeyPair.pubKey)) != String.fromCharCode.apply(null, new Uint8Array(bob_pub)))
|
||||
return false;
|
||||
|
||||
return crypto_tests.ECDHE(bobKeyPair.pubKey, aliceKeyPair.privKey).then(function(ss) {
|
||||
return textsecure.crypto.testing_only.ECDHE(bobKeyPair.pubKey, aliceKeyPair.privKey).then(function(ss) {
|
||||
if (String.fromCharCode.apply(null, new Uint16Array(ss)) != String.fromCharCode.apply(null, new Uint16Array(shared_sec)))
|
||||
return false;
|
||||
|
||||
return crypto_tests.ECDHE(aliceKeyPair.pubKey, bobKeyPair.privKey).then(function(ss) {
|
||||
return textsecure.crypto.testing_only.ECDHE(aliceKeyPair.pubKey, bobKeyPair.privKey).then(function(ss) {
|
||||
if (String.fromCharCode.apply(null, new Uint16Array(ss)) != String.fromCharCode.apply(null, new Uint16Array(shared_sec)))
|
||||
return false;
|
||||
else
|
||||
|
@ -204,7 +204,7 @@ registerOnLoadFunction(function() {
|
|||
for (var i = 0; i < 10; i++)
|
||||
info[i] = 240 + i;
|
||||
|
||||
return crypto_tests.HKDF(IKM, salt, info).then(function(OKM){
|
||||
return textsecure.crypto.testing_only.HKDF(IKM, salt, info).then(function(OKM){
|
||||
var T1 = hexToArrayBuffer("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf");
|
||||
var T2 = hexToArrayBuffer("34007208d5b887185865");
|
||||
return (getString(OKM[0]) == getString(T1) && getString(OKM[1]).substring(0, 10) == getString(T2));
|
||||
|
@ -300,28 +300,28 @@ registerOnLoadFunction(function() {
|
|||
];
|
||||
|
||||
var axolotlTestVectors = function(v, remoteDevice) {
|
||||
var origCreateNewKeyPair = crypto_tests.createNewKeyPair;
|
||||
var origCreateNewKeyPair = textsecure.crypto.testing_only.createNewKeyPair;
|
||||
var doStep;
|
||||
var stepDone;
|
||||
|
||||
stepDone = function(res) {
|
||||
if (!res || privKeyQueue.length != 0) {
|
||||
crypto_tests.createNewKeyPair = origCreateNewKeyPair;
|
||||
textsecure.crypto.testing_only.createNewKeyPair = origCreateNewKeyPair;
|
||||
return false;
|
||||
} else if (step == v.length) {
|
||||
crypto_tests.createNewKeyPair = origCreateNewKeyPair;
|
||||
textsecure.crypto.testing_only.createNewKeyPair = origCreateNewKeyPair;
|
||||
return true;
|
||||
} else
|
||||
return doStep().then(stepDone);
|
||||
}
|
||||
|
||||
var privKeyQueue = [];
|
||||
crypto_tests.createNewKeyPair = function(isIdentity) {
|
||||
textsecure.crypto.testing_only.createNewKeyPair = function(isIdentity) {
|
||||
if (privKeyQueue.length == 0 || isIdentity)
|
||||
throw new Error('Out of private keys');
|
||||
else {
|
||||
var privKey = privKeyQueue.shift();
|
||||
return crypto_tests.privToPub(privKey, false).then(function(keyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(privKey, false).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!');
|
||||
|
@ -345,15 +345,15 @@ registerOnLoadFunction(function() {
|
|||
message.type = data.type;
|
||||
message.source = remoteDevice.encodedNumber;
|
||||
message.message = data.message;
|
||||
return crypto.handleIncomingPushMessageProto(decodeIncomingPushMessageProtobuf(getString(message.encode()))).then(function(res) {
|
||||
return textsecure.crypto.handleIncomingPushMessageProto(decodeIncomingPushMessageProtobuf(getString(message.encode()))).then(function(res) {
|
||||
return res.message.body == data.expectedSmsText;
|
||||
});
|
||||
}
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return crypto_tests.privToPub(data.ourIdentityKey, true).then(function(keyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(data.ourIdentityKey, true).then(function(keyPair) {
|
||||
storage.putEncrypted("25519KeyidentityKey", keyPair);
|
||||
return crypto_tests.privToPub(data.ourPreKey, false).then(function(keyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(data.ourPreKey, false).then(function(keyPair) {
|
||||
storage.putEncrypted("25519KeypreKey" + data.preKeyId, keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
|
@ -374,7 +374,7 @@ registerOnLoadFunction(function() {
|
|||
var message = new PushMessageContentProtobuf();
|
||||
message.body = data.smsText;
|
||||
|
||||
return crypto.encryptMessageFor(remoteDevice, message).then(function(res) {
|
||||
return textsecure.crypto.encryptMessageFor(remoteDevice, message).then(function(res) {
|
||||
//XXX: This should be all we do: stepDone(getString(data.expectedCiphertext) == getString(res.body));
|
||||
if (res.type == 1) { //XXX: This should be used for everything...
|
||||
var expectedString = getString(data.expectedCiphertext);
|
||||
|
@ -395,7 +395,7 @@ registerOnLoadFunction(function() {
|
|||
privKeyQueue.push(data.ourEphemeralKey);
|
||||
|
||||
if (data.ourIdentityKey !== undefined)
|
||||
return crypto_tests.privToPub(data.ourIdentityKey, true).then(function(keyPair) {
|
||||
return textsecure.crypto.testing_only.privToPub(data.ourIdentityKey, true).then(function(keyPair) {
|
||||
storage.putEncrypted("25519KeyidentityKey", keyPair);
|
||||
return postLocalKeySetup();
|
||||
});
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
<script type="text/javascript" src="js/webcrypto.js"></script>
|
||||
<script type="text/javascript" src="js/crypto.js"></script>
|
||||
<script type="text/javascript" src="js/helpers.js"></script>
|
||||
<!-- TODO: Tests for api stuff -->
|
||||
<script type="text/javascript" src="js/api.js"></script>
|
||||
<script type="text/javascript" src="js/fake_api.js"></script>
|
||||
<!-- TODO: Tests for api stuff -->
|
||||
<!--<script type="text/javascript" src="js/fake_api.js"></script>-->
|
||||
<script type="text/javascript" src="js/test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue