handshake-org / hs-airdrop

Decentralized airdrop to open source developers
Other
1.4k stars 169 forks source link

New-format RSA Keys are unsupported #10

Closed kousu closed 5 years ago

kousu commented 5 years ago

Your README and help text explicitly say that RSA keys are supported, but it doesn't work.

Here's an example on a fresh key:

mac:hs-airdrop kousu$ ssh-keygen -f test-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in test-key.
Your public key has been saved in test-key.pub.
The key fingerprint is:
SHA256:p3xNohZyN6uzOChq9wxTAsiwbDEdEoOxhTSLP3q2d7g kousu@mac
The key's randomart image is:
+---[RSA 2048]----+
|=@+..            |
|O+B.             |
|=*               |
|...              |
|  o. .. S = .    |
| . .o  + * *     |
|. oo o  = o .    |
| +.oB oo.o       |
|o.ooE=..oo       |
+----[SHA256]-----+
mac:hs-airdrop kousu$ ./bin/hs-airdrop test-key [addr] 0.5 --bare
Passphrase: 
Error: Invalid key pair.
    at RawPrivateKey.read (/Users/kousu/src/hs-airdrop/node_modules/bcrypto/lib/ssh.js:848:13)
    at RawPrivateKey.decode (/Users/kousu/src/hs-airdrop/node_modules/bufio/lib/struct.js:91:10)
    at Function.decode (/Users/kousu/src/hs-airdrop/node_modules/bufio/lib/struct.js:143:23)
    at SSHPrivateKey.decodeSSH (/Users/kousu/src/hs-airdrop/node_modules/bcrypto/lib/ssh.js:438:34)
    at SSHPrivateKey.fromString (/Users/kousu/src/hs-airdrop/node_modules/bcrypto/lib/ssh.js:634:21)
    at Function.fromString (/Users/kousu/src/hs-airdrop/node_modules/bufio/lib/struct.js:155:23)
    at readKey (/Users/kousu/src/hs-airdrop/bin/hs-airdrop:411:33)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)

Here is that keypair so you can verify for yourselves:

< test-key >
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAFqCssG5
4D92mbdpIPcx2DAAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQDsQPGtT6Vb
VepP2TYLQ6cZKxipTsjL/bI7z793oT4zhE1gG9Nc4FqC6jsZoe9eSh3+HGLmRwiCkS6wcG
G23VCEkMatDQPWIee1kezeHr0JqHGX6+dFCU53VoavLaBTr4yzafNfPqaQGhmF4EgrNsRG
mYwp1JsB6osMMR9MFJbgUF8LPmeQ0q1qut3dJE8eZULbJnBn0O+W5VlYqumq9lNRcBHAxv
T/sDDMzNFpMn78CtFQGVGN6M+ln9ZrkoIYBgYIn9PSckd0kF2hyarYf6TehA8tC98N1gFJ
pd+OiQOi7VYMvstpoFkPCAUCEqX7DR5iN0ZNfgJSXcB6/B2vtY7DAAAD4H232V0kYeC/J8
hUaVGDxKYBz8fr4WpihAl0EwESWDsnd7kES/lXlRH/aUR1u9Xy1NQ6QpKpPPDn2TzpjA0X
y9LF7jLcH19Hs15wbpPN+2M/rrHqYRUn22/lQkoVgov6ju7a4Vsoi5fHtmx+Bv/7yBEEt6
Zv1BadyvRPLHODI7L+ofkPn0ZCerF5+4WB90gsc0ucljtKExqq3Qc1aXm0ITLGhCAvxrUl
ZIJU0B4kDa/ncUyoMiu3wN8Dvr+ppixwI4XVfbDlwDedHSyA8i1HLwLOy1WPKIZDlOA9HJ
PZrjscLYqh/6FDfEp1UFAAyOxSFCAkhDLg04TRBf8SjNRPDYS/17cvCfSZCLfw7uazpXUK
G7aKlp02uniM4WE/txxwtVYzLsqf7LHkYzo7zxULEh+l2+ltw+BGYB/M1NB8MXNsQP2iDE
zI7td2lDyLKPlxzb8gvPJGUo1g7KeUgGL5p2k8L8bIQRDSpBmlYKNVjv4LYSlhQpagBPTm
jN0Gsto41gpWMF+7RbEV//PL4okh9Z/pHFRJXFzJybvdLnGT65eenCptTP9ivCDsZFUjdl
EzgnabREQAEsQn5U7yEL97GOEGdOezrGi5LzUlrsbS0cbOaKTbKWJJEoXejaX1wyao5bzK
NR74BDa1XiczPnRvlCeleIxOzV5hjKYxVjP5cw0Ipdc54ax2nYmaK99YBkFpX9F5/ZS4jp
CFNUd0Trye+6F0caUVKvjvFHLxeT4GjrhdhpLZDpxgGDiAkFsqMgoJsi+vdUzQ5L+Vfnhv
zx4ws37SzJr+ns/ZEgc4aZ/kF9OJ+Ak/hpKV97paPcBsTgCYKcIeUe/gNcl9IJPwgYvADC
qPV6o/cBr3MtVf05j7KdfylwdKkRi1imaLvpamgloNuKewTDkfU51PxmIp8IpJP4s6UypX
M56Dqn8UxeL9sqTc+uo9ZIdcUoTnpoIlDxXPA0s7PZtTapvCimiaP64VT1ZwJCgmFYq/pC
ODkqZ93NrP+6Xd3L2mtrqxazzldtfssXLFUpA4Z3uJJ5GULXM06Dx1KkuqHbbjNob7bYmL
u9ZMxKGXkjf1fI41CPC7/40g/PvdxPRp+EAkCZvDP9bPzxZzHVu0VjZG8HiS4pFV8tyiI5
T5E1MUCgm2PkaOqhBJc3Pr8/9XbCxUE86Y4ruxoy8xAQzHSIDNVJ5oJCeQdnQfx1v4VV2r
G2jXcVVdFLP/KHp34syASKn33T1BP1Sb+2qlmcGgoNwze67uzP6mGBBFd66+RnBOjj0fGR
lnDrYVWpDpkYDpZnu5bVZZCCrGgMk/dLL8TIuoFvaldYT4hehO
-----END OPENSSH PRIVATE KEY-----
< test-key.pub >
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsQPGtT6VbVepP2TYLQ6cZKxipTsjL/bI7z793oT4zhE1gG9Nc4FqC6jsZoe9eSh3+HGLmRwiCkS6wcGG23VCEkMatDQPWIee1kezeHr0JqHGX6+dFCU53VoavLaBTr4yzafNfPqaQGhmF4EgrNsRGmYwp1JsB6osMMR9MFJbgUF8LPmeQ0q1qut3dJE8eZULbJnBn0O+W5VlYqumq9lNRcBHAxvT/sDDMzNFpMn78CtFQGVGN6M+ln9ZrkoIYBgYIn9PSckd0kF2hyarYf6TehA8tC98N1gFJpd+OiQOi7VYMvstpoFkPCAUCEqX7DR5iN0ZNfgJSXcB6/B2vtY7D kousu@mac

These lines in the ssh codebase you're using

https://github.com/bcoin-org/bcrypto/blob/934f5ea45a0bc0926b9e7916f68bfeb2ea4881e3/lib/ssh.js#L348-L350

https://github.com/bcoin-org/bcrypto/blob/934f5ea45a0bc0926b9e7916f68bfeb2ea4881e3/lib/ssh.js#L422-L424

imply that it only works with ED25519 keys. Indeed, the error seems to be that in bcrypto

https://github.com/bcoin-org/bcrypto/blob/934f5ea45a0bc0926b9e7916f68bfeb2ea4881e3/lib/ssh.js#L813-L819

i.e. it's expecting to read exactly a 32 byte private key, followed by a second copy of a 32 byte public key, which makes no sense for RSA keys.

kousu commented 5 years ago

On further inspection, I think what is going on is that my RSA key is in the new format marked by "BEGIN OPENSSH PRIVATE KEY" defined in https://github.com/openbsd/src/blob/master/usr.bin/ssh/PROTOCOL.key. As @tedu mentions, that format was initially only used for ed25519 keys by default, but can hold any kind, whereas bcrypto only supports the ed25519 format (probably having reverse engineered it from examples).

I can force the old format with ssh-keygen -m PEM and indeed, this works with hs-airdrop:

mac:hs-airdrop kousu$ ssh-keygen -m PEM -f test-key
Generating public/private rsa key pair.
test-key already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in test-key.
Your public key has been saved in test-key.pub.
The key fingerprint is:
SHA256:Fco9gxPCgOVF16QEaIxjPCpbdUWBHncREt678nTXd8Q kousu@mac
The key's randomart image is:
+---[RSA 2048]----+
| . =o===X==o     |
|  B.=.=*.Oo.     |
| o =.o oB.*      |
|o .   .  o +   . |
|.o      S .     E|
|.          .   o |
|        . o . . +|
|         + . .  o|
|          .      |
+----[SHA256]-----+
mac:hs-airdrop kousu$ ./bin/hs-airdrop test-key [addr] 0.5 --bare
Passphrase: 
Attempting to create proof.
This may take a bit...
Decrypting nonce...
Downloading: https://github.com/handshake-org/hs-tree-data/raw/master/nonces/249.bin...
Error: Could not find nonce in bucket 249.
    at findNonce (/Users/kousu/src/hs-airdrop/bin/hs-airdrop:234:9)

(for reference, here's the new key in the old format:

< test-key >
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,F1B9DEBB43D65B1EC58C5A15A1AC6755

V98A1I1LdrLHAeG4CNW1MzAHu6FOT90ApKnlQmwj/TgNt0sxWdvf2uhpEmV45JSy
PB8Y6XDkejqe3qRXmPeIw4+cLV9i/NiFo12fUcH44eDk+g2SSNWn/4Sdq5KHjrTu
bdZeHRBvqGuc2LFsbhq6f2r1DyjgPY/Wp3IfsD7GPB5Qfk/Qb2Pyu/WEOwuHfa14
BkDUcLV5QGoeQTNXy5j4+XWYY1t1De8C8bkJ2Q2cgQDRaTIdPfNs4Qj0bnpwEzel
uGpsEngzIGRUaGsSAqGHhqbrONQeZi/rJeCBOiulPztHaO7BcsTHlzG+NtHl/4af
fgushKp8onIYJ1oKK0U8B3Sfuqoo9vSvZUPjWG+r0ULRk4m0MfrH0YYjG8kiYhmJ
abEw8VpIMumMzxWKd3+qyhpgPF3BmwmuK11jwuFK+ewTkeDHgrw6RM/GYkCj0Ga4
fkkfM5KuoefU4bFLUl5+SgEnIapHglCricZNrg0fymVougYZFBFCbpDm3APgya4K
pBwRoL4M2Ealrw9bf2q+0Bk0j2nLKytTFqVPZCO/+QldU2WuWKThM87bJvQ5534r
1zYFUN3134n9UioLa8F4iDrgqiKPuVB+0BXdsBm2r8Hct1s7Y6U2h+smIBxtC3jT
edXP2CA6I6fzTNPN96ESbG3R2Z2TT+KpjozeM0gwC58CrO8A9Ki3A6cFK6Fj49J8
VVoV0AEv+tqytNTXV1tCeUyIEOH9kwg7U5FNxhjBu3NJwSo/OLCIYnmtMOPDh/Bn
ekyzoNP+LlO7bnJvFPeB9k+rv2yAvVjFesRMsjYrXa0zWMbro6J4kInYP+aQpuv0
VNcmIHIu14tmRcp7jkZt+0oUyohD1xBoxqzIZTh//Eug+W8fJkn/g7hZ0xWAhgiQ
qst0V8sNfCAzSxcEKmrYEVOBQmxBO1v2s75u1ytQPRiIUDXRe98y1E4CI626BcUj
eTgQUO+UoFAqbf7+9sxATedTaT3SLtcq/d5EOAl7JoId4Pp0whHDegDuaKIhGN7/
74yx6HANo5wof8dr32bx0ZDlKUov9nPAdwXH+4eNkLCDLdAp7lXxQZ2dv1WGoWpE
OGRe4+S15hk0t3Fkdqscjy9ihCtpHA1m9mF2b1Eedv8oB0WLJD4Ik5/hGk/4Ljcg
NSLS2akmg1HL0jPz7ZkO31luPwdeW0BULla6jvu7G46tvozk/YUrLW2jqnFeAykU
9iw/6XfhJ5+rZ2JjNHqPhduv/h2h5gHm/sGVg7oGylrN5hXFb8Ftm1s2G+pTlWjJ
Zcv1ylxaYWob8C2yCTU3420Y0OwIVGoKCZ33qe5yBmkYqXnhjyUQlxuIxSmhhNcN
HAdengo5/azVQiBQprea02Y0bmggnEGAr/8JMy3Nz/lw6PfCCFVm/rhEpFBuKRWn
S9sB1CJZ8WQk2OnDltt9btLjRiImLEwrq0tb9+xi7sUfj7eLEL76V38o4CNhVLzP
dnJCdxFzVFXFQH3BQFc+WTEA60jSBzSrOFPhkXAQYGnVvTFLL/22Mta6wvdTy4oR
+NKW9rLvxUIQGazJUD7V/VEan0k0HfJ2ZTZdj8XrdUTxLSbHJ6OyX8lnmbDaW9tb
-----END RSA PRIVATE KEY-----

)

kousu commented 5 years ago

After all that, I figure this isn't really your bug. I've reported it at https://github.com/bcoin-org/bcrypto/issues/11 instead. But since this will probably affect a lot of your users, I'm going to leave this open to share this workaround:

If you have a key file with "OPENSSH PRIVATE KEY", you can trick ssh-keygen into changing formats by using -m PEM in combination with changing the password on the keyfile, like this:

anaesthetic-mac:hs-airdrop kousu$ ssh-keygen -p -m PEM -f test-key
Enter old passphrase: 
Key has comment 'kousu@anaesthetic-mac.internal.kn0x.io'
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.

But Beware, this is a destructive, in-place operation (make a backup!). You can see it's in the old format:

$ cat test-key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,1944209D192A316AFC7B583E0D874CED

sUOSWCOmXntjprmRUsnIRfIvFrwD92Wu0UoUdSWCEqacZ51WRjvaU7IQ3Ea/lQfI
gti3AAgEpw0sWzOpHdLotgmcXXrJ9ITCLHt3Y8+sktXHRuJ7s63NCHEE1r82Pt7T
n227pKZL0Ne6Le9MS3Vql1Q3HrQnW7NAIzneaGYN48vTzHXVaPs98oZRgN7Fh5Vl
fw2F9Mh34c6/haOqwkJzyhVBdm8OJBZwi0egAm/GJRYFkBAyQhAXXGn/EgZNwCMQ
Zrjl3DKBZJcL8w06SucuOl6XBZto7WjouTz6M5XryeMUx7IeNqUJYQhQUkjmAV0t
Zxi7tDBEjJAsNYIHAEvoJvy7L7tbJ6hHYNkZM5fCwKjj5cGgodOr77+Bt9744mW2
GOpE5cBDDxECA2iee1VUWDUr1AbcoMnD/9+syd3De7MHc83o7gH4WOU0UkSsNLkI
E51IEOMYE1N2nIY3PC2+TaamPwnVuNFletQeIavVMiRCDDJsEDNakXXpUSw9g4eS
xku2PNM+mZiLdjh/lT+l9iLOiIH1z1EfXRYLpAxCkAmi/wBJc0bRU7nV0zlK2LYM
nE1fs7li4DvkNl81BKck42Ji49WrLXLn5Qe+8eJcIvuYhmF1YzkIQi3Sh5yUaRMO
IDAl/zTJd4CxudsXSlymqZRW8OcvXcG+cOZqN6g+il/M0XpLADJW/DPUxec6iQrR
fggJmletKW/X6SBlwyGi0iM9H3Cn+ViL7JT92lWScG0f0aMqkTwS7D63+3j9FUJc
5Vjt9NtyBk1s/lkxXcJHqBToVs7BQ7GWIOFdv0nNZUgHDuCSS/vzC50pejEJL0zC
1YqUR/RSEVyRMjgKNjmM2Qo4cr9TtjsI3dsn971gwPYA4mz2U7yL4FKnSFkb2cts
awAmW72qwGIQY9cUgCxFapiWnDs2/gHVTSVsF9qVegc+SzwxXq0m0Z+0doC2Mqe6
rS0vbkdB7KZzXtGy/yTkrQKd8wTi2yrSgAbmbk6LJTP0UkNUZIncmgKMuJt03QCD
OoNHi29fNPF8rUg4ftJdrOHCEq3sPnCuHrrAtmSpNlblpZ3o+oFzUHBXbLRBZCO0
eZoxLhesCNadJVhqhZsaNthADCUHObB7VR9srEICL5Wn4ZTHibT2S/dwHcV57t8e
tGzKq/QPMxIsM8D0xBgyaxLiNfZX+eC0b21KxJkW9ptpESxLYchOhlPPbQLZgSPM
pPrYsllK8z122OWBndTKqGHnS5KXPJWxLpNxKwKJlllv5p9amXo1qdgiZ7NiVlcv
EcenGRhg2ItXNHJayDJbg2pb8NND9Mz6fojib5Sax5P0cW7/IgXvCuhKVMU/uNJa
018YM6UdvmFlvA/7qEptKsJK8By6A6H/Rry4iEeQaQmvGtB2i2uj71eEKxRnbglF
UvAbYJprhlOPRq3H0JbSU7jOsSxCDpUctAHKeted9oJubMf2w/dqEtmAPy6+ARnb
IyaP0HI5heUMY8dU4qZYL+Cx4BAXVHTJN2lTlxRFK2Nn3qoGlBhOYucGSzEyzLM8
0w7zJHvfc9LXCRqtmZozHjhVsUjtrGzHBZloA61lcvsN4la3HV6ddjVK+MGgNKbf
-----END RSA PRIVATE KEY-----

and hs-airdrop will accept it:

$ ./bin/hs-airdrop test-key [addr] 0.5 --bare
Passphrase: 
Attempting to create proof.
This may take a bit...
Decrypting nonce...
Downloading: https://github.com/handshake-org/hs-tree-data/raw/master/nonces/177.bin...
Error: Could not find nonce in bucket 177.
    at findNonce (/Users/kousu/src/hs-airdrop/bin/hs-airdrop:234:9)
chjj commented 5 years ago

Hmm, I wasn't aware that openssh even used the new format for anything other than ed25519 keys yet. The reason they're not implemented in bcrypto is that I couldn't find any real examples of RSA keys encoded in the new format. And yes, it was partially reverse engineered since I could only find sparse info on the new format (aside from a small readme which didn't outline the exact structure of different keys).

I'll play with this some more and figure it out.

kousu commented 5 years ago

I'm not surprised. The rollout of openssh.org through to everyone in the world is slow. It took me an afternoon tracing code to even realize I was using a new format key.

Let me throw you some e-appreciation for doing maintenance drudgery: thank you for your work 🎩

kousu commented 5 years ago

Thank you @chjj! You are a gentleman and a scholar.