public function testVerifyDocumentSha256() { $doc = new DOMDocument(); $doc->load($this->fixturesDir . '/DSig/sign_document_sha256_result.xml'); $signature = DSig::locateSignature($doc); $this->assertInstanceOf('\\DOMElement', $signature, 'Signature element'); $this->assertTrue(DSig::verifyReferences($signature), 'Verify references'); $this->assertTrue(DSig::verifyDocumentSignature($signature), 'Verify signature'); }
/** * Modify the given request XML. * * @param \BeSimple\SoapCommon\SoapRequest $request SOAP request * * @return void */ public function filterRequest(CommonSoapRequest $request) { // get \DOMDocument from SOAP request $dom = $request->getContentDocument(); // locate security header $security = $dom->getElementsByTagNameNS(Helper::NS_WSS, 'Security')->item(0); if (null !== $security) { // is security header still valid? $query = '//' . Helper::PFX_WSU . ':Timestamp/' . Helper::PFX_WSU . ':Expires'; $xpath = new \DOMXPath($dom); $xpath->registerNamespace(Helper::PFX_WSU, Helper::NS_WSU); $expires = $xpath->query($query, $security)->item(0); if (null !== $expires) { $expiresDatetime = \DateTime::createFromFormat(static::DATETIME_FORMAT, $expires->textContent, new \DateTimeZone('UTC')); $currentDatetime = new \DateTime('now', new \DateTimeZone('UTC')); if ($currentDatetime > $expiresDatetime) { throw new \SoapFault('wsu:MessageExpired', 'Security semantics are expired'); } } $usernameToken = $security->getElementsByTagNameNS(Helper::NS_WSS, 'UsernameToken')->item(0); if (null !== $usernameToken) { $usernameTokenUsername = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Username')->item(0); $usernameTokenPassword = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Password')->item(0); $password = call_user_func($this->usernamePasswordCallback, $usernameTokenUsername->textContent); if ($usernameTokenPassword->getAttribute('Type') == Helper::NAME_WSS_UTP . '#PasswordDigest') { $nonce = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Nonce')->item(0); $created = $usernameToken->getElementsByTagNameNS(Helper::NS_WSU, 'Created')->item(0); $password = base64_encode(sha1(base64_decode($nonce->textContent) . $created->textContent . $password, true)); } if (null === $password || $usernameTokenPassword->textContent != $password) { throw new \SoapFault('wsse:FailedAuthentication', 'The security token could not be authenticated or authorized'); } } // add SecurityTokenReference resolver for KeyInfo $keyResolver = array($this, 'keyInfoSecurityTokenReferenceResolver'); XmlSecurityDSig::addKeyInfoResolver(Helper::NS_WSS, 'SecurityTokenReference', $keyResolver); // do we have a reference list in header $referenceList = XmlSecurityEnc::locateReferenceList($security); // get a list of encrypted nodes $encryptedNodes = XmlSecurityEnc::locateEncryptedData($dom, $referenceList); // decrypt them if (null !== $encryptedNodes) { foreach ($encryptedNodes as $encryptedNode) { XmlSecurityEnc::decryptNode($encryptedNode); } } // locate signature node $signature = XmlSecurityDSig::locateSignature($security); if (null !== $signature) { // verify references $options = array('id_ns_prefix' => Helper::PFX_WSU, 'id_prefix_ns' => Helper::NS_WSU); if (XmlSecurityDSig::verifyReferences($signature, $options) !== true) { throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid'); } // verify signature if (XmlSecurityDSig::verifyDocumentSignature($signature) !== true) { throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid'); } } $security->parentNode->removeChild($security); } }
/** * Modify the given request XML. * * @param \BeSimple\SoapCommon\SoapResponse $response SOAP response * * @return void */ public function filterResponse(CommonSoapResponse $response) { // get \DOMDocument from SOAP response $dom = $response->getContentDocument(); // locate security header $security = $dom->getElementsByTagNameNS(Helper::NS_WSS, 'Security')->item(0); if (null !== $security) { // add SecurityTokenReference resolver for KeyInfo $keyResolver = array($this, 'keyInfoSecurityTokenReferenceResolver'); XmlSecurityDSig::addKeyInfoResolver(Helper::NS_WSS, 'SecurityTokenReference', $keyResolver); // do we have a reference list in header $referenceList = XmlSecurityEnc::locateReferenceList($security); // get a list of encrypted nodes $encryptedNodes = XmlSecurityEnc::locateEncryptedData($dom, $referenceList); // decrypt them if (null !== $encryptedNodes) { foreach ($encryptedNodes as $encryptedNode) { XmlSecurityEnc::decryptNode($encryptedNode); } } // locate signature node $signature = XmlSecurityDSig::locateSignature($security); if (null !== $signature) { // verify references $options = array('id_ns_prefix' => Helper::PFX_WSU, 'id_prefix_ns' => Helper::NS_WSU); if (XmlSecurityDSig::verifyReferences($signature, $options) !== true) { throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid'); } // verify signature if (XmlSecurityDSig::verifyDocumentSignature($signature) !== true) { throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid'); } } $security->parentNode->removeChild($security); } }