Thursday, October 11, 2018

Porting Keybase to NetBSD

Keybase significantly simplifies the whole keypair/PGP thing and makes what is usually a confusing, difficult experience actually rather pleasant. At its heart is an open-source command line utility that does all of the heavy cryptographic lifting. But it's also hooked up to the network of all other Keybase users, so you don't have to work very hard to maintain big keychains. Pretty cool!

So, this evening, I tried to get it to all work on NetBSD.

The Keybase client code base is, in my opinion, not very well architected... there exist many different Keybase clients (command line apps, desktop apps, mobile apps) and for some reason the code for all of them are seemingly in this single repository, without even using Git submodules. Not sure what that's about.

Anyway, "go build"-ing the command line program (it's written in Go) failed immediately because there's some platform-specific code that just does not seem to recognize that NetBSD exists (but they do for FreeBSD and OpenBSD). Looks like the Keybase developers maintain a Golang wrapper around struct proc, which of course is different from OS to OS. So I literally just copypasted the OpenBSD wrapper, renamed it to "NetBSD", and the build basically succeeded from there! This is of course super janky and untrustworthy, but it seems to Mostly Just Work...

I forked the GitHub repo, you can see the diff on top of keybase 2.7.3 here: bccaaf3096a

Eventually I ended up with a ~/go/bin/keybase which launches just fine. Meaning, I can main() okay. But the moment you try to do anything interesting, it looks super scary:

charlotte@sakuracity:~/go/bin ./keybase login
▶ WARNING Running in devel mode
▶ INFO Forking background server with pid=12932
▶ ERROR unexpected error in Login: API network error: doRetry failed,
attempts: 1, timeout 5s, last err: Get
http://localhost:3000/_/api/1.0/merkle/path.json?last=3784314&load_deleted=1&load_reset_chain=1&poll=10&sig_hints_low=3&uid=38ae1dfa49cd6831ea2fdade5c5d0519:
dial tcp [::1]:3000: connect: connection refused

There's a few things about this error message that stuck out to me:

  • Forking a background server? What?
  • It's trying to connect to localhost? That must be the server that doesn't work ...

Unfortunately, this nonfunctional "background server" sticks around even when a command as simple as 'login' command just failed:

charlotte@sakuracity:~/go/bin ps 12932
  PID TTY STAT    TIME COMMAND
  12932 ?   Ssl  0:00.21 ./keybase --debug --log-file
  /home/charlotte/.cache/keybase.devel/keybase.service.log service --chdir
  /home/charlotte/.config/keybase.devel --auto-forked 

I'm not exactly sure what the intended purpose of the "background server" even is, but fortunately we can kill it and even tell the keybase command to not even spawn one:

charlotte@sakuracity:~/go/bin ./keybase help advanced | grep -- --standalone
   --standalone                         Use the client without any daemon support.

And then we can fix wanting to connect to localhost by specifying an expected Keybase API server -- how about the one hosted at https://keybase.io?

charlotte@sakuracity:~/go/bin ./keybase help advanced | grep -- --server
   --server, -s                         Specify server API.

Basically, what I'm trying to say is that if you specify both of these options, the keybase command does what I expect on NetBSD:

charlotte@sakuracity:~/go/bin ./keybase --standalone -s https://keybase.io login
▶ WARNING Running in devel mode
Please enter the Keybase passphrase for dressupgeekout (6+ characters): 

charlotte@sakuracity:~/go/bin ./keybase --standalone -s https://keybase.io id dressupgeekout
▶ WARNING Running in devel mode
▶ INFO Identifying dressupgeekout
✔ public key fingerprint: 7873 DA50 A786 9A3F 1662 3A17 20BD 8739 E82C 7F2F
✔ "dressupgeekout" on github:
https://gist.github.com/0471c7918d254425835bf5e1b4bcda00 [cached 2018-10-11
20:55:21 PDT]
✔ "dressupgeekout" on reddit:
https://www.reddit.com/r/KeybaseProofs/comments/9ng5qm/my_keybase_proof_redditdressupgeekout/
[cached 2018-10-11 20:55:21 PDT]

Hey, that's pretty cool!

I verified that signing data works:

charlotte@sakuracity:~/go/bin echo "SOYLENT GREEN IS PEOPLE" > /tmp/secret.txt

charlotte@sakuracity:~/go/bin ./keybase --standalone -s https://keybase.io sign -i /tmp/secret.txt -o /tmp/secret.signed.txt 
▶ WARNING Running in devel mode
charlotte@sakuracity:~/go/bin cat /tmp/secret.signed.txt 
BEGIN KEYBASE SALTPACK SIGNED MESSAGE. kXR7VktZdyH7rvq v5weRa0zkV2Q3rQ yJlaULSlqaeTnR5 enipWZdks4GrGGp MDHBBLInD3IXYih w4EXhfbZNlo99Pk n3P8ntUP9rt4DWl bWnVnS5T52YVtNB QiKoN7LMVa60GG8 ZvOGShKaIKZNG1n kWMcxKWUTPOLK0N JPAPxafF9Y25RBO ZAzpsfkd26FRFUO OW54leXr5YA3MK8 VTMvU4b4. END KEYBASE SALTPACK SIGNED MESSAGE.

And verifying that signature works:

charlotte@sakuracity:~/go/bin ./keybase --standalone -s https://keybase.io verify -i /tmp/secret.signed.txt 
▶ WARNING Running in devel mode
Signed by dressupgeekout (you).
SOYLENT GREEN IS PEOPLE

But unfortunately, encrypting data (and I guess decrypting it, too) is not functional at this time:

charlotte@sakuracity:~/go/bin ./keybase --standalone -s https://keybase.io encrypt -i ~/pictures/random/unicorn.jpg -o /tmp/unicorn.jpg.encrypted dressupgeekout
▶ WARNING Running in devel mode
▶ ERROR Can't run command in standalone mode

But you can't turn off standalone mode because then we're back to where we started:

charlotte@sakuracity:~/go/bin ./keybase -s https://keybase.io encrypt -i ~/pictures/random/unicorn.jpg -o /tmp/unicorn.jpg.encrypted dressupgeekout
▶ WARNING Running in devel mode
▶ INFO Forking background server with pid=4222
▶ ERROR Keybase services aren't running - KBFS client not found.

It is kinda cool that some of the interesting functionality of Keybase does work on NetBSD though!

No comments:

Post a Comment