OpenSSL utilizza, per molte delle sue funzioni, uno o più files contenenti dei dati casuali
per inizializzare il generatore dei
numeri casuali
. Uno degli utilizzi più semplici di OpenSSL è proprio quello di generare files contenenti
dati pseudo-casuali.
Esistono diversi modi per poter creare un file contenente dei dati casuali. I primi due modi
che mostreremo non usano OpenSSL, mentre il terzo utilizza un comando proprio di OpenSSL: il
comando
rand
.
cat file_a file_b file_c > file_casuale
dd if=/dev/random of=file_casuale bs=1b count=1k
$ openssl rand –out
file_casuale 4096
Un altro modo di usare OpenSSL è quello di generare una o più chiavi private per utilizzare protocolli di comunicazione ed algoritmi di cifratura a chiave pubblica. OpenSSL permette di generare sia chiavi RSA che chiavi DSA.
Per generare una chiave RSA , si utilizza il comando openssl genrsa di cui diamo la sintassi nella figura 4.4 seguente.
Ad esempio, il comando seguente genera una chiave RSA. In particolare, viene utilizzato il file file_casuale (generato, ad esempio, come mostrato al paragrafo 4.1) come origine di dati casuali, e si ottiene il file chiave_privata.pem di 1024 bit:
$ openssl
genrsa -rand file_casuale -out chiave_privata.pem 1024
Un esempio di output di questo comando è mostrato in figura 4.5.
Si noti che, per default, il
comando genrsa genera una chiave RSA utilizzando come esponente pubblico
il valore e=655537. Si può, in alternativa, scegliere il valore dell’esponente
e=3 utilizzando l’opzione –3. L’opzione –F4, invece, indica
ancora l’esponente di default.
Eventualmente, per creare una chiave privata cifrata con un algoritmo di cifratura a blocchi, basta
aggiungere un'opzione a scelta tra -des, -des3 e -idea, che stanno ad indicare
rispettivamente gli algoritmi DES, DES-triplo e IDEA (che sono gli unici disponibili per il comando
genrsa). Nella figura 4.6 viene mostrato il caso in cui si utilizza l'opzione -des3,
mentre un esempio di output di tale comando è mostrato in figura 4.7.
Si noti che, quando si richiede la creazione di una chiave privata cifrata, viene richiesta una passphrase come chiave dell’algoritmo di cifratura. Se è presente l’opzione –passout, la passphrase non sarà richiesta a video, ma sarà presa da una sorgente alternativa indicata nel comando. Ad esempio, indicando –passout file:nome_file si indica che la passphrase deve essere presa dal file nome_file.
Volendo riportare in chiaro la chiave cifrata creata in precedenza, si usa il comando
openssl rsa
,
di cui mostriamo la sintassi nella figura 4.8 seguente,
in modo simile a quanto riportato nell’esempio in Figura 4.9 seguente:
In modo analogo funziona l'operazione di protezione di una chiave; in pratica si aggiunge l'opzione attraverso cui si specifica il tipo di algoritmo:
$ openssl rsa -des3 -in chiave_privata.pem -out chiave_priv_prot.pem
In modo simile al comando genrsa,
anche in questo caso possono essere specificate delle sorgenti
alternative per
le passphrase con le opzioni –passin che indica una sorgente per la
passphrase del file di input e –passout per una sorgente della
passphrase del file di output.
Il comando rsa può anche
essere usato per visualizzare il modulo della chiave RSA utilizzando
l'opzione -modulus in modo simile a quanto mostrato nell'esempio
seguente:
$ openssl rsa –in chiave_privata.pem –modulus
L'opzione –text, invece, stampa la chiave in formato leggibile mostrando i valori della chiave pubblica e privata, nonché i fattori ed altri coefficienti. Ad esempio, il comando seguente
$ openssl rsa –in chiave_privata.pem –text
fornisce un output del tipo mostrato nella figura 4.10 seguente.
L'opzione –pubout, invece, viene utilizzata per inserire in un file la chiave pubblica, vista come una coppia (n.e) codificata in PEM come nell’esempio seguente:
$ openssl rsa –in
chiave_privata.pem –out chiave_pubblica.pem -pubout
Per ulteriori opzioni sui comandi genrsa ed rsa si veda le relative sezioni nella parte Manuale.
Per generare una chiave DSA , bisogna per prima cosa generare i parametri che servono per creare le chiavi pubblica e privata DSA. Per fare ciò si utilizza il comando dsaparam di OpenSSL.
Il comando dsaparam, di cui è riportata la sintassi nella figura 4.11 seguente, permette di generare dei parametri per le chiavi DSA.
In particolare, il seguente comando genera un insieme di parametri DSA di 512 bit e li scrive in un file in formato leggibile.
$ openssl dsaparam -out param_dsa -rand file_casuale -text 512
L'opzione
–out param_dsa indica il file in cui verranno scritti i parametri
generati. L’opzione –rand file_casuale, invece, indica un file di dati
casuali che viene utilizzato per inizializzare il generatore di numeri casuali.
L’opzione –text indica che i parametri devono essere stampati in formato
leggibile. Il valore 512, infine, indica la dimensione dell’insieme dei
parametri.
Un
esempio di output del comando precedente è quello rappresentato nella Figura
4.12
Una volta generato un insieme di parametri DSA, si può passare alla generazione delle chiavi DSA usando il comando gendsa di cui riportiamo la sintassi in Figura 4.13.
Per generare una chiave DSA si può utilizzare il comando nel modo seguente:
$ openssl gendsa -out dsa_key.pem -rand file_casuale
param_dsa
che fornisce un output simile a quello mostrato in Figura 4.14. L’opzione –out indica il file in cui verrà scritta la chiave, mentre l’opzione –rand permette di specificare uno o più file di dati casuali che servono ad inizializzare il generatore di numeri casuali. Il valore param_dsa indica il file da cui prelevare i parametri DSA generati tramite il comando dsaparam.
Eventualmente, con l’opzione –text la chiave viene scritta in formato leggibile come mostrato nella Figura 4.15 seguente. Inoltre, come visto nel comando rsa, è possibile cifrare e decifrare ed effettuare altri tipi di operazioni sulle chiavi DSA utilizzando il comando dsa ( vedere la sezione relativa nel manuale ).
OpenSSL contiene anche un tool di crittografia molto completo per quel che riguarda le normali operazioni di cifratura e decifratura. Infatti, in OpenSSL sono disponili sistemi di cifratura per cifrare con i più noti algoritmi di cifratura a chiave pubblica ed a chiave simmetrica. In particolare, openssl mette a disposizione i seguenti algoritmi:
Per cifrare e decifrare un file, in particolare, OpenSSL mette a disposizione il comando enc, di cui è mostrata la sintassi nella Figura 4.16, tramite il quale è possibile chiamare uno qualsiasi degli algoritmi disponibili.
In
particolare, si noti che è possibile utilizzare anche semplicemente il nome
dell'algoritmo di cifratura che si vuole utilizzare al posto del comando enc.
Per
mostrare l’utilizzo degli algoritmi di cifratura, consideriamo il testo in
chiaro (tratto da ‘A livella di Totò) mostrato nella Figura 4.17
seguente che supporremo memorizzato nel file TestoinChiaro.txt.
Andiamo, quindi, a cifrare tale testo con alcuni degli algoritmi supportati da OpenSSL. Per cifrare il testo, si utilizza il comando seguente specificando il particolare algoritmo alg desiderato:
$ openssl alg -in
Testo_in_chiaro.txt -out Testo_cifrato.txt -pass file:password -e
Per decifrare, si utilizza lo stesso comando nel modo seguente:
$
openssl alg -in Testo_cifrato.txt -out Testo_in_chiaro.txt -pass file:password –d
Nelle Figure seguenti vengono mostrati alcuni esempi di cifratura del testo indicato in Figura 4.17 con alcuni degli algoritmi supportati da OpenSSL.
OpenSSL fornisce anche delle routines per generare valori hash di messaggi e files utilizzando diversi tipi di funzioni Hash. In particolare, le funzioni supportate sono le seguenti:
Per calcolare il valore hash di un testo, si utilizza il comando dgst di cui riportiamo la sintassi nella Figura 4.20.
Per mostrare l'utilizzo del comando dgst utilizzeremo il testo mostrato nella figura 4.21, di cui calcoliamo i valori hash con le varie funzioni supportate.
Per calcolare il valore hash del testo suddetto, si utilizza il comando seguente indicando la funzione da utilizzare nel campo –func.
$ openssl dgst -func -out myjoin.md5 myjoin.c
In particolare, uno o più file di cui calcolare il valore hash vengono indicati alla fine del comando (nel nostro caso myjoin.c). Gli output delle varie funzioni hash calcolate sul testo suddetto vengono riportati nella figura 4.22.
Il comando dgst può anche essere utilizzato per firmare un Message Digest o verificare la firma su un Message Digest. In particolare, per firmare un MD, si utilizza il comando nel modo seguente:
$ openssl dgst -out myjoin.sig -sign
rsa_key.pem myjoin.dss1
in cui myjoin.dss1 contiene il valore da firmare, il file rsa_key.pem contiene la chiave RSA con cui firmare e il file myjoin.sig (mostrato in figura 4.22) contiene la firma.
Per verificare la firma di un MD, invece, si utilizza il comando seguente:
$ openssl dgst -verify rsa_pub.pem
-signature myjoin.sig myjoin.dss1
in cui
myjoin.dss1 contiene il file firmato, il file myjoin.sig contiene
la firma da verificare (specificato dall’opzione –signature) e il file rsa_pub.pem
contiene la chiave pubblica con cui verificare la firma.
La risposta della
verifica è del tipo Verify OK o Verify not OK.
Un'altra funzione di OpenSSL è la possibilità di generare i parametri per il protocollo di accordo sulle chiavi di Diffie-Hellman. Tali parametri, una volta generati, possono essere utilizzati, ad esempio, per la gestione delle connessioni tra server e client (vedere la sezione relativa a s_server e s_client).
Per generare i parametri DH, si utlizza il comando dhparam di cui si riporta la sintassi nella Figura 4.23 seguente.
Ad esempio, il comando
$ openssl dhparam -out dh_par.pem -5 -rand file_casuale 512
genera un insieme di parametri di Diffie-Helman di 512 byte (indicato dal valore 512 alla fine della riga di comando). L’opzione –5 indica il tipo di generatore da usare. L'opzione –rand, ancora una volta, indica uno o più files di dati casuale da utilizzare per l’inizializzazione del generatore di numeri casuali. Infine l'opzione –out indica il nome del file in cui scrivere i parametri DH. L’output di tale comando è mostrato nella figura 4.24.
Tali parametri possono essere trasformati in formato leggibile con l’opzione –text come mostrato nel comando seguente:
$ openssl dhparam -in dh_par.pem -out dh_par.txt –text
In tal caso l’output appare come mostrato in figura 4.25.
Per mettere in
piedi un servizio che utilizzi i protocolli SSL/TLS, occorre predisporre dei
file contenenti chiavi e certificati.
Di solito,
quando si installano servizi che utilizzano questi protocolli, la procedura di
installazione si prende
cura di predisporre automaticamente i file necessari
per consentire il funzionamento, senza che le certificazioni
che si ottengono
abbiano alcun valore.
In generale si comincia dalla
creazione o dalla definizione di un file contenente dati casuali, come punto di
partenza per generare una chiave privata (come descritto nel punti 4.1
– 4.3), quindi si passa alla creazione di
una richiesta di
certificazione, oppure alla creazione di un certificato
auto-firmato, senza valore.
Teoricamente, il certificato che identifica e garantisce l'identità del servizio che si gestisce, deve essere fornito da un'autorità di certificazione. Tale autorità, per rilasciare il certificato, deve ricevere un documento intermedio, definibile come una richiesta di certificazione. Per ottenere un certificato o una richiesta di certificato si può utilizzare il comando req di cui mostriamo la sintassi nella Figura 4.26 seguente.
La chiave pubblica che vi viene inserita si ottiene a partire dalla chiave privata, e gli altri dati necessari per il certificato che si vuole ottenere, si inseriscono in modo interattivo. È interessante vedere come avviene. Il seguente comando genera una nuova richiesta di certificazione:
$ openssl req -new -key chiave_privata.pem -out
richiesta.pem
La procedura interattiva per il riempimento dei campi viene mostrata nella Figura 4.27 seguente.
Le informazioni
che si inviano in questo modo sono molto importanti, e il significato preciso
varia a seconda del contesto per il quale si richiede la certificazione. Sarà
l'autorità per la certificazione a stabilire quali informazioni servono
precisamente.
Per verificare
il contenuto del certificato, che nel suo formato PEM non è leggibile
direttamente, si può usare il comando openssl req con
l'opzione -text:
$ openssl
req -text -in richiesta.pem
che fornisce un output del tipo mostrato in figura 4.28.
Per generare in proprio il certificato auto-firmato, in modo da attivare ugualmente il servizio anche se non si può dimostrare di essere chi si afferma di essere, si può aggiungere l'opzione -x509. Anche in questo caso vengono richieste tutte le informazioni già viste.
$ openssl req -new -x509 -key chiave_privata.pem
-out richiesta.pem
In alcuni casi può essere necessario fondere assieme la chiave privata, in chiaro, e il certificato; questo accade in particolare quando si allestisce un server HTTP Apache-SSL. Di solito la chiave privata non può essere cifrata, perché deve essere letta da un servizio autonomo che non può interrogare un utente. Si deve ottenere una cosa simile a quella mostrata nella figura 4.29 seguente.
L'aggregazione può essere fatta a mano (attraverso cat), oppure si può utilizzare un comando unico che crea la chiave privata (di dimensione predefinita) e anche il certificato autoprodotto:
$ openssl req -new -x509 -nodes -out
cert.pem -keyout cert.pem
In questo esempio è stata usata l'opzione -keyout per dirigere la chiave privata nello stesso file del certificato, e anche l'opzione -nodes, per evitare la protezione della chiave che in questi casi deve essere usata in chiaro.
L'utilizzo di OpenSSL per la gestione di
un'autorità
di certificazione richiede la conoscenza di molti dettagli sul
funzionamento di questo sistema.
In generale, il file di configurazione
predefinito consente di ottenere delle richieste di certificati o di generare
dei certificati fittizi auto-firmati.
In questo gruppo di sezioni si vuole mostrare
schematicamente l'uso di OpenSSL nella gestione di un'autorità di
certificazione, anche con qualche esempio, ma senza l'intenzione di arrivare a
ottenere dei certificati realistici.
Per la creazione di un'autorità di certificazione
autonoma, ovvero di un'autorità principale (root),
che non abbia
ottenuto a sua volta un certificato da un'autorità di livello superiore,
bisogna realizzare una
propria chiave privata e un proprio certificato
auto-firmato.
Diversamente, se si dipendesse dalla
certificazione di un'altra autorità, bisognerebbe predisporre una propria
richiesta e sottoporla all'autorità superiore da cui si dovrebbe ottenere il
certificato.
Per default, per la gestione della CA viene
utilizzato il file openssl.cnf. In alternativa, è possibile creare un
proprio file di configurazione ed utilizzarlo specificando l’opzione –config.
Per la creazione di un file di
configurazione si veda la parte Installazione e
Configurazione
oppure la parte del Manuale relativa al comando
ca.
Tutti i file necessari alla configurazione ed
alla gestione di una CA devono essere
inseriti a partire dalla directory
./demoCA/.
In particolare, si suppone che ./demoCA/private/.rand
sia un file contenente informazioni casuali da cui
si genera una chiave privata
(preferibilmente cifrata) ./demoCA/private/CAkey.pem.
Per tale chiave, si deve generare un certificato
auto-firmato memorizzandolo, ad esempio, nel file
./demoCA/CAcert.pem.
Si osservi in particolare che è possibile
indicare espressamente il periodo di validità del certificato con
l'opzione -days.
Il certificato, in quanto tale, va conservato anche
nella directory destinata a contenere la copia di quelli che
verranno
rilasciati in qualità di autorità di certificazione, che ad esempio potrebbe
essere
./demoCA/certs/.
Questi file devono avere un nome che inizia con il loro numero di serie, e dal
momento
che il numero del certificato dell'autorità stessa è il numero zero,
obbligatoriamente, il file deve
chiamarsi ./demoCA/certs/00.pem.
Per effettuare le funzioni proprie di una CA, si
utilizza il comando
ca di
cui riportiamo la sintassi in
figura 4.30.
Per le operazioni di rilascio dei certificati,
ovvero della firma di questi a partire dai file di richiesta relativi, occorre
prendere confidenza con l'uso di alcuni file: il file contenente l’indice dei
certificati rilasciati e il file contenente il prossimo numero di serie da
utilizzare.
Come abbiamo già accennato in precedenza (vedi
par. 4.7.1),
i certificati
rilasciati da un'autorità di certificazione hanno un numero seriale
progressivo; questo numero viene
conservato nel file del prossimo numero
seriale che, ad esempio, potrebbe essere il file demoCA/serial.
Il numero in questione viene annotato secondo una
notazione esadecimale, tradotta in caratteri normali, ma
senza alcun prefisso.
In pratica, nella fase di configurazione della
CA, dopo aver predisposto il certificato della stessa autorità,
occorre creare
questo file contenente il prossimo numero seriale inserendovi all’interno una
sola riga
contenete il valore 01 e conclusa da un codice di interruzione
di fine riga, e nulla altro.
Ogni volta che viene creato un certificato,
questo numero viene incrementato automaticamente. Inoltre, se non
viene
specificato il nome del file in cui scrivere il certificato, viene utilizzato
come nome del file il numero di
serie del certificato, con l'aggiunta
dell'estensione consueta. Il certificato verrà poi posto nella directory
prevista per l'accumulo provvisorio. Ad esempio, noi supporremo che i
certificati sono posti nella directory
demoCA/newcerts/.
Oltre al file col numero seriale, esiste un altro
file che viene modificato dalla creazione di un certificato: il
file che contiene
l'indice dei certificati, che, ad esempio, potrebbe essere il file demoCA/index.txt.
Inizialmente, dopo la creazione del certificato
dell'autorità stessa, questo indice è semplicemente un file vuoto;
con la
creazione dei certificati successivi, viene aggiunta una riga per ognuno di
questi, che va intesa come un
record suddiviso in campi separati da un carattere di tabulazione singolo.
Ad esempio, nella figura 4.31 viene
mostrato un record di esempio di un
certificato.
Si noti che, prima del valore 01, è presente un ulteriore campo che, nel nostro caso di esempio, è un campo con contenuto nullo. Si noti inoltre, che i dati dell’ultimo campo dovrebbero essere posti su un’unica riga, anche se qui non è stato possibile per motivi di stampa. I campi hanno il significato seguente:
La creazione (ovvero la firma) di un certificato si ottiene, come detto in precedenza, con il comando openssl ca . fornendo in particolare il file contenente la richiesta. Per esempio, se si volesse semplicemente accettare la richiesta costituita dal file richiesta.pem, si dovrebbe usare il comando
openssl ca -in richiesta.pem
dove l'opzione –in indica il file da cui
prelevare la richiesta (per default viene utilizzato lo standard input).
Avendo, inoltre, in questo caso indicato esclusivamente il nome del file che
contiene la richiesta, le altre
informazioni vengono prese dal file di
configurazione.
In base a quanto indicato in precedenza, quindi,
per la firma viene usata la chiave contenuta nel file
demoCA/private/cakey.pem,
il file del certificato viene creato nella directory demoCA/newcerts/,
con un nome corrispondente al suo numero di serie e con la solita estensione .pem, e soprattutto, è stata
usata la sezione predefinita nel file di configurazione,
ovvero la sezione [CA_default].
Al contrario, se si volesse dichiarare tutto in
modo esplicito, lo stesso comando avrebbe dovuto essere espresso
nel modo
seguente:
openssl ca -name CA_default -keyfile demoCA/private/cakey.pem
(segue)
-in richiesta.pem -out demoCA/newcerts/`cat demoCA/serial
in cui:
Se viene usato questo comando, viene avviata una procedura interattiva che richiede alcune risposte e conferme come indicato nella Figura 4.32 seguente.
Una volta creato un certificato in questo modo, questo va collocato nella sua posizione definitiva, che in questo caso è la directory demoCA/certs/.
Se si incontra la necessità di revocare dei
certificati prima della loro scadenza normale, la CA deve pubblicare
un elenco
di revoca, o CRL (Certificate Revocation List).
Questo elenco viene prodotto in OpenSSL in due
fasi: per prima cosa deve essere modificato il file contenente
l'elenco dei certificati (./demoCA/index.txt) sostituendo la lettera «V»
con la lettera «R», e inserendo la
scadenza anticipata nel terzo campo. La
Figura 4.33, in particolare, mostra il caso di due certificati che vengono
revocati prima della scadenza.
Nella seconda fase, deve essere generato l’elenco dei certificati revocati vero e proprio utilizzando l’opzione –gencrl del comando openssl ca come nel comando seguente:
openssl ca -gencrl -out ./demoCA/crl/crl.pem
Con questo comando, viene creato il file ./demoCA/crl/crl.pem, contenente l'elenco di revoca, il cui contenuto può essere riletto con il comando
openssl crl -text -in ./demoCA/crl/crl.pem
e che ha un aspetto simile a quello presentato in figura 4.34.
In generale, con OpenSSL si lavora con file
(richieste, certificati, elenchi di revoca, ecc.) in formato PEM, che è in
pratica una forma compatta dei dati, utilizzando però solo il codice ASCII a
7 bit. Ci sono situazioni in cui è
necessario convertire questo formato in
un altro, oppure è necessario acquisire dei dati da un formato diverso
dal
solito.
In generale, quando si usano comandi che possono
ricevere dati in ingresso, o quando devono generare dati in
uscita, sempre
relativi a certificati e affini, si possono usare rispettivamente le opzioni -inform e
-outform,
seguite dalla sigla del formato (non sono disponibili sempre tutti). Vengono
mostrati alcuni
esempi.
Il comando seguente effettua la conversione del
certificato certificato.pem nel file certificato.der,
che risulta in formato DER (binario).
$ openssl
x509 -in certificato.pem -outform der -out certificato.der
Il comando seguente converte l'elenco di revoca crl.pem nel file crl.der in formato DER.
$ openssl crl -in crl.pem -outform der -out crl.der
OpenSSL mette a disposizione anche la possibilità di effettuare, ovviamente, una connessione utilizzando i protocolli SSL/TLS. In particolare, è possibile utilizzare i due comandi di testing s_server (di cui si riporta la sintassi nella figura 4.36) ed s_client (di cui si riporta la sintassi nella figura 4.35) che forniscono semplici programmi per stabilire una connessione client/server SSL.
In generale, la connessione che
viene stabilita tra client e server si limita solo ad effettuare un semplice
rimbalzo dei messaggi digitati dal client e dal server (una semplice chat
protetta).
E’ comunque possibile, come
vedremo più avanti, utilizzare questi programmi in maniera differente
utilizzando alcune opzioni.
Illustriamo, di seguito, alcuni
esempi di connessione tra client e server.
Quando si vuole generare una connessione sicura tra un server ed un client OpenSSL, bisogna che il server possieda un certificato (come ad esempio un certificato self-signed) ed una chiave privata (RSA o DSA). Il server, allora si pone in ascolto su una porta di comunicazione (per default viene utilizzata la porta 4433) usando il comando
$ openssl s_server –accept
nport –cert certificato –key chiave –dhparam parametri
in cui l’opzione –accept indica il numero della porta su cui mettersi in ascolto (nport), l’opzione –cert indica il file contenente il certificato, l’opzione –key indica il file contenente la chiave e l’opzione –dhparam indica il file contente i parametri di Diffie-Hellman (nel caso in cui se ne possegga uno). L'output immediato di questo comando è del tipo mostrato in figura 4.37.
Se un client vuole connettersi al server in ascolto, allora deve usare il comando
$ openssl s_client –host nome_host
nel caso in cui il server sia in ascolto sulla porta di default, oppure
$ openssl s_client –connect nome_host:porta
nel caso in cui il server sia in ascolto su una porta diversa. A questo punto il client ed il server iniziano una fase di handshake in cui si scambiano una serie di parametri di sessione ed al termine della quale, se è andato tutto bene, viene stabilita la connessione. In particolare, server e client forniscono una serie di output come mostrato nella figura 4.38.
Si ribadisce che, in questo caso, il client non ha avuto bisogno di inviare un proprio certificato per stabilire la connessione, dato che il server non effettua alcuna verifica sul certificato e non richiede che il client ne i nvii uno.
Se il server desidera che il
client che si autentica invii un certificato per effettuare la connessione,
allora deve utilizzare l’opzione –verify o l’opzione –Verify. La
prima opzione richiede un certificato,
ma il client potrebbe anche non averne
uno da inviare, mentre la seconda genera un errore nel caso in cui il
client
non invia il certificato.
A questo punto, il server
potrebbe mettersi in ascolto lanciando il seguente comando:
$ openssl s_server -cert certificato -key chiave -dhparam param
-Verify 9
in cui il valore 9 indica il livello di profondità della verifica da effettuare sul certificato. In questo caso, se il client stabilisce una connessione senza inviare il certificato (usando il comando di cui al punto 4.8.1), allora viene generato un errore e la connessione viene rifiutata, fornendo un output del tipo mostrato in figura 4.39.
Per permettere ad un client di autenticarsi per una connessione con un server che richiede un certificato, bisogna utilizzare l’opzione –cert per indicare il certificato e l'opzione –key per indicare la chiave da utilizzare. In particolare, quindi, bisogna utilizzare il comando
$ openssl s_client –host nome_host –cert certificato –key chiave
A questo punto bisogna fare
alcune puntualizzazioni. OpenSSL permette l'accesso al client anche se la
verifica del certificato non è andata a buon fine. Questo potrebbe anche essere
considerato come un bug,
ma considerando che s_client ed s_server sono solo
programmi di testing, forse questa scelta potrebbe
considerarsi giustificata.
In particolare, s_server fornisce un messaggio d'errore nel caso in cui la
verifica del
certificato non dia esito positivo , ma permette, come detto
prima, al client di accedere lo stesso alla
connessione.
Ci sono alcune differenze nelle
risposte date a seconda del tipo di certificato che viene inviato dal client.
Ad esempio, i comandi precedenti
danno risposte del tipo mostrato in Figura 4.40 nel caso in cui non sono
conosciuti i certificati delle CA del server e del client.
Per fare in modo che il server riconosca la CA del client, il server ha bisogno di un certificato della CA del client che deve essere specificato nell'opzione CAfile, come mostrato nel comando seguente:
$ openssl s_server -cert certificato -key chiave -dhparam param -CAfile certCA_client -Verify 9
In alternativa, si può
specificare una directory contenente uno o più certificati trusted
utilizzando
l'opzione CApath. Tale directory, però, deve essere in
hash format.
Analogamente, per fare in modo
che il client riconosca la CA del server, essa deve essere una CA fidata, per
cui il client ha bisogno del certificato della CA che viene specificato nel
comando s_client ancora con l'opzione
CAfile, come nel comando
seguente:
$ openssl s_client -host nome_host -cert certif -key chiave -CAfile certCA_server
In questo caso, l'output del client e del server saranno del tipo mostrato in figura 4.41.
Quando il client ed il server
effettuano la fase di handshake, si accordano, tra l’altro, sul tipo di
cifrario da utilizzare per scambiarsi i dati e sulle chiavi da usare. In
generale, il client propone una lista di
cifrari che esso supporta, tra i quali
il server ne sceglie uno. Il cifrario scelto dal server è il primo della lista
del client che sia anche supportato dal server.
Se la lista dei cifrari non viene
specificata, viene utilizzata una lista di default. La lista può essere
specificata usando lìopzione –cipher come nell'esempio seguente:
$ openssl client -host
nome_host -cipher DES,RSA
In tale esempio, il client
specifica i suoi cifrari preferiti in ordine di preferenza (prima il DES e poi
RSA). In questo caso particolare, il server utilizzerà il DES in quanto è il
primo della lista del client che anche il
server supporta.
Anche il server ha la possibilità
di specificare una propria lista di cifrari, come nell’esempio seguente:
$ openssl s_server -accept nport -cert certificato -key chiave -cipher
lista_cifrari
Può capitare che il server non supporti nessuno dei cifrari richiesti dal client, come nel caso dei comandi seguenti:
$ openssl client -host nome_host -cipher RC5
$ openssl s_server -cert certificato -key chiave
In questo caso, la connessione non viene stabilita e vengono generati dei messaggi di errore come quelli mostrati in figura 4.42. Si noti che i messaggi di errore vengono generati solo dal client perché il server fa solo cadere la connessione.
Come abbiamo detto in precedenza, se vengono specificati più cifrari, il server sceglie il primo della lista che anche lui supporta. Ad esempio, se si lanciano i comandi
$ openssl s_client -host nome_host -cipher RC5,DES2,DES
$ openssl s_server -cert certificato -key chiave
il server sceglierà il DES, perché è il primo che supporta, dato che RC5 e DES2 non sono supportati, come dimostra la figura 4.43 seguente.
Esistono un’opzione in s_server
che permette di emulare un semplice web server. Per fare ciò si utilizza
l'opzione –WWW. Si noti che l'opzione –www indica una funzione
differente, ovvero restituisce
al client informazioni di sessione e sui cifrari
utilizzati in formato html.
Quando si usa l'opzione –WWW
per emulare il web server, tutte le pagine richieste vengono risolte a partire
dalla directory corrente.
Ad esempio, si può connettere un
s_client ad un s_server in funzioni di web server usando i comandi
$ openssl s_client -host nome_host
$ openssl s_server -cert certificato -key chiave -WWW
L’output di tale connessione è, di base, lo stesso di quella delle connessioni normali. A questo punto, però, si ha la possibilità di lanciare comandi HTML dal client al server. Si noti, però, che al termine dell’esecuzione del comando, la connessione viene chiusa. Ad esempio, se il client lancia il comando GET /, gli viene inviata il formato html della pagina del server e poi la connessione viene chiusa, come mostra la figura 4.44.
E’ possibile, tra l’altro,
avviare una sessione di comunicazione protetta tra un client OpenSSL e un web
server esterno che supporti il protocollo SSL/TLS.
Ad esempio, il seguente comando
permette di connettere un s_client locale al web server del sito
https://www.mondowind.it/
$ openssl s_client -connect www.mondowind.it:443
Si noti che, in questo caso, non è necessario inviare un certificato, dato che il sito suddetto non ne richiede uno. L'output del comando è mostrato in Figura 4.45.
A questo punto, se si lancia il
comando HTML GET / di cui sopra, viene ottenuto un risultato simile a
quello della
figura 4.44 (lato client):
Come nel caso, di s_client e
s_server normali, anche in questo caso è possibile scegliere il particolare
cifrario da usare. Nel caso in cui, il cifrario non è supportato dal web
server, la connessione non viene
stabilita, come mostrato nella Figura 4.46.
Un'altra funzione che si può
effettuare con s_server è il testing di un web browser. In particolare, facendo
funzionare s_server come un web server (vedi paragrafo 4.8.5),
è possibile connettere un web
browser (come NETSCAPE) al server attivato. Questo può essere fatto, ad
esempio, facendo connettere il web browser alla porta su cui è in ascolto
s_server specificando l’indirizzo e la
porta nell'URL del browser.
Una questione importante è che
alcuni browser (come
Netscape e MSIE)
supportano solo RSA, per cui essi non possono connettersi ai server che non
usano
certificati che portino chiavi RSA.
Ad esempio, se lanciamo il
comando
$ openssl s_server -WWW -cert certificato -key chiave
sulla macchina nome_macchina, specificando nell'URL di Netscape l'indirizzo https://nome_macchina:4433 si ottiene il risultato della Figura 4.47.
Fig 4.47 Connessione di un web browser ad s_server. Il certificato è spirato per cui il browser chiede all'utente se vuole fidarsi o meno. |
In particolare, il risultato della Figura 4.48 si ottiene quando il certificato è spirato. Se il certificato è valido, ma Netscape non riconosce la CA come trusted, allora Netscape chiede di nuovo se l’utente vuole fidarsi meno. Si ottiene, pertanto, la stessa catena di passi della figura 4.47, tranne per l’aspetto del certificato (Step 4) che sarà simile a quello mostrato in Figura 4.48.
Infine, se si utilizza un certificato di cui Netscape riconosce la CA, allora non viene richiesta alcuna conferma. Semplicemente, Netscape avverte che l'utente sta utilizzando un certificato firmato da una CA fidata. Ad esempio, nella Figura 4.49 è mostrata la risposta di Netscape all'utilizzo di un certificato firmato da una CA fidata.
In particolare, la CA fidata è la CA “Andrea CA” che abbiamo inserito all’interno dell’elenco delle CA di Netscape come si può vedere dalla figura 4.50 che mostra, appunto, l’elenco delle CA fidate di Netscape.
A questo punto, una volta terminata la fase di autenticazione, se sulla macchina server è presente il file index.html nella directory dove gira il server, tale pagina sarà caricata nel browser, come mostrato in Figura 4.51.
Infine, se si specifica l'opzione –www al posto dell'opzione –WWW, dopo la fase di autenticazione, la pagina html con le informazioni di sessione sarà caricata nel browser come mostrato nella figura 4.52.
Se il client si è disconnesso da
un server, esso può provare a riconnettersi allo stesso server utilizzando gli
stessi parametri di sessione. In questo caso, la procedura di handshake diventa
molto più rapida, in quanto
non viene fatto tutto lo scambio di messaggi della
connessione normale. In fase di riconnessione, il server
verifica se è
possibile utilizzare gli stessi parametri della sessione precedente. Se è
possibile, viene avviata
la fase di riconnessione.
Per richiedere la riconnessione,
il client usa l'opzione –reconnect come nel caso seguente:
$ openssl s_client -host nome_host -reconnect
ottenendo una risposta come quella in figura 4.53.
Una questione che si pone con i
certificati generati utilizzando OpenSSL è il come fare ad importare un
certificato generato da OpenSSL nel database dei certificati personali
contenuti ed utilizzati da Netscape.
Infatti, Netscape accetta solo
certificati in formato PKCS#12 (memorizzati in files con estensione .p12),
mentre OpenSSL, di base, genera solo certificati in formato PEM o DER.
Per permettere a Netscape di
importare un certificato di OpenSSL, allora, bisogna agire in due fasi.
Dopo aver generato un certificato in formato PEM o DER con OpenSSL, lo si converte in formato PKCS#12 utilizzando il comando pkcs12 di OpenSSL di cui riportiamo la sintassi nella Figura 4.54 seguente.
Il comando pkcs12, in
generale, ha una funzione ben più ampia di quella di una semplice conversione
di formato. Esso fornisce la possibilità di trattare in generale i certificati
in formato PKCS#12 (come quelli
generati da Netscape).
Per i nostri scopi, comunque, ci
interessa sapere in particolare come si fa a convertire un certificato OpenSSL
in un certificato PKCS#12. Per fare ciò si utilizza il comando nel modo
seguente:
$ openssl pkcs12 -in
certificato.pem -inkey chiave_privata -out certificato.p12 -export
in cui:
Quando si lancia questo comando, viene richiesta una password di esportazione che poi dovrà essere usata ogni volta che si vuole importare il certificato da qualche parte (Fig. 4.55).
Questo comando, quindi, fornisce un output del tipo mostrato in figura 4.56.
Dopo aver convertito il certificato in formato PKCS#12, bisogna importarlo all’interno di Netscape. Per fare questo si procede nel seguente modo.