12 require_once(
'XMLSecLibs/WSSESoap.php');
38 protected $keyFile=
'';
44 protected $passPhrase=
'';
50 protected $certFile=
'';
55 private $conTrazabilidadPAI =
true;
60 private $enableWSSecurity =
true;
65 private $userToken =
'';
70 private $passUserToken =
'';
75 protected $nsCert = null;
80 protected $idApp = null;
86 protected $mtom =
false;
101 $this->passPhrase=
'';
104 $this->conTrazabilidadPAI =
true;
105 $this->enableWSSecurity =
true;
107 if (is_array($vOptions))
109 $vOptions[
'trace'] =
true;
113 $vOptions = array(
'trace' =>
true);
116 return parent::__construct($wsdl, $vOptions);
128 $this->keyFile = $pathKey;
140 return($this->keyFile);
152 $this->passPhrase = $passphrase;
164 return($this->passPhrase);
176 $this->certFile = $pathCert;
187 return($this->certFile);
199 if (!is_array($vCertData))
200 throw new \Exception(
'La información debe venir como array asociativo');
202 if (array_key_exists(
'certFile', $vCertData))
204 $this->certFile = $vCertData[
'certFile'];
208 throw new \Exception(
'El array asociativo debe contener la ruta al certificado');
211 if (array_key_exists(
'keyFile', $vCertData))
213 $this->keyFile = $vCertData[
'keyFile'];
217 throw new \Exception(
'El array asociativo debe contener la ruta al fichero de clave');
220 if (array_key_exists(
'passPhrase', $vCertData))
222 $this->passPhrase = $vCertData[
'passPhrase'];
252 if (!is_array($vTrazabilidadPAI))
254 throw new \Exception(
'Las opciones de trazabilidad deben ser un array asociativo');
257 if (array_key_exists(
'idApp', $vTrazabilidadPAI))
259 $this->idApp = $vTrazabilidadPAI[
'idApp'];
263 throw new \Exception(
'El array asociativo debe contener el ID de la aplicación que consume el WS');
266 if ($this->enableWSSecurity)
268 if (!empty($this->certFile))
270 $this->getCertificateSerial();
284 if (empty ($vTrazabilidadPAI))
286 if (empty($this->idApp))
288 throw new \Exception(__CLASS__.
":: Debe fijarse el idApp");
291 if ($this->enableWSSecurity())
293 if(empty($this->nsCert) && !empty($this->certFile))
295 $this->nsCert = $this->getCertificateSerial();
303 $this->loadTrazabilidad($vTrazabilidadPAI);
310 $this->conTrazabilidadPAI =
true;
320 $this->conTrazabilidadPAI =
false;
331 $this->enableWSSecurity =
true;
341 $this->enableWSSecurity =
false;
353 $this->userToken = $username;
354 $this->passUserToken = $password;
366 $certFile = realpath($this->certFile);
367 $cert = file_get_contents($certFile);
370 throw new \Exception(__FILE__.
'::'.__CLASS__.
" - No puedo leere el contenido de $certFile ");
372 $v_certData = openssl_x509_parse($cert,
true);
373 $this->nsCert = strtoupper(self::numberBaseConvert($v_certData[
'serialNumber']));
374 return $this->nsCert;
389 private static function numberBaseConvert($numstring, $frombase=10, $tobase=16)
391 $chars =
"0123456789abcdefghijklmnopqrstuvwxyz";
392 $tostring = substr($chars, 0, $tobase);
393 $length = strlen($numstring);
396 for ($i = 0; $i < $length; $i++)
398 $number[$i] = strpos($chars, $numstring{$i});
404 for ($i = 0; $i < $length; $i++)
406 $divide = $divide * $frombase + $number[$i];
407 if ($divide >= $tobase)
409 $number[$newlen++] = (int)($divide / $tobase);
410 $divide = $divide % $tobase;
411 } elseif ($newlen > 0)
413 $number[$newlen++] = 0;
417 $result = $tostring{$divide} . $result;
418 }
while ($newlen != 0);
431 private function getPAITraceToken()
433 $t = microtime(
true);
434 $micro = sprintf(
"%06d",($t - floor($t)) * 1000000);
435 $date = new \DateTime( date(
'Y-m-d H:i:s.'.$micro, $t));
436 $token = $this->nsCert.
'-'.$this->idApp.
'-'.substr($date->format(
'YmdHisu'), 0, 17);
452 public function __doRequest($newRequest, $location, $action, $version, $one_way = null)
454 if ($this->enableWSSecurity==
true)
457 $doc = new \DOMDocument(
'1.0');
460 $doc->loadXML($newRequest);
463 $objWSSE =
new WSSESoap($doc,
false,
false);
465 if (!empty($this->certFile))
468 $objKey =
new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array(
'type'=>
'private'));
470 $objKey->passphrase = $this->getPassPhrase();
472 $objKey->loadKey($this->getKeyFile(),
true);
475 $objWSSE->signSoapDoc($objKey);
478 $token = $objWSSE->addBinaryToken(file_get_contents($this->getCertFile()),
true);
480 $objWSSE->attachTokentoSig($token);
482 elseif (!empty($this->userToken))
485 $objWSSE->addUserToken($this->userToken, $this->passUserToken, $this->
true);
490 throw new \Exception(
'Al activar WSSecurity es obligatorio suministrar un certificado o los datos que componene el UserToken');
494 $objWSSE->addTimestamp(3600);
497 $newRequest = $objWSSE->saveXML();
500 if ($this->conTrazabilidadPAI)
502 $dom = new \DOMDocument(
'1.0');
503 $dom->loadXML($newRequest);
504 $xpath = new \DOMXpath($dom);
505 $headers = $xpath->query(
"/*[local-name()='Envelope']/*[local-name()='Header']");
507 if (($headers->length) > 0)
509 $header = $headers->item(0);
513 $envelop = $dom->firstChild;
514 $prefijo = $dom->lookupPrefix (
'http://schemas.xmlsoap.org/soap/envelope/');
515 $header = $dom->createElementNS (
'http://schemas.xmlsoap.org/soap/envelope/',$prefijo.
':Header',
'');
516 $body = $envelop->firstChild;
517 $header = $envelop->insertBefore($header, $body);
520 $nodoTraza = $dom->createElementNS(
'http://dgti.gva.es/interoperabilidad',
'Id_trazabilidad');
521 $nodoTraza->appendChild(
new \DOMText( (
string) $this->getPAITraceToken()));
522 $header->appendChild($nodoTraza);
523 unset($newRequest);$newRequest=null;gc_collect_cycles();
524 $newRequest = $dom->saveXML();
528 $response = parent::__doRequest($newRequest, $location, $action, $version, $one_way);
531 if (strpos($response,
"Content-Type: application/xop+xml") ===
false)
__construct($wsdl, $vOptions=null)
setUserToken($username, $password)
enablePAITrace___($vTrazabilidadPAI=null)
setPassPhrase($passphrase)
loadTracertPAI($vTrazabilidadPAI)
__doRequest($newRequest, $location, $action, $version, $one_way=null)