-
Notifications
You must be signed in to change notification settings - Fork 49
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
key format inconsistency #251
Comments
@lukpueh can you have a look if this issue includes all of your comments? I tried to include your 2 summaries from slack |
@mnm678 This is obviously one for you to watch / participate in as well... |
Note: I have modified the issue and added an observation from our work on the golang implementation. |
Thanks for adding the note, @shibumi! I think there is no harm in consolidating the RSA in-memory format to PKCS8, private keys are never in tuf/in-toto metadata, so there should be no metadata backwards compatibility problem. That said, I don't think it is a big deal, it just looks a bit odd that securesystemslib private keys have the private portion in a PKCS1 PEM block and the public portion in a PKCS8 PEM block. I doubt that the mismatch is intentional. So I'd say it is not a priority to change this, but I would at least document it somewhere. FYI all, we originally discussed this in in-toto/in-toto-golang#56 |
Hi everybody, We store RSA keys in-memory as PEM blocks as specified in RFC7468, In my opinion, this adds a huge technical debt and layer for making mistakes and if we agree on loading keys as specified in RFC7468](https://tools.ietf.org/html/rfc7468) we could also agree on storing them in-memory for future versions on the long term. I am not arguing that we should change this now, but on the long term we should definitely work on this, in my opinion. |
A nice example for such technical debt is this awesome PR from @trishankatdatadog : theupdateframework/python-tuf@1a8a0e7...f5eb59b#diff-6289f254358d3e8e498537ca81acd6fdR247 The This is definitely something to improve for the future :) |
Well, the complication is mostly in filling in the right fields (esp. "scheme") in the key dictionary SSLib expects, which is not the hard part. Vault stores RSA/ECDSA pubkeys as PEM, so we just copy those over, but Ed25519 is base64-encoded, so we just have to decode that. The real messiness, IMHO, is requiring "keytype", "scheme", and "keyid" baked into key formats on disk, which doesn't always make sense (especially for RSA). Also, duplicate fields (why both "keytype" and "scheme"?) |
Agreed! I think this is what this issue here is partly about. Btw. we don't bake in keytype/scheme/keyid for RSA on disk, we support standard PEM format there. We only have a custom format for ed25519 and ecdsa.
Please see #239 |
Small note on this: in-toto-golang is doing this differently now. We store ed25519 as PEM on disk there. For ecdsa and in-toto-golang we have not a decision yet, but I am pretty sure we do the same for it, because it would make sense. |
Erratum: However, I still stand by my claim that it looks a bit odd that we use PKCS1 (RFC8017) for private key files but not for public key files (yes, PKCS1 does define syntax for both). I also still think we don't need to change anything about it. |
Another issue that came up from @trishankatdatadog : #262 (comment)
I just thought, I would add this here as comment, because I think it's another issue we should have in mind, if we ever want to change our in-memory key format. |
Another thought for future key changes from theupdateframework/tuf#1091 (comment) is to include in the key format a representation that will be the same for all uses of a key (different signing or hashing algorithms) such as the modulus and exponent for RSA. This would be useful for ensuring a unique threshold of keys is being applied to a metadata file. (We decided this issue can be put off for now, but if anyone is looking at the key format in the future this might be something to consider) |
I think I have found another potential problem or the problem is me not understanding how this works: If we call in-toto run on a directory with the directory path and the key as parameters, RecordArtifacts will hash all files in this directory, but with which hash function? Right now we just hash everything in in-toto-golang with sha256, but I am a little bit confused right now on how we could make this hash function independent. What I, as a user, would expect is: the hash function will be chosen by the used key. So if I use ed25519, we should also hash all files with sha512, but what we do right now is the exact opposite. Am I wrong and are these two completely unrelated tasks (signing the link files and recording the files via hashing their content)? Let us say these tasks should be unrelated to each other, via which mechanism do we pass the right hash function to the RecordArtifacts call? I see two options here:
def _hash_artifact(filepath, hash_algorithms=None, normalize_line_endings=False):
if not hash_algorithms:
hash_algorithms = ['sha256']
.... I guess, this means, that in-toto supports only sha256 right now, too. The in-toto lib does not make use of the hash_algorithms parameter yet, is this correct? Do we track multi-hash support somewhere? |
@shibumi, thanks for your question and the detailed account of how you tried to find an answer! The short answer: The longer answer:
|
@lukpueh thanks for your clarification Reading your long answer I am able to compile these points for in-toto-golang:
Looks like I have implemented this correctly
That's what is missing right now in the go implementation. How do we want to proceed here? What way will TUF go? CC: @trishankatdatadog I feel uncomfortable with calling a hardcoded sha256 function and if we set a specific function it should be in the specification, I guess. The alternative would be to make this dynamic and/or fallback on a specific hash function if necessary.
ah okay interesting, I implemented it this way, that the dev is able to choose a specific hash function. The match rules for hash algorithms is definitely a different topic we should talk about :D |
We plan to remove the
IMO it's perfectly fine to keep using sha256 keyids as default, as long as we don't expect them anywhere. |
Thanks again for creating this issue, @shibumi, and for all your insights, everyone else! I think we should try to identify and create a bit more bite-sized sub-issues, coordinating with discussions in secure-systems-lab/dsse#1 and other issues under the 1.0.0 milestone. |
Add convenience dispatcher for other private key import interface functions, to import any of the supported private key types from file (rsa, ecdsa, ed25519). This transfers a similar function, currently implemented in in-toto.util, in order to close in-toto/in-toto#80. Caveat: - The key type must be specified via argument (or defaults to RSA). In the future we might want to let the parser infer the key type, as we do in the related in-toto-golang implementation. See https://github.com/in-toto/in-toto-golang/blob/5fba7c22a062a30b6e373f33362d647eabf15822/in_toto/keylib.go#L281-L361 - Currently, the function does not support a signing scheme parameter and thus assigns the default value from import_rsa_privatekey_from_file to the returned key. For the other keep types, the scheme is encoded in the on-disk format. In the future we might want to consolidate this as part of secure-systems-lab#251. For now the primary goal is to have a simple interface that is enough to close in-toto/in-toto#80.
Add convenience dispatcher for other private key import interface functions, to import any of the supported private key types from file (rsa, ecdsa, ed25519). This transfers a similar function, currently implemented in in-toto.util, in order to close in-toto/in-toto#80. Caveat: - The key type must be specified via argument (or defaults to RSA). In the future we might want to let the parser infer the key type, as we do in the related in-toto-golang implementation. See https://github.com/in-toto/in-toto-golang/blob/5fba7c22a062a30b6e373f33362d647eabf15822/in_toto/keylib.go#L281-L361 - Currently, the function does not support a signing scheme parameter and thus assigns the default value from import_rsa_privatekey_from_file to the returned key. For the other keep types, the scheme is encoded in the on-disk format. In the future we might want to consolidate this as part of secure-systems-lab#251. For now the primary goal is to have a simple interface that is enough to close in-toto/in-toto#80.
Add convenience dispatcher for other private key import interface functions, to import any of the supported private key types from file (rsa, ecdsa, ed25519). This transfers a similar function, currently implemented in in-toto.util, in order to close in-toto/in-toto#80. Caveat: - The key type must be specified via argument (or defaults to RSA). In the future we might want to let the parser infer the key type, as we do in the related in-toto-golang implementation. See https://github.com/in-toto/in-toto-golang/blob/5fba7c22a062a30b6e373f33362d647eabf15822/in_toto/keylib.go#L281-L361 - Currently, the function does not support a signing scheme parameter and thus assigns the default value from import_rsa_privatekey_from_file to the returned key. For the other keep types, the scheme is encoded in the on-disk format. In the future we might want to consolidate this as part of secure-systems-lab#251. For now the primary goal is to have a simple interface that is enough to close in-toto/in-toto#80.
Cross-referencing question about key formats in theupdateframework/go-tuf#127. |
I have divided this issue into 3 separate chunks:
Let's close here and have further more focussed discussions there. |
Description of issue or feature request:
Based on this PR (#250) we had a discussion around a default or custom key format. The PR showed up a few inconsistencies regarding public key generation in
in-toto-keygen
. We generate a key id for private keys, but no key id will be written for public keys. This lead to the question if we want to support key ids in our key format.Current behavior:
Right now TUF and in-toto behave differently regarding key formats:
GPG_PUBKEY_SCHEMA -- requires keyid
ANYKEY_SCHEMA -- requires keyid
PUBLIC_KEY_SCHEMA -- does not require keyid, but allows it because unrecognized keys are allowed
KEY_SCHEMA -- does not require keyid, but allows it because unrecognized keys are allowed.
Also we seem to differ between different stages (in-memory, on-disk, etc):
This comments from @lukpueh might be important for this PR, too: (#250 (comment)):
While working on the Go implementation Lukas found an issue in the PKCS key loading.
In the Go implementation we are able to load a PKCS1 private key, however while extracting the public key out of the PKCS1 key we are storing the public key as PKCS8. Therefore we end up with two different PEM representations in our in-memory key format. The securesystemslib seems to do it that way, too. We should really have a look at this.
Should we drop PKCS1 support completely for private keys?
Expected behavior:
to be discussed
The text was updated successfully, but these errors were encountered: