dotnet / sign

Code Signing CLI tool supporting Authenticode, NuGet, VSIX, and ClickOnce
MIT License
439 stars 84 forks source link

Add option to download/export certificates from Trusted Signing #734

Open mjcheetham opened 4 days ago

mjcheetham commented 4 days ago

Add a new option --certificate-export-path to the code trusted-signing command that allows users to export the certificate used to sign from the Trusted Signing service to a file on disk. This is particularly useful for users who need a copy of the latest Trusted Signing certificate to upload to a third-party service such as NuGet.org to allow verification of the signed packages that are published there.

This pull request is organised in two commits that can be reviewed individually and are as follows:

  1. Add (I)Exporter that can export a certificate to a file on disk from a certificate provider.

  2. Add an export certificate option to the code-signing command for Trusted Signing.

Open questions

Alternative implementations

dlemstra commented 2 days ago

I am not sure if this should be added to this application. In the future nuget.org will probably look at the Subscriber identity validation EKU inside the certificate (https://github.com/NuGet/NuGetGallery/issues/10027).

But I also understand that you need some method to get the certificate from the signed file because it rotates so often. With a NuGet package you could get the certificate by unzipping the file and use openssl to extract it from .signature.p7s. But that is probably not something you would want everybody to do themselves. But I am also not sure that adding an export functionality to this application is the best solution to solve your problem,

I also don't think you can update the certificate through automation on a NuGet account so this still requires some manual work. A user could also use the NuGet package explorer to get the certificate and then upload the package, This is what I am now doing myself. Another option would be something like https://www.nuget.org/packages/Knapcode.CertificateExtractor#readme-body-tab if you want to do this in a pipeline.

p.s. I noticed in your referenced commit that you are still specifying -d and -u but you are no longer required to do that.

p.s. After writing my response I realized that I misunderstood your PR description and I have update this post. Sorry about the confusing earlier messages.

joelverhagen commented 2 days ago

(btw, I am not a decision maker for Sign CLI, just an interested team member)

I agree with @dlemstra. I feel your pain here. I ran into this problem when using Trusted Signing + Sign CLI + GitHub Actions. The solution I took was writing my own CLI tool which runs after Sign CLI in GitHub Actions and extract the .cer file and includes it in the artifacts. Then I manually upload the .cer file and .nupkg to NuGet.org via the web UI.

Here is a sample: https://github.com/joelverhagen/PackageLifeCycle/blob/7930b64f7e72518faf6b646187b47b46e2d64d22/.github/workflows/build.yml#L76-L87

This is not ideal but I think this is a point-in-time problem due to https://github.com/NuGet/NuGetGallery/issues/10027.

IMHO interacting with the .cer with Trusted Signing is a bit of a "code smell". It suggests the scenario you're in does NOT support Trusted Signing EKU pinning somewhere and therefore is not resilient to the short-lived .cer files. This is of course the situation with NuGet.org but again I think the fix there is to push the service to support Trusted Signing instead of hacking in support with .cer files.

Unless there is another strong case for .cer retrieval, then I hesitate to make it a part of Sign CLI, which would then need to be supported long after NuGet.org supports proper Trusted Signing pinning based on EKU. I wonder if there is another scenario you have in mind where you really need the .cer?