Prepare auto updates
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Updater;
|
||||
|
||||
use LIT\MCP\Updater\PackageSignature;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class PackageSignatureTest extends TestCase
|
||||
{
|
||||
private string $zip = '';
|
||||
private string $secretKey = '';
|
||||
private PackageSignature $signature;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$pair = sodium_crypto_sign_keypair();
|
||||
$this->secretKey = sodium_crypto_sign_secretkey($pair);
|
||||
$this->signature = new PackageSignature(base64_encode(sodium_crypto_sign_publickey($pair)));
|
||||
$this->zip = (string) tempnam(sys_get_temp_dir(), 'lit-mcp-sig');
|
||||
file_put_contents($this->zip, 'zip bytes');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
unlink($this->zip);
|
||||
}
|
||||
|
||||
public function testASignatureOverNameAndContentVerifies(): void
|
||||
{
|
||||
$signature = $this->sign('wp-lit-mcp-1.0.0.zip');
|
||||
|
||||
self::assertTrue($this->signature->verifies('wp-lit-mcp-1.0.0.zip', $this->zip, $signature));
|
||||
}
|
||||
|
||||
public function testAnotherAssetNameDoesNotVerify(): void
|
||||
{
|
||||
$signature = $this->sign('wp-lit-mcp-1.0.0.zip');
|
||||
|
||||
self::assertFalse($this->signature->verifies('wp-lit-mcp-1.0.1.zip', $this->zip, $signature));
|
||||
}
|
||||
|
||||
public function testChangedContentDoesNotVerify(): void
|
||||
{
|
||||
$signature = $this->sign('x.zip');
|
||||
file_put_contents($this->zip, 'changed bytes');
|
||||
|
||||
self::assertFalse($this->signature->verifies('x.zip', $this->zip, $signature));
|
||||
}
|
||||
|
||||
public function testAnotherKeyDoesNotVerify(): void
|
||||
{
|
||||
$foreign = new PackageSignature(base64_encode(sodium_crypto_sign_publickey(sodium_crypto_sign_keypair())));
|
||||
|
||||
self::assertFalse($foreign->verifies('x.zip', $this->zip, $this->sign('x.zip')));
|
||||
}
|
||||
|
||||
/** @dataProvider malformedInput */
|
||||
public function testMalformedInputFailsClosed(string $signature, string $publicKey, string $zipPath): void
|
||||
{
|
||||
$subject = new PackageSignature($publicKey === 'real' ? $this->realKey() : $publicKey);
|
||||
|
||||
self::assertFalse($subject->verifies('x.zip', $zipPath === 'zip' ? $this->zip : $zipPath, $signature));
|
||||
}
|
||||
|
||||
/** @return array<string, array{string, string, string}> */
|
||||
public static function malformedInput(): array
|
||||
{
|
||||
return [
|
||||
'signature is no base64' => ['not base64 !!', 'real', 'zip'],
|
||||
'signature is empty' => ['', 'real', 'zip'],
|
||||
'signature has the wrong length' => [base64_encode('short'), 'real', 'zip'],
|
||||
'no key configured' => ['AAAA', '', 'zip'],
|
||||
'key has the wrong length' => ['AAAA', base64_encode('short'), 'zip'],
|
||||
'file is missing' => ['AAAA', 'real', '/nonexistent/x.zip'],
|
||||
];
|
||||
}
|
||||
|
||||
private function sign(string $assetName): string
|
||||
{
|
||||
$message = PackageSignature::message($assetName, $this->zip);
|
||||
|
||||
return base64_encode(sodium_crypto_sign_detached($message, $this->secretKey));
|
||||
}
|
||||
|
||||
private function realKey(): string
|
||||
{
|
||||
return base64_encode(sodium_crypto_sign_publickey(sodium_crypto_sign_keypair()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user