Page 1 of 2

Code signing with SHA-256

Posted: Tue Jan 26, 2016 8:42 am
by Archi
The new Microsoft code signing policy requires the usage of SHA-256 since January 1, 2016.

The following input of the "Time Stamp URL" seems to work:

Code: Select all

http://timestamp.comodoca.com/authenticode" /fd SHA256"

Unfortunately, the time stamping server is still using SHA-1 and not SHA-256.
Can a comodo SHA-256 time stamping server be used with InstallAware X2?

Re: Code signing with SHA-256

Posted: Tue Jan 26, 2016 1:16 pm
by FrancescoT
Dear Archi,

from what I can tell and as long as a SHA2 certificate is used, it should be enough to pass the proper SHA256 timestamp URL as "http://timestamp.comodoca.com/authenticode?td=SHA256".

I have heard of problems with such timestamp server ... but honestly, I don't know if any issues may still persist.

Regards

Re: Code signing with SHA-256

Posted: Wed Jan 27, 2016 4:12 am
by Archi
I've finally found a solution:
  • goto the authenticode folder inside the program folder of InstallAware
  • rename signtool.exe to signtool2.exe
  • compile the attached program code as signtool.exe and place it into the authenticode folder
  • use following input for the "Time Stamp URL" (inside InstallAware):

    Code: Select all

    http://timestamp.comodoca.com/rfc3161
Even a dual signature (SHA-1 and SHA-256) is possible with this method. All you need is to call signtool2.exe twice.

Code: Select all

#include <windows.h>
#include <tchar.h>

#define MAX 32767

int _tmain(int argc, _TCHAR* argv[])
{
   int i, k;
   _TCHAR cmd[MAX+1], *p;

   cmd[MAX] = _T('\0');
   if (_sntprintf(cmd, MAX, _T("\"%s"), argv[0]) < 0) return 1;
   p = _tcsrchr(cmd, _T('.'));
   if (p == NULL) return 1;
   if (_sntprintf(p, MAX-(p-cmd), _T("2.exe\"")) < 0) return 1;

   p += _tcslen(p);
   for (i = k = 1; i < argc; i++) {
      if (_tcscmp(argv[i], _T("/t")) == 0) {
         if (_sntprintf(p, MAX-(p-cmd), _T(" /tr")) < 0) return 1;
         k = -2;
      }
      else {
         if (_sntprintf(p, MAX-(p-cmd), _T(" \"%s\""), argv[i]) < 0) return 1;
      }
      p += _tcslen(p);
      if (++k == 0) {
         if (_sntprintf(p, MAX-(p-cmd), _T(" /fd SHA256 /td SHA256")) < 0) return 1;
         p += _tcslen(p);
      }
   }

   DWORD exitCode;
   STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO);
   PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return 1;
   WaitForSingleObject(pi.hProcess, INFINITE);
   if (!GetExitCodeProcess(pi.hProcess, &exitCode)) return 1;
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);

   return exitCode;
}

Re: Code signing with SHA-256

Posted: Thu Jan 28, 2016 11:56 am
by FrancescoT
Dear Archi,

first of all many thanks for sharing your solution with the InstallAware community.
Anyway IA X3 users have the possibility to use a simpler approach and this due the "new Build Events" feature available with IA X3.
- Build events let you run custom applications/processes as an integral part of your build process -

For what concerns the new Microsoft SHA-2 enforcement, unfortunately this seems to be quite complex and for what we see, it's not so clear its correct application. For example; the fact that the MSI file format does not support dual signing and a different approach needs to be used for signing a single MSI to be conformant with the policy down to Windows Vista.

Regards

Re: Code signing with SHA-256

Posted: Wed Feb 03, 2016 7:44 am
by Archi
According to Microsoft
This restriction will not apply to the time-stamp certificate used to time-stamp the code-signing certificate or the certificate’s signature hash (thumbprint) until January 1, 2017. After this time, Windows will treat any code with a SHA-1 time-stamp or SHA-1 signature hash (thumbprint) as if the code did not have a time-stamp signature.

That means my installer's signature would expire when the certificate expires from January 1, 2017 onwards. I've also found out that it is not trivial to make a valid SHA-256 signature with a SHA-1 time stamp signature for Windows XP and Windows Vista (both require a special system update to recognize these signatures correctly). For me, the solution are SHA-256 signatures with SHA-256 time stamp signatures, and to additionally pack these exe/msi files inside a ZIP file for Windows XP and Windows Vista (because the corresponding exe/msi files are denied by the Internet Explorer due to an invalid signature on Windows XP or Windows Vista).

Re: Code signing with SHA-256

Posted: Wed Feb 03, 2016 2:06 pm
by FrancescoT
Dear Archi,

this "seems to mean" that; after January 1, 2017 any file signed with a SHA-1 time-stamp or SHA-1 signature hash will be treated as as if the code did not have a time-stamp signature.

Regards

Re: Code signing with SHA-256

Posted: Tue Feb 16, 2016 6:24 pm
by erich.einfalt
Using the Post-Compress examples from the InstallAware article at http://www.installaware.com/blog/?p=416, the build log when building from the IDE consistently ends with the error shown in the last line :

Building Project: MSCodeSignTest
Output Folder: D:\Documents\!Notes\Installer\dist\Release\SingleDeployment Type: Compressed Single Self Installing EXE
Code Signing: Disabled
Compression: Default
Compiler Variables: CERT_FOLDER=C:\Cert,"POST-COMPRESS-EVENT-COMMANDS=""#CERT_FOLDER#\SignTool.exe"" sign /f ""#CERT_FOLDER#\Codesign_Certificate.pfx"" /t http://timestamp.verisign.com/scripts/timstamp.dll /p <Codesign_Certificate_pfx_password> ""D:\Documents\!Notes\Installer\dist\Release\Single\#TITLE#Setup.exe""$NEWLINE$$NEWLINE$""#CERT_FOLDER#\SignTool.exe” sign /f ""#CERT_FOLDER#\Codesign_Certificate.pfx"" /as /fd SHA256 /tr http://timestamp.geotrust.com/tsa /td SHA256 /p <Codesign_Certificate_pfx_password> “D:\Documents\!Notes\Installer\dist\Release\Single\#TITLE#Setup.exe”",POST-COMPRESS-EVENT-ABORT=TRUE,BUILDMODE=SFX,LANGUAGE=English,TITLE=MSCodeSignTest,TARGETDIR=$TARGETDIR$,"IADIR=E:\Program Files (x86)\InstallAware X3",PROJDIR=D:\Documents\!Notes\Installer\MSCODE~1,IAVER=20.10
###
Cleared output folder D:\Documents\!Notes\Installer\dist\Release\SingleBuilt plug-in action (Un)Install MSI Setup
Copied file E:\Program Files (x86)\MSCodeSignTest\dummy.exe
Created Windows Installer database
Built installation executable
Injected setup languages
Injected runtime files
Compressing install: componentstree.dfm (0%)
Compressing install: MSCodeSignTestSetup.msi (0%)
Compressing install: MSCodeSignTestSetup.exe (35%)
Compressed setup files
Prepared SFX data
Created SFX file
Error during build: Post-Compress command ""C:\Cert\SignTool.exe” sign /f "C:\Cert\Codesign_Certificate.pfx" /as /fd SHA256 /tr http://timestamp.geotrust.com/tsa /td SHA256 /p <Codesign_Certificate_pfx_password> “D:\Documents\!Notes\Installer\dist\Release\Single\MSCodeSignTestSetup.exe”" failed

It should be noted that the 1st Post-Compress event using the SHA1 timestamp URL works without error. The 2nd Post-Compress event is the one that fails. The RFC-3161 SHA256 timestamp URL is different than the SHA1 timestamp URL (which is as expected). It should be noted that several RFC-3161 SHA256 timestamps URLs from various vendors were tried and all failed.

Secondary question: Is there a way to capture a Build Event exit code?

!! UPDATE -- UPDATE -- UPDATE -- UPDATE !!!!!!!!!!!!!!!!!!!!
Removing all double quotes in the 2nd statement results in completion without error. In this case the double-quotes for the 2nd statement were not necessary because there are no spaces in any of the path names in the statement. While that works for me in this case, it still does not explain why it works WITH quotes in the 1st statement. The only difference between the 1st and 2nd statements is the additional command line options and the timestamp server URL.

Re: Code signing with SHA-256

Posted: Wed Feb 17, 2016 3:01 pm
by FrancescoT
Dear Erich,

honestly it's very strange!
I always use double quotes with path parameters and I never had any problem with the build events.

Regards

Re: Code signing with SHA-256

Posted: Thu Apr 14, 2016 3:54 am
by pfennig
“D:\Documents\!Notes\Installer\dist\Release\Single\MSCodeSignTestSetup.exe”
doesn't have correct quotes, but so called left and right double quotation marks.

Might have been the culprit.

Re: Code signing with SHA-256

Posted: Sun Apr 17, 2016 5:55 pm
by Archi
I've updated the code above to use double signing for exe-files and single signing for msi-files. However, the code assumes that the certificate file names are creatable with the input certificate file name by replacing its extension with either "-sha1.p12" or "-sha256.p12". Also, you need to update the original file signtool.exe with that of a more recent SDK:

Code: Select all

#include <windows.h>
#include <tchar.h>

#define MAX 32767
const TCHAR sha1Url[] = _T("http://timestamp.comodoca.com/authenticode");

DWORD shell(LPTSTR cmd)
{
   DWORD exitCode;
   STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO);
   PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return 1;
   WaitForSingleObject(pi.hProcess, INFINITE);
   if (!GetExitCodeProcess(pi.hProcess, &exitCode)) return 1;
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
   return exitCode;
}

BOOL repext(_TCHAR *dest, size_t n, const _TCHAR *src, const _TCHAR *ext)
{
   if (_tcslen(src) >= n) return FALSE;
   _tcscpy(dest, src);
   _TCHAR *p = _tcsrchr(dest, _T('.'));
   if (p == NULL) return TRUE;
   if (_tcslen(dest) + _tcslen(ext) - _tcslen(p) >= n) return FALSE;
   _tcscpy(p, ext);
   return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
   int i, k;
   _TCHAR cmd[MAX+1], *p, *p2, *pBaseExe;
   bool isMsi = false;
   DWORD exitCode;

   cmd[MAX] = _T('\0');
   if (_sntprintf(cmd, MAX, _T("\"%s"), argv[0]) < 0) return 1;
   p = _tcsrchr(cmd, _T('.'));
   if (p == NULL) return 1;
   if (_sntprintf(p, MAX-(p-cmd), _T("2.exe\"")) < 0) return 1;
   p += _tcslen(p);
   pBaseExe = p;

   p2 = _tcsrchr(argv[argc - 1], _T('.'));
   if (p2) {
      if (_tcsicmp(p2, _T(".msi")) == 0) {
         isMsi = true;
      }
   }

   if (isMsi) {
      for (i = k = 1; i < argc; i++) {
         if (_tcscmp(argv[i - 1], _T("/f")) == 0) {
            _TCHAR file[MAX_PATH];
            if (!repext(file, _countof(file), argv[i], _T("-sha256.p12"))) return 1;
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), file) < 0) return 1;
         }
         else if (_tcscmp(argv[i], _T("/t")) == 0) {
            if (_sntprintf(p, MAX - (p - cmd), _T(" /tr")) < 0) return 1;
            k = -2;
         }
         else {
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), argv[i]) < 0) return 1;
         }
         p += _tcslen(p);
         if (++k == 0) {
            if (_sntprintf(p, MAX - (p - cmd), _T(" /fd SHA256 /td SHA256")) < 0) return 1;
            p += _tcslen(p);
         }
      }
   }
   else {
      for (i = k = 1; i < argc; i++) {
         if (_tcscmp(argv[i - 1], _T("/t")) == 0) {
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), sha1Url) < 0) return 1;
         }
         else if (_tcscmp(argv[i - 1], _T("/f")) == 0) {
            _TCHAR file[MAX_PATH];
            if (!repext(file, _countof(file), argv[i], _T("-sha1.p12"))) return 1;
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), file) < 0) return 1;
         }
         else {
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), argv[i]) < 0) return 1;
         }
         p += _tcslen(p);
      }
      
      exitCode = shell(cmd);
      if (exitCode) return exitCode;

      p = pBaseExe;
      for (i = k = 1; i < argc; i++) {
         if (_tcscmp(argv[i - 1], _T("/f")) == 0) {
            _TCHAR file[MAX_PATH];
            if (!repext(file, _countof(file), argv[i], _T("-sha256.p12"))) return 1;
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), file) < 0) return 1;
         }
         else if (_tcscmp(argv[i], _T("/t")) == 0) {
            if (_sntprintf(p, MAX - (p - cmd), _T(" /tr")) < 0) return 1;
            k = -2;
         }
         else {
            if (_sntprintf(p, MAX - (p - cmd), _T(" \"%s\""), argv[i]) < 0) return 1;
         }
         p += _tcslen(p);
         if (++k == 0) {
            if (_sntprintf(p, MAX - (p - cmd), _T(" /fd SHA256 /td SHA256 /as")) < 0) return 1;
            p += _tcslen(p);
         }
      }
   }

   return shell(cmd);
}

Re: Code signing with SHA-256

Posted: Tue Jul 05, 2016 10:29 am
by shlomid
Hi,

Executing this from command-line works well:
//# SHA-1
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /f "C:\InstallAware\CodeSigning\Codesign_Certificate.pfx" /t http://timestamp.verisign.com/scripts/timstamp.dll /p <Password> "C:\test\TestCodeSingShamir.exe"
//# SHA-256
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /f "C:\InstallAware\CodeSigning\Codesign_Certificate.pfx" /as /fd SHA256 /tr http://sha256timestamp.ws.symantec.com/sha256/ /td SHA256 /p <Password> "C:\test\TestCodeSingShamir.exe"


but from IA X3 Post-Compress event for "Web-deployment" build according to the following IA blog:
http://www.installaware.com/blog/?p=416

failed all the time! i cant get it to work.
please help!

"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /f #CERT_PATH# /as /fd SHA256 /tr http://sha256timestamp.ws.symantec.com/sha256 /td SHA256 /p <Password> "c:\install\Shamir\Test\Release\Web\#TITLE#.exe"

i tried with/without compiler variables but no luck...

Thanks!
Shlomi

Re: Code signing with SHA-256

Posted: Tue Jul 05, 2016 11:54 am
by FrancescoT
Dear Shlomi,

if it works from command line, it must work via IA events as well ... it really strange, I suppose there must be something wrong with the parameters passed to the build events.

Bu the way, I am not able to open "http://sha256timestamp.ws.symantec.com/sha256/" via browser .. it opens as; "http://sha256timestamp.ws.symantec.com/sha256" ...instead.

Regards

Re: Code signing with SHA-256

Posted: Tue Jul 05, 2016 5:22 pm
by shlomid
Hi Francesco,

is there a way to debug this error? all i get is that is failed without further indication on why.

please help, we need this ASAP.

thanks!
Shlomi

Re: Code signing with SHA-256

Posted: Wed Jul 06, 2016 11:29 am
by FrancescoT
Dear Shlomi,

as I said previously, if it works from command line it must work via IA events as well. So it doesn't exist a better way than command line to verify the passed parameters.

In addition I have also reported to you that the timestamp URL you said to have used via Event ("http://sha256timestamp.ws.symantec.com/sha256/") looks to be wrong. It should be; "http://sha256timestamp.ws.symantec.com/sha256" ...instead.

At any rate, I just tried the double signature process via IA Event and I am not able to see any problem ... using the correct command line parameters, of course.

In my case I used the following command lines to double sign the generated Web EXE.

Post build Event:
"C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe" sign /f <Cert_File_Path> /t http://timestamp.comodoca.com/authenticode /p <Cert_Password> "#PROJDIR#\Release\Web\#TITLE#.msi"
"C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe" sign /f <Cert_File_Path> /t http://timestamp.comodoca.com/authenticode /p <Cert_Password> "#PROJDIR#\Release\Web\#TITLE#.exe"
"C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe" sign /f <Cert_File_Path> /as /fd sha256 /tr http://timestamp.comodoca.com/rfc3161 /td sha256 /p <Cert_Password> "#PROJDIR#\Release\Web\#TITLE#.exe"

Post Compress Event:
"C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe" sign /f <Cert_File_Path> /t http://timestamp.comodoca.com/authenticode /p <Cert_Password> "#PROJDIR#\Release\Web\#TITLE#.exe"
"C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe" sign /f <Cert_File_Path> /as /fd sha256 /tr http://timestamp.comodoca.com/rfc3161 /td sha256 /p <Cert_Password> "#PROJDIR#\Release\Web\#TITLE#.exe"

-----------------
In my case the signtool path is different due the fact that I have exclusively installed Win10 SDK on my Win 10 machine.
I also used a different Timestamp URL .... this just because I have a Comodo certificate ... anyway any valid Timestamp URL can be used.

Hope this helps you.

Regards

Re: Code signing with SHA-256

Posted: Sun Aug 14, 2016 8:42 am
by tofutim
Francesco, when using this, do I uncheck the regular authenticode signature then? Where do I find the post-build events?

Update. I found the post-build events (under the Project Settings). Another question, the post build events you have deal with the Web version. How would i deal with the Single version too? Also, why do you sign both post-compress and post-build? Is that redundant?