← Articles

openssl-win-root : utiliser le magasin de certificats Windows avec Ruby

Si vous utilisez Ruby sous Windows, vous verrez tôt ou tard une requête HTTPS échouer avec une erreur de vérification de certificat, alors que le même site s’ouvre sans problème dans votre navigateur. openssl-win-root est un petit gem qui aide précisément dans ce cas.

Rendons d’abord à César ce qui est à César : le gem a été écrit par Stas Ukolov, et le dépôt d’origine est github.com/ukoloff/openssl-win-root. Sa première version date de 2015. Ma contribution est modeste, je la décris plus bas.

Le problème

L’OpenSSL de Ruby ne consulte pas le magasin de certificats Windows. Il a besoin de ses propres certificats d’autorités de certification. RubyInstaller fournit un fichier cacert.pem, mais comme le souligne le README du gem, ce fichier n’est pas mis à jour automatiquement. Il s’agit du bundle datant de la compilation de votre version de Ruby ; des certificats racine plus récents peuvent donc manquer.

Windows, en revanche, tient son propre magasin de certificats racine de confiance à jour. Ce magasin contient aussi les certificats que votre entreprise installe, par exemple via une stratégie de groupe. Ruby ne les voit tout simplement pas.

Ce que fait le gem

Lorsque vous le chargez sous Windows, openssl-win-root :

  1. lit les certificats racine de confiance dans le magasin système de Windows (via l’API crypt32, à l’aide de Fiddle),
  2. les écrit sous forme de fichiers PEM dans un dossier pem à l’intérieur du répertoire du gem, nommés comme OpenSSL l’attend pour un répertoire de certificats,
  3. ajoute ce dossier au magasin de certificats par défaut d’OpenSSL et y fait pointer la variable d’environnement SSL_CERT_DIR.

Aucun accès réseau n’est nécessaire. Sur les autres systèmes d’exploitation, le gem ne fait rien ; vous pouvez donc l’inclure sans risque dans un projet multiplateforme.

Utilisation

Ajoutez-le à votre Gemfile, uniquement pour Windows :

gem 'openssl-win-root' if Gem.win_platform?

Lancez ensuite bundle, ou installez-le directement :

gem install openssl-win-root

Chargez-le avant d’effectuer des requêtes HTTPS :

require 'openssl/win/root'
require 'net/http'

Net::HTTP.get(URI('https://www.ruby-lang.org/')).length

Si votre projet utilise Bundler.require, comme Rails, le require explicite est inutile.

Les certificats exportés peuvent aussi servir en dehors de Ruby. Faites pointer SSL_CERT_DIR, ou l’option -CApath de la commande openssl, vers le dossier renvoyé par :

OpenSSL::Win::Root.path

Points à garder à l’esprit

Mon rôle

À la sortie de Ruby 3.2, le gem a cessé de fonctionner : il appelait File.exists?, que Ruby 3.2 a supprimé. C’est le même problème que celui décrit dans mon article sur le gem file_exists. J’ai ouvert une pull request avec la correction d’un seul mot.

Je suis l’un des deux propriétaires du gem sur RubyGems, et en janvier 2023 j’ai publié la version 1.1.2 depuis mon fork. Cette version a très peu changé :

Tout le reste, l’idée et l’implémentation, est le travail de Stas.

Liens