aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2024-12-03 09:53:36 -0100
committerMaxence Lange <maxence@artificial-owl.com>2024-12-04 09:30:55 -0100
commit4df315552391af1c89516fa2f2c1796666f086be (patch)
tree90c08080734f5ea5d3272d04f81c82776fe69c6d /lib
parent948547bd5dbd181122333b8636f094638b036b39 (diff)
downloadnextcloud-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.php7
-rw-r--r--lib/private/OCM/OCMSignatoryManager.php25
-rw-r--r--lib/private/Security/Signature/Model/IncomingSignedRequest.php52
-rw-r--r--lib/private/Security/Signature/SignatureManager.php6
-rw-r--r--lib/public/OCM/IOCMProvider.php36
-rw-r--r--lib/unstable/Security/Signature/Model/Signatory.php3
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);