diff --git a/composer.json b/composer.json index f1c3a1a6..9ddce743 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "psr/container": "^2.0", "psr/log": "^3", "simplesamlphp/composer-module-installer": "^1.3", - "simplesamlphp/openid": "^0", + "simplesamlphp/openid": "~0.0.18", "spomky-labs/base64url": "^2.0", "symfony/expression-language": "^6.3", "symfony/psr-http-message-bridge": "^7.1", diff --git a/config/module_oidc.php.dist b/config/module_oidc.php.dist index 802be944..98ac0cb7 100644 --- a/config/module_oidc.php.dist +++ b/config/module_oidc.php.dist @@ -410,6 +410,13 @@ $config = [ ], ], + // (optional) Trust Mark Status Endpoint Usage Policy. Check the TrustMarkStatusEndpointUsagePolicyEnum for the + // available options. Default is RequiredIfEndpointProvidedForNonExpiringTrustMarksOnly, meaning that the + // Trust Mark Status Endpoint will be used to check the status of non-expiring Trust Marks if the + // Trust Mark Status Endpoint is provided by the Trust Mark Issuer. + ModuleConfig::OPTION_FEDERATION_TRUST_MARK_STATUS_ENDPOINT_USAGE_POLICY => + \SimpleSAML\OpenID\Codebooks\TrustMarkStatusEndpointUsagePolicyEnum::RequiredIfEndpointProvidedForNonExpiringTrustMarksOnly, + // (optional) Dedicated federation cache adapter, used to cache federation artifacts like trust chains, entity // statements, etc. It will also be used for token reuse check in federation context. Setting this option is // recommended in production environments. If set to null, no caching will be used. Can be set to any diff --git a/docs/6-oidc-upgrade.md b/docs/6-oidc-upgrade.md index 434fd522..eae2b3f5 100644 --- a/docs/6-oidc-upgrade.md +++ b/docs/6-oidc-upgrade.md @@ -74,6 +74,7 @@ capabilities are to be used): statements - federation participation limiting based on Trust Marks for RPs - (from v6.1) own Trust Marks to dynamically fetch + - (from v6.3) Trust Mark Status Endpoint Usage Policy - signer algorithm - entity statement duration - organization name @@ -131,6 +132,13 @@ menu in the Administration area. `config-templates/module_oidc.php` to `config/module_oidc.php.dist`. This is only relevant for new installations, since initially it is necessary to copy the template file to the default SSP config dir. +- (from v6.3) A new option for Trust Mark Status Endpoint Usage Policy has +been introduced, which can be used to control how the Trust Mark Status +Endpoint is used when validating Trust Marks. The default value is +`RequiredIfEndpointProvidedForNonExpiringTrustMarksOnly`, which +means that the Trust Mark Status Endpoint is only used if the +endpoint is provided by the Trust Mark Issuer, and the Trust +Mark does not expire. Below are also some internal changes that should not have an impact on the OIDC OP implementers. However, if you are using this module as a library or diff --git a/src/Factories/FederationFactory.php b/src/Factories/FederationFactory.php index 96503899..b2db10f4 100644 --- a/src/Factories/FederationFactory.php +++ b/src/Factories/FederationFactory.php @@ -43,6 +43,8 @@ public function build(): Federation maxCacheDuration: $this->moduleConfig->getFederationCacheMaxDurationForFetched(), cache: $this->federationCache?->cache, logger: $this->loggerService, + defaultTrustMarkStatusEndpointUsagePolicyEnum: + $this->moduleConfig->getFederationTrustMarkStatusEndpointUsagePolicy(), ); } } diff --git a/src/ModuleConfig.php b/src/ModuleConfig.php index d595503e..3abe4bbe 100644 --- a/src/ModuleConfig.php +++ b/src/ModuleConfig.php @@ -25,6 +25,7 @@ use SimpleSAML\Module\oidc\Bridges\SspBridge; use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException; use SimpleSAML\OpenID\Codebooks\ScopesEnum; +use SimpleSAML\OpenID\Codebooks\TrustMarkStatusEndpointUsagePolicyEnum; class ModuleConfig { @@ -82,14 +83,16 @@ class ModuleConfig final public const OPTION_FEDERATION_TRUST_ANCHORS = 'federation_trust_anchors'; final public const OPTION_FEDERATION_TRUST_MARK_TOKENS = 'federation_trust_mark_tokens'; final public const OPTION_FEDERATION_DYNAMIC_TRUST_MARKS = 'federation_dynamic_trust_mark_tokens'; + final public const OPTION_FEDERATION_PARTICIPATION_LIMIT_BY_TRUST_MARKS = + 'federation_participation_limit_by_trust_marks'; + final public const OPTION_FEDERATION_TRUST_MARK_STATUS_ENDPOINT_USAGE_POLICY = + 'federation_trust_mark_status_endpoint_usage_policy'; final public const OPTION_FEDERATION_CACHE_DURATION_FOR_PRODUCED = 'federation_cache_duration_for_produced'; final public const OPTION_PROTOCOL_CACHE_ADAPTER = 'protocol_cache_adapter'; final public const OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS = 'protocol_cache_adapter_arguments'; final public const OPTION_PROTOCOL_USER_ENTITY_CACHE_DURATION = 'protocol_user_entity_cache_duration'; final public const OPTION_PROTOCOL_CLIENT_ENTITY_CACHE_DURATION = 'protocol_client_entity_cache_duration'; final public const OPTION_PROTOCOL_DISCOVERY_SHOW_CLAIMS_SUPPORTED = 'protocol_discover_show_claims_supported'; - final public const OPTION_FEDERATION_PARTICIPATION_LIMIT_BY_TRUST_MARKS = - 'federation_participation_limit_by_trust_marks'; final public const OPTION_PKI_NEW_PRIVATE_KEY_PASSPHRASE = 'new_private_key_passphrase'; final public const OPTION_PKI_NEW_PRIVATE_KEY_FILENAME = 'new_privatekey'; @@ -817,6 +820,21 @@ public function getFederationParticipationLimitByTrustMarks(): array ); } + public function getFederationTrustMarkStatusEndpointUsagePolicy(): TrustMarkStatusEndpointUsagePolicyEnum + { + /** @psalm-suppress MixedAssignment */ + $policy = $this->config()->getOptionalValue( + self::OPTION_FEDERATION_TRUST_MARK_STATUS_ENDPOINT_USAGE_POLICY, + null, + ); + + if ($policy instanceof TrustMarkStatusEndpointUsagePolicyEnum) { + return $policy; + } + + return TrustMarkStatusEndpointUsagePolicyEnum::RequiredIfEndpointProvidedForNonExpiringTrustMarksOnly; + } + /** * @throws \SimpleSAML\Error\ConfigurationError */ diff --git a/tests/unit/src/ModuleConfigTest.php b/tests/unit/src/ModuleConfigTest.php index 51237c14..94b84f8d 100644 --- a/tests/unit/src/ModuleConfigTest.php +++ b/tests/unit/src/ModuleConfigTest.php @@ -15,6 +15,7 @@ use SimpleSAML\Module\oidc\Bridges\SspBridge; use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException; +use SimpleSAML\OpenID\Codebooks\TrustMarkStatusEndpointUsagePolicyEnum; use SimpleSAML\Utils\Config; use SimpleSAML\Utils\HTTP; use stdClass; @@ -476,4 +477,25 @@ public function testCanGetIsFederationParticipationLimitedByTrustMarksFor(): voi $this->sut()->isFederationParticipationLimitedByTrustMarksFor('https://ta.example.org/'), ); } + + public function testCanGetFederationTrustMarkStatusEndpointUsagePolicy(): void + { + // Assert default policy. + $this->assertSame( + TrustMarkStatusEndpointUsagePolicyEnum::RequiredIfEndpointProvidedForNonExpiringTrustMarksOnly, + $this->sut()->getFederationTrustMarkStatusEndpointUsagePolicy(), + ); + + // Assert custom configuration. + $sut = $this->sut( + overrides: [ + ModuleConfig::OPTION_FEDERATION_TRUST_MARK_STATUS_ENDPOINT_USAGE_POLICY => + TrustMarkStatusEndpointUsagePolicyEnum::Required, + ], + ); + $this->assertSame( + TrustMarkStatusEndpointUsagePolicyEnum::Required, + $sut->getFederationTrustMarkStatusEndpointUsagePolicy(), + ); + } }