How to add timestamp certificate to a signed PE file on Linux? - linux

I need to digitally sign&timestamp a PE file (EFI, actually) on Linux. I found 3 tools for signing PE files: pesign, osslsigncode and signcode (mono), but it seems none quite fits my needs. The problem is, the key is on a hardware token and cannot be exported. Therefore I have to create a certificate database, add token driver entry there and work via this DB. Only pesign allows this, but it does not support timestamping. osslsigncode and signcode support timestamping, but they cannot use the database.
The Windows signttool.exe can perform signing and timestamping as separate steps. So I thought, I might use pesign to sign the file and then only timestamp it with another tool. But as I discovered, osslsigncode and signcode do not support separate timestamping (in osslsigncode project it's listed in the TODO file, but no signs of it in repository yet).
Are there some tools I missed? Are there not-too-lowlevel libraries which would allow me to write such program myself? (Preferrably, C/C++/Perl/Python.) I tried to get the timestamping code from osslsigncode, but failed to detach it easily from the prior steps (removing existing signature and adding a new one).
P.S. I also tried to run signtool.exe under wine, but 1) failed to get it working, and 2) I'm not sure it's legally permitted (I'm not good at analyzing EULAs).

Since march 2015, there is a patch in osslsigncode which allows you sign the code via a key on a PKCS#11 token. It is not part of an official release yet. So you have to build it yourself, but it works like charm for me.
An example invocation looks like this:
osslsigncode sign -pkcs11engine /usr/lib/engines/engine_pkcs11.so -pkcs11module /usr/lib/libeTPkcs11.so -certs ~/mysigningcert.pem -key 0:42ff -in ~/filetosign.exe -out ~/signedfile.exe
The -pkcs11module switch takes the PKCS#11 library as a parameter, the parameter for -key is in the format slotID:keyID.

SignServer Enterprise Edition supports signing and time-stamping of PE files using Authenticode.
Also hardware tokens are supported through the PKCS#11 interface.
SignServer is typically setup on separate server or VM and preferably runs on Linux (but Windows is also supported).
The files you want to sign can simply be sent to the server with an HTTP POST and then the response is the signed file.
https://www.signserver.org/

current osslsigncode has timestamp option -t:
osslsigncode sign \
-pkcs12 cert.pfx -pass "**********" \
-t http://timestamp.digicert.com \
-in app.exe -out app-sign-with-timestamp.exe
See https://github.com/mtrojnar/osslsigncode

Related

Do I need to digitally sign my code for Linux

coming from Windows, I am used to sign my code (.exe, .dll). Especially with the recent Windows versions, executing unsigned code or code signed with a self-signed certificate becomes more and more difficult, if not impossible. I do therefore own a (payed) Authenticode EV certificate and have integrated signing into my build chain.
How important/mandatory is code signing under Linux?
Thnx, Armin.

Unable to sign APK after migrating from IntelliJ to Android Studio (or password problem?)

I recently switched back to Android Studio after a few months of trying out the Android plugin of IntelliJ.
Then I tried signing the APK of an app that is currently in beta test in the play store but the signature does not match what is on the Dev Play Console for the previous versions.
I double checked and I am sure that I am using the same keystore (and same key) as before.
Now I am left with two possibilities:
• There's a problem of code signing when migrating IntelliJ to Android?
• My passwords for the keystore are wrong. But then, why would it succeed in building the APK?
Can I rule out any of these two directions?
It reads on the Google help that if the keystores are lost (which is not the case, but maybe the password is), one need to recreate a completely new app on the Play Store with a new package name.
There really would be no alternative to this?
PS: I had downloaded some certificates for apk signing in the past, but I don't know how to use them within Android studio in stead of the jks files.
EDIT
The error message I get from the store is :
You uploaded an APK that is not signed with the upload certificate.
You must use the same certificate. The upload certificate has fingerprint:
[ SHA1: XXX ]
and the certificate used to sign the APK you uploaded have
fingerprint:
[ SHA1: YYY ]
Yet, when I run the following:
keytool -list -v -keystore "/Path/upload_keystore.jks"
-alias "upload_key" -storepass ***** -keypass ****
I get that the SHA1 is actually XXX (and not YYY).
So it should be right.
Also, weird thing: whatever passwords I use, I get the same SHA1, and it is the correct one!
But I also get the following message:
Warning:
The JKS keystore uses a proprietary format. It is recommended to
migrate to PKCS12 which is an industry standard format using "keytool
-importkeystore -srckeystore /Path/upload_keystore.jks -
destkeystore /Path/upload_keystore.jks -deststoretype pkcs12".
Which is weird since it was generated by Google.
Ok, I just did a clean build, and signed it again, and it worked.
I guess the first signing attempt was wrong, but it got cached and prevented the other signing attempts to really be effective.

PlayReady Company Certificates for testing

I am writing a tool suite that, among other things, must support PlayReady Model Certificate generation from various Device Company CA certificates (which we will receive from customers).
In order to properly test the software end-to-end I need to obtain some test Company certificates. I could not find the relevant information in PlayReady documentation that was provided by Microsoft. Is there a way to obtain such certificates easily?
(Thinking about it, there probably should exist a root certificate for testing purposes only - I could not find any info on that as well)
Thanks in advance.
What you are looking for can be found in a subdirectory below the 'test' directory of the source code that is provided when you install the Microsoft PlayReady Device Porting Kit (PK). If you do not have this Device PK MSI installer (perhaps you only have the Microsoft PlayReady Certificate Generation Kit MSI), then I recommend that you contact Microsoft to legally obtain a copy of the latest PlayReady Device PK MSI.
If you have PlayReady Device PK 2.0.0:
If you need it, a test root certificate is located here:
c:\PlayReady\Device_PK_2.0.0\test\ToolTests\files\rootcert.dat
There are some example test group/model certificates (bgroupcert*), and their associated test private keys (zgpriv*), are located here: C:\PlayReady\Device_PK_2.0.0\test\devicedevcert\
There are also some example files that you may find informative in the C:\PlayReady\Device_PK_2.0.0\Samples\ sub-directory, such as:
SampleDACResponsePR.dat
SampleDACResponseWMDRMPD.xml
SamplePrivKeys.xml
It looks like there are also some potentially useful files in the C:\PlayReady\Device_PK_2.0.0\test\certs\files sub-directory, such as:
companyprivkey.xml
companypubkeymodulusb64.txt
rootprivkey.xml
rootpubkeymodulusb64.txt
testrootprivkey.dat
testrootpubkey.dat
unsignedtemplate.xml
That said, you should be able to use the following tools, and some of the files above, to simulate/test the full certificate request and generation process:
C:\PlayReady\Device_PK_2.0.0\Tools\generatecompanycertrequest.exe
C:\PlayReady\Device_PK_2.0.0\Tools\generatekeypair.exe
C:\PlayReady\Device_PK_2.0.0\Tools\generatemodelcert.exe
Note: Since PlayReady certificate chains are in "binary" format (i.e. not XML), you will need to use bcertdump to view them, similar to: c:\PlayReady\Device_PK_2.0.0\Tools\bcertdump.exe -b:.\rootcert.dat -v
Also, if/when you have PlayReady Device PK 2.5.0, things may be organized (and work) slightly differently.

Win7 64bit legacy nt4 driver signing issue

it's been since WinXP I don't use the Windows DDK (now WDK) and I've noticed something big is changed.
I'm developing a legacy NT4 filter driver (without .inf and without .cat) with the latest Win7 DDK, my environment is
Windows 7 64bit
Visual Studio 2010
WinDDK v7600.16385.1
VisualDDK plugin for VS (latest version)
I have issue self signing this driver, since I'm still developing it I don't have (and don't know how to get) an appropriate WHQL certificate, therefore I'm following a procedure I've found online.
#echo off
set SIGNTOOL="c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe"
set MAKECERT="c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert.exe"
set PVK2PFX="c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\pvk2pfx.exe"
set CERTPVK="C:\Users\myself\Desktop\testdriver\avtxagent\package\mycompanynametest.pvk"
set CERTPFX="C:\Users\myself\Desktop\testdriver\avtxagent\package\mycompanynametest.pfx"
set CERT="C:\Users\myself\Desktop\testdriver\avtxagent\package\mycompanynametest.cer"
set DRIVER="C:\Users\myself\Desktop\testdriver\avtxagent\package\avtxagent.sys"
set CERTSUBJ="mycompanyname (test)"
del *.cer *.pfx *.pvk
cls
%MAKECERT% -r -n "CN=mycompanyname (test)" -sv %CERTPVK% %CERT%
%PVK2PFX% -pvk %CERTPVK% -spc %CERT% -pfx %CERTPFX%
pause
cls
%SIGNTOOL% sign /v /f %CERTPFX% /t "http://timestamp.verisign.com/scripts/timestamp.dll" %DRIVER%
pause
cls
:: verification
%SIGNTOOL% verify /pa /v %DRIVER%
pause
Basically what I'm doing is generate the certificate each time (I've already tried with a certificate generated only once, still same issue), signing my driver and then trying to verify the signature.
In this last step, the verification, I get the issue:
SignTool Error: A certificate chain processed, but terminated in a
root certificate which is not trusted by the trust provider.
Obviously when I try to install and then start the legacy driver both programmatically and with sc, I get the error:
[SC] CreateService SUCCESS
[SC] StartService FAILED 577:
Windows cannot verify the digital signature for this file. A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.
If I follow this guide http://technet.microsoft.com/en-us/library/cc754841.aspx and import the certificate inside the Trusted Certification the verification process goes well, but I get the same error from sc.
What am I doing wrong ? And, is there anyone can explain what I have to do to get an appropriate certificate to use in production environment since the documentation is kind of lacky?
You don't need a WHQL signature to sign a kernel-mode driver. What you do need is a code signing certificate purchased from GlobalSign or Verisign (others won't work). When you have one, use this code signing certificate to sign your driver. NOTE: you also need to include a cross-certificate from Microsoft.
Alternatively (solely for debugging purposes) you can load the system in test mode, in which the signature is not checked. To do this you need to press F8 during system boot and choose the corresponding option in the menu.
This is likely due to the fact that the private CA you used to generate the certificate is not trusted by your system. These look relevant:
http://technet.microsoft.com/en-us/library/dd441378(office.13).aspx
http://technet.microsoft.com/en-us/library/cc754841.aspx
You need to install your self-signed certificate as a trusted root certification authority and as a trusted publisher into the local machine store (normally, certmgr.msc shows and manages your user account's store instead):
certmgr.exe -add <your.cer> -s -r localMachine ROOT
certmgr.exe -add <your.cer> -s -r localMachine TRUSTEDPUBLISHER
As you can see, it's very impractical here to generate a new certificate each time. You'd rather generate it once and then reuse.
(Courtesy of http://winitpro.ru/index.php/2014/05/08/kak-samostoyatelno-podpisat-drajver-dlya-windows-7/; instructions to the same effect are at https://technet.microsoft.com/en-us/library/dd919238(v=ws.10).aspx)

Thawte driver signing for 64-bit Windows

If this question is off-topic, please recommend another StackExchange site to post this on :-)
Our company recently purchased G2 code signing certificate from Thawte. I've run through all steps neccessary to sign a 64-bit driver, so it can be installed under Windows 7 64-bit.
Namely, I have:
downloaded a G2 Thawte cross-certificate
obtained our own Thawte certificate (actually a .p12 file which I had to import and re-export as .pfx file for it to work)
successfully signed the driver via the following command: signtool.exe sign /ac cross.cer /f private_key.pfx /p ***** /t "http://timestamp.verisign.com/scripts/timstamp.dll" /v my_driver.sys
imported our company certificate (and even all those Thawte certificates when the first didn't work) into machine's trusted root authorities and trusted publishers
importted thawte cross-certificate into Intermediate Certification Authorities
I've tried to verify the signature using signtool.exe verify /pa /v my_driver.sys, which has passed. If I do not use /pa in the command line, this would say "SignTool Error: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider." (is that something I should be worried about?)
Now when I try to install the driver using a simple INF file (not a cab file), the result is red warning about Windows not being able to verify the issuer of the driver. When I choose not to install the driver, I get a following extra message: A file could not be verified because it does not have an associated catalog signed via Authenticode(tm).
I've read that Thawte could not really be used to sign drivers like this in the past because somehow MS stopped to support it, yet it's still listing a cross-certificate on their website. Not sure if this is still valid, cannot find any proof of it.
Any advice would be greatly appreciated.
You need to add a CatalogFile reference to your inf file, run Inf2Cat.exe (in the DDK) to generate the cat file, then use signtool.exe to sign that too.

Resources