Exemple #1
0
 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;
 }
 static function staticLocateKeyInfo(XMLSecurityKey $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) {
                             /**
                              * @var DOMElement $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':
                         /**
                          * @var DOMElement $child
                          */
                         if ($x509certNodes = $child->getElementsByTagName('X509Certificate')) {
                             if ($x509certNodes->length > 0) {
                                 /**
                                  * @var \DOMNodeList $x509certNodes
                                  */
                                 $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;
 }