I have a php
web application that allows our users to download our software installer setup.exe
.
We've just started signing our code, both the the installer and the applications within it, which is all fine. However when I upload this installer to our web server, and download it through the php
web application, setup.exe
is no longer digitally signed! It's as if it was never signed in the first place.
Here's what I've tried:
-
[right click] -> [properties]
shows thatsetup.exe
is not code signed. Howeversetup.exe
is the expected version. - I ran the installer, and installed our software. The applications that are installed ARE code signed, and the expected version matching the installer.
- I tried downloading
setup.exe
directly from the web server through thecpanel
File Manager and this is fine -setup.exe
is digitally signed and the expected version. - Attempts to download
setup.exe
from the web site via different browsers (firefox, edge) result in the same behaviour.
EDIT
- I also tried moving the
setup.exe
file to a public area on the site, and downloading it directly through the browser - works perfectly. All I can think is that the issue has to be in how PHP is serving the application to the browser.
I thought the HTTP headers or the PHP download function we have written might be related to the problem.
Our generic include.php
file has the following headers to prevent caching:
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Fri, 01 Jan 2016 01:00:00 GMT"); // a date in the past
And this is our download function:
function DownloadFile($file, $filename) {
// check if file exists and write header info and output file
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/x-msdownload');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
return true;
}
else {
// file does not exist
return false;
}
}
Which is primarily from the readfile()
example on php.net. Are there any red flags here? What's going on?