mirror of
https://github.com/devcode-it/openstamanager.git
synced 2025-02-03 01:08:08 +01:00
Merge remote-tracking branch 'origin/p7m'
This commit is contained in:
commit
150b8efefe
@ -81,6 +81,11 @@ function download(button, file) {
|
||||
buttonRestore(button, restore);
|
||||
$(button).prop("disabled", true);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert("'.tr('Errore').': " + xhr.responseJSON.error.message);
|
||||
|
||||
buttonRestore(button, restore);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -34,6 +34,17 @@ class FatturaElettronica
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->file = static::getImportDirectory().'/'.$name;
|
||||
|
||||
if (ends_with($name, '.p7m')) {
|
||||
$file = XML::decodeP7M($this->file);
|
||||
|
||||
if (!empty($file)) {
|
||||
delete($this->file);
|
||||
|
||||
$this->file = $file;
|
||||
}
|
||||
}
|
||||
|
||||
$this->xml = XML::readFile($this->file);
|
||||
|
||||
// Individuazione fattura pre-esistente
|
||||
|
132
src/Util/XML.php
132
src/Util/XML.php
@ -20,7 +20,7 @@ class XML
|
||||
*/
|
||||
public static function read($string)
|
||||
{
|
||||
$content = static::stripP7MData($string);
|
||||
$content = $string;
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
@ -39,84 +39,106 @@ class XML
|
||||
/**
|
||||
* Interpreta i contenuti di un file XML.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function readFile($path)
|
||||
public static function readFile($file)
|
||||
{
|
||||
return static::read(file_get_contents($path));
|
||||
return static::read(file_get_contents($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the PKCS#7 header and the signature info footer from a digitally-signed .xml.p7m file using CAdES format.
|
||||
* Interpreta i contenuti di un file XML.
|
||||
*
|
||||
* TODO: controllare il funzionamento con gli allegati (https://forum.italia.it/t/in-produzione-xml-ricevuto-non-leggibile/5695/2).
|
||||
* @param string $file
|
||||
*
|
||||
* @param string $string File content
|
||||
*
|
||||
* @return string An arguably-valid XML string with the .p7m header and footer stripped away.
|
||||
*
|
||||
* @source https://www.ryadel.com/php-estrarre-contenuto-file-xml-p7m-cades-fattura-elettronica-pa/
|
||||
* @return string|bool
|
||||
*/
|
||||
protected static function stripP7MData($string)
|
||||
public static function decodeP7M($file)
|
||||
{
|
||||
// skip everything before the XML content
|
||||
$string = substr($string, strpos($string, '<?xml '));
|
||||
$directory = pathinfo($file, PATHINFO_DIRNAME);
|
||||
$content = file_get_contents($file);
|
||||
|
||||
// skip everything after the XML content
|
||||
preg_match_all('/<\/.+?>/', $string, $matches, PREG_OFFSET_CAPTURE);
|
||||
$lastMatch = end($matches[0]);
|
||||
$base64 = base64_decode(base64_encode($content), true);
|
||||
if ($base64 !== false) {
|
||||
$content = $base64;
|
||||
}
|
||||
|
||||
$result = substr($string, 0, $lastMatch[1] + strlen($lastMatch[0]) + 1);
|
||||
file_put_contents($file, self::removeBOM($content));
|
||||
|
||||
return static::sanitizeXML($result);
|
||||
$output_file = $directory.'/'.basename($file, '.p7m');
|
||||
|
||||
exec('openssl smime -verify -noverify -in "'.$file.'" -inform DER -out "'.$output_file.'"', $output, $cmd);
|
||||
if (!file_exists($output_file)) {
|
||||
$signer = $directory.'/signer';
|
||||
|
||||
self::decode($file, $output_file, $signer);
|
||||
|
||||
self::der2smime($file);
|
||||
self::decode($file, $output_file, $signer);
|
||||
|
||||
if (!file_exists($output_file)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $output_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes invalid characters from a UTF-8 XML string.
|
||||
* Decodifica il file utilizzando le funzioni native PHP.
|
||||
*
|
||||
* @param string a XML string potentially containing invalid characters
|
||||
* @param $file
|
||||
* @param $output_file
|
||||
* @param $signer
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function decode($file, $output_file, $signer)
|
||||
{
|
||||
openssl_pkcs7_verify($file, PKCS7_NOVERIFY | PKCS7_NOSIGS, $signer);
|
||||
$result = openssl_pkcs7_verify($file, PKCS7_NOVERIFY | PKCS7_NOSIGS, $signer, [], $signer, $output_file);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove UTF8 BOM.
|
||||
*
|
||||
* @param $text
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @source https://www.ryadel.com/php-eliminare-caratteri-non-validi-file-stringa-xml-utf8-utf-8/
|
||||
* @source https://stackoverflow.com/questions/10290849/how-to-remove-multiple-utf-8-bom-sequences
|
||||
*/
|
||||
protected static function sanitizeXML($string)
|
||||
protected static function removeBOM($text)
|
||||
{
|
||||
if (!empty($string)) {
|
||||
$regex = '/(
|
||||
[\xC0-\xC1] # Invalid UTF-8 Bytes
|
||||
| [\xF5-\xFF] # Invalid UTF-8 Bytes
|
||||
| \xE0[\x80-\x9F] # Overlong encoding of prior code point
|
||||
| \xF0[\x80-\x8F] # Overlong encoding of prior code point
|
||||
| [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start
|
||||
| [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start
|
||||
| [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
|
||||
| (?<=[\x0-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
|
||||
| (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
|
||||
| (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
|
||||
| (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
|
||||
| (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
|
||||
)/x';
|
||||
$string = preg_replace($regex, '', $string);
|
||||
$bom = pack('H*', 'EFBBBF');
|
||||
$text = preg_replace("/^$bom/", '', $text);
|
||||
|
||||
$result = '';
|
||||
$length = strlen($string);
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$current = ord($string[$i]);
|
||||
if (($current == 0x9) ||
|
||||
($current == 0xA) ||
|
||||
($current == 0xD) ||
|
||||
(($current >= 0x20) && ($current <= 0xD7FF)) ||
|
||||
(($current >= 0xE000) && ($current <= 0xFFFD)) ||
|
||||
(($current >= 0x10000) && ($current <= 0x10FFFF))) {
|
||||
$result .= chr($current);
|
||||
}
|
||||
}
|
||||
$string = $result;
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
return $string;
|
||||
/**
|
||||
* @param $file
|
||||
*
|
||||
* @return bool|int
|
||||
*
|
||||
* @source http://php.net/manual/en/function.openssl-pkcs7-verify.php#123118
|
||||
*/
|
||||
protected static function der2smime($file)
|
||||
{
|
||||
$to = <<<TXT
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: attachment; filename="smime.p7m"
|
||||
Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"
|
||||
Content-Transfer-Encoding: base64
|
||||
\n
|
||||
TXT;
|
||||
$from = file_get_contents($file);
|
||||
$to .= chunk_split(base64_encode($from));
|
||||
|
||||
return file_put_contents($file, $to);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user