SignatureAlgorithm::RSA_SHA512, 'digestAlgorithm' => DigestAlgorithm::SHA512, 'extraSignatureHeaders' => [], 'ttl' => 300, 'dateHeader' => 'D, d M Y H:i:s T', 'ttlSignatory' => 86400 * 3, 'bodyMaxSize' => 50000, ]; } /** * @inheritDoc * * @return Signatory * @throws IdentityNotFoundException * @since 31.0.0 */ public function getLocalSignatory(): Signatory { /** * TODO: manage multiple identity (external, internal, ...) to allow a limitation * based on the requested interface (ie. only accept shares from globalscale) */ if ($this->appConfig->hasKey('core', self::APPCONFIG_SIGN_IDENTITY_EXTERNAL, true)) { $identity = $this->appConfig->getValueString('core', self::APPCONFIG_SIGN_IDENTITY_EXTERNAL, lazy: true); $keyId = 'https://' . $identity . '/ocm#signature'; } else { $keyId = $this->generateKeyId(); } if (!$this->identityProofManager->hasAppKey('core', 'ocm_external')) { $this->identityProofManager->generateAppKey('core', 'ocm_external', [ 'algorithm' => 'rsa', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA, ]); } $keyPair = $this->identityProofManager->getAppKey('core', 'ocm_external'); $signatory = new Signatory(true); $signatory->setKeyId($keyId); $signatory->setPublicKey($keyPair->getPublic()); $signatory->setPrivateKey($keyPair->getPrivate()); return $signatory; } /** * - tries to generate a keyId using global configuration (from signature manager) if available * - generate a keyId using the current route to ocm shares * * @return string * @throws IdentityNotFoundException */ private function generateKeyId(): string { try { return $this->signatureManager->generateKeyIdFromConfig('/ocm#signature'); } catch (IdentityNotFoundException) { } $url = $this->urlGenerator->linkToRouteAbsolute('cloud_federation_api.requesthandlercontroller.addShare'); $identity = $this->signatureManager->extractIdentityFromUri($url); // catching possible subfolder to create a keyId like 'https://hostname/subfolder/ocm#signature $path = parse_url($url, PHP_URL_PATH); $pos = strpos($path, '/ocm/shares'); $sub = ($pos) ? substr($path, 0, $pos) : ''; return 'https://' . $identity . $sub . '/ocm#signature'; } /** * @inheritDoc * * @param string $remote * * @return Signatory|null must be NULL if no signatory is found * @since 31.0.0 */ public function getRemoteSignatory(string $remote): ?Signatory { try { $ocmProvider = $this->ocmDiscoveryService->discover($remote, true); /** * @experimental 31.0.0 * @psalm-suppress UndefinedInterfaceMethod */ $signatory = $ocmProvider->getSignatory(); $signatory?->setSignatoryType(SignatoryType::TRUSTED); return $signatory; } catch (OCMProviderException $e) { $this->logger->warning('fail to get remote signatory', ['exception' => $e, 'remote' => $remote]); return null; } } }