Skip to content

Support Signing and Authentication subkeys#358

Open
jrruethe wants to merge 13 commits into
romanz:masterfrom
jrruethe:subkeys
Open

Support Signing and Authentication subkeys#358
jrruethe wants to merge 13 commits into
romanz:masterfrom
jrruethe:subkeys

Conversation

@jrruethe

@jrruethe jrruethe commented Aug 9, 2021

Copy link
Copy Markdown

This pull request is for adding a Signing subkey and an Authentication subkey, in addition to the existing Encryption subkey. It also changes the Primary key to be Certify only. This structure matches best practices found here and here.

One of the benefits of this structure is that it becomes possible to use the Trezor to deterministically generate the Primary and Subkeys, use the included recovery script to mimic the generation and recover the secret portions (suggested to only do this in an offline Tails environment), then move the secret subkeys to a smartcard device like a Yubikey 5. This allows one to achieve the security and determinism of the Trezor (especially when utilizing Shamir), while maintaining the compatability and convienience of a smartcard like the Yubikey. Note that with this scheme, the Primary (certifying) key remains completely offline, and is not intended to be used.

The current code creates a Primary key with Certify and Sign capabilities, and a single Encryption Subkey. The Primary key uses SLIP 13, while the Encryption Subkey uses SLIP 17. Both use derivation index 0 of their respective schemes. The code uses a single boolean named ecdh to differentiate the two.

This pull request adds an enum named KeyFlags. This enum accomplishes 3 things simultaneously:

  • Determines the capabilities of the keys
  • Determines the derivation index
  • Determines the curve algorithm

The derivation index comes into play because we want the Primary Key, Signing Subkey, and Authentication Subkey to all be different. I chose to use derivation indices 0, 1, 2 for these respectively. The derivation index is normally passed to the Trezor via the IdentityType message, using a field named index. Currently, this value is not set by trezor-agent, so it defaults to 0. In order for _identity_proto to properly set the index, it needs to be available in the identity_dict of the Identity class. Per SLIP 13/17, the derivation index is separate from the identity_str (RFC 3986 URI), therefore the index is derived from a KeyFlag parameter added to the constructor. This change does end up rippling through some code, notably necessatating an Identity for each Public Key created in init.

A majority of the rest of the changes involve replacing the ecdh variable with the KeyFlags enum and adjusting functions and calls accordingly.

A second change was needed to accomplish the goal. Now that multiple subkeys (and therefore multiple KeyFlags) are at play, the decode class needed to be able to parse these KeyFlags from the keys. The KeyFlags are stored inside the hashed area of the signature packets for a key. According to page 69 of RFC 4880, the signature packet always follows the pubkey/subkey packet, so the load_by_keygrip was rewritten to map them together and return it to get_identity. A unit test was added for this.

Finally, gpg version 2.1.14 adds a new subpacket type 33, which is not part of RFC 4880 (and has caused some problems for other clients). It is used for verifying cross-certification of signing subkeys, and is only specifically required for signing subkeys (not authentication subkeys, this was verified by using gpg to generate a new key with subkeys, then dump the packets). Here are some handy links:

That last link shows a "gotcha", where the signature creation date must be greater than 0 for gpg to register it as a cross-certification signature. I chose to add 1 to the embedded signature creation time. This does not affect the public keys themselves.

Lastly, I rearranged some fields to match the same order that gpg produces, refactored libagent/gpg/__init__.py since the inclusion of the subkeys has introduced some repetition.

I did multiple tests to ensure backward compatability. First, I wiped a Trezor and initialized it with a mnemonic of all all all all all all all all all all all all. Then, I used the current version of trezor-agent to both sign and encrypt a file.

Next, I used the version of trezor-agent from this pull request to both verify and decrypt the file, using the "normal" key layout. The fingerprints and keygrips were also compared and found to be the same. Afterwards, I did the test again by passing the --smartcard flag to generate the three subkeys. The fingerprint and keygrip of the certifying key and encryption key are the same, as expected, and the "smartcard" layout is able to both verify and decrypt the same file.

Lastly, I used the contrib/trezor_agent_recovery.py script to recover the public and private keys. The public key was compared to the one generated by trezor-agent init --smartcard and found to be the same, and the private key was the proper pair. Using the private key, I was able to decrypt the file without the Trezor.

This confirms the ability to both generate and recover the private subkeys, for moving to a Yubikey 5.

I tried to maintain the same coding style that was present, and made sure that pylint and pytest both passed. If you have any questions, let me know. Thank you!

@slvrfn

slvrfn commented Sep 19, 2021

Copy link
Copy Markdown

@jrruethe Have you tried generating a ssh key after these changes? I just tried and am getting the following error:

Traceback (most recent call last):
File "/home/cameron/miniconda3/envs/trezor/bin/trezor-agent", line 8, in
sys.exit(ssh_agent())
File "/home/cameron/miniconda3/envs/trezor/bin/trezor_agent.py", line 4, in
ssh_agent = lambda: ssh.main(DeviceType)
File "/home/cameron/miniconda3/envs/trezor/lib/python3.9/site-packages/libagent/ssh/init.py", line 173, in wrapper
return func(*args, **kwargs)
File "/home/cameron/miniconda3/envs/trezor/lib/python3.9/site-packages/libagent/ssh/init.py", line 269, in main
identities = [device.interface.Identity(
TypeError: init() missing 1 required positional argument: 'keyflag'

It appears there is a parameter in Identity: keyflag that is not set from "libagent/ssh/init.py"

@jrruethe

Copy link
Copy Markdown
Author

I have not, but I can look at that and fix it. I only did testing with GPG, not SSH. Thanks for the heads up!

@jrruethe

Copy link
Copy Markdown
Author

@slvrfn I believe I fixed the issue you had with SSH.

@romanz romanz mentioned this pull request Oct 22, 2021
@lukechilds

Copy link
Copy Markdown

Hey, awesome work on this @jrruethe! Just wanted to check what the status of this is?

@jrruethe

Copy link
Copy Markdown
Author

@lukechilds I've been using my branch without issues for my own purposes, so for what I needed it is complete. I used it to generate deterministic subkeys from the Trezor and load them onto my Yubikey 5 NFC, which can then be used with the standard GPG installation.

@romanz

romanz commented Dec 13, 2021

Copy link
Copy Markdown
Owner

Sorry for the very delayed response...
Could you please rebase over the latest master?

@McCodeman

McCodeman commented Feb 8, 2022

Copy link
Copy Markdown

@lukechilds I've been using my branch without issues for my own purposes, so for what I needed it is complete. I used it to generate deterministic subkeys from the Trezor and load them onto my Yubikey 5 NFC, which can then be used with the standard GPG installation.

@jrruethe Do you have a writeup or can you point me in the right direction for moving loading subkeys onto the Yubikey 5 NFC.

@talosgt

talosgt commented Feb 26, 2022

Copy link
Copy Markdown

@lukechilds I've been using my branch without issues for my own purposes, so for what I needed it is complete. I used it to generate deterministic subkeys from the Trezor and load them onto my Yubikey 5 NFC, which can then be used with the standard GPG installation.

@jrruethe Hi Joe! This is exactly what I wanted to get working. As @McCodeman would you please be able to provide instructions on how to do exactly what you said? I would love to backup the Trezor master key and create/revoke subkeys and use them with my Yubikey. Sounds amazing! Thanks!!

@jrruethe

Copy link
Copy Markdown
Author

Essentially, I used the script in this pull request "contrib/trezor_agent_recover.py" with the "--smartcard" option. I used a Tails environment that was not connected to the internet, and entered my Trezor seed into the script, which output the private GPG keys (both the master and subkeys). After that, I just used the standard instructions for moving the subkeys to a Yubikey, such as this guide: https://github.com/drduh/YubiKey-Guide

There isn't a way to extract the private keys directly from the Trezor itself, which is why I supplied the recovery script. The recovery script generates the same keys as the Trezor when the same seed is used. This means that signing and encryption operations done with the Trezor can be used with the Yubikey, and vice versa.

@talosgt

talosgt commented Feb 26, 2022

Copy link
Copy Markdown

Essentially, I used the script in this pull request "contrib/trezor_agent_recover.py" with the "--smartcard" option. I used a Tails environment that was not connected to the internet, and entered my Trezor seed into the script, which output the private GPG keys (both the master and subkeys). After that, I just used the standard instructions for moving the subkeys to a Yubikey, such as this guide: https://github.com/drduh/YubiKey-Guide

There isn't a way to extract the private keys directly from the Trezor itself, which is why I supplied the recovery script. The recovery script generates the same keys as the Trezor when the same seed is used. This means that signing and encryption operations done with the Trezor can be used with the Yubikey, and vice versa.

Thanks for replying so quick! I'm an absolute novice on github. I don't mind running the python file on my regular computer as I'm just testing around with my Trezor, there's nothing on it. My question is how do I just run the file? Just open Terminal and run the saved file? Or do I enter my seed somewhere into the python script and run it? I did a shamir seed, so I would have enter the entire thing? Then do I remove do a "rm -r trezor" that I currently have and then run the script as if I'm doing the "trezor-gpg init... -- smartcard" command? I sent you an email in hopes that you can guide me, I don't mind compensating for your time as I'm very interested in this. I came across GPG not long ago and became very interested. Thanks!

@talosgt

talosgt commented Feb 26, 2022

Copy link
Copy Markdown

@jrruethe sorry, how do you run this version of the script instead of the usual "trezor-gpg init..." ?

@jrruethe

Copy link
Copy Markdown
Author

For an ubuntu-based system, the following commands should get you started:

sudo apt install python3-setuptools
git clone https://github.com/jrruethe/trezor-agent.git
cd trezor-agent
git checkout subkeys
sudo python3 ./setup.py install
python3 ./contrib/trezor_agent_recover.py --smartcard true

@talosgt

talosgt commented Feb 26, 2022

Copy link
Copy Markdown

@jrruethe thanks for getting back! I got a traceback, maybe I'm doing something wrong?

Traceback (most recent call last): File "trezor_agent_recover.py", line 25, in <module> from libagent.formats import KeyFlags # type: ignore ImportError: cannot import name 'KeyFlags' from 'libagent.formats' (/home/granttesler/.local/lib/python3.8/site-packages/libagent/formats.py)

@talosgt

talosgt commented Mar 25, 2022

Copy link
Copy Markdown

@jrruethe any advice for why I'm getting the Traceback for the Keyflags error that I listed above?

@lukechilds

Copy link
Copy Markdown

@jrruethe your contrib/trezor_agent_recover.py is really useful to me. I'm not too familiar with the internals of this lib, would it be simple to modify it to also export the SSH key?

@jrruethe

Copy link
Copy Markdown
Author

Unfortunately, I don't have the capacity to work on this any more right now.

For SSH, I have my GPG agent set up to also be an SSH agent. SSH connections utilize the authorization subkey on the Yubikey.

This guide has instructions on how to go that route:
https://github.com/drduh/YubiKey-Guide

@lukechilds

lukechilds commented Aug 13, 2022

Copy link
Copy Markdown

No worries @jrruethe, that sounds ideal. I'll look into it, thanks!

Comment on lines +28 to +29
curve_name_to_curve = {"nist256p1": curves.NIST256p}
curve_name_to_seed = {"nist256p1": "Nist256p1 seed"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrruethe Thanks for this work!
Any chance of you having some time to add ed25519 support to your script and rebase on top of master?
I'd be very much interested in using it with my current keys, but they're edwards.
Thanks

@romanz

romanz commented May 29, 2023

Copy link
Copy Markdown
Owner

@jrruethe Could you please rebase your PR over latest master?
I would be happy to merge it :)

@jrruethe

jrruethe commented Jun 1, 2023

Copy link
Copy Markdown
Author

I'll try to do this soon, I gotta test it out again with a real trezor

@jrruethe

jrruethe commented Jun 2, 2023

Copy link
Copy Markdown
Author

After rebasing, I can't seem to decrypt files, so apparently I messed something up. I'll try to dig in deeper if I get a chance

@jrruethe

jrruethe commented Jun 2, 2023

Copy link
Copy Markdown
Author

@romanz Ok, I got it all working and retested it with a real trezor. I also tested the trezor_agent_recover.py script again, and everything looks good.

Ready to merge! Thanks!

EDIT - I certainly hope I did that right, my git is not as strong as it should be :)

@romanz

romanz commented Jun 3, 2023

Copy link
Copy Markdown
Owner

I suggest cherry-picking only your commits into a clean branch over master.

@romanz

romanz commented Jun 3, 2023

Copy link
Copy Markdown
Owner

I have squashed all the changes above into a single commit: f16310f.
Please review it - it should contain the same code as e11afff above:

$ git diff e11afff f16310f

@romanz

romanz commented Jun 3, 2023

Copy link
Copy Markdown
Owner

It seems that CI didn't run on this PR...

My bad - fixed in 2b49eac (please rebase over latest master).

@romanz romanz left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrruethe Could you please fix the CI errors here:
https://github.com/romanz/trezor-agent/actions/runs/5162519295/jobs/9300268171#step:5:67

You can also run the tests locally via tox, which used to run the following checks:

$ tox
...
py3: commands[0]> pycodestyle libagent
py3: commands[1]> isort --skip-glob .tox -c libagent
py3: commands[2]> pylint --reports=no --rcfile .pylintrc libagent
py3: commands[3]> pydocstyle libagent
py3: commands[4]> coverage run --source libagent -m pytest -v libagent
...

@jrruethe

jrruethe commented Jun 3, 2023

Copy link
Copy Markdown
Author

I think thats better? tox looks happy locally, for me.

@jrruethe

jrruethe commented Jun 5, 2023

Copy link
Copy Markdown
Author

@romanz Anything else needed to get this merged?

@andrevmatos

Copy link
Copy Markdown
Contributor

@jrruethe any chance of getting the same capabilities for ed25519? It seems to be more advised these days than nist's.
Thanks

@jrruethe

jrruethe commented Jun 5, 2023

Copy link
Copy Markdown
Author

@andrevmatos I don't have any plans to implement that right now. I am just trying to get the current PR completed.

@romanz

romanz commented Jun 6, 2023

Copy link
Copy Markdown
Owner

@romanz Anything else needed to get this merged?

Will do the final review this weekend - many thanks for the contribution!

@romanz romanz self-assigned this Jun 8, 2023

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this file in a separate repository/snippet please.
I prefer not to instruct the users to enter their seed on a non-secure device.

Comment thread libagent/age/client.py Outdated
def create_identity(user_id):
"""Create AGE identity for hardware device."""
result = interface.Identity(identity_str='age://', curve_name="ed25519")
result = interface.Identity(identity_str='age://', curve_name="ed25519", keyflag=None)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't keyflag_to_index throw an exception?

$ age-plugin-trezor -i foo
2023-06-09 19:03:29,483 ERROR        age plugin failed: None                                                                              [__init__.py:178]
Traceback (most recent call last):
  File "/home/user/trezor-agent/libagent/age/__init__.py", line 174, in main
    run_pubkey(device_type=device_type, args=args)
  File "/home/user/trezor-agent/libagent/age/__init__.py", line 47, in run_pubkey
    pubkey = c.pubkey(identity=client.create_identity(args.identity), ecdh=True)
  File "/home/user/trezor-agent/libagent/age/client.py", line 15, in create_identity
    result = interface.Identity(identity_str='age://', curve_name="ed25519", keyflag=None)
  File "/home/user/trezor-agent/libagent/device/interface.py", line 69, in __init__
    self.identity_dict['index'] = keyflag_to_index(keyflag)
  File "/home/user/trezor-agent/libagent/formats.py", line 49, in keyflag_to_index
    return {
KeyError: None

Comment thread libagent/gpg/decode.py
user_ids += [p for p in packets if p['type'] == 'user_id']

for packets in packets_per_key:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove the line

Suggested change

Comment thread libagent/gpg/decode.py
# The key packet contains the keygrip
# The signature packet contains the keyflag in the hashed area
# Map them together
# pylint: disable=consider-using-enumerate

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not to use for i, p in enumerate(packets) below?

Comment thread libagent/gpg/decode.py
mapping = {}
for i in range(0, len(packets)):
p = packets[i]
if p['type'] == 'pubkey' or \

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to break into 2 lines

Suggested change
if p['type'] == 'pubkey' or \
if p['type'] == 'pubkey' or p['type'] == 'subkey':

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's just a random note by a random passerby, but... i also like structuring boolean trees as one entry per line. it's easier to parse for my brain when the textual structure is in sync with the semantic structure.

Comment thread libagent/gpg/encode.py
embedded_sig = None
else:
if subkey.keyflag == KeyFlags.SIGN:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove empty line

Suggested change

Comment thread libagent/gpg/protocol.py
KeyFlags.SIGN,
KeyFlags.AUTHENTICATE,
KeyFlags.CERTIFY_AND_SIGN):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment thread libagent/gpg/protocol.py
self.ecdh_packet = b''

elif keyflag == KeyFlags.ENCRYPT:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment thread libagent/ssh/__init__.py
@@ -181,7 +182,8 @@ def parse_config(contents):
"""Parse config file into a list of Identity objects."""
for identity_str, curve_name in re.findall(r'\<(.*?)\|(.*?)\>', contents):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this regexp work for the new identity format?

Comment thread libagent/signify/__init__.py Outdated

def _create_identity(user_id):
result = interface.Identity(identity_str='signify://', curve_name='ed25519')
result = interface.Identity(identity_str='signify://', curve_name='ed25519', keyflag=None)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't keyflag_to_index throw an exception?

@romanz

romanz commented Jun 9, 2023

Copy link
Copy Markdown
Owner

I also tested it using fake-device agent (on 3c45889), and it seems that regular GPG identity fails to sign:

$ gpg --version
gpg (GnuPG) 2.2.27

$ export GNUPGHOME=/tmp/gnupg
$ rm -r /tmp/gnupg/

$ fake-device-gpg init "User"
2023-06-09 19:09:11,039 WARNING      This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [__init__.py:171]
2023-06-09 19:09:11,045 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:86]
2023-06-09 19:09:11,045 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,045 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,045 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,045 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,051 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,051 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,052 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,052 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
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   nistp256 1970-01-01 [C]
      8F37E3F7339D2542B8133BE64D8F4714A14548AC
uid           [ultimate] User
ssb   nistp256 1970-01-01 [E]

$ gpg --sign README.md 
gpg: using "User" as default secret key for signing
gpg: no default secret key: Unusable secret key
gpg: signing failed: Unusable secret key

It does seems to work on master:

$ rm -r /tmp/gnupg/
$ fake-device-gpg init "User"
2023-06-09 19:10:56,352 WARNING      This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [__init__.py:118]
2023-06-09 19:10:56,357 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:33]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,365 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,365 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
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   nistp256 1970-01-01 [SC]
      8F37E3F7339D2542B8133BE64D8F4714A14548AC
uid           [ultimate] User
ssb   nistp256 1970-01-01 [E]

$ rm README.md.gpg 
$ gpg --sign README.md 
gpg: using "User" as default secret key for signing

$ gpg --verify README.md.gpg 
gpg: Signature made Fri 09 Jun 2023 19:11:08 IDT
gpg:                using ECDSA key 8F37E3F7339D2542B8133BE64D8F4714A14548AC
gpg: Good signature from "User" [uncertain]

@jrruethe Could you please take a look?

@jrruethe

Copy link
Copy Markdown
Author

I also tested it using fake-device agent (on 3c45889), and it seems that regular GPG identity fails to sign:

$ gpg --version
gpg (GnuPG) 2.2.27

$ export GNUPGHOME=/tmp/gnupg
$ rm -r /tmp/gnupg/

$ fake-device-gpg init "User"
2023-06-09 19:09:11,039 WARNING      This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [__init__.py:171]
2023-06-09 19:09:11,045 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:86]
2023-06-09 19:09:11,045 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,045 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,045 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,045 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,051 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,051 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:09:11,052 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:09:11,052 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
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   nistp256 1970-01-01 [C]
      8F37E3F7339D2542B8133BE64D8F4714A14548AC
uid           [ultimate] User
ssb   nistp256 1970-01-01 [E]

$ gpg --sign README.md 
gpg: using "User" as default secret key for signing
gpg: no default secret key: Unusable secret key
gpg: signing failed: Unusable secret key

It does seems to work on master:

$ rm -r /tmp/gnupg/
$ fake-device-gpg init "User"
2023-06-09 19:10:56,352 WARNING      This GPG tool is still in EXPERIMENTAL mode, so please note that the API and features may change without backwards compatibility! [__init__.py:118]
2023-06-09 19:10:56,357 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:33]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,358 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,358 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
2023-06-09 19:10:56,365 CRITICAL     NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!                                                       [fake_device.py:31]
2023-06-09 19:10:56,365 CRITICAL     ONLY FOR DEBUGGING AND TESTING!!!                                                                    [fake_device.py:32]
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   nistp256 1970-01-01 [SC]
      8F37E3F7339D2542B8133BE64D8F4714A14548AC
uid           [ultimate] User
ssb   nistp256 1970-01-01 [E]

$ rm README.md.gpg 
$ gpg --sign README.md 
gpg: using "User" as default secret key for signing

$ gpg --verify README.md.gpg 
gpg: Signature made Fri 09 Jun 2023 19:11:08 IDT
gpg:                using ECDSA key 8F37E3F7339D2542B8133BE64D8F4714A14548AC
gpg: Good signature from "User" [uncertain]

@jrruethe Could you please take a look?

The reason for the signing failure is that the key is being generated as [C] (certify only) instead of [SC] (signing and certify), but I haven't figured out why yet.

@talosgt

talosgt commented Jun 28, 2023

Copy link
Copy Markdown

any update to this?

@romanz

romanz commented Jun 29, 2023

Copy link
Copy Markdown
Owner

@talosgt There is an open issue (#358 (comment)) with this PR.

@doolio

doolio commented Sep 3, 2023

Copy link
Copy Markdown
Contributor

@jrruethe have you had a chance to look into the open issue?

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

Successfully merging this pull request may close these issues.

9 participants