Cheap PKCS#11 Device
A simple model for do-it-yourself software licencing is to embed a public key in your software and ship it with signed blobs that indicate the following:
- the feature that is licenced
- the expiry date of the licence
- the machine on which the licence is valid
That's fairly trivial to perform using an API like the Microsoft CNG. Of course the user may set their clock back so you must periodically re-check the licence blobs at runtime. Also you probably indicate "the machine" via mac address, hard-drive serial number and the like which aren't terribly difficult to fake/clone or specify in a VM.
So, instead of specifying a machine you could specify a public key that matches a private key on a USB PKCS#11 token. Then at runtime you ask the token to sign a nonce and if it verifies you know the users is in possession of the token.
So, all we need is an affordable USB PKCS#11 device that is willing to sign arbitrary blobs over an API. Preferably the company providing the tokens would allow custom branding on the USB case. Of course the device must resist cloning of the private key. Certainly it should not be readable over any API, and ideally attempts to open the USB case would destroy the data on the device.
An obvious alternative to the above is a licencing system that connects to a central server, in which case you could know who is running your software and from where. But if like me you have an offline requirement, then that wont work.
An unavoidable flaw with an offline system is that you have no reliable clock. It would be a benefit if the PKCS#11 device could include an internal timestamp with each signed nonce, although that requires an onboard battery.
Another flaw with an offline system is that it's difficult to revoke licences. I think you'd have to include a unique licence ID in each signed blob, then in future versions of your software you could have a list of revoked IDs. This style of revocation only effects customers who upgrade to a new binary.