Skip to content

Commit

Permalink
Refactor to xsd types
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 23, 2025
1 parent 5af7263 commit b240ede
Show file tree
Hide file tree
Showing 85 changed files with 759 additions and 969 deletions.
36 changes: 20 additions & 16 deletions src/SAML11/Compat/AbstractContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Psr\Log\LoggerInterface;
use SimpleSAML\SAML11\Assert\Assert;
use SimpleSAML\SAML11\XML\ExtensionPointInterface;
use SimpleSAML\XML\AbstractElement;
use SimpleSAML\XML\{AbstractElement, ElementInterface};
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Type\QNameValue;
use SimpleSAML\XMLSecurity\Alg\Encryption\EncryptionAlgorithmFactory;
use SimpleSAML\XMLSecurity\Alg\KeyTransport\KeyTransportAlgorithmFactory;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
Expand Down Expand Up @@ -71,20 +72,17 @@ public function registerExtensionHandler(string $class): void
* Such classes must have been registered previously by calling registerExtensionHandler(), and they must
* extend \SimpleSAML\XML\AbstractElement.
*
* @param string|null $namespace The namespace URI for the given element.
* @param string $element The local name of the element.
* @param \SimpleSAML\XML\Typr\QNameValue|null $qName The qualified name of the element.
*
* @return string|null The fully-qualified name of a class extending \SimpleSAML\XML\AbstractElement and
* implementing support for the given element, or null if no such class has been registered before.
* @psalm-return class-string|null
*/
public function getElementHandler(?string $namespace, string $element): ?string
public function getElementHandler(QNameValue $qName): ?string
{
Assert::nullOrValidURI($namespace, SchemaViolationException::class);
Assert::validNCName($element, SchemaViolationException::class);

$key = ($namespace === null) ? $element : implode(':', [$namespace, $element]);
$key = $qName->getRawValue();
if (array_key_exists($key, $this->registry) === true) {
Assert::implementsInterface($this->registry[$key], ElementInterface::class);
return $this->registry[$key];
}

Expand All @@ -98,21 +96,27 @@ public function getElementHandler(?string $namespace, string $element): ?string
* Such classes must have been registered previously by calling registerExtensionHandler(), and they must
* implement \SimpleSAML\SAML11\XML\saml\ExtensionPointInterface.
*
* @param string $type The type of the identifier (xsi:type of a BaseID element).
*
* @param \SimpleSAML\XML\Type\QNameValue $qName The qualified name of the extension.
* @return string|null The fully-qualified name of a class implementing
* \SimpleSAML\SAML11\XML\saml\ExtensionPointInterface or null if no such class has been registered before.
* @psalm-return class-string|null
*/
public function getExtensionHandler(string $type): ?string
public function getExtensionHandler(QNameValue $qName): ?string
{
Assert::notEmpty($type, 'Cannot search for identifier handlers with an empty type.');
$type = implode(':', [self::XSI_TYPE_PREFIX, $type]);
if (!array_key_exists($type, $this->registry)) {
$prefix = $qName->getNamespacePrefix()->getValue();
$namespaceURI = $qName->getNamespaceURI()->getValue();

if ($namespaceURI !== null) {
$localName = $qName->getLocalName()->getValue();;
$key = $qName->getRawValue();
if (array_key_exists($key, $this->registr) === true) {
Assert::implementsInterface($this->registry[$key], ExtensionPointInterface::class);
return $this->registry[$key];
}
return null;
}
Assert::implementsInterface($this->registry[$type], ExtensionPointInterface::class);
return $this->registry[$type];

return null;
}


Expand Down
14 changes: 14 additions & 0 deletions src/SAML11/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,18 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants
* Top-level status code.
*/
public const STATUS_VERSION_MISMATCH = 'samlp:VersionMismatch';

/** @var string[] */
public static array $STATUS_CODES = [
self::STATUS_REQUEST_DENIED,
self::STATUS_REQUEST_VERSION_DEPRECATED,
self::STATUS_REQUEST_VERSION_TOO_HIGH,
self::STATUS_REQUEST_VERSION_TOO_LOW,
self::STATUS_REQUESTER,
self::STATUS_RESOURCE_NOT_RECOGNIZED,
self::STATUS_RESPONDER,
self::STATUS_SUCCESS,
self::STATUS_TOO_MANY_RESPONSES,
self::STATUS_VERSION_MISMATCH,
];
}
4 changes: 4 additions & 0 deletions src/SAML11/Type/DateTimeValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
*/
class DateTimeValue extends BaseDateTimeValue
{
// Lowercase p as opposed to the base-class to covert the timestamp to UTC as demanded by the SAML specifications
public const string DATETIME_FORMAT = 'Y-m-d\\TH:i:sp';


/**
* Validate the value.
*
Expand Down
10 changes: 6 additions & 4 deletions src/SAML11/XML/ExtensionPointInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace SimpleSAML\SAML11\XML;

use SimpleSAML\XML\Type\{AnyURIValue, NCNameValue, QNameValue};

/**
* Interface for several extension points objects.
*
Expand All @@ -16,29 +18,29 @@ interface ExtensionPointInterface
*
* @return string
*/
public static function getXsiTypeName(): string;
public static function getXsiTypeName(): NCNameValue;


/**
* Get the namespace for the element's xsi:type.
*
* @return string
*/
public static function getXsiTypeNamespaceURI(): string;
public static function getXsiTypeNamespaceURI(): AnyURIValue;


/**
* Get the namespace-prefix for the element's xsi:type.
*
* @return string
*/
public static function getXsiTypePrefix(): string;
public static function getXsiTypePrefix(): NCNameValue;


/**
* Return the xsi:type value corresponding this element.
*
* @return string
*/
public function getXsiType(): string;
public function getXsiType(): QNameValue;
}
26 changes: 12 additions & 14 deletions src/SAML11/XML/ExtensionPointTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use RuntimeException;
use SimpleSAML\SAML11\Assert\Assert;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Type\{AnyURIValue, NCNameValue, QNameValue};

/**
* Trait for several extension points objects.
Expand All @@ -16,9 +17,9 @@
trait ExtensionPointTrait
{
/**
* @inheritDoc
* @return \SimpleSAML\XML\Type\QNameValue
*/
public function getXsiType(): string
public function getXsiType(): QNameValue
{
return $this->type;
}
Expand All @@ -27,9 +28,9 @@ public function getXsiType(): string
/**
* Get the local name for the element's xsi:type.
*
* @return string
* @return \SimpleSAML\XML\Type\NCNameValue
*/
public static function getXsiTypeName(): string
public static function getXsiTypeName(): NCNameValue
{
Assert::true(
defined('static::XSI_TYPE_NAME'),
Expand All @@ -38,17 +39,16 @@ public static function getXsiTypeName(): string
RuntimeException::class,
);

Assert::validNCName(static::XSI_TYPE_NAME, SchemaViolationException::class);
return static::XSI_TYPE_NAME;
return NCNameValue::fromString(static::XSI_TYPE_NAME);
}


/**
* Get the namespace for the element's xsi:type.
*
* @return string
* @return \SimpleSAML\XML\Type\AnyURIValue
*/
public static function getXsiTypeNamespaceURI(): string
public static function getXsiTypeNamespaceURI(): AnyURIValue
{
Assert::true(
defined('static::XSI_TYPE_NAMESPACE'),
Expand All @@ -57,17 +57,16 @@ public static function getXsiTypeNamespaceURI(): string
RuntimeException::class,
);

Assert::validURI(static::XSI_TYPE_NAMESPACE, SchemaViolationException::class);
return static::XSI_TYPE_NAMESPACE;
return AnyURIValue::fromString(static::XSI_TYPE_NAMESPACE);
}


/**
* Get the namespace-prefix for the element's xsi:type.
*
* @return string
* @return \SimpleSAML\XML\Type\NCNameValue
*/
public static function getXsiTypePrefix(): string
public static function getXsiTypePrefix(): NCNameValue
{
Assert::true(
defined('static::XSI_TYPE_PREFIX'),
Expand All @@ -78,7 +77,6 @@ public static function getXsiTypePrefix(): string
RuntimeException::class,
);

Assert::validNCName(static::XSI_TYPE_PREFIX, SchemaViolationException::class);
return static::XSI_TYPE_PREFIX;
return NCNameValue::fromString(static::XSI_TYPE_PREFIX);
}
}
46 changes: 31 additions & 15 deletions src/SAML11/XML/SignableElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML11\Compat\ContainerSingleton;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Type\{AnyURIValue, Base64BinaryValue};
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\RuntimeException;
use SimpleSAML\XMLSecurity\Exception\UnsupportedAlgorithmException;
use SimpleSAML\XMLSecurity\Exception\{RuntimeException, UnsupportedAlgorithmException};
use SimpleSAML\XMLSecurity\Utils\XML;
use SimpleSAML\XMLSecurity\XML\ds\CanonicalizationMethod;
use SimpleSAML\XMLSecurity\XML\ds\KeyInfo;
use SimpleSAML\XMLSecurity\XML\ds\Signature;
use SimpleSAML\XMLSecurity\XML\ds\SignatureMethod;
use SimpleSAML\XMLSecurity\XML\ds\SignatureValue;
use SimpleSAML\XMLSecurity\XML\ds\SignedInfo;
use SimpleSAML\XMLSecurity\XML\ds\Transform;
use SimpleSAML\XMLSecurity\XML\ds\Transforms;
use SimpleSAML\XMLSecurity\XML\ds\{
CanonicalizationMethod,
KeyInfo,
Signature,
SignatureMethod,
SignatureValue,
SignedInfo,
Transform,
Transforms,
};
use SimpleSAML\XMLSecurity\XML\SignableElementTrait as BaseSignableElementTrait;

use function base64_encode;
Expand Down Expand Up @@ -105,22 +107,36 @@ protected function doSign(DOMElement $xml): DOMElement
* 5.4.1: SAML assertions and protocols MUST use enveloped signatures when
* signing assertions and protocol messages
*/
new Transform(C::XMLDSIG_ENVELOPED),
new Transform($this->c14nAlg),
new Transform(
AnyURIValue::fromString(C::XMLDSIG_ENVELOPED),
),
new Transform(
AnyURIValue::fromString($this->c14nAlg),
),
]);

$canonicalDocument = XML::processTransforms($transforms, $xml);

$signedInfo = new SignedInfo(
new CanonicalizationMethod($this->c14nAlg),
new SignatureMethod($algorithm),
new CanonicalizationMethod(
AnyURIValue::fromString($this->c14nAlg),
),
new SignatureMethod(
AnyURIValue::fromString($algorithm),
),
[$this->getReference($digest, $transforms, $xml, $canonicalDocument)],
);

$signingData = $signedInfo->canonicalize($this->c14nAlg);
$signedData = base64_encode($this->signer->sign($signingData));

$this->signature = new Signature($signedInfo, new SignatureValue($signedData), $this->keyInfo);
$this->signature = new Signature(
$signedInfo,
new SignatureValue(
Base64BinaryValue::fromString($signedData),
$this->keyInfo,
),
);
return DOMDocumentFactory::fromString($canonicalDocument)->documentElement;
}

Expand Down
3 changes: 1 addition & 2 deletions src/SAML11/XML/SignedElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ protected function setSignature(Signature $signature): void

$reference = array_pop($references);
Assert::notNull($reference->getURI(), "URI attribute not found.", ReferenceValidationFailedException::class);
Assert::validURI($reference->getURI(), ReferenceValidationFailedException::class);
Assert::startsWith(
$reference->getURI(),
$reference->getURI()->getValue(),
'#',
"Reference must contain a same-document reference to the ID-attribute of the root element.",
ReferenceValidationFailedException::class,
Expand Down
39 changes: 0 additions & 39 deletions src/SAML11/XML/StringElementTrait.php

This file was deleted.

43 changes: 0 additions & 43 deletions src/SAML11/XML/URIElementTrait.php

This file was deleted.

Loading

0 comments on commit b240ede

Please sign in to comment.