%% cryptoapp.tex (was ssl.tex)
%%
%% Copyright (C) 2006-2018 Simone Piccardi and Truelite Srl.
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%%
%% Sicurezza: Sezione su SSL e dintorni
%%
%% S. Piccardi Jan. Apr 2006
%% 
\chapter{Le applicazioni della crittografia}
\label{cha:SSL_PKI}


\section{Infrastrutture di chiave pubblica}
\label{sec:PKI}

Come primo passo nell'affrontare la trattazione delle varie applicazioni della
crittografia ai servizi di sicurezza, è necessario introdurre alcuni concetti
di base sulle cosiddette \textsl{infrastrutture di chiavi pubbliche} dato che
queste vengono a costituire un quadro concettuale comune utilizzato, sia pure
in modi diversi, da tutte quelle applicazioni che usano la crittografia sia
per la riservatezza dei dati, che per i servizi di identificazione ed
autenticazione.


\subsection{Breve introduzione alle \textit{PKI}}
\label{sec:PKI_intro}

Uno dei punti chiave di qualunque politica di sicurezza è quello della
gestione dei servizi di identificazione e di autenticazione già illustrati in
sez.~\ref{sec:security_services}; un tentativo di risolvere in maniera
generica questo problema è quello effettuato tramite l'uso delle cosiddette
\textsl{infrastrutture di chiavi pubbliche}, comunemente note sotto la sigla
\itindex{Public~Key~Infrastructure~(PKI)} \textit{PKI}, che sta per
\textit{Public Key Infrastructure}.

Abbiamo visto in sez.~\ref{sec:crypto_asymmetric} e sez.~\ref{sec:crypto_hash}
come la crittografia chiave asimmetrica oltre a fornire un meccanismo molto
comodo per la gestione di comunicazioni riservata, permette, quando abbinata
alle funzioni di hash crittografico, di realizzare funzionalità di verifica
dell'integrità. Questo tipo di utilizzo può essere esteso ed organizzato in
maniera da fornire servizi di autenticazione, identificazione e
\index{firma~digitale} firma digitale.

L'idea è che dimostrando di avere la chiave privata corrispondente ad una
certa chiave pubblica posso dimostrare la mia identità, cosa che può essere
utilizzata con meccanismi di \textit{challenge and response},\footnote{si
  chiamano così quelle tecniche che prevedono una \textsl{sfida} a cui bisogna
  saper dare una \textsl{risposta}: usualmente il procedimento viene eseguito
  tramite l'invio di un segreto (in metodo più comune è quello di un numero
  casuale cifrato con la chiave pubblica del destinatario), che bisogna
  restituire decifrato, (che nel caso si può fare solo con il possesso della
  chiave privata).} per effettuare una autenticazione.\footnote{come ad
  esempio si fa con l'autenticazione a chiavi di SSH.}  Al contempo l'uso
delle funzioni di hash crittografico combinato alla cifratura con la chiave
privata, permette di ottenere la firma digitale, in cui allo stesso tempo si
dimostra sia la provenienza che l'integrità delle informazioni.

Fintanto che si resta in un ambito in cui è possibile eseguire un controllo
diretto della corrispondenza fra una coppia di chiavi ed il relativo
possessore non serve nient'altro, ma quando si cerca di applicare tutto questo
in maniera generica nei confronti di chiunque, riemerge il problema degli
attacchi di \itindex{man-in-the-middle} \textit{man-in-the-middle} di cui
abbiamo parlato in sez.~\ref{sec:crypto_asymmetric}.  Occorre allora un
ulteriore meccanismo che consenta di verificare la corrispondenza fra una
chiave pubblica e l'identità a cui la si associa (che questa sia una persona o
altro).

In teoria con PKI si dovrebbe indicare in maniera assolutamente generica
quell'insieme di procedure, applicazioni, entità che consente di gestire,
creare, diffondere e mantenere l'associazione fra una determinata chiave
pubblica e l'identità a questa abbinata che ne potrà fare uso per i citati
servizi di identificazione e autenticazione, in modo che chiunque possa essere
confidente della validità di questa associazione, risolvendo il problema del
\itindex{man-in-the-middle} \textit{man-in-the-middle}.

Quasi sempre però piuttosto che a questa definizione generica, la sigla PKI fa
riferimento all'implementazione di uno dei possibili modelli strutturali che
cercano di dare una risposta a queste problematiche, ed anche noi nel seguito
di questa sezione faremo riferimento a questa accezione, quello che si basa
sull'idea di delegare la verifica della corrispondenza fra chiavi
crittografiche ed identità ad una entità terza (il cosiddetto TTP, o
\itindex{Trusted~Third~Party~(TTP)} \textit{Trusted Third Party}) che si
presuppone essere fidata senza verifica e che viene a svolgere un ruolo affine
a quello di un notaio.

Questo comunque non è l'unico modello possibile, dato che presenta un
importante punto critico nel dilemma costituito dal fatto che si ripone una
fiducia incondizionata in chi svolge il ruolo di \textit{Trusted Third Party},
che potrebbe non meritarla. Esiste pertanto un altro modello strutturale che è
quello del cosiddetto \textit{web of trust}, scelto da programmi come PGP e
GPG, che tratteremo in sez.~\ref{sec:web_of_trust}.

Inoltre benché l'idea di \textit{Trusted Third Party} sia implementabile in
modi diversi, la modalità principale in cui oggi viene realizzata è attraverso
le cosiddette \textit{Certification Authority}, (in breve CA), una serie di
soggetti a cui è delegato, con una forma alquanto complessa ed tutt'altro che
scevra da problemi di affidabilità e sicurezza, questo compito. Quello delle
CA è il modello a cui fa riferimento il protocollo SSL (che tratteremo con
maggiori dettagli in sez.~\ref{sec:ssl_intro}) che è quello più utilizzato per
fornire riservatezza e verifica dell'identità nei servizi di rete.


\subsection{Chiavi, certificati e \textit{Certification Authority}}
\label{sec:pki_certificates}

\itindbeg{Certification~Authority~(CA)}

Il componente di base su cui si costruisce una PKI basata sulle CA è il
cosiddetto \textsl{certificato digitale} (in inglese \textit{public key
  certificate} o \textit{digital identity certificate}). Dal punto di vista
realizzativo questo non è altro che un file che contiene la chiave pubblica di
una coppia di chiavi asimmetriche, a cui vengono aggiunte una serie di dati il
più importante dei quali è la \index{firma~digitale} firma digitale rilasciata
dell'entità (la \textit{Certification Authority}) che attesta l'autenticità
delle informazioni (la chiave ed il resto) riportate nel certificato stesso.

Un utente potrà usare il suo certificato insieme alla
\textsl{chiave}\footnote{nella terminologia delle PKI si parla sempre di
  \textsl{certificato} e \textit{chiave}, dal punto di vista crittografico il
  primo corrisponde alla chiave pubblica, la seconda alla chiave privata.} ad
esso associata per stabilire una comunicazione cifrata con la procedura di
\itindex{Diffie-Hellman} \textit{Diffie-Hellman} (o altro meccanismo
equivalente), potrà usarlo per effettuare firme digitali, e potrà usare la
chiave per decifrare messaggi che siano stati cifrati con il suo certificato,
esattamente come si fa con una qualunque coppia di chiavi asimmetriche.

La differenza con la chiave pubblica di una ordinaria coppia di chiavi
asimmetriche sta nel fatto chi riceve il certificato ottiene anche le
informazioni aggiuntive, fra cui appunto la \index{firma~digitale} firma
digitale del certificato stesso e detta firma copre non solo la chiave
pubblica, ma anche i dati aggiuntivi presenti nel certificato, garantendone
autenticità ed integrità nei confronti di attacchi di
\textit{man-in-the-middle}. Sulla base della verifica di quest'ultima si potrà
dedurre l'autenticità, nel senso di corrispondenza all'identità proclamata,
sia della chiave pubblica che delle informazioni presenti nel certificato.

L'idea di base di una PKI strutturata in questo modo è che, avendo una firma
all'interno di un certificato, la si potrà usare per verificarne l'autenticità
con il certificato di chi l'ha apposta. È sempre possibile infatti usare un
certificato per firmarne un altro,\footnote{questa affermazione in termini
  stretti è scorretta, in quanto non si usa un certificato per firmarne un
  altro, ma si usa la chiave ad esso associata, ed il certificato (che
  contiene una chiave pubblica) serve solo per fare la verifica della firma;
  per semplicità espositiva si parla spesso di certificato firmato con un
  altro certificato, dando per sottinteso che si sta facendo riferimento alla
  chiave associata quest'ultimo.} e questo è il meccanismo che consente di
delegare il compito di garantire la effettiva correttezza dei dati presenti in
un certificato all'\textsl{ente certificatore} (la \textit{Certification
  Authority}) poi lo firmerà. In questo modo ci si deve preoccupare di
ottenere in maniera fidata solo il certificato della CA, riducendo di molto il
rischio di attacchi di \itindex{man-in-the-middle} \textit{man-in-the-middle}.

Questo comporta anche un cambiamento nella modalità con cui si effettua
l'autenticazione usando il certificato. Nel meccanismo classico, ad esempio
quello usato da SSH, ci si limitava a verificare che chi presentava il
certificato avesse la corrispondente chiave pubblica, dando per scontato che
il certificato fosse ``\textsl{autentico}''. In questo caso basta controllare
che il certificato sia valido con la firma in esso contenuta. Pertanto non è
più necessario verificare direttamente le chiavi pubbliche di ogni
corrispondente, e l'unico certificato della cui autenticità occorre
preoccuparsi in prima persona è quello della \textit{Certification Authority}.

Resta ovviamente il problema di come verificare la correttezza del certificato
dell'ente certificatore rispetto ad attacchi \itindex{man-in-the-middle}
\textit{man-in-the-middle}. Questo semplicemente non è possibile, dato che a
questo punto non esiste più un terzo a cui rivolgersi che possa garantire per
lui, per cui si deve assumere il rischio e darlo per valido senza conferme.
Per questo il caso più comune per i certificati usati dalle
\textit{Certification Authority} è che sono autofirmati.  Questo significa che
una CA attesta da se stessa la validità del proprio certificato, firmandolo
con la chiave ad esso associato.

Questo problema di fiducia è meno teorico di quanto si possa pensare, infatti
ci sono da sempre serie critiche relative alla scarsa qualità dei controlli
posti in atto dalle varie \textit{Certification Authority}, che in molti casi
si sono dimostrati tutt'altro che adeguati; si tenga presente infatti che
basta che una \textit{Certification Authority} sia sovvertita o segua
procedure poco sicure emettendo certificati senza verifiche sufficienti per
compromettere la sicurezza di tutto il sistema, che è condizionata da quella
del suo anello più debole.

Resta inoltre aperto un problema tutt'altro che banale relativo a questo
modello; quello della distribuzione dei certificati e della verifica degli
stessi.  Quando il sistema è nato si era pensato di ricalcare il meccanismo
degli elenchi telefonici in uso nelle telecomunicazioni, un meccanismo molto
complesso associato allo standard X.509,\footnote{da cui è tratto anche lo
  schema dei dati originale di LDAP, nato anche questo per mantenere rubriche,
  e poi trasformatosi in un servizio generico, e parte della nomenclatura
  resta la stessa, per un approfondimento si consulti il capitolo di
  \cite{IS-LDAP}.}  per cui sarebbe stato possibile creare una gerarchia nella
distribuzione usando le informazioni contenute nei certificati stessi, con
delle relazioni di dipendenza che facessero ottenere in maniera diretta i
certificati di un attore finale attraverso una ricerca nella gerarchia dei
fornitori, in cui a ciascun livello sarebbe stata presente una
\textit{Certification Authority} che certificava quella del livello
successivo, con una singola \textit{Certification Authority} radice da cui
sarebbero state certificate tutte le altre.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|l|p{8cm}|}
    \hline
    \textbf{Sigla}&\textbf{Nome} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{C} &\textit{Country}& Il paese, espresso con il codice a due
                                  lettere usato anche per la localizzazione e
                                  i domini di primo livello, ad 
                                  esempio \texttt{C=IT}.\\ 
    \texttt{ST}&\textit{State}  & Lo stato\footnotemark\ (negli USA) o la 
                                  provincia, ad esempio \texttt{ST=FI}.\\ 
    \texttt{L} &\textit{Locality}&La località, come la città o il comune, ad
                                  esempio \texttt{L=Firenze}.\\
    \texttt{O} &\textit{Organization}&Il nome dell'organizzazione o della
                                  società, ad esempio
                                  \texttt{O=Truelite Srl}.\\ 
    \texttt{OU}&\textit{Organizational Unit}& Il nome dell'unità operativa (il
                                  dipartimento o la sezione)
                                  della precedente organizzazione, ad esempio
                                  \texttt{OU=IT department}.\\
    \texttt{CN}&\textit{Common name}&Il nome dell'identità a cui si fa
                                  riferimento, che può essere a seconda dei
                                  casi un nominativo, un indirizzo di posta o
                                  un nome a dominio, ad esempio
                                  \texttt{CN=www.truelite.it}.\\ 
    \hline
  \end{tabular}
  \caption{Le informazioni di identificazione presenti nei certificati.} 
\label{tab:x509_informations}
\end{table}

\footnotetext{stato deriva dalla visione centrata sugli Stati Uniti, in cui lo
  stato fa riferimento ad uno degli stati dell'unione, e che altrove è stato
  associato a realtà territoriali considerate equivalenti, in Italia in genere
  si fa riferimento a una provincia.}

Questo approccio comportava una specifica scelta delle informazioni di
identificazione inserite all'interno del certificato, che dovevano appunto
seguire il modello gerarchico dello standard X.509, che prevede una
suddivisione di stampo geografico, con indicazioni relative allo stato, alla
località ed alla organizzazione, un po' come si organizzano gli elenchi del
telefono. Per questo le informazioni previste erano quelle riportate nello
schema illustrato in tab.~\ref{tab:x509_informations}. Ripercorrendo la
gerarchia a partire dal livello più alto (il singolo stato) a quello più basso
(una unità interna ad una organizzazione) si sarebbe potuto ottenere il
certificato relativo al singolo appartenente alla stessa.

Però, in mancanza di una autorità centrale che stabilisse questa gerarchia, e
visto anche lo scarso interesse delle varie organizzazioni che avrebbero
dovuto usarla come utenti (in particolare di quelle private) a rendere
pubblica la loro struttura organizzativa interna, la gerarchizzazione
descritta è mai stata realizzata, ed invece sono nate invece una serie di
\textit{Certification Authority} totalmente indipendenti fra loro e senza
nessuna relazione gerarchica, e non è mai stato realizzato nessun sistema di
distribuzione diretta dei certificati. Tra l'altro l'avere impostato tutta
l'architettura in forma gerarchica rende ora estremamente complesso realizzare
relazioni di fiducia paritarie in cui due CA si attestano reciprocamente la
loro validità.

Le informazioni di identificazione previste dallo standard X.509 sono però
rimaste all'interno del formato dei certificati anche se ai nostri giorni
buona parte di esse non risultano di nessuna utilità, o vengono usate per
contenuti del tutto diversi da quelli indicati in
tab.~\ref{tab:x509_informations}. Il solo dato che viene effettivamente usato
resta quello del \textit{Common Name} che in molti casi è l'unica informazione
utilizzata per determinare l'identità a cui il certificato è associato, cosa
che tra l'altro pone problemi tutt'altro che banali in caso di omonimia. Per i
nomi a dominio infatti non ci sono problemi, essendo questi univoci, ma la
cosa diventa assai complicata con i certificati personali ad uso dei programmi
di posta.

Oltre alle informazioni di tab.~\ref{tab:x509_informations}, che sono indicate
dal soggetto che richiede il certificato per identificarsi,\footnote{anche se
  nella pratica in genere l'unica informazione che un richiedente può
  stabilire è quella del \textit{Common Name}, le altre in genere vengono
  sovrascritte dalla CA quando firma il certificato.} e che vengono inserite
in quella che si chiama una \itindex{Certificate~Signing~Request~(CSR)}
\textit{Certificate Signing Request} (o CSR),\footnote{si tratta in genere di
  un file in cui, sempre in opportuno formato (in genere PEM), si inserisce la
  chiave pubblica e le suddette informazioni pubbliche, così che poi una
  \textit{Certification Authority} possa firmarle.}  all'interno di un
certificato vengono riportati una serie di altri dati che vengono inseriti
dalla \textit{Certification Authority} al momento della firma. Le informazioni
vengono raggruppate in diverse sezioni (che si sono riportate in
tab.~\ref{tab:x509_sections}) ciascuna della quale è identificata da un nome
ed il cui contenuto è stato definito da vari standard. Si noti come in
tab.~\ref{tab:x509_sections} non viene citata la firma digitale, questa
infatti non fa parte dei dati ivi descritti, ma certifica la validità degli
stessi.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Sezione}&\textbf{Significato}\\
    \hline
    \hline
    \textit{Version}  &     Versione dello standard X.509 usato (oggi il 
                            valore in uso è sempre 3).\\ 
    \textit{Serial Number}& Numero seriale del certificato; ogni CA assegna un
                            seriale a ciascun certificato che firma, usato per
                            identificarlo ad esempio nelle liste di revoca
                            (CRL).\\
    \textit{Signature Algorithm}& Algoritmo crittografico usato per la firma,
                            identificato dal suo nome convenzionale.\\ 
    \textit{Issuer}       & I dati identificativi dell'ente che firma il
                            certificato, espressi in forma compatta con le
                            sigle di tab.~\ref{tab:x509_informations}.\\  
    \textit{Validity}     & L'intervallo di validità del certificato, con la
                            data di inizio e la data di scadenza.\\ 
    \textit{Subject}      & I dati identificativi del soggetto del
                            certificato, espressi sempre con le sigle di
                            tab.~\ref{tab:x509_informations}.\\  
    \textit{Subject Public Key Info}& La chiave pubblica del certificato, che
                            comprende sia il valore della chiave stessa, che
                            il tipo di chiave usata (ad esempio se RSA, DSA o
                            di altro tipo).\\ 
    \textit{X509v3 extensions}& Una serie di estensioni che consentono di
                            aggiungere informazioni aggiuntive previste dalla
                            terza revisione dello standard X.509.\\ 
%    \textit{}& .\\ 
    \hline
  \end{tabular}
  \caption{Le sezioni in cui sono suddivisi i dati inseriti nei certificati.} 
\label{tab:x509_sections}
\end{table}


Fra i dati di tab.~\ref{tab:x509_sections} uno dei più importanti è quello
relativo al periodo di validità del certificato della sezione
\textit{Validity}, in cui vengono inserite una data di inizio ed una data di
scadenza, oltre la quale, pur restando corretta la firma, il certificato non
verrà più considerato valido. La scadenza serve ad evitare la permanenza di
certificati validi relativi ad identità magari non più esistenti, ma
soprattutto a garantire a chi gestisce le CA un reddito continuativo per il
rinnovo.

Le estensioni del protocollo (quelle della sezione \textit{X509v3 extensions})
consentono inoltre di indicare altri dati significativi. Fra questi ad esempio
è possibile indicare la tipologia di uso del certificato,\footnote{il dato si
  chiama \textit{Netscape Cert Type}, e prevede tipologie indicate come
  \textit{SSL Client}, \textit{S/MIME}, \textit{Object Signing}, \textit{SSL
    Server}.}  se si tratta di un certificato personale per la firma digitale,
o di un certificato di un server o di quello di un client.\footnote{ad esempio
  nel protocollo SSL alcuni client non riconoscono come valido il certificato
  di un server che contattano se questo non viene qualificato come \textit{SSL
    Server} nel campo \textit{Netscape Cert Type}.}  Un'altra informazione
importante, sempre inserita all'interno delle estensioni, è quella di poter
indicare delle ulteriori identità alternative, da aggiungersi ai dati indicati
nel \textit{Common Name} della sezione \textit{Subject}.\footnote{il dato
  viene identificato come \textit{X509v3 Subject Alternative Name}, e prevede
  indicazioni di nomi, indirizzi IP o nomi a dominio alternativi (ci
  ritorneremo in sez.~\ref{sec:openssl}) che per chi supporta questa
  estensione risultano validi come se fossero stati inseriti nel
  \textit{Common Name}.}

Come già detto, in assenza di un meccanismo centralizzato di distribuzione dei
certificati validi in tempo reale da parte delle \textit{Certification
  Authority} e del proliferare di queste ultime, uno dei punti critici del
sistema è quello dell'aggiornamento dei dati in caso di compromissione di un
certificato. Per quanto riguarda le \textit{Certification Authority} in genere
quello che accade è che una lista dei loro certificati viene distribuita
direttamente da loro sul web o inclusa direttamente nei programmi (questo è ad
esempio quello che avviene con i browser web), ed essendo questi in numero
limitato ed in genere piuttosto controllati il problema veniva considerato non
significativo,\footnote{salvo poi rivelarsi estremamente serio con la
  compromissione di una CA e conseguente emissione di certificati falsi validi
  intestati a domini di grande rilevanza, cosa che ha costretto gli
  sviluppatori dei browser più usati ad inserire delle patch ad hoc per
  escludere questi singoli certificati (dato che escludere il certificato
  della CA avrebbe reso invalidi tutti i certificati da essa firmati)
  mostrando quanto possa essere fragile il sistema.} e non è pertanto prevista
nessuna procedura specifica per affrontarlo (questo significa che in sostanza
i certificati radice non sono revocabili).

La compromissione dei certificati degli utenti è invece considerata
eventualità assolutamente normale, ed è prevista una contromisura specifica
nella forma delle cosiddette \itindex{Certificate~Revocation~List~(CRL)}
\textit{Certificate Revocation List} o CRL. Il meccanismo prevede che in caso
di compromissione del suo certificato un utente debba notificare l'avvenuto
alla propria \textit{Certification Authority} la quale provvederà ad inserire
il numero seriale dello stesso all'interno di questa lista di certificati
revocati. Un altro utente potrà così accorgersi, utilizzando detta lista,
dell'avvenuta compromissione e non considerare più valido detto certificato. É
compito delle \textit{Certification Authority} compilare e pubblicare queste
liste (che sono da loro firmate), e questo in genere avviene esattamente, come
per i propri certificati, tramite sito web.

Il grandissimo problema di tutto ciò è che è facoltà dell'utente finale
effettuare il controllo di una eventuale revoca, e che se decide di farlo è
lui che deve curarsi di ottenere una CRL aggiornata dalla sua CA, verificare
che il certificato esaminato non vi compaia e solo allora passare alla
verifica della firma. La cosa comporta un notevole aggravio gestionale anche
perché a differenza del certificato della CA, che si scarica in sostanza una
volta sola e che molti programmi inseriscono direttamente al proprio interno,
le CRL devono essere mantenute continuamente aggiornate, e questo per tutte le
CA esistenti, che finiscono per l'avere meccanismi di distribuzione diversi e
tutt'altro che coordinati.

La conseguenza è che il meccanismo di gestione della revoca dei certificati
comporta una notevole complicazione della gestione totalmente a carico
dell'utente finale dato che non è mai stato previsto un sistema automatico di
applicazione delle CRL.\footnote{anche se in conseguenza dei problemi che ciò
  comporta ne sono stati proposti alcuni che dovrebbero effettuare il
  controllo in tempo reale, solo che a questo punto verrebbe da chiedersi
  perché non distribuire direttamente i certificati validi.} Il risultato è
che nella stragrande maggioranza dei casi il meccanismo risulta troppo oneroso
e complesso e le CRL vengono completamente ignorate. 

Benché l'effettiva sicurezza del modello delle PKI basate sulle
\textit{Certification Authority} possa essere soggetta a parecchi dubbi,
illustrati nelle pagine precedenti, esso resta dominante in particolare per la
sua applicazione nel protocollo SSL che tratteremo in
sez.~\ref{sec:ssl_intro}. Inoltre questi problemi emergono nella sua
applicazione a livello globale, e non si pongono affatto qualora si voglia
utilizzare una CA propria di cui si abbia un controllo diretto. Per questo
motivo i concetti esposti in questo paragrafo torneranno utili in molte altre
occasioni, dato che sono parecchi i programmi che fanno uso di chiavi e
certificati per garantire riservatezza ed identificazione.

\itindend{Certification~Authority~(CA)}

\subsection{Il protocollo SSL/TLS e il programma \texttt{stunnel}}
\label{sec:ssl_intro}

La principale applicazione del modello di PKI basato sulle
\textit{Certification Authority} descritte in sez.~\ref{sec:pki_certificates} è
quella del protocollo SSL (oggi ribattezzato TLS) che si appoggia a questo
tipo di infrastruttura per introdurre un maggiore livello di sicurezza nei
protocolli di rete.  Come accennato anche in sez.~\ref{sec:security_risk}
infatti i protocolli di rete non forniscono nessuna forma di autenticazione né
di riservatezza nella comunicazione, pertanto diventa possibile sia spacciarsi
per altri che intercettare il traffico in maniera tutto sommato molto
semplice.

Una delle possibili risposte a questo problema è stata quella di definire un
protocollo specifico, originariamente chiamato
\itindex{Secure~Socket~Layer~(SSL)} SSL (sigla che sta per \textit{Secure
  Socket Layer}), che si interponesse fra i protocolli del livello di
trasporto e quelli di applicazione,\footnote{tratteremo in
  sez.~\ref{sec:VPN_IPSEC} un diverso approccio al problema.} per introdurre
meccanismi di autenticazione e verifica dell'identità del corrispondente e di
cifratura del traffico.

Il protocollo SSL originale venne sviluppato da Netscape Corporation
principalmente come risposta al problema di consentire un accesso sicuro ai
siti web, nell'ottica di favorire il commercio elettronico. Il protocollo
nacque come \textsl{strato} intermedio fra il TCP i vari possibili protocolli
del livello applicativo; all'inizio era usato per HTTP, ma è utilizzabile in
generale con qualunque protocollo che usi TCP.

Il concetto è che una applicazione, invece di scrivere direttamente su un
socket TCP, utilizzi uno speciale ``\textsl{socket sicuro}'' gestito dal
protocollo. Tutte le operazioni di apertura del socket con la verifica del
corrispondente e tutte le successive operazioni di cifratura dei dati prima
della loro trasmissione sulla rete attraverso un socket ordinario vengono
gestite dal protocollo. In sostanza una applicazione deve solo utilizzare le
funzioni di libreria per creare il \textsl{socket sicuro} e poi usarlo come se
fosse un socket ordinario.

La prima versione ampiamente diffusa del protocollo SSL, nato come standard
industriale basato sulle specifiche interne create da Netscape, è stata la
2.0, L'azienda pubblicò successivamente in forma di \textit{Internet Draft}
(ormai scaduto) un proposta per la successiva versione 3.0, che forniva alcune
correzioni per prevenire alcuni attacchi, ampliava gli algoritmi di cifratura
utilizzabili ed introduceva il supporto per le catene di certificati.

Questa bozza, pubblicata nel 1996, divenne la base su cui l'IETF sviluppò una
standardizzazione non più proprietaria, cambiando però nome al protocollo in
\itindex{Transport~Layer~Security~(TLS)} \textit{Transport Layer Security} (in
breve TLS). La prima versione è stata il TLS 1.0 (classificato anche come SSL
3.1) che è definito
nell'\href{http://www.ietf.org/rfc/rfc2246.txt}{RFC~2246}. Il protocollo è
stato soggetto ad ulteriori perfezionamenti,\footnote{nel 2006 è stata
  rilasciata la versione 1.1 (SSL 3.2) definita
  dall'\href{http://www.ietf.org/rfc/rfc4346.txt}{RFC~4346}, nel 2008 è stata
  rilasciata la versione 1.2 (SSL 3.3) definita
  dall'\href{http://www.ietf.org/rfc/rfc5246.txt}{RFC~5246}.} e nel seguito ci
riferiremo ad esso in modo generico sia con la sigla TLS che con la sigla SSL.

Come accennato SSL nasce per garantire un accesso sicuro (cifrato ed
autenticato) ai siti web, così che si potesse essere sicuri di comunicare in
maniera non intercettabile con l'interlocutore scelto e si potesse essere
garantiti sull'identità di quest'ultimo. Il protocollo, astraendo
l'interfaccia di programmazione dei socket, è comunque generico e può essere
usato con qualunque tipo di comunicazione tanto che oggi viene usato da una
grande varietà di servizi di rete.

A grandi linee\footnote{una trattazione dettagliata va al di là dello scopo di
  questo testo, per approfondire si può consultare
  \url{http://en.wikipedia.org/wiki/Transport_Layer_Security}.} il
funzionamento del protocollo può essere diviso in tre passi principali. Il
primo passo, che viene svolto in fase di creazione del socket sicuro, prevede
che venga effettuata una negoziazione fra i due capi della connessione sugli
algoritmi di crittografia, le eventuali compressioni dei dati e la versione di
protocollo da usare, in modo da accordarsi su una scelta che sia utilizzabile
da tutti e due. Il protocollo prevede che venga usata la versione più recente
del protocollo supportata da entrambi, mentre si possono indicare delle
preferenze per gli algoritmi di cifratura in fase di configurazione.

Il secondo passo, sempre in fase di creazione del socket sicuro, prevede lo
scambio delle chiavi e la verifica dell'identità del corrispondente che viene
stabilita proprio usando il modello di PKI basato sulle \textit{Certification
  Authority} illustrato in sez.~\ref{sec:pki_certificates}.  Normalmente è il
server che deve autenticarsi presso il client presentando un certificato
valido in quanto firmato da una delle \textit{Certification Authority}
riconosciute dal client, ma se non interessa si può ignorare l'autenticazione
per ottenere solo la cifratura del traffico, o può essere richiesta anche
l'autenticazione del client, che a questo punto dovrà presentare anche lui un
certificato al server che lo verificherà con le sue \textit{Certification
  Authority}.

Dato che la compromissione di una \textit{Certification Authority} è critica,
con TLS 1.0 è stato introdotto il supporto per le \textsl{catene di
  certificati} che consentono l'uso dei cosiddetti \textsl{certificati
  intermedi}. In questo caso una CA può delegare la firma dei certificati
finali degli utenti ad un \textsl{certificato intermedio}. Il meccanismo
prevede che una CA possa firmare con il suo certificato, (detto in questo caso
\textsl{radice}) un certificato intermedio, che questo ne possa firmare un
altro e così via, creando appunto una \textsl{catena di certificati} la cui
validità può essere verificata ripercorrendo all'indietro la catena fino ad
arrivare alla firma del certificato della CA sul primo certificato della
catena, in genere comunque per non complicare troppo le cose viene usato un
solo certificato intermedio.

Il vantaggio dell'uso dei certificati intermedi è che questi possono essere
sostituiti più facilmente in caso di compromissione in quanto vengono forniti
direttamente dal server all'interno della negoziazione fatta dal protocollo
SSL,\footnote{questo comporta che se il proprio certificato è firmato da un
  certificato intermedio nella configurazione di SSL occorrerà indicare
  opportunamente di fornire anche questo, a differenza di quanto avverrebbe
  per un certificato firmato direttamente da un certificato \textsl{radice}.}
per cui non è necessario che vengano sostituiti i certificati delle CA in
tutti i client ma basta sostituire i certificati intermedi sul server. In
questo modo si può pensare di applicare una politica di sicurezza estremamente
rigida sul certificato radice, usando sempre i certificati intermedi per
apporre le firme, riducendo così il rischio di compromissione del certificato
radice di una CA.

Una volta completato il secondo passo e verificata l'identità del
corrispondente, o dei corrispondenti qualora si richieda la mutua
autenticazione, l'ultimo passo prevede la determinazione di una chiave di
sessione sfruttando la crittografia a chiave asimmetrica. Da questo punto in
poi il socket sicuro sarà pronto per essere usato dalle applicazioni come un
socket normale e tutto il traffico inviato su di esso verrà automaticamente
cifrato e decifrato, e la sua integrità verrà garantita con la generazione
degli opportuni codici di controllo.

Originariamente il supporto del protocollo richiedeva l'uso diretto di una
porta dedicata per il traffico cifrato con SSL; ad esempio per i siti web si
usa la porta 443 e l'indicazione \texttt{https}, al posto della ordinaria
porta 80 e di \texttt{http}.  Con le versioni più recenti è possibile
utilizzare le porte dell'ordinario traffico in chiaro utilizzando un
meccanismo denominato \textit{STARTLS}, in cui, se supportato
dall'applicazione (in genere con una estensione del relativo protocollo
applicativo) si fa partire la negoziazione dalla connessione sicura
all'interno di una connessione in chiaro; questo tipo di applicazione è ad
esempio comune con i server di posta elettronica che prevedono una apposita
estensione del protocollo SMTP.

La parte in genere più complessa della gestione del protocollo SSL è quella
relativa alla indicazione dei certificati e delle chiavi da usare per la
verifica delle identità dei corrispondenti ed alle varie opzioni che
consentono di controllare le modalità con cui viene effettuata la creazione
dei socket sicuri. Dato che oggi nella gran parte dei casi il supporto per
l'uso del protocollo viene gestito direttamente tramite l'uso di opportune
librerie all'interno delle singole applicazioni,\footnote{esistono in realtà
  diverse implementazioni alternative del protocollo, come quella delle
  \texttt{libssl} del progetto OpenSSL, che ha alcuni problemi di
  compatibilità di licenza con la GPL, o quella delle \texttt{libtls} del
  progetto GNU, nata anche per risolvere detti problemi.}  ognuna di esse
fornisce anche le proprie direttive di configurazione.

Non tratteremo quindi la configurazione di SSL, dato che questa varia da
applicazione ad applicazione, ma prenderemo invece in esame il programma
\index{comando!\texttt{stunnel}} \texttt{stunnel} che, come dice il nome,
consente di creare dei \textsl{tunnel} fra traffico in chiaro e traffico
protetto da SSL e che consente di fare usare il protocollo anche da
applicazioni che non lo supportano direttamente. Il programma infatti è in
grado sia di accettare connessioni SSL, decifrare il traffico e reinoltrarlo
in chiaro su un socket ordinario, che di accettare connessioni in chiaro,
eseguire una connessione SSL e inviarvi sopra il traffico cifrato.\footnote{si
  fa riferimento solo a traffico TCP, \texttt{stunnel} non supporta UDP, anche
  se con TLS sono state introdotte estensioni del protocollo (\textit{Datagram
    Transport Layer Security} o DTLS) in grado di funzionare anche con UDP.}

Questo consente ad un client che supporta il protocollo SSL di connettersi ad
un servizio che non lo supporta tramite \texttt{stunnel} (usato nella
cosiddetta modalità server in cui accetta connessioni SSL e reinoltra il
traffico in chiaro) o viceversa far collegare ad un server con SSL un client
che non supporta il protocollo, usando \texttt{stunnel} per la connessione (in
modalità client, in cui riceve connessioni in chiaro e le reinoltra su
SSL). Infine mettendo in comunicazione fra loro due istanze, una in modalità
server e l'altra in modalità client, si potranno connettere usando il
protocollo anche applicazioni che non supportano SSL sia lato client che
server.

Il comportamento del programma viene determinato dal file di configurazione
passato come argomento, ma se non si indica niente di default viene usato
\index{configurazione!\texttt{/etc/stunnel/stunnel.conf}}
\texttt{/etc/stunnel/stunnel.conf}.\footnote{si fa riferimento alla versione 4
  del programma, ma dato che questa ha visto una completa revisione delle
  modalità di funzionamento è talvolta disponibile anche la versione 3 che ha
  una sintassi completamente diversa.} Si può inoltre usare l'opzione
\texttt{-fd} seguita da un numero per fargli leggere la configurazione dal
corrispondente file descriptor, per il quale si usa esclusivamente 0, per la
lettura dallo \textit{standard input}. Buona parte delle distribuzioni
provvedono inoltre il supporto per l'avvio automatico all'interno delle
procedure di bootstrap.\footnote{ad esempio Debian avvia una istanza per ogni
  file terminante in \texttt{.conf} che si trova in \texttt{/etc/stunnel/},
  preso come rispettivo file di configurazione (si deve però abilitare la cosa
  in \texttt{/etc/default/stunnel}).}

Il formato del file di configurazione è quello dei \texttt{.ini} di Windows
contenenti assegnazioni di valori a direttive di configurazione; nella parte
iniziale del file si impostano le caratteristiche generali di funzionamento
del programma, mentre per ogni tunnel che si vuole creare (il comando supporta
la gestione di più tunnel in contemporanea) si deve usare una apposita sezione
identificata da un nome fra parentesi quadre che indichi il relativo
servizio. È comunque possibile utilizzare le direttive specifiche per i
singoli tunnel anche globalmente nel qual caso verranno applicate come default
a tutti i tunnel creati.

Per una maggiore sicurezza si può far girare il programma in un
\itindex{chroot} \textit{chroot}, la relativa directory si imposta con la
direttiva \texttt{chroot}, nel qual caso si deve tener conto che tutti i
pathname che si specificheranno in seguito saranno relativi a detta
directory. Si può inoltre indicare con le direttive \texttt{setuid} e
\texttt{setgid} per conto di quale utente e gruppo eseguire il programma in
modo da fargli cedere i privilegi di amministratore.\footnote{ad esempio su
  Debian viene usato l'utente \texttt{stunnel4}, su RedHat/CentOS
  \texttt{stunnel}.}

Benché sia possibile specificarli per ciascun tunnel, in genere si indicano in
maniera generica anche i file relativi ai certificati necessari per l'uso di
SSL. La principale direttiva usata a tale scopo è \texttt{cert}, che serve ad
indicate il file contenente il certificato che \texttt{stunnel} deve
presentare ai propri corrispondenti. La direttiva è necessaria solo in
modalità server, dato che in modalità client, a meno che non sia richiesta la
mutua autenticazione, non è necessario presentare nessun certificato.

Il programma supporta solo il formato PEM (torneremo con qualche dettaglio in
più su questo in sez.~\ref{sec:openssl}) che ha il vantaggio di consentire
l'unione di più certificati in formato PEM in un singolo file con la semplice
concatenazione. Questo consente di inserire in unico file anche la chiave (che
però deve essere posta in testa al certificato) ed eventuali certificati
intermedi qualora il certificato necessitasse anche di questi; anche in
quest'ultimo caso l'ordine conta e questi devono essere inseriti nel file nel
relativo ordine gerarchico, con in fondo il certificato finale. È sempre
possibile comunque utilizzare la direttiva \texttt{key} per specificare in
sede separata il file della chiave, che contenendo informazioni sensibili deve
essere adeguatamente protetto e non leggibile da estranei.

Qualora invece si usi il programma in modalità client e si voglia verificare
il destinatario della propria connessione SSL occorrerà indicare quali CA si
intendono utilizzare per la verifica. Per questo si può utilizzare la
direttiva \texttt{CAfile} per indicare il file con il relativo certificato (o
i certificati, se sono più di una).  Si può inoltre indicare una CRL per
eliminare i certificati non più validi con \texttt{CRLfile}.

La direttiva che permette di determinare il comportamento del programma (se
cioè questo deve lavorare in modalità client o server) è \texttt{client}. Di
default infatti, se la direttiva non viene specificata, \texttt{stunnel} si
comporta come server, accettando connessioni in SSL e reinoltrandole in
chiaro. Se si definisce la direttiva come \texttt{yes} si attiva invece la
modalità client, e si può usare \texttt{stunnel} per reinoltrare su SSL
connessioni in chiaro. Si può impostare esplicitamente la modalità server
definendo la direttiva come \texttt{no}.

Una seconda direttiva che controlla il funzionamento del programma,
significativa principalmente per la modalità client, è \texttt{verify} che
imposta il livello di verifica richiesta in una connessione SSL, il default
infatti, se non la si usa, è di non controllare. La direttiva richiede un
valore numerico che indica un livello di verifica secondo quanto riportato in
tab.~\ref{tab:stunnel_conf}. In genere si usa il livello 2 per accertarsi, in
modalità client, di effettuare la connessione ad un server SSL corretto,
mentre il livello 3 viene usato principalmente per connessioni punto punto in
cui si richiede che il corrispondente presenti esattamente il certificato
indicato dalla direttiva \texttt{cert}.

Si tenga presente comunque che le verifiche eseguite da \texttt{stunnel}
quando si imposta un livello di verifica si basano esclusivamente sul fatto
che la firma del certificato sia valida rispetto alle CA utilizzate e che
questo non sia stato revocato (se si è indicata una CRL con le relative
direttive). Non viene ad esempio controllata la corrispondenza di un eventuale
nome a dominio contenuto nel certificato con quello usato per la effettuare la
connessione.

Per ogni tunnel che si crea si devono poi utilizzare le direttive
\texttt{accept} e \texttt{connect} per definire gli estremi del tunnel. La
sintassi è identica per entrambi, e nella forma \texttt{indirizzo:porta}, dove
sia l'indirizzo che la porta possono essere specificati in forma sia numerica
che simbolica. Si può indicare anche soltanto una porta omettendo l'indirizzo.

Con \texttt{accept} si imposta la porta locale su cui si accettano
connessioni, in questo caso se lo si vuole impostare l'indirizzo IP deve
essere uno di quelli assegnati alla macchina; se non si specifica nulla verrà
usato l'indirizzo generico. Il significato della direttiva dipende dalla
modalità di funzionamento scelta. In modalità server questa è la porta su cui
si accettano le connessioni SSL, mentre in modalità client si accettano le
connessioni in chiaro.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Direttiva}&\textbf{Significato}\\
    \hline
    \hline
    \texttt{chroot}& indica la directory da usare per il \textit{chroot}.\\ 
    \texttt{setgid}& gruppo per conto del quale eseguire il programma.\\ 
    \texttt{setuid}& utente per conto del quale eseguire il programma.\\ 
    \texttt{debug} & attiva la registrazione delle informazioni di debug da
                     specificare nella forma
                     \textit{facility.priority} usata dal
                     \textit{syslog}.\\  
    \texttt{compression}& algoritmo di compressione dei dati (prende i valori
                     \texttt{zlib} o \texttt{rle}), di default è disattivata.\\ 
    % \texttt{foreground}& prende i valori \texttt{yes} e \texttt{no} (il
    %                  default) lascia il programma attivo sul terminale a
    %                  scopo di controllo.\\ 
    \texttt{pid}   & indica il file su cui salvare il PID del processo,
                     (relativo alla directory specificata con
                     \texttt{chroot}).\\ 
    \hline
    \texttt{accept} & porta sulla quale si ricevono le connessioni.\\
    \texttt{CApath} & directory con i certificati della CA, nel formato delle
                      cosiddette \itindex{standard~certificate~directory} 
                      \textit{standard certificate directory} (vedi
                      sez.~\ref{sec:openssl}).\\
    \texttt{CAfile} & file con il certificato (o i certificati) delle CA.\\ 
    \texttt{client} & specifica se il programma deve agire come client, cioè
                      ascoltare per connessioni in chiaro e reinoltrare il
                      traffico su una connessione SSL, il default è il
                      contrario (si ascolta in SSL e si reinoltra in chiaro).\\ 
    \texttt{connect}& porta verso la quale ci si connette per reinoltrare il
                      traffico.\\  
    \texttt{CRLpath}& directory con i file delle CRL (indicizzati come per
                      \texttt{CApath}).\\  
    \texttt{CRLfile}& file con le \textit{Certificate Revocation List} dei
                      certificati da invalidare.\\ 
    \texttt{cert}   & file con il certificato (ed eventualmente la relativa
                      chiave e i necessari certificati intermedi).\\ 
    \texttt{key}    & file con la chiave del certificato (se su file
                      separato). \\ 
    \texttt{sslVersion}& versione del protocollo da utilizzare, prende i valori
                      \texttt{all}, \texttt{SSLv2}, 
                      \texttt{SSLv3} e \texttt{TLSv1}.\\
    \texttt{verify} & livello di verifica del corrispondente
                      richiesto nella connessione SSL, i possibili valori
                      sono: \texttt{1}, se esiste il certificato del
                      corrispondente, deve essere valido; \texttt{2}, il
                      certificato del corrispondere deve esistere ed essere
                      valido; \texttt{3}, il certificato deve corrispondere a
                      quello indicato localmente; se non si specifica nulla
                      non viene eseguita nessuna verifica.\\ 
%    \texttt{}& .\\ 
    \hline
  \end{tabular}
  \caption{Le direttive per il file di configurazione di \texttt{stunnel}.} 
\label{tab:stunnel_conf}
\end{table}

Viceversa con \texttt{connect} si definisce la destinazione verso cui si
reinoltrano le connessioni, ed anche in questo caso il significato dipende
dalla modalità di impiego di \texttt{stunnel}, in modalità server in genere si
indica una porta locale verso cui si redirige il traffico in chiaro, anche
avrebbe poco senso dirigere il traffico in chiaro verso un'altra macchina,
rendendo vano l'uso di \texttt{stunnel} per evitare la trasmissione dei dati
in chiaro, mentre in modalità client si indica l'indirizzo del server SSL a
cui ci si rivolge.

Le altre principali direttive sono riportate in tab.~\ref{tab:stunnel_conf};
nella prima parte si sono riportate le direttive globali, mentre nella seconda
parte quelle impostabili a livello di singolo servizio. Per una documentazione
completa si rimanda al solito alla lettura della pagina di manuale del comando.


\subsection{Gestione di chiavi, certificati e CA}
\label{sec:openssl}

Benché esistano diversi programmi che consentono di creare e gestire chiavi e
certificati ed anche mantenere una \textit{Certification Authority} in maniera
completa, con applicazioni web come OpenCA (\url{www.openca.org}) o ad
interfaccia grafica come \texttt{tinyca}, ci concentreremo sulla suite di
programmi \texttt{openssl} fornita dal progetto omonimo
(\url{www.openssl.org}) e presente nella maggior parte delle
distribuzioni. Detta suite fornisce un insieme di programmi per operare su
chiavi e certificati a riga di comando, usati da buona parte delle
applicazioni per la gestione delle CA.

In realtà il comando \index{comando!\texttt{openssl}} \texttt{openssl} non è
altro che un wrapper che consente di invocare una serie di sottocomandi che
consentono di effettuare tutte le più varie operazioni relative alla gestione
di una infrastruttura di chiavi, certificati e \textit{Certification
  Authority}; esso infatti viene invocato sempre nella forma:
\begin{Example}
openssl sottocomando [opzioni e argomenti]
\end{Example}
dove con \texttt{sottocomando} si indica quale dei programmi che fanno parte
della suite si vuole utilizzare; un breve elenco dei più significativi è
riportato in tab.~\ref{tab:openssl_subcommand}.\footnote{trattare tutte le
  funzionalità di \texttt{openssl} va al di là dello scopo di questo testo,
  gli interessati possono consultare la documentazione del progetto e le
  pagine di manuale, che si accedono usando solo il nome del sottocomando.}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Sottocomando}&\textbf{Significato}\\
    \hline
    \hline
    \texttt{ca}    & gestione di una \textit{Certification Authority}.\\ 
    \texttt{crl}   & gestione delle liste di revoca (CRL).\\ 
    \texttt{dsa}   & gestione delle chiavi DSA (soprasseduto da
                     \texttt{pkey}).\\  
    \texttt{rsa}   & gestione delle chiavi RSA (soprasseduto da
                     \texttt{pkey}).\\  
    \texttt{gendsa}& creazione delle chiavi DSA (soprasseduto da
                     \texttt{genpkey}).\\  
    \texttt{genpkey}&creazione di chiavi pubbliche (generico, sostituisce 
                     i due comandi \texttt{genrsa} e \texttt{gendsa}).\\ 
    \texttt{genrsa}& creazione delle chiavi RSA (soprasseduto da
                     \texttt{genpkey}).\\  
    \texttt{pkey}&   gestione delle chiavi pubbliche (generico, sostituisce
                     i due comandi \texttt{dsa} e \texttt{rsa}).\\ 
    \texttt{req}   & gestione delle richieste di certificati
                     (\textit{Certificate Signing Request}, o CSR) X.509.\\ 
    \texttt{x509}  & gestione dei certificati X.509.\\ 
    \texttt{verify}& verifica dei certificati X.509.\\ 
    \texttt{s\_client}& client per il protocollo SSL, per uso diagnostico.\\ 
    \texttt{s\_server}& server SSL minimale per uso diagnostico.\\ 
%    \texttt{}& .\\ 
    \hline
  \end{tabular}
  \caption{I principali sottocomandi di \texttt{openssl}.} 
\label{tab:openssl_subcommand}
\end{table}

Ciascun sottocomando di \texttt{openssl} prevede delle opzioni e degli
argomenti specifici, ma esistono una serie di opzioni generiche che restano le
stesse per tutti i sottocomandi. In particolare si può indicare il file da cui
leggere i dati in ingresso con \texttt{-in} (il default è usare lo
\textit{standard input}) e quello su cui scrivere i dati in uscita con
\texttt{-out} (il default è usare lo \textit{standard output}). Si può
richiedere una uscita testuale con \texttt{-text} e la rimozione dall'uscita
del contenuto delle versioni codificate con \texttt{-noout}.

Di particolare rilevanza sono poi le due opzioni \texttt{-passin} e
\texttt{-passout} (e in certi casi anche semplicemente \texttt{-pass}), che
vengono usate dai vari sottocomandi che richiedono l'immissione di una
password, da utilizzare rispettivamente in ingresso per decifrare, e in uscita
per cifrare.

Entrambe le opzioni prendono un parametro che indica la modalità in cui si
fornisce la password, secondo la sintassi generica illustrata in
tab.~\ref{tab:openssl_pass_mode}. Si tenga presente che se una password è
necessaria e non si è indicato nulla, questa verrà richiesta esplicitamente
sul terminale, e che in questo caso una semplice redirezione dello
\textit{standard input} non funzionerà, in quanto viene controllato che i dati
ricevuti in ingresso siano immessi proprio da un terminale.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Parametro}&\textbf{Significato}\\
    \hline
    \hline
    \texttt{pass:password}& la password viene scritta direttamente sulla riga
                            di comando (insicuro in quanto osservabile con
                            \texttt{ps}).\\ 
    \texttt{env:var}      & la password viene letta dalla variabile di
                            ambiente indicata (potenzialmente insicuro perché
                            osservabile con \texttt{ps} con alcuni Unix).\\
    \texttt{file:pathname}& la password viene letta dalla prima riga del file
                            indicato.\\
    \texttt{fd:number}    & la password viene letta dal file descriptor
                            indicato dal numero passato come parametro.\\
    \texttt{stdin}        & la password viene letta dallo \textit{standard
                             input}.\\ 
%    \texttt{}& .\\ 
    \hline
  \end{tabular}
  \caption{Sintassi dei parametri con cui indicare le password nelle opzioni
    \texttt{-passin} e \texttt{-passout} di \texttt{openssl}.} 
\label{tab:openssl_pass_mode}
\end{table}

Come accennato \texttt{openssl} supporta diversi formati per la gestione di
file e certificati, fra questi i due principali sono il formato binario
\itindex{Distinguished~Encoding~Rules~(DER)} DER (\textit{Distinguished
  Encoding Rules}), ed il formato testuale
\itindex{Privacy~Enhanced~Mail~(PEM)} PEM (\textit{Privacy Enhanced Mail}) che
è un DER trasformato in ASCII puro con la codifica \textit{base64} e
l'aggiunta di righe di separazione in testa ed in coda alle informazioni.

Benché sia meno efficiente in termini di spazio rispetto al DER, il PEM è di
gran lunga il formato più comune, principalmente per la maggiore
maneggevolezza. Si possono infatti copiare facilmente i dati con un taglia e
incolla da un qualunque editor, ed unire più certificati ed anche le chiavi in
un solo file, semplicemente accodandoli uno all'altro.  Per questo motivo è il
formato usato di default da tutti i comandi della suite \texttt{openssl}.  Un
esempio di un certificato in formato PEM è il seguente:
\begin{FileExample}[label=cert\_sample.pem]
-----BEGIN CERTIFICATE-----
MIIHBjCCBO6gAwIBAgIBKzANBgkqhkiG9w0BAQUFADCBoDELMAkGA1UEBhMCSVQx
CzAJBgNVBAgTAkZJMRAwDgYDVQQHEwdGaXJlbnplMRUwEwYDVQQKEwxUcnVlbGl0
ZSBTcmwxIDAeBgNVBAsTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQD
...
Eo32qyn9RP66aBV3EIFduasYGAk5M2AX4yIdhv4HPDW1XZMRdTJRsNnue5rSV0ER
AWu2pBug3i5sc33R1eymWuh5wfRNPzS2XqUExXKgo/oPEZF85QkPsK/vjZcXUriV
yVsE5GgC6Nos4dkbRo6RPBAsDk0vmWdIRuo=
-----END CERTIFICATE-----
\end{FileExample}

Ovviamente l'esame dei dati di un certificato in questa forma non è proprio
immediato, per questo uno dei sottocomandi di \texttt{openssl} più utilizzati
è \texttt{x509}, che permette di visualizzarne le informazioni in forma
esplicita, oltre a fornire operazioni di gestione e di conversione in formati
diversi. Un esempio di invocazione per la visualizzazione dei dati è il
seguente:
\begin{Console}
$ \textbf{openssl x509 -text -noout < www.fi.trl-cert.pem}
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            93:b0:c1:d4:92:f8:9b:c0
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=IT, ST=FI, O=Truelite, OU=IT, CN=CA/emailAddress=info@truelite.it
        Validity
            Not Before: Jun  1 09:26:09 2011 GMT
            Not After : May 31 09:26:09 2012 GMT
        Subject: C=IT, ST=FI, L=Firenze, O=Truelite, OU=IT,CN=www.trl.tl/emailAddr
ess=info@trl.tl
        Subject Public Key Info:
            ...
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                B1:2B:49:96:BE:2D:A8:AE:13:A4:3D:05:9A:C0:DF:E8:AB:57:0C:FB
            X509v3 Authority Key Identifier: 
                keyid:2D:13:7D:AB:78:6B:BC:E8:57:9F:4F:51:78:97:8F:27:E8:78:2D:5B

    Signature Algorithm: sha1WithRSAEncryption
        ...
\end{Console} 
%$
e si noti come vengano riportati i contenuti delle varie sezioni in cui sono
suddivise le informazioni, il cui significato è stato illustrato in
tab.~\ref{tab:x509_sections}.

Il sottocomando supporta una serie di opzioni per visualizzare soltanto i dati
delle singole sezioni o altre informazioni; fra queste vale la pena citare
l'opzione \texttt{-hash} che consente di ottenere l'hash delle informazioni
della sezione \textit{Subject} del certificato, che deve essere usato per i
nomi dei file che si mettono nelle cosiddette
\itindex{standard~certificate~directory} \textit{standard certificate
  directory}.

Le librerie che implementano il protocollo SSL infatti consentono di indicare
un elenco di certificati specificando semplicemente una directory che li
contenga come singoli file. In tal caso però i file però vengono cercati, come
forma di indicizzazione, con un nome nella forma \texttt{XXXXXXXX.0} dove
\texttt{XXXXXXXX} è appunto questo hash. Una directory che contiene file di
certificati con questi nomi viene appunto chiamata
\itindex{standard~certificate~directory} \textit{standard certificate
  directory}.\footnote{come esempio si può vedere il contenuto si
  \texttt{/etc/ssl/certs} dove in genere vengono installati i certificati
  delle \textit{Certification Authority} commerciali più note.} Questo
significa che se si vuole usare una di queste directory non è sufficiente
copiare all'interno i file dei certificati, ma occorre usare esplicitamente
questo tipo di nomi; in genere quello che si fa è creare dei link simbolici,
ottenendo il nome con l'opzione \texttt{-hash} del comando \texttt{x509}.

In genere la creazione di un certificato è un procedimento che richiede
diversi passi, l'ultimo dei quali è quello della firma da parte di una
\textit{Certification Authority}. Su quest'ultimo, che si può effettuare
direttamente qualora si gestisca una CA in proprio, torneremo più avanti, ma
nel caso si debba ottenere un certificato da una CA terza occorre seguire una
procedura ben precisa fin dall'inizio.

A differenza di quanto avveniva con SSH infatti in questo caso non esiste,
essendoci in ballo un eventuale ente terzo, un comando singolo per creare
chiave e certificato, ma occorre eseguire diverse operazioni. Volendo fare le
cose un passo alla volta, il primo da compiere è quello di creare una
chiave. Come illustrato in tab.~\ref{tab:openssl_subcommand} esistono vari
sottocomandi deputati alla generazione di una chiave, per semplicità
prenderemo in considerazione solo \texttt{genrsa} che consente di generare
chiavi RSA.

Questo è il comando più semplice, gli altri sono comunque più o meno
equivalenti essendo i concetti gli stessi, anche se per alcuni formati può
essere necessario generare dei dati intermedi, cosa che comunque è documentata
nelle rispettive pagine di manuale.  Un esempio di uso del comando è:
\begin{Console}
$ \textbf{openssl genrsa}
Generating RSA private key, 512 bit long modulus
.++++++++++++
....++++++++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBALWFfAmGzuq08FgioYn3v0qhPGeZtpr+GPLa1j30/tTeSAZY65C3
GQEeoZYaanNFbLxU0NrnwkeMlgmXbgpSE0UCAwEAAQJBAK0lS6CGr36f4xYeynmh
ER2t2MF1lQIY2FFmvq9Qr3b5iN/MMMElrGOOR4BMMaO/SFsAtyYH5UqdzArBNghm
Fs0CIQDcTl89kmA9DnDGUNjRbfnum1n1FoynwKMOfmZPUezBfwIhANLucMXCp6RX
1bGjC2k203amYQtIuBUn+mci9QAABgU7AiEAtDrNgcKxRuH8ctGLP3JYSNMA+hez
hD19aAsSSgv8w6MCIHqAvMI+MPrDgHpwhPoQO3QXYRkanL68vzMTHFNpsBVtAiEA
pDG2dCvmn/GWR0W0ycLAu5shCv9XOs+mhCmgSXLwykw=
-----END RSA PRIVATE KEY-----
\end{Console}
%$

Il comando stampa sullo \textit{standard input} i suoi risultati in formato
PEM, ma si può far salvare direttamente soltanto le informazioni su un file con
la citata opzione \texttt{-out}, lo stesso risultato si ottiene comunque
redirigendo l'uscita su un file.  Il comando supporta l'uso di un argomento
per specificare la dimensione in bit della chiave (il default, come mostrato,
è di 512 bit). 

La chiave viene generata senza nessuna protezione, ma si può richiedere la
cifratura della stessa con una fra le opzioni \texttt{-des}, \texttt{-des3} e
\texttt{-idea} che utilizzano i corrispondenti algoritmi di cifratura,
(rispettivamente DES, 3DES e IDEA, vedi sez.~\ref{sec:crypto_symmetric}), nel
qual caso verrà chiesta una password, che si potrà impostare con
\texttt{-passout} con uno qualunque dei metodi indicati in
tab.~\ref{tab:openssl_pass_mode} o immettere direttamente sul terminale.

Se viceversa si vuole decifrare una chiave RSA si dovrà utilizzare il
sottocomando \texttt{rsa}, che è anche quello che si usa per la gestione di
questo tipo di chiavi. In tal basterà usarlo per fargli leggere il file con la
chiave cifrata, ed eventualmente redirigere l'uscita su un altro file. Al
solito verrà richiesta la password sul terminale o la si potrà indicare con
\texttt{-passin}. Usando le stesse opzioni indicate per \texttt{genrsa} si
potrà invece cifrare una chiave in chiaro o ottenere una cifratura con un
diverso algoritmo (in quel caso si dovrà anche specificare una password in
uscita).  Per il resto la sintassi è analoga a quella di \texttt{x509} e lo si
può utilizzare allo stesso modo per far generare una stampa in formato
testuale dei dati associati alla chiave, anche se in questo caso, trattandosi
soltanto di dati di natura crittografica, il contenuto esplicito è di scarso
interesse.

Nella creazione di un certificato il sottocomando più importante è però
\texttt{req}, che è quello che consente di creare una \textsl{richiesta di
  certificato} (una \textit{Certificate Signing Request} o CSR), cioè il file
che le \textit{Certification Authority} firmano per la creazione di un
certificato. Una CA infatti non ha nessuna necessità di avere a disposizione
la chiave associata ad un certificato, e per questo tutto quello che è
necessario inviare è una richiesta che contenga solo la chiave pubblica ed i
propri dati informativi (quelli di tab.~\ref{tab:x509_informations}).

La creazione di una richiesta si effettua usando il sottocomando con l'opzione
\texttt{-new}; se usata da sola questa comporta anche la creazione di default
di una chiave RSA a 1024 bit per la quale viene richiesta la password,
altrimenti si può indicare l'uso di una chiave precedentemente creata con
\texttt{genrsa} usando l'opzione \texttt{-key}. Questo ad esempio è utile in
quanto è normale effettuare la creazione di una CSR con dati diversi in caso
di rinnovo del certificato, pur mantenendo la stessa chiave, così da non dover
sostituire anche questa. Pertanto se si è salvata la chiave precedente sul
file \texttt{key.pem} si potrà creare una richiesta di certificato con:
\begin{Console}
$ \textbf{openssl req -new -key key.pem}
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:\textbf{IT}
State or Province Name (full name) [Some-State]:\textbf{FI}
Locality Name (eg, city) []:\textbf{Firenze}
Organization Name (eg, company) [Internet Widgits Pty Ltd]:\textbf{Truelite Srl}
Organizational Unit Name (eg, section) []:\textbf{IT}
Common Name (eg, YOUR name) []:\textbf{www.truelite.it}
Email Address []:\textbf{info@truelite.it}

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: 
An optional company name []:
-----BEGIN CERTIFICATE REQUEST-----
MIIBRjCB8QIBADCBizELMAkGA1UEBhMCSVQxCzAJBgNVBAgMAkZJMRAwDgYDVQQH
DAdGaXJlbnplMRUwEwYDVQQKDAxUcnVlbGl0ZSBTcmwxCzAJBgNVBAsMAklUMRgw
FgYDVQQDDA93d3cudHJ1ZWxpdGUuaXQxHzAdBgkqhkiG9w0BCQEWEGluZm9AdHJ1
ZWxpdGUuaXQwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnITR9WvfIToVy8ER6T2l
HEEJcxeVeIdpytOTXs1O/rGBoW9aw8d0GPPcKVq6aI+lqIGS4L3JbdSgs3lc46jj
7wIDAQABoAAwDQYJKoZIhvcNAQEFBQADQQBqfHAIOxY4wBXIy5DBZjY2oA07MQpP
oqMpGEb9as71sJNVP2UE/mfrnv0Nv5kn9jgYjmD7apZBF7f+/djn0yGb
-----END CERTIFICATE REQUEST-----
\end{Console}
%$

Si noti come il comando richieda l'immissione di una serie di informazioni da
terminale (quelle di tab.~\ref{tab:x509_informations} più alcuni dati
aggiuntivi) evidenziati in grassetto nell'esempio, e poi stampi la richiesta
di certificato ottenuta in formato PEM. Nel fare le richieste inoltre il
comando suggerisce per alcuni campi dei valori di default che possono essere
accettati premendo invio, o si può specificare il carattere ``\texttt{.}'' per
lasciare il campo vuoto. Questi default provengono dal file
\texttt{/etc/ssl/openssl.cnf}, che come vedremo più avanti serve da file di
configurazione per una serie di impostazioni relative a tutti vari
sottoprogrammi di \texttt{openssl}, e possono essere opportunamente
preimpostati per velocizzare la creazione.

Inoltre il sottocomando \texttt{req} consente anche di esaminare i dati
contenuti in una richiesta in formato PEM (o DER) in forma esplicita testuale,
ad esempio per verificare la correttezza del \textit{Common Name} e dei dati
della sezione \textit{Subject}, e lo si può utilizzare in tal senso
esattamente con le stesse opzioni già viste in precedenza per \texttt{x509} e
\texttt{rsa}. Ad esempio con il precedente certificato otterremo:
\begin{Console}
$ \textbf{openssl req -text -noout < csr.pem}
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=IT, ST=FI, L=Firenze, O=Truelite Srl, OU=IT,CN=www.truelite.it/
emailAddress=info@truelite.it
        Subject Public Key Info:
            ...
    Signature Algorithm: sha1WithRSAEncryption
        ...
\end{Console}
%$

Una volta creata una CSR il passo successivo è quello di farla firmare da una
\textit{Certification Authority} per ottenere un certificato. Se si vuole
usare il certificato per farsi identificare da terzi occorrerà rivolgersi ad
una delle varie CA commerciali riconosciute come valide da questi
ultimi,\footnote{in genere, dato che l'uso principale dei certificati è per
  garantire siti web, chi stabilisce se una CA è valida sono i fornitori dei
  browser, che includono all'interno dei propri programmi i certificati di
  quelle ritenute tali.}  inviandogli la richiesta e riottenendo indietro il
certificato firmato; cosa che normalmente implica anche un pagamento ed una
qualche forma di verifica dell'identità.

Quest'ultima è quasi sempre estremamente blanda, e viene effettuata nei
termini della verifica della risposta ad una email o con un controllo
superficiale della proprietà del dominio, a meno di che non sia stato
richiesto un cosiddetto \textit{Extended Validation Certificate} per
l'emissione del quale sono richiesti dei controlli leggermente più
approfonditi.

Questa è una estensione introdotta di recente, che cerca di rispondere agli
evidenti problemi dimostrati dalle CA nel fare il loro lavoro (quello di
verifica) che con le procedure ordinarie si è dimostrato inadeguato. Chi
emette questi certificati (caratterizzati da specifici valori del campo
\textit{Certificate Policies} nelle estensioni X509.3) dichiara di aver
seguito una procedura più stringente nella verifica della identità del
richiedente e marca il certificato come rispondente a questa politica. Il
risultato è che i browser più recenti classificano questo tipo di certificati
come più affidabili, (in genere colorando di verde qualche elemento grafico) e
che le CA chiedono un prezzo molto più alto per la sua emissione.

Dato che, come accennato in sez.~\ref{sec:pki_certificates}, quando si chiede
la firma ad una CA commerciale in genere l'unica informazione presente nella
CSR che rimane disponibile nel certificato che si riottiene indietro è il
\textit{Common Name} della sezione \textit{Subject}, si deve avere cura di
specificarlo in maniera corretta. In genere, essendo questo tipo di
applicazione mirato principalmente ai siti web, è essenziale che il
\textit{Common Name} corrisponda al nome a dominio con cui il sito viene
raggiunto (quello completo che si mette nella URL di richiesta) dato che è su
questa corrispondenza che viene eseguito il controllo da parte dei browser.

Questo comporta in genere una forte limitazione riguardo l'uso del
certificato, in quanto esso può essere utilizzato solo per un
sito;\footnote{si tenga inoltre presente che in genere non è possibile usare
  certificati diversi per diversi \textit{Virtual Host} se questi sono
  riferiti allo stesso indirizzo IP (cioè \textit{host based}), a meno di non
  utilizzare versioni molto di browser e server web che supportano una
  specifica estensione del protocollo SSL; per maggiori dettagli si consulti
  la sez.~1.4.5 di \cite{WebServ}.}  se un browser si rivolgesse allo stesso
sito con un nome diverso si avrebbe un errore, o meglio uno di quegli
avvertimenti allarmistici riguardo la presunta inaffidabilità e pericolosità
del sito stesso, che può essere rimosso solo accettando esplicitamente il
certificato.

Esiste comunque la possibilità, fintanto che si resta all'interno di uno
stesso dominio, di usare un cosiddetto certificato \textit{wildcard}, valido
per tutti i nomi all'interno di quel dominio. In sostanza si tratta in questo
caso di specificare il \textit{Common Name} nella forma:
\begin{Example}
*.dominio.it
\end{Example}
e questo sarà considerato dai browser come valido per qualunque nome
all'interno di quel dominio. Si tenga presente però che questo vale solo per
nomi nella forma \texttt{xxx.dominio.it}, con \texttt{xxx} nome qualunque,
mentre in generale (la cosa varia a seconda del browser) non saranno validi né
ulteriori sotto-domini (cioè nomi nella forma \texttt{yyy.xxx.dominio.it}), né
il semplice \texttt{dominio.it}.

Se non interessa che un certificato sia riconosciuto dai browser di terzi, o
se interessa solo cifrare le connessioni, o se i servizi sono ad uso interno o
non riguardano il web, si può decidere di realizzare in proprio una CA con la
quale firmare i propri certificati. Come accennato questo può facilitare la
distribuzione delle credenziali, in quanto non è più necessario verificare una
manualmente una ad una tutte le chiavi pubbliche dei corrispondenti, ma
basterà distribuire il certificato della CA per garantire l'autenticità dei
certificati utilizzati dai vari servizi.

Dato che in questo caso la CA viene ad assumere un ruolo centrale nella
verifica di integrità della propria infrastruttura, è in generale buona norma
creare i certificati e le chiavi su una macchina dedicata, non connessa alla
rete e tenuta in luogo sicuro. L'accesso alle chiavi della CA permette infatti
di creare certificati in maniera arbitraria e compromettere tutte le
comunicazioni fra i servizi che la usano spacciandosi per altri. Non
disponendo di una macchina dedicata si può eseguire l'operazione su un
portatile isolato dalla rete, e salvare tutti i file su un supporto temporaneo
(magari cifrato). I veri paranoici possono anche stampare per ulteriore
precauzione le chiavi (per riporle in luogo sufficientemente sicuro), e poi
cancellare il tutto, ovviamente usando un programma di cancellazione sicura
come \texttt{wipe} o \texttt{shred}.

Benché sia disponibile un apposito sottocomando \texttt{ca} di
\texttt{openssl} il suo utilizzo diretto per la creazione totalmente manuale
di una \textit{Certification Authority} risulta piuttosto macchinoso, dovendo
ad esempio salvare i certificati emessi, tracciare i numeri seriali, e
mantenere manualmente vari dati.  Lo stesso progetto OpenSSL considera detto
comando ``\textsl{stravagante e talvolta ostile}'' (citazione dalla pagina di
manuale). Per questo motivo insieme ai singoli sottocomandi di
\texttt{openssl} il progetto OpenSSL mette a disposizione alcuni script che
consentono di semplificare l'operazione di gestione di una CA, che sono quelli
che prenderemo in considerazione.

Gli script distribuiti dal progetto sono due, \texttt{CA.pl} è la versione in
Perl mentre \texttt{CA.sh} è uno script di shell,\footnote{con il pacchetto
  Debian di \texttt{openssl} questi vengono installati sotto
  \texttt{/usr/lib/ssl/misc/}.} ed il loro uso permette di semplificare la
creazione della \textit{Certification Authority}, facendo da interfaccia ad
\texttt{openssl} per la gestione delle varie operazioni da eseguire per creare
la propria CA personale. Entrambi gli script funzionano allo stesso modo e
prendono gli stessi parametri, per semplicità faremo riferimento allo script
di shell.

Entrambi gli script sono piuttosto grezzi, si usano invocandoli su un
terminale, e salvano tutti i dati in una directory \texttt{demoCA} creata
nella directory da cui vengono lanciati, il nome comunque può essere cambiato
con una delle variabili di configurazione di \texttt{openssl.cnf} che
tratteremo più avanti.  In realtà gli script non fanno altro che chiamare
nella opportuna sequenza i vari sottocomandi di \texttt{openssl}, e salvare i
file in quella directory e nella directory corrente adottando una convenzione
sui nomi che gli consente di riutilizzarli in successive invocazioni.

Entrambi gli script fanno riferimento ad alcune variabili di ambiente che
usano per impostare dei default. Se queste non sono presenti i valori di dette
variabili vengono preimpostati all'interno degli script stessi.\footnote{fra
  queste può trarre in inganno la variabile \texttt{DAYS}, che dovrebbe
  specificare di quanti giorni deve essere la validità di un certificato, in
  realtà questo valore viene impostato dentro \texttt{openssl.cnf} e nelle
  versioni recenti di \texttt{openssl} qualunque cosa si scriva nello script
  viene ignorato.} In particolare la variabile \texttt{SSLEAY\_CONFIG} serve
per indicare un file di configurazione alternativo rispetto
\texttt{openssl.cnf}, un possibile esempio del suo uso è impostare:
\begin{Example}
export SSLEAY\_CONFIG="-config ./openssl.cnf" 
\end{Example}

All'inizio di entrambi gli script sono poste le definizioni di una serie di
ulteriori variabili interne che impostano dei default per nomi di file e
comandi ed altri parametri interni che possono essere cambiati solo
modificando gli script,\footnote{fra queste c'è anche \texttt{DAYS}, ma come
  detto viene comunque ignorata, la durata deve essere impostata con
  \texttt{openssl.cnf}.} fra queste è particolarmente rilevante
\texttt{CADAYS} che imposta la durata del certificato della CA, il suo valore
di default infatti è di tre anni, che può risultare troppo breve.

Il primo passo per la creazione di una propria \textit{Certification
  Authority} personale è quello di creare l'infrastruttura che conterrà i vari
dati, fra cui il certificato della CA e la chiave corrispondente con cui
verranno poi firmati i certificati rilasciati dalla stessa.  Questo si fa una
volta per tutte invocando lo script con l'opzione \texttt{-newca} che eseguirà
in sequenza le varie operazioni necessarie. Come primo passo verrà creata la
chiave privata, si otterrà pertanto un'uscita del tipo:
\begin{Console}
$ \textbf{/usr/lib/ssl/misc/CA.sh -newca}
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 1024 bit RSA private key
....................++++++
....++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
\end{Console}
%$
dove prima viene richiesta l'immissione di un eventuale file da cui importare
dati già pronti (deve essere un file in formato PEM contenente chiave e
certificato). Se come nel nostro caso si vuole fare una creazione da zero si
dovrà premere invio per generare la chiave privata della CA e poi sarà
richiesta una password con cui proteggerla che va inserita due volte per
conferma.

Come secondo passo lo script crea internamente una CSR e richiede l'immissione
delle informazioni previste dallo standard X.509 per il certificato della CA
come per il precedente esempio di richiesta, per cui l'uscita a video
del comando prosegue con qualcosa del tipo:
\begin{Console}
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:\textbf{IT}
State or Province Name (full name) [Some-State]:\textbf{FI}     
Locality Name (eg, city) []:\textbf{Firenze}
Organization Name (eg, company) [Internet Widgits Pty Ltd]:\textbf{Truelite S.r.L.}
Organizational Unit Name (eg, section) []:\textbf{CA}
Common Name (eg, YOUR name) []:\textbf{truelite.it}
Email Address []:\textbf{info@truelite.it} 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
\end{Console}
dove si devono immettere i dati che verranno inseriti nel certificato della
nostra CA esattamente come si è fatto con il sottocomando \texttt{req}.

Infine nell'ultimo passo verrà richiesta la password della chiave privata
impostata all'inizio per firmare la richiesta appena generata ed ottenere il
certificato della CA. Di questo poi verranno stampate le informazioni più
rilevanti, per cui la parte finale dell'uscita del comando sarà qualcosa del
tipo:
\begin{Terminal}
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/./cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            8d:34:8f:65:45:ad:86:80
        Validity
...
\end{Terminal}

Come accennato tutti i file e le directory necessarie per la gestione della
\textit{Certification Authority} verranno creati dallo script in una
sottodirectory \texttt{demoCA} a partire da quella in cui lo si è eseguito: in
particolare la chiave della CA verrà posta in
\texttt{demoCA/private/cakey.pem} ed il certificato con la chiave pubblica in
\texttt{demoCA/cacert.pem}; si potranno poi controllare i dati relativi a
quest'ultimo con il comando:
\begin{Console}
$ \textbf{openssl x509 -text -noout < demoCA/cacert.pem}
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            8d:34:8f:65:45:ad:86:80
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=IT, ST=FI, O=Truelite S.r.L., OU=CA, CN=truelite.it/emailAddre
ss=info@truelite.it
        Validity
            Not Before: Jun 14 13:24:57 2011 GMT
            Not After : Jun 13 13:24:57 2014 GMT
        Subject: C=IT, ST=FI, O=Truelite S.r.L., OU=CA, CN=truelite.it/emailAddr
ess=info@truelite.it
        Subject Public Key Info:
            ...
        X509v3 extensions:
            ...
            X509v3 Basic Constraints: 
                CA:TRUE
    ...
\end{Console}
%$
e si noti come \textit{Issuer} e \textit{Subject} in questo caso siano
identici.

Oltre a questi file la directory \texttt{demoCA} conterrà pure tutti gli altri
dati necessari alla gestione della CA, in particolare sono rilevanti il file
\texttt{demoCA/index.txt} che contiene la lista dei certificati rilasciati con
numero seriale e contenuto del campo \textit{Subject} e \texttt{demoCA/serial}
che contiene il numero seriale che verrà usato per il prossimo certificato che
verrà firmato.

Una volta inizializzata la propria \textit{Certification Authority} si potrà
passare alla creazione dei certificati. Per questo occorrerà anzitutto creare
una CSR, che si potrà generare sia come descritto in precedenza che lanciando
lo script con l'opzione \texttt{-newreq}, in questo caso verranno richieste
una password per la chiave e le solite informazioni per la richiesta, che
verranno salvate rispettivamente nei file \texttt{newkey.pem} e
\texttt{newreq.pem} nella directory corrente.

L'ultimo passo per ottenere un certificato è quello di firmare la richiesta
con la propria \textit{Certification Authority}, per questo si deve invocare
lo script con l'opzione \texttt{-sign}, restando sempre nella directory in cui
si era creata la CA e la richiesta, lo script infatti assume di trovare la
richiesta di certificato nel file \texttt{newreq.pem} della directory corrente
ed i file della CA nella sottodirectory \texttt{demoCA}. Così facendo si
otterrà un risultato del tipo:
\begin{Console}
$ \textbf{/usr/lib/ssl/misc/CA.sh -sign}
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            8d:34:8f:65:45:ad:86:81
        Validity
            Not Before: Jun 14 15:40:39 2011 GMT
            Not After : Jun 13 15:40:39 2012 GMT
        Subject:
            countryName               = IT
            stateOrProvinceName       = FI
            localityName              = Firenze
            organizationName          = Simone Piccardi
            organizationalUnitName    = gnulinux
            commonName                = piccardi.gnulinux.it
            emailAddress              = piccardi@gnulinux.it
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                83:F5:29:87:A0:F0:3D:6F:65:BC:B7:73:1E:6C:B0:E0:5E:40:D3:3E
            X509v3 Authority Key Identifier: 
                keyid:FF:5D:CC:D7:34:88:C0:FE:9D:DE:D1:E3:F1:C0:78:34:82:C7:62:4C

Certificate is to be certified until Jun 13 15:40:39 2012 GMT (365 days)
Sign the certificate? [y/n]:\textbf{y}


1 out of 1 certificate requests certified, commit? [y/n]\textbf{y}
Write out database with 1 new entries
...
Signed certificate is in newcert.pem
\end{Console}
%$
il comando chiederà la password della CA per firmare il certificato, e dopo
averne ricapitolato i dati chiederà di dare conferma riguardo la firma e la
memorizzazione del nuovo certificato che sarà salvato nel file
\texttt{newcert.pem}. Oltre a questo lo script genererà le informazioni (come
i file \texttt{index.txt} e \texttt{serial}) necessarie alla CA per tenere
traccia dei vari certificati firmati, e questo saranno copiati in
\texttt{demoCA/newcert}, dove sono mantenuti tutti i certificati firmati in
altrettanti file nominati per numero seriale.  Qualora si voglia creare un
altro certificato basterà ripetere l'operazione mettendo una nuova richiesta
in \texttt{newreq.pem} avendo cura di spostare un eventuale precedente
\texttt{newcert.pem} che verrebbe sovrascritto.

Eseguendo la firma in questo modo si utilizzeranno i valori di default sia per
la durata del certificato che per i dati aggiuntivi previsti per la sezione
delle \textit{X509v3 extensions}. Come accennato questi sono definiti
all'interno di \index{configurazione!\texttt{/etc/ssl/openssl.cnf}}
\texttt{/etc/ssl/openssl.cnf}, che fa da file di configurazione per i vari
sottocomandi di \texttt{openssl}. La documentazione al riguardo è scarsa e
inorganica, e divisa nelle pagine di manuale dei vari comandi, ma la versione
del file fornita con il pacchetto di OpenSSL è ampiamente commentata e
sufficientemente autoesplicativa; essendo l'argomento molto vasto, ne
tratteremo solo le parti più rilevanti. 

Il file ha il formato dei file \texttt{.ini} di Windows, con assegnazioni di
valori a chiavi di configurazione suddivise in sezioni introdotte da un nome
fra parentesi quadre, corrispondente al sottocomando a cui le chiavi fanno
riferimento. Alcune chiavi di configurazione fanno a loro volta riferimento ad
insiemi di valori, pertanto la loro assegnazione non è ad un valore diretto,
ma al nome di una successiva sezione in cui sono raggruppate le assegnazioni
delle ulteriori sottochiavi. Faremo riferimento alla versione del file
distribuita con il pacchetto \texttt{openssl} di Debian Squeeze.

Nella sezione \texttt{[req]} si trovano le configurazioni relative alla
generazione di richieste di certificato con il sottocomando \texttt{req}. Fra
queste c'è la dimensione di default delle chiavi private che viene specificata
con la chiave di configurazione \texttt{default\_bits} mentre i valori di
default ed i limiti che devono essere applicati ai vari campi delle
informazioni di tab.~\ref{tab:x509_informations} vengono specificati dalla
chiave \texttt{distinguished\_name}. Questa fa riferimento ai valori che sono
raggruppati nella successiva sottosezione
\texttt{[req\_distinguished\_name]},\footnote{in sostanza nel file si trova
  impostato \texttt{distinguished\_name = req\_distinguished\_name}.} dove si
trovano le assegnazioni delle ulteriori di chiavi di configurazione che
consentono di specificare descrizione, valori di default e dimensioni dei vari
dati; queste sono nella forma \texttt{countryName},
\texttt{countryName\_default}, \texttt{countryName\_min}, ecc.  Essendo il
formato piuttosto esplicito non staremo a dilungarci.

Le impostazioni per la gestione di una \textit{Certification Authority} sono
contenute nella sezione relativa al comando \texttt{ca}, la quale rimanda
direttamente alla sottosezione \texttt{[CA\_default]}.  È all'interno di
questa che si controllano i valori di default usati nella gestione della
propria CA, in particolare i vari default per il nome della directory dove si
salvano i vari file (è qui che è indicato l'uso di \texttt{demoCA} e degli
ulteriori file e sottodirectory illustrati in precedenza) ma soprattutto la
chiave \texttt{default\_days} che è quella che imposta la durata di un
certificato all'atto della firma.

Sempre qui la chiave \texttt{x509\_extensions} rimanda alla successiva sezione
\texttt{[usr\_cert]} per configurare quali delle informazioni aggiuntive
previste nelle \textit{X509v3 extensions} devono essere inserite nel
certificato all'atto della firma, presenti nella omonima sezione del
certificato (vedi tab.~\ref{tab:x509_sections}). Questa è in genere la sezione
più rilevante per l'uso pratico perché queste informazioni aggiuntive possono
essere usate dai client del protocollo SSL per prendere decisioni riguardo la
validità o meno del certificato.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|l|}
    \hline
    \textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \texttt{objsign}& certificato per firma digitale (\textit{Object
      Signing}).\\  
    \texttt{email} & certificato per posta elettronica (\textit{S/MIME}).\\ 
    \texttt{client}& certificato di tipo client (\textit{SSL Client}).\\ 
    \texttt{server}& certificato per server (\textit{SSL Server}).\\ 
%    \texttt{}& .\\ 
    \hline
  \end{tabular}
  \caption{Valori possibili per la chiave di configurazione
    \texttt{nsCertType} di \texttt{openssl.cnf}.} 
\label{tab:openssl_cnf_nsCertType}
\end{table}

Una di queste informazioni riguarda la tipologia di uso del certificato a cui
abbiamo accennato anche in sez.~\ref{sec:pki_certificates}; questa viene
impostata con la chiave \texttt{nsCertType}. Di default questa chiave non
viene definita per cui la relativa informazione non viene aggiunta, ma qualora
la si voglia indicare si deve assegnare detta chiave ad uno o più dei valori
illustrati in tab.~\ref{tab:openssl_cnf_nsCertType} (se sono più di uno si
deve usare una lista separata da virgole), che indicano, ai programmi che
usano questa informazione, quale è l'uso consentito per il certificato.

Un'altra informazione importante che si imposta in questa sezione è quella
relativa ai nomi alternativi (\textit{X509v3 Subject Alternative Name}) che si
possono associare al \textit{Common Name} specificato nel \textit{Subject} del
certificato. Questo consente ad esempio di inserire nel certificato ulteriori
nomi a dominio, indirizzi IP o indirizzi di posta elettronica che verranno
ritenuti validi per una connessione SSL da un programma che utilizzi questa
estensione. Si tenga presente però che questa informazione, come tutte le
altre della sezione \textit{X509v3 extensions}, viene inserita all'atto della
firma, cosa che può essere fatta solo da chi gestisce la CA, e non da chi
genera la richiesta di certificato.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Tipo}&\textbf{Significato}\\
    \hline
    \hline
    \texttt{DNS}  & un nome a dominio, da indicare come FQDN.\\ 
    \texttt{IP}   & un indirizzo IP, da indicare in notazione \textit{dotted
                      decimal}.\\  
    \texttt{email}& un indirizzo email, da indicare nella notazione elementare
                    \texttt{nome@dominio.it}.\\ 
%    \texttt{}& .\\ 
    \hline
  \end{tabular}
  \caption{Tipi utilizzabili per i valori della chiave di configurazione
    \texttt{subjectAltName} di \texttt{openssl.cnf}.} 
\label{tab:openssl_cnf_subjectAltName}
\end{table}

La chiave di configurazione che consente di impostare queste informazioni è
\texttt{subjectAltName}; anche questa di default è commentata per cui la
relativa informazione non viene aggiunta ed anche in questo caso si può
indicare una lista di valori, sempre separati da virgole. I valori possono
indicare diversi tipi di nomi alternativi, e devono essere specificati secondo
il formato ``\texttt{TIPO:valore}'', dove i vari tipi si sono riassunti in
tab.~\ref{tab:openssl_cnf_subjectAltName}. 

Come esempio di personalizzazione delle informazioni inserite in un
certificato consideriamo di avere modificato \texttt{openssl.cnf} definendo le
seguenti chiavi di configurazione:
\begin{FileExample}[label=openssl.cnf]
...
default_days    = 730
...
nsCertType      = server, client
...
subjectAltName  = DNS:gapil.gnulinux.it,IP:78.46.114.60
...
\end{FileExample}
si otterrà, eseguendo la firma con questa nuova versione di
\texttt{openssl.cnf}, un certificato con una scadenza di due anni, ed al cui
interno compariranno le ulteriori informazioni aggiuntive:
\begin{Console}
$ \textbf{./CA.sh -sign}
Using configuration from ./openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            89:77:13:a8:58:7b:ae:42
        Validity
            Not Before: Jun 15 14:35:16 2011 GMT
            Not After : Jun 14 14:35:16 2013 GMT
        Subject:
            countryName               = IT
            stateOrProvinceName       = FI
            localityName              = Firenze
            organizationName          = Simone Piccardi
            organizationalUnitName    = gnulinux
            commonName                = piccardi.gnulinux.it
            emailAddress              = piccardi@gnulinux.it
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, SSL Server
            ...
            ...
            X509v3 Subject Alternative Name: 
                DNS:gapil.gnulinux.it, IP Address:78.46.114.60
Certificate is to be certified until Jun 14 14:35:16 2013 GMT (730 days)
Sign the certificate? [y/n]:\texttt{y}
...
\end{Console}
%$

Come si vede la procedura di firma è abbastanza grezza dato che se si deve
cambiare la durata o uno aggiungere o modificare uno qualunque dei dati
aggiuntivi previsti per la sezione delle \textit{X509v3 extensions}, si deve
eseguire la relativa modifica a \texttt{/etc/ssl/openssl.cnf} (o ad una sua
alternativa) tutte le volte che si esegue una firma. Una cosa che rende
alquanto scomodo l'uso di questi script quando si hanno richieste appena un
po' più sofisticate e diversificate rispetto a valori di default uguali per
tutti, come potrebbe essere anche solo l'inserimento di un nome a dominio
alternativo.


\section{Il \textit{web of trust}}
\label{sec:web_of_trust}

In questa sezione tratteremo quel modello alternativo per la realizzazione di
una infrastruttura di chiavi pubbliche che viene denominato ``\textit{web of
  trust}'' (cioè ``\textsl{ragnatela di confidenza}'') e che si pone come
principale alternativa rispetto a quello delle \textit{Certification
  Authority} che abbiamo appena esaminato. In questo contesto prenderemo in
esame il programma GPG (\textit{GNU Privacy Guard}), che è la principale
applicazione che usa questo modello alternativo, analizzandone il
funzionamento e le modalità di utilizzo.


\subsection{Il modello del \textit{web of trust}}
\label{sec:web_of_trust_model}

Il modello del \textit{web of trust} è il principale (se non l'unico) modello
alternativo rispetto a quello del \textit{Trusted Third Party} per la
realizzazione di una PKI (intesa nel significato generico e non come la
implementazione classica vista in sez.~\ref{sec:PKI}. Anche in questo caso si
continuano ad utilizzare gli stessi algoritmi crittografici a chiave pubblica
già illustrati in sez.~\ref{sec:crypto_asymmetric} e
sez.~\ref{sec:crypto_hash} per la cifratura, l'autenticazione e la verifica di
integrità, si cambiano però le modalità per rispondere alle problematiche
poste dagli attacchi di \itindex{man-in-the-middle}
\textit{man-in-the-middle}.

In questo caso infatti, invece di delegare il compito di verifica della
corrispondenza fra le credenziali ed una identità reale ad un soggetto terzo,
assunto fidato a priori, si distribuisce il compito fra gli stessi utenti
finali. Il meccanismo cioè è quello in cui ognuno cerca di verificare queste
corrispondenze direttamente per quanto gli è possibile, ed inserisce le
verifiche che ha fatto in un meccanismo di distribuzione di questa
informazione.

In sostanza quello che viene fatto è che ciascun soggetto firma le chiavi
pubbliche dei corrispondenti di cui ha verificato direttamente l'identità,
restituendo agli stessi la chiave firmata. Ognuno potrà così raccogliere tutte
le firme apposte sulla propria chiave dai terzi che l'hanno verificata
direttamente, e che avendola firmata ne attestano la ``\textsl{validità}''.

Questo è il meccanismo che permette di realizzare quella \textsl{ragnatela di
  confidenza} in cui ciascuno può decidere se fidarsi o meno delle credenziali
(la chiave pubblica) di un terzo non conosciuto direttamente, sulla base delle
verifiche che sono state fatte dagli altri soggetti partecipanti alla
ragnatela. Queste sono disponibili e possono essere controllate proprio perché
su ogni chiave pubblica è prevista la presenza delle firme che sono vi sono
state apposte da coloro che l'hanno verificata direttamente.

Anche in questo modello il problema resta quello dell'affidabilità delle
verifiche che non sono state effettuate direttamente, e di quanto ci si possa
fidare dei terzi che le compiono. Solo che stavolta le verifiche sono
distribuite e l'onere della decisione sulla fiducia o meno sulle stesse non
viene delegato ad un terzo di cui si è obbligati a fidarsi, e invece può
essere determinato in base alla fiducia che ciascuno può assegnare ad ogni
altro membro della ragnatela.\footnote{vedremo in seguito come ciascuno può
  stabilire un valore di confidenza (il cosiddetto \textit{trust}) relativo ad
  ogni altro membro della ragnatela.}  In questo modo anche se non si ha una
verifica diretta, ma ve ne sono molte indirette da parte di terzi, si può
decidere di aver raggiunto un ragionevole livello di fiducia.

Per questo motivo e per la sua natura distribuita, almeno dal punto di vista
teorico, il modello del \textit{web of trust} è più sicuro, sia perché
consente un controllo più dettagliato dell'attribuzione della fiducia, sia
perché in questo caso la compromissione di una \textit{Certification
  Authority} non è sufficiente per creare una falsificazione generale di
qualunque chiave, come invece è già successo nel caso di un \textit{Trusted
  Third Party} risultato non troppo affidabile.\footnote{si fa riferimento a
  quanto verificatosi nel 2011 con la compromissione di varie CA (Comodo,
  DigiNotar) che ha portato all'emissione di numerosi certificati falsi per
  conto anche di terzi che non facevano riferimento a dette
  \textit{Certification Authority}.}

Inoltre il modello si presta naturalmente anche alla distribuzione diretta
delle informazioni, è infatti possibile per il singolo pubblicare le proprie
chiavi pubbliche, corredate di tutte le firme raccolte, così che un terzo
possa ottenerle direttamente, ed esiste una rete dei cosiddetti
\textit{keyserver} che si scambiano direttamente queste informazioni, a cui ci
si può rivolgere per ottenere le chiavi pubbliche altrui e pubblicare le
proprie.

Il sistema fornisce inoltre anche una risposta molto più efficace ai problemi
dovuti alla eventuale compromissione di una chiave privata, è infatti
possibile, fintanto che se ne possiede una copia, perché ovviamente questa
operazione può essere effettuata solo dal proprietario, generare una revoca
della propria chiave. Questa revoca potrà essere pubblicata e se viene inviata
alla citata rete di \textit{keyserver} verrà immediatamente incorporata nei
dati della propria chiave pubblica rendendola invalida una volta per tutte. Si
evitano così tutti i problemi relativi alla distribuzione periodiche di CRL.

Benché con l'introduzione di PGP (di cui parleremo più avanti) questo modello
sia nato e si sia sviluppato in forma alternativa a quello delle
\textit{Certification Authority} illustrato in sez.~\ref{sec:PKI_intro}, e
faccia quindi riferimento alla nomenclatura classica di chiave pubblica e
chiave privata, pur utilizzando un diverso formato per le informazioni, esso
resta comunque completamente generico, e può essere implementato anche usando
le chiavi e i certificati illustrati in sez.~\ref{sec:pki_certificates}.

Infine si tenga presente che i due modelli si possono sovrapporre, ed in
particolare si possono realizzare sistemi misti in cui si sovrappone un ente
certificatore centrale alle verifiche distribuite. Un esempio di questo
modello è quello realizzato dal progetto \textit{CAcert.org}.

\subsection{Una panoramica su GPG/PGP}
\label{sec:gpg_intro}

Il progetto \itindex{GNU~Privacy~Guard~(GPG)} \textit{GNU Privacy Guard} (GPG)
nasce come reimplementazione libera di \itindex{Pretty~Good~Privacy~(PGP)} PGP
(\textit{Pretty Good Privacy}), un programma per la cifratura della posta
elettronica scritto da Philip Zimmerman nel 1991 e considerato come la prima
applicazione ad aver utilizzato su larga scala la crittografia a chiave
asimmetrica.

Utilizzato inizialmente per la cifratura dei messaggi di posta elettronica, il
programma permette anche di cifrare file arbitrari, e supporta anche la
creazione di firme digitali, tanto che oggi viene comunemente usato come
meccanismo principale nella verifica di autenticità ed integrità dei pacchetti
software distribuiti via rete dalle principali distribuzioni di GNU/Linux.
 
Dato che PGP non era software libero e che per le versioni più recenti non
sono neanche disponibili i sorgenti, per cui non se ne può verificare la
sicurezza,\footnote{in particolare non è possibile sapere se non vi siano
  state inserite delle \textit{backdoor}, che è critico per gli scopi del
  programma.}  GPG venne creato come alternativa libera e sviluppato anche
grazie ad un sostanzioso finanziamento da parte del governo tedesco, che
voleva poter disporre di un programma che garantisse in maniera adeguata la
sicurezza delle proprie comunicazioni. A tutti gli effetti è equivalente al
più famoso antenato ed è usato correntemente al suo posto.

Entrambi i programmi usano crittografia a chiave asimmetrica e sono
compatibili fra loro. Noi tratteremo solo GPG ma la nomenclatura è nata con
PGP, per cui nella stessa si fa riferimento a questo programma, anche se
quanto diremo si applica in maniera identica anche per GPG. In questo caso non
esistono certificati e chiavi, ma si parla di \textsl{chiave pubblica PGP}
(\textit{PGP public key}) e di \textsl{chiave privata PGP} (\textit{PGP
  private key}) che insieme costituiscono la cosiddetta ``\textsl{coppia di
  chiavi}'' (quella che in gergo si chiama \textit{keypair}). Essendo PGP nato
come sistema per lo scambio sicuro di posta elettronica, non è previsto niente
di simile al protocollo SSL, e non è possibile cifrare in maniera generica il
traffico di rete usando GPG.

Il formato delle chiavi PGP e l'intero funzionamento del sistema è stato
standardizzato con il nome di \textit{OpenPGP},\footnote{la versione più
  recente dello standard è specificata
  nell'\href{http://www.ietf.org/rfc/rfc4880.txt}{RFC~4880}.} ed è a questo
standard che fanno riferimento le varie implementazioni. Entrambi i tipi di
chiave possono essere rappresentate in forma testuale, in un formato molto
simile al PEM, con dati codificati in \textit{base64} racchiusi fra delle
linee di intestazione che indicano il contenuto.

Come un certificato anche una chiave pubblica PGP contiene informazioni
ulteriori oltre ai semplici elementi crittografici, ma non essendovi mai
stata, neanche dal punto di vista teorico, una autorità centrale, non esiste
niente di affine alle informazioni dello standard X.509 che si trovano nei
certificati. 

Una chiave pubblica PGP è costituita dalla parte pubblica di una chiave
asimmetrica principale (detta \textit{master signing key}), dalle parti
pubbliche delle sottochiavi e da una lista di ``\textsl{identificativi
  utente}'' (il cosiddetto \textit{User ID}). Il sistema infatti prevede che
la chiave principale venga usata per solo per firmare le sottochiavi, che sono
quelle che possono essere usate per firmare e cifrare i messaggi; queste fanno
la vece dei certificati intermedi, e possono essere aggiunte e rimosse. La
presenza di queste sottochiavi e di tutti gli identificativi sono validate
dalla firma dalla \textit{master signing key}.

Ciascuna chiave e sottochiave porta con sé, oltre alle informazioni
crittografiche una data di creazione, una scadenza ed un identificativo, detto
\textit{Key-ID}; questo corrisponde alle prime otto cifre della cosiddetta
\textsl{impronta digitale} (la \textit{fingerprint}) della chiave, che altro
non è che l'hash crittografico della stessa.  In genere si usa la
\textit{fingerprint} della \textit{master signing key} ed il relativo
\textit{Key-ID} per identificare univocamente una chiave pubblica PGP, ed è a
questo che si fa riferimento quando si parla genericamente di
\textit{fingerprint} e di \textit{Key-ID} di una chiave.

Gli ``\textsl{identificativi utente}'' (o \textit{User ID}) servono invece ad
indicare la persona o ad l'entità a cui è associata la chiave PGP, e sono
composti a loro volta di un nome e cognome, di un commento, e di un indirizzo
di posta elettronica, nella forma:
\begin{Example}
Nome Cognome (Commento) <emailuser@dominio.it>
\end{Example}
in genere se ne indica almeno uno in fase di creazione, a cui ne possono
essere aggiunti in seguito degli altri, corrispondenti ad esempio ai diversi
indirizzi di posta che una persona può avere. Come per le sottochiavi gli
identificativi possono essere aggiunti e rimossi. 

Per assicurare l'integrità delle informazioni relative alle sottochiavi ed
alle identità presenti in una chiave pubblica, queste sono comunque sempre
firmate dalla \textit{master signing key} cosicché risulti impossibile ad un
terzo aggiungere ad essa una identità o una sottochiave fittizia. Una chiave
privata PGP ha una struttura analoga a quella di una chiave pubblica, ma in
questo caso contiene come elementi crittografici solo le parti private della
\textit{master signing key} e di tutte le altre sottochiavi, e non vi sono
presenti né gli identificativi utente, né le firme ricevute.

Infine con la chiave pubblica sono distribuite anche tutte le firme che questa
ha ricevuto da parte dei terzi che ne hanno controllato la
validità,\footnote{fra queste è sempre compresa, anche se non elencata
  esplicitamente la firma da parte della propria \textit{master signing key}.}
che in questo caso però non vengono da una CA, ma da tutti gli altri utenti di
GPG/PGP che la hanno verificata, cosa che viene fatta o per conoscenza diretta
del titolare della chiave o in uno dei tanti \textit{key signing party} che
vengono organizzati presso conferenze, congressi e riunioni varie.

In tal caso è bene portarsi con se almeno due documenti di identità ed
abbondanti stampe della \textit{fingerprint} della chiave da cedere ai
presenti. I documenti sono necessari a convincere gli altri partecipanti che
voi siete effettivamente voi,\footnote{questo se volete dimostrare la vostra
  identità pubblica, è possibile anche usare identità anonime, nel qual caso
  però dovrete dimostrare di essere chi dichiarate di essere in modo diverso.}
la \textit{fingerprint} (in genere stampata in esadecimale su un biglietto
insieme alle altre informazioni) ed il relativo \textit{Key-ID} serve a non
doversi portar dietro l'intera chiave pubblica fornendo comunque al
corrispondente tutto il necessario perché questi possa procurarsela essendo
sicuro che sia quella ``\textsl{giusta}''.


\subsection{Il comando \texttt{gpg} e l'uso di GPG}
\label{sec:gpg_utilization}

\input{gpg.tex}

% LocalWords:  TLS SSL PKI public key infrastructure the middle authority PEM
% LocalWords:  certification secure socket layer corporation TCP draft hash and
% LocalWords:  transport security RFC openssl  challenge response SSH TTP third
% LocalWords:  trusted of PGP GPG digital identity OpenCA guard pretty good DER
% LocalWords:  PKCS Diffie Hellman LDAP organization organizational unit common
% LocalWords:  department name tab version number CRL signature algorithm info
% LocalWords:  issuer validity subject extensions cert type MIME object Philip
% LocalWords:  signing client sez patch revocation list libssl libtls locality
% LocalWords:  Zimmerman Truelite DSA stunnel https STARTLS SMTP RSA Request sh
% LocalWords:  CSR UDP Datagram DTLS descriptor bootstrap conf ini Windows yes
% LocalWords:  chroot pathname setuid setgid CAfile CRLfile verify accept debug
% LocalWords:  connect facility priority syslog compression zlib rle pid PID pl
% LocalWords:  CApath CRLpath sslVersion all tinyca wrapper crl to IT ST FI Srl
% LocalWords:  dsa pkey genpkey genrsa gendsa rsa req OpenSSL Perl var ps fd
% LocalWords:  shell wipe days filename making using configuration from is it
% LocalWords:  generating writing new pass phrase verifying about asked you OU
% LocalWords:  information that will incorporated into your request what CN May
% LocalWords:  called distinguished DN There quite few fields but can leave for
% LocalWords:  blank there value id field left letter company section address
% LocalWords:  demoCA text please following attributes sent with an FQDN fully
% LocalWords:  qualified domain OpenLDAP hostname requests certified commit ls
% LocalWords:  write entries updated signed umask wildcard subjectAltName slapd
% LocalWords:  GnuTLS certs root CAcert org SSLv TLSv newca parker Before GMT
% LocalWords:  not after rsaEncryption newreq CertAuth AU eg pem noout VPN sign
% LocalWords:  modulus matches subjects as follows countryName PRINTABLE until
% LocalWords:  stateOrProvinceName localityName organizationName commonName Aug
% LocalWords:  emailAddress newcert newkey read URL DNS total stdin passin at
% LocalWords:  passout encoding rules enhanced BEGIN identifier sha comment
% LocalWords:  WithRSAEncryption generated long env Jun basic Constraints DES
% LocalWords:  validation policies virtual host based shred cnf SSLEAY Repeat
% LocalWords:  CONFIG config CADAYS truelite details TRUE index txt Squeeze
% LocalWords:  organizationalUnitName bits min usr objsign nsCertType dotted
% LocalWords:  decimal gnulinux keyserver backdoor keypair OpenPGP gpg gen We
% LocalWords:  fingerprint gnupg home passphrase GnuPG Foundation Inc This if
% LocalWords:  change redistribute extent permitted law select kind want may
% LocalWords:  only selection keys between keysize specify how should valid
% LocalWords:  does expire expires weeks months years this correct need form
% LocalWords:  identify constructs protect ssh lot bytes perform other move
% LocalWords:  action keyboard utilize disks during generation gives better
% LocalWords:  generator gain enough entropy available work give collect has
% LocalWords:  trustdb created marked ultimately checking marginal needed he
% LocalWords:  depth keyring revoke reason specified been compromised longer
% LocalWords:  superseded used here decision description empty line unlock OS
% LocalWords:  armored forced which hide away gets access make unusable just
% LocalWords:  smart print store become unreadable have caution system might
% LocalWords:  machine others armor send recv sending hkp requesting scheme
% LocalWords:  imported processed ldap mailto requested selected cancel local
% LocalWords:  probably archive Aautomatic untrusted recipient encrypt detach
% LocalWords:  assurance belongs named primary subkey certain person main say
% LocalWords:  really doing answer next question anyway detached decrypt edit
% LocalWords:  automatic encrypted never usage unknown revoked save quit des
% LocalWords:  unable sure changes correctly looking passports fingerprints
% LocalWords:  different sources marginally back shown necessarily unless Pty
% LocalWords:  restart program RedHat CentOS Widgits Ltd DigiNotar WARRANTY
% LocalWords:  Elgamal Heinrich Heine Der Dichter uid sec asc BLOCK Surchi
% LocalWords:  Fri Jul CEST fpr

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "sicurezza"
%%% End: 

