PDA

View Full Version : Codesigning using SHA-2, SHA256



tdhintz
11-18-2014, 05:06 PM
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.

MichaelU
11-19-2014, 09:09 AM
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 <InstallShield>\System\signtool.exe and does something else instead.

tdhintz
11-19-2014, 09:27 AM
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.

tdhintz
11-19-2014, 09:30 AM
This additional commentary on Microsoft's SHA-1 policy.

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

MichaelU
11-20-2014, 09:32 AM
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.

rassmm
12-15-2014, 10:25 AM
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 <InstallShield>\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.

rassmm
12-17-2014, 10:29 AM
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!



#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

// 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[i]);
fclose(fp);
#endif

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

for (i = 1; i < argc; i++)
if (strcmp(argv[i], "/f") == 0)
pfx = argv[++i];
else if (strcmp(argv[i], "/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);
}

Thinkeye
06-09-2015, 10:24 AM
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.

DebbieL
06-10-2015, 08:08 AM
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 (http://www.installshield.com/ReleaseNotes/PrePro-2015.asp).

Stefan_M
06-11-2015, 07:36 AM
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

MichaelU
06-11-2015, 07:49 AM
The supported way of changing the timestamp server in InstallShield is to edit settings.xml (http://helpnet.flexerasoftware.com/installshield22helplib/installshield22helplib.htm#StartTopic=helplibrary/SettingsXML-Timestamp.htm). (Take care editing that file, and keep a backup of the last known good version.)

Stefan_M
06-11-2015, 08:22 AM
I changed the line
<DigitalSignature Timestamp="http://timestamp.verisign.com/scripts/timstamp.dll"/>
to
<DigitalSignature Timestamp="http://timestamp.geotrust.com/tsa"/>
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.

MichaelU
06-11-2015, 08:58 AM
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.

Stefan_M
06-12-2015, 05:03 AM
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.

MichaelU
06-12-2015, 06:34 AM
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?

joshstechnij
06-12-2015, 08:56 AM
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.

Tobias79
06-22-2015, 04:19 AM
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 256parameter.

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

Tobias79
09-24-2015, 10:13 AM
Any feedback on my previous post? :)

Nick Umanski
01-14-2016, 09:17 AM
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?

Tobias79
01-14-2016, 10:04 AM
Acc. TechNet ( http://social.technet.microsoft.com/wiki/contents/articles/32288.windows-enforcement-of-authenticode-code-signing-and-timestamping.aspx#How_to_handle_MSI_files ) 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.

Nick Umanski
01-14-2016, 10:27 AM
@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"

Tobias79
01-14-2016, 10:47 AM
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


I assume MSIs (with SHA1 only) will not be considered as signed with invalid signature if carried out this year. Even if not implicitely stated in the TechNet article. Think the Microsoft approach they did last year for e.g. the VCRedist (https://www.microsoft.com/en-us/download/details.aspx?id=48145) should be the same as if they would release the package this year. Setup.exe (and containing assemblies) signed with digest algorithm SHA1/256 and MSI with SHA1..

I mean why should they otherwise adapt signing for PE files to SHA1/256 but not for the MSI. Just my interpretation.

Nick Umanski
01-14-2016, 12:25 PM
You make it sound like 'they' had a choice in the matter. But in fact the new signing encryption was forced on them by a security problem. I suspect that it was NOT anticipated that SHA-256 would fail on .msi files and the lack of information on the subject is because a solution still hasn't been found.

Curiously, the .msi's I've produced since the 1st January still work as do individual binaries encrypted by an SHA-1 algorithm. So it looks like the security patch meant to enforce this hasn't been deployed yet.

What I don't understand is why Flexera/InstallShield don't seem to have the first clue as to what is going on, when they should be camping on Microsoft's door demanding information.