Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
PROJECTNAME: 'web-eid/web-eid-authtoken-validation-php'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Download Coverity Build Tool
run: |
curl --silent --data "token=$TOKEN&project=$PROJECTNAME" -o cov-analysis-linux64.tar.gz https://scan.coverity.com/download/linux64
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: shivammathur/setup-php@v2
with:
Expand All @@ -26,7 +26,7 @@ jobs:

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
Expand Down
2 changes: 1 addition & 1 deletion src/certificate/CertificateValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static function validateIsValidAndSignedByTrustedCA(

if ($certificate->validateSignature()) {
$chain = $certificate->getChain();
$trustedCACert = end($chain);
$trustedCACert = next($chain);

// Verify that the trusted CA cert is presently valid before returning the result.
self::certificateIsValidOnDate($trustedCACert, $now, "Trusted CA");
Expand Down
70 changes: 70 additions & 0 deletions tests/certificate/CertificateValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@
namespace web_eid\web_eid_authtoken_validation_php\certificate;

use DateTime;
use phpseclib3\File\X509;
use web_eid\web_eid_authtoken_validation_php\testutil\Certificates;
use web_eid\web_eid_authtoken_validation_php\testutil\Dates;
use web_eid\web_eid_authtoken_validation_php\util\TrustedCertificates;
use PHPUnit\Framework\TestCase;
use web_eid\web_eid_authtoken_validation_php\exceptions\CertificateExpiredException;
use web_eid\web_eid_authtoken_validation_php\exceptions\CertificateNotTrustedException;
use web_eid\web_eid_authtoken_validation_php\exceptions\CertificateNotYetValidException;

class CertificateValidatorTest extends TestCase
{

protected function tearDown(): void
{
Dates::resetMockedCertificateValidatorDate();
}

public function testWhenCertificateDateValid(): void
{
$cert = Certificates::getJaakKristjanEsteid2018Cert();
Expand All @@ -56,4 +65,65 @@ public function testWhenCertificateExpired(): void
$cert = Certificates::getJaakKristjanEsteid2018Cert();
$this->assertNull(CertificateValidator::certificateIsValidOnDate($cert, new DateTime("20.01.2050 16:00:00"), "User"));
}

public function testWhenCertSignedByDirectIssuerThenReturnsIssuerCert(): void
{
Dates::setMockedCertificateValidatorDate(new DateTime("2022-01-20 16:00:00"));

$issuerCA = Certificates::getTestEsteid2018CA();

$result = CertificateValidator::validateIsValidAndSignedByTrustedCA(
$this->freshJaakKristjanCert(),
new TrustedCertificates([$issuerCA])
);

$this->assertEquals(
$issuerCA->saveX509($issuerCA->getCurrentCert(), X509::FORMAT_PEM),
$result->saveX509($result->getCurrentCert(), X509::FORMAT_PEM)
);
}

public function testWhenCertWithThreeLevelChainThenReturnsIssuerNotRootCert(): void
{
Dates::setMockedCertificateValidatorDate(new DateTime("2022-01-20 16:00:00"));

$issuerCA = Certificates::getTestEsteid2018CA();
$rootCA = Certificates::getTestEsteid2018CAGov();

$result = CertificateValidator::validateIsValidAndSignedByTrustedCA(
$this->freshJaakKristjanCert(),
new TrustedCertificates([$issuerCA, $rootCA])
);

// The intermediate issuing CA must be returned, not the root CA
$this->assertEquals(
$issuerCA->saveX509($issuerCA->getCurrentCert(), X509::FORMAT_PEM),
$result->saveX509($result->getCurrentCert(), X509::FORMAT_PEM)
);
$this->assertNotEquals(
$rootCA->saveX509($rootCA->getCurrentCert(), X509::FORMAT_PEM),
$result->saveX509($result->getCurrentCert(), X509::FORMAT_PEM)
);
}

public function testWhenCertNotTrustedThenThrows(): void
{
Dates::setMockedCertificateValidatorDate(new DateTime("2022-01-20 16:00:00"));

$this->expectException(CertificateNotTrustedException::class);

CertificateValidator::validateIsValidAndSignedByTrustedCA(
$this->freshJaakKristjanCert(),
new TrustedCertificates([Certificates::getTestEsteid2015CA()])
);
}

private function freshJaakKristjanCert(): X509
{
// Load a fresh instance so that loadCA() calls from previous tests don't accumulate
$template = Certificates::getJaakKristjanEsteid2018Cert();
$fresh = new X509();
$fresh->loadX509($template->saveX509($template->getCurrentCert(), X509::FORMAT_PEM));
return $fresh;
}
}