diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 1882689..1974360 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -15,7 +15,7 @@ build: file: build/logs/clover.xml environment: php: - version: 7.2 + version: 8.0 filter: excluded_paths: - test/ diff --git a/.travis.yml b/.travis.yml index 98fb6d6..08516d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: php php: - - "7.2" - - "7.3" + - "8.0" + - "8.1" before_script: - "composer install" - "composer require php-coveralls/php-coveralls" diff --git a/README.md b/README.md index 38770b1..11d5cd2 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ textual encodings of cryptographic structures _(PEM)_. ## Requirements -- PHP >=7.2 +- PHP >=8.0 ## Installation diff --git a/composer.json b/composer.json index d1764e1..905f8d1 100644 --- a/composer.json +++ b/composer.json @@ -18,14 +18,14 @@ } ], "require": { - "php": ">=7.2" + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^8.1" + "phpunit/phpunit": "^9.5" }, "autoload": { "psr-4": { "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" } } -} \ No newline at end of file +} diff --git a/lib/CryptoEncoding/PEM.php b/lib/CryptoEncoding/PEM.php index d55b858..da76abd 100644 --- a/lib/CryptoEncoding/PEM.php +++ b/lib/CryptoEncoding/PEM.php @@ -1,9 +1,20 @@ _type = $type; - $this->_data = $data; + $this->type = $type; + $this->data = $data; } /** @@ -83,12 +95,12 @@ public function __toString(): string public static function fromString(string $str): self { if (!preg_match(self::PEM_REGEX, $str, $match)) { - throw new \UnexpectedValueException('Not a PEM formatted string.'); + throw new UnexpectedValueException('Not a PEM formatted string.'); } $payload = preg_replace('/\s+/', '', $match[2]); $data = base64_decode($payload, true); if (false === $data) { - throw new \UnexpectedValueException('Failed to decode PEM data.'); + throw new UnexpectedValueException('Failed to decode PEM data.'); } return new self($match[1], $data); } @@ -104,9 +116,11 @@ public static function fromString(string $str): self */ public static function fromFile(string $filename): self { - if (!is_readable($filename) || - false === ($str = file_get_contents($filename))) { - throw new \RuntimeException("Failed to read {$filename}."); + if ( + !is_readable($filename) || + false === ($str = file_get_contents($filename)) + ) { + throw new RuntimeException("Failed to read {$filename}."); } return self::fromString($str); } @@ -118,7 +132,7 @@ public static function fromFile(string $filename): self */ public function type(): string { - return $this->_type; + return $this->type; } /** @@ -128,7 +142,7 @@ public function type(): string */ public function data(): string { - return $this->_data; + return $this->data; } /** @@ -138,8 +152,13 @@ public function data(): string */ public function string(): string { - return "-----BEGIN {$this->_type}-----\n" . - trim(chunk_split(base64_encode($this->_data), 64, "\n")) . "\n" . - "-----END {$this->_type}-----"; + return sprintf( + "-----BEGIN %s-----\n' . + '%s\n' . + '-----END %s-----", + $this->type, + trim(chunk_split(base64_encode($this->data), 64, "\n")), + $this->type + ); } } diff --git a/lib/CryptoEncoding/PEMBundle.php b/lib/CryptoEncoding/PEMBundle.php index 54c528d..46d5207 100644 --- a/lib/CryptoEncoding/PEMBundle.php +++ b/lib/CryptoEncoding/PEMBundle.php @@ -1,31 +1,48 @@ _pems = $pems; + $this->pems = $pems; } /** @@ -48,18 +65,21 @@ public function __toString(): string public static function fromString(string $str): self { if (!preg_match_all(PEM::PEM_REGEX, $str, $matches, PREG_SET_ORDER)) { - throw new \UnexpectedValueException('No PEM blocks.'); + throw new UnexpectedValueException('No PEM blocks.'); } + $pems = array_map( function ($match) { $payload = preg_replace('/\s+/', '', $match[2]); $data = base64_decode($payload, true); if (false === $data) { - throw new \UnexpectedValueException( - 'Failed to decode PEM data.'); + throw new UnexpectedValueException('Failed to decode PEM data.'); } return new PEM($match[1], $data); - }, $matches); + }, + $matches + ); + return new self(...$pems); } @@ -74,9 +94,11 @@ function ($match) { */ public static function fromFile(string $filename): self { - if (!is_readable($filename) || - false === ($str = file_get_contents($filename))) { - throw new \RuntimeException("Failed to read {$filename}."); + if ( + !is_readable($filename) || + false === ($str = file_get_contents($filename)) + ) { + throw new RuntimeException("Failed to read {$filename}."); } return self::fromString($str); } @@ -91,18 +113,18 @@ public static function fromFile(string $filename): self public function withPEMs(PEM ...$pems): self { $obj = clone $this; - $obj->_pems = array_merge($obj->_pems, $pems); + $obj->pems = array_merge($obj->pems, $pems); return $obj; } /** * Get all PEMs in a bundle. * - * @return PEM[] + * @return \Sop\CryptoEncoding\PEM[] */ public function all(): array { - return $this->_pems; + return $this->pems; } /** @@ -110,14 +132,14 @@ public function all(): array * * @throws \LogicException If bundle contains no PEM objects * - * @return PEM + * @return \Sop\CryptoEncoding\PEM */ public function first(): PEM { - if (!count($this->_pems)) { - throw new \LogicException('No PEMs.'); + if (!count($this->pems)) { + throw new LogicException('No PEMs.'); } - return $this->_pems[0]; + return $this->pems[0]; } /** @@ -125,14 +147,14 @@ public function first(): PEM * * @throws \LogicException If bundle contains no PEM objects * - * @return PEM + * @return \Sop\CryptoEncoding\PEM */ public function last(): PEM { - if (!count($this->_pems)) { - throw new \LogicException('No PEMs.'); + if (!count($this->pems)) { + throw new LogicException('No PEMs.'); } - return $this->_pems[count($this->_pems) - 1]; + return $this->pems[count($this->pems) - 1]; } /** @@ -142,7 +164,7 @@ public function last(): PEM */ public function count(): int { - return count($this->_pems); + return count($this->pems); } /** @@ -152,9 +174,9 @@ public function count(): int * * @return \ArrayIterator */ - public function getIterator(): \ArrayIterator + public function getIterator(): ArrayIterator { - return new \ArrayIterator($this->_pems); + return new ArrayIterator($this->pems); } /** @@ -164,10 +186,14 @@ public function getIterator(): \ArrayIterator */ public function string(): string { - return implode("\n", + return implode( + "\n", array_map( function (PEM $pem) { return $pem->string(); - }, $this->_pems)); + }, + $this->pems + ) + ); } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index fb8cff1..40ae1c5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,26 +1,18 @@ - - - - test/unit - - - - - lib - - - - - - - \ No newline at end of file + + + + lib + + + + + + + + + test/unit + + + + diff --git a/test/bootstrap.php b/test/bootstrap.php index 95bcee8..61e0f2a 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -1,6 +1,6 @@ assertInstanceOf(PEMBundle::class, $bundle); @@ -26,9 +31,9 @@ public function testBundle() /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testAll(PEMBundle $bundle) + public function testAll(PEMBundle $bundle): void { $this->assertContainsOnlyInstancesOf(PEM::class, $bundle->all()); } @@ -36,9 +41,9 @@ public function testAll(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testFirst(PEMBundle $bundle) + public function testFirst(PEMBundle $bundle): void { $this->assertInstanceOf(PEM::class, $bundle->first()); $this->assertEquals($bundle->all()[0], $bundle->first()); @@ -47,9 +52,9 @@ public function testFirst(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testLast(PEMBundle $bundle) + public function testLast(PEMBundle $bundle): void { $this->assertInstanceOf(PEM::class, $bundle->last()); $this->assertEquals($bundle->all()[149], $bundle->last()); @@ -58,9 +63,9 @@ public function testLast(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testCount(PEMBundle $bundle) + public function testCount(PEMBundle $bundle): void { $this->assertCount(150, $bundle); } @@ -68,9 +73,9 @@ public function testCount(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testIterator(PEMBundle $bundle) + public function testIterator(PEMBundle $bundle): void { $values = []; foreach ($bundle as $pem) { @@ -82,9 +87,9 @@ public function testIterator(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testString(PEMBundle $bundle) + public function testString(PEMBundle $bundle): void { $this->assertIsString($bundle->string()); } @@ -92,20 +97,20 @@ public function testString(PEMBundle $bundle) /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ - public function testToString(PEMBundle $bundle) + public function testToString(PEMBundle $bundle): void { $this->assertIsString(strval($bundle)); } - public function testInvalidPEM() + public function testInvalidPEM(): void { $this->expectException(UnexpectedValueException::class); PEMBundle::fromString('invalid'); } - public function testInvalidPEMData() + public function testInvalidPEMData(): void { $str = <<<'DATA' -----BEGIN TEST----- @@ -116,20 +121,20 @@ public function testInvalidPEMData() PEMBundle::fromString($str); } - public function testInvalidFile() + public function testInvalidFile(): void { $this->expectException(RuntimeException::class); PEMBundle::fromFile(TEST_ASSETS_DIR . '/nonexistent'); } - public function testFirstEmptyFail() + public function testFirstEmptyFail(): void { $bundle = new PEMBundle(); $this->expectException(LogicException::class); $bundle->first(); } - public function testLastEmptyFail() + public function testLastEmptyFail(): void { $bundle = new PEMBundle(); $this->expectException(LogicException::class); @@ -139,7 +144,7 @@ public function testLastEmptyFail() /** * @depends testBundle * - * @param PEMBundle $bundle + * @param \Sop\CryptoEncoding\PEMBundle $bundle */ public function testWithPEMs(PEMBundle $bundle) { diff --git a/test/unit/PEMTest.php b/test/unit/PEMTest.php index 14121b2..757ced0 100644 --- a/test/unit/PEMTest.php +++ b/test/unit/PEMTest.php @@ -1,9 +1,16 @@ assertEquals(PEM::TYPE_PUBLIC_KEY, $pem->type()); } - public function testData() + public function testData(): void { $data = 'payload'; $encoded = base64_encode($data); @@ -51,13 +58,13 @@ public function testData() $this->assertEquals($data, PEM::fromString($str)->data()); } - public function testInvalidPEM() + public function testInvalidPEM(): void { $this->expectException(UnexpectedValueException::class); PEM::fromString('invalid'); } - public function testInvalidPEMData() + public function testInvalidPEMData(): void { $str = <<<'DATA' -----BEGIN TEST----- @@ -68,7 +75,7 @@ public function testInvalidPEMData() PEM::fromString($str); } - public function testInvalidFile() + public function testInvalidFile(): void { $this->expectException(RuntimeException::class); PEM::fromFile(TEST_ASSETS_DIR . '/nonexistent'); @@ -77,9 +84,9 @@ public function testInvalidFile() /** * @depends testFromFile * - * @param PEM $pem + * @param \Sop\CryptoEncoding\PEM $pem */ - public function testString(PEM $pem) + public function testString(PEM $pem): void { $this->assertIsString($pem->string()); } @@ -87,9 +94,9 @@ public function testString(PEM $pem) /** * @depends testFromFile * - * @param PEM $pem + * @param \Sop\CryptoEncoding\PEM $pem */ - public function testToString(PEM $pem) + public function testToString(PEM $pem): void { $this->assertIsString(strval($pem)); }