Archive: Compression interferes w/ Code Signing


Compression interferes w/ Code Signing
  We are new users of NSIS. We resisted switching from the builder included w/ Visual Studio for years – and now are left to wonder what took us so long to switch. NSIS is a fantastic Installation Builder! It took some time to learn our way around, but this system is proving itself to be a real winner.

We’ve encountered one MINOR issue. It’s could be our lack of familiarity with NSIS – but after studying the FAQ, the Forums & the Docs, we’re left wondering how others might have solved the issue.

Summary: We are unable to effectively Sign a Build & use Compression.

Details:
We’ve added a call to the Microsoft ‘signtool.exe’ as the very last statement of setup.nsi.

For example:

        !system signtool.exe (parameters omitted) setup.exe


We’ve confirmed that this step executes as expected. But it would appear that the compression (selected with the ‘SelectCompressor’ directive) always runs as the last step of any compile. This makes sense of course as it ensures the highest compression – but by altering the Build AFTER it has been signed, the signature is no longer is valid.

What We Tried:

We checked around the various plug-ins, but none would seem to directly address this issue. We got excited when we saw the PostExec.nsh plugin (http://nsis.sourceforge.net/Run_Comm...er_Compilation), but it suffers from the same behavior describe above – that compression still runs as the last step of any compile.

We use the EclipseNSIS environment for generating our builds, so we thought perhaps it might be useful to explore what options the Eclipse IDE offered to address this. When the EclipeNSIS environment does have options for steps-before-compilation, it does not have options for steps-after-compilation. We thought of trying to alter the EclipseNSIS code to add this option – but realized this was not the best solution. It would mean always having todo the build from within Eclipse – which is not our regular coding environment.

Question:

So our question is simple. Is there a way to control WHEN compression happens in the build cycle? Or, is there a way to run a step AFTER the compression happens?

Of course we could just turn off compression – but we’d loose the benefit of a cool NSIS feature, and that would be sad. :(

Workarounds:

Of course we can just roll up a call to the signing tool in a batch file that 1st performs the compile, then signs the build (which is what we are now doing) – but we wanted to post to the forum to see if others might have a more elegant solution. Feel free to suggest RTFM – but if one could point us to the appropriate ‘M’ we’d appreciate it :D

Considering the tremendous number of problems we’ve now solved with this exceptional tool – we consider this a minor issue. But just wanted to check in.

We use a batch processor (used to be ANT, now we're using something else), so a batch file should certainly work.
From digging through the search results, that's also the most typical response: use a batch file.

The main alternative is the same as you've already tried, although this post..
http://forums.winamp.com/showpost.ph...22&postcount=7
..uses a VBScript to check whether makensis is running or not instead. I suspect both -should- work, so I'm not sure why the "Run Command After Compilation" one doesn't appear to work for you.

Another option - but it received no comments, so I have no idea if it works (does it only pack the header.. while the code signing should be for the entire thing?) - was to use !packhdr: http://nsis.sourceforge.net/Docs/Cha...packhdr#5.1.10

Edit: oh, and off-topic: disable NSIS's CRC check (since the code sign bit already takes care of that)


The next version of nsis adds a new !finalize command that could be used for stuff like this, in the mean time, you are stuck with using either a batchfile or !system tricks.

The system trick goes something like this:

!ifNdef REALBUILD
outfile "$%temp%\dummy.exe"
page instfiles
section
sectionend
!system '"${NSISDIR}\makensis" /DREALBUILD "${__FILE__}"' = 0

!else

;your actual code here

!endif
To sign the uninstaller, you would have to pull the same kind of trick so you can call WriteUninstaller on your local machine and sign and include that as a normal file in the real installer.

We use a batch file and it works perfectly. I look forward to that !finalize command, though!


I tried this in my batchfile

SignTool.exe sign /f cert /p pass /t http://timestamp.comodoca.com/authenticode $1


But it didn't work.

I added the !system "sign.bat setup.exe" before the !endif

Maybe I didn't make myself clear, before !endif you put the real installer script, not signing code:

!define OUTPUT mysetup.exe

>!ifNdef REALBUILD
outfile "$%temp%\dummy.exe"
>page instfiles
section
sectionend
>!system '"${NSISDIR}\makensis" /DREALBUILD "${__FILE__}"' = 0
>!system '"signtool.exe" "${OUTPUT}" /param etc' = 0
>!else
>outfile "${OUTPUT}"
>;more of your installer script...
!endif

Thanks, works great!