Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add element registry #55

Merged
merged 4 commits into from
Sep 13, 2024
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
2 changes: 2 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ comment:
branches: null
github_checks:
annotations: false
ignore:
- 'src/XML/element.registry.php'
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,19 @@
"ext-pcre": "*",
"ext-spl": "*",

"simplesamlphp/assert": "^1.1",
"simplesamlphp/xml-common": "^1.15"
"simplesamlphp/assert": "^1.3",
"simplesamlphp/xml-common": "^1.18"
},
"require-dev": {
"simplesamlphp/simplesamlphp-test-framework": "^1.5"
"simplesamlphp/simplesamlphp-test-framework": "^1.7"
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"phpstan/extension-installer": true,
"simplesamlphp/composer-module-installer": true,
"phpstan/extension-installer": true
"simplesamlphp/composer-xmlprovider-installer": true
}
}
}
4 changes: 3 additions & 1 deletion src/XML/EncryptableElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ public function encrypt(EncryptionAlgorithmInterface $encryptor): EncryptedData

$keyInfo = new KeyInfo([$encryptedKey]);

$factory = new EncryptionAlgorithmFactory($this->getBlacklistedAlgorithms() ?? EncryptionAlgorithmFactory::DEFAULT_BLACKLIST);
$factory = new EncryptionAlgorithmFactory(
$this->getBlacklistedAlgorithms() ?? EncryptionAlgorithmFactory::DEFAULT_BLACKLIST,
);
$encryptor = $factory->getAlgorithm($this->blockCipherAlgId, $sessionKey);
$encryptor->setBackend($this->getEncryptionBackend());
}
Expand Down
4 changes: 3 additions & 1 deletion src/XML/EncryptedElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ protected function decryptData(EncryptionAlgorithmInterface $decryptor): string
$encryptedKey = $this->getEncryptedKey();
$decryptionKey = $encryptedKey->decrypt($decryptor);

$factory = new EncryptionAlgorithmFactory($this->getBlacklistedAlgorithms() ?? EncryptionAlgorithmFactory::DEFAULT_BLACKLIST);
$factory = new EncryptionAlgorithmFactory(
$this->getBlacklistedAlgorithms() ?? EncryptionAlgorithmFactory::DEFAULT_BLACKLIST,
);
$decryptor = $factory->getAlgorithm($encMethod->getAlgorithm(), new SymmetricKey($decryptionKey));
$decryptor->setBackend($this->getEncryptionBackend());
}
Expand Down
3 changes: 2 additions & 1 deletion src/XML/SignedElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ private function verifyInternal(SignatureAlgorithmInterface $verifier): SignedEl
if (
$verifier?->verify(
$c14nSignedInfo, // the canonicalized ds:SignedInfo element (plaintext)
base64_decode($this->getSignature()->getSignatureValue()->getRawContent(), true), // the actual signature
// the actual signature
base64_decode($this->getSignature()->getSignatureValue()->getRawContent(), true),
)
) {
/*
Expand Down
13 changes: 2 additions & 11 deletions src/XML/ds/DigestMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\ExtendableElementTrait;
Expand All @@ -29,7 +28,7 @@ final class DigestMethod extends AbstractDsElement
* Initialize a DigestMethod element.
*
* @param string $Algorithm
* @param \SimpleSAML\XML\Chunk[] $elements
* @param list<\SimpleSAML\XML\SerializableElementInterface> $elements
*/
public function __construct(
protected string $Algorithm,
Expand Down Expand Up @@ -73,15 +72,7 @@ public static function fromXML(DOMElement $xml): static
Assert::same($xml->namespaceURI, DigestMethod::NS, InvalidDOMElementException::class);

$Algorithm = DigestMethod::getAttribute($xml, 'Algorithm');

$elements = [];
foreach ($xml->childNodes as $elt) {
if (!($elt instanceof DOMElement)) {
continue;
}

$elements[] = new Chunk($elt);
}
$elements = self::getChildElementsFromXML($xml);

return new static($Algorithm, $elements);
}
Expand Down
18 changes: 1 addition & 17 deletions src/XML/ds/DsObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\XsNamespace as NS;
Expand Down Expand Up @@ -112,22 +111,7 @@ public static function fromXML(DOMElement $xml): static
$Id = DsObject::getOptionalAttribute($xml, 'Id', null);
$MimeType = DsObject::getOptionalAttribute($xml, 'MimeType', null);
$Encoding = DsObject::getOptionalAttribute($xml, 'Encoding', null);

$elements = [];
foreach ($xml->childNodes as $elt) {
if (!($elt instanceof DOMElement)) {
// @TODO: support mixed content
continue;
} elseif ($elt->namespaceURI === self::NS) {
$elements[] = match ($elt->localName) {
'SignatureProperties' => SignatureProperties::fromXML($elt),
'Manifest' => Manifest::fromXML($elt),
default => new Chunk($elt),
};
}

$elements[] = new Chunk($elt);
}
$elements = self::getChildElementsFromXML($xml);

return new static($Id, $MimeType, $Encoding, $elements);
}
Expand Down
105 changes: 44 additions & 61 deletions src/XML/ds/KeyInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\SerializableElementInterface;
use SimpleSAML\XML\XsNamespace as NS;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
use SimpleSAML\XMLSecurity\XML\dsig11\KeyInfoReference;
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedData;
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey;

/**
* Class representing a ds:KeyInfo element.
Expand All @@ -21,11 +20,16 @@
*/
final class KeyInfo extends AbstractDsElement
{
use ExtendableElementTrait;

/** @var \SimpleSAML\XML\XsNamespace */
public const XS_ANY_ELT_NAMESPACE = NS::OTHER;


/**
* Initialize a KeyInfo element.
*
* @param (
* \SimpleSAML\XML\SerializableElementInterface|
* \SimpleSAML\XMLSecurity\XML\ds\KeyName|
* \SimpleSAML\XMLSecurity\XML\ds\KeyValue|
* \SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod|
Expand All @@ -34,29 +38,26 @@ final class KeyInfo extends AbstractDsElement
* \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData|
* \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey
* )[] $info
* @param \SimpleSAML\XML\SerializableElementInterface[] $children
* @param string|null $Id
*/
public function __construct(
protected array $info,
array $children = [],
protected ?string $Id = null,
) {
Assert::notEmpty($info, 'ds:KeyInfo cannot be empty', InvalidArgumentException::class);
Assert::maxCount($info, C::UNBOUNDED_LIMIT);
Assert::allIsInstanceOfAny(
$info,
[
Chunk::class,
KeyName::class,
KeyValue::class,
RetrievalMethod::class,
X509Data::class,
EncryptedData::class,
EncryptedKey::class,
],
'KeyInfo can only contain instances of KeyName, X509Data, EncryptedKey or Chunk.',
$combi = array_merge($info, $children);

Assert::notEmpty($combi, 'ds:KeyInfo cannot be empty', InvalidArgumentException::class);
Assert::maxCount($combi, C::UNBOUNDED_LIMIT);
Assert::allIsInstanceOf(
$combi,
SerializableElementInterface::class,
InvalidArgumentException::class,
);
Assert::nullOrValidNCName($Id);

$this->setElements($children);
}


Expand All @@ -74,20 +75,11 @@ public function getId(): ?string
/**
* Collect the value of the info-property
*
* @return (
* \SimpleSAML\XML\SerializableElementInterface|
* \SimpleSAML\XMLSecurity\XML\ds\KeyName|
* \SimpleSAML\XMLSecurity\XML\ds\KeyValue|
* \SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod|
* \SimpleSAML\XMLSecurity\XML\ds\X509Data|
* \SimpleSAML\XMLSecurity\XML\dsig11\KeyInfoReference|
* \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData|
* \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey
* )[]
* @return list<\SimpleSAML\XML\SerializableElementInterface>
*/
public function getInfo(): array
{
return $this->info;
return array_merge($this->info, $this->getElements());
}


Expand All @@ -106,36 +98,27 @@ public static function fromXML(DOMElement $xml): static
Assert::same($xml->namespaceURI, KeyInfo::NS, InvalidDOMElementException::class);

$Id = self::getOptionalAttribute($xml, 'Id', null);
$info = [];

foreach ($xml->childNodes as $n) {
if (!($n instanceof DOMElement)) {
continue;
} elseif ($n->namespaceURI === C::NS_XDSIG) {
$info[] = match ($n->localName) {
'KeyName' => KeyName::fromXML($n),
'KeyValue' => KeyValue::fromXML($n),
'RetrievalMethod' => RetrievalMethod::fromXML($n),
'X509Data' => X509Data::fromXML($n),
default => new Chunk($n),
};
} elseif ($n->namespaceURI === C::NS_XDSIG11) {
$info[] = match ($n->localName) {
'KeyInfoReference' => KeyInfoReference::fromXML($n),
default => new Chunk($n),
};
} elseif ($n->namespaceURI === C::NS_XENC) {
$info[] = match ($n->localName) {
'EncryptedData' => EncryptedData::fromXML($n),
'EncryptedKey' => EncryptedKey::fromXML($n),
default => new Chunk($n),
};
} else {
$info[] = new Chunk($n);
}
}

return new static($info, $Id);
$keyName = KeyName::getChildrenOfClass($xml);
$keyValue = KeyValue::getChildrenOfClass($xml);
$retrievalMethod = RetrievalMethod::getChildrenOfClass($xml);
$x509Data = X509Data::getChildrenOfClass($xml);
//$pgpData = PGPData::getChildrenOfClass($xml);
//$spkiData = SPKIData::getChildrenOfClass($xml);
//$mgmtData = MgmtData::getChildrenOfClass($xml);

$info = array_merge(
$keyName,
$keyValue,
$retrievalMethod,
$x509Data,
//$pgpdata,
//$spkidata,
//$mgmtdata,
);

$children = self::getChildElementsFromXML($xml);
return new static($info, $children, $Id);
}


Expand All @@ -153,8 +136,8 @@ public function toXML(DOMElement $parent = null): DOMElement
$e->setAttribute('Id', $this->getId());
}

foreach ($this->getInfo() as $n) {
$n->toXML($e);
foreach ($this->getInfo() as $elt) {
$elt->toXML($e);
}

return $e;
Expand Down
10 changes: 1 addition & 9 deletions src/XML/ds/KeyValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\ElementInterface;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
Expand Down Expand Up @@ -83,14 +82,7 @@ public static function fromXML(DOMElement $xml): static
TooManyElementsException::class,
);

$elements = [];
foreach ($xml->childNodes as $element) {
if (!($element instanceof DOMElement) || $element->namespaceURI === KeyValue::NS) {
continue;
}

$elements[] = new Chunk($element);
}
$elements = self::getChildElementsFromXML($xml);
Assert::maxCount(
$elements,
1,
Expand Down
11 changes: 1 addition & 10 deletions src/XML/ds/SignatureProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
Expand Down Expand Up @@ -81,15 +80,7 @@ public static function fromXML(DOMElement $xml): static
$Target = self::getAttribute($xml, 'Target');
$Id = self::getOptionalAttribute($xml, 'Id', null);

$children = [];
foreach ($xml->childNodes as $child) {
if (!($child instanceof DOMElement)) {
continue;
}

$children[] = new Chunk($child);
}

$children = self::getChildElementsFromXML($xml);
Assert::minCount(
$children,
1,
Expand Down
Loading