public function addReference($name, $node, $type) { if (!$node instanceof DOMNode) { throw new Exception('$node is not of type DOMNode'); } $curencdoc = $this->encdoc; $this->_resetTemplate(); $encdoc = $this->encdoc; $this->encdoc = $curencdoc; $refuri = XMLSecurityDSig::generate_GUID(); $element = $encdoc->documentElement; $element->setAttribute("Id", $refuri); $this->references[$name] = array("node" => $node, "type" => $type, "encnode" => $encdoc, "refuri" => $refuri); }
/** * Validate the receipt contained in the given XML element using the * certificate provided. * * @param DOMDocument $dom * @param resource $certificate * @return bool */ protected function validateXml(DOMDocument $dom, $certificate) { $secDsig = new XMLSecurityDSig(); // Locate the signature in the receipt XML. $dsig = $secDsig->locateSignature($dom); if ($dsig === null) { throw new RunTimeException('Cannot locate receipt signature'); } $secDsig->canonicalizeSignedInfo(); $secDsig->idKeys = array('wsu:Id'); $secDsig->idNS = array('wsu' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'); if (!$secDsig->validateReference()) { throw new RunTimeException('Reference validation failed'); } $key = $secDsig->locateKey(); if ($key === null) { throw new RunTimeException('Could not locate key in receipt'); } $keyInfo = XMLSecEnc::staticLocateKeyInfo($key, $dsig); if (!$keyInfo->key) { $key->loadKey($certificate); } return $secDsig->verify($key) == 1; }
/** * @param \DOMElement $node * @param DeserializationContext $context * * @throws \LightSaml\Error\LightSamlSecurityException */ public function deserialize(\DOMElement $node, DeserializationContext $context) { $this->checkXmlNodeName($node, 'Signature', SamlConstants::NS_XMLDSIG); $this->signature = new XMLSecurityDSig(); $this->signature->idKeys[] = $this->getIDName(); $this->signature->sigNode = $node; $this->signature->canonicalizeSignedInfo(); $this->key = null; $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); XMLSecEnc::staticLocateKeyInfo($key, $node); if ($key->name || $key->key) { $this->key = $key; } $this->certificates = array(); $list = $context->getXpath()->query('./ds:KeyInfo/ds:X509Data/ds:X509Certificate', $node); foreach ($list as $certNode) { $certData = trim($certNode->textContent); $certData = str_replace(array("\r", "\n", "\t", ' '), '', $certData); $this->certificates[] = $certData; } }
/** * Test that signatures contain the corresponding public keys. */ public function testGetValidatingCertificates() { $certData = XMLSecurityDSig::staticGet509XCerts(CertificatesMock::PUBLIC_KEY_PEM); $certData = $certData[0]; $signedMockElementCopy = Utils::copyElement($this->signedMockElement); $signedMockElementCopy->ownerDocument->appendChild($signedMockElementCopy); $tmp = new SignedElementHelperMock($signedMockElementCopy); $certs = $tmp->getValidatingCertificates(); $this->assertCount(1, $certs); $this->assertEquals($certData, $certs[0]); // Test with two certificates. $tmpCert = '-----BEGIN CERTIFICATE----- MIICsDCCAhmgAwIBAgIJALU2mjA9ULI2MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTAwODAzMDYzNTQ4WhcNMjAwODAyMDYzNTQ4WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDG6q53nl3Gn/9JE+ZiCgEB+EPcGbvzi0NrBDkKz9SKBNflxKQ+De/OAVQ9RQZO tEm/j0hoSCGO7maemOm1PVNtDuMchSroPs0L4szLhh6m1uMhw9RXqq34C+Cr7Wee ZNPQTFnQhBYqnYM03/e3SeUawiZ7rGeAMJ/8BSk0CB1GAQIDAQABo4GnMIGkMB0G A1UdDgQWBBRnHHPiQ/pV/xDZg3EBmU3ik64ORDB1BgNVHSMEbjBsgBRnHHPiQ/pV /xDZg3EBmU3ik64ORKFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALU2mjA9 ULI2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAScv7ee6QajoSM4c4 +fX+eYdjHFsvtqHD0ng987viS8eGjIrRfKAMHVzzs1jSU0TxMM7WUFDf6FpjW+Do r+X+X2Al/n6aDn7qAxXbl0RZuB+saxn+yFR6HFKggwkR1L2pimCuD0gTr6LlrNgf edF1YfJgq35hcMMLY9RE/0C0bCI= -----END CERTIFICATE-----'; $mock = new SignedElementHelperMock(); $mock->setSignatureKey(CertificatesMock::getPrivateKey()); $mock->setCertificates(array($tmpCert, CertificatesMock::PUBLIC_KEY_PEM)); $this->signedMockElement = $mock->toSignedXML(); $tmp = new SignedElementHelperMock($this->signedMockElement); $certs = $tmp->getValidatingCertificates(); $this->assertCount(1, $certs); $this->assertEquals($certData, $certs[0]); }
/** * Try to extract the public key from DOM node. * * Sets publicKey and keyAlgorithm properties if success. * * @see publicKey * @see keyAlgorithm * * @param DOMNode $dom * * @return bool `true` If public key was extracted or `false` if cannot be possible */ protected function setPublicKeyFromNode(DOMNode $dom) { // try to get the public key from the certificate $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($dom); if (!$objDSig) { return false; } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { return false; } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); $this->publicKey = $objKey->getX509Certificate(); $this->keyAlgorithm = $objKey->getAlgorith(); return true; }
public function EncryptBody($siteKey, $objKey, $token) { $enc = new XMLSecEnc(); foreach ($this->envelope->childNodes as $node) { if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') { break; } } $enc->setNode($node); /* encrypt the symmetric key */ $enc->encryptKey($siteKey, $objKey, false); $enc->type = XMLSecEnc::Content; /* Using the symmetric key to actually encrypt the data */ $encNode = $enc->encryptNode($objKey); $guid = XMLSecurityDSig::generateGUID(); $encNode->setAttribute('Id', $guid); $refNode = $encNode->firstChild; while ($refNode && $refNode->nodeType != XML_ELEMENT_NODE) { $refNode = $refNode->nextSibling; } if ($refNode) { $refNode = $refNode->nextSibling; } if ($this->addEncryptedKey($encNode, $enc, $token)) { $this->AddReference($enc->encKey, $guid); } }
/** * Insert a Signature-node. * * @param XMLSecurityKey $key The key we should use to sign the message. * @param array $certificates The certificates we should add to the signature node. * @param \DOMElement $root The XML node we should sign. * @param \DOMNode $insertBefore The XML element we should insert the signature element before. */ public static function insertSignature(XMLSecurityKey $key, array $certificates, \DOMElement $root, \DOMNode $insertBefore = null) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); switch ($key->type) { case XMLSecurityKey::RSA_SHA256: $type = XMLSecurityDSig::SHA256; break; case XMLSecurityKey::RSA_SHA384: $type = XMLSecurityDSig::SHA384; break; case XMLSecurityKey::RSA_SHA512: $type = XMLSecurityDSig::SHA512; break; default: $type = XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($root), $type, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID', 'overwrite' => false)); $objXMLSecDSig->sign($key); foreach ($certificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, true); } $objXMLSecDSig->insertSignature($root, $insertBefore); }
public function signDocument() { if (strlen($this->content2SignIdentifier) == 0) { return; } // get content to sign // get content to sign $doc = new DOMDocument('1.0', 'UTF-8'); $doc->loadXML($this->xmlMessage); $xpath = new DOMXPath($doc); $nodeset = $xpath->query("//{$this->content2SignIdentifier}")->item(0); // sign // sign $objXMLSecDSig = new XMLSecurityDSig(''); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::C14N); $objXMLSecDSig->addReference($nodeset, XMLSecurityDSig::SHA256, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), array('id_name' => 'Id', 'uri' => $this->msgIdentifier, 'overwrite' => false)); openssl_pkcs12_read(file_get_contents($this->myCertificatePathP12), $raw, $this->myCertificatePassword); $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private')); $objKey->loadKey($raw['pkey']); $objXMLSecDSig->sign($objKey, $nodeset); $objXMLSecDSig->add509Cert($raw['cert'], true, false, array('issuerSerial' => true, 'subjectName' => true, 'issuerCertificate' => false)); $this->xmlMessage = $doc->saveXML(); }
public function addMessageID($id = null) { /* Add the WSA MessageID or return existing ID */ if (!is_null($this->messageID)) { return $this->messageID; } if (empty($id)) { $id = XMLSecurityDSig::generateGUID('uuid:'); } $header = $this->locateHeader(); $nodeID = $this->soapDoc->createElementNS(self::WSANS, self::WSAPFX . ':MessageID', $id); $header->appendChild($nodeID); $this->messageID = $id; }
/** * @param \DOMNode $parent * @param SerializationContext $context */ public function serialize(\DOMNode $parent, SerializationContext $context) { if ($this->signingOptions && false === $this->signingOptions->isEnabled()) { return; } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod($this->getCanonicalMethod()); $key = $this->getXmlSecurityKey(); switch ($key->type) { case XMLSecurityKey::RSA_SHA256: $type = XMLSecurityDSig::SHA256; break; case XMLSecurityKey::RSA_SHA384: $type = XMLSecurityDSig::SHA384; break; case XMLSecurityKey::RSA_SHA512: $type = XMLSecurityDSig::SHA512; break; default: $type = XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($parent), $type, array(SamlConstants::XMLSEC_TRANSFORM_ALGORITHM_ENVELOPED_SIGNATURE, XMLSecurityDSig::EXC_C14N), array('id_name' => $this->getIDName(), 'overwrite' => false)); $objXMLSecDSig->sign($key); $objXMLSecDSig->add509Cert($this->getCertificate()->getData(), false, false, $this->signingOptions ? $this->signingOptions->getCertificateOptions()->all() : null); $firstChild = $parent->hasChildNodes() ? $parent->firstChild : null; if ($firstChild && $firstChild->localName == 'Issuer') { // The signature node should come after the issuer node $firstChild = $firstChild->nextSibling; } $objXMLSecDSig->insertSignature($parent, $firstChild); }
public function processSignature($refNode) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys[] = 'wswsu:Id'; $objXMLSecDSig->idNS['wswsu'] = self::WSUNS; $objXMLSecDSig->sigNode = $refNode; /* Canonicalize the signed info */ $objXMLSecDSig->canonicalizeSignedInfo(); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception('Validation Failed'); } $key = null; $objKey = $objXMLSecDSig->locateKey(); if ($objKey) { if ($objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $refNode)) { /* Handle any additional key processing such as encrypted keys here */ } } if (empty($objKey)) { throw new Exception('Error loading key to handle Signature'); } do { if (empty($objKey->key)) { $this->SOAPXPath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS); $query = './xmlsecdsig:KeyInfo/wswsse:SecurityTokenReference/wswsse:Reference'; $nodeset = $this->SOAPXPath->query($query, $refNode); if ($encmeth = $nodeset->item(0)) { if ($uri = $encmeth->getAttribute('URI')) { $arUrl = parse_url($uri); if (empty($arUrl['path']) && ($identifier = $arUrl['fragment'])) { $query = '//wswsse:BinarySecurityToken[@wswsu:Id="' . $identifier . '"]'; $nodeset = $this->SOAPXPath->query($query); if ($encmeth = $nodeset->item(0)) { $x509cert = $encmeth->textContent; $x509cert = str_replace(array("\r", "\n"), '', $x509cert); $x509cert = "-----BEGIN CERTIFICATE-----\n" . chunk_split($x509cert, 64, "\n") . "-----END CERTIFICATE-----\n"; $objKey->loadKey($x509cert); break; } } } } throw new Exception('Error loading key to handle Signature'); } } while (0); if (!$objXMLSecDSig->verify($objKey)) { throw new Exception('Unable to validate Signature'); } return true; }