/** * @param \DOMNode $parent * @param \AerialShip\LightSaml\Meta\SerializationContext $context * @return \DOMNode */ function getXml(\DOMNode $parent, SerializationContext $context) { $objXMLSecDSig = new \XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod($this->getCanonicalMethod()); $key = $this->getXmlSecurityKey(); switch ($key->type) { case \XMLSecurityKey::RSA_SHA256: $type = \XMLSecurityDSig::SHA256; break; case \XMLSecurityKey::RSA_SHA384: $type = \XMLSecurityDSig::SHA384; break; case \XMLSecurityKey::RSA_SHA512: $type = \XMLSecurityDSig::SHA512; break; default: $type = \XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($parent), $type, array(Protocol::XMLSEC_TRANSFORM_ALGORITHM_ENVELOPED_SIGNATURE, \XMLSecurityDSig::EXC_C14N), array('id_name' => $this->getIDName(), 'overwrite' => FALSE)); $objXMLSecDSig->sign($key); $objXMLSecDSig->add509Cert($this->getCertificate()->getData(), false, false); $firstChild = $parent->hasChildNodes() ? $parent->firstChild : null; if ($firstChild && $firstChild->localName == 'Issuer') { // The signature node should come after the issuer node $firstChild = $firstChild->nextSibling; } $objXMLSecDSig->insertSignature($parent, $firstChild); }
/** * Adds signature key and senders certificate to an element (Message or Assertion). * * @param string|DomDocument $xml The element we should sign * @param string $key The private key * @param string $cert The public */ public static function addSign($xml, $key, $cert) { if ($xml instanceof DOMDocument) { $dom = $xml; } else { $dom = new DOMDocument(); $dom = self::loadXML($dom, $xml); if (!$dom) { throw new Exception('Error parsing xml string'); } } /* Load the private key. */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($key, false); /* Get the EntityDescriptor node we should sign. */ $rootNode = $dom->firstChild; /* Sign the metadata with our private key. */ $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($rootNode), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($objKey); /* Add the certificate to the signature. */ $objXMLSecDSig->add509Cert($cert, true); $insertBefore = $rootNode->firstChild; $messageTypes = array('samlp:AuthnRequest', 'samlp:Response', 'samlp:LogoutRequest', 'samlp:LogoutResponse'); if (in_array($rootNode->tagName, $messageTypes)) { $issuerNodes = self::query($dom, '/' . $rootNode->tagName . '/saml:Issuer'); if ($issuerNodes->length == 1) { $insertBefore = $issuerNodes->item(0)->nextSibling; } } /* Add the signature. */ $objXMLSecDSig->insertSignature($rootNode, $insertBefore); /* Return the DOM tree as a string. */ $signedxml = $dom->saveXML(); return $signedxml; }
/** * Insert a Signature-node. * * @param XMLSecurityKey $key The key we should use to sign the message. * @param array $certificates The certificates we should add to the signature node. * @param DOMElement $root The XML node we should sign. * @param DOMNode $insertBefore The XML element we should insert the signature element before. */ public static function insertSignature(XMLSecurityKey $key, array $certificates, DOMElement $root, DOMNode $insertBefore = NULL) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); switch ($key->type) { case XMLSecurityKey::RSA_SHA256: $type = XMLSecurityDSig::SHA256; break; case XMLSecurityKey::RSA_SHA384: $type = XMLSecurityDSig::SHA384; break; case XMLSecurityKey::RSA_SHA512: $type = XMLSecurityDSig::SHA512; break; default: $type = XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($root), $type, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID', 'overwrite' => FALSE)); $objXMLSecDSig->sign($key); foreach ($certificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($root, $insertBefore); }
/** * Signs the given metadata if metadata signing is enabled. * * @param string $metadataString A string with the metadata. * @param array $entityMetadata The metadata of the entity. * @param string $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or 'Shib 1.3 SP'. * * @return string The $metadataString with the signature embedded. * @throws Exception If the certificate or private key cannot be loaded, or the metadata doesn't parse properly. */ public static function sign($metadataString, $entityMetadata, $type) { $config = SimpleSAML_Configuration::getInstance(); // check if metadata signing is enabled if (!self::isMetadataSigningEnabled($config, $entityMetadata, $type)) { return $metadataString; } // find the key & certificate which should be used to sign the metadata $keyCertFiles = self::findKeyCert($config, $entityMetadata, $type); $keyFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['privatekey']); if (!file_exists($keyFile)) { throw new Exception('Could not find private key file [' . $keyFile . '], which is needed to sign the metadata'); } $keyData = file_get_contents($keyFile); $certFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['certificate']); if (!file_exists($certFile)) { throw new Exception('Could not find certificate file [' . $certFile . '], which is needed to sign the metadata'); } $certData = file_get_contents($certFile); // convert the metadata to a DOM tree try { $xml = SAML2_DOMDocumentFactory::fromString($metadataString); } catch (Exception $e) { throw new Exception('Error parsing self-generated metadata.'); } // load the private key $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); if (array_key_exists('privatekey_pass', $keyCertFiles)) { $objKey->passphrase = $keyCertFiles['privatekey_pass']; } $objKey->loadKey($keyData, false); // get the EntityDescriptor node we should sign $rootNode = $xml->firstChild; // sign the metadata with our private key if ($type == 'ADFS IdP') { $objXMLSecDSig = new sspmod_adfs_XMLSecurityDSig($metadataString); } else { $objXMLSecDSig = new XMLSecurityDSig(); } $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($rootNode), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($objKey); // add the certificate to the signature $objXMLSecDSig->add509Cert($certData, true); // add the signature to the metadata $objXMLSecDSig->insertSignature($rootNode, $rootNode->firstChild); // return the DOM tree as a string return $xml->saveXML(); }
public static function PrepSAMLAssertion(&$saml_xml_request) { // // Gather inputs needed during assembly of SAML Assertion (e.g., keys, certs, timestamps, IDs_ // $DateTimeNow = new DateTime(null, new DateTimeZone("UTC")); $DateTimeNowString = $DateTimeNow->format("Y-m-d\\TH:i:s.B\\Z"); $DateTime15Min = new DateTime(null, new DateTimeZone("UTC")); $DateTime15Min->modify('+900 sec'); $DateTime15MinString = $DateTime15Min->format("Y-m-d\\TH:i:s.B\\Z"); $SAMLParams = array(); $SAMLParams['IssueInstant'] = $DateTimeNowString; $SAMLParams['Issuer'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['ID'] = SimpleSAML_Utilities::generateID(); $SAMLParams['NameID'] = SAML_NAME_ID; $SAMLParams['NotBefore'] = $DateTimeNowString; $SAMLParams['NotOnOrAfter'] = $DateTime15MinString; $SAMLParams['AuthnInstant'] = $DateTimeNowString; $SAMLParams['Audience'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['x509'] = file_get_contents(SAML_X509_CERT_PATH); $SAMLParams['private_key'] = file_get_contents(SAML_X509_PRIVATE_KEY_PATH); // // Assemble DOM containing correct SAML assertion // $xml = new DOMDocument('1.0', 'utf-8'); // Assertion $assertion = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion', 'saml2:Assertion'); $assertion->setAttribute('ID', $SAMLParams['ID']); $assertion->setAttribute('Version', '2.0'); $assertion->setAttribute('IssueInstant', $SAMLParams['IssueInstant']); $xml->appendChild($assertion); // Issuer $issuer = $xml->createElement('saml2:Issuer', $SAMLParams['Issuer']); $assertion->appendChild($issuer); // Subject + NameID + SubjectConfirmation $subject = $xml->createElement('saml2:Subject'); $assertion->appendChild($subject); // NameID $nameid = $xml->createElement('saml2:NameID', $SAMLParams['NameID']); $nameid->setAttribute('Format', 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'); $subject->appendChild($nameid); // SubjectConfirmation $confirmation = $xml->createElement('saml2:SubjectConfirmation'); $confirmation->setAttribute('Method', 'urn:oasis:names:tc:SAML:2.0:cm:bearer'); $subject->appendChild($confirmation); // Conditions + AudienceRestriction + Audience $condition = $xml->createElement('saml2:Conditions'); $condition->setAttribute('NotBefore', $SAMLParams['NotBefore']); $condition->setAttribute('NotOnOrAfter', $SAMLParams['NotOnOrAfter']); $assertion->appendChild($condition); // AudienceRestriction $audiencer = $xml->createElement('saml2:AudienceRestriction'); $condition->appendChild($audiencer); // Audience $audience = $xml->createElement('saml2:Audience', $SAMLParams['Audience']); $audiencer->appendChild($audience); // AuthnStatement + AuthnContext + AuthnContextClassRef $authnstat = $xml->createElement('saml2:AuthnStatement'); $authnstat->setAttribute('AuthnInstant', $SAMLParams['AuthnInstant']); $authnstat->setAttribute('SessionIndex', $SAMLParams['ID']); $assertion->appendChild($authnstat); // AuthnContext $authncontext = $xml->createElement('saml2:AuthnContext'); $authnstat->appendChild($authncontext); // AuthnContextClassRef $authncontext_ref = $xml->createElement('saml2:AuthnContextClassRef', 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified'); $authncontext->appendChild($authncontext_ref); //Private KEY $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($SAMLParams['private_key']); //Sign the Assertion $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($assertion), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('URI' => 'ID', 'overwrite' => false, 'id_name' => 'ID')); $objXMLSecDSig->sign($objKey); $objXMLSecDSig->add509Cert($SAMLParams['x509']); $objXMLSecDSig->insertSignature($assertion, $subject); $saml = $xml->saveXML(); // // Change Reference URI locally (considered changing 'xmlseclibs.php', but // that seemed inappropriate) // preg_match("/<ds:Reference URI=\"#(.+?)\">/is", $saml, $URI); $saml = str_replace("Id=\"" . $URI[1] . "\"", "", $saml); $saml = str_replace($URI[1], $SAMLParams["ID"], $saml); // // Prepare Base64-Encoded SAML Assertion request body based on DOM // $saml = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $saml); $saml_xml_request = base64_encode(stripslashes($saml)); }
public static function ADFS_SignResponse($response, $key, $cert) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('AssertionID'); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $responsedom = new DOMDocument(); $responsedom->loadXML(str_replace("\r", "", $response)); $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'AssertionID')); $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($key, TRUE); $objXMLSecDSig->sign($objKey); if ($cert) { $public_cert = file_get_contents($cert); $objXMLSecDSig->add509Cert($public_cert, TRUE); } $newSig = $responsedom->importNode($objXMLSecDSig->sigNode, TRUE); $firstassertionroot->appendChild($newSig); return $responsedom->saveXML(); }
function processDocument() { global $src_file, $target_file, $user_pubkey_file_path, $user_cert_file_path; require dirname(__FILE__) . '/xmlseclibs.php'; if (file_exists($target_file)) { unlink($target_file); } $doc = new DOMDocument(); $doc->load($src_file); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); /* gako pribatu bat behar dugu prozesua burutzeko. orain edozein erabiliko dugu. gero txartelekoarekin ordezkatzeko */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objKey->loadKey(dirname(__FILE__) . '/privkey.pem', TRUE); $objDSig->sign($objKey); /* Add associated public key */ // $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/mycert.pem')); // $objDSig->add509Cert(file_get_contents($user_cert_file_path)); if (!file_exists($user_cert_file_path)) { debug('File not found', $user_cert_file_path); } else { $objDSig->add509Cert($user_cert_file_path); } $objDSig->appendSignature($doc->documentElement); $doc->save($target_file); }
/** * @dataProvider testXmlSignProvider * @throws \Exception */ public function testXmlSign($dsigAlgorithm, $keyType, $expectedFileName) { $doc = new \DOMDocument(); $doc->load(dirname(__FILE__) . '/../basic-doc.xml'); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, $dsigAlgorithm, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); $objKey = new XMLSecurityKey($keyType, array('type' => 'private')); /* load private key */ $objKey->loadKey(dirname(__FILE__) . '/../privkey.pem', true); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objDSig->sign($objKey); /* Add associated public key */ $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/../mycert.pem')); $objDSig->appendSignature($doc->documentElement); $sign_output = $doc->saveXML(); $sign_output_def = file_get_contents($expectedFileName); $this->assertEquals($sign_output_def, $sign_output, "Signature doesn't match"); }
/** * Insert a Signature-node. * * @param XMLSecurityKey $key The key we should use to sign the message. * @param array $certificates The certificates we should add to the signature node. * @param DOMElement $root The XML node we should sign. * @param DomElement $insertBefore The XML element we should insert the signature element before. */ public static function insertSignature(XMLSecurityKey $key, array $certificates, DOMElement $root, DOMNode $insertBefore = NULL) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($root), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($key); foreach ($certificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($root, $insertBefore); }
/** * Signs the given DOMElement and inserts the signature at the given position. * * The private key must be set before calling this function. * * @param $node The DOMElement we should generate a signature for. * @param $insertInto The DOMElement we should insert the signature element into. * @param $insertBefore The element we should insert the signature element before. Defaults to NULL, * in which case the signature will be appended to the element spesified in * $insertInto. */ public function sign($node, $insertInto, $insertBefore = NULL) { assert('$node instanceof DOMElement'); assert('$insertInto instanceof DOMElement'); assert('is_null($insertBefore) || $insertBefore instanceof DOMElement ' . '|| $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText'); if ($this->privateKey === FALSE) { throw new Exception('Private key not set.'); } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $options = array(); if ($this->idAttrName !== FALSE) { $options['id_name'] = $this->idAttrName; } $objXMLSecDSig->addReferenceList(array($node), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), $options); $objXMLSecDSig->sign($this->privateKey); if ($this->certificate !== FALSE) { // Add the certificate to the signature $objXMLSecDSig->add509Cert($this->certificate, TRUE); } // Add extra certificates foreach ($this->extraCertificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($insertInto, $insertBefore); }
$doc->load($dir); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); /* gako pribatu bat behar dugu prozesua burutzeko. orain edozein erabiliko dugu. gero txartelekoarekin ordezkatzeko */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objKey->loadKey(dirname(__FILE__) . '/privkey.pem', TRUE); $objDSig->sign($objKey); /* Add associated public key */ // $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/mycert.pem')); // $objDSig->add509Cert(file_get_contents($user_cert_file_path)); if (!file_exists($user_cert_file_path)) { die('File not found : ' . $user_cert_file_path); } else { $objDSig->add509Cert($user_cert_file_path); } $objDSig->appendSignature($doc->documentElement); $doc->save($target_file); ?> <h3>Por favor, apriete el botón "Enviar" para acabar con el registro del fichero en la Agencia de Proteccion de datos</h3> <?php echo '<form id="formMyFirma" name="formMyFirma" method="post" onsubmit="document.getElementById(\'sinatuta\').value = signDigest(document.getElementById(\'sinatzeko\').value);" action="' . str_replace("http://", "https://", UsuarioPeer::getRuta()) . '/notificaciones/enviar/id_notificacion/' . $notificacion->notid . '/id_fichero/' . $notificacion->id_fichero . '/yafirmado/1">'; echo '<input type="hidden" id="sinatzeko" name="sinatzeko" value="' . trim(strip_tags(_CANON_DATA)) . '">'; echo '<input type="hidden" id="sinatuta" name="sinatuta" value="">'; //echo '<input onclick="document.getElementById(\'sinatuta\').value = signDigest(document.getElementById(\'sinatzeko\').value);" value="Firmar documento con tarjeta" type="button"><br />'; echo '<input type="submit" name="submit" value="Enviar" /><br />'; echo '</form>'; echo '<script type="text/javascript">'; echo '/*document.getElementById(\'sinatuta\').value = signDigest(document.getElementById(\'sinatzeko\').value);*/';
/** * Signs the given metadata if metadata signing is enabled. * * @param $metadataString A string with the metadata. * @param $entityMetadata The metadata of the entity. * @param $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or 'Shib 1.3 SP'. * @return The $metadataString with the signature embedded. */ public static function sign($metadataString, $entityMetadata, $type) { $config = SimpleSAML_Configuration::getInstance(); /* Check if metadata signing is enabled. */ if (!self::isMetadataSigningEnabled($config, $entityMetadata, $type)) { return $metadataString; } /* Find the key & certificate which should be used to sign the metadata. */ $keyCertFiles = self::findKeyCert($config, $entityMetadata, $type); $keyFile = $config->getPathValue('certdir', 'cert/') . $keyCertFiles['privatekey']; if (!file_exists($keyFile)) { throw new Exception('Could not find private key file [' . $keyFile . '], which is needed to sign the metadata'); } $keyData = file_get_contents($keyFile); $certFile = $config->getPathValue('certdir', 'cert/') . $keyCertFiles['certificate']; if (!file_exists($certFile)) { throw new Exception('Could not find certificate file [' . $certFile . '], which is needed to sign the metadata'); } $certData = file_get_contents($certFile); /* Convert the metadata to a DOM tree. */ $xml = new DOMDocument(); if (!$xml->loadXML($metadataString)) { throw new Exception('Error parsing self-generated metadata.'); } /* Load the private key. */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); if (array_key_exists('privatekey_pass', $keyCertFiles)) { $objKey->passphrase = $keyCertFiles['privatekey_pass']; } $objKey->loadKey($keyData, FALSE); /* Get the EntityDescriptor node we should sign. */ $rootNode = $xml->firstChild; /* Sign the metadata with our private key. */ $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($rootNode), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($objKey); /* Add the certificate to the signature. */ $objXMLSecDSig->add509Cert($certData, true); /* Add the signature to the metadata. */ $objXMLSecDSig->insertSignature($rootNode, $rootNode->firstChild); /* Return the DOM tree as a string. */ return $xml->saveXML(); }
public function sendResponse($response, $idmetaindex, $spentityid, $relayState = null) { $idpmd = $this->metadata->getMetaData($idmetaindex, 'saml20-idp-hosted'); $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote'); $destination = $spmd['AssertionConsumerService']; if (empty($idpmd['privatekey'])) { throw new Exception('SAML: RSA private key not configured. This is required to sign the authentication response.'); } if (empty($idpmd['certificate'])) { throw new Exception('SAML: X.509 certificate not configured. This is required to attach to the authentication response.'); } // XMLDSig. Sign the complete request with the key stored in cert/server.pem $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); try { $responsedom = new DOMDocument(); $responsedom->loadXML(str_replace("\n", "", str_replace("\r", "", $response))); } catch (Exception $e) { throw new Exception("foo"); } $responseroot = $responsedom->getElementsByTagName('Response')->item(0); $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); /* Determine what we should sign - either the Response element or the Assertion. The default * is to sign the Assertion, but that can be overridden by the 'signresponse' option in the * SP metadata or 'saml20.signresponse' in the global configuration. */ $signResponse = FALSE; if (array_key_exists('signresponse', $spmd) && $spmd['signresponse'] !== NULL) { $signResponse = $spmd['signresponse']; if (!is_bool($signResponse)) { throw new Exception('Expected the \'signresponse\' option in the metadata of the' . ' SP \'' . $spmd['entityid'] . '\' to be a boolean value.'); } } else { $signResponse = $this->configuration->getBoolean('saml20.signresponse', FALSE); } if ($signResponse) { // Sign the response. $objXMLSecDSig->addReferenceList(array($responseroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); } else { // Sign the assertion. $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); } $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); if (array_key_exists('privatekey_pass', $idpmd)) { $objKey->passphrase = $idpmd['privatekey_pass']; } $objKey->loadKey($idpmd['privatekey']); $objXMLSecDSig->sign($objKey); $objXMLSecDSig->add509Cert($idpmd['certificate'], true); if ($signResponse) { $objXMLSecDSig->appendSignature($responseroot, true, false); } else { $objXMLSecDSig->appendSignature($firstassertionroot, true, true); } if (isset($spmd['assertion.encryption']) && $spmd['assertion.encryption']) { $encryptedassertion = $responsedom->createElement("saml:EncryptedAssertion"); $encryptedassertion->setAttribute("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion"); $firstassertionroot->parentNode->replaceChild($encryptedassertion, $firstassertionroot); $encryptedassertion->appendChild($firstassertionroot); $enc = new XMLSecEnc(); $enc->setNode($firstassertionroot); $enc->type = XMLSecEnc::Element; $objKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC); if (isset($spmd['sharedkey'])) { $objKey->loadkey($spmd['sharedkey']); } else { $key = $objKey->generateSessionKey(); $objKey->loadKey($key); if (empty($spmd['certificate'])) { throw new Exception("Public key for encrypting assertion needed, but not specified for saml20-sp-remote id: " . $spentityid); } $keyKey = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, array('type' => 'public')); $keyKey->loadKey($spmd['certificate']); $enc->encryptKey($keyKey, $objKey); } $encNode = $enc->encryptNode($objKey); # replacing the unencrypted node } $response = $responsedom->saveXML(); SimpleSAML_Utilities::validateXMLDocument($response, 'saml20'); # openssl genrsa -des3 -out server.key 1024 # openssl rsa -in server.key -out server.pem # openssl req -new -key server.key -out server.csr # openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt if ($this->configuration->getValue('debug')) { $p = new SimpleSAML_XHTML_Template($this->configuration, 'post-debug.php'); $p->data['header'] = 'SAML Response Debug-mode'; $p->data['RelayStateName'] = 'RelayState'; $p->data['RelayState'] = $relayState; $p->data['destination'] = $destination; $p->data['response'] = str_replace("\n", "", base64_encode($response)); $p->data['responseHTML'] = htmlentities($responsedom->saveHTML()); $p->show(); } else { $p = new SimpleSAML_XHTML_Template($this->configuration, 'post.php'); $p->data['RelayStateName'] = 'RelayState'; $p->data['RelayState'] = $relayState; $p->data['destination'] = $destination; $p->data['response'] = base64_encode($response); $p->show(); } }