File p7m contenenti file binario

Salve, abbiamo un problema e magari qualcuno di voi conosce la risposta.
Saltuariamente, ci arrivano file p7m contenenti degli xml in formato binario e non in formato testo.
l’errore durante l’encript (con openssl) è:
Error reading S/MIME message
580:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1199:
580:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:374:Type=PKCS7

Ho visto sul forum che da un errore simile anche quando si tratta di file base64 ma non credo sia questo il problema perché se faccio

openssl base64 -d -in nomefile.p7m

dopo ottengo lo stesso errore.

Aprendo il file p7m con un notepad vedo una stringa di caratteri mentre in quelle che non mi danno problemi vedo i tag del file xml

1 Mi Piace

Per stringa di caratteri cosa intendi?
Se ci sono solo lettere, numeri e i caratteri ‘+’, ‘/’ ed eventuali ‘=’ in fondo, allora è base64.

Sì, è esattamente come dici tu (compresi ‘==’ in fondo) ma se provo a gestirlo come base64 mi da sempre lo stesso errore.
Cosa sbaglio?

Se provi ad eseguire questo comando, ti dà errore?

openssl base64 -d -in nomefile.p7m | openssl smime -verify -inform DER -noverify -out nomefile.xml

Se sì, ed esegui solo il primo comando, cosa viene fuori?

openssl base64 -d -in nomefile.p7m

Se non viene fuori niente e non dà errore, controlla se per caso i dati base64 sono tutti su una riga senza un “a capo” finale. Se è così, prova a modificare il file aggiungendo una riga vuota in fondo e ripeti l’operazione.

Se lancio il comando chew mi hai detto ricevo lo stesso errore.
Incollo l’output:
C:\Users\Administrator\Desktop\FirmaNonVerificabile>openssl base64 -d -in IT01360570384_F000R.xml.p7m | openssl smime -verify -inform DER -noverify -out IT01360570384_F000R.xml
Error reading S/MIME message
5088:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:157:

Se lancio solamente:
openssl base64 -d -in IT01360570384_F000R.xml.p7m

non da errore ma poi ricevo lo stesso errore

Se provo a aggiungere un accapo alla fine ricevo un errore in più, vedi sotto:

C:\Users\Administrator\Desktop\FirmaNonVerificabile>openssl base64 -d -in IT01360570384_F000R.xml.p7m | openssl smime -verify -inform DER -noverify -out IT01360570384_F000R.xml
Error reading S/MIME message
2592:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1199:
2592:error:0D08403A:asn1 encoding routines:ASN1_TEMPLATE_EX_D2I:nested asn1 error:tasn_dec.c:550:Field=d.other, Type=PKCS7

Ma quando hai eseguito openssl base64 -d -in IT01360570384_F000R.xml.p7m sul file originale, non ti ha stampato niente a video?

Prova ad eseguire il comando:
openssl base64 -d -in IT01360570384_F000R.xml.p7m -out test.p7m
con il file dove hai aggiunto un a capo in fondo e dai un’occhiata al file test.p7m così generato. Cosa vedi dentro?

Ho fato come dici, non da errore e se apro test.p7m con un notepad adesso vedo un file con dei geroglifici strani (??). Il file è diventato solo 1 Kb.
Se provo a decriptarlo con openssl ottengo lo stesso errore di prima

Hmm… non saprei. Dovrei vedere il file originale per saperti dire qualcosa.
Se riesci a farmelo vedere, posso darci un’occhiata (eventualmente mandami un link in un messaggio privato).

Scusa ma non mi è chiara una cosa.
dici che nel p7m ci sono file xml in binario, quindi vuol dire che estrai i file xml dalla firma. A che pro, quindi fare openssl base64 -d -in nomefile.p7m?
Intendi che è direttamente il file p7m ad essere binario? Se fosse così, scusa la domanda banale, hai provato ad aprirlo direttamente con il dike e vedere se lo legge?

Utilizzando file protector e si aprono benissimo. Da openssl ricevo errore

ok allora è il metodo di decodifica di openSSL. A me faceva ESATTAMENTE la stessa cosa (anche l’errore identico: wrong tag), ed anche a me random. Alla fine, esasperato, sviluppando in C#, ho utilizzato direttamente le librerie interne ed ho risolto (grazie proprio all’aiuto avuto su questo forum).

Su oltre 200.000 fatture ricevute non ho mai avuto problemi con openssl.
Il problema spesso è nella decodifica base64 a seconda della piattaforma utilizzata i terminatori di riga cambiano e sembrano dare noia sia a base64 -d sotto unix sia a openssl base64 -d
Sarebbe interessante vedere quel file…

Quello che ho notato io sotto Linux è:

  • Il comando base64 si aspetta terminatori di riga Unix (LF) e non tollera i caratteri CR. I dati base64 possono stare su un’unica riga senza terminatore di riga.
  • Il comando openssl base64 funziona sia con terminatori Unix che Windows, ma se i dati stanno su una sola riga, questa deve essere terminata. Curiosamente, se i dati base64 sono su più righe, l’ultima può anche non essere terminata.

Visto che le librerie standard di quasi tutti i linguaggi hanno già la funzione per la decodifica base64, io la farei da codice, prima di passare il risultato ad openssl per la sola decodifica cms/smime. Oppure, una volta stabilito che si tratta di dati base64, si possono elaborare per portarli in una forma che si è sicuri che venga accettata dal programma esterno usato.

Comunque se qualcuno vuole un esempio di file per vedere come è fatto per me non ci sono problemi

Ti avevo mandato un PM con il mio indirizzo email, se vuoi mandami un esempio e ci do un’occhiata.

Allora, ho dato un’occhiata al file che mi ha mandato @Simocigni e ho constatato che si tratta di un problema con openssl base64.
Prima avevo scritto:

Purtroppo non mi ero accorto che se la riga è troppo lunga, l’output non contiene tutto il file ma solo l’ultima porzione. La lunghezza varia, su una fattura ho ottenuto 74 byte su 552266, su un’altra 520 su 5896, ma non so il nesso.

Se invece si spezzano i dati base64 su più righe (da 70 caratteri per esempio), openssl funziona.

openssl base64 ha anche l’opzione -A, che si aspetta i dati base64 su una singola riga, ma in questo caso fallisce se i dati sono su più righe.

La conclusione è che non c’è un comando (né base64, né openssl base64) che sia in grado di decodificare tutti i possibili file (riga singola, righe multiple con separatori unix, righe multiple con separatori windows). Bisogna per forza di cose preprocessare il file per renderlo “digeribile” dal comando usato, oppure verificare se è su una singola riga e usare l’opzione apposita con openssl.

Io ho visto che usando sed o tr per rimuovere i CR passando poi l’output a base64 -d non ho mai eccezioni dato che se il CR non c’è sed non lo sostituisce…
E’ vero che magari nel 50% dei casi sto facendo un lavoro inutile ma visti i tempi di sed nell’elaborare un file perderei più tempo a capire se quello è un file dos oppure no…

Avendo a disposizione tutti i tool Unix, non è difficile portare i file nella forma voluta, ma @Simocigni lavora in windows dove i comandi sed e tr non ci sono (e nemmeno base64).
Volendo ci sono delle versioni dei tool Unix per windows compilate nativamente (senza doversi portare dietro tutto cygwin).

su windows effettivamente tanti tools da command line mancano, ma esistono come componenti in .net
Se dovessi usare windows probabilmente non userei neanche openssl ma direttamente le classi .net
Per fortuna posso usare linux :slight_smile:

Noi infatti abbiamo implementato tutto in .NET (anche se lo facciamo girare sotto Linux).

Però vedo sul forum che c’è più di qualcuno che usa PHP sotto Windows, quindi è difficile da fare sia direttamente in PHP che passando il tutto ad un comando esterno. La decodifica base64 però la si può fare facilmente in PHP.