public function testSignDocumentSha256() { // if key has a passphrase, set it via fifth parameter in factory $key = Key::factory(Key::RSA_SHA256, $this->fixturesDir . '/privkey.pem', true, Key::TYPE_PRIVATE); $cert = Key::factory(Key::RSA_SHA256, $this->fixturesDir . '/mycert.pem', true, Key::TYPE_PUBLIC); $doc = new DOMDocument(); $doc->formatOutput = true; $doc->load($this->fixturesDir . '/DSig/sign_document.xml'); $keyInfo = DSig::createX509CertificateKeyInfo($doc, $cert); $signature = DSig::createSignature($key, DSig::EXC_C14N, $doc->documentElement, null, $keyInfo); DSig::addNodeToSignature($signature, $doc, DSig::SHA1, DSig::TRANSFORMATION_ENVELOPED_SIGNATURE); DSig::signDocument($signature, $key, DSig::EXC_C14N); $file = $this->fixturesDir . '/DSig/sign_document_sha256_result.xml'; $this->assertXmlStringEqualsXmlFile($file, $doc->saveXML(), "Sign document with SHA256"); }
public function testGenerateSessionKeyParity() { /* Run the test several times, to increase the chance of detecting an error. */ for ($t = 0; $t < 16; $t++) { $key = Key::factory(Key::TRIPLEDES_CBC); $k = $key->getKey(); for ($i = 0; $i < strlen($k); $i++) { $byte = ord($k[$i]); $parity = 0; while ($byte !== 0) { $parity ^= $byte & 1; $byte >>= 1; } $this->assertEquals(1, $parity, "Check that generated triple-des keys have the correct parity."); } } }
public function testEncryption() { $key = Key::factory(Key::AES256_CBC); $cert = Key::factory(Key::RSA_OAEP_MGF1P, $this->fixturesDir . '/mycert.pem', true, Key::TYPE_PUBLIC); $tests = array(array('ref' => false, 'type' => Enc::ELEMENT, 'file' => 'encrypt_document_element.xml', 'desc' => 'Encrypt document with type ELEMENT'), array('ref' => false, 'type' => Enc::CONTENT, 'file' => 'encrypt_document_content.xml', 'desc' => 'Encrypt document with type CONTENT'), array('ref' => true, 'type' => Enc::ELEMENT, 'file' => 'encrypt_document_element_reference.xml', 'desc' => 'Encrypt document with type ELEMENT and key reference'), array('ref' => true, 'type' => Enc::CONTENT, '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/encrypt_document.xml'); if ($test['ref']) { $guid = 'EncKey-57cf0489-02e2-45c0-9fcc-fe1a51b53ab2'; // static - normally use DSig::generateUUID() $keyInfo = Enc::createEncryptedKeyReferenceKeyInfo($doc, $guid); $encryptedData = Enc::encryptNode($doc->documentElement, $test['type'], $key, null, $keyInfo); Enc::createEncryptedKey($guid, $key, $cert, $doc->documentElement); } else { $encryptedData = Enc::encryptNode($doc->documentElement, $test['type'], $key); Enc::createEncryptedKey(null, $key, $cert, $encryptedData); } $file = $this->fixturesDir . '/Enc/' . $test['file']; $expected = $this->removeCipherValues(file_get_contents($file)); $actual = $this->removeCipherValues($doc->saveXML()); $this->assertEquals($expected, $actual, $test['desc']); } }
/** * 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; }
/** * Sign the document. * * @param DOMElement $signature Signature element to sign * @param Key $keyForSignature Key used to sign data * @param string $canonicalizationAlgorithm Canonicalization algorithm * * @return DOMElement */ public static function signDocument(DOMElement $signature, Key $keyForSignature, $canonicalizationAlgorithm) { $doc = $signature->ownerDocument; $signedInfo = $signature->getElementsByTagNameNS(self::NS_XMLDSIG, 'SignedInfo')->item(0); if (!is_null($signedInfo)) { $canonicalizedData = self::canonicalizeData($signedInfo, $canonicalizationAlgorithm); $signatureValueString = base64_encode($keyForSignature->signData($canonicalizedData)); $signatureValue = $doc->createElementNS(self::NS_XMLDSIG, self::PFX_XMLDSIG . ':SignatureValue', $signatureValueString); $keyInfo = $signature->getElementsByTagNameNS(self::NS_XMLDSIG, 'KeyInfo')->item(0); $signature->insertBefore($signatureValue, $keyInfo); } return $signatureValue; }
/** * Add public key. * * @param string $encryptionType Encryption type * @param string $key Public key * @param boolean $keyIsFile Given key parameter is path to key file * * @return void */ public function addPublicKey($encryptionType, $key = null, $keyIsFile = true) { $this->publicKey = XmlSecurityKey::factory($encryptionType, $key, $keyIsFile, XmlSecurityKey::TYPE_PUBLIC); }