|
Zillabit ProjectsGeeky TidbitsAlso for completeness are notes on failed attempts to run official Microsoft tools under Wine, in case this information is helpful to anyone. Update: I now use osslsigncode instead. I recommend that as the best alternative for most people. (You will need to read the README file to get started.) But if you are already using the Mono project it might be easiest to use the Mono signcode tool, in which case these notes might be helpful to you. Installation of Mono stuff on Debian Sarge
Recently fixed bugs in the Mono Authenticode implementationIn late 2006 i found that the Mono Authenticode implementation created bad signatures for two cases of interest. I filed bug 79741 and Sebastian fixed these problems quickly, in revision 69502 in December 2006. In case you don't have a version of this code recent enough to contain the fixes, you might want to know about workarounds.EXE files with debugging information after the end of the PE section will trigger this bug. For example, executables built with MinGW will contain such debugging info by default. The easy workaround is to use the strip command to remove that info before signing, for example i586-mingw32msvc-strip helloworld.exe Installer files created with NSIS place the bulk of the installer data after the last PE section. Using the strip command will discard the installer data and leave a tiny useless file, so that is not a viable workaround for this case. You'll want the fixed code for this case. Working around problems with PVK passwordAttempting to runsigncode -v mykey.pvk -spc mycert.spc -t http://timestamp.verisign.com/scripts/timstamp.dll helloworld.exefails with this output: Unhandled Exception: System.Security.Cryptography.CryptographicException: Invalid data and/or password in <0x000a0> Mono.Security.Authenticode.PrivateKey:.ctor (System.Byte[] data, System.String password) in <0x000c4> Mono.Security.Authenticode.PrivateKey:CreateFromFile (System.String filename, System.String password) in <0x0000c> Mono.Security.Authenticode.PrivateKey:CreateFromFile (System.String filename) in <0x0005d> Mono.Tools.SignCode:GetPrivateKey (System.String keyfile, System.Security.Cryptography.CspParameters csp) in <0x006ac> Mono.Tools.SignCode:Main (System.String[] args)Examining a recent version of the signcode.cs source code it seems that first it attempts to open the PVK file without a password, then if that fails it is supposed to prompt for a password and try opening the PVK again with that password. However the initial failure throws an unhandled exception before going any farther. Because I do not know if there is any way to prevent the program from terminating on this unhandled exception, I downloaded the source file and edited it so that it would skip the attempt to open the PVK without a password: --- signcode.cs-orig 2006-10-24 11:58:40.081094750 -0700 +++ signcode.cs 2006-10-24 01:32:10.306788250 -0700 @@ -62,14 +62,14 @@ return null; } - PrivateKey pvk = PrivateKey.CreateFromFile (keyfile); - if (pvk.Encrypted) { + //PrivateKey pvk = PrivateKey.CreateFromFile (keyfile); + //if (pvk.Encrypted) { Console.WriteLine ("Enter password for {0}: ", keyfile); string password = Console.ReadLine (); - pvk = PrivateKey.CreateFromFile (keyfile, password); + PrivateKey pvk = PrivateKey.CreateFromFile (keyfile, password); if (pvk.RSA == null) Console.WriteLine ("Invalid password!"); - } + //} rsa = pvk.RSA; } else {After compiling this with mcs -r:Mono.Security.dll signcode.csit is possible to run the local signcode tool and it will prompt for the password then successfully write out the signed EXE. ./signcode.exe -v mykey.pvk -spc mycert.spc -t http://timestamp.verisign.com/scripts/timstamp.dll helloworld.exeAn alternative workaround is to use the signcode tool as-is but to create a version of the PVK file without a password with a program like this: using System; using System.IO; using System.Text; using Mono.Security.Authenticode; public class PrivateKeyTest { private const string testfilein = "testin.pvk"; private const string testfileout = "testout.pvk"; public static void Main () { PrivateKey pvk = PrivateKey.CreateFromFile (testfilein, "my_actual_password"); pvk.Save (testfileout); } }where you replace "my_actual_password" with the real password. Of course the usual security caveats apply if you're going to leave a password-less key sitting around. Working around problems with Thawte certificate in MonoInitially Windows told me that my signature was not OK. I found this thread on the Mono list which sounded exactly like my problem because my certificate was issued by Thawte.
cert2spc my-company.cer thawte-code-signing.cer thawte-premium-server.cer myfixedcert.spcwhich creates the new file myfixedcert.spc. Now try signing again with the new fixed SPC file: ./signcode.exe -v mykey.pvk -spc myfixedcert.spc helloworld.exeNow Windows should tell you that the signature is OK! Failure to check the signature in Mono with the chktrust toolEven though Windows confirmed the signature was good, I was unable to get the chktrust tool in Mono to successfully confirm the signature. The steps i attempted were to add the Thawte root certificate to the "Trust" store withsudo certmgr -add -c -m Trust thawte-premium-server.certhen confirm it is there with certmgr -list -c -m Trustthen attempt to check the signature with chktrust helloworld.exebut the output is WARNING! helloworld.exe is not timestamped! ERROR! helloworld.exe couldn't find the certificate that signed the file! Failed attempts to run official Microsoft tools under WineI also attempted to use both the older signcode.exe tool and the new signtool.exe running under Wine. Both failed, even after attempting to copy some missing DLLs from a Windows XP system into the local directory.The signcode.exe tool actually does start and even show the dialog box for entering the PVK file's password ("Enter Private Key Password"), but after password entry Wine prints the following and no output EXE file is written: fixme:crypt:CRYPT_VerifyImage (rsaenh.dll, 0x7fd6bc60): not verifying image fixme:crypt:CRYPT_VerifyImage (rsaenh.dll, 0x7fd6fd18): not verifying image Error: Unable to open a CSP provider with the correct private key Error: Signing Failed. Result = 80092006, (-2146885626) Wine failed with return code 255The signtool.exe tool is unable to start. Wine crashes into winedbg with the following output: fixme:actctx:QueryActCtxW stub! fixme:commctrl:InitCommonControlsEx Unknown class! dwICC=0x4000 fixme:seh:EXC_RtlRaiseException call (from 0x100a259) to unimplemented function msvcrt.dll._wsetlocale fixme:msvcrt:_XcptFilter (-2147483392,0x7fb8e8b4)semi-stub wine: Unhandled exception (thread 0009), starting debugger... WineDbg starting on pid 0x8 Unhandled exception: unimplemented function msvcrt.dll._wsetlocale called in 32-bit code (0x7fa4d051). In 32 bit mode. Register dump: CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033 EIP:7fa4d051 ESP:7fb8ed18 EBP:7fb8ed7c EFLAGS:00200212( - 00 - -IA1) EAX:7fb8ed24 EBX:7fa7ac80 ECX:00000000 EDX:00000005 ESI:7fc66490 EDI:00000000 Stack dump: 0x7fb8ed18: 01000000 0104c3a0 7fb8ed50 80000100 0x7fb8ed28: 00000001 00000000 0100a259 00000002 0x7fb8ed38: 7fa6f7e0 7fa6fb07 0104c908 7f81cb50 0x7fb8ed48: 00000005 0104c908 7fb8ed84 7f7d3342 0x7fb8ed58: 7fb8eea0 0104c90a 0000000a 00000000 0x7fb8ed68: 00000000 00000000 00000000 0000029d Backtrace: =>1 0x7fa4d051 in msvcrt (+0xd051) (0x7fb8ed7c) 2 0x7fa4d956 __wine_stub_msvcrt_dll_536 in msvcrt (0x7fb8ed8c) 3 0x0100a259 in signtool (+0xa259) (0x7fb8fea4) 4 0x01010ab2 EntryPoint in signtool (0x7fb8ff20) 5 0x7fc73de2 in kernel32 (+0x53de2) (0x7fb8fff4) 6 0xb7f35181 wine_switch_to_stack in libwine.so.1 (0x00000000) 0x7fa4d051: subl $4,%esp Wine-dbg>This page doesn't give much hope that this can be made to work. |