Firefox ignores signature on successfully signed XPI - how to diagnose?

2k views Asked by At

I've created a Firefox plugin, a Win32-native code DLL - using Firebreath. I'm working on Windows 7/x64, and targeting Windows only. The plugin itself is working well, but I'm really stuck getting a correctly signed XPI. If I don't sign my XPI, it's accepted and installed by FF 3.6 thru 10 (beta). Of course, during the install it lists the publisher as (Author not verified). So, I spent a week debugging the signing process... but FF 9 and 10 still say (Author not verified)! FF 3.6 rejects the signed XPI as invalid.

How do I troubleshoot this??

Just to repeat: I sign the xpi without error, and the resulting XPI installs successfully on FF 9 and 10, but FF still says (Author not verified).

Here's the batch code I use to sign the XPI:

echo * clean out old signing folder and xpi
if exist package rmdir /S /Q package
if exist %package%.xpi del %package%.xpi
echo * copy in files for package
md package
xcopy ..\*.rdf package
md package\plugins
xcopy ..\build\bin\Plugin\Debug\*.dll package\plugins
echo * clean out certificate database
del *.db
echo * import our signing certificate
pk12util -d . -i %keyfile% -K %pwd% -w keypass.txt
echo * adjust trust on base, intermediate and root cert
certutil -M -d . -n "VeriSign" -t "c,c,C"
certutil -M -d . -n "VeriSign Class 3 Code Signing 2010 CA - VeriSign, Inc." -t "TC,TC,TC"
certutil -M -d . -n "%certname%" -t "u,u,Cu"
certutil -L -d .
echo * create signed package
signtool -d . -X -Z %package%.xpi -k "%certname%" -p %pwd% package
2

There are 2 answers

1
StefanB On

Basically your signature needs to include full certificate chain up to the trusted VeriSign root certificate, bypassing the "VeriSign Class 3 Public Primary Certification Authority - G5" with unknown trust in mozilla (bug 602107), as by default the chain ends too soon.

Your XPI is currently signed with your certificate, with no further certificate chain included, relying that the user's browser will trust the issuer of your certificate immediately. You can examine this with Mozilla's jarsigner tool (see Mozilla NSS tools):

Tools\nss-3.11>jarsigner -verify -verbose -certs my-old.xpi
    2057 Thu Sep 15 15:17:44 CEST 2011 META-INF/zigbert.rsa
sm        87 Thu Sep 15 15:17:44 CEST 2011 chrome.manifest

  X.509, CN=Company Name inc., OU=General, OU=Digital ID Class 3 - Microsoft Software Validation v2, O=Company Name inc., L=City, ST=State, C=XX
  [certificate will expire on 26.4.13 0:59]

(showing just the output for the 1st file)

You need to include a few more certificates to complete the chain to a certificate that is by default explicitly trusted in the end user's browser. In the end it should look like this:

jarsigner -verify -verbose -certs my-newly-signed.xpi

    2057 Thu Sep 15 15:17:44 CEST 2011 META-INF/zigbert.rsa
sm        87 Thu Sep 15 15:17:44 CEST 2011 chrome.manifest

  X.509, CN=Company Name inc., OU=General, OU=Digital ID Class 3 - Microsoft Software Validation v2, O=Company Name inc., L=City, ST=State, C=XX
  [certificate will expire on 26.4.13 0:59]
  X.509, CN=VeriSign Class 3 Code Signing 2010 CA, OU=Terms of use at https://www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
  [certificate is valid from 8.2.10 1:00 to 8.2.20 0:59]
  [KeyUsage extension does not support code signing]
  X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
  [certificate is valid from 8.11.06 1:00 to 8.11.21 0:59]
  [KeyUsage extension does not support code signing]
  X.509, OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
  [certificate is valid from 23.5.06 19:01 to 23.5.16 19:11]

To achieve this you need to:

  1. remove the not-explicitly-trusted VeriSing's built-in certificates from the certificate database with Mozilla's certutil tool
  2. Build the certificate trust chain of your certificate all the way up to Microsoft's "Class 3 Public Primary Certification Authority".
  3. sign the xpi (this time full certificates chain will be included in the signature)
  4. verify the xpi with jarsigner as described above
  5. test the xpi in Firefox - you should not see "Author not verified" anymore.

Caveats:

  • Trust bits in the built-in Firefox certificate store are actually 3-state (trusted, untrusted and unknown), despite only being shown as 2-state checkbox in the FF GUI (checked=trusted, unchecked=untrusted OR unknown). By default trust is unknown, which enables you to bypass the VeriSign's certificate as described. If you ever enabled trust via FF's checkboxes it will still work, but if you uncheck the trust checkbox the trust will be set to untrusted, which will prevent bypassing that certificate in the chain. The easiest (only?) way to reset this back to initial unknown is to delete your firefox profile.
  • After Mozilla eventually enables the code-signing trust bit (see the bug above) you will still need to sign like this if you want to support older versions of Firefox.

Hope it helps!

3
Jim Blandy On

I work for Mozilla, but this isn't an authoritative answer, just what I've gathered asking around:

So, essentially, each certificate authority has three trust bits Mozilla might grant it: they might trust it to sign websites, and/or mail, and/or code. Your certificate is from a certificate authority that Mozilla doesn't trust to sign code. (This is why going and manually setting the bit in your preferences makes it work—for you.)

I'm told so few people try to use binary code in xpi's that Mozilla doesn't really have an organized way to find out which authorities can be used for what. However, you can check out this list: look at the "Code Trust Bit":

https://spreadsheets.google.com/pub?key=ttwCVzDVuWzZYaDosdU6e3w&single=true&gid=0&output=html

For example (picked completely at random), ComSign Secured CA has the "Websites" and "Code" trust bits set.

I gather that Mozilla publicly discusses what rights to grant to each CA, and re-evaluates each CA periodically:

https://wiki.mozilla.org/CA:Schedule#Queue_for_Public_Discussion