. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Robert Richards nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @author Robert Richards * @copyright 2007 Robert Richards * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version 1.1.2 */ require('xmlseclibs.php'); define('SAML_ASSERT_NS', 'urn:oasis:names:tc:SAML:1.0:assertion'); function processCard($xmlToken, $privateKey=NULL, $sslEnabled=True) { try { if ($sslEnabled) { $encdom = new DOMDocument(); $encdom->loadXML($xmlToken); $objenc = new XMLSecEnc(); $encData = $objenc->locateEncryptedData($encdom); if (! $encData) { throw new Exception("Cannot locate Encrypted Data"); } $objenc->setNode($encData); $objenc->type = $encData->getAttribute("Type"); $key = NULL; $objKey = $objenc->locateKey(); if ($objKey) { if ($objKeyInfo = $objenc->locateKeyInfo($objKey)) { if ($objKeyInfo->isEncrypted) { $objencKey = $objKeyInfo->encryptedCtx; $objKeyInfo->loadKey($privateKey, TRUE); $key = $objencKey->decryptKey($objKeyInfo); } } } if (empty($objKey) || empty($key)) { throw new Exception("Error loading key to handle Decryption"); } $objKey->loadKey($key); $token = NULL; if ($decrypt = $objenc->decryptNode($objKey, FALSE)) { /* we have the saml token so load er up */ $token = new DOMDocument(); $token->loadXML($decrypt); } } else { $token = new DOMDocument(); $token->loadXML($xmlToken); } if (empty($token)) { throw new Exception("Unable to decrypt token"); } /* Validate the SAML token */ $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys[] = 'AssertionID'; $objDSig = $objXMLSecDSig->locateSignature($token); /* Canonicalize the signed info */ $objXMLSecDSig->canonicalizeSignedInfo(); $retVal = NULL; if ($objDSig) { $retVal = $objXMLSecDSig->validateReference(); } if (! $retVal) { throw new Exception("SAML Validation Failed"); } $key = NULL; $objKey = $objXMLSecDSig->locateKey(); if ($objKey) { if ($objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig)) { /* Handle any additional key processing such as encrypted keys here */ } } if (empty($objKey)) { throw new Exception("Error loading key to handle Signature"); } if (! $objXMLSecDSig->verify($objKey)) { throw new Exception("Unable to validate Signature"); } return $token; } catch (DOMException $domE) { print "DOM Error: ".$domE->getMessage(); } catch (Exception $e) { print 'Error: '.$e->getMessage(); } return NULL; } function checkDateConditions($start=NULL, $end=NULL) { $currentTime = time(); if (! empty($start)) { $startTime = strtotime($start); /* Allow for a 10 minute difference in Time */ if (($startTime < 0) || (($startTime - 600) > $currentTime)) { return FALSE; } } if (! empty($end)) { $endTime = strtotime($end); if (($endTime < 0) || ($endTime <= $currentTime)) { return FALSE; } } return TRUE; } function getAssertions($token) { $assertions = array(); if ($token instanceof DOMDocument) { $xPath = new DOMXpath($token); $xPath->registerNamespace('mysaml', SAML_ASSERT_NS); $query = '/mysaml:Assertion/mysaml:Conditions'; $nodelist = $xPath->query($query); if ($node = $nodelist->item(0)) { $start = $node->getAttribute('NotBefore'); $end = $node->getAttribute('NotOnOrAfter'); if (! checkDateConditions($start, $end)) { return $assertions; } } $query = '/mysaml:Assertion/mysaml:AttributeStatement/mysaml:Attribute'; $nodelist = $xPath->query($query); foreach ($nodelist AS $node) { if ($name = $node->getAttribute('AttributeName')) { $value = ''; foreach ($node->childNodes AS $child) { if ($child->localName == 'AttributeValue') { $value = $child->textContent; break; } } $assertions[$name] = $value; } } } return $assertions; }