gosu / releasy

A rake task generator to help with building/packaging/deploying Ruby applications (⚠️ unmaintained)
https://spooner.github.com/libraries/releasy/
MIT License
378 stars 29 forks source link

Feature Request: Code Signing, and some extra security... #39

Closed Harrison-Uhl closed 11 years ago

Harrison-Uhl commented 11 years ago

Hi:

I'm developing a Ruby app that I want to distribute as an all-in-one (e.g. a Windows .exe file) I'd also like to keep some of my code private-ish (the really private stuff is only on my server as a Web Service.)

More important than private-ish is that users can easily confirm that what they have received has not been modified by others along the way.

My thought is to sign the exe file as per Window's signed apps. Unfortunately, if the Ruby app is left installed, this does not cover the actual Ruby source code. (It only covers the source code at the time of extraction from the exe file. However, later a user might modify the code to try to reverse engineer the app, or perhaps a virus....)

I see that Ruby Gems provide for a cryptographic signature that can be checked on install. I'd be perfectly happy to place most of my code in signed gems. But this still falls short. Once the gem is installed, there appears to be no further checks.

REQUEST 1) If the (Windows signed) exe file could hold a Public key to confirm the authenticity of the files installed, and Releasy could hash and sign the Ruby source files (and perhaps designated data files) at the time the exe is made -- using a private key that never leaves the packager's computer, then there is a strong authentication path from the signed installed files all the way back to a well established certificate authority. (In use, the Releasy generated exe would first look for a permanent install, and if it found one, it would confirm the sigs instead of doing a full unpack.)

I also anticipate that my app will have additional plugins (perhaps as signed gems) that the app will want to download and install. As these could be signed by my private key, the Releasy generated exe could also confirm these using it's build in public key. The exe file would need some way to tell the Ruby app what files passed or failed the sig tests.

As no one could change the embedded public key in the exe file without breaking the Windows signature for the exe file itself, this should provide a path for 'delegation of trust'. (I'm not sure exactly when Windows checks the signatures e.g. only on install, on file modification, and/or on demand -- but I'm prepared to tell the users what extra steps they need to do to confirm the sigs anytime they want.)

REQUEST 2) While I understand that anything can be decompiled given enough time, I'm also interested in increasing the effort required -- if it can be done easily.

The Ruby interpreter can take Ruby source from the standard input. My request is that the Releasy generated exe optionally feed the top level script file directly to Ruby's standard input. (As such, this top level script file need never be written, in plain text, to a file on the end use's hard disk, thereby considerably upping the decompile effort.)

If the Releasy exe is feeding to Ruby's standard input, then this might also be the most secure path to tell the app the results of any sig tests done on source files. This path would also provide a more secure place to hide/protest things like other credentials/encryption keys/... (They could be embedded in the top level script that is never written in plain text to the user's hard disk.)

REQUEST 3) Please consider adding provisions for either a splash screen, or a start up progress bar so that users can be reassured that the delays in starting the app are normal and expected.

Thanks Harrison

bil-bas commented 11 years ago

Your requests seem sensible, but they are well out of the capacity and intention of Releasy to provide. When building for Windows on Windows, Releasy is essentially just a wrapper around running the Ocra gem. When building for Windows on other operating systems, the EXE is always the same, having been built on Windows by Ocra and all Releasy does is hack that exe to change the Ruby script run. Essentially this means that you should be asking https://github.com/larsch/ocra for this functionality, since that is what creates the EXE even in Releasy - if it is added there, I definitely try to support its use from Releasy, though I wouldn't be able to offer that functionality if building cross-platform

Some other thoughts, however:

2) I think this is probably not worthwhile in general. Any real Ruby application would contain many files, so just making the first one "hidden" would not help unless the application was tweaked to work that way. The Crate gem used a database to hold all the files and patched require/load/import methods (and now, require_relative would need to be patched too) so that they would load these files. This reduced the number of files and obviously decreased load-time. As far as I'm aware, Crate isn't supported any more and doesn't support Ruby 1.9, but it sounds like possibly a better technique to hide code if you are super-keen)

:windows_standalone is probably your best option at the moment, though even in this case, it is trivial to access the files if the user has any clue at all about how Ocra works, though since that adds 1-2seconds to startup your app, I wouldn't recommend it.

3) In this case, I often try to load up my window with the minimum number of gems loaded as possible, then I can show a message while I load the remaining gems.

Harrison-Uhl commented 11 years ago

A further thought: If Releasy's run-time exe could feed first one, then perhaps other Ruby scripts to the standard input of the Ruby interpreter, then pretty much everything could be done in Ruby. (There would have to be a way for the first script to tell the exe what to do next.)

This approach opens many possibilities without having to code them all at the C level.

bil-bas commented 11 years ago

Refer to my previous answer. However useful this functionality might be, it has nothing to do with Releasy, but rather its dependency (Ocra). Sorry!