Bump to php-saml 2.10.5

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
Lukas Reschke 2017-03-16 16:21:24 +01:00
parent 775cf5bac5
commit ea7f1c3e39
No known key found for this signature in database
GPG key ID: B9F6980CF6E759B1
16 changed files with 267 additions and 72 deletions

10
3rdparty/composer.lock generated vendored
View file

@ -8,16 +8,16 @@
"packages": [
{
"name": "onelogin/php-saml",
"version": "2.10.3",
"version": "2.10.5",
"source": {
"type": "git",
"url": "https://github.com/onelogin/php-saml.git",
"reference": "eb6cfbca928106205558a596988923da0e47bd9d"
"reference": "3319d7707f342e38291eee6b01a4a5f8df1b333b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/onelogin/php-saml/zipball/eb6cfbca928106205558a596988923da0e47bd9d",
"reference": "eb6cfbca928106205558a596988923da0e47bd9d",
"url": "https://api.github.com/repos/onelogin/php-saml/zipball/3319d7707f342e38291eee6b01a4a5f8df1b333b",
"reference": "3319d7707f342e38291eee6b01a4a5f8df1b333b",
"shasum": ""
},
"require": {
@ -58,7 +58,7 @@
"onelogin",
"saml"
],
"time": "2017-01-11T17:18:41+00:00"
"time": "2017-03-13T09:56:49+00:00"
}
],
"packages-dev": [],

View file

@ -1,17 +1,17 @@
[
{
"name": "onelogin/php-saml",
"version": "2.10.3",
"version_normalized": "2.10.3.0",
"version": "2.10.5",
"version_normalized": "2.10.5.0",
"source": {
"type": "git",
"url": "https://github.com/onelogin/php-saml.git",
"reference": "eb6cfbca928106205558a596988923da0e47bd9d"
"reference": "3319d7707f342e38291eee6b01a4a5f8df1b333b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/onelogin/php-saml/zipball/eb6cfbca928106205558a596988923da0e47bd9d",
"reference": "eb6cfbca928106205558a596988923da0e47bd9d",
"url": "https://api.github.com/repos/onelogin/php-saml/zipball/3319d7707f342e38291eee6b01a4a5f8df1b333b",
"reference": "3319d7707f342e38291eee6b01a4a5f8df1b333b",
"shasum": ""
},
"require": {
@ -33,7 +33,7 @@
"ext-mcrypt": "Install mcrypt and php5-mcrypt libs in order to support encryption",
"lib-openssl": "Install openssl lib in order to handle with x509 certs (require to support sign and encryption)"
},
"time": "2017-01-11T17:18:41+00:00",
"time": "2017-03-13T09:56:49+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {

View file

@ -4,7 +4,7 @@ php:
- 5.6
- 5.5
- 5.4
- 5.3
# - 5.3
- 7.0
env:

View file

@ -1,5 +1,22 @@
CHANGELOG
=========
v.2.10.5
* Be able to get at the auth object the last processed ID
* Improve NameID Format support
* Reset errorReason attribute of the auth object after each Process method
* Validate serial number as string to work around libxml2 limitation
* Make the Issuer on the Response Optional
v.2.10.4
* [+](https://github.com/onelogin/php-saml/commit/949359f5cad5e1d085c4e5447d9aa8f49a6e82a1) Security update for signature validation on LogoutRequest/LogoutResponse
* [#192](https://github.com/onelogin/php-saml/pull/192) Added ability to configure DigestAlgorithm in settings
* [#183](https://github.com/onelogin/php-saml/pull/183) Fix strpos bug when decrypting assertions
* [#186](https://github.com/onelogin/php-saml/pull/186) Improve info on entityId validation Exception
* [#188](https://github.com/onelogin/php-saml/pull/188) Fixed issue with undefined constant of UNEXPECTED_SIGNED_ELEMENT
* Read ACS binding on AuthNRequest builder from settings
* Be able to relax Destination validation on SAMLResponses and let this
attribute to be empty with the 'relaxDestinationValidation' setting
v.2.10.3
* Implement a more specific exception class for handling some validation errors
* Minor changes on time validation/exceptions

View file

@ -10,6 +10,9 @@ and supported by OneLogin Inc.
Warning
-------
Update php-saml to 2.10.4, this version includes a security patch related to
[signature validations on LogoutRequests/LogoutResponses](https://github.com/onelogin/php-saml/commit/949359f5cad5e1d085c4e5447d9aa8f49a6e82a1)
Update php-saml to 2.10.0, this version includes a security patch that contains extra validations that will prevent signature wrapping attacks. [CVE-2016-1000253](https://github.com/distributedweaknessfiling/DWF-Database-Artifacts/blob/ab8ae6e845eb506fbeb10a7e4ccb379f0b4222ca/DWF/2016/1000253/CVE-2016-1000253.json)
php-saml < v2.10.0 is vulnerable and allows signature wrapping!
@ -458,6 +461,10 @@ $advancedSettings = array (
// (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).
'wantXMLValidation' => true,
// If true, SAMLResponses with an empty value at its Destination
// attribute will not be rejected for this fact.
'relaxDestinationValidation' => false,
// Algorithm that the toolkit will use on signing process. Options:
// 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
// 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
@ -466,6 +473,13 @@ $advancedSettings = array (
// 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
'signatureAlgorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
// Algorithm that the toolkit will use on digest process. Options:
// 'http://www.w3.org/2000/09/xmldsig#sha1'
// 'http://www.w3.org/2001/04/xmlenc#sha256'
// 'http://www.w3.org/2001/04/xmldsig-more#sha384'
// 'http://www.w3.org/2001/04/xmlenc#sha512'
'digestAlgorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1',
// ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses
// uppercase. Turn it True for ADFS compatibility on signature verification
'lowercaseUrlencoding' => false,
@ -1061,6 +1075,23 @@ Also a developer can use setSelfProtocol, setSelfHost, setSelfPort and getBaseUR
At the settings the developer will be able to set a 'baseurl' parameter that automatically will use setBaseURL to set values for setSelfProtocol, setSelfHost, setSelfPort and setBaseURLPath.
### Working behind load balancer ###
Is possible that asserting request URL and Destination attribute of SAML response fails when working behind load balancer with SSL offload.
You should be able to workaround this by configuring your server so that it is aware of the proxy and returns the original url when requested.
Or by using the method described on the previous section.
### Reply attacks ###
In order to avoid reply attacks, you can store the ID of the SAML messages already processed, to avoid processing them twice. Since the Messages expires and will be invalidated due that fact, you don't need to store those IDs longer than the time frame that you currently accepting.
Get the ID of the last processed message/assertion with the getLastMessageId/getLastAssertionId method of the Auth object.
### Main classes and methods ###
Described below are the main classes and methods that can be invoked.

View file

@ -77,6 +77,10 @@ $advancedSettings = array (
// (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).
'wantXMLValidation' => true,
// If true, SAMLResponses with an empty value at its Destination
// attribute will not be rejected for this fact.
'relaxDestinationValidation' => false,
// Algorithm that the toolkit will use on signing process. Options:
// 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
// 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
@ -85,6 +89,13 @@ $advancedSettings = array (
// 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
'signatureAlgorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
// Algorithm that the toolkit will use on digest process. Options:
// 'http://www.w3.org/2000/09/xmldsig#sha1'
// 'http://www.w3.org/2001/04/xmlenc#sha256'
// 'http://www.w3.org/2001/04/xmldsig-more#sha384'
// 'http://www.w3.org/2001/04/xmlenc#sha512'
'digestAlgorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1',
// ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses
// uppercase. Turn it True for ADFS compatibility on signature verification
'lowercaseUrlencoding' => false,

View file

@ -2,7 +2,7 @@
"name": "onelogin/php-saml",
"description": "OneLogin PHP SAML Toolkit",
"license": "MIT",
"version": "2.10.3",
"version": "2.10.5",
"homepage": "https://onelogin.zendesk.com/hc/en-us/sections/200245634-SAML-Toolkits",
"keywords": ["saml", "saml2", "onelogin"],
"autoload": {

View file

@ -6,7 +6,6 @@
*/
class OneLogin_Saml2_Auth
{
/**
* Settings data.
*
@ -59,6 +58,28 @@ class OneLogin_Saml2_Auth
*/
private $_sessionExpiration;
/**
* The ID of the last message processed
*
* @var string
*/
private $_lastMessageId;
/**
* The ID of the last assertion processed
*
* @var string
*/
private $_lastAssertionId;
/**
* The NotOnOrAfter value of the valid SubjectConfirmationData
* node (if any) of the last assertion processed
*
* @var DateTime
*/
private $_lastAssertionNotOnOrAfter;
/**
* If any error.
*
@ -82,7 +103,7 @@ class OneLogin_Saml2_Auth
/**
* The most recently-constructed/processed XML SAML request
* (AuthNRequest, LogoutRequest)
* (AuthNRequest, LogoutRequest)
*
* @var string
*/
@ -91,7 +112,7 @@ class OneLogin_Saml2_Auth
/**
* The most recently-constructed/processed XML SAML response
* (SAMLResponse, LogoutResponse). If the SAMLResponse was
* encrypted, by default tries to return the decrypted XML
* encrypted, by default tries to return the decrypted XML
*
* @var string
*/
@ -146,6 +167,7 @@ class OneLogin_Saml2_Auth
public function processResponse($requestId = null)
{
$this->_errors = array();
$this->_errorReason = null;
if (isset($_POST) && isset($_POST['SAMLResponse'])) {
// AuthnResponse -- HTTP_POST Binding
$response = new OneLogin_Saml2_Response($this->_settings, $_POST['SAMLResponse']);
@ -158,6 +180,9 @@ class OneLogin_Saml2_Auth
$this->_authenticated = true;
$this->_sessionIndex = $response->getSessionIndex();
$this->_sessionExpiration = $response->getSessionNotOnOrAfter();
$this->_lastMessageId = $response->getId();
$this->_lastAssertionId = $response->getAssertionId();
$this->_lastAssertionNotOnOrAfter = $response->getAssertionNotOnOrAfter();
} else {
$this->_errors[] = 'invalid_response';
$this->_errorReason = $response->getError();
@ -184,9 +209,10 @@ class OneLogin_Saml2_Auth
*
* @throws OneLogin_Saml2_Error
*/
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false, $cbDeleteSession = null, $stay=false)
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false, $cbDeleteSession = null, $stay = false)
{
$this->_errors = array();
$this->_errorReason = null;
if (isset($_GET) && isset($_GET['SAMLResponse'])) {
$logoutResponse = new OneLogin_Saml2_LogoutResponse($this->_settings, $_GET['SAMLResponse']);
$this->_lastResponse = $logoutResponse->getXML();
@ -196,6 +222,7 @@ class OneLogin_Saml2_Auth
} else if ($logoutResponse->getStatus() !== OneLogin_Saml2_Constants::STATUS_SUCCESS) {
$this->_errors[] = 'logout_not_success';
} else {
$this->_lastMessageId = $logoutResponse->id;
if (!$keepLocalSession) {
if ($cbDeleteSession === null) {
OneLogin_Saml2_Utils::deleteLocalSession();
@ -219,6 +246,7 @@ class OneLogin_Saml2_Auth
}
}
$inResponseTo = $logoutRequest->id;
$this->_lastMessageId = $logoutRequest->id;
$responseBuilder = new OneLogin_Saml2_LogoutResponse($this->_settings);
$responseBuilder->build($inResponseTo);
$this->_lastResponse = $responseBuilder->getXML();
@ -378,7 +406,7 @@ class OneLogin_Saml2_Auth
*
* @return If $stay is True, it return a string with the SLO URL + LogoutRequest + parameters
*/
public function login($returnTo = null, $parameters = array(), $forceAuthn = false, $isPassive = false, $stay=false, $setNameIdPolicy = true)
public function login($returnTo = null, $parameters = array(), $forceAuthn = false, $isPassive = false, $stay = false, $setNameIdPolicy = true)
{
assert('is_array($parameters)');
@ -419,7 +447,7 @@ class OneLogin_Saml2_Auth
*
* @throws OneLogin_Saml2_Error
*/
public function logout($returnTo = null, $parameters = array(), $nameId = null, $sessionIndex = null, $stay=false, $nameIdFormat = null)
public function logout($returnTo = null, $parameters = array(), $nameId = null, $sessionIndex = null, $stay = false, $nameIdFormat = null)
{
assert('is_array($parameters)');
@ -434,6 +462,9 @@ class OneLogin_Saml2_Auth
if (empty($nameId) && !empty($this->_nameid)) {
$nameId = $this->_nameid;
}
if (empty($nameIdFormat) && !empty($this->_nameidFormat)) {
$nameIdFormat = $this->_nameidFormat;
}
$logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, null, $nameId, $sessionIndex, $nameIdFormat);
@ -583,6 +614,32 @@ class OneLogin_Saml2_Auth
return base64_encode($signature);
}
/**
* @return string The ID of the last message processed
*/
public function getLastMessageId()
{
return $this->_lastMessageId;
}
/**
* @return string The ID of the last assertion processed
*/
public function getLastAssertionId()
{
return $this->_lastAssertionId;
}
/**
* @return The NotOnOrAfter value of the valid
* SubjectConfirmationData node (if any)
* of the last assertion processed
*/
public function getLastAssertionNotOnOrAfter()
{
return $this->_lastAssertionNotOnOrAfter;
}
/**
* Returns the most recently-constructed/processed
* XML SAML request (AuthNRequest, LogoutRequest)

View file

@ -123,7 +123,7 @@ REQUESTEDAUTHN;
{$providerNameStr}{$forceAuthnStr}{$isPassiveStr}
IssueInstant="$issueInstant"
Destination="{$idpData['singleSignOnService']['url']}"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
ProtocolBinding="{$spData['assertionConsumerService']['binding']}"
AssertionConsumerServiceURL="{$spData['assertionConsumerService']['url']}">
<saml:Issuer>{$spData['entityId']}</saml:Issuer>
{$nameIdPolicyStr}
@ -137,7 +137,7 @@ AUTHNREQUEST;
/**
* Returns deflated, base64 encoded, unsigned AuthnRequest.
*
*
* @param bool|null $deflate Whether or not we should 'gzdeflate' the request body before we return it.
*/
public function getRequest($deflate = null)

View file

@ -78,7 +78,7 @@ class OneLogin_Saml2_ValidationError extends Exception
const WRONG_DESTINATION = 24;
const EMPTY_DESTINATION = 25;
const WRONG_AUDIENCE = 26;
const ISSUER_NOT_FOUND_IN_RESPONSE = 27;
const ISSUER_MULTIPLE_IN_RESPONSE = 27;
const ISSUER_NOT_FOUND_IN_ASSERTION = 28;
const WRONG_ISSUER = 29;
const SESSION_EXPIRED = 30;

View file

@ -6,7 +6,6 @@
*/
class OneLogin_Saml2_LogoutRequest
{
/**
* Contains the ID of the Logout Request
* @var string
@ -50,7 +49,6 @@ class OneLogin_Saml2_LogoutRequest
}
if (!isset($request) || empty($request)) {
$spData = $this->_settings->getSPData();
$idpData = $this->_settings->getIdPData();
$security = $this->_settings->getSecurityData();
@ -288,7 +286,7 @@ LOGOUTREQUEST;
*
* @return bool If the Logout Request is or not valid
*/
public function isValid($retrieveParametersFromServer=false)
public function isValid($retrieveParametersFromServer = false)
{
$this->_error = null;
try {
@ -359,7 +357,6 @@ LOGOUTREQUEST;
}
if (isset($_GET['Signature'])) {
if (!isset($_GET['SigAlg'])) {
$signAlg = XMLSecurityKey::RSA_SHA1;
} else {
@ -402,7 +399,7 @@ LOGOUTREQUEST;
}
}
if (!$objKey->verifySignature($signedQuery, base64_decode($_GET['Signature']))) {
if ($objKey->verifySignature($signedQuery, base64_decode($_GET['Signature'])) !== 1) {
throw new OneLogin_Saml2_ValidationError(
"Signature validation failed. Logout Request rejected",
OneLogin_Saml2_ValidationError::INVALID_SIGNATURE

View file

@ -6,6 +6,11 @@
*/
class OneLogin_Saml2_LogoutResponse
{
/**
* Contains the ID of the Logout Response
* @var string
*/
public $id;
/**
* Object that represents the setting info
@ -57,6 +62,10 @@ class OneLogin_Saml2_LogoutResponse
}
$this->document = new DOMDocument();
$this->document = OneLogin_Saml2_Utils::loadXML($this->document, $this->_logoutResponse);
if ($this->document->documentElement->hasAttribute('ID')) {
$this->id = $this->document->documentElement->getAttribute('ID');
}
}
}
@ -100,11 +109,10 @@ class OneLogin_Saml2_LogoutResponse
*
* @throws Exception
*/
public function isValid($requestId = null, $retrieveParametersFromServer=false)
public function isValid($requestId = null, $retrieveParametersFromServer = false)
{
$this->_error = null;
try {
$idpData = $this->_settings->getIdPData();
$idPEntityId = $idpData['entityId'];
@ -209,7 +217,7 @@ class OneLogin_Saml2_LogoutResponse
}
}
if (!$objKey->verifySignature($signedQuery, base64_decode($_GET['Signature']))) {
if ($objKey->verifySignature($signedQuery, base64_decode($_GET['Signature'])) !== 1) {
throw new OneLogin_Saml2_ValidationError(
"Signature validation failed. Logout Response rejected",
OneLogin_Saml2_ValidationError::INVALID_SIGNATURE
@ -251,13 +259,13 @@ class OneLogin_Saml2_LogoutResponse
$spData = $this->_settings->getSPData();
$idpData = $this->_settings->getIdPData();
$id = OneLogin_Saml2_Utils::generateUniqueID();
$this->id = OneLogin_Saml2_Utils::generateUniqueID();
$issueInstant = OneLogin_Saml2_Utils::parseTime2SAML(time());
$logoutResponse = <<<LOGOUTRESPONSE
<samlp:LogoutResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="{$id}"
ID="{$this->id}"
Version="2.0"
IssueInstant="{$issueInstant}"
Destination="{$idpData['singleLogoutService']['url']}"
@ -274,9 +282,9 @@ LOGOUTRESPONSE;
/**
* Returns a Logout Response object.
*
*
* @param bool|null $deflate Whether or not we should 'gzdeflate' the response body before we return it.
*
*
* @return string Logout Response deflated and base64 encoded
*/
public function getResponse($deflate = null)
@ -302,6 +310,14 @@ LOGOUTRESPONSE;
return $this->_error;
}
/**
* @return the ID of the Response
*/
public function getId()
{
return $this->id;
}
/**
* Returns the XML that will be sent as part of the response
* or that was received at the SP

View file

@ -44,6 +44,13 @@ class OneLogin_Saml2_Response
*/
private $_error;
/**
* NotOnOrAfter value of a valid SubjectConfirmationData node
*
* @var DateTime
*/
private $_validSCDNotOnOrAfter;
/**
* Constructs the SAML Response object.
*
@ -200,7 +207,7 @@ class OneLogin_Saml2_Response
}
// Validate Asserion timestamps
$this->validateTimestamps();
$this->validateTimestamps();
// Validate AuthnStatement element exists and is unique
if (!$this->checkOneAuthnStatement()) {
@ -223,10 +230,12 @@ class OneLogin_Saml2_Response
if ($this->document->documentElement->hasAttribute('Destination')) {
$destination = trim($this->document->documentElement->getAttribute('Destination'));
if (empty($destination)) {
throw new OneLogin_Saml2_ValidationError(
"The response has an empty Destination value",
OneLogin_Saml2_ValidationError::EMPTY_DESTINATION
);
if (!$security['relaxDestinationValidation']) {
throw new OneLogin_Saml2_ValidationError(
"The response has an empty Destination value",
OneLogin_Saml2_ValidationError::EMPTY_DESTINATION
);
}
} else {
if (strpos($destination, $currentURL) !== 0) {
$currentURLNoRouted = OneLogin_Saml2_Utils::getSelfURLNoQuery();
@ -243,9 +252,13 @@ class OneLogin_Saml2_Response
// Check audience
$validAudiences = $this->getAudiences();
if (!empty($validAudiences) && !in_array($spEntityId, $validAudiences)) {
if (!empty($validAudiences) && !in_array($spEntityId, $validAudiences, true)) {
throw new OneLogin_Saml2_ValidationError(
"$spEntityId is not a valid audience for this Response",
sprintf(
"Invalid audience for this Response (expected '%s', got '%s')",
$spEntityId,
implode(',', $validAudiences)
),
OneLogin_Saml2_ValidationError::WRONG_AUDIENCE
);
}
@ -256,7 +269,7 @@ class OneLogin_Saml2_Response
$trimmedIssuer = trim($issuer);
if (empty($trimmedIssuer) || $trimmedIssuer !== $idPEntityId) {
throw new OneLogin_Saml2_ValidationError(
"Invalid issuer in the Assertion/Response",
"Invalid issuer in the Assertion/Response (expected '$idPEntityId', got '$trimmedIssuer')",
OneLogin_Saml2_ValidationError::WRONG_ISSUER
);
}
@ -264,7 +277,7 @@ class OneLogin_Saml2_Response
// Check the session Expiration
$sessionExpiration = $this->getSessionNotOnOrAfter();
if (!empty($sessionExpiration) && $sessionExpiration <= time()) {
if (!empty($sessionExpiration) && $sessionExpiration + OneLogin_Saml2_Constants::ALLOWED_CLOCK_DRIFT <= time()) {
throw new OneLogin_Saml2_ValidationError(
"The attributes have expired, based on the SessionNotOnOrAfter of the AttributeStatement of this Response",
OneLogin_Saml2_ValidationError::SESSION_EXPIRED
@ -297,16 +310,21 @@ class OneLogin_Saml2_Response
}
if ($scnData->hasAttribute('NotOnOrAfter')) {
$noa = OneLogin_Saml2_Utils::parseSAML2Time($scnData->getAttribute('NotOnOrAfter'));
if ($noa <= time()) {
if ($noa + OneLogin_Saml2_Constants::ALLOWED_CLOCK_DRIFT <= time()) {
continue;
}
}
if ($scnData->hasAttribute('NotBefore')) {
$nb = OneLogin_Saml2_Utils::parseSAML2Time($scnData->getAttribute('NotBefore'));
if ($nb > time()) {
if ($nb > time() + OneLogin_Saml2_Constants::ALLOWED_CLOCK_DRIFT) {
continue;
}
}
// Save NotOnOrAfter value
if ($scnData->hasAttribute('NotOnOrAfter')) {
$this->_validSCDNotOnOrAfter = $noa;
}
$anySubjectConfirmation = true;
break;
}
@ -383,9 +401,47 @@ class OneLogin_Saml2_Response
}
}
/**
* @return the ID of the Response
*/
public function getId()
{
$id = null;
if ($this->document->documentElement->hasAttribute('ID')) {
$id = $this->document->documentElement->getAttribute('ID');
}
return $id;
}
/**
* @return the ID of the assertion in the Response
*/
public function getAssertionId()
{
if (!$this->validateNumAssertions()) {
throw new IllegalArgumentException("SAML Response must contain 1 Assertion.");
}
$assertionNodes = $this->_queryAssertion("");
$id = null;
if ($assertionNodes->length == 1) {
if ($assertionNodes->item(0)->hasAttribute('ID')) {
$id = $assertionNodes->item(0)->getAttribute('ID');
}
}
return $id;
}
/**
* @return the NotOnOrAfter value of the valid SubjectConfirmationData * node if any
*/
public function getAssertionNotOnOrAfter()
{
return $this->_validSCDNotOnOrAfter;
}
/**
* Checks if the Status is success
*
*
* @throws $statusExceptionMsg If status is not success
*/
public function checkStatus()
@ -439,7 +495,7 @@ class OneLogin_Saml2_Response
/**
* Gets the audiences.
*
*
* @return array @audience The valid audiences of the response
*/
public function getAudiences()
@ -459,7 +515,7 @@ class OneLogin_Saml2_Response
/**
* Gets the Issuers (from Response and Assertion).
*
*
* @return array @issuers The issuers of the assertion/response
*/
public function getIssuers()
@ -467,13 +523,15 @@ class OneLogin_Saml2_Response
$issuers = array();
$responseIssuer = OneLogin_Saml2_Utils::query($this->document, '/samlp:Response/saml:Issuer');
if ($responseIssuer->length == 1) {
$issuers[] = $responseIssuer->item(0)->textContent;
} else {
throw new OneLogin_Saml2_ValidationError(
"Issuer of the Response not found or multiple.",
OneLogin_Saml2_ValidationError::ISSUER_NOT_FOUND_IN_RESPONSE
);
if ($responseIssuer->length > 0) {
if ($responseIssuer->length == 1) {
$issuers[] = $responseIssuer->item(0)->textContent;
} else {
throw new OneLogin_Saml2_ValidationError(
"Issuer of the Response is multiple.",
OneLogin_Saml2_ValidationError::ISSUER_MULTIPLE_IN_RESPONSE
);
}
}
$assertionIssuer = $this->_queryAssertion('/saml:Issuer');
@ -586,7 +644,7 @@ class OneLogin_Saml2_Response
/**
* Gets the SessionNotOnOrAfter from the AuthnStatement.
* Could be used to set the local session expiration
*
*
* @return int|null The SessionNotOnOrAfter value
*/
public function getSessionNotOnOrAfter()
@ -604,7 +662,7 @@ class OneLogin_Saml2_Response
* Could be used to be stored in the local session in order
* to be used in a future Logout Request that the SP could
* send to the SP, to set what specific session must be deleted
*
*
* @return string|null The SessionIndex value
*/
@ -620,7 +678,7 @@ class OneLogin_Saml2_Response
/**
* Gets the Attributes from the AttributeStatement element.
*
*
* @return array The attributes of the SAML Assertion
*/
public function getAttributes()
@ -706,7 +764,6 @@ class OneLogin_Saml2_Response
$signNodes = $this->document->getElementsByTagName('Signature');
}
foreach ($signNodes as $signNode) {
$responseTag = '{'.OneLogin_Saml2_Constants::NS_SAMLP.'}Response';
$assertionTag = '{'.OneLogin_Saml2_Constants::NS_SAML.'}Assertion';
@ -747,7 +804,7 @@ class OneLogin_Saml2_Response
throw new OneLogin_Saml2_ValidationError(
'Found an invalid Signed Element. SAML Response rejected',
OneLogin_Saml2_ValidationError::INVALID_SIGNED_ELEMENT
);
);
}
if (in_array($sei, $verifiedSeis)) {
@ -772,7 +829,7 @@ class OneLogin_Saml2_Response
if (!$this->validateSignedElements($signedElements)) {
throw new OneLogin_Saml2_ValidationError(
'Found an unexpected Signature Element. SAML Response rejected',
OneLogin_Saml2_ValidationError::UNEXPECTED_SIGNED_ELEMENT
OneLogin_Saml2_ValidationError::UNEXPECTED_SIGNED_ELEMENTS
);
}
}
@ -953,7 +1010,7 @@ class OneLogin_Saml2_Response
if (!$encData) {
throw new OneLogin_Saml2_ValidationError(
"Cannot locate encrypted assertion",
OneLogin_Saml2_ValidationError::MISSING_ENCRYPTED_ELEMENT
OneLogin_Saml2_ValidationError::MISSING_ENCRYPTED_ELEMENT
);
}
@ -962,7 +1019,7 @@ class OneLogin_Saml2_Response
if (!$objKey = $objenc->locateKey()) {
throw new OneLogin_Saml2_ValidationError(
"Unknown algorithm",
OneLogin_Saml2_ValidationError::KEY_ALGORITHM_ERROR
OneLogin_Saml2_ValidationError::KEY_ALGORITHM_ERROR
);
}
@ -987,7 +1044,6 @@ class OneLogin_Saml2_Response
if ($decrypted instanceof DOMDocument) {
return $decrypted;
} else {
$encryptedAssertion = $decrypted->parentNode;
$container = $encryptedAssertion->parentNode;
@ -998,10 +1054,9 @@ class OneLogin_Saml2_Response
!$container->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml') &&
!$container->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml2')
) {
if (strpos($encryptedAssertion->tagName, 'saml2:') !== false) {
$ns = 'xmlns:saml2';
} else if (strpos($encryptedAssertion->tagName, 'saml:') != false) {
} else if (strpos($encryptedAssertion->tagName, 'saml:') !== false) {
$ns = 'xmlns:saml';
} else {
$ns = 'xmlns';
@ -1025,7 +1080,7 @@ class OneLogin_Saml2_Response
return $this->_error;
}
/*
/*
* Returns the SAML Response document (If contains an encrypted assertion, decrypts it)
*
* @return DomDocument SAML Response

View file

@ -371,6 +371,11 @@ class OneLogin_Saml2_Settings
$this->_security['wantNameId'] = true;
}
// Relax Destination validation
if (!isset($this->_security['relaxDestinationValidation'])) {
$this->_security['relaxDestinationValidation'] = false;
}
// encrypt expected
if (!isset($this->_security['wantAssertionsEncrypted'])) {
$this->_security['wantAssertionsEncrypted'] = false;
@ -384,11 +389,16 @@ class OneLogin_Saml2_Settings
$this->_security['wantXMLValidation'] = true;
}
// Algorithm
// SignatureAlgorithm
if (!isset($this->_security['signatureAlgorithm'])) {
$this->_security['signatureAlgorithm'] = XMLSecurityKey::RSA_SHA1;
}
// DigestAlgorithm
if (!isset($this->_security['digestAlgorithm'])) {
$this->_security['digestAlgorithm'] = XMLSecurityDSig::SHA1;
}
if (!isset($this->_security['lowercaseUrlencoding'])) {
$this->_security['lowercaseUrlencoding'] = false;
}
@ -835,7 +845,8 @@ class OneLogin_Saml2_Settings
}
$signatureAlgorithm = $this->_security['signatureAlgorithm'];
$metadata = OneLogin_Saml2_Metadata::signMetadata($metadata, $keyMetadata, $certMetadata, $signatureAlgorithm);
$digestAlgorithm = $this->_security['digestAlgorithm'];
$metadata = OneLogin_Saml2_Metadata::signMetadata($metadata, $keyMetadata, $certMetadata, $signatureAlgorithm, $digestAlgorithm);
}
return $metadata;
}

View file

@ -188,7 +188,7 @@
<complexType name="X509IssuerSerialType">
<sequence>
<element name="X509IssuerName" type="string"/>
<element name="X509SerialNumber" type="integer"/>
<element name="X509SerialNumber" type="string"/>
</sequence>
</complexType>

View file

@ -1,6 +1,6 @@
{
"php-saml": {
"version": "2.10.3",
"released": "11/01/2017"
"version": "2.10.5",
"released": "13/03/2017"
}
}