/** * Tries to resolve a key from the given \DOMElement. * * @param \DOMElement $node Node where to resolve the key * @param string $algorithm XML security key algorithm * * @return \ass\XmlSecurity\Key|null */ public function keyInfoSecurityTokenReferenceResolver(\DOMElement $node, $algorithm) { foreach ($node->childNodes as $key) { if (Helper::NS_WSS === $key->namespaceURI) { switch ($key->localName) { case 'KeyIdentifier': return $this->serviceSecurityKey->getPublicKey(); case 'Reference': $uri = $key->getAttribute('URI'); $referencedNode = $this->getReferenceNodeForUri($node, $uri); if (XmlSecurityEnc::NS_XMLENC === $referencedNode->namespaceURI && 'EncryptedKey' == $referencedNode->localName) { $key = XmlSecurityEnc::decryptEncryptedKey($referencedNode, $this->userSecurityKey->getPrivateKey()); return XmlSecurityKey::factory($algorithm, $key, false, XmlSecurityKey::TYPE_PRIVATE); } elseif (Helper::NS_WSS === $referencedNode->namespaceURI && 'BinarySecurityToken' == $referencedNode->localName) { $key = XmlSecurityPem::formatKeyInPemFormat($referencedNode->textContent); return XmlSecurityKey::factory(XmlSecurityKey::RSA_SHA1, $key, false, XmlSecurityKey::TYPE_PUBLIC); } } } } return null; }
/** * Gets the security referenced in the given $encryptedData element. * * You can add your own key resolver by calling: * $ns = 'myns'; * $localname = 'MyKeyInfo'; * $keyResolver = array('MyClass' => 'function'); * \ass\XmlSecurity\DSig::addKeyInfoResolver($ns, $localName, $keyResolver); * * @param DOMElement $encryptedData Encrypted data element * @param Key $key Key to decrypt EncryptedKey * * @return Key|null */ public static function getSecurityKey(DOMElement $encryptedData, Key $key = null) { $encryptedMethod = $encryptedData->getElementsByTagNameNS(self::NS_XMLENC, 'EncryptionMethod')->item(0); if (!is_null($encryptedMethod)) { $algorithm = $encryptedMethod->getAttribute('Algorithm'); $keyInfo = $encryptedData->getElementsByTagNameNS(DSig::NS_XMLDSIG, 'KeyInfo')->item(0); if (!is_null($keyInfo)) { if (null !== $key) { $encryptedKey = self::locateEncryptedKey($keyInfo); if (null !== $encryptedKey) { $keyString = Enc::decryptEncryptedKey($encryptedKey, $key); return Key::factory($algorithm, $keyString, false, Key::TYPE_PRIVATE); } else { $class = __CLASS__; $keyResolver = function (DOMElement $node, $algorithm) use($class, $key) { if ($class::RETRIEVAL_METHOD_ENCRYPTED_KEY == $node->getAttribute('Type')) { $uri = $node->getAttribute('URI'); $referencedNode = $class::getReferenceNodeForUri($node, $uri); if (null !== $referencedNode && $class::NS_XMLENC == $referencedNode->namespaceURI && 'EncryptedKey' == $referencedNode->localName) { $keyString = $class::decryptEncryptedKey($referencedNode, $key); return Key::factory($algorithm, $keyString, false, Key::TYPE_PRIVATE); } } return null; }; DSig::addKeyInfoResolver(DSig::NS_XMLDSIG, 'RetrievalMethod', $keyResolver); } } return DSig::getSecurityKeyFromKeyInfo($keyInfo, $algorithm); } } return null; }