Tuesday, February 19, 2013

Application Signing with Mono

I spent the weekend writing a Winblows... a Windoze... a WindOWS application (sorry, that's hard for me to do because I'm an opensource kind of guy, and really don't use Windows much).  See, I had this problem of having an old Windows Vista Home PC without the ability to automatically store new files onto a NAS that could then be edited on a Macbook Pro and automatically be ready for edit back on the Windows box (before you give me spiels about "use sharing" - the Windows computer is not on all the time, and with Vista Home, you can't change those locations to be a network share from a NAS - trust me, I tried and failed miserably).

In the process, I wrote a simply application for Wingoes that monitors specific directories (I made it configurable so you can easily control it).  Since I didn't want to download a WinPose SDK kit, I wrote and compiled the Winhose thing using Mono - and ran into a problem I couldn't find an easy solution to : signing the resulting .EXE application.  I did manage to figure it out after a few hours, though.  Here's how I did it.

  1. Ensure you have the mono-devel package installed.  Up to this point, I had a working application without the mono-devel package.  It provides a nice binary called "signtool".  e.g.

    yum install mono-devel
  2. Next, create a new certificate authority configuration file.  It can be almost identical to your regular signing CA with one change - in the "[ server_cert ]" section, change "extendedKeyUsage" to a value of "codeSigning", and possibly generate new keys and configure them in the file.  I generated new keys for this one :

    cd /etc/pki/tls/
    openssl genrsa -des3 -out private/signing.key 4096

    openssl req -new -x509 -days 3650 -key private/signing.key -out certs/signing.crt
  3. Create your own signing request and key :

    openssl req -newkey rsa:1024 -nodes -out silverhawk-codesign.csr -keyout silverhawk-codesign.key
  4. Sign your certificate :

    openssl ca -batch -config /etc/pki/tls/signing.conf -notext -in silverhawk-codesign.csr -out silverhawk-codesign.crt

  5. I then exported the files into various formats just in case they are needed down the road.  Please keep these secure!  My formatting options :

    openssl pkcs12 -export -out silverhawk-codesign.pfx -inkey silverhawk-codesign.key -in silverhawk-codesign.crt
    openssl pkcs12 -in silverhawk-codesign.pfx -out silverhawk-codesign.pem -nodes

    openssl rsa -in silverhawk-codesign.key -outform PVK -pvk-strong -out silverhawk-codesign.pvk

    openssl crl2pkcs7 -nocrl -certfile silverhawk-codesign.crt -outform DER -out silverhawk-codesign.spc

  6. Next, you can finally sign the application :

    signcode -spc /path/to/created/silverhawk-codesign.spc -v /path/to/created/silverhawk-codesign.pvk -a sha1 -$ commercial -n "SilverSync" -i http://www.silverhawk.net/ -t http://timestamp.verisign.com/scripts/timstamp.dll -tr 10 SilverSync.exe
This finally allowed my to save firewall information on the application when it ran.  Hooray!