Sealed Sender support

https://signal.org/blog/sealed-sender/
This commit is contained in:
Scott Nonnenberg 2018-10-17 18:01:21 -07:00
parent 817cf5ed03
commit a7d78c0e9b
38 changed files with 2996 additions and 789 deletions

View file

@ -1,104 +1,119 @@
'use strict';
describe('Crypto', function() {
it('roundtrip symmetric encryption succeeds', async function() {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
describe('Crypto', () => {
describe('accessKey/profileKey', () => {
it('verification roundtrips', async () => {
const profileKey = await Signal.Crypto.getRandomBytes(32);
const accessKey = await Signal.Crypto.deriveAccessKey(profileKey);
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var decrypted = await Signal.Crypto.decryptSymmetric(key, encrypted);
const verifier = await Signal.Crypto.getAccessKeyVerifier(accessKey);
var equal = Signal.Crypto.constantTimeEqual(plaintext, decrypted);
if (!equal) {
throw new Error('The output and input did not match!');
}
const correct = await Signal.Crypto.verifyAccessKey(accessKey, verifier);
assert.strictEqual(correct, true);
});
});
it('roundtrip fails if nonce is modified', async function() {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
describe('symmetric encryption', () => {
it('roundtrips', async () => {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[2] = 9;
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var decrypted = await Signal.Crypto.decryptSymmetric(key, encrypted);
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
var equal = Signal.Crypto.constantTimeEqual(plaintext, decrypted);
if (!equal) {
throw new Error('The output and input did not match!');
}
});
throw new Error('Expected error to be thrown');
});
it('roundtrip fails if nonce is modified', async () => {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
it('fails if mac is modified', async function() {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[2] = 9;
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[uintArray.length - 3] = 9;
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
throw new Error('Expected error to be thrown');
});
throw new Error('Expected error to be thrown');
});
it('roundtrip fails if mac is modified', async () => {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
it('fails if encrypted contents are modified', async function() {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[uintArray.length - 3] = 9;
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[35] = 9;
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
throw new Error('Expected error to be thrown');
});
throw new Error('Expected error to be thrown');
it('roundtrip fails if encrypted contents are modified', async () => {
var message = 'this is my message';
var plaintext = new dcodeIO.ByteBuffer.wrap(
message,
'binary'
).toArrayBuffer();
var key = textsecure.crypto.getRandomBytes(32);
var encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
var uintArray = new Uint8Array(encrypted);
uintArray[35] = 9;
try {
var decrypted = await Signal.Crypto.decryptSymmetric(
key,
uintArray.buffer
);
} catch (error) {
assert.strictEqual(
error.message,
'decryptSymmetric: Failed to decrypt; MAC verification failed'
);
return;
}
throw new Error('Expected error to be thrown');
});
});
});