0byt3m1n1
Path:
/
home
/
mgatv524
/
www
/
fmd
/
vendor
/
onelogin
/
php-saml
/
lib
/
Saml2
/
[
Home
]
File: Metadata.php
<?php /** * This file is part of php-saml. * * (c) OneLogin Inc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @package OneLogin * @author OneLogin Inc <saml-info@onelogin.com> * @license MIT https://github.com/onelogin/php-saml/blob/master/LICENSE * @link https://github.com/onelogin/php-saml */ use RobRichards\XMLSecLibs\XMLSecurityKey; use RobRichards\XMLSecLibs\XMLSecurityDSig; /** * Metadata lib of OneLogin PHP Toolkit */ class OneLogin_Saml2_Metadata { const TIME_VALID = 172800; // 2 days const TIME_CACHED = 604800; // 1 week /** * Generates the metadata of the SP based on the settings * * @param array $sp The SP data * @param bool|string $authnsign authnRequestsSigned attribute * @param bool|string $wsign wantAssertionsSigned attribute * @param DateTime|null $validUntil Metadata's valid time * @param int|null $cacheDuration Duration of the cache in seconds * @param array $contacts Contacts info * @param array $organization Organization ingo * @param array $attributes * * @return string SAML Metadata XML */ public static function builder($sp, $authnsign = false, $wsign = false, $validUntil = null, $cacheDuration = null, $contacts = array(), $organization = array(), $attributes = array()) { if (!isset($validUntil)) { $validUntil = time() + self::TIME_VALID; } $validUntilTime = OneLogin_Saml2_Utils::parseTime2SAML($validUntil); if (!isset($cacheDuration)) { $cacheDuration = self::TIME_CACHED; } $sls = ''; if (isset($sp['singleLogoutService'])) { $slsUrl = htmlspecialchars($sp['singleLogoutService']['url'], ENT_QUOTES); $sls = <<<SLS_TEMPLATE <md:SingleLogoutService Binding="{$sp['singleLogoutService']['binding']}" Location="{$slsUrl}" /> SLS_TEMPLATE; } if ($authnsign) { $strAuthnsign = 'true'; } else { $strAuthnsign = 'false'; } if ($wsign) { $strWsign = 'true'; } else { $strWsign = 'false'; } $strOrganization = ''; if (!empty($organization)) { $organizationInfoNames = array(); $organizationInfoDisplaynames = array(); $organizationInfoUrls = array(); foreach ($organization as $lang => $info) { $organizationInfoNames[] = <<<ORGANIZATION_NAME <md:OrganizationName xml:lang="{$lang}">{$info['name']}</md:OrganizationName> ORGANIZATION_NAME; $organizationInfoDisplaynames[] = <<<ORGANIZATION_DISPLAY <md:OrganizationDisplayName xml:lang="{$lang}">{$info['displayname']}</md:OrganizationDisplayName> ORGANIZATION_DISPLAY; $organizationInfoUrls[] = <<<ORGANIZATION_URL <md:OrganizationURL xml:lang="{$lang}">{$info['url']}</md:OrganizationURL> ORGANIZATION_URL; } $orgData = implode("\n", $organizationInfoNames)."\n".implode("\n", $organizationInfoDisplaynames)."\n".implode("\n", $organizationInfoUrls); $strOrganization = <<<ORGANIZATIONSTR <md:Organization> {$orgData} </md:Organization> ORGANIZATIONSTR; } $strContacts = ''; if (!empty($contacts)) { $contactsInfo = array(); foreach ($contacts as $type => $info) { $contactsInfo[] = <<<CONTACT <md:ContactPerson contactType="{$type}"> <md:GivenName>{$info['givenName']}</md:GivenName> <md:EmailAddress>{$info['emailAddress']}</md:EmailAddress> </md:ContactPerson> CONTACT; } $strContacts = "\n".implode("\n", $contactsInfo); } $strAttributeConsumingService = ''; if (isset($sp['attributeConsumingService'])) { $attrCsDesc = ''; if (isset($sp['attributeConsumingService']['serviceDescription'])) { $attrCsDesc = sprintf( ' <md:ServiceDescription xml:lang="en">%s</md:ServiceDescription>' . PHP_EOL, $sp['attributeConsumingService']['serviceDescription'] ); } if (!isset($sp['attributeConsumingService']['serviceName'])) { $sp['attributeConsumingService']['serviceName'] = 'Service'; } $requestedAttributeData = array(); foreach ($sp['attributeConsumingService']['requestedAttributes'] as $attribute) { $requestedAttributeStr = sprintf(' <md:RequestedAttribute Name="%s"', $attribute['name']); if (isset($attribute['nameFormat'])) { $requestedAttributeStr .= sprintf(' NameFormat="%s"', $attribute['nameFormat']); } if (isset($attribute['friendlyName'])) { $requestedAttributeStr .= sprintf(' FriendlyName="%s"', $attribute['friendlyName']); } if (isset($attribute['isRequired'])) { $requestedAttributeStr .= sprintf(' isRequired="%s"', $attribute['isRequired'] === true ? 'true' : 'false'); } $reqAttrAuxStr = " />"; if (isset($attribute['attributeValue']) && !empty($attribute['attributeValue'])) { $reqAttrAuxStr = '>'; if (is_string($attribute['attributeValue'])) { $attribute['attributeValue'] = array($attribute['attributeValue']); } foreach ($attribute['attributeValue'] as $attrValue) { $reqAttrAuxStr .=<<<ATTRIBUTEVALUE <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">{$attrValue}</saml:AttributeValue> ATTRIBUTEVALUE; } $reqAttrAuxStr .= "\n </md:RequestedAttribute>"; } $requestedAttributeData[] = $requestedAttributeStr . $reqAttrAuxStr; } $requestedAttributeStr = implode(PHP_EOL, $requestedAttributeData); $strAttributeConsumingService = <<<METADATA_TEMPLATE <md:AttributeConsumingService index="1"> <md:ServiceName xml:lang="en">{$sp['attributeConsumingService']['serviceName']}</md:ServiceName> {$attrCsDesc}{$requestedAttributeStr} </md:AttributeConsumingService> METADATA_TEMPLATE; } $spEntityId = htmlspecialchars($sp['entityId'], ENT_QUOTES); $acsUrl = htmlspecialchars($sp['assertionConsumerService']['url'], ENT_QUOTES); $metadata = <<<METADATA_TEMPLATE <?xml version="1.0"?> <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="{$validUntilTime}" cacheDuration="PT{$cacheDuration}S" entityID="{$spEntityId}"> <md:SPSSODescriptor AuthnRequestsSigned="{$strAuthnsign}" WantAssertionsSigned="{$strWsign}" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> {$sls} <md:NameIDFormat>{$sp['NameIDFormat']}</md:NameIDFormat> <md:AssertionConsumerService Binding="{$sp['assertionConsumerService']['binding']}" Location="{$acsUrl}" index="1" /> {$strAttributeConsumingService} </md:SPSSODescriptor>{$strOrganization}{$strContacts} </md:EntityDescriptor> METADATA_TEMPLATE; return $metadata; } /** * Signs the metadata with the key/cert provided * * @param string $metadata SAML Metadata XML * @param string $key x509 key * @param string $cert x509 cert * @param string $signAlgorithm Signature algorithm method * @param string $digestAlgorithm Digest algorithm method * * @return string Signed Metadata */ public static function signMetadata($metadata, $key, $cert, $signAlgorithm = XMLSecurityKey::RSA_SHA256, $digestAlgorithm = XMLSecurityDSig::SHA256) { return OneLogin_Saml2_Utils::addSign($metadata, $key, $cert, $signAlgorithm, $digestAlgorithm); } /** * Adds the x509 descriptors (sign/encriptation) to the metadata * The same cert will be used for sign/encrypt * * @param string $metadata SAML Metadata XML * @param string $cert x509 cert * @param bool $wantsEncrypted Whether to include the KeyDescriptor for encryption * * @return string Metadata with KeyDescriptors */ public static function addX509KeyDescriptors($metadata, $cert, $wantsEncrypted = true) { $xml = new DOMDocument(); $xml->preserveWhiteSpace = false; $xml->formatOutput = true; try { $xml = OneLogin_Saml2_Utils::loadXML($xml, $metadata); if (!$xml) { throw new Exception('Error parsing metadata'); } } catch (Exception $e) { throw new Exception('Error parsing metadata. '.$e->getMessage()); } $formatedCert = OneLogin_Saml2_Utils::formatCert($cert, false); $x509Certificate = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'X509Certificate', $formatedCert); $keyData = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'ds:X509Data'); $keyData->appendChild($x509Certificate); $keyInfo = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'ds:KeyInfo'); $keyInfo->appendChild($keyData); $keyDescriptor = $xml->createElementNS(OneLogin_Saml2_Constants::NS_MD, "md:KeyDescriptor"); $SPSSODescriptor = $xml->getElementsByTagName('SPSSODescriptor')->item(0); $SPSSODescriptor->insertBefore($keyDescriptor->cloneNode(), $SPSSODescriptor->firstChild); if ($wantsEncrypted === true) { $SPSSODescriptor->insertBefore($keyDescriptor->cloneNode(), $SPSSODescriptor->firstChild); } $signing = $xml->getElementsByTagName('KeyDescriptor')->item(0); $signing->setAttribute('use', 'signing'); $signing->appendChild($keyInfo); if ($wantsEncrypted === true) { $encryption = $xml->getElementsByTagName('KeyDescriptor')->item(1); $encryption->setAttribute('use', 'encryption'); $encryption->appendChild($keyInfo->cloneNode(true)); } return $xml->saveXML(); } }