mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
90 lines
3.9 KiB
TypeScript
90 lines
3.9 KiB
TypeScript
import { afterAllCleanUp, encryptionService, expectNotThrow, expectThrow, setupDatabaseAndSynchronizer, switchClient } from '../../testing/test-utils';
|
|
import { decryptPrivateKey, generateKeyPair, ppkDecryptMasterKeyContent, ppkGenerateMasterKey, ppkPasswordIsValid, mkReencryptFromPasswordToPublicKey, mkReencryptFromPublicKeyToPassword } from './ppk';
|
|
import { runIntegrationTests } from './ppkTestUtils';
|
|
|
|
describe('e2ee/ppk', () => {
|
|
|
|
beforeEach(async () => {
|
|
await setupDatabaseAndSynchronizer(1);
|
|
await switchClient(1);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await afterAllCleanUp();
|
|
});
|
|
|
|
it('should create a public private key pair', async () => {
|
|
const ppk = await generateKeyPair(encryptionService(), '111111');
|
|
|
|
const privateKey = await decryptPrivateKey(encryptionService(), ppk.privateKey, '111111');
|
|
const publicKey = ppk.publicKey;
|
|
|
|
expect(privateKey).toContain('BEGIN RSA PRIVATE KEY');
|
|
expect(privateKey).toContain('END RSA PRIVATE KEY');
|
|
expect(privateKey.length).toBeGreaterThan(350);
|
|
|
|
expect(publicKey).toContain('BEGIN RSA PUBLIC KEY');
|
|
expect(publicKey).toContain('END RSA PUBLIC KEY');
|
|
expect(publicKey.length).toBeGreaterThan(350);
|
|
});
|
|
|
|
it('should create different key pairs every time', async () => {
|
|
const ppk1 = await generateKeyPair(encryptionService(), '111111');
|
|
const ppk2 = await generateKeyPair(encryptionService(), '111111');
|
|
|
|
const privateKey1 = await decryptPrivateKey(encryptionService(), ppk1.privateKey, '111111');
|
|
const privateKey2 = await decryptPrivateKey(encryptionService(), ppk2.privateKey, '111111');
|
|
const publicKey1 = ppk1.publicKey;
|
|
const publicKey2 = ppk2.publicKey;
|
|
|
|
expect(privateKey1).not.toBe(privateKey2);
|
|
expect(publicKey1).not.toBe(publicKey2);
|
|
});
|
|
|
|
it('should encrypt a master key using PPK', (async () => {
|
|
const ppk = await generateKeyPair(encryptionService(), '111111');
|
|
const masterKey = await ppkGenerateMasterKey(encryptionService(), ppk, '111111');
|
|
const plainText = await ppkDecryptMasterKeyContent(encryptionService(), masterKey, ppk, '111111');
|
|
expect(plainText.length).toBeGreaterThan(50); // Just checking it's not empty
|
|
expect(plainText).not.toBe(masterKey.content);
|
|
}));
|
|
|
|
it('should check if a PPK password is valid', (async () => {
|
|
const ppk = await generateKeyPair(encryptionService(), '111111');
|
|
expect(await ppkPasswordIsValid(encryptionService(), ppk, '222')).toBe(false);
|
|
expect(await ppkPasswordIsValid(encryptionService(), ppk, '111111')).toBe(true);
|
|
await expectThrow(async () => ppkPasswordIsValid(encryptionService(), null, '111111'));
|
|
}));
|
|
|
|
it('should transmit key using a public-private key', (async () => {
|
|
// This simulate sending a key from one user to another using
|
|
// public-private key encryption. For example used when sharing a
|
|
// notebook while E2EE is enabled.
|
|
|
|
// User 1 generates a master key
|
|
const key1 = await encryptionService().generateMasterKey('mk_1111');
|
|
|
|
// Using user 2 private key, he reencrypts the master key
|
|
const ppk2 = await generateKeyPair(encryptionService(), 'ppk_1111');
|
|
const ppkEncrypted = await mkReencryptFromPasswordToPublicKey(encryptionService(), key1, 'mk_1111', ppk2);
|
|
|
|
// Once user 2 gets the master key, he can decrypt it using his private key
|
|
const key2 = await mkReencryptFromPublicKeyToPassword(encryptionService(), ppkEncrypted, ppk2, 'ppk_1111', 'mk_2222');
|
|
|
|
// Once it's done, both users should have the same master key
|
|
const plaintext1 = await encryptionService().decryptMasterKeyContent(key1, 'mk_1111');
|
|
const plaintext2 = await encryptionService().decryptMasterKeyContent(key2, 'mk_2222');
|
|
|
|
expect(plaintext1).toBe(plaintext2);
|
|
|
|
// We should make sure that the keys are also different when encrypted
|
|
// since they should be using different passwords.
|
|
expect(key1.content).not.toBe(key2.content);
|
|
}));
|
|
|
|
it('should decrypt and encrypt data from different devices', (async () => {
|
|
await expectNotThrow(async () => runIntegrationTests(true));
|
|
}));
|
|
|
|
});
|