diff options
Diffstat (limited to 'lib/private/Security/Signature/Model/SignedRequest.php')
-rw-r--r-- | lib/private/Security/Signature/Model/SignedRequest.php | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/private/Security/Signature/Model/SignedRequest.php b/lib/private/Security/Signature/Model/SignedRequest.php new file mode 100644 index 00000000000..12a43f32bcc --- /dev/null +++ b/lib/private/Security/Signature/Model/SignedRequest.php @@ -0,0 +1,216 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Security\Signature\Model; + +use JsonSerializable; +use NCU\Security\Signature\Enum\DigestAlgorithm; +use NCU\Security\Signature\Exceptions\SignatoryNotFoundException; +use NCU\Security\Signature\Exceptions\SignatureElementNotFoundException; +use NCU\Security\Signature\ISignedRequest; +use NCU\Security\Signature\Model\Signatory; + +/** + * @inheritDoc + * + * @since 31.0.0 + */ +class SignedRequest implements ISignedRequest, JsonSerializable { + private string $digest = ''; + private DigestAlgorithm $digestAlgorithm = DigestAlgorithm::SHA256; + private array $signingElements = []; + private array $signatureData = []; + private string $signature = ''; + private ?Signatory $signatory = null; + + public function __construct( + private readonly string $body, + ) { + } + + /** + * @inheritDoc + * + * @return string + * @since 31.0.0 + */ + public function getBody(): string { + return $this->body; + } + + /** + * set algorithm used to generate digest + * + * @param DigestAlgorithm $algorithm + * + * @return self + * @since 31.0.0 + */ + protected function setDigestAlgorithm(DigestAlgorithm $algorithm): self { + $this->digestAlgorithm = $algorithm; + return $this; + } + + /** + * @inheritDoc + * + * @return DigestAlgorithm + * @since 31.0.0 + */ + public function getDigestAlgorithm(): DigestAlgorithm { + return $this->digestAlgorithm; + } + + /** + * @inheritDoc + * + * @return string + * @since 31.0.0 + */ + public function getDigest(): string { + if ($this->digest === '') { + $this->digest = $this->digestAlgorithm->value . '=' + . base64_encode(hash($this->digestAlgorithm->getHashingAlgorithm(), $this->body, true)); + } + return $this->digest; + } + + /** + * @inheritDoc + * + * @param array $elements + * + * @return self + * @since 31.0.0 + */ + public function setSigningElements(array $elements): self { + $this->signingElements = $elements; + return $this; + } + + /** + * @inheritDoc + * + * @return array + * @since 31.0.0 + */ + public function getSigningElements(): array { + return $this->signingElements; + } + + /** + * @param string $key + * + * @return string + * @throws SignatureElementNotFoundException + * @since 31.0.0 + * + */ + public function getSigningElement(string $key): string { // getSignatureDetail / getSignatureEntry() ? + if (!array_key_exists($key, $this->signingElements)) { + throw new SignatureElementNotFoundException('missing element ' . $key . ' in Signature header'); + } + + return $this->signingElements[$key]; + } + + /** + * store data used to generate signature + * + * @param array $data + * + * @return self + * @since 31.0.0 + */ + protected function setSignatureData(array $data): self { + $this->signatureData = $data; + return $this; + } + + /** + * @inheritDoc + * + * @return array + * @since 31.0.0 + */ + public function getSignatureData(): array { + return $this->signatureData; + } + + /** + * set the signed version of the signature + * + * @param string $signature + * + * @return self + * @since 31.0.0 + */ + protected function setSignature(string $signature): self { + $this->signature = $signature; + return $this; + } + + /** + * @inheritDoc + * + * @return string + * @since 31.0.0 + */ + public function getSignature(): string { + return $this->signature; + } + + /** + * @inheritDoc + * + * @param Signatory $signatory + * @return self + * @since 31.0.0 + */ + public function setSignatory(Signatory $signatory): self { + $this->signatory = $signatory; + return $this; + } + + /** + * @inheritDoc + * + * @return Signatory + * @throws SignatoryNotFoundException + * @since 31.0.0 + */ + public function getSignatory(): Signatory { + if ($this->signatory === null) { + throw new SignatoryNotFoundException(); + } + + return $this->signatory; + } + + /** + * @inheritDoc + * + * @return bool + * @since 31.0.0 + */ + public function hasSignatory(): bool { + return ($this->signatory !== null); + } + + public function jsonSerialize(): array { + return [ + 'body' => $this->body, + 'digest' => $this->getDigest(), + 'digestAlgorithm' => $this->getDigestAlgorithm()->value, + 'signingElements' => $this->signingElements, + 'signatureData' => $this->signatureData, + 'signature' => $this->signature, + 'signatory' => $this->signatory ?? false, + ]; + } +} |