Newly created SSH Private Keys with passphrase not working anymore

Newly created SSH Private Keys with a passphrase (since week 16 2020 update) are not working anymore. They can’t be used to mirror a git repo and the showing of the public key will fail. The last point can be reproduced on secure: https://secure.phabricator.com/K63 (Show Public Key is not working)

The passphrase for this key is: LPlHKtiKfEb8pZ4jCXZL

Not affected by this behavior are old keys with passphrase or new keys without a passphrase. So maybe something happens while creating the row for the passphrase_secret table…

Reproduction Instructions
(1) Create a ssh-key with ssh-keygen. Enter a passphrase.
(2) Store the public key on some some machine or service which hosts git repos.
(3) Create a SSH Private Key in Phabcriator.
(4) Use this key to mirror a phabricator hosted git repo to the machine or service from point (2).
(5) See a “Permission denied, please try again.” when looking int he logs with ./bin/phd log.

Phabricator/Arcanist Version
phabricator 17426a60f00a
arcanist af9faba02f11

Thanks! I think this should be fixed by https://secure.phabricator.com/D21245.

This fix is not retroactive (existing broken credentials will still be broken) since we’ve lost the passphrases, but editing the credential and supplying new key material or creating a new credential should put it into the right state.

See https://secure.phabricator.com/T13454 for context. Briefly, if a key does not respond to ssh-keygen -y ... (“print the public key”), I don’t know any reliable, automated way to distinguish between “passphrase-protected key” and “invalid, non-keyfile” in the general case, short of parsing the key itself.

Prior to T13454, we used an extremely dumb heuristic. Now, we use a moderately dumb heuristic.

Code reorganization associated with the new heuristic rewrote a piece of code that’s roughly this:

data_to_store = strip_passphrase_from_private_key(private_key, passphrase);

The rewrite incorrectly caused strip_passphrase_from_private_key(...) to return the unmodified private key, because it invoked ssh-keygen -y instead of ssh-keygen -p. Both commands accept the same arguments and the “output” of -p is to rewrite the file it is passed in-place, so this “worked” and creates Credential objects that pass cursory inspection, but don’t actually work if you try to use them. I overlooked this while testing the change.

Well I only understand half of what you are explaining. But I have pulled master and tested it again. Everything works as expected. So thank you for the fast response!