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

Breaking change in beevik/etree & RFC3161 support for ClickOnce #4

Merged
merged 2 commits into from
Apr 9, 2019

Conversation

siliconsheep
Copy link

Hey!

There's been a breaking change in beevik/etree (https://github.com/beevik/etree/releases/tag/v1.0.1), causing the paths starting with "//" to be interpreted as an absolute path. This caused a wrong DigestValue to be picked. Changed that now to ".//DigestValue" so it picks the DigestValue in the Authenticode Signature block as intented.

Microsoft has also moved on to using RFC3161 timestamping servers for their ClickOnce manifests, so requesting an RFC3161 timestamp for those tasks. This does break the verification somehow (probably because that was only applicable to the non-RFC3161 requests), so replaced that with a warning for now. The resulting signed manifests are properly signed and timestamped though.

If you can give me a few pointers on how to verify those timestamps properly, I'll make sure to address that as well!

… Added RFC3161 support for ClickOnce manifests
@mtharp
Copy link
Contributor

mtharp commented Mar 25, 2019

Hi! Thank you very much for doing the legwork on identifying the etree issue.

I think you might be right about the RFC 3161 change, as I was able to install an application signed this way. But I can't tell whether the timestamp was actually checked and used, and I'm also not sure when this functionality became available so it's possible there are older platforms I might still need to support, so I'd like to have a flag to revert to the legacy timestamp as needed. You can see signers/pecoff/signer.go for an example of how to do that.

As for why verifying is failing, it's because the legacy timestamp is a signature over just the encrypted digest while the RFC 3161 type is a signature over a timestamp structure. In order to be able to verify both, something like this would work:

var OidTSTInfo = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 4} // in lib/pkcs9/structs.go
if timestamp.Content.ContentInfo.ContentType.Equal(pkcs9.OidTSTInfo) {
    // pkcs9 timestamp
    cs, err = pkcs9.Verify(timestamp, encryptedDigest, extraCerts)
} else {
    // legacy timestamp
    cs, err = pkcs9.VerifyMicrosoftToken(timestamp, encryptedDigest)
}

If you pull that out into its own private function, then both the signing self-check and the standalone verifier in lib/appmanifest/verify.go can use it.

Thank you!

@siliconsheep
Copy link
Author

siliconsheep commented Mar 27, 2019 via email

@siliconsheep
Copy link
Author

Hey Michael,

Thanks again for your inputs! I've added a flag to choose the timestamping model, as well as fixed the verification properly this time.

Tested with a manifest file, it got signed and verified perfectly. I wanted to test the legacy method as well, but couldn't find a legacy timestamping server that still worked. As that code was untouched, that should still work though.

Let me know if anything else needs to be updated!

//Dieter

@mtharp mtharp merged commit a0ac69f into sassoftware:master Apr 9, 2019
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 this pull request may close these issues.

2 participants