Exemple #1
0
 public function testDecryption()
 {
     $key = Key::factory(Key::RSA_OAEP_MGF1P, $this->fixturesDir . '/privkey.pem', true, Key::TYPE_PRIVATE);
     $tests = array(array('ref' => false, 'file' => 'encrypt_document_element.xml', 'desc' => 'Decrypt document with type ELEMENT'), array('ref' => false, 'file' => 'encrypt_document_content.xml', 'desc' => 'Decrypt document with type CONTENT'), array('ref' => true, 'file' => 'encrypt_document_element_reference.xml', 'desc' => 'Encrypt document with type ELEMENT and key reference'), array('ref' => true, 'file' => 'encrypt_document_content_reference.xml', 'desc' => 'Encrypt document with type CONTENT and key reference'));
     foreach ($tests as $test) {
         $doc = new DOMDocument();
         $doc->load($this->fixturesDir . '/Enc/' . $test['file']);
         // get a list of encrypted nodes
         $encryptedNodes = Enc::locateEncryptedData($doc);
         // decrypt them
         foreach ($encryptedNodes as $encryptedNode) {
             $decryptionKey = Enc::getSecurityKey($encryptedNode, $key);
             Enc::decryptNode($encryptedNode, $decryptionKey);
         }
         // remove EncryptedKey if still part of XML (CONTENT with referenced key)
         $encryptedKey = Enc::locateEncryptedKey($doc);
         if (null !== $encryptedKey) {
             $encryptedKey->parentNode->removeChild($encryptedKey);
         }
         $file = $this->fixturesDir . '/Enc/encrypt_document.xml';
         $this->assertXmlStringEqualsXmlFile($file, $doc->saveXML(), $test['desc']);
     }
 }
 /**
  * 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);
     }
 }