diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml index 56d73ac..ee2e8d9 100644 --- a/.github/workflows/diagnostics.yml +++ b/.github/workflows/diagnostics.yml @@ -16,18 +16,13 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' + - php: '8.1' phpcq_install: 'update' phpcq_flags: '' composer_install: 'update --prefer-lowest' extensions: '' - - php: '8.0' - output: '-o default' - phpcq_install: 'update' - phpcq_flags: '' - composer_install: 'update' - extensions: '' - php: '8.1' + output: '-o default' phpcq_install: 'update' phpcq_flags: '' composer_install: 'update' diff --git a/src/Signature/SignatureVerifier.php b/src/Signature/SignatureVerifier.php index 8c62123..589be87 100644 --- a/src/Signature/SignatureVerifier.php +++ b/src/Signature/SignatureVerifier.php @@ -43,7 +43,7 @@ public function verify(string $content, string $signature): VerificationResult return VerificationResult::UNKOWN_ERROR(); } - if (! $this->trustKeyStrategy->isTrusted($fingerprint)) { + if (!$this->isTrusted($fingerprint)) { return VerificationResult::UNTRUSTED_KEY($fingerprint); } @@ -68,4 +68,15 @@ private function doVerify(string $content, string $signature): VerificationResul return VerificationResult::VALID($fingerprint); } + + private function isTrusted(string $fingerprint): bool + { + if ($this->trustKeyStrategy->isTrusted($fingerprint)) { + return true; + } + if (16 < strlen($fingerprint)) { + return $this->trustKeyStrategy->isTrusted(substr($fingerprint, -16)); + } + return false; + } } diff --git a/src/Wrapper/GnuPGBinaryWrapper.php b/src/Wrapper/GnuPGBinaryWrapper.php index 9e2074f..f14735d 100644 --- a/src/Wrapper/GnuPGBinaryWrapper.php +++ b/src/Wrapper/GnuPGBinaryWrapper.php @@ -273,10 +273,10 @@ private function parseVerifyOutput(string $result) foreach ($status as $line) { $parts = explode(' ', $line); - if (count($parts) < 3) { + if (count($parts) < 8) { continue; } - $fingerprint = $parts[2]; + $fingerprint = $parts[8] ?? ''; if (strpos($line, 'VALIDSIG') !== false) { // [GNUPG:] VALIDSIG D8406D0D82947747{...}A394072C20A 2014-07-19 1405769272 0 4 0 1 10 00 D8{...}C20A diff --git a/tests/Signature/SignatureVerifierTest.php b/tests/Signature/SignatureVerifierTest.php new file mode 100644 index 0000000..2d0b0e8 --- /dev/null +++ b/tests/Signature/SignatureVerifierTest.php @@ -0,0 +1,68 @@ +createBinaryWrapper(sys_get_temp_dir()); + } catch (RuntimeException $exception) { + self::markTestSkipped('gnupg extension not loaded'); + } + + $fileDownloader = $this->createMock(FileDownloaderInterface::class); + $fileDownloader->expects($this->never())->method('downloadFile'); + $keyDownloader = new KeyDownloader($fileDownloader); + + $verifier = new SignatureVerifier($gpg, $keyDownloader); + + $baseDir = dirname(__DIR__); + + $result = $verifier->verify( + file_get_contents($baseDir . '/fixtures/test.txt'), + file_get_contents($baseDir . '/fixtures/test.txt.asc') + ); + + self::assertTrue($result->isUntrustedKey()); + self::assertSame('11BD3E86C5497BA1EB3B58B96DA9559564C3328F', $result->getFingerprint()); + } + + public function testExtractingInformationWithExtension(): void + { + $factory = new GnuPGFactory(sys_get_temp_dir()); + try { + $gpg = $factory->createExtensionWrapper(sys_get_temp_dir()); + } catch (RuntimeException $exception) { + self::markTestSkipped('gnupg extension not loaded'); + } + + $fileDownloader = $this->createMock(FileDownloaderInterface::class); + $fileDownloader->expects($this->never())->method('downloadFile'); + $keyDownloader = new KeyDownloader($fileDownloader); + + $verifier = new SignatureVerifier($gpg, $keyDownloader); + + $baseDir = dirname(__DIR__); + + $result = $verifier->verify( + file_get_contents($baseDir . '/fixtures/test.txt'), + file_get_contents($baseDir . '/fixtures/test.txt.asc') + ); + + self::assertTrue($result->isUntrustedKey()); + self::assertSame('11BD3E86C5497BA1EB3B58B96DA9559564C3328F', $result->getFingerprint()); + } +}