Caratteri non validi all'interno dei tag XML su fatture ricevute tramite SDICoop

Buongiorno,

a volte succede di ricevere fatture firmate che contengono caratteri non validi all’interno dei tag XML.

Nel caso di caratteri non ammessi (unicode o caratteri invisibili) riesco a rimuoverli, ma succede di trovare caratteri ammessi che non devono essere presenti all’interno dei tag.

Ad esempio:

<AliquotaIVA>0.00</AliquotakIVA>
<CondizioniPagamento>TP01</CondizioniPagamento6>

provocando l’errore dell’interprete XML ( simplexml_load_string).

Sembra che, in alcuni casi, lo SDI non verifichi la corretta sintassi dei tag XML quando sono firmati.

Se succede a qualcun altro, come avete risolto?

Dici che sono XML firmati… sono per caso file .p7m? Se è così, come fai ad estrarre l’XML dal file .p7m?

Lo chiedo perché in passato su questo forum c’era qualcuno che usava metodi “artigianali” che cercavano di estrarre il file dall’XML con un’espressione regolare e/o togliere i header binari dei blocchi, ma questo metodo alle volte lascia byte spuri nel file prodotto.

si, sono file p7m da cui provo a rimuovere la firma.

Tentavo di rimuovere la firma con la funzione:

openssl_pkcs7_verify ($fileP7m , PKCS7_NOVERIFY , null , array($certCA), $certCA, $fileXML);

e nel caso non avesse funzionato provavo a rimuovere la firma con un espressione regolare, ma come hai scritto tu, restano dei byte spuri nel file prodotto.

ho cercato sul forum un metodo alternativo e sembra che con la funzione

openssl cms -verify -noverify -inform DER -in fattura.xml.p7m -no_attr_verify -out fattura.xml

la rimozione della firma vada a buon fine.

Sì, quel comando dovrebbe funzionare in tutti i casi, però l’ultima volta che ne abbiamo discusso qui, era venuto fuori che non c’era modo di fare l’equivalente usando direttamente la libreria in PHP, ma bisognava per forza eseguirlo come programma esterno.

Cercando adesso, vedo che in PHP (dalla versione 8.0 in poi) c’è anche la funzione openssl_cms_verify che sembrerebbe fare l’equivalente del comando openssl cms. L’unico problema è che, stando alla documentazione, a differenza della funzione openssl_pkcs7_verify, non c’è il parametro $output_filename in cui viene salvato il file senza firma.
Credo però che la documentazione del PHP sia sbagliata. Leggendo i sorgenti (in C) della libreria php, mi sembra che il parametro $content, che è indicato come il file contenente i dati firmati quando la firma è separata, in realtà sia il file di output (parametro out della funzione CMS_verify di OpenSSL), mentre i dati nel caso di firma separata vadano passati in $sigfile, che va a finire nel parametro indata di CMS_verify).

ho fatto dei test con questi parametri ma non ha funzionato in nessun caso.

openssl_csm_verify ($fileP7m , 0, null , array($certCA), $certCA, $fileXML);

openssl_csm_verify ($fileP7m , OPENSSL_CMS_NOVERIFY, null , array($certCA), $certCA, $fileXML);

openssl_csm_verify ($fileP7m , OPENSSL_CMS_NOVERIFY, null , array($certCA), $certCA, $fileXML, null,null, OPENSSL_ENCODING_DER);

openssl_csm_verify ($fileP7m , OPENSSL_CMS_NOVERIFY| OPENSSL_CMS_NOATTR, null , array($certCA), $certCA, $fileXML);

openssl_csm_verify ($fileP7m , OPENSSL_CMS_NOVERIFY| OPENSSL_CMS_NOATTR, null , array($certCA), $certCA, $fileXML, null, null, OPENSSL_ENCODING_DER);

alla fine ho usato exec con il comando:

openssl cms -verify -noverify -inform DER -in fattura.xml.p7m -no_attr_verify -out fattura.xml

Grazie comunque per i consigli.