Overview

You've got a hot new product, ready to sell - You're a pro now! But part of that professionalism is making sure you have signed versions of all your drivers. If you're using a FTDI or Cypress or SiLabs chip to do USB, you might already have a signed driver that comes with it.

If not, its an extra step and expense that will make your life (and your customer's lives!) much easier. These are my notes as I signed a Circuit Playground CDC driver file, made an installer, then signed that installer

 More details!

Big ups to Pololu-pal David Grayson's intensely detailed tutorial which taught me everything I know! :)

http://www.davidegrayson.com/signing/#howto

Really, read the above if you need more than these steps, or read both tutorials at once for stereo-vision learning

Installing Windows SDK

Visit Microsoft's SDK download page to grab the latest standalone SDK. Even though this is the Windows 10 SDK, you can install it on Windows 7 if you need to.

https://dev.windows.com/en-us/downloads/windows-10-sdk

Its ok to install in C:\Program Files(x86)\Windows Kits\10\

The screenshot below shows the minimal set of features you need to install to do signing: Windows IP over USB (required by SDK for UWP), Windows SDK Signing Tools for Desktop Apps (installs signtool.exe), and Windows SDK for UWP Managed Apps (installs certmgr.exe). You can install more if you're doing Windows development.

Done!

You can now find signtool.exe and certmgr.exe in C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64 (or a newer version, if one has been released). Previous SDK installations did not include a version number in the path.

Download Windows WDK (Windows Driver Kit)

Go to https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk and download the latest WDK (not ADK, scroll down!). You don't need to install Visual Studio first even though it looks like a prerequisite. Install into the same location:

This warning is OK.

Half an hour later...WDK is installed!

Now you can check C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86  (or whatever version you installed) to see that you have a new tool called inf2cat.exe.

Buy & Download Certificate

In order to sign a driver you need a Code Signing Certificate - once purchased you can use it for a period of time to sign as much code/drivers as you like. For example, a 3 year certificate can be used for 3 years to sign drivers as needed. After 3 years, all your signed drivers still work great but you will have to buy a new cert if you have code you would like to sign a-new

Buy Code Signing Certificate

We bought our cert from GlobalSign

Make an account, it will have a strange usrename that starts with PAR

You can click on Order Certificates - we already did so we have a certificate we paid for a few years ago, certificates cost ~$500

To re-download your certificate you'll have to click EDIT to the left of the Order ID. Which is so counter-intuitive but basically you are re-issuing the cert.

Continue through and pick a secure Pickup Password, this password is only used to download the certificate, it isnt the password for the cert itself!

Pick a hash algorithm. For backwards compatibility with XP SP2 you can request SHA-1 but these days you should probably just go with SHA-256 since it is more secure

Click Next...this will have the pickup email sent to the email address associated with the account.

Check your email, you'll have the pickup link in there. Click it!

You'll be asked for that password from before. If by chance you forgot it in the last 5 minutes, you'll need to start over.

You'll now be asked to be a private key for the certificate. You'll need this to install the certificate. Keep this secret from getting out or someone could be able to sign malware with your name, no good eh?!

OK finally - download the certificate file!

Install Certificate

OK how that you have the pfx file, right click on it and Install it!

Go through the wizard to install the cert...

Make sure the right file is selected:

To install, you'll need to enter in that long private key you put in doing the pickup process. I recommend marking the key as exportable, so you don't have to go thru the pickup process if another person needs to install it and you lost the certificate file.

You can use the Automatic Store to put it in your cert manager

And, Finish!

Checking Installed Cert

Now that you have the certificate, its easy to check it out in your Cert Manager.  Visit C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86 and run certmgr.exe

In Personal, you'll be able to see your signing cert!

You can click on Advanced to get more details about the cert:

Download Intermediate Certificate

Finally, you need the matching root certificate file from GlobalSign. Go here to download it, you'll need to cross-lookup the right cert, for SHA-256 its Root-R3.crt

Save the root certificate to your Desktop, you'll need it in the next step

Signing Driver

We'll be signing a serial port inf driver file. Basically this just tells Windows "Hey use the CDC Serial driver you have already" but lets it know the name, VID and PID for the device.

You can use our generic INF file, just be sure to edit it to change the VID/PID and identifier strings!

I recommend having the name of the inf not have space in it, just during the signing process

Also, put the inf into a folder on your desktop, also without spaces in it.

Only perform these steps on one inf at a time, in a single folder. srsly.

For example, I put AdafruitCircuitPlayground.inf into C:\User\ladyada\Desktop\CircuitPlayDriver

Inf2Cat

To start you'll need to create a catalog file for the inf. You will use inf2cat for this

Run this command in the directory with the inf file

E.g. if the driver inf is in C:\Users\ladyada\Desktop\CircuitPlayDriver, open up a command line and cd C:\Users\ladyada\Desktop\CircuitPlayDriver

"C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86\inf2cat" /v /os:XP_X86,Vista_X86,Vista_X64,7_X86,7_X64,8_X86,8_X64,6_3_X86,6_3_X64,10_X86,10_X64 /driver:.

(The screenshot below is slightly obsolete: it doesn't have the version number in the path.)

Add the Root Certificate

Copy that root certificate you downloaded at the end of the last step into the same directory

Signing!

OMG are you ready??? It's finally time to sign the driver!

Open up a new command line and go to the directory with the inf & cat in it

"C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86\signtool" sign /v /n "Your company name" /ac "Root-R3.crt" /tr http://timestamp.globalsign.com/?signature=sha2 /td sha256 *.cat

Of course, change Your Company Name to the certificate name's owner, and the intermediate certificate name if necessary.

(The screenshot below is slightly obsolete.)

Now if the driver gets installed, the user will see the following, a happy installer!

Making an Installer

OK now you have a nice signed driver, so lets make a fancy installer so people can just double-click to install

These instructions are pretty much the same as the great tutorial at:

blog.codebender.cc/2016/01/04/create-a-simple-windows-driver-installer-using-nsis/

I installed 3.0b3, the latest version as of this tutorial's writing

Find DPinst

This is the Microsoft driver installation software which came with the WDK you installed earlier.

Go to C:\Program Files (x86)\Windows Kits\10\Redist\DIFx and you can find many versions.

I recommend grabbing

C:\Program Files (x86)\Windows Kits\10\Redist\DIFx\dpinst\MultiLin\x64\dpinst.exe

and putting it in your driver folder, called dpinst-x64.exe

Also grab

C:\Program Files (x86)\Windows Kits\10\Redist\DIFx\dpinst\MultiLin\x86\dpinst.exe

and put that also in your driver folder, called dpinst-x86.exe

 

Create a configuration file!

You can spend a ton of time making super customized installation programs - ours originally was for installing a wide range of drivers, here's the core of it

Download: file
# Adafruit Board Driver NSIS Install Script
# Author: Tony DiCola

# Import some useful functions.
!include WinVer.nsh   # Windows version detection.
!include x64.nsh      # X86/X64 version detection.

# Set attributes that describe the installer.
Icon "Assets\adafruit.ico"
Caption "Adafruit Board Drivers"
Name "Adafruit board drivers"
Outfile "adafruit_cplay.exe"
ManifestSupportedOS "all"
SpaceTexts "none"

# Install driver files to a temporary location (then dpinst will handle the real install).
InstallDir "$TEMP\adafruit_cplay"

# Set properties on the installer exe that will be generated.
VIAddVersionKey /LANG=1033 "ProductName" "Adafruit Circuit Playground Driver"
VIAddVersionKey /LANG=1033 "CompanyName" "Adafruit Industries"
VIAddVersionKey /LANG=1033 "LegalCopyright" "Adafruit Industries"
VIAddVersionKey /LANG=1033 "FileDescription" "Installer for Adafruit Circuit Playground board driver."
VIAddVersionKey /LANG=1033 "FileVersion" "1.0.0"
VIProductVersion "1.0.0.0"
VIFileVersion "1.0.0.0"

# Define variables used in sections.
Var dpinst   # Will hold the path and name of dpinst being used (x86 or x64).

# Components page allows user to pick the drivers to install.
PageEx components
  ComponentText "Check the board drivers below that you would like to install.  Click install to start the installation." \
    "" "Select board drivers to install:"
PageExEnd

# Instfiles page does the actual installation.
Page instfiles


# Sections define the components (drivers) that can be installed.
# The section name is displayed in the component select screen and if selected
# the code in the section will be executed during the install.
# Note that /o before the name makes the section optional and not selected by default.

# This first section is hidden and always selected so it runs first and bootstraps
# the install by copying all the files and dpinst to the temp folder location.
Section
  # Copy all the drivers and dpinst exes to the temp location.
  SetOutPath $INSTDIR
  File /r "Drivers"
  File "dpinst-x64.exe"
  File "dpinst-x86.exe"
  # Set dpinst variable based on the current OS type (x86/x64).
  ${If} ${RunningX64}
    StrCpy $dpinst "$INSTDIR\dpinst-x64.exe"
  ${Else}
    StrCpy $dpinst "$INSTDIR\dpinst-x86.exe"
  ${EndIf}
SectionEnd

Section "Circuit Playground"
  # Use dpisnt to install the driver.
  # Note the following options are specified:
  #  /sw = silent mode, hide the installer but not OS prompts (critical!)
  #  /path = path to directory with driver data
  ExecWait '"$dpinst" /sw /path "$INSTDIR\Drivers\Adafruit_CircuitPlayground"'
SectionEnd

Place this file in the directory with dpinst-x86 and dpinst-x64

In Assets, put an ico file with your logo

Inside Drivers put another folder that contains the actual driver files. E.g. Drivers/CircuitPlayground/circuitplay.inf this way you can expand the installer to install more software & drivers easily

If you'd like you can check out our package for the structure:

Go back to the NSI file, right click and Compile it

Read thru the text to make sure everything was found properly!

You can now test it out - double click to run the installer

Check the Details again, to verify the installer did what its supposed to do

Sign the Installer

OK since you have everything set up its easy to also sign the installer! Go into the directory where you have the generated exe and run

"C:\Program Files (x86)\Windows Kits\10\bin\x86\signtool" sign /v /n "Company Name" /tr http://timestamp.globalsign.com/?signature=sha2 /td sha256 driverinstaller.exe

When the customer double clicks, it will let them know that this is Verified to be from Adafruit Industries!

You can see information about the certificate if you Show Details:

You can also check the exe properties:

This guide was first published on Mar 14, 2016. It was last updated on Mar 14, 2016.