Click here to Skip to main content
Click here to Skip to main content

Licensing .NET components with a PKI Token (Gemalto .NET Card) demystified

, 25 Oct 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
This article demonstrates how to write a licensing provider for .NET licensing that gets licenses from a Gemalto .NET Card V2.

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.

/// <span class="code-SummaryComment"><summary>
</span>/// This class implements a simple license repository
/// <span class="code-SummaryComment"></summary>
</span>class LicenseRepository : ItemRepository
{
    private static LicenseRepository _instance = null;

    public static LicenseRepository Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new LicenseRepository();
            }

            return _instance;
        }
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// There must be only one LicenseRepository
    /// <span class="code-SummaryComment"></summary>
</span>    private LicenseRepository()
    {
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Adds a LicenseInfo to the repository
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="name">License name</param>
</span>    /// <span class="code-SummaryComment"><param name="licenseInfo">LicenseInfo object</param>
</span>    /// <span class="code-SummaryComment"><returns>true if added, false otherwise</returns>
</span>    public bool AddLicense(string name, LicenseInfo licenseInfo)
    {
        return AddItem(name, licenseInfo);
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Remove a license from the repository
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="name">License name</param>
</span>    /// <span class="code-SummaryComment"><returns>true if removed, false otherwise</returns>
</span>    public bool RemoveLicense(string name)
    {
        bool removed = false;
        int index = FindItemIndex(name);
        if (index != NOT_FOUND)
        {
            RemoveItem(index);
            removed = true;
        }

        return removed;
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets a LicenseInfo by its name
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="name">License name</param>
</span>    /// <span class="code-SummaryComment"><returns>LicenseInfo object, null if not found</returns>
</span>    public LicenseInfo GetLicense(string name)
    {
        LicenseInfo licenseInfo = null;
        int index = FindItemIndex(name);
        if (index != NOT_FOUND)
        {
            licenseInfo = GetItem(index) as LicenseInfo;
        }

        return licenseInfo;
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets the names of the license installed in this token
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><returns></returns>
</span>    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.

/// <span class="code-SummaryComment"><summary>
</span>/// Simple LicenseInfo. This class can be completed
/// with more information about the license for the
/// given component
/// <span class="code-SummaryComment"></summary>
</span>class LicenseInfo
{
    private string componentClassName;

    public LicenseInfo(string componentClassName)
    {
        this.componentClassName = componentClassName;
    }
    /// <span class="code-SummaryComment"><summary>
</span>    /// Component class name
        /// <span class="code-SummaryComment"></summary>
</span>    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

    /// <span class="code-SummaryComment"><summary>
</span>    /// Verify the PIN
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="pinValue">PIN value</param>
</span>    public void VerifyPIN(string pinValue);

    /// <span class="code-SummaryComment"><summary>
</span>    /// Invalidate PIN if it is already verified
    /// <span class="code-SummaryComment"></summary>
</span>    public void InvalidatePIN();

    public bool IsPINBlocked;

    public bool IsPINVerified;

    public int TriesRemainingForPIN;

    #endregion

    #region Public interface for the service
    /// <span class="code-SummaryComment"><summary>
</span>    /// Install a component license
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="componentName">Component name to license</param>
</span>    /// <span class="code-SummaryComment"><param name="componentClassName">Component type name,
</span>    ///    including name spaces<span class="code-SummaryComment"></param>
</span>    /// <span class="code-SummaryComment"><returns>true if installed, false otherwise</returns>
</span>    public bool InstallLicense(string componentName, string componentClassName);

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets the list of installed licenses
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><returns>Array of license name</returns>
</span>    public string[] GetInstalledLicenseNames();

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets the license info, Compoenent class name in our case
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="name">License name</param>
</span>    /// <span class="code-SummaryComment"><returns>Component class name</returns>
</span>    public string GetLicenseInfo(string name);

    /// <span class="code-SummaryComment"><summary>
</span>    /// Get the signature for a given component.
    /// This is a simple implemetation.
    /// 
    /// Unfortunately the .NET remoting version of the .NET
    /// card cannot return a class instance. So if more info
    /// would have to be returned, you need to use [out] parameters
    /// 
    /// In this simple example we don't need
    /// to return anything except the signature
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="componentName">Component name</param>
</span>    /// <span class="code-SummaryComment"><param name="encrChallenge">Encrypted challenge</param>
</span>    /// <span class="code-SummaryComment"><returns>Encrypted signature for that component.
</span>    /// Null if the component is not registered<span class="code-SummaryComment"></returns>
</span>    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.

/// <span class="code-SummaryComment"><summary>
</span>/// Simple license implementation for Component
/// <span class="code-SummaryComment"></summary>
</span>public class ComponentLicense : License
{
    private string componentType;

    /// <span class="code-SummaryComment"><summary>
</span>    /// Creates an instance
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="componentType">Component full
</span>    /// type name (including namespace)<span class="code-SummaryComment"></param>
</span>    public ComponentLicense(string componentType)
    {
        this.componentType = componentType;
    }

    public override void Dispose()
    {
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets the license key, in our case the full
    /// type name of the license component
    /// <span class="code-SummaryComment"></summary>
</span>    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.

/// <span class="code-SummaryComment"><summary>
</span>/// Implements LicenseProvider for the Smartcard
/// <span class="code-SummaryComment"></summary>
</span>public class SmartcardLicenseProvider : LicenseProvider
{
    public SmartcardLicenseProvider()
    {
        SetupSecrets();
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Implements the GetLicense method
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="context"></param>
</span>    /// <span class="code-SummaryComment"><param name="type"></param>
</span>    /// <span class="code-SummaryComment"><param name="instance"></param>
</span>    /// <span class="code-SummaryComment"><param name="allowExceptions"></param>
</span>        /// <span class="code-SummaryComment"><returns>A ComponentLicense instance</returns>
</span>    /// <span class="code-SummaryComment"><exception cref="LicenseException">When the license
</span>    /// is not verified<span class="code-SummaryComment"></exception>
</span>    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.

/// <span class="code-SummaryComment"><summary>
</span>/// This component is licensed in the Token
/// <span class="code-SummaryComment"></summary>
</span>[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:

Licensing demo screenshot

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.

Licensing manager

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

orouit
Architect Consistel - Singapore
Singapore Singapore
Software Architect, COM, .NET and Smartcard based security specialist.
 
I've been working in the software industry since I graduated in Electrical and Electronics Engineering. I chose software because I preferred digital to analog.
 
I started to program with 6802 machine code and evolved to the current .NET technologies... that was a long way.
 
For more than 20 years I have always worked in technical positions as I simply like to get my hands dirty and crack my brain when things don't go right!
 
After 12 years in the smart card industry I can claim a strong knowledge in security solutions based on those really small computers! I'm currently back in the business to design the licensing system for the enterprise solution I'm currenly working on, using a .NET smart card (yes they can run .NET CLR!)
 
View my profile on LinkedIn
 
You can contact me for professional consulting by using the forum.

Comments and Discussions

 
QuestionLoading a prive key onto the card Pinmemberdarrylhu12-Apr-13 2:48 
AnswerRe: Loading a prive key onto the card Pinmemberorouit12-Apr-13 7:02 
AnswerRSA on Gemalto .NET Smart Card Pinmembernesto22219-Jan-12 13:44 
GeneralRe: RSA on Gemalto .NET Smart Card Pinmembernesto22219-Jan-12 23:13 
GeneralRe: RSA on Gemalto .NET Smart Card Pinmemberorouit26-Jan-12 16:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411022.1 | Last Updated 25 Oct 2011
Article Copyright 2011 by orouit
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid