Эта проблема характерна для MinGW / MSYS, который обычно используется как часть пакета Git для Windows .
Решение состоит в том, чтобы передать -subjаргумент с ведущими //(двойные косые черты вперед), а затем использовать \(обратные косые черты) для разделения пар ключ / значение. Как это:
"//O=Org\CN=Name"
Затем это будет волшебным образом передано opensslв ожидаемой форме:
"/O=Org/CN=Name"
Итак, чтобы ответить на конкретный вопрос, вы должны изменить -subjстроку в своем скрипте на следующую.
-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"
Это должно быть все, что вам нужно.
Что это за магия?
Для тех, кому интересно, что именно здесь происходит, я могу объяснить эту загадку. Причина в том, что MSYS разумно предполагает, что аргументы, содержащие косую черту, на самом деле являются путями. И когда эти аргументы передаются исполняемому файлу, который не был скомпилирован специально для MSYS (как opensslв этом случае), он преобразует пути POSIX в пути Win32 . Правила для этого преобразования довольно сложны, поскольку MSYS изо всех сил пытается охватить наиболее распространенные сценарии взаимодействия. Это также объясняет, почему использование opensslиз командной строки Windows ( cmd.exe) работает нормально, потому что никаких волшебных преобразований не производится.
Вы можете протестировать преобразование следующим образом.
$ cmd //c echo "/CN=Name"
"C:/Program Files (x86)/Git/CN=Name"
Мы не можем использовать echoисполняемый файл, поставляемый с MSYS, поскольку он был скомпилирован для MSYS, вместо этого мы будем использовать echoвстроенный в cmd. Обратите внимание: поскольку cmdпереключатели начинаются с /(общего для команд Windows), нам нужно обрабатывать это с помощью двойных слэшей. Как мы видим в выходных данных, аргумент был расширен до пути Windows, и становится ясно, почему opensslэто действительно так Subject does not start with '/'..
Посмотрим еще несколько конверсий.
$ cmd //c echo "//CN=Name"
/CN=Name
Двойная косая черта заставляет MSYS полагать, что аргумент является переключателем стиля Windows, который приводит к удалению /только (без преобразования пути). Вы могли подумать, что с этим мы могли бы просто использовать косую черту, чтобы добавить больше пар ключ / значение. Давай попробуем.
$ cmd //c echo "//O=Org/CN=Name"
//O=Org/CN=Name
Внезапно двойные косые черты в начале не удаляются. Это потому, что теперь, когда после начальных двойных косых черт ставится косая черта, MSYS считает, что мы ссылаемся на путь UNC (например, // server / path). Если бы это было передано opensslему, первое слово ключ / значение пропустило бы Subject Attribute /O has no known NID, skipped.
Вот соответствующее правило из вики MinGW, объясняющее это поведение:
- Аргумент, начинающийся с 2 или более /, считается экранированным переключателем стиля Windows и будет передан с удалением ведущего / и изменением всего \ на /.
- За исключением того, что если за ведущим блоком / следует /, аргумент считается UNC-путем, а ведущий / не удаляется.
В этом правиле мы можем увидеть метод, который мы могли бы использовать для создания нужного нам аргумента. Поскольку все, \что следует за аргументом, начинающимся с, //будет преобразовано в простой /. Давай попробуем.
$ cmd //c echo "//O=Org\CN=Name"
/O=Org/CN=Name
И, как мы видим, это действительно работает.
Надеюсь, это немного проясняет магию.
cat -vet /path/to/scriptи посмотрите, заканчиваются ли строки на «^ M $» (стиль Windows) или просто «$» (стиль unix).