Mostly done device-bringup stuff
This commit is contained in:
parent
c0a8c00884
commit
02d0c58e5e
8 changed files with 64 additions and 73 deletions
|
@ -5694,8 +5694,8 @@ CryptoJS.lib.Cipher || (function (undefined) {
|
|||
WhisperMessage : protocolMessages.WhisperMessage,
|
||||
PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage,
|
||||
ProvisioningUuid : deviceMessages.ProvisioningUuid,
|
||||
DeviceInit : deviceMessages.DeviceInit,
|
||||
IdentityKey : deviceMessages.IdentityKey,
|
||||
ProvisionEnvelope : deviceMessages.ProvisionEnvelope,
|
||||
ProvisionMessage : deviceMessages.ProvisionMessage,
|
||||
DeviceControl : deviceMessages.DeviceControl,
|
||||
WebSocketResponseMessage : subProtocolMessages.WebSocketResponseMessage,
|
||||
WebSocketRequestMessage : subProtocolMessages.WebSocketRequestMessage,
|
||||
|
@ -6190,13 +6190,9 @@ window.textsecure.registerSingleDevice = function(number, verificationCode, step
|
|||
});
|
||||
}
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo, stepDone) {
|
||||
var deviceInit = textsecure.protobuf.DeviceInit.decode(encodedDeviceInit, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(deviceInit).then(function(identityKey) {
|
||||
if (identityKey.server != textsecure.api.relay)
|
||||
throw new Error("Unknown relay used by master");
|
||||
var number = identityKey.phoneNumber;
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedProvisionEnvelope, cryptoInfo, stepDone) {
|
||||
var envelope = textsecure.protobuf.ProvisionEnvelope.decode(encodedProvisionEnvelope, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(identityKey) {
|
||||
stepDone(1);
|
||||
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
|
@ -6210,10 +6206,10 @@ window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo,
|
|||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.putUnencrypted("registrationId", registrationId);
|
||||
|
||||
return textsecure.api.confirmCode(number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
var numberId = number + "." + result;
|
||||
return textsecure.api.confirmCode(identityKey.number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
var numberId = identityKey.number + "." + result.deviceId;
|
||||
textsecure.storage.putUnencrypted("number_id", numberId);
|
||||
textsecure.storage.putUnencrypted("regionCode", libphonenumber.util.getRegion(number));
|
||||
textsecure.storage.putUnencrypted("regionCode", libphonenumber.util.getRegionCodeForNumber(identityKey.number));
|
||||
stepDone(2);
|
||||
|
||||
return textsecure.protocol.generateKeys().then(function(keys) {
|
||||
|
@ -6758,7 +6754,7 @@ window.textsecure.api = function () {
|
|||
URL_CALLS.devices = "/v1/devices";
|
||||
URL_CALLS.keys = "/v2/keys";
|
||||
URL_CALLS.push = "/v1/websocket";
|
||||
URL_CALLS.temp_push = "/v1/provisioning";
|
||||
URL_CALLS.temp_push = "/v1/websocket/provisioning";
|
||||
URL_CALLS.messages = "/v1/messages";
|
||||
URL_CALLS.attachment = "/v1/attachments";
|
||||
|
||||
|
@ -7950,26 +7946,26 @@ window.textsecure.protocol = function() {
|
|||
var keyPair;
|
||||
|
||||
socketInfo.decryptAndHandleDeviceInit = function(deviceInit) {
|
||||
var masterEphemeral = toArrayBuffer(deviceInit.masterEphemeralPubKey);
|
||||
var message = toArrayBuffer(deviceInit.identityKeyMessage);
|
||||
var masterEphemeral = toArrayBuffer(deviceInit.publicKey);
|
||||
var message = toArrayBuffer(deviceInit.body);
|
||||
|
||||
return textsecure.crypto.ECDHE(masterEphemeral, keyPair.privKey).then(function(ecRes) {
|
||||
return HKDF(ecRes, masterEphemeral, "WhisperDeviceInit").then(function(keys) {
|
||||
if (new Uint8Array(message)[0] != (3 << 4) | 3)
|
||||
throw new Error("Bad version number on IdentityKeyMessage");
|
||||
return HKDF(ecRes, '', "TextSecure Provisioning Message").then(function(keys) {
|
||||
if (new Uint8Array(message)[0] != 1)
|
||||
throw new Error("Bad version number on ProvisioningMessage");
|
||||
|
||||
var iv = message.slice(1, 16 + 1);
|
||||
var mac = message.slice(message.length - 32, message.length);
|
||||
var ivAndCiphertext = message.slice(0, message.length - 32);
|
||||
var ciphertext = message.slice(16 + 1, message.length - 32);
|
||||
var mac = message.slice(message.byteLength - 32, message.byteLength);
|
||||
var ivAndCiphertext = message.slice(0, message.byteLength - 32);
|
||||
var ciphertext = message.slice(16 + 1, message.byteLength - 32);
|
||||
|
||||
return verifyMAC(ivAndCiphertext, ecRes[1], mac).then(function() {
|
||||
window.textsecure.crypto.decrypt(ecRes[0], ciphertext, iv).then(function(plaintext) {
|
||||
var identityKeyMsg = textsecure.protobuf.IdentityKey.decode(plaintext);
|
||||
return verifyMAC(ivAndCiphertext, keys[1], mac).then(function() {
|
||||
return window.textsecure.crypto.decrypt(keys[0], ciphertext, iv).then(function(plaintext) {
|
||||
var identityKeyMsg = textsecure.protobuf.ProvisionMessage.decode(plaintext);
|
||||
|
||||
textsecure.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKey)).then(function(identityKeyPair) {
|
||||
return textsecure.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKeyPrivate)).then(function(identityKeyPair) {
|
||||
crypto_storage.putKeyPair("identityKey", identityKeyPair);
|
||||
identityKeyMsg.identityKey = null;
|
||||
identityKeyMsg.identityKeyPrivate = null;
|
||||
|
||||
return identityKeyMsg;
|
||||
});
|
||||
|
|
|
@ -142,14 +142,13 @@
|
|||
new WebSocketResource(socket, function(request) {
|
||||
if (request.path == "/v1/address" && request.verb == "PUT") {
|
||||
var proto = textsecure.protobuf.ProvisioningUuid.decode(request.body);
|
||||
qrCode.makeCode('textsecure-device-init:/' +
|
||||
'?channel_uuid=' + proto.uuid +
|
||||
'&channel_server=' + textsecure.api.relay +
|
||||
'&publicKey=' + btoa(getString(cryptoInfo.publicKey)));
|
||||
qrCode.makeCode('tsdevice:/' +
|
||||
'?uuid=' + proto.uuid +
|
||||
'&pub_key=' + btoa(getString(cryptoInfo.pubKey)));
|
||||
$('img').removeAttr('style');
|
||||
$('#multi-device .status').text("Use your phone to scan the QR code.")
|
||||
request.respond(200, 'OK');
|
||||
} else {
|
||||
} else if (request.path == "/v1/message" && request.verb == "PUT") {
|
||||
$('#init-setup').hide();
|
||||
$('#verify1done').text('');
|
||||
$('#verify2done').text('');
|
||||
|
@ -158,8 +157,7 @@
|
|||
$('#verify5done').text('');
|
||||
$('#verify').show().addClass('in');
|
||||
|
||||
|
||||
textsecure.registerSecondDevice(message.body, cryptoInfo, function(step) {
|
||||
textsecure.registerSecondDevice(request.body, cryptoInfo, function(step) {
|
||||
switch(step) {
|
||||
case 1:
|
||||
$('#verify1done').text('done');
|
||||
|
@ -171,16 +169,19 @@
|
|||
$('#verify3done').text('done');
|
||||
break;
|
||||
case 4:
|
||||
//TODO: User needs to verify number before we continue
|
||||
$('#complete-number').text(parsedNumber);
|
||||
//XXX: User needs to verify number before we continue
|
||||
$('#verify4done').text('done');
|
||||
//$('#complete-number').text(parsedNumber);
|
||||
textsecure.registration.done();
|
||||
case 5:
|
||||
//TODO: Do sync to get 5!
|
||||
$('#verify').hide();
|
||||
$('#setup-complete').show().addClass('in');
|
||||
textsecure.registration.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else
|
||||
console.log(request.path);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@ window.textsecure.api = function () {
|
|||
URL_CALLS.devices = "/v1/devices";
|
||||
URL_CALLS.keys = "/v2/keys";
|
||||
URL_CALLS.push = "/v1/websocket";
|
||||
URL_CALLS.temp_push = "/v1/provisioning";
|
||||
URL_CALLS.temp_push = "/v1/websocket/provisioning";
|
||||
URL_CALLS.messages = "/v1/messages";
|
||||
URL_CALLS.attachment = "/v1/attachments";
|
||||
|
||||
|
|
|
@ -268,13 +268,9 @@ window.textsecure.registerSingleDevice = function(number, verificationCode, step
|
|||
});
|
||||
}
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo, stepDone) {
|
||||
var deviceInit = textsecure.protobuf.DeviceInit.decode(encodedDeviceInit, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(deviceInit).then(function(identityKey) {
|
||||
if (identityKey.server != textsecure.api.relay)
|
||||
throw new Error("Unknown relay used by master");
|
||||
var number = identityKey.phoneNumber;
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedProvisionEnvelope, cryptoInfo, stepDone) {
|
||||
var envelope = textsecure.protobuf.ProvisionEnvelope.decode(encodedProvisionEnvelope, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(identityKey) {
|
||||
stepDone(1);
|
||||
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
|
@ -288,17 +284,16 @@ window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo,
|
|||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.putUnencrypted("registrationId", registrationId);
|
||||
|
||||
return textsecure.api.confirmCode(number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
var numberId = number + "." + result;
|
||||
return textsecure.api.confirmCode(identityKey.number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
var numberId = identityKey.number + "." + result.deviceId;
|
||||
textsecure.storage.putUnencrypted("number_id", numberId);
|
||||
textsecure.storage.putUnencrypted("regionCode", libphonenumber.util.getRegion(number));
|
||||
textsecure.storage.putUnencrypted("regionCode", libphonenumber.util.getRegionCodeForNumber(identityKey.number));
|
||||
stepDone(2);
|
||||
|
||||
return textsecure.protocol.generateKeys().then(function(keys) {
|
||||
stepDone(3);
|
||||
return textsecure.api.registerKeys(keys).then(function() {
|
||||
stepDone(4);
|
||||
//TODO: Send DeviceControl.NEW_DEVICE_REGISTERED to all other devices
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
WhisperMessage : protocolMessages.WhisperMessage,
|
||||
PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage,
|
||||
ProvisioningUuid : deviceMessages.ProvisioningUuid,
|
||||
DeviceInit : deviceMessages.DeviceInit,
|
||||
IdentityKey : deviceMessages.IdentityKey,
|
||||
ProvisionEnvelope : deviceMessages.ProvisionEnvelope,
|
||||
ProvisionMessage : deviceMessages.ProvisionMessage,
|
||||
DeviceControl : deviceMessages.DeviceControl,
|
||||
WebSocketResponseMessage : subProtocolMessages.WebSocketResponseMessage,
|
||||
WebSocketRequestMessage : subProtocolMessages.WebSocketRequestMessage,
|
||||
|
|
|
@ -762,26 +762,26 @@ window.textsecure.protocol = function() {
|
|||
var keyPair;
|
||||
|
||||
socketInfo.decryptAndHandleDeviceInit = function(deviceInit) {
|
||||
var masterEphemeral = toArrayBuffer(deviceInit.masterEphemeralPubKey);
|
||||
var message = toArrayBuffer(deviceInit.identityKeyMessage);
|
||||
var masterEphemeral = toArrayBuffer(deviceInit.publicKey);
|
||||
var message = toArrayBuffer(deviceInit.body);
|
||||
|
||||
return textsecure.crypto.ECDHE(masterEphemeral, keyPair.privKey).then(function(ecRes) {
|
||||
return HKDF(ecRes, masterEphemeral, "WhisperDeviceInit").then(function(keys) {
|
||||
if (new Uint8Array(message)[0] != (3 << 4) | 3)
|
||||
throw new Error("Bad version number on IdentityKeyMessage");
|
||||
return HKDF(ecRes, '', "TextSecure Provisioning Message").then(function(keys) {
|
||||
if (new Uint8Array(message)[0] != 1)
|
||||
throw new Error("Bad version number on ProvisioningMessage");
|
||||
|
||||
var iv = message.slice(1, 16 + 1);
|
||||
var mac = message.slice(message.length - 32, message.length);
|
||||
var ivAndCiphertext = message.slice(0, message.length - 32);
|
||||
var ciphertext = message.slice(16 + 1, message.length - 32);
|
||||
var mac = message.slice(message.byteLength - 32, message.byteLength);
|
||||
var ivAndCiphertext = message.slice(0, message.byteLength - 32);
|
||||
var ciphertext = message.slice(16 + 1, message.byteLength - 32);
|
||||
|
||||
return verifyMAC(ivAndCiphertext, ecRes[1], mac).then(function() {
|
||||
window.textsecure.crypto.decrypt(ecRes[0], ciphertext, iv).then(function(plaintext) {
|
||||
var identityKeyMsg = textsecure.protobuf.IdentityKey.decode(plaintext);
|
||||
return verifyMAC(ivAndCiphertext, keys[1], mac).then(function() {
|
||||
return window.textsecure.crypto.decrypt(keys[0], ciphertext, iv).then(function(plaintext) {
|
||||
var identityKeyMsg = textsecure.protobuf.ProvisionMessage.decode(plaintext);
|
||||
|
||||
textsecure.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKey)).then(function(identityKeyPair) {
|
||||
return textsecure.crypto.createKeyPair(toArrayBuffer(identityKeyMsg.identityKeyPrivate)).then(function(identityKeyPair) {
|
||||
crypto_storage.putKeyPair("identityKey", identityKeyPair);
|
||||
identityKeyMsg.identityKey = null;
|
||||
identityKeyMsg.identityKeyPrivate = null;
|
||||
|
||||
return identityKeyMsg;
|
||||
});
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<div class='row'>
|
||||
<div class='col-xs-offset-1 col-md-6'>
|
||||
<div id="verify" class="collapse narrow">
|
||||
<div id="verify1">Receiving identity key...<span class="done"></span></div>
|
||||
<div id="verify1">Receiving identity key...<span class="verify1done"></span></div>
|
||||
<div id="verify2">Verifying number and setup code...<span class="done" id="verify2done"></span></div>
|
||||
<div id="verify3">Generating keys...<span class="done" id="verify3done"></span></div>
|
||||
<div id="verify4">Registering...<span class="done" id="verify4done"></span></div>
|
||||
|
|
|
@ -4,17 +4,16 @@ message ProvisioningUuid {
|
|||
optional string uuid = 1;
|
||||
}
|
||||
|
||||
message DeviceInit {
|
||||
required bytes masterEphemeralPubKey = 1;
|
||||
required bytes identityKeyMessage = 2; // contains an IdentityKey
|
||||
|
||||
message ProvisionEnvelope {
|
||||
optional bytes publicKey = 1;
|
||||
optional bytes body = 2; // Encrypted ProvisionMessage
|
||||
}
|
||||
|
||||
message IdentityKey {
|
||||
required bytes identityKey = 1;
|
||||
required string phoneNumber = 2;
|
||||
required string server = 3;
|
||||
required bool masterSupportsSms = 4;
|
||||
required uint32 provisioningCode = 5;
|
||||
message ProvisionMessage {
|
||||
optional bytes identityKeyPrivate = 2;
|
||||
optional string number = 3;
|
||||
optional string provisioningCode = 4;
|
||||
}
|
||||
|
||||
message DeviceControl {
|
||||
|
|
Loading…
Reference in a new issue