-
Notifications
You must be signed in to change notification settings - Fork 137
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
Added checks for gpg key expiration in signature verification #245
Conversation
e34fb49
to
6288778
Compare
|
Thanks for the PR, @michizhou! As you can see, both AppVeyor and Travis CI builds fail. Please fix all issues. The build logs should give you some ideas, where to look. |
|
@lukpueh I am not too sure how to fix these issues. They all stem from errors with importing some modules, yet IIRC, the import statements affected are the same as before (i.e. never modified). So I am not sure why they are giving off errors now. I will investigate and try my best to find where the problem is. If I can't find them I'll let you know. |
|
@michizhou, please read the linter error carefully. The import errors are caused by earlier syntax errors. |
90a307b
to
1c9734a
Compare
|
@michizhou, please take a look at the discussion about rebasing after having submitted a PR secure-systems-lab/lab-guidelines#14 (comment). I did tell you to make use of rebase to get rid of merge commits in your branches and to keep your history clean. However, that doesn't mean that you should stop adding new commits. I see that you've been force-pushing the same commit again and again, probably to troubleshoot/fix the build errors? But it's totally okay to create separate commits for your troubleshooting changes. That way I (and other developers) can better track your progress and jump in to help. It might also be a good idea to test locally before pushing to GitHub. See #216 (comment) for some instructions. |
93fd58f
to
81abffd
Compare
|
@lukpueh Most of the updates I force-pushed for my commits have been corrections for small, trivial mistakes in formatting and variable assignments/declarations with no substantial changes in code content or structure. As of now most of the build errors seem related to the signature and key formats in |
|
Sure, no problem. I see a lot of I also just realized that it is indeed better to add the key expiration date to the public key dict (as I had suggested originally) and not to the signature, because the signature object itself is not signed, whereas a public key, at least when embedded in an in-toto layout, is. As for signature expiration dates, it wouldn't really make sense to add it to the key, and it's unsafe to add it to the signature, so I think we should just ignore it. TBH I don't know if anyone even uses these. |
|
@lukpueh With regards to signature expiration dates, I am actually only adding the key expiration times to the key creation dates to get key expiration dates, without making use of signature expiration times beyond assignment. In any case, I will remove the signature expiration time field since we won't use it. With regards to adding the key expiration date to the public key dict, although I agree and understand your approach, I am afraid it is impossible with the Version 4 packets, since key expiration times (i.e. time in seconds for which key is valid after its creation date) are only found in the signature packets. Because of this, at parsing of the public key packet for construction of the public key dict, we cannot derive the key expiration date for addition to the public key dict. The only way to derive key expiration date would be to add the key expiration time to the signature dict and then add it (if it exists and is not 0) to the creation date of the public key dict in the |
|
@lukpueh So the errors related to the key expiration checks in signature verification have disappeared, but there seems to be a lot of |
Take a look at any public key in your gpg keychain (or the in-toto test gpg keychain), I bet that they all have a self-signature attached, because GnuPG automatically creates a self-signature when you create a key. You can use the following command, to list all public keys and their attached signatures in a keychain. Change You can also export a single public key, as we do in our in_toto.gpg module, and look at all the packets that are included. You will see that the key and their subkeys have a self-signature attached. |
|
Re Please also address the comments I left above. |
|
@lukpueh Are you saying that to derive the key expiration date at the time of key export I would have to use the key expiration time from the exported key's self-signature rather than the signature that is generated at line 98 in the |
Yes!
Well, that's kind of the exercise here. :) Take a look at the functions in
What do you think? :) |
|
@lukpueh Just to let you know, I am still in the process of working through the build errors, so I am not quite done with all my changes as of yet. From what I can tell so far, it seems that my changing of the format for the key creation date field of the public key data structure didn't mitigate the |
|
@lukpueh First of all, I want to deeply apologize for burdening you with my subpar commits from the past week. I have managed to resolve almost all build error issues by refactoring significant parts of the code, so when you have the time I would appreciate it if you could review my changes. As a heads up, in a future commit I am planning to include a new data structure designed to store all parsed public keys and incorporating it into the signature packet parsing process to properly match up self-signatures with their respective public keys in order to allow for dynamic updates of key expiration dates and times from self-signatures that could then be passed onto their public keys. |
|
Hey @michizhou, no need to apologize. You're getting there! ;) I saw that your travis builds still fail. This is due to a new version of pylint that flags unnecessary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes, @michizhou. This looks a lot better. Please address my comments and add tests.
ae21313
to
007b256
Compare
|
@lukpueh I have resolved most of the comments in your review with my latest changes to the code and also added a new test suite in the gpg test script as per your suggestion. I have also addressed some of your comments with my own thoughts, which I would like you to consider. If you have any additional concerns about the code in its current state, please let me know in your next review. Thanks! |
|
@lukpueh I have pushed a new commit that includes the new data structure used for storing all parsed public keys and incorporates it into the signature packet parsing process to properly match up self-signatures with their respective public keys as I mentioned in #245 (comment). Along with my previous commit ( |
|
@michizhou, tests are still failing. |
|
@lukpueh I am fully aware that the tests are failing at the moment. In adding new gpg tests in the test script two weeks ago @SantiagoTorres mentioned I could make use of mock.patch to streamline the test script code. However, my changes using mock.patch brought about the current build errors. I let him know about the errors, and as of now I am still in correspondence with him on troubleshooting the build errors, which is still in progress. I expect to resolve the issue within the next few days, after which I intend to update the code so that it won't produce any build errors. |
|
@lukpueh I managed to resolve the build errors with the mock patch in my tests. When you have the chance, feel free to look over my recent changes and share your thoughts. |
|
Awesome! Thanks, @michizhou. Can you please take a look at the coverage report and add tests so that all your code additions are covered. |
|
@lukpueh Not a problem. I will try to add tests to cover for the code additions not yet accounted for. |
|
@lukpueh I sincerely and deeply apologize for not getting back to you sooner. I ended up having to not only add more tests to increase coverage but also had to update the keyring I used for my tests with a new one that was compatible with the SHA256 hash algorithm used by the rest of the code. I have also refactored the signature packet processing block to integrate more steps into signature verification. As for the build errors, I am not quite sure why they are showing up, since when I locally tested all my modified code on my own machine it passed with no issues. It might have to do with the new keyring directory I added to ensure compatibility with the tests that I mentioned above. Please let me know if you think there is a need for additional changes to address other issues I haven't mentioned. |
d358c4a
to
4942d29
Compare
|
@michizhou, the reason why your tests fail on travis and appveyor is that they unfortunately can't handle the keyring format you're using in You have to generate the test keys on a system with a version of gpg below 2.1 (see 87e8c4b and What’s new in GnuPG 2.1) . Btw. you don't need to create a new keyring, you can also add test keys to one of the existing test keyrings e.g.: # In the root of the in-toto project on a system with gpg <2.1
gpg --homedir tests/gpg_keyrings/rsa --gen-key |
|
The issue is that the certification signatures in the existing keyrings
for subkeys use sha1 as the signing algo, which we don't support.
…On Wed, Jan 30, 2019 at 08:22:20AM -0800, lukpueh wrote:
@michizhou, the reason why your tests fail on travis and appveyor is that they unfortunately can't handle the keyring format you're using in `tests/gpg_keyrings/new_keyr`.
You have to generate the test keys on a system with a version of gpg below 2.1 (see 87e8c4b and [*What’s new in GnuPG 2.1*](https://www.gnupg.org/faq/whats-new-in-2.1.html)) . Btw. you don't need to create a new keyring, you can also add test keys to one of the existing test keyrings e.g.:
```bash
# In the root of the in-toto project on a system with gpg <2.1
gpg --homedir tests/gpg_keyrings/rsa --gen-key
```
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#245 (comment)
|
|
The hashing algorithm is only relevant to verify the self-signature, and not to parse its sub-packets (such as the expiration date). I was able to parse the keys' expiration dates from self-signatures with digest algo 2, 8 and 10 respectively (that's SHA1, SHA256 and SHA512), using gpg key rings below and above version 2.1, and I did not have to modify any hashing related code in our gpg module. However, by not verifying the self-signature, i.e. if the expiration date actually belongs to the corresponding key, an attacker who controls our gpg public keys might forge them. So a la long we should try to support other hashing algorithms and self-signature verification. The former might be as easy as updating the used hashing algorithms in our @michizhou, please ignore self-signature verification for now and just try to parse the expiration date. And last but not least, please be very careful with |
237216f
to
22793c5
Compare
Support verification of gpg signatures that use SHA1 and SHA512. Together with SHA256, these seem to be the most widely used hashing algorithms for signatures over keys, such as self-signatures. Use the following command to see the distribution of hash algos on your local gpg keyring (2, 8 and 10 should stick out). gpg --export | gpg --list-packets | grep ":signature packet:" -a2 |\ grep -o "digest algo [0-9]*" | sort | uniq -c See RFC4880 9.4 for the list of all hash algorithm IDs. We continue to use SHA256 exclusively for metadata signing and verification. This addition is only needed to support self-signature verification.
Add optional supported_hash_algorithms argument to parse_signature_packet to support parsing signature packets with other hash algos. So far only SHA256 was supported, which remains default.
Add optional supported_signature_types argument to parse_signature_packet to support parsing signature packets of other types, e.g. different types of self-signatures. So far only SIGNATURE_TYPE_BINARY packets were supported, which remains the default.
Update parse_signature_packet to add an optional opaque info dictionary to the returned signature. Whether it is added or not may be configured via boolean "include_info" parameter. Per default it is not added. Currently the info dictionary contains the signature_type and hash_algorithm and an empty list that may be used to add subpackets such as a key expiration date. The corresponding subpacket parsing code is already there (commented out).
Update parse_signature_packet to only return the optional short_keyid if it was parsed from the signature packet to (better) match in_toto.gpg.formats.SIGNATURE_SCHEMA. Note that the returned signature still might fail the schema check, due to an empty keyid, but it is the responsibility of the caller to adjust accordingly. This commit also updates comments and calling functions.
This commit modifies the gpg public key parsing function to parse additional packets, including User ID and User Attribute packets, as well as signature packets corresponding to any of the other parsed packets. Additionally, the commit adds a helper function to verify self-certificates that may carry information about the primary key, such as key expiration date. And it adds a helper function to verify sub key binding signatures and updates the public key export function to only return subkeys that are verifiably bound to the primary key.
Fix unsubscriptable-object error on Python2.7 that occurs due to a dict operation on a variable that gets initialized as None first and then must get re-initialized as dict inside a loop.
The current implementation doesn't parse the expiration dates of keys in the keyring. Add code to parse and verify that keys used within in-toto are not expired.
Enhanced parsing of public key bundles with additional information parsing of key expiration times from signatures to provide master public keys and subkeys with information needed to ensure that no expired keys are used within in-toto. Also added tests to ensure proper key expiration time parsing from signatures and new public key with a set Primary User ID flag for tests.
22793c5
to
7b4ffce
Compare
|
Taken over by #266 |
Please fill in the fields below to submit a pull request. The more information
that is provided, the better.
Fixes issue #236:
Description of the changes being introduced by the pull request:
Implemented new checks to verify key expiration and included it as part of the signature verification process. Added warnings to be issued at time of signing and whenever public keys are extracted. Parsed expiration times at signature creation and included it into format of signature data structure.
Noteworthy:
I used a scheme that involves going through all valid self-signatures of a public key's user ID packets with set key expiration times and taking the key expiration time of the most recent signature to help assign expiration dates to public keys, prioritizing signatures with expiration times that had a Primary User ID flag set. To refine my use cases, I conducted an investigation to determine whether User ID packets having its key expiration time and Primary User ID flag set in different self-signatures was a common occurrence by analyzing public keys and signatures in real world keychains.
I made these preliminary findings regarding relative frequencies of key expiration dates and Primary User ID flags in self-signatures for public keys. Out of 50k signatures and ~1100 User ID packets:
686 self-signatures had a Primary User ID flag set
437 self-signatures had a Primary User ID flag set but no key expiration time (most of these were associated with keys that did not have any set expiration time)
1795 self-signatures had a set key expiration time (249 of which also have a Primary User ID flag set)
11 User ID packets had key expiration time and Primary User ID flag set in different self-signatures
Please verify and check that the pull request fulfills the following
requirements: