SignTool Check equivalent of .application and .manifest files?
I am using signtool.exe v6.2.9200.20527 to support / tr and / td. In the following examples, 0961 ... 35d2 is the SHA1 fingerprint of the SHA256 code signing certificate in the user's current personal certificate store.
Example 1: Signing code using SHA256 digest, no time stamp.
c:signtool.exe sign /fd sha256 /sha1 0961...35d2 CertificateCheck.exe
c:signtool.exe verify /all /pa CertificateCheck.exe
File: CertificateCheck.exe
Index Algorithm Timestamp
========================================
0 sha256 None
Successfully verified: CertificateCheck.exe
Example 2: Signing code with SHA1 digest without time stamp.
c:signtool.exe sign /fd sha1 /sha1 0961...35d2 CertificateCheck.exe
c:signtool.exe verify /all /pa CertificateCheck.exe
File: CertificateCheck.exe
Index Algorithm Timestamp
========================================
0 sha1 None
Successfully verified: CertificateCheck.exe
Example 3: Duplicate subscription with SHA256 digest and SHA1 digest and time stamp.
c:signtool.exe sign /fd sha256 /sha1 0961...35d2 /tr http://timestamp.globalsign.com/scripts/timstamp.dll /td sha256 CertificateCheck.exe
c:signtool.exe sign /as /fd sha1 /sha1 0961...35d2 /tr http://timestamp.globalsign.com/scripts/timstamp.dll /td sha1 CertificateCheck.exe
c:signtool.exe verify /all /pa CertificateCheck.exe
File: CertificateCheck.exe
Index Algorithm Timestamp
========================================
0 sha256 RFC3161
1 sha1 RFC3161
By using the signtool verify / v function, I can also view the certificate details and the certificate trust chain ...
c:signtool.exe verify /all /pa /v CertificateCheck.exe
Verifying: CertificateCheck.exe
Signature Index: 0 (Primary Signature)
Hash of file (sha256): 6774...B2D1
Signing Certificate Chain:
Issued to: GlobalSign
Issued by: GlobalSign
Expires: Sun Mar 18 20:00:00 2029
SHA1 hash: D69B...76AD
Issued to: GlobalSign CodeSigning CA - SHA256 - G2
Issued by: GlobalSign
Expires: Fri Aug 02 20:00:00 2019
SHA1 hash: 4E34...36FF
Issued to: Example Company Pty Ltd
Issued by: GlobalSign CodeSigning CA - SHA256 - G2
Expires: Fri May 11 02:17:24 2018
SHA1 hash: 0961...35D2
The signature is timestamped: Wed May 06 13:51:05 2015
Timestamp Verified by:
Issued to: GlobalSign Root CA
Issued by: GlobalSign Root CA
Expires: Fri Jan 28 22:00:00 2028
SHA1 hash: B1BC...829C
Issued to: GlobalSign Timestamping CA - G2
Issued by: GlobalSign Root CA
Expires: Fri Jan 28 22:00:00 2028
SHA1 hash: C0E4...5B71
Issued to: GlobalSign TSA for Standard - G2
Issued by: GlobalSign Timestamping CA - G2
Expires: Tue Mar 03 10:00:00 2026
SHA1 hash: 19E1...65B6
Signature Index: 1
Hash of file (sha1): CFA4...7863
Signing Certificate Chain:
Issued to: GlobalSign
Issued by: GlobalSign
Expires: Sun Mar 18 20:00:00 2029
SHA1 hash: D69B...76AD
Issued to: GlobalSign CodeSigning CA - SHA256 - G2
Issued by: GlobalSign
Expires: Fri Aug 02 20:00:00 2019
SHA1 hash: 4E34...36FF
Issued to: Example Company Pty Ltd
Issued by: GlobalSign CodeSigning CA - SHA256 - G2
Expires: Fri May 11 02:17:24 2018
SHA1 hash: 0961...35D2
The signature is timestamped: Wed May 06 13:51:06 2015
Timestamp Verified by:
Issued to: GlobalSign Root CA
Issued by: GlobalSign Root CA
Expires: Fri Jan 28 22:00:00 2028
SHA1 hash: B1BC...829C
Issued to: GlobalSign Timestamping CA - G2
Issued by: GlobalSign Root CA
Expires: Fri Jan 28 22:00:00 2028
SHA1 hash: C0E4...5B71
Issued to: GlobalSign TSA for Standard - G2
Issued by: GlobalSign Timestamping CA - G2
Expires: Tue Mar 03 10:00:00 2026
SHA1 hash: 19E1...65B6
Successfully verified: CertificateCheck.exe
Number of signatures successfully Verified: 2
Number of warnings: 0
Number of errors: 0
We also double-sign our ClickOnce .Application and .manifest files using a combination of Mage.exe and SignTool.exe, but SignTool Verify doesn't seem to work with .application and .manifest files:
c:signtool.exe verify /all /pa /v CertificateCheck.application
Verifying: CertificateCheck.application
SignTool Error: This file format cannot be verified because it is not recognized.
Number of signatures successfully Verified: 0
Number of warnings: 0
Number of errors: 1
c:signtool.exe verify /all /pa /v CertificateCheck.exe.manifest
Verifying: CertificateCheck.exe.manifest
SignTool Error: This file format cannot be verified because it is not recognized.
Number of signatures successfully Verified: 0
Number of warnings: 0
Number of errors: 1
We can open the .manifest and .application files in an XML compatible editor to see that the base64 encoded signatures are actually added, but is there a SignTool Verify equivalent that allows me to see the signatures and / or certificate of the trusted chains attached to the command line ? Or am I just wrong? I would like to do this so that we can add a test step to our build scripts.
Additional Information...
Ok this seems to be a version related issue.
I've put together several different versions of SignTool to try different things. The V5 series had different Verify / manifest switches, while none of the v6 series I encountered did. On the other hand, the v6 series support SHA2 certificates and algorithms, while the v5 series doesn't really like them.
Using signtool.exe v5.2.3790.2568 I can check the strong name (app id) like this:
signtool verify /manifest /snonly /v CertificateChecker.application
Successfully verified: CertificateChecker.application
Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0
But if I try to show the certificate trust chain (and there is a SHA256 certificate in there), it throws an error:
signtool verify /manifest /pa /v CertificateChecker.application
SignTool Error: CryptVerifyManifestFile returned error: 0x800B0004
The subject is not trusted for the specified action.
Signing Certificate Chain:
Issued to: GlobalSign
Issued by: GlobalSign
Expires: 2029-03-18 8:00:00 PM
SHA1 hash: D69B...76AD
Issued to: GlobalSign CodeSigning CA - SHA256 - G2
Issued by: GlobalSign
Expires: 2019-08-02 8:00:00 PM
SHA1 hash: 4E34...A36FF
Issued to: Example Pty Ltd
Issued by: GlobalSign CodeSigning CA - SHA256 - G2
Expires: 2018-05-11 2:17:24 AM
SHA1 hash: 0961...A35D2
File is not timestamped.
SignTool Error: File not valid: CertificateChecker.application
Number of files successfully Verified: 0
Number of warnings: 0
Number of errors: 1
So I'm left with a variation on my original question: is there a SignTool Verify replacement for ClickOnce.application and .manifest files ... and does it support SHA256?
source to share
mage.exe
Manifest creation and editing tool
mage -s CertificateCheck.application
I don't know how to check the CLI yet.
source to share
Use this code to validate ClickOnce manifest:
// based on tip from http://www.pcreview.co.uk/threads/tool-for-clickonce-maifest-and-application-signature-validation.3308405/#post-11299058
private static ManifestSignatureInformationCollection GetClickOnceManifestSignature(string manifestPath)
{
bool isApplicationManifest;
if (manifestPath.EndsWith(".exe.manifest"))
{
isApplicationManifest = true;
}
else if (manifestPath.EndsWith(".application"))
{
isApplicationManifest = false;
}
else
{
throw new InvalidOperationException("Unrecognized manifest type, expected either application manifest (.exe.manifest) or deployment manifest (.application)");
}
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("asmv1", "urn:schemas-microsoft-com:asm.v1");
XElement assemblyIdentityXml = XDocument.Load(manifestPath).XPathSelectElement("/asmv1:assembly/asmv1:assemblyIdentity", namespaceManager);
string applicationIdentityPart = string.Format(
"{0}, Version={1}, Culture={2}, PublicKeyToken={3}, processorArchitecture={4}",
assemblyIdentityXml.Attribute("name").Value,
assemblyIdentityXml.Attribute("version").Value,
assemblyIdentityXml.Attribute("language").Value,
assemblyIdentityXml.Attribute("publicKeyToken").Value,
assemblyIdentityXml.Attribute("processorArchitecture").Value);
if (isApplicationManifest)
{
applicationIdentityPart += ", type=" + assemblyIdentityXml.Attribute("type").Value;
}
return ManifestSignatureInformation.VerifySignature(
ActivationContext.CreatePartialActivationContext(new ApplicationIdentity(applicationIdentityPart + "/" + applicationIdentityPart),
new[] { manifestPath, manifestPath }),
isApplicationManifest ? ManifestKinds.Application : ManifestKinds.Deployment);
}
private static void Main(string[] args)
{
ManifestSignatureInformationCollection resultDeployment = GetClickOnceManifestSignature(@"path\to\DeploymentManifest.application");
ManifestSignatureInformationCollection resultApplication = GetClickOnceManifestSignature(@"path\to\ApplicationManifest.exe.manifest");
Console.WriteLine("Deployment manifest is trusted: ");
Console.WriteLine(resultDeployment[0].AuthenticodeSignature.TrustStatus == TrustStatus.KnownIdentity || resultDeployment[0].AuthenticodeSignature.TrustStatus == TrustStatus.Trusted);
Console.WriteLine("Application manifest is trusted: ");
Console.WriteLine(resultApplication[0].AuthenticodeSignature.TrustStatus == TrustStatus.KnownIdentity || resultApplication[0].AuthenticodeSignature.TrustStatus == TrustStatus.Trusted);
}
source to share
Not that I know. Microsoft's idiocy still hits me sometimes.
The old signtool.exes does not support SHA256. Newer versions do, but don't support manifest signing (why the heck did M $ remove this functionality ?!). mage.exe does not support HSM certificate servers if you do not know the private key (which is the purpose of using such servers to secure certificates). This is really amazing.
source to share