You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/test/session/crypto/MessageEncrypter_test.ts

173 lines
5.2 KiB
TypeScript

import { expect } from 'chai';
import * as crypto from 'crypto';
import * as sinon from 'sinon';
import { MessageEncrypter } from '../../../session/crypto';
import { EncryptionType } from '../../../session/types/EncryptionType';
import { Stubs, TestUtils } from '../../test-utils';
import { UserUtil } from '../../../util';
import { SignalService } from '../../../protobuf';
// tslint:disable-next-line: max-func-body-length
describe('MessageEncrypter', () => {
const sandbox = sinon.createSandbox();
const ourNumber = 'ourNumber';
beforeEach(() => {
TestUtils.stubWindow('libsignal', {
SignalProtocolAddress: sandbox.stub(),
SessionCipher: Stubs.SessionCipherStub,
} as any);
TestUtils.stubWindow('textsecure', {
storage: {
protocol: sandbox.stub(),
},
});
TestUtils.stubWindow('Signal', {
Metadata: {
SecretSessionCipher: Stubs.SecretSessionCipherStub,
},
});
TestUtils.stubWindow('libloki', {
crypto: {
FallBackSessionCipher: Stubs.FallBackSessionCipherStub,
} as any,
});
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourNumber);
});
afterEach(() => {
sandbox.restore();
TestUtils.restoreStubs();
});
describe('EncryptionType', () => {
describe('MediumGroup', () => {
it('should throw an error', async () => {
const data = crypto.randomBytes(10);
const promise = MessageEncrypter.encrypt(
'1',
data,
EncryptionType.MediumGroup
);
await expect(promise).to.be.rejectedWith(
'Encryption is not yet supported'
);
});
});
describe('SessionRequest', () => {
it('should call FallbackSessionCipher encrypt', async () => {
const data = crypto.randomBytes(10);
const spy = sandbox.spy(
Stubs.FallBackSessionCipherStub.prototype,
'encrypt'
);
await MessageEncrypter.encrypt(
'1',
data,
EncryptionType.SessionRequest
);
expect(spy.called).to.equal(
true,
'FallbackSessionCipher.encrypt should be called.'
);
});
it('should pass the padded message body to encrypt', async () => {
const data = crypto.randomBytes(10);
const spy = sandbox.spy(
Stubs.FallBackSessionCipherStub.prototype,
'encrypt'
);
await MessageEncrypter.encrypt(
'1',
data,
EncryptionType.SessionRequest
);
const paddedData = MessageEncrypter.padPlainTextBuffer(data);
const firstArgument = new Uint8Array(spy.args[0][0]);
expect(firstArgument).to.deep.equal(paddedData);
});
it('should return an UNIDENTIFIED SENDER envelope type', async () => {
const data = crypto.randomBytes(10);
const result = await MessageEncrypter.encrypt(
'1',
data,
EncryptionType.SessionRequest
);
expect(result.envelopeType).to.deep.equal(
SignalService.Envelope.Type.UNIDENTIFIED_SENDER
);
});
});
describe('Signal', () => {
it('should call SessionCipher encrypt', async () => {
const data = crypto.randomBytes(10);
const spy = sandbox.spy(Stubs.SessionCipherStub.prototype, 'encrypt');
await MessageEncrypter.encrypt('1', data, EncryptionType.Signal);
expect(spy.called).to.equal(
true,
'SessionCipher.encrypt should be called.'
);
});
it('should pass the padded message body to encrypt', async () => {
const data = crypto.randomBytes(10);
const spy = sandbox.spy(Stubs.SessionCipherStub.prototype, 'encrypt');
await MessageEncrypter.encrypt('1', data, EncryptionType.Signal);
const paddedData = MessageEncrypter.padPlainTextBuffer(data);
const firstArgument = new Uint8Array(spy.args[0][0]);
expect(firstArgument).to.deep.equal(paddedData);
});
it('should return an UNIDENTIFIED SENDER envelope type', async () => {
const data = crypto.randomBytes(10);
const result = await MessageEncrypter.encrypt(
'1',
data,
EncryptionType.Signal
);
expect(result.envelopeType).to.deep.equal(
SignalService.Envelope.Type.UNIDENTIFIED_SENDER
);
});
});
});
describe('Sealed Sender', () => {
it('should pass the correct values to SecretSessionCipher encrypt', async () => {
const types = [EncryptionType.SessionRequest, EncryptionType.Signal];
for (const type of types) {
const spy = sandbox.spy(
Stubs.SecretSessionCipherStub.prototype,
'encrypt'
);
await MessageEncrypter.encrypt('user', crypto.randomBytes(10), type);
const args = spy.args[0];
const [device, certificate] = args;
const expectedCertificate = SignalService.SenderCertificate.create({
sender: ourNumber,
senderDevice: 1,
});
expect(device).to.equal('user');
expect(certificate.toJSON()).to.deep.equal(
expectedCertificate.toJSON()
);
spy.restore();
}
});
});
});