/** * @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; } }
/** * 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; }
/** * Create key from an EncryptedKey-element. * * @param DOMElement $element The EncryptedKey-element. * @throws Exception * * @return XMLSecurityKey The new key. */ public static function fromEncryptedKeyElement(DOMElement $element) { $objenc = new XMLSecEnc(); $objenc->setNode($element); if (!($objKey = $objenc->locateKey())) { throw new Exception("Unable to locate algorithm for this Encrypted Key"); } $objKey->isEncrypted = true; $objKey->encryptedCtx = $objenc; XMLSecEnc::staticLocateKeyInfo($objKey, $element); return $objKey; }
public function decryptSoapDoc($doc, $options) { $privKey = null; $privKey_isFile = false; $privKey_isCert = false; if (is_array($options)) { $privKey = !empty($options['keys']['private']['key']) ? $options['keys']['private']['key'] : null; $privKey_isFile = !empty($options['keys']['private']['isFile']) ? true : false; $privKey_isCert = !empty($options['keys']['private']['isCert']) ? true : false; } $objenc = new XMLSecEnc(); $xpath = new DOMXPath($doc); $envns = $doc->documentElement->namespaceURI; $xpath->registerNamespace('soapns', $envns); $xpath->registerNamespace('soapenc', 'http://www.w3.org/2001/04/xmlenc#'); $nodes = $xpath->query('/soapns:Envelope/soapns:Header/*[local-name()="Security"]/soapenc:EncryptedKey'); $references = array(); if ($node = $nodes->item(0)) { $objenc = new XMLSecEnc(); $objenc->setNode($node); if (!($objKey = $objenc->locateKey())) { throw new Exception('Unable to locate algorithm for this Encrypted Key'); } $objKey->isEncrypted = true; $objKey->encryptedCtx = $objenc; XMLSecEnc::staticLocateKeyInfo($objKey, $node); if ($objKey && $objKey->isEncrypted) { $objencKey = $objKey->encryptedCtx; $objKey->loadKey($privKey, $privKey_isFile, $privKey_isCert); $key = $objencKey->decryptKey($objKey); $objKey->loadKey($key); } $refnodes = $xpath->query('./soapenc:ReferenceList/soapenc:DataReference/@URI', $node); foreach ($refnodes as $reference) { $references[] = $reference->nodeValue; } } foreach ($references as $reference) { $arUrl = parse_url($reference); $reference = $arUrl['fragment']; $query = '//*[@Id="' . $reference . '"]'; $nodes = $xpath->query($query); $encData = $nodes->item(0); if ($algo = $xpath->evaluate('string(./soapenc:EncryptionMethod/@Algorithm)', $encData)) { $objKey = new XMLSecurityKey($algo); $objKey->loadKey($key); } $objenc->setNode($encData); $objenc->type = $encData->getAttribute('Type'); $decrypt = $objenc->decryptNode($objKey, true); } return true; }
/** * 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; }
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; }