diff --git a/src/CA.php b/src/CA.php index 11ea19a..91f4c4a 100644 --- a/src/CA.php +++ b/src/CA.php @@ -13,12 +13,10 @@ namespace Rollerworks\Component\X509Validator; -class CA +final readonly class CA { - public function __construct(private readonly string $contents) {} - - public function getContents(): string - { - return $this->contents; - } + public function __construct( + public string $contents, + public ?self $parent = null + ) {} } diff --git a/src/CAResolverImpl.php b/src/CAResolverImpl.php index e654f1c..facca33 100644 --- a/src/CAResolverImpl.php +++ b/src/CAResolverImpl.php @@ -17,7 +17,7 @@ use Rollerworks\Component\X509Validator\Violation\TooManyCAsProvided; use Rollerworks\Component\X509Validator\Violation\UnableToResolveParent; -class CAResolverImpl implements CAResolver +final class CAResolverImpl implements CAResolver { private readonly X509DataExtractor $extractor; @@ -64,6 +64,8 @@ private function isSignatureValid(string $contents, string $pupKey): bool /** @param array $caList */ private function resolveCA(string $certificate, array $caList): CA { + $parent = null; + foreach ($caList as $index => $contents) { $data = $this->extractor->extractRawData($contents, $index, true); $this->validateCA($data); @@ -72,16 +74,16 @@ private function resolveCA(string $certificate, array $caList): CA continue; } - // Check if self signed, otherwise resolve it's parent + // Check if the CA is self signed, otherwise resolve it's parent if (! $this->isSignatureValid($contents, $data->pubKey)) { // THIS issuer cannot be the parent of another parent, so remove it // from the list. This speeds-up the resolving process. unset($caList[$index]); - $this->resolveCA($contents, $caList); + $parent = $this->resolveCA($contents, $caList); } - return new CA($contents); + return new CA($contents, $parent); } $x509Info = $this->extractor->extractRawData($certificate); diff --git a/src/OCSPValidator.php b/src/OCSPValidator.php index a0d1ee0..3ac3035 100644 --- a/src/OCSPValidator.php +++ b/src/OCSPValidator.php @@ -84,7 +84,7 @@ public function validateStatus(string $certificate, array $caList = []): void } $certificateSeq = $this->certificateLoader->fromString($certificate); - $issuerCertificate = $this->certificateLoader->fromString($ca->getContents()); + $issuerCertificate = $this->certificateLoader->fromString($ca->contents); $ocspResponderUrl = $this->certificateInfo->extractOcspResponderUrl($certificateSeq); diff --git a/src/Violation/UnableToResolveParent.php b/src/Violation/UnableToResolveParent.php index 78f118a..86a3ec0 100644 --- a/src/Violation/UnableToResolveParent.php +++ b/src/Violation/UnableToResolveParent.php @@ -17,8 +17,11 @@ final class UnableToResolveParent extends Violation { - public function __construct(private readonly string $name, private readonly string $issuer, int $code = 1) - { + public function __construct( + public readonly string $name, + public readonly string $issuer, + int $code = 1 + ) { parent::__construct(sprintf('Unable to resolve the parent CA of certificate "%s", issued by "%s".', $name, $issuer), $code); } diff --git a/tests/CAResolverImplTest.php b/tests/CAResolverImplTest.php index c07796d..85fe0df 100644 --- a/tests/CAResolverImplTest.php +++ b/tests/CAResolverImplTest.php @@ -22,6 +22,7 @@ use Rollerworks\Component\X509Validator\Violation\TooManyCAsProvided; use Rollerworks\Component\X509Validator\Violation\UnableToResolveParent; use Rollerworks\Component\X509Validator\Violation\UnprocessablePEM; +use Rollerworks\Component\X509Validator\X509Info; /** * @internal @@ -501,7 +502,7 @@ public function it_resolves_a_valid_ca_list(): void 'DigiCert SHA2 Secure Server CA' => $ca1, ]); - $intermediateCA = new CA($ca1); + $intermediateCA = new CA($ca1, new CA($ca2)); self::assertEquals($intermediateCA, $ca); }