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

Tool for importing PEM formatted ecdsa keys #522

Closed
danbev opened this issue Nov 14, 2022 · 8 comments
Closed

Tool for importing PEM formatted ecdsa keys #522

danbev opened this issue Nov 14, 2022 · 8 comments

Comments

@danbev
Copy link
Contributor

danbev commented Nov 14, 2022

Description of issue or feature request:
Currently, the in-toto command line tools support a --key-type option of ecdsa. The expected format is of type json following the securesystemslib specification.

When creating keys with tools like openssl or cosign the generated keys are often in PEM format and they have to be converted to be able to be passed to the in-toto command line tools.

I ran into this issue when experimenting with cosign and resorted to creating a python script to do this conversion. I was wondering if this might be useful to others and if it would be possible to have this type of conversion as part of in-toto in some way?

The script currently looks like this:

in-toto--key-import.py
#!/usr/bin/python3

import sys
import json
from pathlib import Path
from securesystemslib.interface import import_ecdsa_publickey_from_file
from securesystemslib.keys import import_ecdsakey_from_private_pem

def convert(key_pem):
  private_key_pem = Path(key_pem).read_text();
  private_key = import_ecdsakey_from_private_pem(private_key_pem);
  print(f"private keyid: {private_key['keyid']}");
  f = open(f"{key_pem}.json", 'w');
  f.write(json.dumps(private_key));
  f.close();

  pub_json_dict = {};
  pub_json_dict['keytype'] = private_key['keytype'];
  pub_json_dict['scheme'] = private_key['scheme'];
  pub_json_dict['keyid_hash_algorithms'] = private_key['keyid_hash_algorithms'];
  pub_json_dict['keyval'] = { 'public': private_key['keyval']['public']};

  f = open(f"{key_pem}.pub.json", 'w');
  f.write(json.dumps(pub_json_dict));
  f.close();

  # Try importing the public key json generated previously to verify that the
  # keyid matches that of the private key.
  imported_pub = import_ecdsa_publickey_from_file(f"{key_pem}.pub.json");
  private_key_id = private_key['keyid'];
  public_key_id = imported_pub['keyid'];
  print(f"public keyid : {public_key_id}");
  if (private_key_id != public_key_id) :
      print('''Conversion from pem to json format failed
               If there has been a change in the order of fields that
               import_publickeys_from_file produces the id generation will
               not work''');
          

if __name__ == '__main__':
  convert(sys.argv[1]);

This can be simplified and use import_ecdsakey_from_public_pem but I ran into an issue while working this.

I'd be happy to do the work if this something that sounds resonable to do.

Current behavior:
N/A

Expected behavior:
N/A

@adityasaky
Copy link
Member

This probably belongs in securesystemslib. Would a fix for secure-systems-lab/securesystemslib#453 make this redundant?

@danbev
Copy link
Contributor Author

danbev commented Nov 29, 2022

Would a fix for secure-systems-lab/securesystemslib#453 make this redundant?

I think that fix will help as people will not run into the issue with key_id's not being consistently generated.

But the suggestion in this issue is that from a users perspective, coming to in-toto with a key generated by cosign the user would have to perform the conversion from pem -> securesystemlib json format themselves. Just trying to use the cosign key directly without this conversion will not work.
The documentation does state that the ecdsa key is expected to be in securesystemlib json format but means the user has to figure out how to do this conversion which might lead frustration.

Another idea is this could be an extension of the current --key-type option, perhaps something like ecdsa-pem and if this is the case then in-toto would perform that conversion?

@lukpueh
Copy link
Member

lukpueh commented Nov 29, 2022

Thanks for raising this issue and sharing your script, @danbev! I agree that it would be extremely useful to make in-toto support standard (and other custom) key formats. The good news is, we are working on a more flexible signing API in securesystemslib, which should make this more intuitive (see Signer interface in secure-systems-lab/securesystemslib#456, if you are curious).

I haven't thought about what this should look like in in-toto CLI such as in-toto-run, but I'd like to change the corresponding library function in runlib.in_toto_run to accept arbitrary Signer objects instead of opinionated securesystemslibs key dictionaries. A custom Signer that imports private key material, e.g. from a standard PEM could then be implemented in your application code.

The new API will also remove the strict requirement about keyids being the sha256 hexdigest of a certain pubkey representation, which doesn't really have a practical use.

I don't have a timeline for when this will be available in in-toto yet, as I'm driving the development in securesystemslib with a focus on in-toto's sister project python-tuf, which also uses securesystemslib. But I'm happy to coordinate any contributions for in-toto. :)

@danbev
Copy link
Contributor Author

danbev commented Nov 29, 2022

@lukpueh This sounds great! I'll try to take a closer look signing API too 👍

@jku
Copy link

jku commented Nov 29, 2022

would this script just work if you don't use import_ecdsa_publickey_from_file()? You write the file yourself, so you can just make sure it's a valid key dictionary so that there's no need to "import" it -- just read it:

  • include keyid in in the serialization json
  • when loading, just read the file as json: that's your keydict

@danbev
Copy link
Contributor Author

danbev commented Nov 29, 2022

would this script just work if you don't use import_ecdsa_publickey_from_file()?

Yes, I really just left the function call in there so that if this issue was fixed upstream, we could remove the messing about with the keyid's at that point.

@jku
Copy link

jku commented Nov 29, 2022

I'm not sure keyid generation will ever be "stable and reliable", I think it makes sense to move to a direction where we don't rely on that.

My initial hand waving about the key generation/import: secure-systems-lab/securesystemslib#466

@lukpueh
Copy link
Member

lukpueh commented Jan 16, 2024

in-toto v2.2.0 CLI consistently supports standard key file formats, as generated e.g. with openssl (see #662). Check out the CHANGELOG for details!

@lukpueh lukpueh closed this as completed Jan 16, 2024
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

4 participants