How to find WiX RemotePayload's CertificatePublicKey hash
Asked Answered
C

2

12

I'm trying to resolve WiX RemotePayload hashes, but I'm not sure how the CertificatePublicKey attribute is found.

Take, for example, the .NET 4.0 Package definition from WiX 3.6 sources:

  <Fragment>
    <util:RegistrySearchRef Id="NETFRAMEWORK40"/>

    <WixVariable Id="WixMbaPrereqPackageId" Value="NetFx40Redist" />
    <WixVariable Id="WixMbaPrereqLicenseUrl" Value="$(var.NetFx40EulaLink)" />

    <PackageGroup Id="NetFx40Redist">
      <ExePackage
          InstallCommand="/q /norestart /ChainingPackage &quot;[WixBundleName]&quot;"
          RepairCommand="/q /norestart /repair /ChainingPackage &quot;[WixBundleName]&quot;"
          UninstallCommand="/uninstall /q /norestart /ChainingPackage &quot;[WixBundleName]&quot;"
          PerMachine="yes"
          DetectCondition="NETFRAMEWORK40"
          Id="NetFx40Redist"
          Vital="yes"
          Permanent="yes"
          Protocol="netfx4"
          DownloadUrl="$(var.NetFx40RedistLink)"
          Compressed="no"
          Name="redist\dotNetFx40_Full_x86_x64.exe">
        <RemotePayload
            Size="50449456"
            Version="4.0.30319.1"
            ProductName="Microsoft .NET Framework 4"
            Description="Microsoft .NET Framework 4 Setup"
            CertificatePublicKey="672605E36DD71EC6B8325B91C5FE6971390CB6B6"
            CertificateThumbprint="9617094A1CFB59AE7C1F7DFDB6739E4E7C40508F"
            Hash="58DA3D74DB353AAD03588CBB5CEA8234166D8B99"/>
      </ExePackage>
    </PackageGroup>
  </Fragment>

From wix36-sources\src\ext\NetFxExtension\wixlib\NetFx4.wxs

I can find the sha1 Hash with fciv -sha1 dotNetFx40_Full_x86_x64.exe...

58da3d74db353aad03588cbb5cea8234166d8b99 dotnetfx40_full_x86_x64.exe

I can find a matching CertificateThumbprint easily through the properties dialog for the file, or using signtool which displays the following output

C:\redist>signtool verify /v /ph dotNetFx40_Full_x86_x64.exe

Verifying: dotNetFx40_Full_x86_x64.exe
Signature Index: 0 (Primary Signature)
Hash of file (sha1): 8E8582D10521962F45F33935C38A2412C4F2D4C7

Signing Certificate Chain:
    Issued to: Microsoft Root Authority
    Issued by: Microsoft Root Authority
    Expires:   Thu Dec 31 03:00:00 2020
    SHA1 hash: A43489159A520F0D93D032CCAF37E7FE20A8B419

        Issued to: Microsoft Code Signing PCA
        Issued by: Microsoft Root Authority
        Expires:   Sat Aug 25 03:00:00 2012
        SHA1 hash: 3036E3B25B88A55B86FC90E6E9EAAD5081445166

            Issued to: Microsoft Corporation
            Issued by: Microsoft Code Signing PCA
            Expires:   Mon Mar 07 18:40:29 2011
            SHA1 hash: 9617094A1CFB59AE7C1F7DFDB6739E4E7C40508F

The signature is timestamped: Thu Mar 18 21:13:46 2010
Timestamp Verified by:
    Issued to: Microsoft Root Authority
    Issued by: Microsoft Root Authority
    Expires:   Thu Dec 31 03:00:00 2020
    SHA1 hash: A43489159A520F0D93D032CCAF37E7FE20A8B419

        Issued to: Microsoft Timestamping PCA
        Issued by: Microsoft Root Authority
        Expires:   Sun Sep 15 03:00:00 2019
        SHA1 hash: 3EA99A60058275E0ED83B892A909449F8C33B245

            Issued to: Microsoft Time-Stamp Service
            Issued by: Microsoft Timestamping PCA
            Expires:   Thu Jul 25 15:11:15 2013
            SHA1 hash: 4D6F357F0E6434DA97B1AFC540FB6FDD0E85A89F

SignTool Error: The signing certificate is not valid for the requested usage.
        This error sometimes means that you are using the wrong verification
        policy. Consider using the /pa option.

Number of files successfully Verified: 0
Number of warnings: 0
Number of errors: 1

What tool can provide the hash for CertificatePublicKey?

edit: Without using heat, I want to understand where the hashes come from.

edit: I'm aware of how this is done in WiX source code and that I can execute
heat payload file -out file.wxs, but I'm looking for some external tool which can provide the expected hash(es) without using heat. This is really only to sate my curiosity.

Chokebore answered 18/9, 2012 at 15:41 Comment(3)
Where is the CertificateThumbprint in the above?Heidyheifer
@Heidyheifer it is the last SHA1 hash for the Signing Certificate Chain.Chokebore
WIX4 requires SHA-512 hash, how to generate it?Oracle
M
19

If you take a look at the sourcecode of the heat tool it uses the Microsoft.Tools.WindowsInstallerXml.Cab.Interop.NativeMethods.HashPublicKeyInfo function to generate the CertificatePublicKey.

byte[] publicKeyIdentifierHash = new byte[128];
uint publicKeyIdentifierHashSize = (uint)publicKeyIdentifierHash.Length;

Microsoft.Tools.WindowsInstallerXml.Cab.Interop.NativeMethods.HashPublicKeyInfo(
    certificate.Handle, 
    publicKeyIdentifierHash, 
    ref publicKeyIdentifierHashSize);

StringBuilder sb = new StringBuilder(((int)publicKeyIdentifierHashSize + 1) * 2);
for (int i = 0; i < publicKeyIdentifierHashSize; ++i)
{
    sb.AppendFormat("{0:X2}", publicKeyIdentifierHash[i]);
}

this.PublicKey = sb.ToString();

You can obviously use this code to generate the thumbprint or according to the wiki page on Public Key fingerprints you can also use the commandline

ssh-keygen -lf /path/to/key.pub

The problem is generating a ssh-keygen pub file that complies with RFC4716 from the certificate and this is where I was stumped.

Personally I just use the heat command-line:

heat.exe payload PATH_TO_FILE -o Output.wxs

and not worry about what it is actually doing as it works!! :)

Mandi answered 19/9, 2012 at 10:15 Comment(3)
I'm using heat now, but I'm looking for a way to get CertificatePublicKey externally from WiX itself. Also, ssh-keygen will generate a PublicKey, but I want to find a way to read the PublicKey from an Authenticode-signed executable in a way that matches the output from the NativeMethods used in heat.Chokebore
I've accepted your answer because you posted the code used by WiX. I've still not been able to find any tool other than heat which would provide the same hash, and that's what I was looking for. Since it looks like there's no such external application, your answer is as good as it gets.Chokebore
heat.exe payload PATH_TO_FILE -o Output.wxs is the golden-child, here. Thank you very much!Computerize
T
1

You can find all the information about a signature in the file properties dialog:

  1. In the file properties dialog, click the signature tab. File properties

  2. Click details, then click 'View Certificate'. View Certificate

  3. Properties like 'Public Key' can be found on the 'Details' tab. Certificate Details

  4. If you need a hash of this Public Key, then you can use your standard hashing tools to get it by using the 'Copy to File' button and hashing that file.

    I was incorrect, the 'Copy to File' does not export the selected property, but instead the whole certificate. You can copy and paste this value into a hash program or a hex editor to get the hash though.

Turnout answered 8/10, 2012 at 17:8 Comment(3)
What you've provided here doesn't give any more details than what I've already shown in my question. Your last step would get the SHA1 hash of the certificate file, not of the public key itself. I've also run through numerous options here but can't seem to find the correct options to generate 672605E36DD71EC6B8325B91C5FE6971390CB6B6, which is what I'm looking for.Chokebore
@JimSchubert, You are correct. I thought it was just a hash of the public key but it is not. I believe it is the hash from CryptHashPublicKeyInfo which includes an ID for the type of Key.Turnout
Thanks. WiX is open source, so I could pull the code (which caveman_dick has posted) and write a utility. I'm really more interested in how to obtain this hash via some external utility outside of heat which generates the payload with the desired hash. This is more for academic curiosity (and perhaps documentation for other devs on my team).Chokebore

© 2022 - 2024 — McMap. All rights reserved.