verifySignature() public method

public verifySignature ( $data, $signature )
Example #1
0
 /**
  * Validate the signature on a HTTP-Redirect message.
  *
  * Throws an exception if we are unable to validate the signature.
  *
  * @param array $data  The data we need to validate the query string.
  * @param XMLSecurityKey $key  The key we should validate the query against.
  */
 public static function validateSignature(array $data, XMLSecurityKey $key)
 {
     assert('array_key_exists("Query", $data)');
     assert('array_key_exists("SigAlg", $data)');
     assert('array_key_exists("Signature", $data)');
     $query = $data['Query'];
     $sigAlg = $data['SigAlg'];
     $signature = $data['Signature'];
     $signature = base64_decode($signature);
     switch ($sigAlg) {
         case XMLSecurityKey::RSA_SHA1:
             if ($key->type !== XMLSecurityKey::RSA_SHA1) {
                 throw new Exception('Invalid key type for validating signature on query string.');
             }
             if (!$key->verifySignature($query, $signature)) {
                 throw new Exception('Unable to validate signature on query string.');
             }
             break;
         default:
             throw new Exception('Unknown signature algorithm: ' . var_export($sigAlg, TRUE));
     }
 }
 public function validateQuery($issuer, $mode = 'SP', $request = 'SAMLRequest')
 {
     $metadataset = 'saml20-idp-remote';
     if ($mode == 'IdP') {
         $metadataset = 'saml20-sp-remote';
     }
     SimpleSAML_Logger::debug('Library - HTTPRedirect validateQuery(): Looking up metadata issuer:' . $issuer . ' in set ' . $metadataset);
     $md = $this->metadata->getMetaData($issuer, $metadataset);
     // check whether to validate or not
     if (!array_key_exists('request.signing', $md) || !$md['request.signing']) {
         return false;
     }
     if (!isset($_GET['Signature'])) {
         throw new Exception('No Signature on the request, required by configuration');
     }
     SimpleSAML_Logger::debug('Library - HTTPRedirect validateQuery(): All required paramaters received.');
     // building query string
     $query = $request . '=' . urlencode($_GET[$request]);
     if ($_GET['RelayState']) {
         $relaystate = $_GET['RelayState'];
         $query .= "&RelayState=" . urlencode($relaystate);
     }
     $algURI = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
     if (isset($_GET['SigAlg']) && $_GET['SigAlg'] != $algURI) {
         throw new Exception('Signature must be rsa-sha1 based');
     }
     $query = $query . "&" . "SigAlg=" . urlencode($algURI);
     SimpleSAML_Logger::debug('Library - HTTPRedirect validateQuery(): Built query: ' . $query);
     SimpleSAML_Logger::debug('Library - HTTPRedirect validateQuery(): Sig Alg: ' . $algURI);
     if (empty($md['certificate'])) {
         throw new Exception('SAML: If you set request.signing to be true in the metadata, you also have to add the certificate parameter.');
     }
     // getting signature from get arguments
     $signature = @base64_decode($_GET['Signature']);
     if (!$signature) {
         throw new Exception('Error base64 decoding signature parameter.');
     }
     // verify signature using xmlseclibs
     $xmlseckey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
     $xmlseckey->loadKey($publickey);
     if (!$xmlseckey->verifySignature($query, $signature)) {
         throw new Exception("Unable to validate Signature");
     }
     //signature ok
     return true;
 }
Example #3
0
 /**
  * Determines if the SAML LogoutResponse is valid
  *
  * @param string $requestId The ID of the LogoutRequest sent by this SP to the IdP
  *
  * @throws Exception
  * @return bool Returns if the SAML LogoutResponse is or not valid
  */
 public function isValid($requestId = null)
 {
     try {
         $idpData = $this->_settings->getIdPData();
         $idPEntityId = $idpData['entityId'];
         if ($this->_settings->isStrict()) {
             $res = OneLogin_Saml2_Utils::validateXML($this->document, 'saml-schema-protocol-2.0.xsd', $this->_settings->isDebugActive());
             if (!$res instanceof DOMDocument) {
                 throw new Exception("Invalid SAML Logout Response. Not match the saml-schema-protocol-2.0.xsd");
             }
             $security = $this->_settings->getSecurityData();
             // Check if the InResponseTo of the Logout Response matchs the ID of the Logout Request (requestId) if provided
             if (isset($requestId) && $this->document->documentElement->hasAttribute('InResponseTo')) {
                 $inResponseTo = $this->document->documentElement->getAttribute('InResponseTo');
                 if ($requestId != $inResponseTo) {
                     throw new Exception("The InResponseTo of the Logout Response: {$inResponseTo}, does not match the ID of the Logout request sent by the SP: {$requestId}");
                 }
             }
             // Check issuer
             $issuer = $this->getIssuer();
             if (empty($issuer) || $issuer != $idPEntityId) {
                 throw new Exception("Invalid issuer in the Logout Request");
             }
             $currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery();
             // Check destination
             if ($this->document->documentElement->hasAttribute('Destination')) {
                 $destination = $this->document->documentElement->getAttribute('Destination');
                 if (!empty($destination)) {
                     if (strpos($destination, $currentURL) === false) {
                         throw new Exception("The LogoutRequest was received at {$currentURL} instead of {$destination}");
                     }
                 }
             }
             if ($security['wantMessagesSigned']) {
                 if (!isset($_GET['Signature'])) {
                     throw new Exception("The Message of the Logout Response is not signed and the SP requires it");
                 }
             }
         }
         if (isset($_GET['Signature'])) {
             if (!isset($_GET['SigAlg'])) {
                 $signAlg = XMLSecurityKey::RSA_SHA1;
             } else {
                 $signAlg = $_GET['SigAlg'];
             }
             if ($signAlg != XMLSecurityKey::RSA_SHA1) {
                 throw new Exception('Invalid signAlg in the recieved Logout Response');
             }
             $signedQuery = 'SAMLResponse=' . urlencode($_GET['SAMLResponse']);
             if (isset($_GET['RelayState'])) {
                 $signedQuery .= '&RelayState=' . urlencode($_GET['RelayState']);
             }
             $signedQuery .= '&SigAlg=' . urlencode($signAlg);
             if (!isset($idpData['x509cert']) || empty($idpData['x509cert'])) {
                 throw new Exception('In order to validate the sign on the Logout Response, the x509cert of the IdP is required');
             }
             $cert = $idpData['x509cert'];
             $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
             $objKey->loadKey($cert, false, true);
             if (!$objKey->verifySignature($signedQuery, base64_decode($_GET['Signature']))) {
                 throw new Exception('Signature validation failed. Logout Response rejected');
             }
         }
         return true;
     } catch (Exception $e) {
         $debug = $this->_settings->isDebugActive();
         if ($debug) {
             echo $e->getMessage();
         }
         return false;
     }
 }
Example #4
0
 /**
  * Checks if the Logout Request recieved is valid.
  *
  * @param OneLogin_Saml2_Settings $settings Settings
  * @param string|DOMDocument      $request  Logout Request decoded
  *
  * @return boolean If the Logout Request is or not valid
  */
 public static function isValid(OneLogin_Saml2_Settings $settings, $request, $debug = false)
 {
     try {
         if ($request instanceof DOMDocument) {
             $dom = $request;
         } else {
             $dom = new DOMDocument();
             $dom = OneLogin_Saml2_Utils::loadXML($dom, $request);
         }
         $idpData = $settings->getIdPData();
         $idPEntityId = $idpData['entityId'];
         if ($settings->isStrict()) {
             $res = OneLogin_Saml2_Utils::validateXML($dom, 'saml-schema-protocol-2.0.xsd', $debug);
             if (!$res instanceof DOMDocument) {
                 throw new Exception("Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd");
             }
             $security = $settings->getSecurityData();
             $currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery();
             // Check NotOnOrAfter
             if ($dom->documentElement->hasAttribute('NotOnOrAfter')) {
                 $na = OneLogin_Saml2_Utils::parseSAML2Time($dom->documentElement->getAttribute('NotOnOrAfter'));
                 if ($na <= time()) {
                     throw new Exception('Timing issues (please check your clock settings)');
                 }
             }
             // Check destination
             if ($dom->documentElement->hasAttribute('Destination')) {
                 $destination = $dom->documentElement->getAttribute('Destination');
                 if (!empty($destination)) {
                     if (strpos($destination, $currentURL) === false) {
                         throw new Exception("The LogoutRequest was received at {$currentURL} instead of {$destination}");
                     }
                 }
             }
             $nameId = self::getNameId($dom);
             // Check issuer
             $issuer = self::getIssuer($dom);
             if (empty($issuer) || $issuer != $idPEntityId) {
                 throw new Exception("Invalid issuer in the Logout Request");
             }
             if ($security['wantMessagesSigned']) {
                 if (!isset($_GET['Signature'])) {
                     throw new Exception("The Message of the Logout Request is not signed and the SP require it");
                 }
             }
         }
         if (isset($_GET['Signature'])) {
             if (!isset($_GET['SigAlg'])) {
                 $signAlg = XMLSecurityKey::RSA_SHA1;
             } else {
                 $signAlg = $_GET['SigAlg'];
             }
             if ($signAlg != XMLSecurityKey::RSA_SHA1) {
                 throw new Exception('Invalid signAlg in the recieved Logout Request');
             }
             $signedQuery = 'SAMLRequest=' . urlencode($_GET['SAMLRequest']);
             if (isset($_GET['RelayState'])) {
                 $signedQuery .= '&RelayState=' . urlencode($_GET['RelayState']);
             }
             $signedQuery .= '&SigAlg=' . urlencode($signAlg);
             if (!isset($idpData['x509cert']) || empty($idpData['x509cert'])) {
                 throw new Exception('In order to validate the sign on the Logout Request, the x509cert of the IdP is required');
             }
             $cert = $idpData['x509cert'];
             $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
             $objKey->loadKey($cert, false, true);
             if (!$objKey->verifySignature($signedQuery, base64_decode($_GET['Signature']))) {
                 throw new Exception('Signature validation failed. Logout Request rejected');
             }
         }
         return true;
     } catch (Exception $e) {
         $debug = $settings->isDebugActive();
         if ($debug) {
             echo $e->getMessage();
         }
         return false;
     }
 }