Эта проблема характерна для 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).