WebApplication.WebFile Breaks Code Signing - Solved

I recently did a search for my apps on the Internet and discovered that Brothersoft, Softpedia and many other “freeware” sites had harvested them from my website, bundled them with adware, repackaged them in their own installers, and were distributing them on their sites without my knowledge or consent.

I created a WebApplication to protect them from being harvested by miscreant bots but I’ve run into a problem now when serving them up as WebFiles where Gatekeeper will block them because they are from an “unidentified developer.” I use the codesign tool from the command line to sign my apps with my Comodo cert and they verify as signed from the command line. If I download the files directly from the site they will install, but when served up as WebFiles from my web app Gatekeeper blocks them.

What is happening when they are served up as WebFiles that breaks the codesigning? I’m using application/octet-stream as the file type. Should it be something else? This problem only affects the Mac binaries, I don’t have any trouble with broken codesigning in the Windows builds.

The problem is you are signing with your Comodo certificate. To satisfy Gatekeeper, you must sign with your Apple-supplied certificate. It has nothing to do with WebFile, though I’ll admit I don’t know why that changes the behavior.

I suspected as much. I suppose I’ll finally have to submit to the Apple Empire and ante up the hundred bucks to mollify Gatekeeper.

I don’t know why the installation behavior is different, either, unless it’s flagged differently by Mavericks when it’s downloaded through the web app rather than from a direct link to the file.

One can’t download an .app file directly, so you must be delivering them in some other format? (.zip ? .dmg ? ) This has the possibility of altering the un-zipped app enough to trigger this situations.

How were you delivering the actual download files?

The Mac apps are packaged in dmg files. As I mentioned previously, they don’t trigger a Gatekeeper warning if downloaded directly via a link, only when served up as a WebFile.

I have modified the download example that comes with Xojo to serve customers with downloads on my web site and the code uses showURL instead of a stream :

if LogoFile <>Nil Then ShowURL(DownloadPage.LogoFile.URL)

It has been working fine to deliver zip files for six months, now.

I did experience an issue with a previous host where the file was truncated when going through the web app for some reason, though. When I switched to 1701, everything went fine and has been ever since.

You say you deliver through a DMG… Is it the DMG that is refused by Gatekeeper or the application inside ? If that is the application inside, it seems strange. How could a download affect the content ?

I’ve tried serving the file as an imported binary directly from within the Web app and as a file served from a folder, both with the same result. The strange thing is, if I verify the file with codesign it shows it’s valid even though Gatekeeper flagged it as coming from an unidentified developer, which does lead me to suspect that it needs an Apple cert for Gatekeeper to accept it, but that doesn’t explain why Gatekeeper doesn’t flag it when it’s downloaded from a web directory via a direct link. I don’t know if that is a result of an issue with Gatekeeper in Mavericks or an issue with Xojo. I just signed up as an Apple developer, so I’ll see what happens after I get the cert from them.

You say ‘the file’. Which file ? The DMG ? The .app ?

I’d love to be able to try this for myself. I’m certain something else is going on, just don’t know what it is without seeing how the dmgs are different.

I distribute the apps in dmg packages, which I imported into the web app. In the Linux build (it’s a Linux server), the files are embedded in the app build and they’re served up as WebFile.Data. I thought that might be the problem, so I changed the app to serve them as folderitems from a subdirectory, but the result was the same.

I haven’t really looked at the dmg packages themselves since they aren’t signed, just the apps. As I mentioned previously, the Windows apps aren’t affected by this problem, just the Mac apps. Windows reports that the apps are signed by an identified developer at installation.

One thing that can be difficult for testing: OS X will remember your choices - once you’ve approved a DMG or App once, that approval sticks. You can see what’s going on using the extended attribute “com.apple.quarantine” flag.

  xattr -l /path/to/file # show extended attributes
  xattr -d com.apple.quarantine /path/to/file # clear quarantine bit

[quote=58545:@Michael Diehr]One thing that can be difficult for testing: OS X will remember your choices - once you’ve approved a DMG or App once, that approval sticks. You can see what’s going on using the extended attribute “com.apple.quarantine” flag.

xattr -l /path/to/file # show extended attributes xattr -d com.apple.quarantine /path/to/file # clear quarantine bit [/quote]
It’s possible that’s why the files downloaded from a direct link don’t trigger a response from Gatekeeper, although those files never have in the first place. I’m going to have to wait until I get my cert from Apple before I can do anymore on this. My expectation is that the Apple cert will solve the problem.

I’m still waiting on my cert from Apple. My enrollment status shows that they are in the process of contacting me to confirm that I am authorized to make decisions on behalf of myself and enter into contracts. I guess things are a bit hectic over there these days.

Have you asked yourself if you are, indeed authorized? :slight_smile:

Well, I finally got the Apple cert but it didn’t solve the problem, it’s still the same. Gatekeeper flags it as coming from an unidentified developer when it’s downloaded as a WebFile but not if it’s downloaded from a direct link to the file. If I verify the file after gatekeeper blocks it from running it shows it has a valid code signature. If I reset the quarantine flag and install it again the problem repeats. I don’t know what’s happening to it as a WebFile, but Gatekeeper won’t pass it.

Ok, time for some debugging. You’ll need your command line.

First, use the MD5 cli tool to compute the hash of each version of the file: original, direct, and WebFile. These should all be the same. If not, you’ve got a problem.

Next, when you verify the signature, use the command codesign -vvvv <path> to get a more detailed verification.

Also, be sure when signing to use the deep parameter, as every bit of executable code inside your app bundle will need to be signed as well.

Without me reading thru all these comments - it should be clear that the gatekeeper protection only gets enabled if a program adds the protection “flag” to the zip or dmg file. Safari, for instance, does this. Other downloading apps may not. That’s also why your freshly created zip or dmg file won’t be checked by Gatekeeper. The necessary “flag” is the quarantine attribute. Don’t know exactly how it works but others here and Google do, for sure.

[quote=58900:@Thom McGrath]Ok, time for some debugging. You’ll need your command line.

First, use the MD5 cli tool to compute the hash of each version of the file: original, direct, and WebFile. These should all be the same. If not, you’ve got a problem.

Next, when you verify the signature, use the command codesign -vvvv <path> to get a more detailed verification.

Also, be sure when signing to use the deep parameter, as every bit of executable code inside your app bundle will need to be signed as well.[/quote]
I’ll check that when I get back to the office.

If I upload the file to my server via FTP and then download it with Safari via a direct link Gatekeeper doesn’t stop the app from running. If I import the file into the WebApp and serve it up as a WebFile using WebFile.Data or I FTP the file to a web folder and serve it up with WebFile.URL Gatekeeper stops the app from running. It’s the same file downloaded with Safari in both cases, but something happens to it when it’s downloaded as WebFile that doesn’t happen when it’s a direct download. I’m going to alter the WebApplication to use an HTTP GET request instead of WebFile and see what happens.