Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion Documentation/CorePackages/PostBuildSigning.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,43 @@ If PostBuildSign==true then no other steps are needed, post-build signing is ena

Steps to ensure that post-build signing is correctly set up for a repo: A manifest file is created as part of the build process, it can be found in AssetManifests/Manifest.xml. This file lists everything that will be signed once the build is complete. If this file has been created and the contents of the ItemsToSign section match the expected set of signed files for the build then no further action is needed.

## Post Build Signing Technical Details

When performing normal in-build signing, the build process generates a list of files to sign (e.g. nupkg files, dlls, msi's, etc.) during the build process. These are combined with information about what certificates to use for each file type or specific file name (located in Sign.props) and fed to SignTool. SignTool processes the input files and performs signing via ESRP, replacing the input files in place with the signed versions. Depending on the build scenario, SignTool may be called multiple times within a build to iteratively build up some archives. For instance, it may be called on individual dlls which are then packaged into an msi, which is then passed SignTool.
Comment thread
mmitche marked this conversation as resolved.
Outdated

Performing post build signing is more involved. The drop that is to be signed is comprised of the outputs of many repos. Some of those outputs may already be signed, some of those outputs may have been repackaged within the outputs of other builds, etc. Thus, most of the effort in post build signing is related to two aspects of the process:
- **Deconstructing (and reconstructing) archives** - With in-build signing, SignTool knew how to deconstruct zip and nupkg archives. These could simply be unzipped, their contents replaced in-line, then zipped back up. Post build signing requires dealing with msi installers too. These are not as amenable to changes to contents (e.g. the msi database encodes file lengths, which change with signing).
- **Tracking the source of all the files** - Let's say dotnet/runtime notes that apphost.exe should not be signed, then the installer repackages that binary in a zip file. When post-build signing runs, it needs to be able to identify that apphost.exe, which appears to be located within an installer produced zip file, actually came from runtime and thus should not be signed.

Post build signing deals with this by recording sidecar information about at build time, then gathering the closure of that info when post build signing runs. The additional information includes the following:
Comment thread
mmitche marked this conversation as resolved.
Outdated
- Archives that can be used to reconstruct installers produced by a build.
- Manifest files which describe the signing data for a build (e.g. items to sign and file extension -> certificate mappings)

The process works as follows:
1. Gather a drop of a build that needs to be signed, including all un-released inputs builds.
Comment thread
mmitche marked this conversation as resolved.
Outdated
2. Locate all build manifests (containing signing information for each input build)
3. Build a list of all files to sign (files to sign should be found in the drop), and the specific certificate info required for those files/extensions (and any files within containers). Each input item to sign is associated with the certificate info present in the same build.
4. Pass this data to SignTool
5. In SignTool:
1. Walk each item to sign. If the item is an archive, unpack it and begin to process the contained files.
2. After a file is unpacked (if necessary), determine what signing cert and/or strong name it should get (if any). Add info to a map of filename+hash of file -> info.
3. Continue until all files are unpacked.
4. Starting at the most nested set of files, create a Microbuild compatible project file and submit for signing.
5. Repack those files into their enclosing containers, if any.
6. Repeat, moving upwards in the tree of files to sign until all files have been repacked.
6. Upload files to storage (feeds and blob storage).

### Determining certificates

The crux of the SignTool algorithm is determining the certificate for a specific file. *Side note: Certificates are associated with a specific file name or file extension, though they cannot be associated with a specific path. For instance, 'foo/bar/baz.zip' is only dealt with as 'baz.zip'*. When dealing with a single repo, SignTool just interprets the signing info as applying to all files passed to it. A baz.zip found anywhere in the input file set is treated identically. When dealing with post build signing, it's possible that a foo.dll found in an sdk asset may actually from the runtime, which may have indicated that *.dll get a different certificate. *So SignTool needs to track where foo.dll originally came from*. Did it come from the build of dotnet/runtime, or from dotnet/sdk? To do this, SignTool associates each input top level item to sign and the signing info for a build with a 'collision priority ID' This collision priority ID serves as a way to disambiguate the source signing information for a nested artifact. As each top-level asset is unpacked, the hash of each nested file is determined and looked up in a map. If the map already contains a file with the same name and hash, the collision priority ID's are compared. If the current one in the map is lower, the signing info for the existing file is used. Otherwise, the certificate information is recomputed based on the lower collision priority ID.
Comment thread
mmitche marked this conversation as resolved.
Outdated

## Additional Information

More information about the file types that are signed and the certificates used to sign them can be found here:
https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props

Additional information about the publishing process in general can be found here:
https://github.com/dotnet/arcade/blob/master/Documentation/CorePackages/Publishing.md

Additional information about the legacy signing process can be found here:
Additional information about the in-build signing process can be found here:
https://github.com/dotnet/arcade/blob/master/Documentation/CorePackages/Signing.md