Ця проблема стосується 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 (наприклад, // сервер / шлях). Якби це було передано, 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).