Heartbleed, OpenSSL, Heartbeat

Mon problème récent avec le kernel linux et/ou les drivers nvidia me fait penser à Heartbleed et Shellshock. Je m’étais abstenu d’en parler ici tellement que ces failles ont bien été expliqué et ont montré à quel point la négligence de qualité existe, en particulier pour OpenSSL.

OpenSSL, un logiciel que j’ai déjà abordé dans un de mes articles, dont le titre est « Quand on code avec les pieds ». J’en avais conclu que les gens en avait marre de patcher OpenSSL et cherchent une alternative, et ce, bien avant Heartbleed.

Avec Heartbleed, même ceux qui n’ont jamais regardé le code d’OpenSSL ont reçu un message clair: OpenSSL est réellement codé avec les pieds. Créer une alternative n’est pas facile, des entreprises se sont mises à faire des dons pour améliorer le tas de merde, mais ça restera un tas de merde, toujours difficilement compréhensible mais avec moins de failles surement.

Concernant Heartbleed, les explications écrites par des journalistes qui ne comprennaient rien étaient souvent vagues ou erronées. Il existe même un hall of fame des pires erreurs journalistiques à ce sujet qui démontre très bien qu’un journaliste de nos jours ne mérite aucune crédibilité aveugle (finalement comme tout sur Internet, mais aussi à la télévision).

Du coup, pour comprendre j’ai consulté la RFC (ou ce lien, je ne sais plus), le but est de faire un keep-alive de la connexion TCP pour éviter une nouvelle connexion et donc une renégociation longue et couteuse en CPU de la connexion sécurisée. Bref, un PING/PONG basique, à titre d’exemple, c’est ce qu’IRC fait déjà depuis des années, SSL ou non puisque le ping/pong est au niveau applicatif. Avec Heartbeat, l’application n’a pas à se soucier du ping/pong puisque c’est réalisé par la couche SSL.

Comme sur l’IRC, quand un client fait un PING, le client transmet une chaîne arbitraire dans la requête et le serveur répond avec cette même chaîne arbritaire. Le contenu de cette chaine arbitraire n’a de sens que pour le client, il peut s’en servir pour suivre l’évolution des réponses du serveur, mais pas obligatoirement. Par exemple sur l’IRC, un usage bien connu est de calculer la latence avec le serveur en utilisant l’heure comme chaîne arbitraire (et on mesure ainsi le temps que le message a mis pour être envoyé et reçu).

C’est exactement la même chose avec Heartbeat (à quelques détails prêt) le client envoie des données arbitraire, et le serveur répond avec ces mêmes données. Rien de sorcier, c’est expliqué très simplement ici, sauf que contrairement à l’IRC qui est exclusivement du texte, en SSL c’est du binaire, et là, « c’est le drame« .

Une erreur de débutant de base, dont le principe bien connu dans le web est: ne jamais faire confiance aux données que le client transmet. Si le client dit qu’il a envoyé une chaîne aléatoire de 64KB, il vaut mieux en être sûr avant de lire ces 64KB qui n’existent peut-être pas.

On disait que l’open source est plus sûr car il y a des gens qui relisent le code et tout et tout, foutaise! Relire du code de merde ça ne fait plaisir à personne, déjà quand on est payé à faire ça c’est chiant, alors faire ça bénévolement et bien, je vous laisse imaginer.

A part suivre l’évolution du code et relire chaque commit, c’est impossible de partir dans un code source à la recherche de bug. C’est impossible pour un bénévole qui n’a aucun autre intérêt que de se faire chier à faire un rapport de bug qui peut être refusé et ensuite se faire traiter comme une merde (au moins Google paie bien pour trouver des bugs dans Chrome). Par contre, quelqu’un qui aurait un intérêt à exploiter un logiciel, lui il va passer du temps à la recherche de faille et on peut compter sur lui pour ne pas les signaler.

D’ailleurs, voici le commit qui a introduit le bug. Très pénible à lire, ce qui me choque le plus c’est la grosse duplication de code entre les fonctions dtls1_process_heartbeat(SSL *s) et tls1_process_heartbeat(SSL *s) qui ont exactement la même signature et font la même chose. Comment une telle chose peut être acceptée ? Ne serait-ce qu’en terme de maintenance derrière. Qu’il existe deux fonctions avec deux noms différents car c’est deux protocoles différents, OK, mais derrière le même code peut être utilisé.

Mais pour avoir déjà travaillé avec OpenSSL pour KvIRC, et pour avoir déjà lu des avis dessus, il est clair que ce projet doit mourrir. C’est juste rédhibitoire, rien que le style de codage est un non sens mais ça c’est une question de goût.

En dehors de la technique, il y a des râleurs qui pensent encore que l’open source c’est être redevable quand on en profite à fond pour en faire du fric. En effet, OpenSSL ne récolte pas beaucoup d’argent, mais c’est leur choix de ne rien demander en retour (l’open source n’est pas tout le temps gratuit). Je comprends les personnes qui se trompent sur l’open source (et gratuit), car quand on construit un outil gratuitement et qu’une autre personne utilise cet outil pour faire des millions, la conscience pousse à être reconnaissant envers l’outil. Mais ils sont dans l’erreur, d’autant plus que ce n’est pas forcément un choix puisqu’un commercial ou qu’un PDG n’a pas connaissance de l’utilisation d’outils open sources gratuits.

Personnellement, je ne donnerai jamais d’argent à des personnes qui codent avec les pieds et feront gaspiller tout l’argent en maintenance.

Pour revenir sur linux de manière générale, quand il n’y a pas d’entreprise derrière un projet, quand des bénévoles sont impliqués, en particulier quand ils sont étudiants et donc débutant, il est particulièrement important de comprendre que la négligence est vite arrivée, avec une qualité médiocre. On l’a vu dans ce blog avec Katepart, on le voit avec OpenSSL, et on le verra encore et encore. La question qui se pose est de savoir si …. c’est le prix à payer de la liberté ?