Create an ISV license from a cryptographic USB token

This post is a product of not reading the full documentation. Lesson #1: read the docs thoroughly, or at least don’t stop reading when you think you’re done.

Publishing an ISV solution

One of the steps when you want to publish an ISV solution is generating the license for your customers. This license has to be signed  using an Authenticode certificate that will enable the solution, limit the number of users or set an expiration date.

If you check the docs you can see the certificate must meet some minimum requirements:

  • Authenticode certificate (X.509) from a certificate authority (CA)
  • The certificate key size must be either of 1024-bit or 2048-bit. 4096-bit keys are not supported

And the idiot writing this stopped reading there, contacted the certificate reseller and ordered a CodeSign certificate with the above requirements. After some weeks I received the USB token and downloaded the certificate.

I was ready to finish developing the solutions and generate the licenses, so I continued reading the docs until I got to the “Certificate import and export“ section and I saw this:

  • Personal Information Exchange (PFX, also known as PKCS #12) – The PKCS #12 format, which uses the .pfx file name extension, supports secure storage of certificates, private keys, and all certificates in a certification path. The PKCS #12 format is the only file format that can be used to export a certificate and its private key.

And now the best part: the purpose of a USB eToken is to hardware protect the private key, which makes exporting the private key  impossible! I’m a stupid with an expensive private key inside a USB!

I’m NOT ordering another certificate

After contacting the reseller and the CA and confirming there’s no way of exporting the private key I started looking for a workaround.

How is the license created? Using the axutil command which also existed to manage models in AX2012. The excutable is found in the PackagesLocalDirectory’s bin folder, and there’s an AXUtilLib.dll library too.

Probably what I’ve done is not allowed by the license, but the available tools would not solve my issue and I’ve had to make my own 🤷‍♂️

I went on and disassembled the DLL and started checking the classes. The executable tool expects a certificatepath parameter, this should be the private key PFX file, but I don’t have it.

We have a class called AXUtil with a GenerateLicense method:

The this.Config.LicenseInfo parameter passed includes the arguments from the command line. So, instead of using the certificate from that path I’ll do the following:

This will allow us to select which certificate to use (from out certificates) and will pass it to LicenseGenerator’s GenerateLicense method. This method accepts no parameters, but thanks to C#’s method overloading I can do this:

And now I can use my method. I’ve had to do one more change to the original AXUtilLib library: changing thee LicenseInfo setters to public.

ISVLicenseGenerator

I’ve created a graphic tool that makes use of this modified library and allows us to create a valid license file with a USB eToken:

The source code of this tool (and the modified DLL) and an executable file ready to use can be downloaded from GitHub, and you can do whatever you want with it. I just hope I don’t receive a notice from Microsoft…

As you can see all you need to do is select the license path and complete the data, like it’s done in the command line tool.

Click on “Generate” and the prompt to select your certificate will appear:

After selecting the certificate, the USB software will prompt for the password:

And done! We have a valid license file generated and ready to be deployed to the customer environments:

I hope that my stupidity will help someone!