First, a little history. Originally we signed our application like this:
signcode /spc C:mycredencials.spc /v a:myprivatekey.pvk /t http://timestamp.verisign.com/scripts/timstamp.dll c:\Project1.exe
The problem is that it required us to enter a password in a dialog box every time this command was run. Since we built several applications at a time, our "automated" build process required a lot of manual intervention.
The solution to that problem was to embed the key in the registry using PVKIMPRT.
The command line for signcode that directly accessed the certificate store was:
signcode -cn "Cool Corp" -n "My Application" -i http://www.example.com/MyApp.html -t http://timestamp.verisign.com/scripts/timstamp.dll c:\Project1.exe
This worked well on Windows XP, but failed on Vista with the error "failed to build the certificate chain." [Update 7/25/2008 - This problem was probably caused because the intermediate key was not installed. See my later post.]
Recent discussions about codesigning seem to advocate using signtool instead of signcode, although there's no discussion about the difference. I found that signtool has one big advantage over signcode: it can read PFX files, which is what Internet Explorer exports (Control Panel / Internet Options / Content / Certificates / Export). However, if you export your certificate to a PFX file in Windows Vista, you are required to provide a password, which didn't play well with one of our automated build tools.
The first solution was to use Windows XP to create the PFX file instead of Vista. WinXP will allow you to export your certificate and private key to a PFX file without a password. However, I found a better solution with a little research.
Signtool can automatically select a code signing certificate from the registry with the /a option. That's very handy. Eventually I ended up with this command in the Post Build Event:
$(SolutionDir)Tools\SignTool sign /a /d "My Application" /du "http://www.example.com/MyApp.html" /t http://timestamp.verisign.com/scripts/timstamp.dll $(TargetPath)
You better use PFX
ReplyDeletehttp://matrixalaya.blogspot.com/2007/03/exporting-non-exportable-certificates.html
How do you verify the file integrity of file?
ReplyDeleteWindows doesn't verify the digital signature of the file other than if it is an ActiveX object (there are few other)?
Do you know Windows API using them one could read the digital file signature from the signed file?
In answer to sumit's question, you can check the signature of a file with the function WinVerifyTrust. Sample code can be found at http://msdn.microsoft.com/en-us/library/aa382384(VS.85).aspx.
ReplyDeleteThanks for the tip on using /a in the post-build task, it made things much simpler.
ReplyDeleteI'm using VS2008, and for whatever reason timestamping (using /t ) is failing in the post-build event, even though the same full signtool command works fine if I manually run it afterward. The error is
EXEC : SignTool error : ISignedCode::Timestamp returned error: 0x80070020
The process cannot access the file because it is being used by another process.
Did you have that hurdle? Any suggestions?
My first guess is that the SignTool error is caused by the indexing system. Try disabling the indexer and see what happens. (Could be Windows Search, Google Search, etc.)
ReplyDeleteRegarding the error I mentioned above: Turns out it was Norton Antivirus's "real time" protection. Aside from disabling that, I was able to overcome this issue by putting the signtool command *after* another unrelated line in my post-build. The unrelated line makes two calls to updateversion and takes < 1 sec, but this gives enough time to free the file lock.
ReplyDeleteThanks for the great post, I got several valuable ideas from it. I recently ran into the signtool 'cannot access the file' problem on Windows 7. I found that adding a command like "ping 127.0.0.1 >NUL" before the signtool command makes the problem go away, or at least makes it much less frequent.
ReplyDeleteAnd just to mention another weird problem I had to resolve with signtool: Using a forward slash ('/') in the sign /d description string causes the resulting digital signature to be considered invalid by Windows. Prefixing with a backslash (like \/) gives a valid signature again, but - both characters end up in the description! I gave up and used a dash instead of the slash...
Spike,
ReplyDeleteTo sleep for one second, use something like this:
ping 127.0.0.1 -n 2 -w 1000 > nul
Or use a "sleep" command from CygWin or the Windows Resource Tools.
Thanks !
ReplyDeleteJim, In my certificate (.cer) that I have installed in "Trusted Root Certifi....." store, I don't have any sort of description in it. This is what I use to sign :
ReplyDeletesign /v /n "Subject PArt of " /t http://timestamp.veris
ign.com/scripts/timestamp.dll Application.exe
but it doesn't work. Can you help me with this. In many sites I found they ae using storename, but you aren't using any store name also. So, is your certificate installed/imported or where it is. Kindly help me. From many days I am after this, but couldn't achieve the goal yet.
Sorry, I have no experience with Trusted Root Certificates. A Trusted Root should either be a registrar or a corporate certificate created by someone who knows what they are doing. A self-signed certificate would almost never be a trusted root.
ReplyDelete