Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/Features/VerifyTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
{
if (!in_array($hashFunc, $this->getSupportedHashFunctions(), true)) {
throw new ClientException(
"Unsupported hash function: {$hashFunc}. " .

Check warning on line 45 in src/Features/VerifyTrait.php

View workflow job for this annotation

GitHub Actions / Infection on PHP 8.4

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ if (!in_array($hashFunc, $this->getSupportedHashFunctions(), true)) { throw new ClientException( "Unsupported hash function: {$hashFunc}. " . - "Supported: " . implode(', ', $this->getSupportedHashFunctions()) + "Supported: " ); } }

Check warning on line 45 in src/Features/VerifyTrait.php

View workflow job for this annotation

GitHub Actions / Infection on PHP 8.4

Escaped Mutant for Mutator "Concat": @@ @@ { if (!in_array($hashFunc, $this->getSupportedHashFunctions(), true)) { throw new ClientException( - "Unsupported hash function: {$hashFunc}. " . - "Supported: " . implode(', ', $this->getSupportedHashFunctions()) + "Unsupported hash function: {$hashFunc}. " . implode(', ', $this->getSupportedHashFunctions()) . "Supported: " ); } }

Check warning on line 45 in src/Features/VerifyTrait.php

View workflow job for this annotation

GitHub Actions / Infection on PHP 8.4

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ { if (!in_array($hashFunc, $this->getSupportedHashFunctions(), true)) { throw new ClientException( - "Unsupported hash function: {$hashFunc}. " . - "Supported: " . implode(', ', $this->getSupportedHashFunctions()) + "Unsupported hash function: {$hashFunc}. " . implode(', ', $this->getSupportedHashFunctions()) ); } }

Check warning on line 45 in src/Features/VerifyTrait.php

View workflow job for this annotation

GitHub Actions / Infection on PHP 8.4

Escaped Mutant for Mutator "Concat": @@ @@ { if (!in_array($hashFunc, $this->getSupportedHashFunctions(), true)) { throw new ClientException( - "Unsupported hash function: {$hashFunc}. " . - "Supported: " . implode(', ', $this->getSupportedHashFunctions()) + "Supported: " . "Unsupported hash function: {$hashFunc}. " . implode(', ', $this->getSupportedHashFunctions()) ); } }
"Supported: " . implode(', ', $this->getSupportedHashFunctions())
);
}
Expand All @@ -60,7 +60,7 @@
int $treeSize
): bool {
$this->assertValidHashFunction($hashFunction);
$rootBytes = $this->decodeMerkleRoot($merkleRoot);
$rootBytes = $this->decodeMerkleRoot($merkleRoot, $hashFunction);

// Verify manually following RFC 9162 §2.1.3 since Tree::verifyInclusionProof
// requires the full tree which we don't have on the client side.
Expand Down Expand Up @@ -386,8 +386,9 @@
* Decode a Merkle root from its prefixed format.
*
* @throws ClientException If the format is invalid
* Supported $hashFunction 'sha256', 'sha384', 'sha512', 'blake2b'
*/
protected function decodeMerkleRoot(string $merkleRoot): string
protected function decodeMerkleRoot(string $merkleRoot, string $hashFunction): string
{
$prefix = 'pkd-mr-v1:';
if (!str_starts_with($merkleRoot, $prefix)) {
Expand All @@ -397,8 +398,16 @@
$encoded = substr($merkleRoot, strlen($prefix));
$decoded = Base64UrlSafe::decodeNoPadding($encoded);

if (strlen($decoded) < 32) {
throw new ClientException('Invalid Merkle root format: expected 32+ bytes');
$expectedByteLen = match ($hashFunction) {
'sha256' => 32,
'sha384' => 48,
'sha512' => 64,
'blake2b' => 32, // variable-length 8 to 512 bits (1 to 64 bytes) but 32 minimum for safety.
default => 32, // Fallback to 32 bytes as a minimum but $hashFunc should never be null.
};

if (strlen($decoded) < $expectedByteLen) {
throw new ClientException("decodeMerkleRoot: Invalid Merkle root format. Expected a minimum of {$expectedByteLen} bytes for {$hashFunction} - Got {$decoded}");
}

return $decoded;
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/Features/VerifyTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ public function testDecodeMerkleRootThrowsOnInvalidLength(): void
$invalidRoot = 'pkd-mr-v1:' . Base64UrlSafe::encodeUnpadded(str_repeat("\x00", 16));

$this->expectException(ClientException::class);
$this->expectExceptionMessage('Invalid Merkle root format: expected 32+ bytes');
$this->expectExceptionMessage('decodeMerkleRoot: Invalid Merkle root format. Expected a minimum of 32 bytes for sha256');

$client->verifyInclusionProof('sha256', $invalidRoot, 'leaf1', $proof, $tree->getSize());
}
Expand Down
Loading