Самые полезные комментарии от @forcefsck. К сожалению, он не заполнил ответ, поэтому я не смог присудить вознаграждение. Вкратце, ответ: PEM + RSA1 + новый формат openSSH, который описан в вопросе, и основная проблема была с PEM.
OpenSSH использует парсер из openSSL (PEM_read_bio_PrivateKey()
), который имеет единственное возвращаемое значение для всех неудач (NULL
) и если он не работает, openSSH ожидает, что это произошло из-за неправильной парольной фразы.
Я только что попробовал собрать OpenSSH без поддержки OpenSSL (--without-openssl
опция configure) и поведение "правильное":
# ./ssh-add <(echo "")
Error loading key "/dev/fd/63": invalid format
Другое дело - как это исправить. Тычок исходит от функции ERR_get_error()
и их друзей, которые должны позволить нам различать разные ошибки.
# ./ssh-add /tmp/rsa
140480353842840:error:0906A068:lib(9):func(106):reason(104):pem_lib.c:457:
Enter passphrase for /tmp/rsa:
140480353842840:error:06065064:lib(6):func(101):reason(100):evp_enc.c:592:
140480353842840:error:0906A065:lib(9):func(106):reason(101):pem_lib.c:482:
Причины: PEM_R_BAD_PASSWORD_READ
, PEM_R_BAD_BASE64_DECODE
, PEM_R_BAD_DECRYPT
.
# ./ssh-add <(echo "")
139656018548376:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:701:Expecting: ANY PRIVATE KEY
или вот это:
140654301202072:error:0906D066:lib(9):func(109):reason(102):pem_lib.c:809:
Причина: PEM_R_NO_START_LINE
, PEM_R_BAD_END_LINE
, но могут быть и другие варианты.
Добавление некоторых дополнительных проверок для ошибок OpenSSL должно дать нам возможность выбирать, какую ошибку мы хотим пометить как ошибку "формата", а какую как "плохую парольную фразу". Это находится в функции sshkey_parse_private_pem_fileblob()
в sshkey.c
на строке около 3800.
unsigned long e = ERR_get_error();
if (ERR_GET_REASON(e) == PEM_R_NO_START_LINE ||
ERR_GET_REASON(e) == PEM_R_BAD_END_LINE) {
r = SSH_ERR_INVALID_FORMAT;
} else {
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
}