Changes between Version 11 and Version 12 of libwdi/signed_driver_walkthrough


Ignore:
Timestamp:
04/19/11 12:01:21 (2 years ago)
Author:
pbatard
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • libwdi/signed_driver_walkthrough

    v11 v12  
    1 [http://libusb.org/wiki/libwdi/usage (Previous)] [http://libusb.org/wiki/libwdi#Documentation (Back to Table of Content)] 
    2  
    3 = Signed Driver Walkthrough = 
    4 [[PageOutline(2-5, Signed Driver Walkthrough)]] 
    5  
    6 This section documents the use of a driver signing digital credential and libwdi to create a driver installer application that allows the installation of a Windows driver without prompts.[[BR]] 
    7  
    8 == Prerequisites == 
    9  
    10  1. A set of driver binaries, along with a static inf file matching the devices you plan to support (the inf that libwdi generates cannot work, as it would then need to be signed on the fly, meaning that that you would have to embed the private key used for signing in your application, with is not something you should ever do) 
    11  1. A valid driver signing certificate (see "Obtaining a driver signing certificate") 
    12  1. The latest libwdi source, and one of the supported libwdi development environments. Since you will also need the latest WDK below, it might be a good idea to use it as your development environment 
    13  1. The [http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=36a2630f-5d56-43b5-b996-7633f2ec14ff latest WDK] 
    14  
    15 For the purpose of this exercise, I will be using libusb-win32_ft2232_driver files from the latest [http://www.freddiechopin.info/index.php/en/download/category/10-openocd-dev OpenOCD-dev 0.5.0] as well as driver signing credentials obtained from !GlobalSign (this would be a .pfx, along with the private key password). The development toolchain will be WDK 7.0.0. 
    16  
    17 == Obtaining a driver signing certificate == 
    18  
    19 To be able to digitally sign a Windows driver, you need a Microsoft Authenticode code signing credential. A credential consists of a public key, embedded in a public certificate, containing your trusted third party verified information, as well as the matching private key, which is used to encrypt what is meant to be decrypted using the public key. 
    20  
    21 Most of the driver signing credentials I am aware of seem to originate either from [http://www.verisign.com/ VeriSign] or [http://www.globalsign.com/ GlobalSign]. Other Certification Authorities providing these services [http://www.microsoft.com/whdc/driver/install/drvsign/crosscert.mspx also exist], but Verisign and !GlobalSign are the two that appear to be most commonly used. 
    22  
    23 '''Verisign''' 
    24 * 1st year driver signing credentials [https://winqual.microsoft.com/help/why_is_a_digital_certificate_required_for_winqual_membership.htm can be obtained for $99] 
    25 * A lot more expensive than !GlobalSign in the long run: $499/year 
    26 * Might not provide credentials for non registered companies 
    27  
    28 '''Globalsign''' 
    29 * More competitive on pricing compared to Verisign 
    30 * Even if non affiliated to a registered company, individual developers can obtain certificates for [http://www.globalsign.com/code-signing/code-signing-for-individual-developers.html $99 (US & Canada)] / [http://www.globalsign.eu/code-signing/buy-code-signing-for-individual-developers.html  €79 (EU)] (promotional offer) 
    31 * More friendly to non-US based customers (based in Belgium) 
    32  
    33 From the date of registration, delivery of your certificate can take from a few days, to a few weeks. 
    34  
    35 == Signing the driver binaries == 
    36  
    37 After downloading either one of the openocd[-x64]-0.5.0-dev windows binaries, one can find the libusb-win32_ft2232_driver-101028.zip archive in the drivers/ directory. 
    38 After further extracting that archive, you will find that it contains an inf file, along with the amd64/ and x86/ containing the the actual driver binaries. If you look at the binaries' properties, on the Digital Signatures tab, you will find that they have already been signed by the libusb-win32 developers (so that they can be installed on Windows outside of test mode). This is not a problem as the signature we are going to create is going to replace any existing one. If you were to recompile the [https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/ libusb-win32] drivers from source, you would of course have no signature. And of course, since there is no signed .cat, the inf is also not signed. 
    39  
    40 '''Timestamping''' 
    41  
    42 While using a trusted time source for signature creation or validation is something you should always consider when using PKI, the reason you want to use timestamping from a trusted timestamping authority when signing your drivers is because it ensures that they can still be used in Windows after the code signing certificate expires. If you don't use timestamping when signing your driver files, then you will have to provide all your users with updated drivers if your original certificate expired. For instance, if you purchased a one year certificate and didn't timestamp, your drivers will cease functioning after one year. 
    43  
    44 Windows Authenticode Certifications Authorities usually provide a timestamping service (usually a dll) that you can reference when signing. Currently these URLs are: 
    45 * http://timestamp.verisign.com/scripts/timstamp.dll (Verisign) 
    46 * http://timestamp.globalsign.com/scripts/timstamp.dll (!GlobalSign) 
    47  
    48 '''Additional Certificate''' 
    49  
    50 While the Windows certificate store has both the !GlobalSign and Verisign root CA certificates as Trusted Root Certification Authorities, these CA certificates are not the ones used for driver code signing. Instead Microsoft have their own "Microsoft Code Verification Root" certificate (which, curiously, will not appear at the top of the certification chain for signed code certificates), which they used to sign the root certificate used by the Certification Authorities they entrusted to provide Authenticode credentials to customers. Microsoft calls that a cross certificate. 
    51  
    52 By default however, Windows platforms only have the Microsoft Code Verification Root certificate installed, not the the ones from subsidiaries, therefore, to be able to validate the trust chain, the CA's Authenticode root certificate must also be provided. 
    53  
    54 In short, this means that you will also need to download the root Authenticode certificate from, !GlobalSign, Verisign or your other third party authority, so that it can be embedded in the signature. Currently, these certificates can be obtained from: 
    55 * http://www.microsoft.com/whdc/driver/install/drvsign/crosscert.mspx#EWAAC (Verisign) 
    56 * http://www.microsoft.com/whdc/driver/install/drvsign/crosscert.mspx#EMG (!GlobalSign) 
    57 For the record, all the certificates above seem set to expire on 2016.05.23. What happens to Windows signed driver users past that date is something that probably warrants some testing... [TODO] 
    58  
    59 Hint: For some weird reasons, Microsoft thought it was a good idea to provide these certificates in the form of an executable. If you want to extract certificate without running the exe, just open it in [http://www.7-zip.org/ 7-Zip], then open the _winzip_ file you'll find there, and you'll get to the MSCV-GlobalSign.cer or MSCV-VSClass3.cer certificates. 
    60  
    61 '''Signing process''' 
    62  
    63 With your driver signing .pfx file, the corresponding private key password, the MSVC-#### certificate above and the timestamp URL, you are now good to sign your driver files. 
    64 It is probably a good idea to place the CA certificate along with your pfx in an easily accessible directory. In the example below, we will use the akeo.pfx driver signing credentials, obtained from !GlobalSign, as well as MSCV-GlobalSign.cer from the D:codesign directory. The timestamping authority will also be the one from !GlobalSign. 
    65 Preferably you want to sign all the driver files, including the DLLs, but technically, only the .sys should be required. 
    66  
    67 To sign the file, open one of the WDK dos prompts (eg. Windows XP x86 Free Build Environment), then navigate to the directory containing the driver files you want to sign (eg "libusb-win32_ft2232_driver-101028amd64libusb0.sys" and issue the following: 
    68  
    69 {{{ 
    70 D:libusb-win32_ft2232_driver-101028amd64>signtool sign /v /ac D:codesignMSCV-GlobalSign.cer /f D:codesignakeo.pfx /p "<YOUR_PASSWORD>" /t http://timestamp.globalsign.com/scripts/timstamp.dll libusb0.sys 
    71 The following certificate was selected: 
    72     Issued to: Akeo Consulting 
    73     Issued by: GlobalSign ObjectSign CA 
    74     Expires:   Sun Jun 26 10:05:35 2011 
    75     SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    76  
    77 Cross certificate chain (using machine store): 
    78     Issued to: Microsoft Code Verification Root 
    79     Issued by: Microsoft Code Verification Root 
    80     Expires:   Sat Nov 01 13:54:03 2025 
    81     SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3 
    82  
    83         Issued to: GlobalSign Root CA 
    84         Issued by: Microsoft Code Verification Root 
    85         Expires:   Mon May 23 17:10:51 2016 
    86         SHA1 hash: 3EEB2750A199F5E7B6A8952430BE5062FE04E9E5 
    87  
    88             Issued to: GlobalSign Primary Object Publishing CA 
    89             Issued by: GlobalSign Root CA 
    90             Expires:   Fri Jan 27 12:00:00 2017 
    91             SHA1 hash: 1AAF4DF10D36215E09E4EEFD70E340C2E4DECF38 
    92  
    93                 Issued to: GlobalSign ObjectSign CA 
    94                 Issued by: GlobalSign Primary Object Publishing CA 
    95                 Expires:   Fri Jan 27 11:00:00 2017 
    96                 SHA1 hash: B859853EF366AC9335763C340A87BD208113055F 
    97  
    98                     Issued to: Akeo Consulting 
    99                     Issued by: GlobalSign ObjectSign CA 
    100                     Expires:   Sun Jun 26 10:05:35 2011 
    101                     SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    102  
    103 Done Adding Additional Store 
    104 Successfully signed and timestamped: libusb0.sys 
    105  
    106 Number of files successfully Signed: 1 
    107 Number of warnings: 0 
    108 Number of errors: 0 
    109 }}} 
    110 For details on what each of the option above does, though they should be fairly explicit, you can issue: {{{signtool sign /?}}}. 
    111  
    112 '''Checking the signed driver files''' 
    113  
    114 Optional, but probably a good idea, as you will get the timestamping info as well.  
    115 {{{ 
    116 D:libusb-win32_ft2232_driver-101028amd64>signtool verify /kp /v libusb0.sys 
    117  
    118 Verifying: libusb0.sys 
    119 Hash of file (sha1): B4C09901487067EB10454F6CFFCFA3C64988EE86 
    120  
    121 Signing Certificate Chain: 
    122     Issued to: GlobalSign Root CA 
    123     Issued by: GlobalSign Root CA 
    124     Expires:   Fri Jan 28 12:00:00 2028 
    125     SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C 
    126  
    127         Issued to: GlobalSign Primary Object Publishing CA 
    128         Issued by: GlobalSign Root CA 
    129         Expires:   Fri Jan 27 12:00:00 2017 
    130         SHA1 hash: 1AAF4DF10D36215E09E4EEFD70E340C2E4DECF38 
    131  
    132             Issued to: GlobalSign ObjectSign CA 
    133             Issued by: GlobalSign Primary Object Publishing CA 
    134             Expires:   Fri Jan 27 11:00:00 2017 
    135             SHA1 hash: B859853EF366AC9335763C340A87BD208113055F 
    136  
    137                 Issued to: Akeo Consulting 
    138                 Issued by: GlobalSign ObjectSign CA 
    139                 Expires:   Sun Jun 26 10:05:35 2011 
    140                 SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    141  
    142 The signature is timestamped: Tue Feb 08 13:54:32 2011 
    143 Timestamp Verified by: 
    144     Issued to: GlobalSign Root CA 
    145     Issued by: GlobalSign Root CA 
    146     Expires:   Fri Jan 28 12:00:00 2028 
    147     SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C 
    148  
    149         Issued to: GlobalSign Timestamping CA 
    150         Issued by: GlobalSign Root CA 
    151         Expires:   Fri Jan 28 12:00:00 2028 
    152         SHA1 hash: 958D23902D5448314F2F811034356A58255CDC9B 
    153  
    154             Issued to: GlobalSign Time Stamping Authority 
    155             Issued by: GlobalSign Timestamping CA 
    156             Expires:   Tue Dec 22 09:32:56 2020 
    157             SHA1 hash: AEDF7DF76BBA2410D67DBAF18F5BA15B417E496C 
    158  
    159 Cross Certificate Chain: 
    160     Issued to: Microsoft Code Verification Root 
    161     Issued by: Microsoft Code Verification Root 
    162     Expires:   Sat Nov 01 13:54:03 2025 
    163     SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3 
    164  
    165         Issued to: GlobalSign Root CA 
    166         Issued by: Microsoft Code Verification Root 
    167         Expires:   Mon May 23 17:10:51 2016 
    168         SHA1 hash: 3EEB2750A199F5E7B6A8952430BE5062FE04E9E5 
    169  
    170             Issued to: GlobalSign Primary Object Publishing CA 
    171             Issued by: GlobalSign Root CA 
    172             Expires:   Fri Jan 27 12:00:00 2017 
    173             SHA1 hash: 1AAF4DF10D36215E09E4EEFD70E340C2E4DECF38 
    174  
    175                 Issued to: GlobalSign ObjectSign CA 
    176                 Issued by: GlobalSign Primary Object Publishing CA 
    177                 Expires:   Fri Jan 27 11:00:00 2017 
    178                 SHA1 hash: B859853EF366AC9335763C340A87BD208113055F 
    179  
    180                     Issued to: Akeo Consulting 
    181                     Issued by: GlobalSign ObjectSign CA 
    182                     Expires:   Sun Jun 26 10:05:35 2011 
    183                     SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    184  
    185 Successfully verified: libusb0.sys 
    186  
    187 Number of files successfully Verified: 1 
    188 Number of warnings: 0 
    189 Number of errors: 0 
    190 }}} 
    191  
    192 == Creating a signed cat file == 
    193  
    194 '''Why would you want a signed cat?''' 
    195  
    196 What we did above allows the installation of drivers in a Windows environment outside of test mode, which is fine and all, but unless you sign the inf as well, you will get the following prompt on Vista and later versions of Windows during driver installation: 
    197  
    198 [[Image(libwdi/zadig:zadig_05.png)]] 
    199  
    200 One way to avoid this prompt is to go through WHQL. However, this is an expensive and time-consuming process, and Microsoft are currently abusing their position to prevent GPL licensed drivers (both GPLv2 '''and''' GPLv3) from being accepted through the WHQL process (for the record, at the time of this post, the libusb-win32 driver is GPLv2) 
    201 The other solution is to use your driver signing credentials to sign the inf, and create a cat file. 
    202  
    203 The only drawback of doing that your users may get a prompt about trusting the company identified by the certificate as a trusted publisher [TODO: pic] unless: 
    204  1. they previously checked "Always trust software from company X" when previously prompted with a similar query 
    205  1. you installed your certificate in the Trusted Publisher system store 
    206 In essence, the end result from both of the options above is that your certificate ends up as a Trusted Publisher on the user system. As we will see later on, libwdi provides an API for option 2. 
    207  
    208 '''Signing a cat file''' 
    209  
    210 Since we're using the WDK, we have access to the {{{inf2cat}}} tool, which is the most convenient way to create a cat out of an inf file. 
    211 Before you can use inf2cat, you must ensure that your .inf contains a CatalogFile entry in the [Version] section, that provides the name of the .cat to be created. The {{{libusb-win32_ft2232_driver.inf}}} file we use is missing it, so we add it: 
    212 {{{ 
    213 CatalogFile = "libusb-win32_ft2232_driver.cat" 
    214 }}} 
    215 Then, you can simply run: 
    216 {{{ 
    217 D:libusb-win32_ft2232_driver-101028>inf2cat /v /driver:. /os:XP_X86,XP_X64,Vista_X86,Vista_X64,7_X86,7_X64 
    218 Processing directory (D:libusb-win32_ft2232_driver-101028) file (info.txt) 
    219 Processing directory (D:libusb-win32_ft2232_driver-101028) file (libusb-win32_ft2232_driver.inf) 
    220 Processing directory (D:libusb-win32_ft2232_driver-101028amd64) file (libusb0.dll) 
    221 Processing directory (D:libusb-win32_ft2232_driver-101028amd64) file (libusb0.sys) 
    222 Processing directory (D:libusb-win32_ft2232_driver-101028x86) file (libusb0.sys) 
    223 Processing directory (D:libusb-win32_ft2232_driver-101028x86) file (libusb0_x86.dll) 
    224 Parsing INF: D:libusb-win32_ft2232_driver-101028libusb-win32_ft2232_driver.inf 
    225 Finished parsing INFs 
    226 Processing INF: D:libusb-win32_ft2232_driver-101028libusb-win32_ft2232_driver.inf 
    227 Finished processing INFs 
    228 Testing driver package... 
    229 Testing driver package... 
    230 Testing driver package... 
    231 Testing driver package... 
    232 Testing driver package... 
    233 Testing driver package... 
    234 Testing driver package... 
    235 Testing driver package... 
    236 Testing driver package... 
    237 Testing driver package... 
    238 Testing driver package... 
    239 Testing driver package... 
    240 Testing driver package... 
    241 Testing driver package... 
    242  
    243 Signability test complete. 
    244  
    245 Errors: 
    246 None 
    247  
    248 Warnings: 
    249 None 
    250  
    251 Catalog generation complete. 
    252 }}} 
    253  
    254 After that, you would sign the generated .cat as follows: 
    255 {{{ 
    256 D:libusb-win32_ft2232_driver-101028>signtool sign /v /ac D:codesignMSCV-GlobalSign.cer /f D:codesignakeo.pfx /p "<YOUR_PASSWORD>" /t http://timestamp.globalsign.com/scripts/timestamp.dll libusb-win32_ft2232_driver.cat 
    257 The following certificate was selected: 
    258     Issued to: Akeo Consulting 
    259     Issued by: GlobalSign ObjectSign CA 
    260     Expires:   Sun Jun 26 10:05:35 2011 
    261     SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    262  
    263 Cross certificate chain (using machine store): 
    264     Issued to: Microsoft Code Verification Root 
    265     Issued by: Microsoft Code Verification Root 
    266     Expires:   Sat Nov 01 13:54:03 2025 
    267     SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3 
    268  
    269         Issued to: GlobalSign Root CA 
    270         Issued by: Microsoft Code Verification Root 
    271         Expires:   Mon May 23 17:10:51 2016 
    272         SHA1 hash: 3EEB2750A199F5E7B6A8952430BE5062FE04E9E5 
    273  
    274             Issued to: GlobalSign Primary Object Publishing CA 
    275             Issued by: GlobalSign Root CA 
    276             Expires:   Fri Jan 27 12:00:00 2017 
    277             SHA1 hash: 1AAF4DF10D36215E09E4EEFD70E340C2E4DECF38 
    278  
    279                 Issued to: GlobalSign ObjectSign CA 
    280                 Issued by: GlobalSign Primary Object Publishing CA 
    281                 Expires:   Fri Jan 27 11:00:00 2017 
    282                 SHA1 hash: B859853EF366AC9335763C340A87BD208113055F 
    283  
    284                     Issued to: Akeo Consulting 
    285                     Issued by: GlobalSign ObjectSign CA 
    286                     Expires:   Sun Jun 26 10:05:35 2011 
    287                     SHA1 hash: 0BF5319EE093F9234D8504527D63CFAFEADEECF8 
    288  
    289 Done Adding Additional Store 
    290 Successfully signed and timestamped: libusb-win32_ft2232_driver.cat 
    291  
    292 Number of files successfully Signed: 1 
    293 Number of warnings: 0 
    294 Number of errors: 0 
    295 }}} 
    296  
    297 == Packaging the signed files in libwdi == 
    298  
    299 Since we went the trouble of creating a fully signed driver package, that can install without prompts, we might as well deliver the whole thing in a package that is attractive for end users. Also, if you want to avoid the need for users to add your certificate as a Trusted Publisher, libwdi can help you out. 
    300  
    301 == Installing the certificate as a Trusted Publisher using libwdi == 
    302  
    303 == Testing the installation == 
    304  
    305 == Links == 
    306  
    307 * [http://www.microsoft.com/whdc/driver/install/drvsign/kmcs-walkthrough.mspx Microsoft's Kernel-Mode Code Signing Walkthrough] (in Microsoft Office 2007 .docx format) 
    308 * [http://www.globalsign.com/support/code-signing/codesign_vista64.php GlobalSign's code signing page] 
    309  
    310