0
0
Fork 0
mirror of https://github.com/nextcloud/server.git synced 2025-02-24 17:06:50 +00:00
nextcloud_server/lib/private/Security/Signature/Model/SignedRequest.php
Maxence Lange 15b72281df fix(signatory): details on interfaces
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
2024-12-04 09:30:55 -01:00

216 lines
4.2 KiB
PHP

<?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,
];
}
}