From 05101b69b0d3160f627174d66641eb72e2751842 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 17 May 2014 00:54:12 -0400 Subject: [PATCH] Some initial helpers.js namespaceing --- js/crypto.js | 64 +++++++++++------- js/helpers.js | 181 +++++++++++++++++++++++++------------------------- js/options.js | 8 +-- js/test.js | 34 +++++----- test.html | 4 +- 5 files changed, 154 insertions(+), 137 deletions(-) diff --git a/js/crypto.js b/js/crypto.js index 611df7250..8fead8a8f 100644 --- a/js/crypto.js +++ b/js/crypto.js @@ -14,14 +14,19 @@ * along with this program. If not, see . */ -// 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; +}(); diff --git a/js/helpers.js b/js/helpers.js index afc4641a7..8d6f5a68a 100644 --- a/js/helpers.js +++ b/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 } diff --git a/js/options.js b/js/options.js index 2a3520c77..beb4b4d1b 100644 --- a/js/options.js +++ b/js/options.js @@ -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) { diff --git a/js/test.js b/js/test.js index b2f2b073f..2d57501c3 100644 --- a/js/test.js +++ b/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(); }); diff --git a/test.html b/test.html index fff704a5e..e2433a8e5 100644 --- a/test.html +++ b/test.html @@ -42,9 +42,9 @@ - - + +