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;
|
return res.buffer;
|
||||||
},
|
},
|
||||||
|
// This returns `true` if verification fails and `false` if it succeeds,
|
||||||
|
// which may be surprising.
|
||||||
verify: function(pubKey, message, sig) {
|
verify: function(pubKey, message, sig) {
|
||||||
// Get a pointer to their public key
|
// Get a pointer to their public key
|
||||||
var publicKey_ptr = _allocate(new Uint8Array(pubKey));
|
var publicKey_ptr = _allocate(new Uint8Array(pubKey));
|
||||||
|
@ -23808,6 +23810,8 @@ Curve25519Worker.prototype = {
|
||||||
|
|
||||||
return curve25519.sign(privKey, message);
|
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) {
|
Ed25519Verify: function(pubKey, msg, sig) {
|
||||||
pubKey = validatePubKeyFormat(pubKey);
|
pubKey = validatePubKeyFormat(pubKey);
|
||||||
|
|
||||||
|
@ -24487,6 +24491,7 @@ SessionBuilder.prototype = {
|
||||||
device.signedPreKey.signature
|
device.signedPreKey.signature
|
||||||
);
|
);
|
||||||
}).then(didVerificationFail => {
|
}).then(didVerificationFail => {
|
||||||
|
// Ed25519Verify returns `false` when verification succeeds and `true` if it fails.
|
||||||
if (didVerificationFail) {
|
if (didVerificationFail) {
|
||||||
throw new Error('Signature verification failed');
|
throw new Error('Signature verification failed');
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,29 +3,52 @@
|
||||||
|
|
||||||
/* global libsignal, textsecure */
|
/* global libsignal, textsecure */
|
||||||
|
|
||||||
describe('Protocol Wrapper', function thisNeeded() {
|
describe('Protocol Wrapper', function protocolWrapperDescribe() {
|
||||||
const store = textsecure.storage.protocol;
|
const store = textsecure.storage.protocol;
|
||||||
const identifier = '+5558675309';
|
const identifier = '+15559999999';
|
||||||
|
|
||||||
this.timeout(5000);
|
this.timeout(5000);
|
||||||
|
|
||||||
before(done => {
|
before(async function thisNeeded() {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
libsignal.KeyHelper.generateIdentityKeyPair()
|
this.identityKeyPair = await libsignal.KeyHelper.generateIdentityKeyPair();
|
||||||
.then(key => textsecure.storage.protocol.saveIdentity(identifier, key))
|
await textsecure.storage.protocol.saveIdentity(
|
||||||
.then(() => {
|
identifier,
|
||||||
done();
|
this.identityKeyPair.pubKey
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processPreKey', () => {
|
describe('processPreKey', () => {
|
||||||
it('rejects if the identity key changes', () => {
|
beforeEach(function thisNeeded() {
|
||||||
const address = new libsignal.SignalProtocolAddress(identifier, 1);
|
const address = new libsignal.SignalProtocolAddress(identifier, 1);
|
||||||
const builder = new libsignal.SessionBuilder(store, address);
|
this.builder = new libsignal.SessionBuilder(store, address);
|
||||||
return builder
|
});
|
||||||
|
|
||||||
|
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({
|
.processPreKey({
|
||||||
identityKey: textsecure.crypto.getRandomBytes(33),
|
identityKey: textsecure.crypto.getRandomBytes(33),
|
||||||
encodedNumber: address.toString(),
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
throw new Error('Allowed to overwrite identity key');
|
throw new Error('Allowed to overwrite identity key');
|
||||||
|
@ -34,5 +57,52 @@ describe('Protocol Wrapper', function thisNeeded() {
|
||||||
assert.strictEqual(e.message, 'Identity key changed');
|
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
Add a link
Reference in a new issue