Solved: “Access Denied” errors when calling signtool.exe from PHP

SIGHntool, why must you give me such grief?

I have spent the last 8 hours trying to figure out why Microsoft’s signtool.exe code signing utility refuses to work when called from PHP’s system() or shell_exec() functions on my WAMP server:

C:\build> "C:\Program Files\InstallMate 7\Tools\signtool.exe" sign /v /f codesignedcert.pfx Setup.exe 2>&1

The following certificate was selected:
    Issued to: <redacted>.
    Issued by: UTN-USERFirst-Object
    Expires:   5/12/2012 6:59:59 PM
    SHA1 hash: <redacted>

Done Adding Additional Store

Attempting to sign: C:\build\Setup.exe

Number of files successfully Signed: 0
Number of warnings: 0
Number of errors: 1

SignTool Error: ISignedCode::Sign returned error: 0x80090010

	Access denied.

SignTool Error: An error occurred while attempting to sign: C:\build\Setup.exe

_Note: the 2>&1 at the end of the signtool call is essential if you want to capture error messages which are emitted to STDERR instead of STDOUT. Yes, I lost an hour or two just on that.


Dead ends

  • Windows 7 apparently sets the read-only attribute on all files, and it isn’t easy to turn that attribute off. But since other file operations worked from PHP, this wasn’t the issue.
  • Prefacing the signtool call with CMD /C didn’t help.
  • Setting full control file permissions on the C:\build folder for Guest, SYSTEM, and any other user account I could think of didn’t help either.
  • Wrapping signtool in a batch file was an exercise in futility.

The maddeningly frustrating thing was that signtool worked great when called from the command line — just not from PHP!

An aha! moment

The issue turned out to be pretty stupid, as they usually do. I merely had to change the account that Apache was running as to that of a normal user, instead of the default local system account.

services.msc - changing the Apache user

Written on May 26, 2011