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
		
	
| 
								 
											7 years ago
										 
									 | 
							
								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);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 |