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

Implement proper Authenticode signature verification #7

Open
nefarius opened this issue Nov 12, 2023 · 6 comments
Open

Implement proper Authenticode signature verification #7

nefarius opened this issue Nov 12, 2023 · 6 comments
Assignees
Labels
enhancement New feature or request

Comments

@nefarius
Copy link
Owner

nefarius commented Nov 12, 2023

Adding signature validation/verification turned out to be a tougher challenge than a few checkboxes in the README can keep track of, so here we are 😛

There are a couple of issues to solve, primarily: what is considered a valid, trustworthy signature?

The expectation of the user and developer might be as follows: if the distributed updater executable either is signed itself (best case scenario) and the downloaded setup is signed by the same company/publisher, it is considered trusted.

Sounds simple enough in theory, how can that be achieved in practice? First, trusting a signed executable involves multiple parameters. The signature is valid as it has not been tampered with. Has it been signed by a CA the OS considers as trustworthy? How do we reliably identify that CA and the publisher/signer? By names? by serial numbers? By certificate fingerprints?

How do we avoid spoofing; let's say someone imports their own "DigiCert" CA and self-signes with the same publisher name; the OS APIs would consider the signatures valid. Now this is an unlikely scenario; importing additional CAs requires elevated permissions so if that is possible, the user system is considered compromised anyway.

Which parameters of the signature and the certificate chain can't be spoofed easily? Which values can be used for comparison?

To be continued...

@nefarius nefarius added the enhancement New feature or request label Nov 12, 2023
@nefarius nefarius self-assigned this Nov 12, 2023
@fredemmott
Copy link
Contributor

Sounds simple enough in theory, how can that be achieved in practice? First, trusting a signed executable involves multiple parameters. The signature is valid as it has not been tampered with. Has it been signed by a CA the OS considers as trustworthy? How do we reliably identify that CA and the publisher/signer? By names? by serial numbers? By certificate fingerprints?

These are all addressed as a black box with WinVerifyTrust(), e.g. https://github.com/fredemmott/OpenXR-API-Layers-GUI/blob/main/src/linters/windows/UnsignedDllLinter.cpp

This doesn't provide any flexibility though - just "is it valid?" and to a (largely undocumented) extent, 'if not, why not?'.

How do we avoid spoofing; let's say someone imports their own "DigiCert" CA and self-signs with the same publisher name; the OS APIs would consider the signatures valid. Now this is an unlikely scenario; importing additional CAs requires elevated permissions so if that is possible, the user system is considered compromised anyway.

IMO this is completely fine and Microsoft's problem; the CA list should be maintained by Windows Update/Defender and the system/network administrator.

@fredemmott
Copy link
Contributor

Though, compared to my example, for an autoupdater you'd probably want WTD_REVOCATION_CHECK_CHAIN instead of WTD_REVOCATION_CHECK_NONE

@nefarius
Copy link
Owner Author

A few very good points! What's still missing though is how would a user of the solution want to configure it to make sure that the binary that gets downloaded not just has a valid signature but is actually signed by a source considered trusted. After all, some random text editor setup might be signed by a company other than mine but the expectation in Signatur verification wouldn't be that this would be a trusted update, only binaries signed by a certain company certificate or publisher in general should be accepted by the updater, otherwise any random signed binary would be considered trusted.

@fredemmott
Copy link
Contributor

I guess the combination of 'got a cert' and 'got an https cert for the update domain' doesn't work for the totally hypothetical situation of someone else getting your domain via a trademark claim :p

@fredemmott
Copy link
Contributor

The cert/CA chain stuff isn't really designed for that problem - perhaps adopting https://theupdateframework.github.io/specification/latest/ (or the crypto approach from it, or something related) could be the way to go as an alternative, or just simple libsodium-based signatures?

Added bonus is they don't require authors to give money to CAs.

@nefarius
Copy link
Owner Author

nefarius commented Apr 1, 2024

Good points. Something that wouldn't require official expensive CAs would indeed be cool. Rolling your own crypto is doomed to fail so I gotta do more research first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants