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.
		
		
		
		
		
			
		
			
				
	
	
		
			207 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
| import { existsSync } from 'fs';
 | |
| import { join } from 'path';
 | |
| 
 | |
| import { assert } from 'chai';
 | |
| import { copy } from 'fs-extra';
 | |
| 
 | |
| import {
 | |
|   _getFileHash,
 | |
|   getSignaturePath,
 | |
|   loadHexFromPath,
 | |
|   verifySignature,
 | |
|   writeHexToPath,
 | |
|   writeSignature,
 | |
| } from '../../updater/signature';
 | |
| import { createTempDir, deleteTempDir } from '../../updater/common';
 | |
| import { keyPair } from '../../updater/curve';
 | |
| 
 | |
| describe('updater/signatures', () => {
 | |
|   it('_getFileHash returns correct hash', async () => {
 | |
|     const filePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|     const expected =
 | |
|       '7bc77f27d92d00b4a1d57c480ca86dacc43d57bc318339c92119d1fbf6b557a5';
 | |
| 
 | |
|     const hash = await _getFileHash(filePath);
 | |
| 
 | |
|     assert.strictEqual(expected, Buffer.from(hash).toString('hex'));
 | |
|   });
 | |
| 
 | |
|   it('roundtrips binary file writes', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const path = join(tempDir, 'something.bin');
 | |
|       const { publicKey } = keyPair();
 | |
| 
 | |
|       await writeHexToPath(path, publicKey);
 | |
| 
 | |
|       const fromDisk = await loadHexFromPath(path);
 | |
| 
 | |
|       assert.strictEqual(
 | |
|         Buffer.from(fromDisk).compare(Buffer.from(publicKey)),
 | |
|         0
 | |
|       );
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   it('roundtrips signature', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const version = 'v1.23.2';
 | |
|       const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|       const updatePath = join(tempDir, 'ghost-kitty.mp4');
 | |
|       await copy(sourcePath, updatePath);
 | |
| 
 | |
|       const privateKeyPath = join(tempDir, 'private.key');
 | |
|       const { publicKey, privateKey } = keyPair();
 | |
|       await writeHexToPath(privateKeyPath, privateKey);
 | |
| 
 | |
|       await writeSignature(updatePath, version, privateKeyPath);
 | |
| 
 | |
|       const signaturePath = getSignaturePath(updatePath);
 | |
|       assert.strictEqual(existsSync(signaturePath), true);
 | |
| 
 | |
|       const verified = await verifySignature(updatePath, version, publicKey);
 | |
|       assert.strictEqual(verified, true);
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   it('fails signature verification if version changes', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const version = 'v1.23.2';
 | |
|       const brokenVersion = 'v1.23.3';
 | |
| 
 | |
|       const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|       const updatePath = join(tempDir, 'ghost-kitty.mp4');
 | |
|       await copy(sourcePath, updatePath);
 | |
| 
 | |
|       const privateKeyPath = join(tempDir, 'private.key');
 | |
|       const { publicKey, privateKey } = keyPair();
 | |
|       await writeHexToPath(privateKeyPath, privateKey);
 | |
| 
 | |
|       await writeSignature(updatePath, version, privateKeyPath);
 | |
| 
 | |
|       const verified = await verifySignature(
 | |
|         updatePath,
 | |
|         brokenVersion,
 | |
|         publicKey
 | |
|       );
 | |
|       assert.strictEqual(verified, false);
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   it('fails signature verification if signature tampered with', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const version = 'v1.23.2';
 | |
| 
 | |
|       const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|       const updatePath = join(tempDir, 'ghost-kitty.mp4');
 | |
|       await copy(sourcePath, updatePath);
 | |
| 
 | |
|       const privateKeyPath = join(tempDir, 'private.key');
 | |
|       const { publicKey, privateKey } = keyPair();
 | |
|       await writeHexToPath(privateKeyPath, privateKey);
 | |
| 
 | |
|       await writeSignature(updatePath, version, privateKeyPath);
 | |
| 
 | |
|       const signaturePath = getSignaturePath(updatePath);
 | |
|       const signature = Buffer.from(await loadHexFromPath(signaturePath));
 | |
|       signature[4] += 3;
 | |
|       await writeHexToPath(signaturePath, signature);
 | |
| 
 | |
|       const verified = await verifySignature(updatePath, version, publicKey);
 | |
|       assert.strictEqual(verified, false);
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   it('fails signature verification if binary file tampered with', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const version = 'v1.23.2';
 | |
| 
 | |
|       const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|       const updatePath = join(tempDir, 'ghost-kitty.mp4');
 | |
|       await copy(sourcePath, updatePath);
 | |
| 
 | |
|       const privateKeyPath = join(tempDir, 'private.key');
 | |
|       const { publicKey, privateKey } = keyPair();
 | |
|       await writeHexToPath(privateKeyPath, privateKey);
 | |
| 
 | |
|       await writeSignature(updatePath, version, privateKeyPath);
 | |
| 
 | |
|       const brokenSourcePath = join(
 | |
|         __dirname,
 | |
|         '../../../fixtures/pixabay-Soap-Bubble-7141.mp4'
 | |
|       );
 | |
|       await copy(brokenSourcePath, updatePath);
 | |
| 
 | |
|       const verified = await verifySignature(updatePath, version, publicKey);
 | |
|       assert.strictEqual(verified, false);
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   it('fails signature verification if signed by different key', async () => {
 | |
|     let tempDir;
 | |
| 
 | |
|     try {
 | |
|       tempDir = await createTempDir();
 | |
| 
 | |
|       const version = 'v1.23.2';
 | |
| 
 | |
|       const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
 | |
|       const updatePath = join(tempDir, 'ghost-kitty.mp4');
 | |
|       await copy(sourcePath, updatePath);
 | |
| 
 | |
|       const privateKeyPath = join(tempDir, 'private.key');
 | |
|       const { publicKey } = keyPair();
 | |
|       const { privateKey } = keyPair();
 | |
|       await writeHexToPath(privateKeyPath, privateKey);
 | |
| 
 | |
|       await writeSignature(updatePath, version, privateKeyPath);
 | |
| 
 | |
|       const verified = await verifySignature(updatePath, version, publicKey);
 | |
|       assert.strictEqual(verified, false);
 | |
|     } finally {
 | |
|       if (tempDir) {
 | |
|         await deleteTempDir(tempDir);
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| });
 |