Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

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

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
25 Oct 2011CPOL8 min read 30.5K   1K   42   5
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.

C#
/// <summary>
/// This class implements a simple license repository
/// </summary>
class LicenseRepository : ItemRepository
{
    private static LicenseRepository _instance = null;

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

            return _instance;
        }
    }

    /// <summary>
    /// There must be only one LicenseRepository
    /// </summary>
    private LicenseRepository()
    {
    }

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

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

        return removed;
    }

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

        return licenseInfo;
    }

    /// <summary>
    /// Gets the names of the license installed in this token
    /// </summary>
    /// <returns></returns>
    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.

C#
/// <summary>
/// Simple LicenseInfo. This class can be completed
/// with more information about the license for the
/// given component
/// </summary>
class LicenseInfo
{
    private string componentClassName;

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

C#
public class LicensingService : MarshalByRefObject
{
    #region Public PIN methods

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

    /// <summary>
    /// Invalidate PIN if it is already verified
    /// </summary>
    public void InvalidatePIN();

    public bool IsPINBlocked;

    public bool IsPINVerified;

    public int TriesRemainingForPIN;

    #endregion

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

    /// <summary>
    /// Gets the list of installed licenses
    /// </summary>
    /// <returns>Array of license name</returns>
    public string[] GetInstalledLicenseNames();

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

    /// <summary>
    /// 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
    /// </summary>
    /// <param name="componentName">Component name</param>
    /// <param name="encrChallenge">Encrypted challenge</param>
    /// <returns>Encrypted signature for that component.
    /// Null if the component is not registered</returns>
    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.

C#
/// <summary>
/// Simple license implementation for Component
/// </summary>
public class ComponentLicense : License
{
    private string componentType;

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

    public override void Dispose()
    {
    }

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

C#
/// <summary>
/// Implements LicenseProvider for the Smartcard
/// </summary>
public class SmartcardLicenseProvider : LicenseProvider
{
    public SmartcardLicenseProvider()
    {
        SetupSecrets();
    }

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

C#
/// <summary>
/// This component is licensed in the Token
/// </summary>
[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.

C#
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)


Written By
Architect Connect In Private
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've been back into business to design the licensing system for the enterprise solution for Consistel using a .NET smart card (yes they can run .NET CLR!)

I'm currently designing a micro-payment solution using the NXP DESFire EV1 with the ACSO6 SAM of ACS. I can then add a full proficient expertise on those systems and NFC payments.
This technology being under strict NDA by NXP I cannot publish any related article about it, however I can provide professional consulting for it.

You can contact me for professional matter by using the forum or via my LinkedIn profile.

Comments and Discussions

 
QuestionLoading a prive key onto the card Pin
darrylhu12-Apr-13 1:48
darrylhu12-Apr-13 1:48 
AnswerRe: Loading a prive key onto the card Pin
orouit12-Apr-13 6:02
professionalorouit12-Apr-13 6:02 
Hi,

I don't have much time to do it right now but here is what you should do:

1 - Write a method to export the private key of the master card. You need to use your own format to export the key as the RSAParameter class won't allow you that.

2 - For the slave card you must write a method to import the exported private key.

You can create a simple byte format to export the private key. The .NET library of the card is quite limited.
Software Architect, COM, .NET and Smartcard security specialist.

AnswerRSA on Gemalto .NET Smart Card Pin
nesto22219-Jan-12 12:44
nesto22219-Jan-12 12:44 
GeneralRe: RSA on Gemalto .NET Smart Card Pin
nesto22219-Jan-12 22:13
nesto22219-Jan-12 22:13 
GeneralRe: RSA on Gemalto .NET Smart Card Pin
orouit26-Jan-12 15:52
professionalorouit26-Jan-12 15:52 

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

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