I am building a Windows (Service) application that, in short, consists of a "bootstrapper" and an "engine" (an object loaded by the bootstrapper, which transfers control to it, and then performs the actual tasks of the application). The bootstrapper is a very basic startup routine that has few features that are likely to change. But the engine itself could be subject to upgrades after installation, and I am implementing a mechanism so that it can upgrade itself - by contacting a "master server" and checking its version number against a "most current" version. If there is a newer version of the engine available, it will download it into a designated folder and call a method in the bootstrapper to "restart".
So, whenever the bootstrapper starts up, it uses MEF to "scan" the appropriate directories for implementations of IEngine, compares their bootstrapper compatibility numbers and picks the newest compatible engine version. Then it transfers control to the engine (which then, in turn, performs the update check etc). If there are no eligible IEngines - or MEF fails during composition - it falls back on a default, built-in implementation of IEngine.
This application will be running on a remote server (or several), and the whole rationale behind this is to keep manual application maintenance to a minimum (as in not having to uninstall/download new version/reinstall etc).
So, the problem: Since the bootstrapper effectively transfers program execution to a method on the IEngine object, a malicious IEngine implementation (or impersonator) that somehow found its way to the application's scanned folders could basically wreak total havoc on the server if it got loaded and was found to be the most eligible engine version.
I am looking for a mechanism to verify that the IEngine implementation is "authentic" - as in issued by a proper authority. I've been playing around with some home brewn "solutions" (having IEngine expose a Validate function that is passed a "challenge" and has to return a proper "Response" - in various ways, like having the bootstrapper produce a random string that is encrypted and passed to the engine candidate, which then has to decrypt and modify the string, then hash it, encrypt the hash and return it to the bootstrapper which will perform a similar string modification on its random string, then hash that and compare that hash to to the decrypted response (hash) from the candidate etc), but I'm sure there are features in .Net to perform this kind of verification? I just looked at Strong Naming, but it seems it's not the best way for a system that will be dynamically loading yet unthought-of dlls..
Input will be greatly appreciated.