Add comments and tests for libsignal-protocol curve validation

This commit is contained in:
Evan Hahn 2020-11-04 11:42:50 -06:00 committed by Evan Hahn
parent 158ed4e455
commit 8e598688e7
2 changed files with 87 additions and 12 deletions

View File

@ -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');
}

View File

@ -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');
});
});
});
});