Skip to content

Commit

Permalink
Start using PHP 8.1 features
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Dec 14, 2023
1 parent 03bbdce commit a69a370
Show file tree
Hide file tree
Showing 19 changed files with 142 additions and 90 deletions.
63 changes: 63 additions & 0 deletions src/C14N.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity;

/**
* Canonicalization algorithms
*/
enum C14N: string
{
case INCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
case INCLUSIVE_WITHOUT_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
case EXCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments';
case EXCLUSIVE_WITHOUT_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#';

/**
* @return bool
*/
public function withComments(): bool
{
return match ($this) {
C14N::INCLUSIVE_WITH_COMMENTS, C14N::EXCLUSIVE_WITH_COMMENTS => true,
default => false,
};
}


/**
* @return bool
*/
public function withoutComments(): bool
{
return match ($this) {
C14N::INCLUSIVE_WITHOUT_COMMENTS, C14N::EXCLUSIVE_WITHOUT_COMMENTS => true,
default => false,
};
}


/**
* @return bool
*/
public function exclusive(): bool
{
return match ($this) {
C14N::EXCLUSIVE_WITH_COMMENTS, C14N::EXCLUSIVE_WITHOUT_COMMENTS => true,
default => false,
};
}


/**
* @return bool
*/
public function inclusive(): bool
{
return match ($this) {
C14N::INCLUSIVE_WITH_COMMENTS, C14N::INCLUSIVE_WITHOUT_COMMENTS => true,
default => false,
};
}
}
9 changes: 1 addition & 8 deletions src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,6 @@ class Constants extends \SimpleSAML\XML\Constants
self::KEY_TRANSPORT_OAEP_MGF1P,
];

/**
* Canonicalization algorithms
*/
public const C14N_INCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
public const C14N_INCLUSIVE_WITHOUT_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
public const C14N_EXCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments';
public const C14N_EXCLUSIVE_WITHOUT_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#';

/**
* Signature algorithms
*/
Expand Down Expand Up @@ -147,4 +139,5 @@ class Constants extends \SimpleSAML\XML\Constants
public const XMLENC_EXI = 'http://www.w3.org/2009/xmlenc11#EXI';

public const XPATH_URI = 'http://www.w3.org/TR/1999/REC-xpath-19991116';
public const NS_EC = 'http://www.w3.org/2001/10/xml-exc-c14n#';
}
7 changes: 4 additions & 3 deletions src/TestUtils/SignedElementTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use DOMDocument;
use Exception;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
use SimpleSAML\XMLSecurity\Exception\NoSignatureFoundException;
Expand Down Expand Up @@ -95,7 +96,7 @@ public function testSignatures(): void
]);

$unsigned = self::$testedClass::fromXML(self::$xmlRepresentation->documentElement);
$unsigned->sign($signer, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS, $keyInfo);
$unsigned->sign($signer, C14N::EXCLUSIVE_WITHOUT_COMMENTS, $keyInfo);
$signed = self::$testedClass::fromXML($unsigned->toXML());
$this->assertEquals(
$algorithm,
Expand Down Expand Up @@ -128,7 +129,7 @@ public function testSignatures(): void
//
// sign without certificates
//
$unsigned->sign($signer, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS, null);
$unsigned->sign($signer, C14N::EXCLUSIVE_WITHOUT_COMMENTS, null);
$signed = self::$testedClass::fromXML($unsigned->toXML());

// verify signature
Expand Down Expand Up @@ -156,7 +157,7 @@ public function testSignatures(): void
$algorithm,
PEMCertificatesMock::getPrivateKey(PEMCertificatesMock::OTHER_PRIVATE_KEY),
);
$unsigned->sign($signer, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS, null);
$unsigned->sign($signer, C14N::EXCLUSIVE_WITHOUT_COMMENTS, null);
$signed = self::$testedClass::fromXML($unsigned->toXML());

// verify signature
Expand Down
21 changes: 8 additions & 13 deletions src/Utils/XML.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimpleSAML\XMLSecurity\Utils;

use DOMElement;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\XML\ds\Transforms;

Expand All @@ -22,7 +23,7 @@ class XML
* Canonicalize any given node.
*
* @param \DOMElement $element The DOM element that needs canonicalization.
* @param string $c14nMethod The identifier of the canonicalization algorithm to use.
* @param \SimpleSAML\XMLSecurity\C14N $c14nMethod The identifier of the canonicalization algorithm to use.
* See \SimpleSAML\XMLSecurity\Constants.
* @param array|null $xpaths An array of xpaths to filter the nodes by. Defaults to null (no filters).
* @param array|null $prefixes An array of namespace prefixes to filter the nodes by. Defaults to null (no filters).
Expand All @@ -31,18 +32,12 @@ class XML
*/
public static function canonicalizeData(
DOMElement $element,
string $c14nMethod,
C14N $c14nMethod,
array $xpaths = null,
array $prefixes = null,
): string {
$withComments = match ($c14nMethod) {
C::C14N_EXCLUSIVE_WITH_COMMENTS, C::C14N_INCLUSIVE_WITH_COMMENTS => true,
default => false,
};
$exclusive = match ($c14nMethod) {
C::C14N_EXCLUSIVE_WITH_COMMENTS, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS => true,
default => false,
};
$withComments = $c14nMethod->withComments();
$exclusive = $c14nMethod->exclusive();

if (
is_null($xpaths)
Expand Down Expand Up @@ -85,14 +80,14 @@ public static function processTransforms(
Transforms $transforms,
DOMElement $data,
): string {
$canonicalMethod = C::C14N_EXCLUSIVE_WITHOUT_COMMENTS;
$canonicalMethod = C14N::EXCLUSIVE_WITHOUT_COMMENTS;
$arXPath = null;
$prefixList = null;
foreach ($transforms->getTransform() as $transform) {
$canonicalMethod = $transform->getAlgorithm();
switch ($canonicalMethod) {
case C::C14N_EXCLUSIVE_WITHOUT_COMMENTS:
case C::C14N_EXCLUSIVE_WITH_COMMENTS:
case C14N::EXCLUSIVE_WITHOUT_COMMENTS:
case C14N::EXCLUSIVE_WITH_COMMENTS:
$inclusiveNamespaces = $transform->getInclusiveNamespaces();
if ($inclusiveNamespaces !== null) {
$prefixes = $inclusiveNamespaces->getPrefixes();
Expand Down
5 changes: 3 additions & 2 deletions src/XML/CanonicalizableElementInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimpleSAML\XMLSecurity\XML;

use SimpleSAML\XML\ElementInterface;
use SimpleSAML\XMLSecurity\C14N;

/**
* An interface for objects that can be canonicalized.
Expand All @@ -26,11 +27,11 @@ interface CanonicalizableElementInterface extends ElementInterface
* Note that if this object was created using fromXML(), it might be necessary to keep the original DOM
* representation of the object.
*
* @param string $method The canonicalization method to use.
* @param \SimpleSAML\XMLSecurity\C14N $method The canonicalization method to use.
* @param string[]|null $xpaths An array of XPaths to filter the nodes by. Defaults to null (no filters).
* @param string[]|null $prefixes An array of namespace prefixes to filter the nodes by. Defaults to null (no
* filters).
* @return string
*/
public function canonicalize(string $method, ?array $xpaths = null, ?array $prefixes = null): string;
public function canonicalize(C14N $method, ?array $xpaths = null, ?array $prefixes = null): string;
}
5 changes: 3 additions & 2 deletions src/XML/CanonicalizableElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimpleSAML\XMLSecurity\XML;

use DOMElement;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\Utils\XML;

/**
Expand Down Expand Up @@ -33,13 +34,13 @@ abstract protected function getOriginalXML(): DOMElement;
* Note that if this object was created using fromXML(), it might be necessary to keep the original DOM
* representation of the object.
*
* @param string $method The canonicalization method to use.
* @param \SimpleSAML\XMLSecurity\C14N $method The canonicalization method to use.
* @param string[]|null $xpaths An array of XPaths to filter the nodes by. Defaults to null (no filters).
* @param string[]|null $prefixes An array of namespace prefixes to filter the nodes by. Defaults to null (no
* filters).
* @return string
*/
public function canonicalize(string $method, ?array $xpaths = null, ?array $prefixes = null): string
public function canonicalize(C14N $method, ?array $xpaths = null, ?array $prefixes = null): string
{
return XML::canonicalizeData($this->getOriginalXML(), $method, $xpaths, $prefixes);
}
Expand Down
5 changes: 3 additions & 2 deletions src/XML/SignableElementInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimpleSAML\XMLSecurity\XML;

use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\XML\ds\KeyInfo;

/**
Expand All @@ -31,12 +32,12 @@ public function getId(): ?string;
*
* @param \SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface $signer The actual signer implementation
* to use.
* @param string $canonicalizationAlg The identifier of the canonicalization algorithm to use.
* @param \SimpleSAML\XMLSecurity\C14N $canonicalizationAlg The identifier of the canonicalization algorithm to use.
* @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo A KeyInfo object to add to the signature.
*/
public function sign(
SignatureAlgorithmInterface $signer,
string $canonicalizationAlg,
C14N $canonicalizationAlg,
?KeyInfo $keyInfo = null
): void;
}
20 changes: 8 additions & 12 deletions src/XML/SignableElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
use SimpleSAML\XMLSecurity\Exception\RuntimeException;
Expand Down Expand Up @@ -40,8 +41,8 @@ trait SignableElementTrait
/** @var \SimpleSAML\XMLSecurity\XML\ds\Signature|null */
protected ?Signature $signature = null;

/** @var string */
private string $c14nAlg = C::C14N_EXCLUSIVE_WITHOUT_COMMENTS;
/** @var \SimpleSAML\XMLSecurity\C14N */
private C14N $c14nAlg = C14N::EXCLUSIVE_WITHOUT_COMMENTS;

/** @var \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null */
private ?KeyInfo $keyInfo = null;
Expand All @@ -67,24 +68,19 @@ abstract public function getId(): ?string;
*
* @param \SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface $signer The actual signer implementation
* to use.
* @param string $canonicalizationAlg The identifier of the canonicalization algorithm to use.
* @param \SimpleSAML\XMLSecurity\C14N $canonicalizationAlg The identifier of the canonicalization algorithm to use.
* @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo A KeyInfo object to add to the signature.
*/
public function sign(
SignatureAlgorithmInterface $signer,
string $canonicalizationAlg = C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
C14N $canonicalizationAlg = C14N::EXCLUSIVE_WITHOUT_COMMENTS,
?KeyInfo $keyInfo = null
): void {
$this->signer = $signer;
$this->keyInfo = $keyInfo;
Assert::oneOf(
$canonicalizationAlg,
[
C::C14N_INCLUSIVE_WITH_COMMENTS,
C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
C::C14N_EXCLUSIVE_WITH_COMMENTS,
C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
],
C14N::cases(),
'Unsupported canonicalization algorithm: %s',
UnsupportedAlgorithmException::class,
);
Expand Down Expand Up @@ -118,10 +114,10 @@ private function getReference(
'Please give your object an identifier.',
RuntimeException::class,
);
if (in_array($this->c14nAlg, [C::C14N_INCLUSIVE_WITH_COMMENTS, C::C14N_EXCLUSIVE_WITH_COMMENTS])) {
if ($this->c14nAlg->withComments()) {
$uri = '#xpointer(/)';
}
} elseif (in_array($this->c14nAlg, [C::C14N_INCLUSIVE_WITH_COMMENTS, C::C14N_EXCLUSIVE_WITH_COMMENTS])) {
} elseif ($this->c14nAlg->withComments()) {
// regular reference, but must retain comments
$uri = '#xpointer(id(' . $id . '))';
} else { // regular reference, can ignore comments
Expand Down
6 changes: 3 additions & 3 deletions src/XML/SignedElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use SimpleSAML\XML\Exception\TooManyElementsException;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\CryptoEncoding\PEM;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
use SimpleSAML\XMLSecurity\Exception\NoSignatureFoundException;
Expand Down Expand Up @@ -87,8 +87,8 @@ private function validateReferenceUri(Reference $reference, DOMElement $xml): vo
in_array(
$this->signature->getSignedInfo()->getCanonicalizationMethod()->getAlgorithm(),
[
C::C14N_INCLUSIVE_WITH_COMMENTS,
C::C14N_EXCLUSIVE_WITH_COMMENTS,
C14N::INCLUSIVE_WITH_COMMENTS,
C14N::EXCLUSIVE_WITH_COMMENTS,
],
)
&& !$reference->isXPointer()
Expand Down
22 changes: 8 additions & 14 deletions src/XML/ds/CanonicalizationMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\C14N;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;

/**
Expand All @@ -21,20 +21,14 @@ final class CanonicalizationMethod extends AbstractDsElement
/**
* Initialize a CanonicalizationMethod element.
*
* @param string $Algorithm
* @param \SimpleSAML\XMLSecurity\C14N $Algorithm
*/
public function __construct(
protected string $Algorithm,
protected C14N $Algorithm,
) {
Assert::validURI($Algorithm, SchemaViolationException::class);
Assert::oneOf(
$Algorithm,
[
C::C14N_EXCLUSIVE_WITH_COMMENTS,
C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
C::C14N_INCLUSIVE_WITH_COMMENTS,
C::C14N_INCLUSIVE_WITHOUT_COMMENTS,
],
C14N::cases(),
'Invalid canonicalization method: %s',
InvalidArgumentException::class,
);
Expand All @@ -44,9 +38,9 @@ public function __construct(
/**
* Collect the value of the Algorithm-property
*
* @return string
* @return \SimpleSAML\XMLSecurity\C14N
*/
public function getAlgorithm(): string
public function getAlgorithm(): C14N
{
return $this->Algorithm;
}
Expand All @@ -66,7 +60,7 @@ public static function fromXML(DOMElement $xml): static
Assert::same($xml->localName, 'CanonicalizationMethod', InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, CanonicalizationMethod::NS, InvalidDOMElementException::class);

$Algorithm = CanonicalizationMethod::getAttribute($xml, 'Algorithm');
$Algorithm = C14N::from(self::getAttribute($xml, 'Algorithm'));

return new static($Algorithm);
}
Expand All @@ -81,7 +75,7 @@ public static function fromXML(DOMElement $xml): static
public function toXML(DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->setAttribute('Algorithm', $this->getAlgorithm());
$e->setAttribute('Algorithm', $this->getAlgorithm()->value);

return $e;
}
Expand Down
Loading

0 comments on commit a69a370

Please sign in to comment.