diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2024-12-03 09:53:36 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2024-12-04 09:30:55 -0100 |
commit | 4df315552391af1c89516fa2f2c1796666f086be (patch) | |
tree | 90c08080734f5ea5d3272d04f81c82776fe69c6d /lib | |
parent | 948547bd5dbd181122333b8636f094638b036b39 (diff) | |
download | nextcloud-server-4df315552391af1c89516fa2f2c1796666f086be.tar.gz nextcloud-server-4df315552391af1c89516fa2f2c1796666f086be.zip |
fix(signed-request): removing unstable from public
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/OCM/Model/OCMProvider.php | 7 | ||||
-rw-r--r-- | lib/private/OCM/OCMSignatoryManager.php | 25 | ||||
-rw-r--r-- | lib/private/Security/Signature/Model/IncomingSignedRequest.php | 52 | ||||
-rw-r--r-- | lib/private/Security/Signature/SignatureManager.php | 6 | ||||
-rw-r--r-- | lib/public/OCM/IOCMProvider.php | 36 | ||||
-rw-r--r-- | lib/unstable/Security/Signature/Model/Signatory.php | 3 |
6 files changed, 54 insertions, 75 deletions
diff --git a/lib/private/OCM/Model/OCMProvider.php b/lib/private/OCM/Model/OCMProvider.php index fb13b7c0f93..61005d3089d 100644 --- a/lib/private/OCM/Model/OCMProvider.php +++ b/lib/private/OCM/Model/OCMProvider.php @@ -210,7 +210,10 @@ class OCMProvider implements IOCMProvider { * enabled: bool, * apiVersion: '1.0-proposal1', * endPoint: string, - * publicKey: Signatory|null, + * publicKey: array{ + * keyId: string, + * publicKeyPem: string + * }, * resourceTypes: list<array{ * name: string, * shareTypes: list<string>, @@ -230,7 +233,7 @@ class OCMProvider implements IOCMProvider { 'apiVersion' => '1.0-proposal1', // deprecated, but keep it to stay compatible with old version 'version' => $this->getApiVersion(), // informative but real version 'endPoint' => $this->getEndPoint(), - 'publicKey' => $this->getSignatory(), + 'publicKey' => $this->getSignatory()->jsonSerialize(), 'resourceTypes' => $resourceTypes ]; } diff --git a/lib/private/OCM/OCMSignatoryManager.php b/lib/private/OCM/OCMSignatoryManager.php index 6b6917bcd4b..3b2cc595507 100644 --- a/lib/private/OCM/OCMSignatoryManager.php +++ b/lib/private/OCM/OCMSignatoryManager.php @@ -144,26 +144,17 @@ class OCMSignatoryManager implements ISignatoryManager { */ public function getRemoteSignatory(string $remote): ?Signatory { try { - return $this->getRemoteSignatoryFromHost($remote); + $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; } } - - /** - * As host is enough to generate signatory using OCMDiscoveryService - * - * @param string $host - * - * @return Signatory|null - * @throws OCMProviderException on fail to discover ocm services - * @since 31.0.0 - */ - public function getRemoteSignatoryFromHost(string $host): ?Signatory { - $ocmProvider = $this->ocmDiscoveryService->discover($host, true); - $signatory = $ocmProvider->getSignatory(); - $signatory?->setSignatoryType(SignatoryType::TRUSTED); - return $signatory; - } } diff --git a/lib/private/Security/Signature/Model/IncomingSignedRequest.php b/lib/private/Security/Signature/Model/IncomingSignedRequest.php index 2a1aa82ac50..d644aa8e1c1 100644 --- a/lib/private/Security/Signature/Model/IncomingSignedRequest.php +++ b/lib/private/Security/Signature/Model/IncomingSignedRequest.php @@ -13,7 +13,6 @@ use NCU\Security\Signature\Enum\SignatureAlgorithm; use NCU\Security\Signature\Exceptions\IdentityNotFoundException; use NCU\Security\Signature\Exceptions\IncomingRequestException; use NCU\Security\Signature\Exceptions\InvalidSignatureException; -use NCU\Security\Signature\Exceptions\SignatoryException; use NCU\Security\Signature\Exceptions\SignatoryNotFoundException; use NCU\Security\Signature\Exceptions\SignatureElementNotFoundException; use NCU\Security\Signature\Exceptions\SignatureException; @@ -53,6 +52,13 @@ class IncomingSignedRequest extends SignedRequest implements $this->verifyHeaders(); $this->extractSignatureHeader(); $this->reconstructSignatureData(); + + try { + // we set origin based on the keyId defined in the Signature header of the request + $this->setOrigin(Signatory::extractIdentityFromUri($this->getSigningElement('keyId'))); + } catch (IdentityNotFoundException $e) { + throw new IncomingRequestException($e->getMessage()); + } } /** @@ -66,21 +72,22 @@ class IncomingSignedRequest extends SignedRequest implements * @throws SignatureNotFoundException */ private function verifyHeaders(): void { + if ($this->request->getHeader('Signature') === '') { + throw new SignatureNotFoundException('missing Signature in header'); + } + // confirm presence of date, content-length, digest and Signature - $date = $this->getRequest()->getHeader('date'); + $date = $this->request->getHeader('date'); if ($date === '') { - throw new SignatureNotFoundException('missing date in header'); + throw new IncomingRequestException('missing date in header'); } - $contentLength = $this->getRequest()->getHeader('content-length'); + $contentLength = $this->request->getHeader('content-length'); if ($contentLength === '') { - throw new SignatureNotFoundException('missing content-length in header'); + throw new IncomingRequestException('missing content-length in header'); } - $digest = $this->getRequest()->getHeader('digest'); + $digest = $this->request->getHeader('digest'); if ($digest === '') { - throw new SignatureNotFoundException('missing digest in header'); - } - if ($this->getRequest()->getHeader('Signature') === '') { - throw new SignatureNotFoundException('missing Signature in header'); + throw new IncomingRequestException('missing digest in header'); } // confirm date @@ -113,7 +120,7 @@ class IncomingSignedRequest extends SignedRequest implements */ private function extractSignatureHeader(): void { $details = []; - foreach (explode(',', $this->getRequest()->getHeader('Signature')) as $entry) { + foreach (explode(',', $this->request->getHeader('Signature')) as $entry) { if ($entry === '' || !strpos($entry, '=')) { continue; } @@ -139,6 +146,8 @@ class IncomingSignedRequest extends SignedRequest implements } /** + * reconstruct signature data based on signature's metadata stored in the 'Signature' header + * * @throws SignatureException * @throws SignatureElementNotFoundException */ @@ -181,27 +190,6 @@ class IncomingSignedRequest extends SignedRequest implements /** * @inheritDoc * - * @param Signatory $signatory - * - * @return $this - * @throws IdentityNotFoundException - * @throws IncomingRequestException - * @throws SignatoryException - * @since 31.0.0 - */ - public function setSignatory(Signatory $signatory): self { - $identity = \OCP\Server::get(ISignatureManager::class)->extractIdentityFromUri($signatory->getKeyId()); - if ($identity !== $this->getOrigin()) { - throw new SignatoryException('keyId from provider is different from the one from signed request'); - } - - parent::setSignatory($signatory); - return $this; - } - - /** - * @inheritDoc - * * @param string $origin * @return IIncomingSignedRequest * @since 31.0.0 diff --git a/lib/private/Security/Signature/SignatureManager.php b/lib/private/Security/Signature/SignatureManager.php index b04d683a3b9..fa52bbfaa7c 100644 --- a/lib/private/Security/Signature/SignatureManager.php +++ b/lib/private/Security/Signature/SignatureManager.php @@ -102,12 +102,6 @@ class SignatureManager implements ISignatureManager { // generate IncomingSignedRequest based on body and request $signedRequest = new IncomingSignedRequest($body, $this->request, $options); - try { - // we set origin based on the keyId defined in the Signature header of the request - $signedRequest->setOrigin($this->extractIdentityFromUri($signedRequest->getSigningElement('keyId'))); - } catch (IdentityNotFoundException $e) { - throw new IncomingRequestException($e->getMessage()); - } try { // confirm the validity of content and identity of the incoming request diff --git a/lib/public/OCM/IOCMProvider.php b/lib/public/OCM/IOCMProvider.php index cd2a59ebd5e..a588d869655 100644 --- a/lib/public/OCM/IOCMProvider.php +++ b/lib/public/OCM/IOCMProvider.php @@ -9,7 +9,6 @@ declare(strict_types=1); namespace OCP\OCM; use JsonSerializable; -use NCU\Security\Signature\Model\Signatory; use OCP\OCM\Exceptions\OCMArgumentException; use OCP\OCM\Exceptions\OCMProviderException; @@ -120,21 +119,21 @@ interface IOCMProvider extends JsonSerializable { */ public function extractProtocolEntry(string $resourceName, string $protocol): string; - /** - * store signatory (public/private key pair) to sign outgoing/incoming request - * - * @param Signatory $signatory - * @since 31.0.0 - */ - public function setSignatory(Signatory $signatory): void; - - /** - * signatory (public/private key pair) used to sign outgoing/incoming request - * - * @return Signatory|null returns null if no Signatory available - * @since 31.0.0 - */ - public function getSignatory(): ?Signatory; + // /** + // * store signatory (public/private key pair) to sign outgoing/incoming request + // * + // * @param Signatory $signatory + // * @experimental 31.0.0 + // */ + // public function setSignatory(Signatory $signatory): void; + + // /** + // * signatory (public/private key pair) used to sign outgoing/incoming request + // * + // * @return Signatory|null returns null if no Signatory available + // * @experimental 31.0.0 + // */ + // public function getSignatory(): ?Signatory; /** * import data from an array @@ -152,7 +151,10 @@ interface IOCMProvider extends JsonSerializable { * enabled: bool, * apiVersion: '1.0-proposal1', * endPoint: string, - * publicKey: Signatory|null, + * publicKey: array{ + * keyId: string, + * publicKeyPem: string + * }, * resourceTypes: list<array{ * name: string, * shareTypes: list<string>, diff --git a/lib/unstable/Security/Signature/Model/Signatory.php b/lib/unstable/Security/Signature/Model/Signatory.php index 7d11a90d24c..d42be9c4544 100644 --- a/lib/unstable/Security/Signature/Model/Signatory.php +++ b/lib/unstable/Security/Signature/Model/Signatory.php @@ -154,6 +154,7 @@ class Signatory extends Entity implements JsonSerializable { */ public function setMetaValue(string $key, string|int|float|bool|array $value): void { $this->metadata[$key] = $value; + $this->setter('metadata', [$this->metadata]); } /** @@ -174,7 +175,7 @@ class Signatory extends Entity implements JsonSerializable { * * @return string * @throws IdentityNotFoundException if identity cannot be extracted - * @since 31.0.0 + * @experimental 31.0.0 */ public static function extractIdentityFromUri(string $uri): string { $identity = parse_url($uri, PHP_URL_HOST); |