git 4 windows avec un certificat SSL non-reconnu

Une histoire de magasin

J’ai de temps en temps besoin d’utiliser git en ligne de commande lorsque le GUI, en l’occurrence Visual Studio, ne suffit pas. Mais dans ce cas, la ligne de commande peut refuser de faire un pull ou un push si le dépôt git commun est accessible via HTTPS et qu’il utilise un certificat interne. C’est à dire que le certificat présenté par le serveur n’est pas auto-signé, mais signé par une autorité de certification non reconnue, comme c’est souvent le cas en entreprise (la vente de certificat n’est rien de plus qu’une grosse arnaque).

Ce problème existe aussi pour les autres outils graphiques qui sont basés sur git for windows, comme l’excellent TortoiseGit.

On est alors confronté au soucis suivant : même si Windows, Visual Studio, Internet Explorer ou Chrome reconnaissent ce certificat, ce n’est pas le cas de git en ligne de commande sous Windows. La raison est que le magasin des certificats racines n’est pas le même. Ce problème avec git n’existe pas sous un système *NIX. Cela arrive typiquement dans les cas suivants :

  • le navigateur est Firefox
  • l’application est écrite en Java
  • l’application embarque mingw ou similaire

Chacune de ces applications ou runtime utilisent leur propre magasin de certificat, ce qui explique qu’une négociation SSL qui passe sous VStudio ne passe plus avec git.

Faire marcher git en SSL avec un certificat interne

J’indique dans ce billet comment ajouter un certificat racine pour git 4 windows. La commande est extrêmement simple, mais la difficulté a résidé à savoir quel est le fichier à modifier. En effet, si l’on regarde le packaging de git, on peut voir des certificats trainer un peu partout, ce n’est pas très propre:

  • ~/usr/ssl/certs/ca-bundle.crt
  • ~/usr/ssl/certs/ca-bundle.trust.crt
  • ~/usr/ssl/cert.pem
  • ~/etc/pki/ca-trust/extracted/java/cacerts
  • ~/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
  • ~/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
  • ~/mingw64/etc/pki/ca-trust/extracted/java/cacerts
  • ~/mingw64/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
  • ~/mingw64/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
  • ~/mingw64/share/pki/ca-trust-source/ca-bundle.trust.crt
  • ~/mingw64/ssl/cert.pem
  • ~/mingw64/ssl/certs/ca-bundle.crt
  • ~/mingw64/ssl/certs/ca-bundle.trust.crt

Alors lequel est-ce ? Et bien c’est l’avant dernier.

Une fois qu’on l’a identifié, la manipulation est enfantine : il suffit d’éditer ce fichier et de lui coller tous les certificats racines supplémentaires au format PEM, comme le fait cette commande avec un shell type bash :

cat ca.crt >> /c/Program\ Files/Git/mingw64/ssl/certs/ca-bundle.crt

Cette manipulation sera à refaire après chaque mise à jour de git for windows.

Il existe un paramètre permettant d’indiquer à l’outil en ligne de commande de ne pas vérifier le certificat du serveur. Cela n’est pas du tout équivalent à ma solution en ce sens que ma solution permet bien d’authentifier le serveur, et que cette solution, si elle fonctionne pour git, ne fonctionne pas forcément pour les outils basés sur git comme TortoiseGit.

Stocker les certificats OpenVPN dans le magasin de certificats de Windows

J’ai très fortuitement découvert une fonctionnalité dans OpenVPN permettant non plus de charger le certificat utilisateur depuis un fichier non chiffré (ou dont le chiffrage présente très peu d’intérêt) mais directement depuis le magasin de certificats Windows, rendant ainsi très difficile l’extraction du certificat une fois installé.

C’est entre autre pratique dans les cas suivants :

  • environnement multi-administrateur
  • vol
  • faible contrôle sur la machine physique

Cela se fait via le paramètre cryptoapicert , et remplace logiquement les paramètres cert  et key . Il s’utilise de la manière suivante :

  • En précisant le sujet du certificat à utiliser : cryptoapicert « SUBJ:Peter Runestig »
  • En précisant l’empreinte du certificat à utiliser : cryptoapicert « THUMB:f6 49 24 41 01 b4 … »

Note : OpenVPN dans sa version 2.3 ne supporte toujours pas les certificats encore exotiques, comme ceux utilisant des courbes elliptiques. Il faudra se limiter à du classique RSA/SHA1.