In una burocrazia che, seppur lentamente, spinge sempre più su digitale e dematerializzazione, sono ormai da qualche anno diventate di uso quotidiano le firme digitali.
La loro incarnazione maggiormente conosciuta si presenta come file con estensione p7m: un contenitore digitale per uno o più documenti firmati.

In effetti data la loro diffusione recentemente mi è capitato di dover rendere disponbile un’utility per l’apertura e la verifica di file p7m a tutti gli utenti di un’azienda. Come fare?

Le alternative gratuite disponibili non mi convincevano pienamente per vari motivi: alcune applicazioni installabili sui PC richiedono privilegi elevati per gli aggiornamenti, mentre i siti web online richiedono il caricamento dell’intero file, il che può essere problematico soprattutto se si tratta di documenti sensibili all’interno dell’azienda.

Quindi?
<spoiler>WebAssembly e OpenSSL</spoiler>

CreeP7M

CreeP7M è un’utility per estrarre e verificare file p7m all’interno del browser web senza inviare il file a terze parti, se vuoi conoscerne i dettagli vai pure al paragrafo successivo, altrimenti sentiti libero di usarla qui sotto!

Seleziona un documento p7m, il file rimane sul tuo PC

Quando da cosa nasce cosa

Va bene sei arrivato fino a qui, ti meriti un giusto approfondimento, diciamo un perchè e un percome.
Giusta o sbagliata che sia, l’idea di lavorare server-side non mi piaceva, non mi restava quindi che usare qualcosa lato client, vuoi che qualcuno non abbia già fatto una libreria JS?!
Risposta: NO!
(ho scoperto solo in seguito dell’esistenza di PKI.js)

Mi sono quindi imbattuto in questo articolo su quoll.it, dove molto chiaramente viene spiegato l’uso di OpenSSL applicato ai file p7m.
BAM! Illuminazione!
Era da tanto che sentivo parlare di WebAssembly e mi è sembrata l’occasione giusta per giocarci ed imparare qualcosa di nuovo compilando appunto OpenSSL in wasm.

P7M con OpenSSL e WebAssembly = CreeP7M

Se si parla di Certificati, e su questo si basano le firme p7m, OpenSSL è la madre, il padre, genitore N, fate voi, della stragrande maggioranza delle implementazioni.

L’idea di base è quindi utilizzare OpenSSL per tutte le operazioni necessarie:

  • Estrazione file
  • Estrazione dati di firma
  • Verifica verso Certification Authorities conosciute
  • Controllo CRL

Senza entrare troppo nel tecnico, tanto potete vedere il sorgente su GitHub, il risultato è un binario OpenSSL.wasm di circa 2.5 MB.
CreeP7M non fa altro che utilizzarlo come una normale applicazione da riga di comando, quindi anche eventuali modifiche o nuove funzionalità sono facilmente implementabili.

Ma veramente verifica i file p7m offline?

La risposta è inequivocabilmente sì, il contenuto del file non viene mai inviato a nessun servizio esterno.
Per quanto riguarda la verifica, sono però richiesti degli “attori” terzi: delle autorità di certificazione autorevoli (CA).

Le CA utilizzate sono quelle definite a livello Europeo e vengono quindi importate di default dal sito istituzionale eidas.ec.europa.eu.

Ogni CA deve esporre una CRL statica o un responder OCSP per la verifica dello stato di revoca dei certificati emessi.
Qui la cosa si fa leggermente tricky: nessuno di questi servizi è interrogabile via JS senza che essi ritornino degli opportuni headers CORS.

L’unica soluzione è usare un servizio di cors-proxy che aggiunga questi headers, se ci fate caso infatti l’inizializzazione di CreeP7M avviene passandogli (opzionali) sia l’URL da cui scaricare le CA, sia l’URL di un cors-proxy a nostra scelta (molto meglio se gestito da noi).

1
2
3
4
const CP7M = new CreeP7M(
'https://eidas.ec.europa.eu/efda/tl-browser/api/v1/browser/tl/IT',
'https://www.itsbalto.com/f/cors-proxy/?apiurl='
);

Le CA vengono salvate nella cache del browser per 15 giorni

Conclusioni

Come sempre lo scopo ultimo è rendere la vita dei nostri utenti più semplice e digitalmente sicura, pertanto se avete suggerimenti sarò felice di ascoltarli.
Intanto ho fatto il battesimo nel mondo del WebAssembly e ho il sentore che presto troverò nuove applicazioni su cui cimentarmi, e voi?
Avete avuto esperienze con WebAssembly? Sono curioso di sentirle nei commenti.