Add comments and tests for libsignal-protocol curve validation
This commit is contained in:
parent
158ed4e455
commit
8e598688e7
2 changed files with 87 additions and 12 deletions
|
@ -23624,6 +23624,8 @@ var Internal = Internal || {};
|
|||
|
||||
return res.buffer;
|
||||
},
|
||||
// This returns `true` if verification fails and `false` if it succeeds,
|
||||
// which may be surprising.
|
||||
verify: function(pubKey, message, sig) {
|
||||
// Get a pointer to their public key
|
||||
var publicKey_ptr = _allocate(new Uint8Array(pubKey));
|
||||
|
@ -23808,6 +23810,8 @@ Curve25519Worker.prototype = {
|
|||
|
||||
return curve25519.sign(privKey, message);
|
||||
},
|
||||
// This returns `true` if verification fails and `false` if it succeeds,
|
||||
// which may be surprising.
|
||||
Ed25519Verify: function(pubKey, msg, sig) {
|
||||
pubKey = validatePubKeyFormat(pubKey);
|
||||
|
||||
|
@ -24487,6 +24491,7 @@ SessionBuilder.prototype = {
|
|||
device.signedPreKey.signature
|
||||
);
|
||||
}).then(didVerificationFail => {
|
||||
// Ed25519Verify returns `false` when verification succeeds and `true` if it fails.
|
||||
if (didVerificationFail) {
|
||||
throw new Error('Signature verification failed');
|
||||
}
|
||||
|
|
|
@ -3,29 +3,52 @@
|
|||
|
||||
/* global libsignal, textsecure */
|
||||
|
||||
describe('Protocol Wrapper', function thisNeeded() {
|
||||
describe('Protocol Wrapper', function protocolWrapperDescribe() {
|
||||
const store = textsecure.storage.protocol;
|
||||
const identifier = '+5558675309';
|
||||
const identifier = '+15559999999';
|
||||
|
||||
this.timeout(5000);
|
||||
|
||||
before(done => {
|
||||
before(async function thisNeeded() {
|
||||
localStorage.clear();
|
||||
libsignal.KeyHelper.generateIdentityKeyPair()
|
||||
.then(key => textsecure.storage.protocol.saveIdentity(identifier, key))
|
||||
.then(() => {
|
||||
done();
|
||||
});
|
||||
this.identityKeyPair = await libsignal.KeyHelper.generateIdentityKeyPair();
|
||||
await textsecure.storage.protocol.saveIdentity(
|
||||
identifier,
|
||||
this.identityKeyPair.pubKey
|
||||
);
|
||||
});
|
||||
|
||||
describe('processPreKey', () => {
|
||||
it('rejects if the identity key changes', () => {
|
||||
beforeEach(function thisNeeded() {
|
||||
const address = new libsignal.SignalProtocolAddress(identifier, 1);
|
||||
const builder = new libsignal.SessionBuilder(store, address);
|
||||
return builder
|
||||
this.builder = new libsignal.SessionBuilder(store, address);
|
||||
});
|
||||
|
||||
it('can process prekeys', async function thisNeeded() {
|
||||
const signedPreKey = await libsignal.KeyHelper.generateSignedPreKey(
|
||||
this.identityKeyPair,
|
||||
123
|
||||
);
|
||||
|
||||
await this.builder.processPreKey({
|
||||
identityKey: this.identityKeyPair.pubKey,
|
||||
registrationId: 1,
|
||||
preKey: {
|
||||
keyId: 1,
|
||||
publicKey: this.identityKeyPair.pubKey,
|
||||
},
|
||||
signedPreKey: {
|
||||
keyId: 123,
|
||||
publicKey: signedPreKey.keyPair.pubKey,
|
||||
signature: signedPreKey.signature,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects if the identity key changes', function thisNeeded() {
|
||||
return this.builder
|
||||
.processPreKey({
|
||||
identityKey: textsecure.crypto.getRandomBytes(33),
|
||||
encodedNumber: address.toString(),
|
||||
})
|
||||
.then(() => {
|
||||
throw new Error('Allowed to overwrite identity key');
|
||||
|
@ -34,5 +57,52 @@ describe('Protocol Wrapper', function thisNeeded() {
|
|||
assert.strictEqual(e.message, 'Identity key changed');
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects with a bad prekey signature', async function thisNeeded() {
|
||||
const signedPreKey = await libsignal.KeyHelper.generateSignedPreKey(
|
||||
this.identityKeyPair,
|
||||
123
|
||||
);
|
||||
const bogusSignature = textsecure.crypto.getRandomBytes(64);
|
||||
|
||||
return this.builder
|
||||
.processPreKey({
|
||||
identityKey: this.identityKeyPair.pubKey,
|
||||
signedPreKey: {
|
||||
keyId: 123,
|
||||
publicKey: signedPreKey.keyPair.pubKey,
|
||||
signature: bogusSignature,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
throw new Error("Didn't reject an invalid signature");
|
||||
})
|
||||
.catch(e => {
|
||||
assert.strictEqual(e.message, 'Signature verification failed');
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects with a prekey signature for a different identity', async function thisNeeded() {
|
||||
const bogusSignedPreKey = await libsignal.KeyHelper.generateSignedPreKey(
|
||||
await libsignal.KeyHelper.generateIdentityKeyPair(),
|
||||
123
|
||||
);
|
||||
|
||||
return this.builder
|
||||
.processPreKey({
|
||||
identityKey: this.identityKeyPair.pubKey,
|
||||
signedPreKey: {
|
||||
keyId: 123,
|
||||
publicKey: bogusSignedPreKey.keyPair.pubKey,
|
||||
signature: bogusSignedPreKey.signature,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
throw new Error("Didn't reject an invalid signature");
|
||||
})
|
||||
.catch(e => {
|
||||
assert.strictEqual(e.message, 'Signature verification failed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue