/** * Signs the specified request. * * @param $request * @param $location * @param $action * @param $version * @param null $oneWay * * @return string Signed request. * @throws \Exception */ protected function signRequest($request) { $doc = new \DOMDocument(); $doc->loadXML($request); $wsse = new WSSESoap($doc); $wsse->addTimestamp(); $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); if (!empty($this->options['passphrase'])) { $key->passphrase = $this->options['passphrase']; } $key->loadKey($this->getCertificateContent()); $wsse->signSoapDoc($key); $token = $wsse->addBinaryToken($this->getCertificateContent()); $wsse->attachTokentoSig($token); return $wsse->saveXML(); }
static function convertRSA($modulus, $exponent) { /* make an ASN publicKeyInfo */ $exponentEncoding = XMLSecurityKey::makeAsnSegment(0x2, $exponent); $modulusEncoding = XMLSecurityKey::makeAsnSegment(0x2, $modulus); $sequenceEncoding = XMLSecurityKey::makeAsnSegment(0x30, $modulusEncoding . $exponentEncoding); $bitstringEncoding = XMLSecurityKey::makeAsnSegment(0x3, $sequenceEncoding); $rsaAlgorithmIdentifier = pack("H*", "300D06092A864886F70D0101010500"); $publicKeyInfo = XMLSecurityKey::makeAsnSegment(0x30, $rsaAlgorithmIdentifier . $bitstringEncoding); /* encode the publicKeyInfo in base64 and add PEM brackets */ $publicKeyInfoBase64 = base64_encode($publicKeyInfo); $encoding = "-----BEGIN PUBLIC KEY-----\n"; $offset = 0; while ($segment = substr($publicKeyInfoBase64, $offset, 64)) { $encoding = $encoding . $segment . "\n"; $offset += 64; } return $encoding . "-----END PUBLIC KEY-----\n"; }
static function staticLocateKeyInfo($objBaseKey = NULL, $node = NULL) { if (empty($node) || !$node instanceof DOMNode) { return NULL; } if ($doc = $node->ownerDocument) { $xpath = new DOMXPath($doc); $xpath->registerNamespace('xmlsecenc', XMLSecEnc::XMLENCNS); $xpath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS); $query = "./xmlsecdsig:KeyInfo"; $nodeset = $xpath->query($query, $node); if ($encmeth = $nodeset->item(0)) { foreach ($encmeth->childNodes as $child) { switch ($child->localName) { case 'KeyName': if (!empty($objBaseKey)) { $objBaseKey->name = $child->nodeValue; } break; case 'KeyValue': foreach ($child->childNodes as $keyval) { switch ($keyval->localName) { case 'DSAKeyValue': throw new Exception("DSAKeyValue currently not supported"); break; case 'RSAKeyValue': $modulus = NULL; $exponent = NULL; if ($modulusNode = $keyval->getElementsByTagName('Modulus')->item(0)) { $modulus = base64_decode($modulusNode->nodeValue); } if ($exponentNode = $keyval->getElementsByTagName('Exponent')->item(0)) { $exponent = base64_decode($exponentNode->nodeValue); } if (empty($modulus) || empty($exponent)) { throw new Exception("Missing Modulus or Exponent"); } $publicKey = XMLSecurityKey::convertRSA($modulus, $exponent); $objBaseKey->loadKey($publicKey); break; } } break; case 'RetrievalMethod': /* Not currently supported */ break; case 'EncryptedKey': $objenc = new XMLSecEnc(); $objenc->setNode($child); if (!($objKey = $objenc->locateKey())) { throw new Exception("Unable to locate algorithm for this Encrypted Key"); } $objKey->isEncrypted = TRUE; $objKey->encryptedCtx = $objenc; XMLSecEnc::staticLocateKeyInfo($objKey, $child); return $objKey; break; case 'X509Data': if ($x509certNodes = $child->getElementsByTagName('X509Certificate')) { if ($x509certNodes->length > 0) { $x509cert = $x509certNodes->item(0)->textContent; $x509cert = str_replace(array("\r", "\n"), "", $x509cert); $x509cert = "-----BEGIN CERTIFICATE-----\n" . chunk_split($x509cert, 64, "\n") . "-----END CERTIFICATE-----\n"; $objBaseKey->loadKey($x509cert, FALSE, TRUE); } } break; } } } return $objBaseKey; } return NULL; }
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; }