Introduction
In a previous article, I showed you how to do a challenge response
authentication using an RSA certificate in a Gemalto .NET card V2. In this article, I will show you how to combine .NET licensing and the ability of this token to generate
an RSA signature of some challenge bytes. There are already many articles on the internet that show how to use the .NET licensing mechanism so I
won't go into details for that part, but concentrate on using the Smart Card to achieve a strong licensing. This technique is the one used by most of the token based
licensing products. Thanks to this Gemalto product, you can now write your own for a very reasonable price and very easily compare to what you would have had to do some time ago.
Background
Please consult my previous article about the Gemalto smart card to understand what I'm going to describe here as we are going to use it heavily.
Extending the authentication service to support .NET component licensing
In the previous article, I wrote a simple piece of code in the card that can sign with an RSA private key some challenge data.
This signature is the foundation of a licensing mechanism using a PKI token. The application or component that you want to license will generate
a random data, then send it to the Smart Card which will sign it using its private key. Then the card service returns the signature bytes
that can be encrypted, and the licensing provider will verify the signature and authorize the component to be created.
What I will add to the signature mechanism is a list of the names of the components that are licensed by the token. Keep in mind that
everything you place in this token is like in a virtual safe that cannot be broken even with the strongest attacks.
The code and data running in the token are unreachable to the user and it's not like on a hard drive or into memory that you can try to
attack. The protocol to access the code is similar to the one used in a banking Smart Card. Data or commands can be protected by PIN code and
you have three tries to guess its value that can be any ASCII string. After three tries, the code is blocked and the card is virtually destroyed. You
could try fancy hardware attacks but once again, PKI cards have strong electronic counter measures that will block the access to the data in
the chip. This is not software I'm talking here, but a hardware self destruct mechanism! There is no back door on a Smart Card, once the
administrator PIN is blocked... you can throw away the card, it's dead!
On a Gemalto card, the administrative PIN is 20 bytes and used in a cryptographic authentication... you have 5 tries to guess its value, so good luck!
Now that I have introduced the hardware safe we are going to use, let us design a simple component license repository in the card. This is a simple
list in the data that will store the class names of the components we want to license in the token.
This simple mechanism can be extended to the infinity if you want to control the number of instances, the validity period of the license, anything you have in mind!
SmartCard LicensingService
In my previous article, I demonstrated how to use the .NET card to sign a challenge data, I also described a simple login/password repository,
which means that the bricks that we need are already there.
The class ItemRepository
can now be used to implement any repository needed in the card. The .NET card framework does not support
Generics so it uses object
as the base element. Based on this class, I implemented a simple LicenseRepository
class to store the information to license components.
class LicenseRepository : ItemRepository
{
private static LicenseRepository _instance = null;
public static LicenseRepository Instance
{
get
{
if (_instance == null)
{
_instance = new LicenseRepository();
}
return _instance;
}
}
private LicenseRepository()
{
}
public bool AddLicense(string name, LicenseInfo licenseInfo)
{
return AddItem(name, licenseInfo);
}
public bool RemoveLicense(string name)
{
bool removed = false;
int index = FindItemIndex(name);
if (index != NOT_FOUND)
{
RemoveItem(index);
removed = true;
}
return removed;
}
public LicenseInfo GetLicense(string name)
{
LicenseInfo licenseInfo = null;
int index = FindItemIndex(name);
if (index != NOT_FOUND)
{
licenseInfo = GetItem(index) as LicenseInfo;
}
return licenseInfo;
}
public string[] GetLicenseNameList()
{
return GetItemAlias();
}
}
This repository stores
LicenseInfo
instances. This class can be extended as we will in order to contain more useful information to license the components.
class LicenseInfo
{
private string componentClassName;
public LicenseInfo(string componentClassName)
{
this.componentClassName = componentClassName;
}
public string ComponentClassName
{
get
{
return componentClassName;
}
}
In the AuthenticationService
the card was generating, the certificate and a method could be used to get the public key. This method cannot be
used in this case because the certificate must be the same in all the tokens that could be used to license the components. In this demo, the
certificate is static and was generated by the card itself, but it is included in the code. This means that the developer of the service can
get its value and virtually crack the licensing mechanism.
In a coming article, I will demonstrate a protocol to generate the private key with a master card and initialize the licensing card so that
even the developer of the application can not get the certificate private key. Such a mechanism is mandatory for a secure environment
like banking. It can also be applied when licensing an application or components because your work is money!
The LicensingService provides the following interface that can be used with the card remoting.
public class LicensingService : MarshalByRefObject
{
#region Public PIN methods
public void VerifyPIN(string pinValue);
public void InvalidatePIN();
public bool IsPINBlocked;
public bool IsPINVerified;
public int TriesRemainingForPIN;
#endregion
#region Public interface for the service
public bool InstallLicense(string componentName, string componentClassName);
public string[] GetInstalledLicenseNames();
public string GetLicenseInfo(string name);
public byte[] GetLicenseSignature(string componentName, byte[] encrChallenge);
#endregion
}
A LicenseProvider using the LicensingService
Now that we have a token that can be used to license a component, we need to connect the dots and use it with the licensing mechanism of .NET.
The .NET Framework provides a mechanism to decorate a class that must inherit from Component
to semi-automatically call the license
verification. My objective is not to describe in detail this mechanism but just to use it, so you can get more information
about .NET licensing in this article.
You need to implement two classes from the System.ComponentModel
namespace: License
and LicenseProvider
.
In each class, a few methods must be implemented but you can create your own methods to support more complex licensing features.
For the License
class, only one method and one property have to be implemented. Below is a primitive implementation for the ComponentLicense
.
public class ComponentLicense : License
{
private string componentType;
public ComponentLicense(string componentType)
{
this.componentType = componentType;
}
public override void Dispose()
{
}
public override string LicenseKey
{ get { return componentType; }
}
}
The second class that must be implemented is the LicenseProvider
itself. An extract of the implementation for the
SmartcardLicenseProvider
is given below. One single method has to be implemented and it is responsible to verify and provide the license itself.
public class SmartcardLicenseProvider : LicenseProvider
{
public SmartcardLicenseProvider()
{
SetupSecrets();
}
public override License GetLicense(LicenseContext context,
Type type, object instance, bool allowExceptions)
{
License license = GetComponentLicense(type);
if (license == null)
{
throw new LicenseException(type);
} return license;
}
#region Private methods
private void SetupSecrets()
{
aesAlgo = Rijndael.Create();
aesAlgo.Key = AESKey;
aesAlgo.IV = AESIv;
rsaAlgo.ImportParameters(RSATokenPublicKey);
}
private ComponentLicense GetComponentLicense(Type componentType)
{
ComponentLicense license = null;
using (LicensingServer licensingServer = new LicensingServer())
{
byte[] challenge = GetChallenge();
byte[] encrChallenge = AESEncrypt(challenge);
byte[] encrSignature =
licensingServer.GetSignatureForLicense(
componentType.Name, encrChallenge);
if (encrSignature != null)
{
byte[] signature = AESDecrypt(encrSignature);
if (VerifySignature(challenge, signature))
{
license = new ComponentLicense(componentType.FullName);
}}
}
return license;
}
}
The key method is the GetComponentLicense()
method that authenticates the token for the given component. In a more complex scenario, this method would collect information from the
token for the component license. In this example, it simply requests an authentication for a given component/license name.
Once those two classes are implemented, the licensing of the component itself is very simple.
[LicenseProvider(typeof(SmartcardLicenseProvider))]
public class LicensedComponent : Component
{
public LicensedComponent()
{
ComponentLicense license =
LicenseManager.Validate(this.GetType(), this) as ComponentLicense;
}
}
You only need to decorate the class you want to license with the attribute LicenseProvider
and call in the constructor the static method
Validate()
of the LicenseManager
. It returns a License
that you can cast to your own type.
Demo application
The token I created to run the demonstration has only one license for the component LicensedComponent
. The demo application tries to create
an instance of LicensedComponent
and one of UnlicensedComponent
.
class Program
{
static void Main(string[] args)
{
try
{
LicensedComponent component1 = new LicensedComponent();
Console.WriteLine("LicensedComponent created!");
UnlicensedComponent component2 = new UnlicensedComponent();
Console.WriteLine("LicensedComponent created!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
This code produces the following result:
The instance of LicensedComponent
can be created but the constructor of UnlicensedComponent
throws a LicenseException
.
Simple license manager application
The LicensingService has two aspects, a method called by the license provider to verify the license and that doesn't need the PIN to be verified, and a set of methods used
to administrate the licenses in the token. Those methods are protected by a PIN which is of course not available for the user of the components.
Points of interest
Cryptography is the domain of brilliant mathematicians but fortunately frameworks like .NET give us implementation for those complex algorithms,
and people like me (who are not mathematicians!) can use them and build things. The importance of a theory like cryptography for IT engineers
or developers is what you can design with it to solve day to day problems in your working life.
RSA public key is a very good example of that. It is used by many security protocols in the IT industry like, for example, the WS-* standards in WCF when security
is enabled using certificates, Windows log on using Smart Cards, or simply signing your favorite .NET assemblies. You can find a lot of literature on the internet
about RSA PKI (Public Key Infrastructure).
Using a PKI token is a very strong licensing method but unfortunately, there is a major weakness in the process which is the .NET platform
itself. Basically, it's a bit like using a bank vault door for your wooden house! No one will be able to break or open the door but one
just need to cut an entry through the walls with a good chainsaw... With a .NET application, the chainsaw is a decompiler like Reflector.
I used it a few years ago to modify and recompile some Microsoft tools when working on the CTP of CardSpace.
I don't have a magic solution for that but you can make it very difficult to break:
- Sign the libraries that are part of the component you want to license
- Obfuscate and sign the DLL that does the license verification
- Systematically use a private implementation for your public interface and obfuscate your DLLs
Although obfuscation doesn't hide the logic and the call to the framework methods, it is going to be very difficult to reconstruct the puzzle of many private methods
calling other private methods when you only have their signature.
In our door and walls metaphor, the code you distribute is the walls. If someone can extract all the bricks and rebuild the walls without the
door... a strong licensing won't serve any purpose! On the other hand, if when they reconstruct the walls some bricks cannot be put at the
right place and the walls are collapsing, then licensing can be useful.