diff --git a/lib/SAML2/SOAPClient.php b/lib/SAML2/SOAPClient.php index 773ab9a689c9bb1eb553732983a2347d58ac39c4..b9655c7750a9061ed6e8c27ad840d897561f6538 100644 --- a/lib/SAML2/SOAPClient.php +++ b/lib/SAML2/SOAPClient.php @@ -16,9 +16,10 @@ class SAML2_SOAPClient { * * @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) { + public function send(SAML2_Message $msg, SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata = NULL) { $issuer = $msg->getIssuer(); @@ -50,6 +51,40 @@ class SAML2_SOAPClient { } } + // do peer certificate verification + if ($dstMetadata !== NULL) { + $peerPublicKey = SimpleSAML_Utilities::loadPublicKey($dstMetadata); + if ($peerPublicKey !== NULL) { + $certData = $peerPublicKey['PEM']; + $peerCertFile = SimpleSAML_Utilities::getTempDir() . '/' . sha1($certData) . '.pem'; + if (!file_exists($peerCertFile)) { + SimpleSAML_Utilities::writeFile($peerCertFile, $certData); + } + // create ssl context + $ctxOpts = array( + 'ssl' => array( + 'verify_peer' => TRUE, + 'verify_depth' => 1, + 'cafile' => $peerCertFile + )); + if (isset($options['local_cert'])) { + $ctxOpts['ssl']['local_cert'] = $options['local_cert']; + unset($options['local_cert']); + } + if (isset($options['passhprase'])) { + $ctxOpts['ssl']['passphrase'] = $options['passphrase']; + unset($options['passphrase']); + } + $context = stream_context_create($ctxOpts); + if ($context === NULL) { + throw new Exception('Unable to create SSL stream context'); + } + $options['stream_context'] = $context; + } else { + throw new Exception('IdP metadata was supplied, but no certData present'); + } + } + $x = new SoapClient(NULL, $options); // Add soap-envelopes @@ -63,7 +98,9 @@ class SAML2_SOAPClient { /* 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.'); + } // Convert to SAML2_Message (DOMElement) $dom = new DOMDocument();