Account setup: confirm first signed prekey, clear prekeys (#1979)
This commit is contained in:
parent
c70fb3a254
commit
33fd9c5dd4
2 changed files with 100 additions and 51 deletions
|
@ -89,6 +89,11 @@
|
||||||
|
|
||||||
var Model = Backbone.Model.extend({ database: Whisper.Database });
|
var Model = Backbone.Model.extend({ database: Whisper.Database });
|
||||||
var PreKey = Model.extend({ storeName: 'preKeys' });
|
var PreKey = Model.extend({ storeName: 'preKeys' });
|
||||||
|
var PreKeyCollection = Backbone.Collection.extend({
|
||||||
|
storeName: 'preKeys',
|
||||||
|
database: Whisper.Database,
|
||||||
|
model: PreKey
|
||||||
|
});
|
||||||
var SignedPreKey = Model.extend({ storeName: 'signedPreKeys' });
|
var SignedPreKey = Model.extend({ storeName: 'signedPreKeys' });
|
||||||
var SignedPreKeyCollection = Backbone.Collection.extend({
|
var SignedPreKeyCollection = Backbone.Collection.extend({
|
||||||
storeName: 'signedPreKeys',
|
storeName: 'signedPreKeys',
|
||||||
|
@ -229,6 +234,12 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
clearPreKeyStore: function() {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
var preKeys = new PreKeyCollection();
|
||||||
|
preKeys.sync('delete', preKeys, {}).always(resolve);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/* Returns a signed keypair object or undefined */
|
/* Returns a signed keypair object or undefined */
|
||||||
loadSignedPreKey: function(keyId) {
|
loadSignedPreKey: function(keyId) {
|
||||||
|
@ -293,6 +304,12 @@
|
||||||
deferred.then(resolve, reject);
|
deferred.then(resolve, reject);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
clearSignedPreKeysStore: function() {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
var signedPreKeys = new SignedPreKeyCollection();
|
||||||
|
signedPreKeys.sync('delete', signedPreKeys, {}).always(resolve);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
loadSession: function(encodedNumber) {
|
loadSession: function(encodedNumber) {
|
||||||
if (encodedNumber === null || encodedNumber === undefined) {
|
if (encodedNumber === null || encodedNumber === undefined) {
|
||||||
|
@ -392,7 +409,6 @@
|
||||||
var sessions = new SessionCollection();
|
var sessions = new SessionCollection();
|
||||||
sessions.sync('delete', sessions, {}).always(resolve);
|
sessions.sync('delete', sessions, {}).always(resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
isTrustedIdentity: function(identifier, publicKey, direction) {
|
isTrustedIdentity: function(identifier, publicKey, direction) {
|
||||||
if (identifier === null || identifier === undefined) {
|
if (identifier === null || identifier === undefined) {
|
||||||
|
|
|
@ -26,21 +26,30 @@
|
||||||
registerSingleDevice: function(number, verificationCode) {
|
registerSingleDevice: function(number, verificationCode) {
|
||||||
var registerKeys = this.server.registerKeys.bind(this.server);
|
var registerKeys = this.server.registerKeys.bind(this.server);
|
||||||
var createAccount = this.createAccount.bind(this);
|
var createAccount = this.createAccount.bind(this);
|
||||||
|
var clearSessionsAndPreKeys = this.clearSessionsAndPreKeys.bind(this);
|
||||||
var generateKeys = this.generateKeys.bind(this, 100);
|
var generateKeys = this.generateKeys.bind(this, 100);
|
||||||
|
var confirmKeys = this.confirmKeys.bind(this);
|
||||||
var registrationDone = this.registrationDone.bind(this);
|
var registrationDone = this.registrationDone.bind(this);
|
||||||
return this.queueTask(function() {
|
return this.queueTask(function() {
|
||||||
return libsignal.KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
|
return libsignal.KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
|
||||||
var profileKey = textsecure.crypto.getRandomBytes(32);
|
var profileKey = textsecure.crypto.getRandomBytes(32);
|
||||||
return createAccount(number, verificationCode, identityKeyPair, profileKey).
|
return createAccount(number, verificationCode, identityKeyPair, profileKey)
|
||||||
then(generateKeys).
|
.then(clearSessionsAndPreKeys)
|
||||||
then(registerKeys).
|
.then(generateKeys)
|
||||||
then(registrationDone);
|
.then(function(keys) {
|
||||||
|
return registerKeys(keys).then(function() {
|
||||||
|
return confirmKeys(keys);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(registrationDone);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
registerSecondDevice: function(setProvisioningUrl, confirmNumber, progressCallback) {
|
registerSecondDevice: function(setProvisioningUrl, confirmNumber, progressCallback) {
|
||||||
var createAccount = this.createAccount.bind(this);
|
var createAccount = this.createAccount.bind(this);
|
||||||
|
var clearSessionsAndPreKeys = this.clearSessionsAndPreKeys.bind(this);
|
||||||
var generateKeys = this.generateKeys.bind(this, 100, progressCallback);
|
var generateKeys = this.generateKeys.bind(this, 100, progressCallback);
|
||||||
|
var confirmKeys = this.confirmKeys.bind(this);
|
||||||
var registrationDone = this.registrationDone.bind(this);
|
var registrationDone = this.registrationDone.bind(this);
|
||||||
var registerKeys = this.server.registerKeys.bind(this.server);
|
var registerKeys = this.server.registerKeys.bind(this.server);
|
||||||
var getSocket = this.server.getProvisioningSocket.bind(this.server);
|
var getSocket = this.server.getProvisioningSocket.bind(this.server);
|
||||||
|
@ -88,9 +97,15 @@
|
||||||
deviceName,
|
deviceName,
|
||||||
provisionMessage.userAgent,
|
provisionMessage.userAgent,
|
||||||
provisionMessage.readReceipts
|
provisionMessage.readReceipts
|
||||||
).then(generateKeys).
|
)
|
||||||
then(registerKeys).
|
.then(clearSessionsAndPreKeys)
|
||||||
then(registrationDone);
|
.then(generateKeys)
|
||||||
|
.then(function(keys) {
|
||||||
|
return registerKeys(keys).then(function() {
|
||||||
|
return confirmKeys(keys);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(registrationDone);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
@ -249,52 +264,68 @@
|
||||||
return this.server.confirmCode(
|
return this.server.confirmCode(
|
||||||
number, verificationCode, password, signalingKey, registrationId, deviceName
|
number, verificationCode, password, signalingKey, registrationId, deviceName
|
||||||
).then(function(response) {
|
).then(function(response) {
|
||||||
return textsecure.storage.protocol.clearSessionStore().then(function() {
|
textsecure.storage.remove('identityKey');
|
||||||
textsecure.storage.remove('identityKey');
|
textsecure.storage.remove('signaling_key');
|
||||||
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');
|
textsecure.storage.remove('device_name');
|
||||||
textsecure.storage.remove('device_name');
|
textsecure.storage.remove('regionCode');
|
||||||
textsecure.storage.remove('regionCode');
|
textsecure.storage.remove('userAgent');
|
||||||
textsecure.storage.remove('userAgent');
|
textsecure.storage.remove('profileKey');
|
||||||
textsecure.storage.remove('profileKey');
|
textsecure.storage.remove('read-receipts-setting');
|
||||||
textsecure.storage.remove('read-receipts-setting');
|
|
||||||
|
|
||||||
// update our own identity key, which may have changed
|
// update our own identity key, which may have changed
|
||||||
// if we're relinking after a reinstall on the master device
|
// if we're relinking after a reinstall on the master device
|
||||||
textsecure.storage.protocol.saveIdentityWithAttributes(number, {
|
textsecure.storage.protocol.saveIdentityWithAttributes(number, {
|
||||||
id : number,
|
id : number,
|
||||||
publicKey : identityKeyPair.pubKey,
|
publicKey : identityKeyPair.pubKey,
|
||||||
firstUse : true,
|
firstUse : true,
|
||||||
timestamp : Date.now(),
|
timestamp : Date.now(),
|
||||||
verified : textsecure.storage.protocol.VerifiedStatus.VERIFIED,
|
verified : textsecure.storage.protocol.VerifiedStatus.VERIFIED,
|
||||||
nonblockingApproval : true
|
nonblockingApproval : true
|
||||||
});
|
});
|
||||||
|
|
||||||
textsecure.storage.put('identityKey', identityKeyPair);
|
textsecure.storage.put('identityKey', identityKeyPair);
|
||||||
textsecure.storage.put('signaling_key', signalingKey);
|
textsecure.storage.put('signaling_key', signalingKey);
|
||||||
textsecure.storage.put('password', password);
|
textsecure.storage.put('password', password);
|
||||||
textsecure.storage.put('registrationId', registrationId);
|
textsecure.storage.put('registrationId', registrationId);
|
||||||
if (profileKey) {
|
if (profileKey) {
|
||||||
textsecure.storage.put('profileKey', profileKey);
|
textsecure.storage.put('profileKey', profileKey);
|
||||||
}
|
}
|
||||||
if (userAgent) {
|
if (userAgent) {
|
||||||
textsecure.storage.put('userAgent', userAgent);
|
textsecure.storage.put('userAgent', userAgent);
|
||||||
}
|
}
|
||||||
if (readReceipts) {
|
if (readReceipts) {
|
||||||
textsecure.storage.put('read-receipt-setting', true);
|
textsecure.storage.put('read-receipt-setting', true);
|
||||||
} else {
|
} else {
|
||||||
textsecure.storage.put('read-receipt-setting', false);
|
textsecure.storage.put('read-receipt-setting', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textsecure.storage.user.setNumberAndDeviceId(number, response.deviceId || 1, deviceName);
|
||||||
textsecure.storage.user.setNumberAndDeviceId(number, response.deviceId || 1, deviceName);
|
textsecure.storage.put('regionCode', libphonenumber.util.getRegionCodeForNumber(number));
|
||||||
textsecure.storage.put('regionCode', libphonenumber.util.getRegionCodeForNumber(number));
|
this.server.username = textsecure.storage.get('number_id');
|
||||||
this.server.username = textsecure.storage.get('number_id');
|
|
||||||
}.bind(this));
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
clearSessionsAndPreKeys: function() {
|
||||||
|
var store = textsecure.storage.protocol;
|
||||||
|
|
||||||
|
console.log('clearing all sessions, prekeys, and signed prekeys');
|
||||||
|
return Promise.all([
|
||||||
|
store.clearPreKeyStore(),
|
||||||
|
store.clearSignedPreKeysStore(),
|
||||||
|
store.clearSessionStore(),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
// Takes the same object returned by generateKeys
|
||||||
|
confirmKeys: function(keys) {
|
||||||
|
var store = textsecure.storage.protocol;
|
||||||
|
var key = keys.signedPreKey;
|
||||||
|
var confirmed = true;
|
||||||
|
|
||||||
|
console.log('confirmKeys: confirming key', key.keyId);
|
||||||
|
return store.storeSignedPreKey(key.keyId, key.keyPair, confirmed);
|
||||||
|
},
|
||||||
generateKeys: function (count, progressCallback) {
|
generateKeys: function (count, progressCallback) {
|
||||||
if (typeof progressCallback !== 'function') {
|
if (typeof progressCallback !== 'function') {
|
||||||
progressCallback = undefined;
|
progressCallback = undefined;
|
||||||
|
@ -309,7 +340,6 @@
|
||||||
throw new Error('Invalid signedKeyId');
|
throw new Error('Invalid signedKeyId');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var store = textsecure.storage.protocol;
|
var store = textsecure.storage.protocol;
|
||||||
return store.getIdentityKeyPair().then(function(identityKey) {
|
return store.getIdentityKeyPair().then(function(identityKey) {
|
||||||
var result = { preKeys: [], identityKey: identityKey.pubKey };
|
var result = { preKeys: [], identityKey: identityKey.pubKey };
|
||||||
|
@ -334,7 +364,9 @@
|
||||||
result.signedPreKey = {
|
result.signedPreKey = {
|
||||||
keyId : res.keyId,
|
keyId : res.keyId,
|
||||||
publicKey : res.keyPair.pubKey,
|
publicKey : res.keyPair.pubKey,
|
||||||
signature : res.signature
|
signature : res.signature,
|
||||||
|
// server.registerKeys doesn't use keyPair, confirmKeys does
|
||||||
|
keyPair : res.keyPair,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -342,6 +374,7 @@
|
||||||
textsecure.storage.put('maxPreKeyId', startId + count);
|
textsecure.storage.put('maxPreKeyId', startId + count);
|
||||||
textsecure.storage.put('signedKeyId', signedKeyId + 1);
|
textsecure.storage.put('signedKeyId', signedKeyId + 1);
|
||||||
return Promise.all(promises).then(function() {
|
return Promise.all(promises).then(function() {
|
||||||
|
// This is primarily for the signed prekey summary it logs out
|
||||||
return this.cleanSignedPreKeys().then(function() {
|
return this.cleanSignedPreKeys().then(function() {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue