diff options
Diffstat (limited to 'lib/SAML2/SOAPClient.php')
-rw-r--r-- | lib/SAML2/SOAPClient.php | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/lib/SAML2/SOAPClient.php b/lib/SAML2/SOAPClient.php deleted file mode 100644 index 0ba6ebe..0000000 --- a/lib/SAML2/SOAPClient.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php -/** - * Implementation of the SAML 2.0 SOAP binding. - * - * @author Shoaib Ali - * @package simpleSAMLphp - * @version $Id$ - */ -class SAML2_SOAPClient { - - const START_SOAP_ENVELOPE = '<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header/><soap-env:Body>'; - const END_SOAP_ENVELOPE = '</soap-env:Body></soap-env:Envelope>'; - - /** - * This function sends the SOAP message to the service location and returns SOAP response - * - * @param SAML2_Message $m The request that should be sent. - * @param SimpleSAML_Configuration $srcMetadata The metadata of the issuer of the message. - * @param SimpleSAML_Configuration $dstMetadata The metadata of the destination of the message. - * @return SAML2_Message The response we received. - */ - public function send(SAML2_Message $msg, SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata = NULL) { - - $issuer = $msg->getIssuer(); - - $ctxOpts = array( - 'ssl' => array( - 'capture_peer_cert' => TRUE, - ), - ); - - // Determine if we are going to do a MutualSSL connection between the IdP and SP - Shoaib - if ($srcMetadata->hasValue('saml.SOAPClient.certificate')) { - $cert = $srcMetadata->getValue('saml.SOAPClient.certificate'); - if ($cert !== FALSE) { - $ctxOpts['ssl']['local_cert'] = SimpleSAML_Utilities::resolveCert($srcMetadata->getString('saml.SOAPClient.certificate')); - if ($srcMetadata->hasValue('saml.SOAPClient.privatekey_pass')) { - $ctxOpts['ssl']['passphrase'] = $srcMetadata->getString('saml.SOAPClient.privatekey_pass'); - } - } - } else { - /* Use the SP certificate and privatekey if it is configured. */ - $privateKey = SimpleSAML_Utilities::loadPrivateKey($srcMetadata); - $publicKey = SimpleSAML_Utilities::loadPublicKey($srcMetadata); - if ($privateKey !== NULL && $publicKey !== NULL && isset($publicKey['PEM'])) { - $keyCertData = $privateKey['PEM'] . $publicKey['PEM']; - $file = SimpleSAML_Utilities::getTempDir() . '/' . sha1($keyCertData) . '.pem'; - if (!file_exists($file)) { - SimpleSAML_Utilities::writeFile($file, $keyCertData); - } - $ctxOpts['ssl']['local_cert'] = $file; - if (isset($privateKey['password'])) { - $ctxOpts['ssl']['passphrase'] = $privateKey['password']; - } - } - } - - // do peer certificate verification - if ($dstMetadata !== NULL) { - $peerPublicKeys = $dstMetadata->getPublicKeys('signing', TRUE); - $certData = ''; - foreach ($peerPublicKeys as $key) { - if ($key['type'] !== 'X509Certificate') { - continue; - } - $certData .= "-----BEGIN CERTIFICATE-----\n" . - chunk_split($key['X509Certificate'], 64) . - "-----END CERTIFICATE-----\n"; - } - $peerCertFile = SimpleSAML_Utilities::getTempDir() . '/' . sha1($certData) . '.pem'; - if (!file_exists($peerCertFile)) { - SimpleSAML_Utilities::writeFile($peerCertFile, $certData); - } - // create ssl context - $ctxOpts['ssl']['verify_peer'] = TRUE; - $ctxOpts['ssl']['verify_depth'] = 1; - $ctxOpts['ssl']['cafile'] = $peerCertFile; - } - - $context = stream_context_create($ctxOpts); - if ($context === NULL) { - throw new Exception('Unable to create SSL stream context'); - } - - $options = array( - 'uri' => $issuer, - 'location' => $msg->getDestination(), - 'stream_context' => $context, - ); - - $x = new SoapClient(NULL, $options); - - // Add soap-envelopes - $request = $msg->toSignedXML(); - $request = self::START_SOAP_ENVELOPE . $request->ownerDocument->saveXML($request) . self::END_SOAP_ENVELOPE; - - SimpleSAML_Utilities::debugMessage($request, 'out'); - - $action = 'http://www.oasis-open.org/committees/security'; - $version = '1.1'; - $destination = $msg->getDestination(); - - - /* Perform SOAP Request over HTTP */ - $soapresponsexml = $x->__doRequest($request, $destination, $action, $version); - if ($soapresponsexml === NULL || $soapresponsexml === "") { - throw new Exception('Empty SOAP response, check peer certificate.'); - } - - SimpleSAML_Utilities::debugMessage($soapresponsexml, 'in'); - - // Convert to SAML2_Message (DOMElement) - $dom = new DOMDocument(); - if (!$dom->loadXML($soapresponsexml)) { - throw new Exception('Not a SOAP response.'); - } - - $soapfault = $this->getSOAPFault($dom); - if (isset($soapfault)) { - throw new Exception($soapfault); - } - //Extract the message from the response - $xml = $dom->firstChild; /* Soap Envelope */ - $samlresponse = SAML2_Utils::xpQuery($dom->firstChild, '/soap-env:Envelope/soap-env:Body/*[1]'); - $samlresponse = SAML2_Message::fromXML($samlresponse[0]); - - /* Add validator to message which uses the SSL context. */ - self::addSSLValidator($samlresponse, $context); - - SimpleSAML_Logger::debug("Valid ArtifactResponse received from IdP"); - - return $samlresponse; - - } - - - /** - * Add a signature validator based on a SSL context. - * - * @param SAML2_Message $msg The message we should add a validator to. - * @param resource $context The stream context. - */ - private static function addSSLValidator(SAML2_Message $msg, $context) { - $options = stream_context_get_options($context); - if (!isset($options['ssl']['peer_certificate'])) { - return; - } - - //$out = ''; - //openssl_x509_export($options['ssl']['peer_certificate'], $out); - - $key = openssl_pkey_get_public($options['ssl']['peer_certificate']); - if ($key === FALSE) { - SimpleSAML_Logger::warning('Unable to get public key from peer certificate.'); - return; - } - - $keyInfo = openssl_pkey_get_details($key); - if ($keyInfo === FALSE) { - SimpleSAML_Logger::warning('Unable to get key details from public key.'); - return; - } - - if (!isset($keyInfo['key'])) { - SimpleSAML_Logger::warning('Missing key in public key details.'); - return; - } - - $msg->addValidator(array('SAML2_SOAPClient', 'validateSSL'), $keyInfo['key']); - } - - - /** - * Validate a SOAP message against the certificate on the SSL connection. - * - * @param string $data The public key that was used on the connection. - * @param XMLSecurityKey $key The key we should validate the certificate against. - */ - public static function validateSSL($data, XMLSecurityKey $key) { - assert('is_string($data)'); - - $keyInfo = openssl_pkey_get_details($key->key); - if ($keyInfo === FALSE) { - throw new Exception('Unable to get key details from XMLSecurityKey.'); - } - - if (!isset($keyInfo['key'])) { - throw new Exception('Missing key in public key details.'); - } - - if ($keyInfo['key'] !== $data) { - SimpleSAML_Logger::debug('Key on SSL connection did not match key we validated against.'); - return FALSE; - } - - SimpleSAML_Logger::debug('Message validated based on SSL certificate.'); - } - - - /* - * Extracts the SOAP Fault from SOAP message - * @param $soapmessage Soap response needs to be type DOMDocument - * @return $soapfaultstring string|NULL - */ - private function getSOAPFault($soapmessage) { - - $soapfault = SAML2_Utils::xpQuery($soapmessage->firstChild, '/soap-env:Envelope/soap-env:Body/soap-env:Fault'); - - if (empty($soapfault)) { - /* No fault. */ - return NULL; - } - $soapfaultelement = $soapfault[0]; - $soapfaultstring = "Unknown fault string found"; // There is a fault element but we havn't found out what the fault string is - // find out the fault string - $faultstringelement = SAML2_Utils::xpQuery($soapfaultelement, './soap-env:faultstring') ; - if (!empty($faultstringelement)) { - return $faultstringelement[0]->textContent; - } - return $soapfaultstring; - } - -} |