summaryrefslogtreecommitdiffstats
path: root/lib/SAML2/SOAPClient.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/SAML2/SOAPClient.php')
-rw-r--r--lib/SAML2/SOAPClient.php223
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;
- }
-
-}