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

Migrate to value types #60

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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: 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
21 changes: 21 additions & 0 deletions src/Assert/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,28 @@
* SimpleSAML\XMLSecurity\Assert\Assert wrapper class
*
* @package simplesamlphp/xml-security
*
* @method static void validCryptoBinary(mixed $value, string $message = '', string $exception = '')
* @method static void validDigestValue(mixed $value, string $message = '', string $exception = '')
* @method static void validECPoint(mixed $value, string $message = '', string $exception = '')
* @method static void validHMACOutputLength(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 nullOrValidDigestValue(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidECPoint(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidHMACOutputLength(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 allValidDigestValue(mixed $value, string $message = '', string $exception = '')
* @method static void allValidECPoint(mixed $value, string $message = '', string $exception = '')
* @method static void allValidHMACOutputLength(mixed $value, string $message = '', string $exception = '')
* @method static void allValidKeyValue(mixed $value, string $message = '', string $exception = '')
*/
class Assert extends BaseAssert
{
use CryptoBinaryTrait;
use DigestValueTrait;
use ECPointTrait;
use HMACOutputLengthTrait;
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,
);
}
}
26 changes: 26 additions & 0 deletions src/Assert/DigestValueTrait.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 DigestValueTrait
{
/**
* @param string $value
* @param string $message
*/
protected static function validDigestValue(string $value, string $message = ''): void
{
parent::validBase64Binary(
$value,
$message ?: '%s is not a valid xs:DigestValue',
InvalidArgumentException::class,
);
}
}
26 changes: 26 additions & 0 deletions src/Assert/ECPointTrait.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 ECPointTrait
{
/**
* @param string $value
* @param string $message
*/
protected static function validECPoint(string $value, string $message = ''): void
{
Assert::validCryptoBinary(
$value,
$message ?: '%s is not a valid dsig11:ECPointType',
InvalidArgumentException::class,
);
}
}
53 changes: 53 additions & 0 deletions src/Assert/HMACOutputLengthTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Assert;

use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XMLSecurity\Exception\ProtocolViolationException;

use function intval;

/**
* @package simplesamlphp/xml-security
*/
trait HMACOutputLengthTrait
{
/**
* The HMAC algorithm (RFC2104 [HMAC]) takes the output (truncation) length in bits as a parameter;
* this specification REQUIRES that the truncation length be a multiple of 8 (i.e. fall on a byte boundary)
* because Base64 encoding operates on full bytes
*
* @var string
*/
private static string $HMACOutputLength_regex = '/^([1-9]\d*)$/D';


/**
* @param string $value
* @param string $message
*/
protected static function validHMACOutputLength(string $value, string $message = ''): void
{
try {
parent::regex(
$value,
self::$HMACOutputLength_regex,
$message ?: '%s is not a valid ds:HMACOutputLengthType',
);
} catch (AssertionFailedException $e) {
throw new SchemaViolationException($e->getMessage());
}

try {
parent::true(
intval($value) % 8 === 0,
'%s is not devisible by 8 and therefore not a valid ds:HMACOutputLengthType',
);
} catch (AssertionFailedException $e) {
throw new ProtocolViolationException($e->getMessage());
}
}
}
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);
}
}
Loading