Support for web socket communication with no signaling key
This commit is contained in:
parent
00755072ee
commit
43e5d16020
7 changed files with 66 additions and 25 deletions
|
@ -681,7 +681,19 @@
|
||||||
textsecure.storage.user.getDeviceId() != '1'
|
textsecure.storage.user.getDeviceId() != '1'
|
||||||
) {
|
) {
|
||||||
window.getSyncRequest();
|
window.getSyncRequest();
|
||||||
window.getAccountManager().maybeUpdateDeviceName();
|
|
||||||
|
try {
|
||||||
|
const manager = window.getAccountManager();
|
||||||
|
await Promise.all([
|
||||||
|
manager.maybeUpdateDeviceName(),
|
||||||
|
manager.maybeDeleteSignalingKey(),
|
||||||
|
]);
|
||||||
|
} catch (e) {
|
||||||
|
window.log.error(
|
||||||
|
'Problem with account manager updates after starting new version: ',
|
||||||
|
e && e.stack ? e.stack : e
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const udSupportKey = 'hasRegisterSupportForUnauthenticatedDelivery';
|
const udSupportKey = 'hasRegisterSupportForUnauthenticatedDelivery';
|
||||||
|
|
|
@ -326,6 +326,7 @@ function HTTPError(message, providedCode, response, stack) {
|
||||||
const URL_CALLS = {
|
const URL_CALLS = {
|
||||||
accounts: 'v1/accounts',
|
accounts: 'v1/accounts',
|
||||||
updateDeviceName: 'v1/accounts/name',
|
updateDeviceName: 'v1/accounts/name',
|
||||||
|
removeSignalingKey: 'v1/accounts/signaling_key',
|
||||||
attachment: 'v1/attachments',
|
attachment: 'v1/attachments',
|
||||||
deliveryCert: 'v1/certificate/delivery',
|
deliveryCert: 'v1/certificate/delivery',
|
||||||
supportUnauthenticatedDelivery: 'v1/devices/unauthenticated_delivery',
|
supportUnauthenticatedDelivery: 'v1/devices/unauthenticated_delivery',
|
||||||
|
@ -388,6 +389,7 @@ function initialize({ url, cdnUrl, certificateAuthority, proxyUrl }) {
|
||||||
sendMessagesUnauth,
|
sendMessagesUnauth,
|
||||||
setSignedPreKey,
|
setSignedPreKey,
|
||||||
updateDeviceName,
|
updateDeviceName,
|
||||||
|
removeSignalingKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
function _ajax(param) {
|
function _ajax(param) {
|
||||||
|
@ -518,14 +520,12 @@ function initialize({ url, cdnUrl, certificateAuthority, proxyUrl }) {
|
||||||
number,
|
number,
|
||||||
code,
|
code,
|
||||||
newPassword,
|
newPassword,
|
||||||
signalingKey,
|
|
||||||
registrationId,
|
registrationId,
|
||||||
deviceName,
|
deviceName,
|
||||||
options = {}
|
options = {}
|
||||||
) {
|
) {
|
||||||
const { accessKey } = options;
|
const { accessKey } = options;
|
||||||
const jsonData = {
|
const jsonData = {
|
||||||
signalingKey: _btoa(_getString(signalingKey)),
|
|
||||||
supportsSms: false,
|
supportsSms: false,
|
||||||
fetchesMessages: true,
|
fetchesMessages: true,
|
||||||
registrationId,
|
registrationId,
|
||||||
|
@ -580,6 +580,13 @@ function initialize({ url, cdnUrl, certificateAuthority, proxyUrl }) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeSignalingKey() {
|
||||||
|
return _ajax({
|
||||||
|
call: 'removeSignalingKey',
|
||||||
|
httpType: 'DELETE',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getDevices() {
|
function getDevices() {
|
||||||
return _ajax({
|
return _ajax({
|
||||||
call: 'devices',
|
call: 'devices',
|
||||||
|
|
|
@ -99,6 +99,12 @@
|
||||||
async deviceNameIsEncrypted() {
|
async deviceNameIsEncrypted() {
|
||||||
await textsecure.storage.user.setDeviceNameEncrypted();
|
await textsecure.storage.user.setDeviceNameEncrypted();
|
||||||
},
|
},
|
||||||
|
async maybeDeleteSignalingKey() {
|
||||||
|
const key = await textsecure.storage.user.getSignalingKey();
|
||||||
|
if (key) {
|
||||||
|
await this.server.removeSignalingKey();
|
||||||
|
}
|
||||||
|
},
|
||||||
registerSingleDevice(number, verificationCode) {
|
registerSingleDevice(number, verificationCode) {
|
||||||
const registerKeys = this.server.registerKeys.bind(this.server);
|
const registerKeys = this.server.registerKeys.bind(this.server);
|
||||||
const createAccount = this.createAccount.bind(this);
|
const createAccount = this.createAccount.bind(this);
|
||||||
|
@ -400,7 +406,6 @@
|
||||||
options = {}
|
options = {}
|
||||||
) {
|
) {
|
||||||
const { accessKey } = options;
|
const { accessKey } = options;
|
||||||
const signalingKey = libsignal.crypto.getRandomBytes(32 + 20);
|
|
||||||
let password = btoa(getString(libsignal.crypto.getRandomBytes(16)));
|
let password = btoa(getString(libsignal.crypto.getRandomBytes(16)));
|
||||||
password = password.substring(0, password.length - 2);
|
password = password.substring(0, password.length - 2);
|
||||||
const registrationId = libsignal.KeyHelper.generateRegistrationId();
|
const registrationId = libsignal.KeyHelper.generateRegistrationId();
|
||||||
|
@ -417,7 +422,6 @@
|
||||||
number,
|
number,
|
||||||
verificationCode,
|
verificationCode,
|
||||||
password,
|
password,
|
||||||
signalingKey,
|
|
||||||
registrationId,
|
registrationId,
|
||||||
encryptedDeviceName,
|
encryptedDeviceName,
|
||||||
{ accessKey }
|
{ accessKey }
|
||||||
|
@ -441,7 +445,6 @@
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
textsecure.storage.remove('identityKey'),
|
textsecure.storage.remove('identityKey'),
|
||||||
textsecure.storage.remove('signaling_key'),
|
|
||||||
textsecure.storage.remove('password'),
|
textsecure.storage.remove('password'),
|
||||||
textsecure.storage.remove('registrationId'),
|
textsecure.storage.remove('registrationId'),
|
||||||
textsecure.storage.remove('number_id'),
|
textsecure.storage.remove('number_id'),
|
||||||
|
@ -464,7 +467,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
await textsecure.storage.put('identityKey', identityKeyPair);
|
await textsecure.storage.put('identityKey', identityKeyPair);
|
||||||
await textsecure.storage.put('signaling_key', signalingKey);
|
|
||||||
await textsecure.storage.put('password', password);
|
await textsecure.storage.put('password', password);
|
||||||
await textsecure.storage.put('registrationId', registrationId);
|
await textsecure.storage.put('registrationId', registrationId);
|
||||||
if (profileKey) {
|
if (profileKey) {
|
||||||
|
|
|
@ -274,8 +274,18 @@ MessageReceiver.prototype.extend({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const promise = textsecure.crypto
|
let promise;
|
||||||
.decryptWebsocketMessage(request.body, this.signalingKey)
|
const headers = request.headers || [];
|
||||||
|
if (headers.includes('X-Signal-Key: true')) {
|
||||||
|
promise = textsecure.crypto.decryptWebsocketMessage(
|
||||||
|
request.body,
|
||||||
|
this.signalingKey
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
promise = Promise.resolve(request.body.toArrayBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
promise = promise
|
||||||
.then(plaintext => {
|
.then(plaintext => {
|
||||||
const envelope = textsecure.protobuf.Envelope.decode(plaintext);
|
const envelope = textsecure.protobuf.Envelope.decode(plaintext);
|
||||||
// After this point, decoding errors are not the server's
|
// After this point, decoding errors are not the server's
|
||||||
|
|
|
@ -39,5 +39,9 @@
|
||||||
getDeviceNameEncrypted() {
|
getDeviceNameEncrypted() {
|
||||||
return textsecure.storage.get('deviceNameEncrypted');
|
return textsecure.storage.get('deviceNameEncrypted');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSignalingKey() {
|
||||||
|
return textsecure.storage.get('signaling_key');
|
||||||
|
},
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
const Request = function Request(options) {
|
const Request = function Request(options) {
|
||||||
this.verb = options.verb || options.type;
|
this.verb = options.verb || options.type;
|
||||||
this.path = options.path || options.url;
|
this.path = options.path || options.url;
|
||||||
|
this.headers = options.headers;
|
||||||
this.body = options.body || options.data;
|
this.body = options.body || options.data;
|
||||||
this.success = options.success;
|
this.success = options.success;
|
||||||
this.error = options.error;
|
this.error = options.error;
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
this.verb = request.verb;
|
this.verb = request.verb;
|
||||||
this.path = request.path;
|
this.path = request.path;
|
||||||
this.body = request.body;
|
this.body = request.body;
|
||||||
|
this.headers = request.headers;
|
||||||
|
|
||||||
this.respond = (status, message) => {
|
this.respond = (status, message) => {
|
||||||
socket.send(
|
socket.send(
|
||||||
|
@ -77,6 +79,7 @@
|
||||||
verb: request.verb,
|
verb: request.verb,
|
||||||
path: request.path,
|
path: request.path,
|
||||||
body: request.body,
|
body: request.body,
|
||||||
|
headers: request.headers,
|
||||||
id: request.id,
|
id: request.id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -105,6 +108,7 @@
|
||||||
verb: message.request.verb,
|
verb: message.request.verb,
|
||||||
path: message.request.path,
|
path: message.request.path,
|
||||||
body: message.request.body,
|
body: message.request.body,
|
||||||
|
headers: message.request.headers,
|
||||||
id: message.request.id,
|
id: message.request.id,
|
||||||
socket,
|
socket,
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,6 +22,7 @@ message WebSocketRequestMessage {
|
||||||
optional string verb = 1;
|
optional string verb = 1;
|
||||||
optional string path = 2;
|
optional string path = 2;
|
||||||
optional bytes body = 3;
|
optional bytes body = 3;
|
||||||
|
repeated string headers = 5;
|
||||||
optional uint64 id = 4;
|
optional uint64 id = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ message WebSocketResponseMessage {
|
||||||
optional uint64 id = 1;
|
optional uint64 id = 1;
|
||||||
optional uint32 status = 2;
|
optional uint32 status = 2;
|
||||||
optional string message = 3;
|
optional string message = 3;
|
||||||
|
repeated string headers = 5;
|
||||||
optional bytes body = 4;
|
optional bytes body = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue