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

test_pe_cert_trust fails after 2024-07-28 #1300

Closed
bmwiedemann opened this issue Jul 3, 2024 · 5 comments · Fixed by #1305
Closed

test_pe_cert_trust fails after 2024-07-28 #1300

bmwiedemann opened this issue Jul 3, 2024 · 5 comments · Fixed by #1305

Comments

@bmwiedemann
Copy link

While working on reproducible builds for openSUSE (sponsored by the NLnet NGI0 fund), I found that
our clamav 1.3.1 package fails a test after 2024-07-28.

How to reproduce the problem

run the tests with the clock set to 2024-07-29, e.g. on openSUSE I do

osc checkout openSUSE:Factory/clamav && cd $_
osc build --vm-type=kvm --noservice --clean --build-opt=--vm-custom-opt="-rtc base=2024-07-29T00:00:00" standard

Attachments

FAILED clamscan/assorted_test.py::TC::test_pe_cert_trust - AssertionError: as...

Background:
As part of my work on reproducible builds for openSUSE, I check that software still gives identical build results in the future.
The usual offset is +16 years, because that is how long I expect some software will be used in some places.
This showed up failing tests in our package build.
See https://reproducible-builds.org/ for why this matters.

@Kangie
Copy link
Contributor

Kangie commented Jul 9, 2024

Let's see.

self.step_name('Test that clam can trust an EXE based on an authenticode certificate check.')

Your test output is truncated, but looking at the test I assume we're failing to validate the certificate because it's not valid in 15 years.

The test.exe that this function evaluates is checked into the repo here: https://github.com/Cisco-Talos/clamav/blob/main/unit_tests/input/pe_allmatch/test.exe

I suspect that getting a signed bin that's valid for 15 years is likely to be more trouble than you excluding this test for reproducible builds :)

@micahsnyder is there any context that you can share around this?

n.b. I'm sure that you will uncover many legitimate bugs through this process, and please don't let me discourage you, but I feel like any users still running current versions of ClamAV in 15+ years have bigger problems than this given the lack of signature updates (etc).

@bmwiedemann
Copy link
Author

bmwiedemann commented Jul 9, 2024

The certificate likely expires in 3 weeks, so something needs to be done about it soon anyway.

In other projects, we use a CA/certs that expire in 1000y. Or does it have to be signed by some official authority? Maybe there is a way to use a custom test-CA for that test? Or a way to use a custom "current" date?

@Kangie
Copy link
Contributor

Kangie commented Jul 9, 2024

The certificate likely expires in 3 weeks, so something needs to be done about it soon anyway.

Oops, I did miss that!

@micahsnyder
Copy link
Contributor

I think I found the -days openssl options responsible for the short-lived cert: https://github.com/Cisco-Talos/clamav/blob/main/unit_tests/input/pe_allmatch/test-exe-src/build.py#L122-L139

I also managed to track down the code which generated the signatures used in our tests.
I'll see if I can modify this and then generate a new test executable and associated signatures so that the certificate won't expire so quickly.

micahsnyder added a commit to micahsnyder/clamav-micah that referenced this issue Jul 10, 2024
The clamscan test "assorted_test.py::TC::test_pe_cert_trust" is about to
fail because the "test.exe" test file was signed with a cert set to
expire after only 2 years, and it has been 23 months.

While attempting to generate a new one that will last 73000 days (200
years), I discovered that any signing certificate set to expire after
2038 will fail the trust-check because the `ca.not_after` variable is
maxed out `time_t` incapable of expressing a higher number.
To fix this, I've upgraded the variables to `uint64_t`.

I also had to replace a bunch of generated signatures to match the new
"test.exe".

Finally, I noticed that "ca.not_before" was being set to the token[8]
instead of token[9], which presumably mean the "NotBefore" field for
Trusted and Revoked Certificates was non-functional, as it was treating
the "CertSign" boolean as the "NotBefore" value.

Fixes: Cisco-Talos#1300
@micahsnyder
Copy link
Contributor

@bmwiedemann @Kangie I have a fix for this. Can you take a look and tell me if you think it makes sense?

micahsnyder added a commit to micahsnyder/clamav-micah that referenced this issue Jul 11, 2024
The clamscan test "assorted_test.py::TC::test_pe_cert_trust" is about to
fail because the "test.exe" test file was signed with a cert set to
expire after only 2 years, and it has been 23 months.

While attempting to generate a new one that will last 73000 days (200
years), I discovered that any signing certificate set to expire after
2038 will fail the trust-check because the `ca.not_after` variable is
maxed out `time_t` incapable of expressing a higher number.
To fix this, I've upgraded the variables to `uint64_t`.

I also had to replace a bunch of generated signatures to match the new
"test.exe".

Finally, I noticed that "ca.not_before" was being set to the token[8]
instead of token[9], which presumably mean the "NotBefore" field for
Trusted and Revoked Certificates was non-functional, as it was treating
the "CertSign" boolean as the "NotBefore" value.

Fixes: Cisco-Talos#1300
@micahsnyder micahsnyder pinned this issue Aug 13, 2024
micahsnyder added a commit to micahsnyder/clamav-micah that referenced this issue Aug 13, 2024
The clamscan test "assorted_test.py::TC::test_pe_cert_trust" is about to
fail because the "test.exe" test file was signed with a cert set to
expire after only 2 years, and it has been 23 months.

While attempting to generate a new one that will last 73000 days (200
years), I discovered that any signing certificate set to expire after
2038 will fail the trust-check because the `ca.not_after` variable is
maxed out `time_t` incapable of expressing a higher number.
To fix this, I've upgraded the variables to `uint64_t`.

I also had to replace a bunch of generated signatures to match the new
"test.exe".

Finally, I noticed that "ca.not_before" was being set to the token[8]
instead of token[9], which presumably mean the "NotBefore" field for
Trusted and Revoked Certificates was non-functional, as it was treating
the "CertSign" boolean as the "NotBefore" value.

Fixes: Cisco-Talos#1300
micahsnyder added a commit to micahsnyder/clamav-micah that referenced this issue Aug 13, 2024
The clamscan test "assorted_test.py::TC::test_pe_cert_trust" is about to
fail because the "test.exe" test file was signed with a cert set to
expire after only 2 years, and it has been 23 months.

While attempting to generate a new one that will last 73000 days (200
years), I discovered that any signing certificate set to expire after
2038 will fail the trust-check because the `ca.not_after` variable is
maxed out `time_t` incapable of expressing a higher number.
To fix this, I've upgraded the variables to `uint64_t`.

I also had to replace a bunch of generated signatures to match the new
"test.exe".

Finally, I noticed that "ca.not_before" was being set to the token[8]
instead of token[9], which presumably mean the "NotBefore" field for
Trusted and Revoked Certificates was non-functional, as it was treating
the "CertSign" boolean as the "NotBefore" value.

Fixes: Cisco-Talos#1300
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 a pull request may close this issue.

3 participants