Code signing with SHA-256

Got a problem you cannot solve? Try here.
Archi
Posts: 4
Joined: Tue Jan 26, 2016 8:19 am

Code signing with SHA-256

Postby Archi » Tue Jan 26, 2016 8:42 am

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?
Last edited by Archi on Wed Feb 03, 2016 7:18 am, edited 1 time in total.

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Tue Jan 26, 2016 1:16 pm

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

Archi
Posts: 4
Joined: Tue Jan 26, 2016 8:19 am

Re: Code signing with SHA-256

Postby Archi » Wed Jan 27, 2016 4:12 am

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;
}
Last edited by Archi on Sun Feb 07, 2016 4:46 pm, edited 1 time in total.

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Thu Jan 28, 2016 11:56 am

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

Archi
Posts: 4
Joined: Tue Jan 26, 2016 8:19 am

Re: Code signing with SHA-256

Postby Archi » Wed Feb 03, 2016 7:44 am

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).

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Wed Feb 03, 2016 2:06 pm

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

erich.einfalt
Posts: 32
Joined: Mon Oct 29, 2012 2:27 pm

Re: Code signing with SHA-256

Postby erich.einfalt » Tue Feb 16, 2016 6:24 pm

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.

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Wed Feb 17, 2016 3:01 pm

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

pfennig
Posts: 168
Joined: Wed Nov 08, 2006 8:39 am

Re: Code signing with SHA-256

Postby pfennig » Thu Apr 14, 2016 3:54 am

“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.
Best regards
pfennig

Archi
Posts: 4
Joined: Tue Jan 26, 2016 8:19 am

Re: Code signing with SHA-256

Postby Archi » Sun Apr 17, 2016 5:55 pm

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);
}

shlomid
Posts: 7
Joined: Sun Apr 03, 2011 12:19 am

Re: Code signing with SHA-256

Postby shlomid » Tue Jul 05, 2016 10:29 am

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

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Tue Jul 05, 2016 11:54 am

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

shlomid
Posts: 7
Joined: Sun Apr 03, 2011 12:19 am

Re: Code signing with SHA-256

Postby shlomid » Tue Jul 05, 2016 5:22 pm

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

FrancescoT
Site Admin
Posts: 5361
Joined: Sun Aug 22, 2010 4:28 am

Re: Code signing with SHA-256

Postby FrancescoT » Wed Jul 06, 2016 11:29 am

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
Francesco Toscano
InstallAware Software

White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE

tofutim
Posts: 176
Joined: Thu Mar 01, 2012 1:16 pm

Re: Code signing with SHA-256

Postby tofutim » Sun Aug 14, 2016 8:42 am

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?


Return to “Technical Support”

Who is online

Users browsing this forum: No registered users and 28 guests