= IRC & SSL = Cette page explique un peu comment manipuler les certificats SSL et comment faire en sorte de vérifier les certificats lorsqu'on se connecte à [[../|IRC]] en [[http://fr.wikipedia.org/wiki/Secure_Sockets_Layer|SSL]] avec le client [[http://weechat.org/|WeeChat]]. <> == C'est quoi ? == Un certificat est un message signé numériquement qui vous assure d'une information : * Le premier certificat qui va vous intéresser dit : ''"Voici K_S, la clé de {{{irc.domain.com}}}"'' . Ainsi, quand vous établissez une connexion avec {{{irc.domain.com}}}, vous utiliserez K_S pour chiffrer votre message afin que seul le serveur que vous cherchez à contacter puisse le déchiffrer. On ne s'intéressera pas ici à ce certificat, mais il faut comprendre qu'il est à l'origine de tout le processus. * Comment pouvez-vous être sûr que personne n'a altéré K_S sur le chemin et que donc K_S est bien la clé de {{{irc.domain.com}}} et non pas celle de Charlie, sur le trajet, qui peut donc lire votre message ? . Il existe un autre type de certificat qui dit ''"Je suis A, voici ma clé K_A, j'atteste que K_S est bien la clé de {{{irc.domain.com}}}"'' . Le principe est que si on fait confiance à A, on peut vérifier que le message est correctement signé, et donc faire confiance à la clé K_S. . Ainsi de suite, B se porte garant de A, etc… * En haut de la chaîne<>, on finit par arriver à ''"Je suis X, j'atteste que K_X est bien la clé de X."'', qu'on appelle un certificat racine. . Donc il y a bien un moment où il va falloir faire confiance à quelqu'un. Votre navigateur a une liste d'``'''autorités de certification''' auxquelles il fait confiance pour signer d'autres certificats. Parfois, comme [[http://hackint.org/#Server|ici]], le certificat racine est signé par les clés GPG de personnes. == Comment on manipule ça ? == On va faire joujou avec les certificats du Cr@ns. Pour récupérer le certificats, on fait ça : {{{ openssl s_client -showcerts -connect irc.crans.org:6697 < /dev/null }}} * {{{openssl}}} est une commande qui permet de faire plein de choses, notamment de se comporter comme un client qui fait du SSL. * {{{s_client}}} nous met en mode client * {{{-showcerts}}} demande de montrer le certificat fournit par le serveur à la connexion * {{{-connect}}} précise où on se connecte. On se connecte au serveur {{{irc.crans.org}}} sur le port {{{6697}}}, qui est le port par défaut du procotole IRC en SSL. * {{{< /dev/null}}} sert à envoyer "rien" à la commande, parce que sinon {{{openssl}}} attend qu'on parle avec le serveur irc, alors que tout ce qui nous intéresse nous, c'est le certificat Attention les yeux, ça raconte plein de choses. Je ne recopie<> ici que la partie qui nous intéresse, qui est au début (s'ensuivent un certain nombre d'explications) : {{{ --- Certificate chain 0 s:/CN=irc.crans.org i:/O=CAcert Inc./OU=http://www.CAcert.org/CN=CAcert Class 3 Root -----BEGIN CERTIFICATE----- MIIF5zCCA8+gAwIBAgIDAggAMA0GCSqGSIb3DQEBBQUAMFQxFDASBgNVBAoTC0NB […] SJIvOl1BQTp+VmIE30a/+1mVOFxXUVpbosM7QrdCFTcswl10cGaCDx2z9VfHDWCb alurbr6Awj5T7Rz/LhYYTc+8oZRbuQ239qf5 -----END CERTIFICATE----- 1 s:/O=CAcert Inc./OU=http://www.CAcert.org/CN=CAcert Class 3 Root i:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org -----BEGIN CERTIFICATE----- MIIHWTCCBUGgAwIBAgIDCkGKMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jv […] d+pLncdBu8fA46A/5H2kjXPmEkvfoXNzczqA6NXLji/L6hOn1kGLrPo8idck9U60 4GGSt/M3mMS+lqO3ig== -----END CERTIFICATE----- 2 s:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org i:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org -----BEGIN CERTIFICATE----- MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 […] zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD -----END CERTIFICATE----- --- Server certificate subject=/CN=irc.crans.org issuer=/O=CAcert Inc./OU=http://www.CAcert.org/CN=CAcert Class 3 Root --- }}} Il y a 3 certificats (0, 1, 2), dont on nous donne un bout du contenu, la partie la plus importante : * {{{i:}}} pour '''issuer''', c'est-à-dire, qui émet ce certificat. * {{{s:}}} pour '''subject''', c'est-à-dire, qui est attesté par ce certificat. . Donc I se porte garant de S. * Pour dire qui ils sont, ils utlisent des champs du certificat, tels que CN (Common Name), O (Organization), OU (Organization Unit) Qu'est-ce qu'il faut comprendre dans tout ça ? * Déjà, on voit que le subject 2 est l'issuer 1, et le subject 1 l'issuer 2. Donc les maillons de cette chaîne s'accrochent bien les uns aux autres. * On voit aussi que l'issuer 2 et le subject 2 sont identiques, c'est le certificat racine. Ici il s'agit du certificat racine de [[CransTechnique/CaCert|CaCert]]. * Enfin, l'élément qui nous intéresse le plus là-dedans, c'est le CN du subject du certificat 0 : {{{irc.crans.org}}}. Si on fait confiance au certificat 2 Faites attention, jusqu'ici, on n'a rien vérifié, on a juste regardé. Tout ça peut très bien être un tissu de mensonges. Vérifier que 2 signe correctement 1 et 1 signe correctement 0, c'est votre client qui le fera à la connexion, pour peu que vous lui ayez donné le certificat 2 en lui disant de lui faire confiance. == Dans WeeChat == === Cas idéal === On va d'abord s'intéresser au cas du réseau Cr@ns, parce qu'il est facile. ==== Dans le shell ==== Pour récupérer le certificat, vous pouvez exécuter la commande de la section précédente et récupérer le certifiat racine (le 3 ème bloc) depuis {{{-----BEGIN CERTIFICATE-----}}} jusqu'à {{{-----END CERTIFICATE-----}}} inclus. Vous le copiez dans un fichier {{{cacert.crt}}}. Pour vérifier que celui-ci est de confiance, vous pouvez demander à une nounou de vous le signer, ou faire un acte de foi, qu'on appelle le TOFU<>. Vous allez avoir besoin de faire ça pour chaque certificat racine des serveurs IRC auxquels vous voulez vous connecter. Vous pouvez donc les mettre chacun dans {{{.crt}}} et faire ensuite : {{{ cat *.crt > allca.pem }}} ==== Dans WeeChat ==== Il faut tout d'abord spécifier à !WeeChat le fichier contenant les certificats auxquels vous faites confiance : {{{ /set weechat.network.gnutls_ca_file ~/.weechat/ssl/allca.pem }}} ''(ce chemin n'est qu'un exemple, c'est celui que j'utilise moi)'' Ensuite, créer le serveur auxquel vous désirez vous connecter : {{{ /server add crans irc.crans.org/6697 -ssl }}} Enfin, dire à !WeeChat que vous voulez vérifier le certificat de ce serveur : {{{ /set irc.server.crans.ssl_verify on }}} ''(Si vous ne faites pas ça, la valeur de {{{irc.server_default.ssl_verify}}} est utilisée)'' Tester : {{{ /connect crans }}} Si ça marche, vous devez voir quelque part : {{{ crans -- | gnutls : le certificat de l'hôte est de confiance }}} === Cas un peu moins simple === On va prendre l'exemple de {{{irc.hackint.org}}} [[http://hackint.org/#Server|Leur site]] nous apprend que le port SSL conseillé est {{{9999}}}, donc allons-y : {{{ openssl s_client -showcerts -connect irc.hackint.org:9999 < /dev/null --- Certificate chain 0 s:/C=US/ST=Florida/L=Tampa/O=Hack.INT IRC Network/CN=morgan.hackint.org i:/C=DE/O=Hack.INT IRC network/CN=hackint.org IRC network CA/emailAddress=hc@hackint.org -----BEGIN CERTIFICATE----- MIIFMzCCBBugAwIBAgIDAOAMMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNVBAYTAkRF […] qy+RMd7NzjjI7qNjHMEYF3rcQaMyuSAKaRQAgI3NpBJjSu5nt6tLWSK9OQk79iOL qxXp3vILWfAl9xou8m0sijGx1EEUV/+EyJJEFSTZhwAXtHudxO+a -----END CERTIFICATE----- --- Server certificate subject=/C=US/ST=Florida/L=Tampa/O=Hack.INT IRC Network/CN=morgan.hackint.org issuer=/C=DE/O=Hack.INT IRC network/CN=hackint.org IRC network CA/emailAddress=hc@hackint.org --- […] }}} Déjà, on note que {{{irc.hackint.org}}} résoud sur plusieurs IP, chacune donnant un certificat différent. Un seul certificat, pas de racine. En fait, la racine est fournie sur le site : http://hackint.org/hackint-cacert.pem On ajoute donc ce certificat dans notre {{{allca.pem}}}, et comme il signe chacun des certificats différents des différentes IP de {{{irc.hackint.org}}}, tout roule. === Cas plus perturbant === {{{irc.freenode.net}}} port {{{6697}}}. Aussi plusieurs IP, la chaîne ne remonte pas jusqu'à la racine, mais à un certificat de Gandi. J'ai jouté ce certificat dans mon {{{allca.pem}}}. === Cas chiant === Sur {{{irc.t411.me}}}, port {{{6697}}}, on trouve un certificat qui n'a pas de champ CN, donc !WeeChat ne peut rien vérifier. Heureusement, !WeeChat propose un autre moyen de vérifier un certificat : enregistrer son fingerprint. On récupère le certificat : {{{ openssl s_client -showcerts -connect irc.t411.me:6697 < /dev/null > t411.bof }}} On affiche son fingerprint : {{{ openssl x509 -fingerprint -in t411.bof | head -n 1 | sed s/://g }}} ''(L'appel à {{{head}}} puis à {{{sed}}} permet juste d'afficher le fingerprint sous la forme sous laquelle !WeeChat le veut.)'' Reste à le donner à manger à !WeeChat : {{{ /server add t411 irc.t411.me/6697 -ssl /set irc.server.t411.ssl_fingerprint B6FE630CADE147BAECF07231DBB99E621104D118 /set irc.server.t411.ssl_verify on }}} !WeeChat vérifiera à chaque connexion que le certificat a ce fingerprint, et que donc c'est le certificat auquel vous faites confiance. Le lecteur attentif aura remarqué à ce stade, qu'il s'agit ici aussi d'un cas de TOFU. ----