it-swarm.com.de

Opensl von einem Bash-Skript unter Windows ausführen - Betreff beginnt nicht mit '/'

In meinem Skript habe ich:

openssl req \
  -x509 \
  -new \
  -nodes \
  -key certs/ca/my-root-ca.key.pem \
  -days 3652 \
  -out certs/ca/my-root-ca.crt.pem \
  -subj "/C=GB/ST=someplace/L=Provo/O=Achme/CN=${FQDN}"

Wenn Sie dies unter Windows in Git Bash 3.1 ausführen, erhalten Sie Folgendes:

Subject does not start with '/'.

Versuchte dem Subj wie folgt zu entkommen: -subj "/ C = UK/ST = irgendwo/L = Provo/O = Achme/CN = $ {FQDN} \"

Funktioniert immer noch nicht Irgendwelche Ideen?

62
iss42

Dieses Problem ist spezifisch für MinGW/MSYS, das häufig als Teil des Pakets Git für Windows verwendet wird.

Die Lösung besteht darin, das -subj-Argument mit den führenden // (doppelte Vorwärtsschrägstriche) zu übergeben und dann mit \ (umgekehrte Schrägstriche) die Schlüssel/Wert-Paare zu trennen. So was:

"//O=Org\CN=Name"

Diese wird dann in der erwarteten Form magisch an openssl übergeben:

"/O=Org/CN=Name"

Um die spezifische Frage zu beantworten, sollten Sie die Zeile -subj in Ihrem Skript folgendermaßen ändern.

-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"

Das sollte alles sein, was Sie brauchen.

Was ist das für eine Magie?

Für diejenigen, die genau wissen wollen, was hier los ist, kann ich dieses Rätsel erklären. Der Grund ist, dass MSYS vernünftigerweise davon ausgeht, dass Argumente, die Schrägstriche enthalten, tatsächlich Pfade sind. Wenn diese Argumente an eine ausführbare Datei übergeben werden, die nicht speziell für MSYS kompiliert wurde (in diesem Fall openssl), wird POSIX-Pfade in Win32-Pfade konvertieren . Die Regeln für diese Konvertierung sind ziemlich komplex, da MSYS sich bemüht, die gängigsten Szenarien für Interoperabilität abzudecken. Dies erklärt auch, warum die Verwendung von openssl in einem Windows-Befehl funktioniert. Die Eingabeaufforderung (cmd.exe) funktioniert einwandfrei, da keine magischen Konvertierungen vorgenommen werden.

Sie können die Konvertierung so testen.

$ cmd //c echo "/CN=Name"
"C:/Program Files (x86)/Git/CN=Name"

Die mit MSYS gelieferte ausführbare Datei echo kann nicht verwendet werden, da sie für MSYS kompiliert wurde. Stattdessen verwenden wir die echo builtin in cmd. Da cmd-Schalter mit / (für Windows-Befehle üblich) beginnen, müssen wir das mit doppelten Schrägstrichen behandeln. Wie wir in der Ausgabe sehen können, wurde das Argument zu einem Windows-Pfad erweitert und es wird klar, warum openssl tatsächlich Subject does not start with '/'. behauptet.

Sehen wir uns noch einige Conversions an.

$ cmd //c echo "//CN=Name"
/CN=Name

Durch doppelte Schrägstriche glaubt MSYS, dass das Argument ein Windows-Stilschalter ist, der dazu führt, dass nur / entfernt wird (keine Pfadumwandlung). Man könnte meinen, dass wir damit einfach Schrägstriche verwenden könnten, um weitere Schlüssel/Wert-Paare hinzuzufügen. Lass es uns versuchen.

$ cmd //c echo "//O=Org/CN=Name"
//O=Org/CN=Name

Plötzlich werden die doppelten Schrägstriche im Start nicht reduziert. Dies liegt daran, dass MSYS nun mit einem Schrägstrich nach den ersten doppelten Schrägstrichen denkt, wir verweisen auf einen UNC-Pfad (z. B. // Server/Pfad). Wenn dies an openssl übergeben wurde, wird der erste Schlüssel/Wert übersprungen, der Subject Attribute /O has no known NID, skipped sagt.

Hier ist die relevante Regel aus dem MinGW-Wiki , die dieses Verhalten erläutert:

  • Ein Argument, das mit 2 oder mehr beginnt/gilt, wird als Windows-Stilschalter mit Escapezeichen betrachtet und mit dem führenden/remove übergeben und alle\in /..__ geändert.
    • Wenn jedoch ein/nach dem führenden Block von/folgt, wird das Argument als UNC-Pfad betrachtet und das führende/wird nicht entfernt.

In dieser Regel sehen wir die Methode, mit der wir das gewünschte Argument erstellen können. Da alle \, die in einem Argument mit // beginnen, in einfachen / konvertiert werden. Lass uns das ausprobieren.

$ cmd //c echo "//O=Org\CN=Name"
/O=Org/CN=Name

Und wie wir sehen, funktioniert es.

Hoffe, das entzaubert die Magie ein bisschen.

144
Korroz

Ich persönlich fand das spezifisch für die verwendete OpenSSL-Binärdatei. Auf meinem System, das msys2/mingw64 verwendet, ist mir aufgefallen, dass zwei verschiedene OpenSSL-Binärdateien vorhanden sind, zum Beispiel:

$ whereis openssl; echo; which openssl
openssl: /usr/bin/openssl.exe /usr/lib/openssl /mingw64/bin/openssl.exe /usr/share/man/man1/openssl.1ssl.gz

/mingw64/bin/openssl

Ich glaube, es ist die Verwendung von /mingw64/bin/openssl, die die Verwendung eines Betreffs erfordert, der mit // beginnt. Ich bin mir jedoch nicht sicher, ob dies spezifisch für das Paket/Build oder die Version von OpenSSL ist unten:

$ while read -r _openSslBin; do printf "${_openSslBin}: "; ${_openSslBin} version; done < <(whereis openssl | egrep -o '[^ ]+?\.exe ')
/usr/bin/openssl.exe: OpenSSL 1.0.2p  14 Aug 2018
/mingw64/bin/openssl.exe: OpenSSL 1.1.1  11 Sep 2018

Ich habe das folgende Beispiel für bash-Code gefunden, um die korrekte Binärdatei basierend auf der OpenSSL-Version auszuwählen, wenn Sie msys/mingw verwenden, um auf meinem Computer zu arbeiten:

# determine openssl binary to use based on OS
# -------------------------------------------
_os="$(uname -s | awk 'BEGIN{FS="_"} {print $1}' | egrep -o '[A-Za-z]+')"
if [ "${_os,,}" = "mingw" ] || [ "${_os,,}" == "msys" ]; then
  while read -r _currentOpenSslBin; do
    if [[ "$(${_currentOpenSslBin}  version | awk '{print $2}')" =~ ^(1\.0\.[0-9].*|0\.\9\.8.*)$ ]]; then
      _openSslBin="${_currentOpenSslBin}"
    fi
  done < <(whereis openssl | egrep -o '\/[^ ]+?\.exe ' | egrep -v 'mingw')
  if [ -n "${_openSslBin}" ]; then
    printf "OpenSSL Binary: ${_openSslBin} (v. $(${_openSslBin}  version | awk '{print $2}'))\n"
  else
    printf "Unable to find compatible version of OpenSSL for use with '${_os}' OS, now exiting...\n"
    exit 1
  fi
else
  _openSslBin="openssl"
fi

# display selected openssl binary and it's version
# ------------------------------------------------
printf "${_openSslBin}: "; ${_openSslBin} version

Neben der Behebung von Problemen mit der Übergabe der Betreffzeichenfolge fand ich auch das Problem, um Probleme mit der Größe des DN zu beheben (ich habe eine benutzerdefinierte openssl.cnf mit einer Richtlinie übergeben, die für keines der Felder ein max_size festgelegt hat und immer noch Probleme hatte bei Verwendung von /mingw64/bin/openssl.exe).

0
Rob Frey