Skip to content

Commit

Permalink
Migrate to value types
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 18, 2025
1 parent feb95e1 commit 9e83fa1
Show file tree
Hide file tree
Showing 206 changed files with 2,857 additions and 2,323 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"ext-spl": "*",

"simplesamlphp/assert": "~1.8.0",
"simplesamlphp/xml-common": "~1.24.0"
"simplesamlphp/xml-common": "dev-feature/xsd-types"
},
"require-dev": {
"simplesamlphp/simplesamlphp-test-framework": "~1.8.0"
Expand Down
9 changes: 9 additions & 0 deletions src/Assert/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@
* SimpleSAML\XMLSecurity\Assert\Assert wrapper class
*
* @package simplesamlphp/xml-security
*
* @method static void validCryptoBinary(mixed $value, string $message = '', string $exception = '')
* @method static void validKeySize(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidCryptoBinary(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidKeySize(mixed $value, string $message = '', string $exception = '')
* @method static void allValidCryptoBinary(mixed $value, string $message = '', string $exception = '')
* @method static void allValidKeyValue(mixed $value, string $message = '', string $exception = '')
*/
class Assert extends BaseAssert
{
use CryptoBinaryTrait;
use KeySizeTrait;
}
26 changes: 26 additions & 0 deletions src/Assert/CryptoBinaryTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Assert;

use InvalidArgumentException;

/**
* @package simplesamlphp/xml-security
*/
trait CryptoBinaryTrait
{
/**
* @param string $value
* @param string $message
*/
protected static function validCryptoBinary(string $value, string $message = ''): void
{
parent::validBase64Binary(
$value,
$message ?: '%s is not a valid xs:cryptoBinary',
InvalidArgumentException::class,
);
}
}
36 changes: 36 additions & 0 deletions src/Assert/KeySizeTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Assert;

use InvalidArgumentException;

/**
* @package simplesamlphp/xml-security
*/
trait KeySizeTrait
{
/**
* The size in bits of the key to be derived from the shared secret as the UTF-8 string for the corresponding
* decimal integer with only digits in the string and no leading zeros.
*
* @var string
*/
private static string $keySize_regex = '/^([1-9]\d+)$/D';


/**
* @param string $value
* @param string $message
*/
protected static function validKeySize(string $value, string $message = ''): void
{
parent::regex(
$value,
self::$keySize_regex,
$message ?: '%s is not a valid xenc:keySizeType',
InvalidArgumentException::class,
);
}
}
80 changes: 76 additions & 4 deletions src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,52 @@
class Constants extends \SimpleSAML\XML\Constants
{
/**
* Digest algorithms
* Symmetric key wrap algorithms
*/
public const KEY_WRAP_3DES = 'http://www.w3.org/2001/04/xmlenc#kw-tripledes';
public const KEY_WRAP_AES128 = 'http://www.w3.org/2001/04/xmlenc#kw-aes128';
public const KEY_WRAP_AES192 = 'http://www.w3.org/2001/04/xmlenc#kw-aes192';
public const KEY_WRAP_AES256 = 'http://www.w3.org/2001/04/xmlenc#kw-aes256';

/** @var string[] */
public static array $KEY_WRAP_ALGORITHMS = [
self::KEY_WRAP_3DES,
self::KEY_WRAP_AES128,
self::KEY_WRAP_AES192,
self::KEY_WRAP_AES256,
];


/**
* Key derivation algorithms
*/
public const KEY_DERIVATION_CONCATKDF = 'http://www.w3.org/2009/xmlenc11#ConcatKDF';
public const KEY_DERIVATION_PBKDF2 = 'http://www.w3.org/2009/xmlenc11#pbkdf2';

/** @var string[] */
public static array $KEY_DERIVATION_ALGORITHMS = [
self::KEY_DERIVATION_CONCATKDF,
self::KEY_DERIVATION_PBKDF2,
];


/**
* Key agreement algorithms
*/
public const KEY_AGREEMENT_ECDH_ES = 'http://www.w3.org/2009/xmlenc11#ECDH-ES';
public const KEY_AGREEMENT_DH = 'http://www.w3.org/2001/04/xmlenc#dh';
public const KEY_AGREEMENT_DH_ES = 'http://www.w3.org/2009/xmlenc11#dh-es';

/** @var string[] */
public static array $KEY_AGREEMENT_ALGORITHMS = [
self::KEY_AGREEMENT_ECDH_ES,
self::KEY_AGREEMENT_DH,
self::KEY_AGREEMENT_DH_ES,
];


/**
* Message digest algorithms
*/
public const DIGEST_SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1';
public const DIGEST_SHA224 = 'http://www.w3.org/2001/04/xmldsig-more#sha224';
Expand All @@ -31,12 +76,14 @@ class Constants extends \SimpleSAML\XML\Constants
self::DIGEST_RIPEMD160 => 'ripemd160',
];


/**
* Padding schemas
*/
public const PADDING_PKCS1 = "PKCS1";
public const PADDING_PKCS1_OAEP = "OAEP";


/**
* Block encryption algorithms
*/
Expand Down Expand Up @@ -81,6 +128,7 @@ class Constants extends \SimpleSAML\XML\Constants
self::BLOCK_ENC_AES256_GCM => 32,
];


/**
* Key transport algorithms
*/
Expand All @@ -95,13 +143,27 @@ 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#';
public const C14N11_INCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/2006/12/xml-c14n11';
public const C14N11_INCLUSIVE_WITHOUT_COMMENTS = 'http://www.w3.org/2006/12/xml-c14n11#WithComments';

/** @var string[] */
public static array $CANONICALIZATION_ALGORITHMS = [
self::C14N_INCLUSIVE_WITH_COMMENTS,
self::C14N_INCLUSIVE_WITHOUT_COMMENTS,
self::C14N_EXCLUSIVE_WITH_COMMENTS,
self::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
self::C14N11_INCLUSIVE_WITH_COMMENTS,
self::C14N11_INCLUSIVE_WITHOUT_COMMENTS,
];


/**
* Signature algorithms
Expand Down Expand Up @@ -139,6 +201,19 @@ class Constants extends \SimpleSAML\XML\Constants
self::SIG_HMAC_RIPEMD160 => self::DIGEST_RIPEMD160,
];


/**
* Encoding algorithms
*/
public const ENCODING_BASE64 = 'http://www.w3.org/2000/09/xmldsig#base64';


/**
* Transforms algorithms
*/
public const TRANSFORMS_BASE64 = 'http://www.w3.org/2000/09/xmldsig#base64';


/**
* XML & XPath namespaces and identifiers
*/
Expand All @@ -153,7 +228,4 @@ class Constants extends \SimpleSAML\XML\Constants
public const XMLENC_ELEMENT = 'http://www.w3.org/2001/04/xmlenc#Element';
public const XMLENC_ENCRYPTEDKEY = 'http://www.w3.org/2001/04/xmlenc#EncryptedKey';
public const XMLENC_EXI = 'http://www.w3.org/2009/xmlenc11#EXI';

// The namespace for the Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES) algorithm
public const XMLENC11_ECDH_ES = 'http://www.w3.org/2009/xmlenc11#ECDH-ES';
}
29 changes: 29 additions & 0 deletions src/Exception/ProtocolViolationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Exception;

/**
* This exception may be raised when a violation of the xmldsig specification is detected
*
* @package simplesamlphp/xml-security
*/
class ProtocolViolationException extends RuntimeException
{
/**
* @param string|null $message
*/
public function __construct(?string $message = null)
{
if ($message === null) {
if (defined('static::DEFAULT_MESSAGE')) {
$message = static::DEFAULT_MESSAGE;
} else {
$message = 'A violation of the XML Signature Syntax and Processing specification occurred.';
}
}

parent::__construct($message);
}
}
23 changes: 16 additions & 7 deletions src/TestUtils/SignedElementTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimpleSAML\XMLSecurity\TestUtils;

use DOMDocument;
use SimpleSAML\XML\Type\Base64BinaryValue;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
Expand Down Expand Up @@ -81,12 +82,20 @@ public function testSignatures(): void
);

$keyInfo = new KeyInfo([
new X509Data([new X509Certificate(
PEMCertificatesMock::getPlainPublicKeyContents(PEMCertificatesMock::PUBLIC_KEY),
)]),
new X509Data([new X509Certificate(
PEMCertificatesMock::getPlainPublicKeyContents(PEMCertificatesMock::OTHER_PUBLIC_KEY),
)]),
new X509Data([
new X509Certificate(
Base64BinaryValue::fromString(
PEMCertificatesMock::getPlainPublicKeyContents(PEMCertificatesMock::PUBLIC_KEY)
),
),
]),
new X509Data([
new X509Certificate(
Base64BinaryValue::fromString(
PEMCertificatesMock::getPlainPublicKeyContents(PEMCertificatesMock::OTHER_PUBLIC_KEY),
),
),
]),
]);

$unsigned = self::$testedClass::fromXML(self::$xmlRepresentation->documentElement);
Expand All @@ -99,7 +108,7 @@ public function testSignatures(): void

// verify signature
$verifier = (new SignatureAlgorithmFactory([]))->getAlgorithm(
$signed->getSignature()->getSignedInfo()->getSignatureMethod()->getAlgorithm(),
$signed->getSignature()->getSignedInfo()->getSignatureMethod()->getAlgorithm()->getValue(),
PEMCertificatesMock::getPublicKey(PEMCertificatesMock::PUBLIC_KEY),
);

Expand Down
28 changes: 28 additions & 0 deletions src/Type/CryptoBinaryValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Type;

use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Type\Base64BinaryValue;
use SimpleSAML\XMLSecurity\Assert\Assert;

/**
* @package simplesaml/xml-security
*/
class CryptoBinaryValue extends Base64BinaryValue
{
/**
* Validate the value.
*
* @param string $value
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
* @return void
*/
protected function validateValue(string $value): void
{
// Note: value must already be sanitized before validating
Assert::validCryptoBinary($this->sanitizeValue($value), SchemaViolationException::class);
}
}
28 changes: 28 additions & 0 deletions src/Type/KeySizeValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Type;

use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Type\IntegerValue;
use SimpleSAML\XMLSecurity\Assert\Assert;

/**
* @package simplesaml/xml-security
*/
class KeySizeValue extends IntegerValue
{
/**
* Validate the value.
*
* @param string $value
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
* @return void
*/
protected function validateValue(string $value): void
{
// Note: value must already be sanitized before validating
Assert::validKeySize($this->sanitizeValue($value), SchemaViolationException::class);
}
}
2 changes: 1 addition & 1 deletion src/Utils/XML.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static function processTransforms(
$arXPath = null;
$prefixList = null;
foreach ($transforms->getTransform() as $transform) {
$canonicalMethod = $transform->getAlgorithm();
$canonicalMethod = $transform->getAlgorithm()->getValue();
switch ($canonicalMethod) {
case C::C14N_EXCLUSIVE_WITHOUT_COMMENTS:
case C::C14N_EXCLUSIVE_WITH_COMMENTS:
Expand Down
Loading

0 comments on commit 9e83fa1

Please sign in to comment.