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

Merge for release 2.3 #77

Merged
merged 34 commits into from
Sep 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c18bc48
Add tests for shibmd:scope.
thijskh Feb 23, 2016
8b06016
shibmd:scope regexp attribute should default to false and be always e…
thijskh Feb 23, 2016
3d93cf9
Fast finish build so we get feedback quickly.
thijskh Feb 24, 2016
dded4f7
Complete coverage for XML/mdrpi/
thijskh Feb 24, 2016
dee5f42
Add coverage for mdattr
thijskh Feb 24, 2016
9236ce9
Complete coverage of SubjectConfirmation
thijskh Feb 24, 2016
b30b2f1
Doc fix: unserialize() does not return Chunk object
thijskh Feb 26, 2016
ac72699
Complete coverage for Chunk and Extensions
thijskh Feb 26, 2016
2cd087c
Basic test coverage for DiscoHints
thijskh Feb 26, 2016
04d939e
Merge pull request #61 from thijskh/master
thijskh Mar 9, 2016
abac7d8
split large tests in more managable units
thijskh Mar 9, 2016
1da2625
Add tests for signed assertion verification
thijskh Mar 11, 2016
aed2223
Remove spurious 'use'
thijskh Mar 11, 2016
bc77409
Revert "Remove spurious 'use'"
thijskh Mar 11, 2016
952e166
Fix namespace in assertion test.
thijskh Mar 14, 2016
6ab32d5
Test for a couple of error conditions
thijskh Mar 14, 2016
b36a822
Fix typo in exception message
thijskh Mar 14, 2016
8a83fc8
Allow the NameID / EncryptedID to be missing from a SAML subject.
jaimeperez Mar 16, 2016
85e1b97
More tests for Assertion
thijskh Mar 17, 2016
75adf10
Fix documentation
thijskh Mar 17, 2016
d9df067
Complete tests for XML/mdui/
thijskh Mar 17, 2016
41076cd
Fix KeyLoader::loadKeys
cb8 Mar 27, 2016
8d1f5fe
Merge pull request #65 from cb8/fix-keyloader
thijskh Mar 28, 2016
c31766d
Allow setting "AllowCreate" in a NameIDPolicy to something other than…
jaimeperez Mar 29, 2016
00e38f8
Update the compat logger to the latest version of SSP.
jaimeperez Jul 26, 2016
d1680d3
Add deprecation tags to classes and methods that work with certificat…
thijskh Aug 5, 2016
e619582
bugfix: PrivateKeyConfiguration alias confused with PrivateKey.
jaimeperez Aug 12, 2016
5f68f86
bugfix: Set logger in SAML2\Assertion\Transformer\NameIDDecryptionTra…
jaimeperez Aug 12, 2016
e25ed1a
Fix typo in error message.
thijskh Aug 15, 2016
a5328a8
EPTI urn mace and urn oid are available
Sep 7, 2016
da07159
EPTI attribute parsing adheres to specified structure
Sep 7, 2016
09e4157
Documentation of attribute value representation is complete
Sep 7, 2016
eeefb67
Merge pull request #76 from SURFnet/feature/correct-epti-attribute-pa…
DRvanR Sep 13, 2016
1cea30c
Merge pull request #69 from thijskh/feature/deprecate-fingerprints
thijskh Sep 13, 2016
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ php:
- hhvm

matrix:
fast_finish: true
allow_failures:
- php: hhvm

Expand Down
75 changes: 58 additions & 17 deletions src/SAML2/Assertion.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use RobRichards\XMLSecLibs\XMLSecEnc;
use RobRichards\XMLSecLibs\XMLSecurityKey;
use SAML2\Exception\RuntimeException;
use SAML2\Utilities\Temporal;
use SAML2\XML\Chunk;
use SAML2\XML\saml\SubjectConfirmation;
Expand Down Expand Up @@ -152,10 +153,21 @@ class Assertion implements SignedElement
private $AuthenticatingAuthority;

/**
* The attributes, as an associative array.
* The attributes, as an associative array, indexed by attribute name
*
* @var array multi-dimensional array, indexed by attribute name with each value representing the attribute value
* of that attribute. This value is an array of \DOMNodeList|string|int
* To ease handling, all attribute values are represented as an array of values, also for values with a multiplicity
* of single. There are 4 possible variants of datatypes for the values: a string, an integer, an array or
* a DOMNodeList
*
* If the attribute is an eduPersonTargetedID, the values will be arrays that are created by @see Utils::parseNameId
* and compatible with @see Utils::addNameID
* If the attribute value has an type-definition (xsi:string or xsi:int), the values will be of that type.
* If the attribute value contains a nested XML structure, the values will be a DOMNodeList
* In all other cases the values are treated as strings
*
* **WARNING** a DOMNodeList cannot be serialized without data-loss and should be handled explicitly
*
* @var array multi-dimensional array of \DOMNodeList|string|int|array
*/
private $attributes;

Expand Down Expand Up @@ -287,21 +299,20 @@ private function parseSubject(\DOMElement $xml)
$subject,
'./saml_assertion:NameID | ./saml_assertion:EncryptedID/xenc:EncryptedData'
);
if (empty($nameId)) {
throw new \Exception('Missing <saml:NameID> or <saml:EncryptedID> in <saml:Subject>.');
} elseif (count($nameId) > 1) {
throw new \Exception('More than one <saml:NameID> or <saml:EncryptedD> in <saml:Subject>.');
}
$nameId = $nameId[0];
if ($nameId->localName === 'EncryptedData') {
/* The NameID element is encrypted. */
$this->encryptedNameId = $nameId;
} else {
$this->nameId = Utils::parseNameId($nameId);
if (count($nameId) > 1) {
throw new \Exception('More than one <saml:NameID> or <saml:EncryptedID> in <saml:Subject>.');
} elseif (!empty($nameId)) {
$nameId = $nameId[0];
if ($nameId->localName === 'EncryptedData') {
/* The NameID element is encrypted. */
$this->encryptedNameId = $nameId;
} else {
$this->nameId = Utils::parseNameId($nameId);
}
}

$subjectConfirmation = Utils::xpQuery($subject, './saml_assertion:SubjectConfirmation');
if (empty($subjectConfirmation)) {
if (empty($subjectConfirmation) && empty($nameId)) {
throw new \Exception('Missing <saml:SubjectConfirmation> in <saml:Subject>.');
}

Expand Down Expand Up @@ -388,7 +399,7 @@ private function parseAuthnStatement(\DOMElement $xml)

return;
} elseif (count($authnStatements) > 1) {
throw new \Exception('More that one <saml:AuthnStatement> in <saml:Assertion> not supported.');
throw new \Exception('More than one <saml:AuthnStatement> in <saml:Assertion> not supported.');
}
$authnStatement = $authnStatements[0];

Expand Down Expand Up @@ -512,7 +523,27 @@ private function parseAttributes(\DOMElement $xml)
*/
private function parseAttributeValue($attribute, $attributeName)
{
/** @var \DOMElement[] $values */
$values = Utils::xpQuery($attribute, './saml_assertion:AttributeValue');

if ($attributeName === Constants::EPTI_URN_MACE || $attributeName === Constants::EPTI_URN_OID) {
foreach ($values as $index => $eptiAttributeValue) {
$eptiNameId = Utils::xpQuery($eptiAttributeValue, './saml:NameID');

if (count($eptiNameId) !== 1) {
throw new RuntimeException(sprintf(
'A "%s" (EPTI) attribute value must be a NameID, none found for value no. "%d"',
$attributeName,
$index
));
}

$this->attributes[$attributeName][] = Utils::parseNameId($eptiNameId[0]);
}

return;
}

foreach ($values as $value) {
$hasNonTextChildElements = false;
foreach ($value->childNodes as $childNode) {
Expand Down Expand Up @@ -582,7 +613,7 @@ private function parseSignature(\DOMElement $xml)
*/
public function validate(XMLSecurityKey $key)
{
assert('$key->type === XMLSecurityKey::RSA_SHA1');
assert('$key->type === \RobRichards\XMLSecLibs\XMLSecurityKey::RSA_SHA1');

if ($this->signatureData === null) {
return false;
Expand Down Expand Up @@ -1469,6 +1500,16 @@ private function addAttributeStatement(\DOMElement $root)
$attribute->setAttribute('NameFormat', $this->nameFormat);
}

if ($name === Constants::EPTI_URN_MACE || $name === Constants::EPTI_URN_OID) {
foreach ($values as $eptiValue) {
$attributeValue = $document->createElementNS(Constants::NS_SAML, 'saml:AttributeValue');
$attribute->appendChild($attributeValue);
Utils::addNameId($attributeValue, $eptiValue);
}

continue;
}

foreach ($values as $value) {
if (is_string($value)) {
$type = 'xs:string';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public function __construct(
LoggerInterface $logger,
PrivateKeyLoader $privateKeyLoader
) {
$this->logger = $logger;
$this->privateKeyLoader = $privateKeyLoader;
}

Expand Down
4 changes: 2 additions & 2 deletions src/SAML2/AuthnRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@ public function toUnsignedXML()
if (array_key_exists('SPNameQualifier', $this->nameIdPolicy)) {
$nameIdPolicy->setAttribute('SPNameQualifier', $this->nameIdPolicy['SPNameQualifier']);
}
if (array_key_exists('AllowCreate', $this->nameIdPolicy) && $this->nameIdPolicy['AllowCreate']) {
$nameIdPolicy->setAttribute('AllowCreate', 'true');
if (array_key_exists('AllowCreate', $this->nameIdPolicy) && is_bool($this->nameIdPolicy['AllowCreate'])) {
$nameIdPolicy->setAttribute('AllowCreate', ($this->nameIdPolicy['AllowCreate']) ? 'true' : 'false');
}
$root->appendChild($nameIdPolicy);
}
Expand Down
4 changes: 4 additions & 0 deletions src/SAML2/Certificate/Fingerprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

/**
* Simple representation of the fingerprint of a certificate
*
* @deprecated Please use full certificates instead.
*/
class Fingerprint
{
Expand All @@ -16,6 +18,8 @@ class Fingerprint

/**
* @param string $fingerPrint
*
* @deprecated Please use full certificates instead.
*/
public function __construct($fingerPrint)
{
Expand Down
5 changes: 5 additions & 0 deletions src/SAML2/Certificate/FingerprintCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

/**
* Simple collection object for transporting keys
* @deprecated Please load full certificates instead.
*/
class FingerprintCollection extends ArrayCollection
{
/**
* Add a key to the collection
*
* @param \SAML2\Certificate\Fingerprint $fingerprint
*
* @deprecated
*/
public function add($fingerprint)
{
Expand All @@ -31,6 +34,8 @@ public function add($fingerprint)
* @param \SAML2\Certificate\Fingerprint $otherFingerprint
*
* @return bool
*
* @deprecated
*/
public function contains(Fingerprint $otherFingerprint)
{
Expand Down
7 changes: 7 additions & 0 deletions src/SAML2/Certificate/FingerprintLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use SAML2\Configuration\CertificateProvider;
use SAML2\Exception\InvalidArgumentException;

/**
* @deprecated Please load full certificates instead.
*/
class FingerprintLoader
{
/**
Expand All @@ -13,6 +16,8 @@ class FingerprintLoader
* @param \SAML2\Configuration\CertificateProvider $configuration
*
* @return \SAML2\Certificate\FingerprintCollection
*
* @deprecated
*/
public static function loadFromConfiguration(CertificateProvider $configuration)
{
Expand All @@ -27,6 +32,8 @@ public static function loadFromConfiguration(CertificateProvider $configuration)
* @param \SAML2\Configuration\CertificateProvider $configuration
*
* @return \SAML2\Certificate\FingerprintCollection
*
* @deprecated
*/
public function loadFingerprints(CertificateProvider $configuration)
{
Expand Down
2 changes: 1 addition & 1 deletion src/SAML2/Certificate/KeyLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function loadKeysFromConfiguration(
public function loadKeys(array $configuredKeys, $usage)
{
foreach ($configuredKeys as $keyData) {
if (isset($key['X509Certificate'])) {
if (isset($keyData['X509Certificate'])) {
$key = new X509($keyData);
} else {
$key = new Key($keyData);
Expand Down
4 changes: 2 additions & 2 deletions src/SAML2/Certificate/PrivateKeyLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ public function loadDecryptionKeys(
return $decryptionKeys;
}

$newPrivateKey = $serviceProvider->getPrivateKey(PrivateKey::NAME_NEW);
$newPrivateKey = $serviceProvider->getPrivateKey(PrivateKeyConfiguration::NAME_NEW);
if ($newPrivateKey instanceof PrivateKey) {
$loadedKey = $this->loadPrivateKey($newPrivateKey);
$decryptionKeys->add($this->convertPrivateKeyToRsaKey($loadedKey));
}

$privateKey = $serviceProvider->getPrivateKey(PrivateKey::NAME_DEFAULT, true);
$privateKey = $serviceProvider->getPrivateKey(PrivateKeyConfiguration::NAME_DEFAULT, true);
$loadedKey = $this->loadPrivateKey($privateKey);
$decryptionKeys->add($this->convertPrivateKeyToRsaKey($loadedKey));

Expand Down
2 changes: 2 additions & 0 deletions src/SAML2/Certificate/X509.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public function getCertificate()

/**
* @return \SAML2\Certificate\Fingerprint
*
* @deprecated Please use full certificates instead.
*/
public function getFingerprint()
{
Expand Down
49 changes: 24 additions & 25 deletions src/SAML2/Compat/Ssp/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace SAML2\Compat\Ssp;

use Psr\Log\LoggerInterface;
use SimpleSAML_Logger;

class Logger implements LoggerInterface
{
Expand All @@ -16,7 +15,7 @@ class Logger implements LoggerInterface
*/
public function emergency($message, array $context = array())
{
SimpleSAML_Logger::emergency($message . var_export($context, true));
\SimpleSAML\Logger::emergency($message . var_export($context, true));
}

/**
Expand All @@ -31,7 +30,7 @@ public function emergency($message, array $context = array())
*/
public function alert($message, array $context = array())
{
SimpleSAML_Logger::alert($message . var_export($context, true));
\SimpleSAML\Logger::alert($message . var_export($context, true));
}

/**
Expand All @@ -45,7 +44,7 @@ public function alert($message, array $context = array())
*/
public function critical($message, array $context = array())
{
SimpleSAML_Logger::critical($message . var_export($context, true));
\SimpleSAML\Logger::critical($message . var_export($context, true));
}

/**
Expand All @@ -58,7 +57,7 @@ public function critical($message, array $context = array())
*/
public function error($message, array $context = array())
{
SimpleSAML_Logger::error($message . var_export($context, true));
\SimpleSAML\Logger::error($message . var_export($context, true));
}

/**
Expand All @@ -73,7 +72,7 @@ public function error($message, array $context = array())
*/
public function warning($message, array $context = array())
{
SimpleSAML_Logger::warning($message . var_export($context, true));
\SimpleSAML\Logger::warning($message . var_export($context, true));
}

/**
Expand All @@ -85,7 +84,7 @@ public function warning($message, array $context = array())
*/
public function notice($message, array $context = array())
{
SimpleSAML_Logger::notice($message . var_export($context, true));
\SimpleSAML\Logger::notice($message . var_export($context, true));
}

/**
Expand All @@ -99,7 +98,7 @@ public function notice($message, array $context = array())
*/
public function info($message, array $context = array())
{
SimpleSAML_Logger::info($message . var_export($context, true));
\SimpleSAML\Logger::info($message . var_export($context, true));
}

/**
Expand All @@ -111,7 +110,7 @@ public function info($message, array $context = array())
*/
public function debug($message, array $context = array())
{
SimpleSAML_Logger::debug($message . var_export($context, true));
\SimpleSAML\Logger::debug($message . var_export($context, true));
}

/**
Expand All @@ -125,29 +124,29 @@ public function debug($message, array $context = array())
public function log($level, $message, array $context = array())
{
switch ($level) {
case SimpleSAML_Logger::ALERT:
SimpleSAML_Logger::alert($message);
case \SimpleSAML\Logger::ALERT:
\SimpleSAML\Logger::alert($message);
break;
case SimpleSAML_Logger::CRIT:
SimpleSAML_Logger::critical($message);
case \SimpleSAML\Logger::CRIT:
\SimpleSAML\Logger::critical($message);
break;
case SimpleSAML_Logger::DEBUG:
SimpleSAML_Logger::debug($message);
case \SimpleSAML\Logger::DEBUG:
\SimpleSAML\Logger::debug($message);
break;
case SimpleSAML_Logger::EMERG:
SimpleSAML_Logger::emergency($message);
case \SimpleSAML\Logger::EMERG:
\SimpleSAML\Logger::emergency($message);
break;
case SimpleSAML_Logger::ERR:
SimpleSAML_Logger::error($message);
case \SimpleSAML\Logger::ERR:
\SimpleSAML\Logger::error($message);
break;
case SimpleSAML_Logger::INFO:
SimpleSAML_Logger::info($message);
case \SimpleSAML\Logger::INFO:
\SimpleSAML\Logger::info($message);
break;
case SimpleSAML_Logger::NOTICE:
SimpleSAML_Logger::notice($message);
case \SimpleSAML\Logger::NOTICE:
\SimpleSAML\Logger::notice($message);
break;
case SimpleSAML_Logger::WARNING:
SimpleSAML_Logger::warning($message);
case \SimpleSAML\Logger::WARNING:
\SimpleSAML\Logger::warning($message);
}
}
}
2 changes: 2 additions & 0 deletions src/SAML2/Configuration/CertificateProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public function getCertificateFile();
* fingerprint is a string containing the certificate fingerprint.
*
* @return null|array|\Traversable
*
* @deprecated Please use getCertifiateFile() or getCertificateData()
*/
public function getCertificateFingerprints();
}
Loading