tdhintz
Active participant

Codesigning using SHA-2, SHA256

InstallShield appears to use the default SHA-1 when signing. How is this set to the newer standard? I don't see the digest type listed in the signing options. Signtool.exe supports /fd SHA256, for example.

I read somewhere that Microsoft stops support for SHA-1 on January 1, 2016.
Labels (1)
0 Kudos
22 Replies
MichaelU
Flexera
Flexera

We don't offer this out of the box today, but are tracking a feature request for adding it as IOJ-1700927. If you can find the source for SHA-1 being unsupported, I can add that to our report as supporting evidence to prioritize this feature.

If you need this kind of signature immediately, you can either sign files yourself at a later point, or create a wrapper for signtool.exe that intercepts the command line arguments we pass to \System\signtool.exe and does something else instead.
0 Kudos
tdhintz
Active participant

Microsoft defined their policy in 2013 as described in the following link:

http://blogs.technet.com/b/pki/archive/2013/11/12/sha1-deprecation-policy.aspx

Specifically:

"Code Signing Certificates

For code signing certificates, Windows will stop accepting SHA1 code signing certificates without time stamps after 1 January 2016. SHA1 code signing certificates that are time stamped before 1 January 2016 will be accepted until such time when Microsoft decides SHA1 is vulnerable to pre-image attack."

It isn't clear to me exactly what Microsoft's policy where code signing is concerned but their intent is clear enough: stop using SHA-1 if you can. The bottom line is that SHA-1 is weak so its use is deprecated wherever possible.

0 Kudos
tdhintz
Active participant

This additional commentary on Microsoft's SHA-1 policy.

https://www.schneier.com/blog/archives/2013/11/microsoft_retir.html

0 Kudos
MichaelU
Flexera
Flexera

Thanks much for the links; they provide pretty strong rationale to add official support ASAP. Unfortunately I can't make any guarantees when "ASAP" means, but I'll be pushing for adding it to our next major release.
0 Kudos
rassmm
Pilgrim

MichaelU wrote:
We don't offer this out of the box today, but are tracking a feature request for adding it as IOJ-1700927. If you can find the source for SHA-1 being unsupported, I can add that to our report as supporting evidence to prioritize this feature.

If you need this kind of signature immediately, you can either sign files yourself at a later point, or create a wrapper for signtool.exe that intercepts the command line arguments we pass to \System\signtool.exe and does something else instead.


I have a wrapper for this that works---allowing me to SHA256 sign---that I'm willing to post.... but I can't get the codesigning of the MSI file to work at all without the wrapper! I can sign the EXE/DLLs, I can sign the final setup exe, but anytime I turn on MSI signing (ie by itself, or with the MSI+EXE option) I get


ISDEV : error -6003: An error occurred streaming 'C:\C...\PROJECT_ASSISTANT\SINGLE_EXE_IMAGE\DiskImages\DISK1\XXX.isc' into setup.exe
ISDEV : error -6003: An error occurred streaming 'C:\...\PROJECT_ASSISTANT\SINGLE_EXE_IMAGE\DiskImages\DISK1\XXX.msi' into setup.exe


Again, this is just with the stock unmodified product. I concede I'm using IS2011, but I expect base functionality like this to work. Antivirus is off. It's not exactly an incentive to upgrade knowing that SHA256 isn't addressed.

Are there known issues in the signing? Any way to get the msi, sign it separately, then generate the final EXE? Thanks.
0 Kudos
rassmm
Pilgrim

Working SHA-2/SHA256 signtool wrapper --- special purpose for use in InstallShield. Can SHA-2 sign exes, dlls, msis. Signing problem I had was due to Microsoft's 2949927 update, uninstall that!


[CODE]#include
#include
#include

// Mock signtool.exe to replace
// C:\program files (x86)\Installshield\2011\System\signtool.exe (or equivalent)
// allowing you to supply better arguments than InstallShield allows
// Limited functionality, just for use by InstallShield
//
// To compile:
// Open command line window
// Set up MS Visual Studio commandline args with vcvars32
// cl signtool.cpp
// Drag signtool.exe to the installshield folder above.
// *** Do NOT replace your main signtool.exe below!
//
// Create a batch file to supply the desired arguments, with the
// same name as your pfx file, but with a .bat extension
// In this sample batch file, you need to:
// Adjust the path to the "real" signtool.exe
// --- ie a modern one that handles SHA-2
// Stick in whatever arguments you want, ie your timestamper
// (The sha2 arguments are already there)
//
//++++++++++++++
// SET tool=C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe
// "%tool%" sign /v /fd sha256 /tr http://timestamp.digicert.com /td sha256 /f %2 /p %3 %1
//--------------
// You can put a "pause" at the end of the batch file to watch it go for testing

int
main(int argc, char *argv[])
{
int i, len;
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
HANDLE hProcess, hThread;
char cmd[8192];
DWORD exitc = 0;
char *pfx = "", *pwd = "", *batch = 0;

#if 0
FILE *fp = fopen("/tmp/signlog.txt", "a");
for (i = 0; i < argc; i++)
fprintf(fp, "Arg %i '%s'\n", i, argv);
fclose(fp);
#endif

if (argc < 2 || strcmp(argv[1], "timestamp") == 0)
exit(0);

for (i = 1; i < argc; i++)
if (strcmp(argv, "/f") == 0)
pfx = argv[++i];
else if (strcmp(argv, "/p") == 0)
pwd = argv[++i];
if (!pfx)
{
printf("No pfx file\n");
exit(1);
}

batch = _strdup(pfx);
len = strlen(batch);
if (_stricmp(batch+len-4, ".pfx") != 0)
{
printf("Bad pfx extension\n");
exit(1);
};
strcpy(batch+len-4, ".bat");

sprintf(cmd, "cmd.exe /C %s \"%s\" \"%s\" \"%s\"",
batch, argv[argc-1], pfx, "******");
printf("About to run command: '%s'\n", cmd);
sprintf(cmd, "cmd.exe /C %s \"%s\" \"%s\" \"%s\"",
batch, argv[argc-1], pfx, pwd);

memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
if (!CreateProcess(0, cmd, 0, 0, FALSE, 0, 0,
0, &sinfo, &pinfo))
{
int lasterr = GetLastError();

printf("Failed %d\n", lasterr);
exit(1);
}
hProcess = pinfo.hProcess;
hThread = pinfo.hThread;

WaitForSingleObject(hProcess, INFINITE);
GetExitCodeProcess(hProcess, &exitc);

CloseHandle(hThread);
CloseHandle(hProcess);

exit(exitc);
}[/CODE]
0 Kudos
PeterKrahulik
Flexera beginner

Please note that by using the following hack you will change installed system in your own responsibility.
Backup any file prior changing/replacing it.

1. Replace the C:\program files (x86)\Installshield\201x\System\signtool.exe by the version from Windows 7 SDK.
2. Inject the command line parameter into URL in your project i.e. http://www.yourdomain.com" /fd sha256"


Note the proper use of ".

Hope it works for you as it did for me.
0 Kudos
DebbieL
Pilgrim

InstallShield 2015, which was just released today, has built-in SHA-256 support for code-signing your installations and files at build time. For more details, see the InstallShield 2015 release notes.
0 Kudos
Stefan_M
Pilgrim

Signing SHA256 with Installshield 2015 works but I didn't find a way to use the timeserver "http://timestamp.geotrust.com/tsa".
Commandline: "/tr http://timestamp.geotrust.com/tsa instead" of "/t http://timestamp.verisign.com/scripts/timstamp.dll"
It looks like that the parameter /tr is nor suppoerted.

/tr URL Specifies the URL of the RFC 3161 time stamp server.

Source: https://msdn.microsoft.com/en-us/library/8s9b9yaz(v=vs.110).aspx
0 Kudos
MichaelU
Flexera
Flexera

The supported way of changing the timestamp server in InstallShield is to edit settings.xml. (Take care editing that file, and keep a backup of the last known good version.)
0 Kudos
Stefan_M
Pilgrim

I changed the line

to

but this didn't work.

Commandline with RFC3161 timeserver
SignTool.exe sign /f cert256.pfx /p password /fd SHA256 /tr http://timestamp.geotrust.com/tsa filename.exe

Commandline with old timeserver
SignTool.exe sign /f cert256.pfx /p password /fd SHA256 /t http://timestamp.verisign.com/scripts/timstamp.dll filename.exe

The difference is the /t <> /tr parameter.
0 Kudos
MichaelU
Flexera
Flexera

Ah, thanks, I missed that difference in your post. However I'm now unclear whether you're talking about InstallShield 2014 or 2015, as we no longer call signtool in InstallShield 2015. In 2014 you're welcome to keep intercepting the command lines and processing them yourself.

Regarding doing this in InstallShield 2015, it looks like the APIs only support generating RFC3161 timestamps on Windows 7 or later - that's not a problem for you is it? Assuming it's not, I can file a request to add support for these. I expect we would also put this in settings.xml, at least if we can add it before our next major release.
0 Kudos
Stefan_M
Pilgrim

Would be nice to have this in IS 2015.

Additionaly it is necessary to sign files with SHA1 and SHA256 because some programs are used with Vista and Windows7/8.

Actual I run signttool twice:
SignTool.exe sign /f Cert_SHA256.pfx /p password /t http://timestamp.verisign.com/scripts/timstamp.dll filename.exe
SignTool.exe sign /as /f Cert_SHA256.pfx /p password /fd SHA256 /tr http://timestamp.geotrust.com/tsa filename.exe

the first signing uses SHA1 for Vista
the second uses SHA256 for Windows7/8

Additional Parameter:
/as Appends this signature. If no primary signature is present, this signature is made the primary signature instead.
0 Kudos
MichaelU
Flexera
Flexera

I will have to double-check with the engineer that implemented this, but my recollection is that we tested the ability to verify SHA-256 signatures and (according to my fuzzy memory) it worked down through Windows XP, er Windows Vista. Since the API required to place additional signatures requires Windows 7 er Windows 8 (we only require Vista for the IDE), and everything seemed to work without it, we chose to use a single signature whose digest's hash algorithm matches the certificate's hash algorithm. Have you encountered a scenario where this fails?
0 Kudos
joshstechnij
Flexera
Flexera

There are a number of reasons that multiple signature support was not added to 2015:
- The API required to sign a file with multiple signatures requires Windows 8.
- Windows Vista does support sha256 signatures with SP2 and hot fix KB2763674 which is available through Windows Update and has been available since November 2012. Only pre-Vista platforms are missing sha256 support, but these will all be out of support in another month or so.
- Windows Installer does not support multiple signatures, only PE files are supported.

Due to these factors, in addition to the engineering effort, multiple signature support was considered low priority and therefore not implemented. This is something that could be implemented in the future, but if Microsoft's push to get everyone on Windows 10 takes off, it might be somewhat irrelevant to support multiple signatures.
0 Kudos
Tobias79
Pilgrim

We use IS2010 on our products. Now I got it working wrapping SignTool.exe with our own wrapper which just forwards the command line to an Windows SDK 8.1 Version of the SignTool.exe with additional
/fd SHA 256
parameter.

But now when building a Setup.Exe with an embedded signed MSI we run into issue
Started signing certificate.msi ...
sign /f /fd SHA256 "\\ourOFS.pfx" /du "http://www.OurUrl.com" /p "OurPassword" /d "certificate" "certificate.msi"
timestamp /q /t "http://timestamp.verisign.com/scripts/timstamp.dll" "certificate.msi"
ISDEV : error -6258: An error occurred extracting digital signature information from file "D:\InstallShield 2010 Projects\My Project Name\Product Configuration 1\Interm\certificate.msi". Make sure the digital signature information provided in the IDE is correct.
Started signing My Project Name.msi ...


Certificate.msi seems to be an MSI with only purpose for temporary storing a certified MSI? Which then is read again from IS Compiler. I assume that behavior same for IS2010 until IS2014. So how to prevent IS to read the certificate from the certificate.msi or enable IS also to read an MSI with sha256 Digest Algorithm?

What are in general the drawbacks when only sign the setup.exe but nomore the embedded MSIs?

Best regards,
Tobias
0 Kudos
Tobias79
Pilgrim

Any feedback on my previous post? 🙂
0 Kudos
Nick_Umanski
Active participant

It seems to me that most of the problem can be worked around.

1. Manually or batch file sign all the binaries before building the installer. This is how we used to do it with IS11.5 and now I've resurrected that process, only modifying it to dual sign. Fortunately, with my InstallShield 2014 installers, I had set up to NOT "Sign Files That Are Already Signed" and thus I don't need to change the installers.

2. Manually or batch file sign the Setup.exe after InstallShield has built it.

The command lines needed to do this in both instances are:

signtool sign /n %CommonName% /t http://timestamp.comodoca.com/authenticode %FileName% >> %LogFile%
signtool sign /n %CommonName% /fd sha256 /tr http://timestamp.comodoca.com/rfc3161 /td sha256 /as %FileName% >> %LogFile%

Replacing %CommonName% with the Common Name of the digital signing certificate, %FileName% being the file to be signed and %LogFile% being the name of the file to hold the results of the operation, useful when signing several hundred files as a background task.

Source: http://zabkat.com/blog/code-signing-sha1-armageddon.htm

_______________________


However, I'm left with one problem, the MSI. Some of my installers spit out an .msi file for use with active directory installment. Others embed an .msi file inside the Setup.exe

I can only sign the standalone .msi once and then only with a SHA-1 (or md5) Digest Algorithm, attempting to add the second signing produces an error. Even if you have an unsigned .msi, you cannot sign it with the SHA-256 Digest Algorithm, which is the most important of the two Algorithms. I presume this is a Microsoft problem rather than an InstallShield one?

As for the embedded .msi I simply cannot access it, but given the previous point, it wouldn't work anyway. However, although it is something I've always done, I'm uncertain whether you actually need to sign an embedded .msi or whether the signed Setup wrapper takes care of that. Can anyone confirm or deny that?

0 Kudos
Tobias79
Pilgrim

Acc. TechNet ( http://social.technet.microsoft.com/wiki/contents/articles/32288.windows-enforcement-of-authenticode... ) recommended strategy is to stick to SHA1 only for MSIs (e.g. MS does it for the new 2015 VCRedists).

IMHO removing signing for MSIs completely if they are embedded within an setup.exe seems ok at first glance. Short testing with IS2010 UI Build also caused trouble when using a new certificate with activated InstallShield certification.
0 Kudos
Nick_Umanski
Active participant

@Tobias79

Yes your TechNet link basically explains my first command line example:
signtool sign /n %CommonName% /t http://timestamp.comodoca.com/authenticode %FileName% >> %LogFile%

The point is, it is an SHA-1 encryption and this will not be valid for digital signing carried out after 01/01/2016, which presumably includes .msi files

It looks to me that Microsoft just haven't got a solution for .msi files and all the 'informed opinions' either don't mention it or sprout a rather confusing technical term such as in this case:

"Note that this approach will meet policy only for the code signing certificate requirement being enforced for SHA-1 code signing certificates starting on 1/1/2016."

...which basically means "Not valid on Win7 and above"
0 Kudos