aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php')
-rw-r--r--vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php94
1 files changed, 74 insertions, 20 deletions
diff --git a/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php b/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php
index 69b47c65a..31c481f22 100644
--- a/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php
+++ b/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php
@@ -2,6 +2,7 @@
namespace HttpSignature;
+use Bakame\Http\StructuredFields\Dictionary;
use Bakame\Http\StructuredFields\InnerList;
use Bakame\Http\StructuredFields\Item;
use Bakame\Http\StructuredFields\OuterList;
@@ -9,7 +10,7 @@ use Bakame\Http\StructuredFields\Parameters;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
-use Bakame\Http\StructuredFields\Dictionary;
+use phpseclib\Crypt\RSA;
class HttpMessageSigner
{
@@ -45,6 +46,13 @@ class HttpMessageSigner
/* PSR-7 interface to signing function */
+ /**
+ * @param string $coveredFields
+ * @param MessageInterface $interface
+ * @param RequestInterface|null $originalRequest
+ * @return MessageInterface
+ * @throws UnProcessableSignatureException
+ */
public function signRequest(string $coveredFields, MessageInterface $interface, RequestInterface $originalRequest = null): MessageInterface
{
@@ -66,6 +74,13 @@ class HttpMessageSigner
}
/* PSR-7 verify interface and also check body digest if included */
+ /**
+ * @param MessageInterface $interface
+ * @param RequestInterface|null $originalRequest
+ * @return bool
+ *
+ * @throws UnProcessableSignatureException
+ */
public function verifyRequest(MessageInterface $interface, RequestInterface $originalRequest = null): bool
{
@@ -263,21 +278,6 @@ class HttpMessageSigner
}
$sigDict = $this->parseStructuredDict($headers['signature']);
- if ($sigDict->isNotEmpty()) {
- $indices = $sigDict->indices();
- foreach ($indices as $index) {
- [$dictName, $members] = $sigDict->getByIndex($index);
- if ($members instanceof Item) {
- $signatures[$dictName] = $members->value();
- }
- if ($members instanceof InnerList) {
- $innerIndices = $members->indices();
- foreach ($innerIndices as $innerIndex) {
- $signatures[$dictName][] = $members->getByIndex($innerIndex);
- }
- }
- }
- }
foreach ($signatureComponents as $dictName => $dictComponents) {
$namedSignatureComponents = $signatureComponents[$dictName];
@@ -289,7 +289,7 @@ class HttpMessageSigner
}
$decodedSig = base64_decode(trim($sigDict[$dictName]->__toString(), ':'));
- return $this->verifySignature($signatureBase, $decodedSig, $params['alg'] ?? $this->algorithm);
+ return $this->verifySignature($signatureBase, $decodedSig, $parameters['alg'] ?? $this->algorithm);
}
return false;
}
@@ -364,12 +364,17 @@ class HttpMessageSigner
private function getFieldValue($fieldName, MessageInterface $interface, $headers, $parameters ): array
{
+ // The $interface has no single method to extract this, so build it from
+ // the avilable components.
+ $targetUri = $interface->getUri()->getScheme() . '://' . $interface->getUri()->getAuthority()
+ . $interface->getUri()->getPath() . $interface->getUri()->getQuery();
+
$value = match ($fieldName) {
'@signature-params' => ['', ''],
'@method' => ['"@method"', strtoupper($interface->getMethod())],
'@authority' => ['"@authority"', $interface->getUri()->getAuthority()],
'@scheme' => ['"@scheme"', strtolower($interface->getUri()->getScheme())],
- '@target-uri' => ['"target-uri"', $interface->getUri()->__toString()],
+ '@target-uri' => ['"@target-uri"', $targetUri],
'@request-target' => ['"@request-target"', $interface->getRequestTarget()],
'@path' => ['"@path"', $interface->getUri()->getPath()],
'@query' => ['"@query"', $interface->getUri()->getQuery()],
@@ -486,7 +491,10 @@ class HttpMessageSigner
private function createSignature(string $data): string
{
return match ($this->algorithm) {
+ 'rsa-v1_5-sha256' => $this->rsaSign($data),
+ 'rsa-v1_5-sha512' => $this->rsa512Sign($data),
'rsa-sha256' => $this->rsaSign($data),
+ 'rsa-pss-sha512' => $this->pssSign($data),
'ed25519' => $this->ed25519Sign($data),
'hmac-sha256' => base64_encode(hash_hmac('sha256', $data, $this->privateKey, true)),
default => throw new UnProcessableSignatureException("Unsupported algorithm: $this->algorithm")
@@ -496,8 +504,13 @@ class HttpMessageSigner
private function verifySignature(string $data, string $signature, string $alg): bool
{
return match ($alg) {
- 'rsa-sha256' => openssl_verify($data, $signature, $this->publicKey,
- OPENSSL_ALGO_SHA256) === 1,
+ 'rsa-v1_5-sha256' => openssl_verify($data, $signature, $this->publicKey,
+ OPENSSL_ALGO_SHA256) === 1,
+ 'rsa-v1_5-sha512' => openssl_verify($data, $signature, $this->publicKey,
+ OPENSSL_ALGO_SHA512) === 1,
+ 'rsa-sha256' => openssl_verify($data, $signature, $this->publicKey,
+ OPENSSL_ALGO_SHA256) === 1,
+ 'rsa-pss-sha512' => $this->pssVerify($data, $signature),
'ed25519' => openssl_verify($data, $signature, $this->publicKey, "Ed25519") === 1,
'hmac-sha256' => hash_equals(
base64_encode(hash_hmac('sha256', $data, $this->privateKey, true)),
@@ -516,6 +529,30 @@ class HttpMessageSigner
}
return base64_encode($signature);
}
+ private function rsa512Sign(string $data): string
+ {
+ if (!openssl_sign($data, $signature, $this->privateKey, OPENSSL_ALGO_SHA512)) {
+ throw new UnProcessableSignatureException("RSA signing failed");
+ }
+ return base64_encode($signature);
+ }
+
+ private function pssSign(string $data): string
+ {
+ $rsa = new RSA();
+ if ($rsa->loadKey($this->privateKey) !== true) {
+ throw new UnprocessableSignatureException("PSS loadkey failure");
+ };
+ $rsa->setHash('sha512');
+ $rsa->setMGFHash('sha512');
+ $rsa->setSignatureMode(RSA::SIGNATURE_PSS);
+ try {
+ $signatureBytes = $rsa->sign($data);
+ } catch (\Exception $exception) {
+ throw new UnprocessableSignatureException($exception->getMessage());
+ }
+ return base64_encode($signatureBytes);
+ }
private function ed25519Sign(string $data): string
{
@@ -525,6 +562,23 @@ class HttpMessageSigner
return base64_encode($signature);
}
+ private function pssVerify(string $data, $signature): bool
+ {
+ $rsa = new RSA();
+ if (!$rsa->loadKey($this->publicKey)) {
+ throw new UnprocessableSignatureException("PSS loadkey failure");
+ };
+ $rsa->setHash('sha512');
+ $rsa->setMGFHash('sha512');
+ $rsa->setSignatureMode(RSA::SIGNATURE_PSS);
+ try {
+ $verified = $rsa->verify($data, $signature);
+ } catch (\Exception $exception) {
+ $verified = false;
+ }
+ return $verified;
+ }
+
/* parse a structed dict */
private function parseStructuredDict(string $headerValue)