Révocation
Niveau :
Résumé : openssl
Vérification
Maintenant que nous avons des certificats propres et bien signés il va falloir les vérifier. Mais il ne s’agit pas simplement de vérifier que le certificat est valide et signé par une autorité de confiance. Tout d’abord, il fautde vérifier toute sa chaine de confiance. Ensuite il faut vérifier ses extensions, par exemple s’il va être utilisé pour les usages auxquels on l’a prévu.
Openssl permet de faire la vérification de la chaine de certification ainsi que la vérification de l’usage. Pour cela il faut installer l’autorité de confiance :
# On trouve le hash du certificat de l'AC $ hash=$(openssl x509 -hash -noout -in cacert.pem) # On installe l'AC en utilisant ce hash (il faut être root ici) $ cp cacert.pem /etc/ssl/certs/$hash.0
Du coup la vérification d’un certificat se fait simplement :
$ openssl verify -purpose sslclient certificat.crt
Pour la vérification des extensions, il faut voir au cas par cas.
Mais contrairement à ce qu’on pense souvent, ce n’est pas tout. Il faut aussi vérifier que le certificat n’est pas révoqué, c’est-à-dire invalidé avant la date limite.
Révocation
La révocation d’un certificat se fait dans plusieurs cas :
- perte de la clé
- départ du propriétaire de la clé
- renouvellement de la clé
- …
En gros à chaque fois qu’on veut garantir que la clé ne sera plus utilisée.
Pour révoquer un certificat alors qu’on a installé une AC openssl comme dans l’article précédent :
# On en profite pour indiquer pourquoi on le révoque # les raisons possibles sont : unspecified, keyCompromise, CACompromise, # affiliationChanged, superseded, cessationOfOperation, certificateHold or removeFromCRL $ openssl ca -config openssl.cnf -revoke client.cert -crl_reason keyCompromise
Il existe 2 mécanismes pour faire savoir au monde qu’on a révoqué un certificat : les CRL et le protocole OCSP.
Certificate Revocation List
Une liste de révocation est une liste complète de certificats révoqués qu’on télécharge. On compare ensuite le certificat à vérifier à cette liste pour savoir si le certificat n’a pas été révoqué.
Cette liste est signée par l’autorité de certification pour garantir qu’elle est valide. Au passage elle est aussi datée. Avec openssl elle se gère de la même façon que l’autorité de certification, avec le même fichier de configuration. Reprenons le fichier de configuration de l’AC et ajoutons-y les spécificités des CRL.
[ Peck_authority ] # Numéro de série pour les CRL crlnumber = $dir/crlnumber # Durée au dela de laquelle la CRL doit être mise à jour default_crl_days= 30 # Ajouter des extensions à la CRL crl_extensions = crl_ext [ crl_ext ] # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always
On stocke les identifiants de crl :
$ echo "00" > ./peckCA/crlnumber
Après avoir révoqué un certificat (voir plus haut) générons la CRL :
$ openssl ca -config openssl.cnf -gencrl -out crl.list
Lisons le contenu de cette liste pour vérifier :
$ openssl crl -in crl.list -text
On peut ensuite vérifier que le certificat est révoqué ou non avec openssl en disposant de la CRL :
# Option non documentée $ openssl verify -CAfile crl.list -crl_check client.cert
Pour le faire automatiquement, il faut installer la CRL de la même façon qu’on a installé le certificat de l’AC :
# Notez l'usage de r0 à la place de 0 $ hash=$(openssl x509 -hash -noout -in crl.list) $ cp crl.list /etc/ssl/certs/$hash.r0 # Et on vérifie la révocation en même temps que la validité $ openssl verify -crl_check client.cert
Pour ne pas devoir mettre à jour les CRL à la main chez tous les clients, il faut la publier. Pour cela, il faut d’abord la convertir, en effet, les clients traditionnels comme firefox lisent la version DER (binaire) et non PEM (ascii).
$ openssl crl -inform PEM -in crl.list -outform DER -out crl.der # puis placez-la sur votre serveur
Et pour que le client sache où aller chercher cette CRL, il faut l’indiquer dans le certificat lorsqu’on le signe :
# Dans la openssl.cnf, utilisé lors de la signature de demandes [ usr_cert ] # Les url en http et en ldap sont autorisées crlDistributionPoints = URI:http://localhost/ca-crl.pem
Malheureusement, openssl ne sait pas aller chercher tout seul la crl pour faire cette vérification.
Enfin notez qu’il existe aussi des extensions deltaCRLindicator et FreshestCRL qui permettent de ne pas télécharger toute la CRL à chaque fois. Mais elles ne sont pas supportées par openssl.
Online Certificate Status Protocol
Le problème des CRL est qu’il nécessite un téléchargement plus ou moins lourd pour faire une seule vérification. C’est tout aussi pénalisant pour l’AC que pour le client. C’est pourquoi un protocole a été inventé pour permettre de faire une vérification au cas par cas.
Il permet de vérifier si un unique certificat est révoqué. Il a aussi l’avantage de ne pas dépendre de la date de validité des CRL qui sont générées et rechargées sur des périodes plus ou moins longues. Ici on a directement la bonne information.
Lançon un serveur OCSP sur notre AC fraîchement créée. Pour faire rapide nous utilisons le certificat de l’AC pour lancer le service, mais pour faire propre, nous aurions du lui créer un certificat spécifique signé par l’AC et ayant l’extension “extendedKeyUsage=OCSPSigning” :
# Il n'y a pas de port par défaut pour OCSP $ openssl ocsp -index /srv/Authority/index.txt -CA /srv/Authority/cacert.pem -rsigner /srv/Authority/cacert.pem -rkey /srv/Authority/private/cakey.pem -port 1234
Vérifions ensuite si un certificat est révoqué. Notez qu’il est nécessaire de préciser le certificat ayant signé celui qu’on veut vérifier :
# Attention, précisez -issuer avant -cert # Il est possible de vérifier plusieurs certificats d'un coup avec plusieurs -cert $ openssl ocsp -host localhost:1234 -issuer /srv/Authority/cacert.pem -cert certificat.crt
Tout comme pour les CRL, il est possible d’indiquer dans le certificat l’endroit où se trouve le serveur OCSP permettant de vérifier la révocation. Les application qui supportent (pas openssl verifiy) l’extension vont alors automatiquement la vérifier :
# Dans la openssl.cnf, utilisé lors de la signature de demandes [ usr_cert ] authorityInfoAccess = OCSP;URI:http://ocsp.my.host/