Adding GPG Stored Keys

@bettyvschmartz

I was able to reproduce issues on Linux and have released onlykey-agent v1.1.11 to address issues. It appears with Linux there are 2 distinct issues:

Issue #1) Init of derivation keys work first time but not second time even if the directory is deleted

The first time you use the agent like this it works:

$ rm -rf /home/osboxes/.gnupg/onlykey && onlykey-gpg init ‘bob smith bob@protonmail.com

If you try to create the same identify a second time (run exact same command) it works, however if you try to create a different identity like this:

$ rm -rf /home/osboxes/.gnupg/onlykey && onlykey-gpg init ‘alice smith alice@protonmail.com

It fails, its as if GPG is remembering the identity directory even though its removed. If you use a different directory like this it works:

rm -rf /home/osboxes/.gnupg/onlykey && onlykey-gpg init ‘alice smith alice@protonmail.com’ --homedir /home/osboxes/.gnupg/onlykey/testalice

This seems to be because rm in Linux does not really delete the file if its held open by a process, running this command shows the deleted file:

$ `sudo lsof -F sn0 | tr -d '\000' | grep deleted | sed 's/^[a-z]*\([0-9]*\)n/\1 /' | sort -n`

After a reboot the file will be actually deleted and the agent can create a different identify in the same location. Still looking into other options here and why this behavior happens.

Issue #2) When using stored keys with imported public keys (-i option) on Mac and some Linux versions this works but I found in some cases it was unable to resolve path to run-agent.sh, and so failed. This is now fixed in version 1.1.11 of onlykey-agent. The fix was to create the environment variable AGENTHOMEDIR that contains whatever --homedir is passed to the onlykey-gpg command.

There are also improvements for better GPG support in in the new v2.1.1 firmware if you have a chance to test that out. Here are some one liners to test with the test key provided above:

Stored Key Test

$ rm -rf /home/osboxes/.gnupg/onlykey && onlykey-gpg init “Bob Smith <bob@protonmail.com>” -sk 102 -dk 101 -i /home/osboxes/testpub.asc --homedir /home/osboxes/.gnupg/onlykey/2 && echo “secret message” | gpg2 --encrypt -r “Bob Smith <bob@protonmail.com>” --homedir /home/osboxes/.gnupg/onlykey/2 | gpg2 --decrypt --homedir /home/osboxes/.gnupg/onlykey/2 && echo “Hello World” | gpg2 --sign --homedir /home/osboxes/.gnupg/onlykey/2 | gpg2 --verify --homedir /home/osboxes/.gnupg/onlykey/2

2021-06-03 15:59:02,533 WARNING This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [init.py:128]

2021-06-03 15:59:02,551 WARNING NOTE: in order to re-generate the exact same GPG key later, run this command with “–time=0” commandline flag (to set the timestamp of the GPG key manually). [init.py:39]

gpg: inserting ownertrust of 6

gpg: checking the trustdb

gpg: marginals needed: 3 completes needed: 1 trust model: pgp

gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u

sec ed25519 2021-03-23 [SC]

04C64623EA51A3B79658DBF7FFADEA1DA23333FD

uid [ultimate] Bob Smith <bob@protonmail.com>

ssb cv25519 2021-03-23 [E]

gpg: encrypted with 256-bit ECDH key, ID 4B433249E7DE1630, created 2021-03-23

“Bob Smith <bob@protonmail.com>”

secret message

gpg: using “Bob Smith <bob@protonmail.com>” as default secret key for signing

gpg: Signature made Thu 03 Jun 2021 03:59:05 PM EDT

gpg: using EDDSA key 04C64623EA51A3B79658DBF7FFADEA1DA23333FD

gpg: issuer “bob@protonmail.com

gpg: Good signature from “Bob Smith <bob@protonmail.com>” [ultimate]

Derived Key Testrm -rf /home/osboxes/.gnupg/onlykey && onlykey-gpg init “Bob Smith <bob@protonmail.com>” --homedir /home/osboxes/.gnupg/onlykey/3 && echo “secret message” | gpg2 --encrypt -r “Bob Smith <bob@protonmail.com>” --homedir /home/osboxes/.gnupg/onlykey/3 | gpg2 --decrypt --homedir /home/osboxes/.gnupg/onlykey/3 && echo “Hello World” | gpg2 --sign --homedir /home/osboxes/.gnupg/onlykey/3 | gpg2 --verify --homedir /home/osboxes/.gnupg/onlykey/3

2021-06-03 16:17:27,197 WARNING This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [init.py:128]

2021-06-03 16:17:27,211 WARNING NOTE: in order to re-generate the exact same GPG key later, run this command with “–time=0” commandline flag (to set the timestamp of the GPG key manually). [init.py:39]

Enter the 3 digit challenge code on OnlyKey to authorize <gpg://Bob Smith <bob@protonmail.com>|ed25519>

1 6 6

Enter the 3 digit challenge code on OnlyKey to authorize <gpg://Bob Smith <bob@protonmail.com>|ed25519>

3 6 2

gpg: inserting ownertrust of 6

gpg: checking the trustdb

gpg: marginals needed: 3 completes needed: 1 trust model: pgp

gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u

sec ed25519 1970-01-01 [SC]

00D7E7648313E75CBCACEE1E4E33E1555C9C727D

uid [ultimate] Bob Smith <bob@protonmail.com>

ssb cv25519 1970-01-01 [E]

gpg: WARNING: cipher algorithm AES256 not found in recipient preferences

gpg: encrypted with 256-bit ECDH key, ID B6A4B0937CCC61C7, created 1970-01-01

“Bob Smith <bob@protonmail.com>”

secret message

gpg: using “Bob Smith <bob@protonmail.com>” as default secret key for signing

gpg: Signature made Thu 03 Jun 2021 04:17:35 PM EDT

gpg: using EDDSA key 00D7E7648313E75CBCACEE1E4E33E1555C9C727D

gpg: issuer “bob@protonmail.com

gpg: Good signature from “Bob Smith <bob@protonmail.com>” [uncertain]

To test this upgrade to the latest firmware here - Release OnlyKey 2.1.1 Firmware · trustcrypto/OnlyKey-Firmware · GitHub

And upgrade to the latest agent with:
$ pip3 install onlykey-agent

1 Like

@t11 great news, it works! Upgraded both the agent and the firmware and so far so good. Can confirm a local GPG generated ECC Key loads fine and I can initialize and use it as normal now.

I’m looking at my original use case which was subsequently to add subkeys for various different services, such that, should one be compromised, I can expire it with the master key from the OnlyKey. Then again this is achievable with a revocation cert. I may be approaching this in a way I’m familiar with (and former best practice), e.g. not with an offline hardware key in mind. Previously it would always make sense to generate the primary key pair and store offline. Then generate ‘online’ subkey pairs for each service or device.

Maybe this isn’t intended usage here? Is the intended design, given the OnlyKey stores the primary key pair offline, to use it across services for a single identity? Only requiring multiple key pairs for multiple identities.

Understand some of this is subjective and based on requirements / risk model but it would be good to know the intention.

Even so, generating subkeys as you documented before doesn’t seem to work. Running:

onlykey-gpg init "myuser@protonmail.com" --subkey

Complains that the ~/.gnupg/onlykey directory already exists.

– BVS

Glad to hear this is working well. For the --subkey option you can only add a subkey to an existing identity, this instead of creating a new one. This is not for adding keys to a GPG identity you created with GPG agent.

Rather than using onlykey-gpg init to create a new GPG key, a subkey may be added to an existing GPG key (not created with onlykey-gpg).

https://docs.crp.to/onlykey-agent.html#add-subkey-to-an-existing-gnupg-identity

I have the same issue with my gpg generated EC key as @bettyvschmartz
I’m using App v5.3.4, OnlyKey v2.1.2-prodc and gpg 2.3.4

I see this error:

TypeError: Cannot read property ‘data’ of undefined

On MacOS using gpg --gen-key and sticking to the defaults it makes a root key for signing and certificate (Ed25519). With only 1 sub-key for encryption (cv25519).
Exporting with gpg --output gpg_private.asc --armor --export-secret-key <keyid> and uploading this through the OnlyKey app works.

But good practice suggests to use a dedicated sub-key for signing, and taking away the signing ability from the root key. This can be done with gpg --expert --edit-key.
But in this case the Onlykey app cannot load the exported version: it fails with the above message.

Is there a workaround coming or suggestions on how to handle this?

I found this GitHub issue: Add support for GPG keys with multiple subkeys · Issue #166 · trustcrypto/OnlyKey-App · GitHub
Is this the reason: multiple subkeys are not supported?

(PS I prefer to have a file based backup and not rely on onlykey hardware only)

@franchan Yes, the issue is likely that OpenPGP.js does not know how to parse the custom key. There is an alternative way of loading keys onto OnlyKey using the advanced tab in the app. There you can load directly the 32 byte private key (p256 or ed25519). In order to get that 32 byte private key other users have had luck following the instructions here - Add support for GPG keys with multiple subkeys · Issue #166 · trustcrypto/OnlyKey-App · GitHub

Let me know if this works for you.

2 Likes