Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GPG keys with multiple subkeys #166

Open
LRitzdorf opened this issue Jun 16, 2021 · 13 comments
Open

Add support for GPG keys with multiple subkeys #166

LRitzdorf opened this issue Jun 16, 2021 · 13 comments

Comments

@LRitzdorf
Copy link

While the OnlyKey documentation specifically mentions the case of OpenPGP keys with multiple subkeys (i.e. the primary signing key, the encryption subkey, and a secondary signing key), the app does not seem to support this case.

I tested this by generating a new Ed25519 keypair, which loaded onto the OnlyKey successfully. This process included a dialog that asked me to choose between loading the primary key and the first subkey (for signing and decryption, respectively). However, after adding a secondary signing subkey to this same original keypair (using gpg --expert --edit-key MY-KEYGRIP-HERE), the loading process failed.

I attempted to load the full keypair, as given by gpg --armor --export-secret-key MY-KEYGRIP-HERE, which gave a TypeError: Cannot read property 'data' of undefined in the app. I also tried the encryption subkey on its own, as given by gpg --armor --export-secret-subkey MY-KEYGRIP-HERE, but this gave an Error parsing PGP key: Invalid enum value.

Ideally, when reading in a key with multiple subkeys, we would simply add options to the subkey selection dialog mentioned above. At the moment, however, it appears that the app doesn't even parse the input correctly, so that's probably the first piece to fix.

@onlykey
Copy link
Collaborator

onlykey commented Jun 18, 2021

We currently use OpenPGP.js to parse keys, GPG supports things that OpenPGP.js does not so keep that in mind. The mention of multiple subkeys was for RSA where a primary 4096 key is used and two 2048 subkeys, we currently don't have support for multiple ECC subkeys we may be able to add this in future app release. There is also the option of manually loading the raw ECC keys (private is 32 bytes) on the advanced tab.

@LRitzdorf
Copy link
Author

Ah, good to know. Thanks!

I realize this isn't directly on topic, but could someone point me toward an article or docs page that outlines how to get the raw ECC key? I'd seen that section of the app, but I'm unclear on how to extract the "raw" key from the key file. (Maybe worth adding a section on this to the OnlyKey docs?)

@onlykey
Copy link
Collaborator

onlykey commented Jun 18, 2021

I will have to look into how to do this with GPG keys. Here is how to do it with OpenSSL keys:

Generate ECC prime256v1 Private Key
$ openssl ecparam -genkey -name prime256v1 -out prime256v1.key
Generate ECC secp256k1 Private Key
$ openssl ecparam -genkey -name secp256k1 -out secp256k1.key
Generate ECC Curve25519 Private Key
$ openssl genpkey -algorithm X25519 -out X25519.key
View prime256v1 Private Key
$ openssl ec -in prime256v1.key -noout -text 2>/dev/null | sed -n '/priv:/,/pub:/p' | grep -o '[0-9a-f]{2}' | tr -d ' \n'
View secp256k1 Private Key
$ openssl ec -in secp256k1.key -noout -text 2>/dev/null | sed -n '/priv:/,/pub:/p' | grep -o '[0-9a-f]{2}' | tr -d ' \n'
View Curve25519 Private Key
$ openssl pkey -in X25519.key -noout -text 2>/dev/null | sed -n '/priv:/,/pub:/p' | grep -o '[0-9a-f]{2}' | tr -d ' \n'

@altsalt
Copy link

altsalt commented Jul 29, 2021

I am also having this problem (potentially among others) and described at least one step towards resolution in this closed issue. That said, I wanted to add commands to export the individual subkeys with gnupg.

To list the info needed to extract subkeys:
gpg --list-keys --with-subkey-fingerprints

To export one subkey, with the keychain to the master:
gpg --export-secret-subkeys --armor '0000000000000000000000000000000000000000' > subkey.asc

To export JUST the subkey:
gpg --export-secret-subkeys --armor '0000000000000000000000000000000000000000!' > subkey_only.asc

@onlykey
Copy link
Collaborator

onlykey commented Jul 30, 2021

I have created a python script that is able to extract raw key values for a PGP primary key and this should work for unlimited number of subkeys. @altsalt You mentioned looking for a method to load keys for more complicated GPG keys with multiple subkeys this should do that. Keep in mind that this script extracts raw key material and displays it so this should only be run on a trusted computer. Here is how to use this script:

$ pip3 install pgpy
  • Edit python file to replace privkey_passphrase with your private key passphrase
  • Edit python file to replace privkey_ascii_armor with your private key
  • Run the file
$ python3 PGPparseprivate.py
privkey is now unlocked
privkey key value:
82794ef9213eb697a9c3d6c5c4cfb29ac58a6a8eb4ed770b32f20ee7ee66811e
subkey key values:
subkey id 5DE5184A688B199D
subkey key value
4bd650c5353367b577ec6fc8843b4cbb5b60ae3c5270e3f11442e19e0861cda8

The shown values are the raw keys, these can be loaded in the advanced tab of the OnlyKey App.

image

@altsalt
Copy link

altsalt commented Aug 5, 2021

Thank you very much for the script @onlykey ! It did not work at first for my rootless subkeys, but I figured out the work-around. Both the issue and fix were left as replies to SecurityInnovation/PGPy#77

The extracted subkey is able to be loaded as you indicated. Excited to do a bit more testing before loading on my real key. Unfortunately, the snag mentioned in #170 is still in play, I will post screenshots in reply to that particular issue.

@LRitzdorf
Copy link
Author

Great to see this working! I'd hesitate to truly close the issue at this point, since there isn't native support for subkeys yet, but it's definitely a step that makes subkeys a workable option!

For any other users here looking for a solution, see the above comments for code that works with both OpenSSL and GPG keys.

@onlykey
Copy link
Collaborator

onlykey commented Aug 16, 2021

@altsalt Great to hear its working. So next step is to test with various key types to see if this covers most use cases. Then we can add in the ability to display and select a subkey to load, then we could have this load to OnlyKey from the script using onlykey-cli.

@altsalt
Copy link

altsalt commented Aug 19, 2021

Working on that step with my trifurcated key sometime this week and will send along results.

@svareille
Copy link

Hi !
I tested the script with an gpg-generated key which features :

  • A primary RSA 4096 key;
  • Two RSA 4096 subkeys for encryption and signature, both expired;
  • Two ECC subkeys for encryption (cv25519) and signature (ed25519) , both valid.

The current script doesn't allow for different algorithms for primary and sub keys.
Plus, I don't really like having to put my passphrase along with my private key directly in the script and thus plain text on my disk.

Therefore I reworked the script to :

  • Take the key from file or stdin
  • Ask for the passphrase interactively or as argument (unsafe if used in a terminal : bash history remembers everything)
  • Know RSA, ECDSA, EdDSA and ECDH algorithms
  • Allow for heterogeneous key algorithms : any combination is accepted
  • Warn if a subkey is expired
  • Color output for better user experience (that one is a bonus)

It currently doesn't extract DSA and ElGamal private keys (not sure if OnlyKey support theses).

The script can be found at https://gist.github.com/SimonVareille/fda49baf5f3e15b5c88e25560aeb2822
The key used is the john_do.asc key whose passphrase is the single letter a : https://gist.github.com/SimonVareille/1e15779ac524eb868600af53ac8a3dca

Do you think it's worth adding in the official repo ?
In any case, any comment would be appreciated !

@onlykey
Copy link
Collaborator

onlykey commented Mar 14, 2022

@SimonVareille Very nice! We can add this to the official repo. DSA and ElGamal private keys are not supported only
RSA (2048bit or 4096bit)
ECC (nist256p1, cv25519, ed25519)

@garrickwelsh
Copy link

garrickwelsh commented Jul 26, 2022

@onlykey I had implemented multiple key and subkey support in libagent for onlykey now. I have a PR to your libagent repository onlykey/lib-agent PR8. I hope this is the correct way as I hoped to let you review changes and push from your repository upstream. I have modified @SimonVareille's script to create a proof of concept that automatically load keys to the onlykey in a format that can later be read off them using onlykey-gpg-agent. onlykey-cli-gpg-add-keys.py
The short coming I have at the moment is that I still require the master key to be installed on the key, I can't just have subkeys installed. I'd like to workaround this as ideally I'd prefer to only load subkeys onto my key. Additional changes pushed to PR so master key is not required on onlykey to support subkeys.

@Technetium1
Copy link

@onlykey There is now OpenPGP.js 5.x, and a beta for 6.x. Have you considered testing the new releases? https://github.com/openpgpjs/openpgpjs/releases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants