Kushal Das

FOSS and life. Kushal Das talks here.

kushal76uaid62oup5774umh654scnu5dwzh4u2534qxhcbi4wbab3ad.onion

Using your OpenPGP key on Yubikey for ssh

Last week I wrote about how you can generate ssh keys on your Yubikeys and use them. There is another way of keeping your ssh keys secure, that is using your already existing OpenPGP key (along with authentication subkey) on a Yubikey and use it for ssh.

In this post I am not going to explain the steps on how to move your key to a Yubikey, but only the steps required to start using it for ssh access. Feel free to have a look at Tumpa if you want an easy way to upload keys to your card.

Enabling gpg-agent for ssh

First we have to add gpg-agent.conf file with correct configuration. Remember to use a different pinentry program if you are on Mac or KDE.

❯ echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf
❯ echo "pinentry-program $(which pinentry-gnome)" >> ~/.gnupg/gpg-agent.conf
❯ echo "export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)" >> ~/.bash_profile
❯ source ~/.bash_profile 
❯ gpg --export-ssh-key <KEYID> > ~/.ssh/id_rsa_yubikey.pub

At this moment your public key (for ssh usage) is at ~/.ssh/id_rsa_yubikey.pub file. You can use it in the ~/.ssh/authorized_keys file on the servers as required.

We can then restart the gpg-agent using the following command and then also verify that the card is attached and gpg-agent can find it.

❯ gpgconf --kill gpg-agent
❯ gpg --card-status

Enabling touch policy on the card

We should also enable touch policy on the card for authentication operation. This means every time you will try to ssh using the Yubikey, you will have to touch the interface (it will be flashing the light till you touch it).

❯ ykman openpgp keys set-touch aut On
Enter Admin PIN: 
Set touch policy of authentication key to on? [y/N]: y

If you still have servers where you have only the old key, ssh client will be smart enough to ask you the passphrase for those keys.

Another try at a new Python module for OpenPGP aka johnnycanencrypt

Using OpenPGP from Python is a pain. There are various documentation/notes on the Internet explaining why, including the famous one from isis agora lovecraft where they explained why they changed the module name to pretty_bad_protocol.

sequoia-pgp is a Rust project to do OpenPGP from scratch in Rust, and as library first approach. You can see the status page to see how much work is already done.

Using this and Pyo3 project I started writing an experimental Python module for OpenPGP called Johnny Can Encrypt.

I just did an release of 0.1.0. Here is some example code.

>>> import johnnycanencrypt as jce
>>> j = jce.Johnny("secret.asc")
>>> data = j.encrypt_bytes("kushal 🐍".encode("utf-8"))
>>> print(data)
-----BEGIN PGP MESSAGE-----

wcFMAwhsWpR1vDokAQ//UQGjrmmPLP0Td8pELf8XZEPh6fY9Xad6XHH6vQjGwvjG
36kK8ejRqyLbZpwVOO1FUfiZt6AyaeIEeEagoolMxmFl67mWBHsw5Z2NUPhydAwJ
EX+VdFn6CtRzQ0xG3T7rOCrsR50COO13gc4fIAn7Rxj1DyjqlFvur10FNnxRm0iJ
jnOwPnWVWKwoROzevfQd1Oef0n4nbkDUuyrS9oHSRFhFF/9I9bGtJhho0VIIcmFG
YVkhR0+QROTZ4edKotUg0R3UUfHmfwT0XcybGWMG/8Nh3W8pYuxwDdtbSMNDZzxu
o9TdpLrgoRIkhyGmuYWrURrRN1hmce5B6XOagWu7aKL7pFhP7Vd6LLoliDwY4G6x
1yKHbSo/1FEof7WBDujCksuVedUO8Gs9giitR/p/U9PBadeyiW0CKTYiTURkkNiF
g79lVfbmM54eZ9zmU+PraVNpekYXvH3o+lvXd5T39mo4Y/dv2fDCjo2aiZ/bE56Q
yn/0Hhmj2ikrsUk3NcuhO4zxt+VLctJt+lfk+R2hal+6NTaRkREdprPp4ltAt/bm
8xwBmqp+FDdxGgY+ItJkG69vsIf4WpPsvBI37fVbeYqrPsaz9NGlz2QKdfQvaH7j
R7rgxf24H2FjbbyNuHF3tJJa4Kfpnhq4nkxA/EdRP9JcVm/X568jLayTLyJGmrbS
PAHlVMLSBXQDApkY+5Veu3teRR5M2BLPr7X/gfeNnTlbZ4kF5S+E+0bjTjrz+6oo
dcsnTYxmcAm9hdPjng==
=1IYb
-----END PGP MESSAGE-----

>>> result = j.decrypt_bytes(data.encode("utf-8"), "mysecretpassword")
>>> print(result.decode("utf-8"))
kushal 🐍

The readme of the project page has build instruction, and more details about available API calls. We can create new keypair (RSA4096). We can encrypt/decrypt bytes and files. We can also sign/verify bytes/files. The code does not have much checks for error handling, this is super early stage.

You will need nettle (on Fedora) and libnettle on Debian (and related development packages) to build it successfully.

I published wheels for Debian Buster (Python3.7), and Fedora 32 (Python3.8).

Issues in providing better wheels for pip install

The wheels are linked against system provided nettle library. And every distribution has a different version. Means even if I am building a python3.7 wheel on Debian, it will not work on Fedora. I wish to find a better solution to this in the coming days.

As I said earlier in this post, this is just starting of this project. It will take time to mature for production use. And because of Sequoia, we will have better defaults of cipher/hash options.

Setting up WKD

We fetch any GPG public key from the keyservers using the GPG fingerprint (or parts of it). This step is still a problematic one for most of us. As the servers may not be responding, or the key is missing (not pushed) to the server. Also, if we only have the email address, there is no easy way to download the corresponding GPG key.

Web Key Directory to rescue

The Web Key Directory comes to the picture. We use WKD to enable others to get our GPG keys for email addresses very easily. In simple terms:

The Web Key Directory is the HTTPS directory from which keys can be fetched.

Let us first see this in action:

gpg --auto-key-locate clear,wkd --locate-key mail@kushaldas.in

The above will fetch you the key for the email address, and you can also assume the person who owns the key also has access to the https://kushaldas.in server.

There are many available email clients, which will do this for you. For example Thunderbird/Enigmail 2.0 or Kmail version 5.6 onwards.

Setting up WKD for your domain

I was going through the steps mentioned in the GNUPG wiki, while weasel pointed to me to a Makefile to keep things even more straightforward.

all: update install

update:
        rm -rfv openpgpkey
        mkdir -v openpgpkey
        echo 'A85FF376759C994A8A1168D8D8219C8C43F6C5E1 mail@kushaldas.in' | /usr/lib/gnupg/gpg-wks-client -v --install-key
        chmod -v 0711 openpgpkey/kushaldas.in
        chmod -v 0711 openpgpkey/kushaldas.in/hu
        chmod -v 0644 openpgpkey/kushaldas.in/hu/*
        touch openpgpkey/kushaldas.in/policy

        ln -s kushaldas.in/hu openpgpkey/
        ln -s kushaldas.in/policy openpgpkey/

install: update
        rsync -Pravz --delete ./openpgpkey root@kushaldas.in:/usr/local/www/kushaldas.in/.well-known/

.PHONY: all update install

The above Makefile is using gpg-wks-client executable and also pushing the changes to the right directory on the server.

Email providers like protonmail already allow users to publish similar information. I hope this small Makefile will help you to set up your domain.