This article
describes how to sign your own Firefox extensions with a code-signing
certificate on a Windows platform. It was developed from the linux
article So you want to sign your XPI package? by MozDev Group’s Pete Collins.
1. Download the latest Network Security Services (NSS) package from the Mozilla FTP site:
ftp://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/
For Windows, you’ll want the nss-3.9.zip package in the NSS_3_9_RTM/WINNT5.0_OPT.OBJ/ folder.
2. Extract the contents of the archive file to a local folder. In my case its C:\Apps\nss-3.9\
3. Download the latest Netscape Portable Runtime from the Mozilla FTP site
http://ftp.mozilla.org/pub/mozilla.org/nspr/releases/
For Windows you’ll want the nspr-4.6.zip package in the v4.6/WINNT5.0_OPT.OBJ/ folder.
4. Extract the contents of the archive file to a local folder. In my case its C:\Apps\nspr-4.6\
5. Add the NSS tools bin/ and lib/, and the NSPR lib/
directories to the system path. You can either set this permanently via
Control Panel->System Properties->Advanced->Environment
Variables->System Variables or do it each time you run the tools
from the command-line (preferably using a batch file).
Windows contains its own version of some of these files (e.g.
certutil.exe) in the system directory (\Windows\system32\) so ensure
the new paths are first in the PATH search list.
C:\> set PATH=C:\Apps\nss-3.9\bin\;C:\Apps\nss-3.9\lib\;C:\Apps\nspr-4.6\lib\;%PATH%
6. Review the NSS Tools documentation
7. Initialise the certificate database.
Decide which folder to create the certificate database in. Use this command to create it (note the trailing dot).
| Code: |
| C:\Projects\CodeSigning\> certutil -N -d . |
The dot will cause the database to be created in the current directory.
You will be prompted for the NSS Certificate database password - don’t forget it!
| Code: |
C:\Projects\CodeSigning\> certutil -N -d .
Enter a password which will be used to encrypt your keys.
The password should be at least 8 characters long,
and should contain at least one non-alphabetic character.
Enter new password:
Re-enter password: |
8. Create a test certificate, using the -p option to set a password for the new certificate
| Code: |
C:\Projects\CodeSigning\> signtool -G myTestCert -d . -p”password”
using certificate directory: .
WARNING: Performing this operation while the browser is running could cause
corruption of your security databases. If the browser is currently running,
you should exit the browser before continuing this operation. Enter
“y” to continue, or anything else to abort: y
Enter certificate information. All fields are optional. Acceptable
characters are numbers, letters, spaces, and apostrophes.
certificate common name: XPI Test
organization: TJworld
organization unit: Software
state or province: Nottingham
country (must be exactly 2 characters): GB
username: tj
email address: certificates@lan.tjworld.net
generated public/private key pair
certificate request generated
certificate has been signed
certificate “myTestCert” added to database
Exported certificate to x509.raw and x509.cacert. |
x509.cacert will be used to sign your XPI package. Check it exists on the file system and in the certificate database:
| Code: |
| C:\Projects\CodeSigning\> dir x509*
14/12/2005 15:13 1,031 x509.cacert
14/12/2005 15:13 798 x509.raw
C:\Projects\CodeSigning\> certutil -d . -L
myTestCert u,u,Cu |
8. Prepare your XPI file for signing
Create a new folder just for signing, copy your existing XPI into it,
unzip* it (maintaining paths), delete the XPI and return to the
certificate-database folder.
* Assumes you have a zip utility available on your system path. This example is using the CygWin bin/zip.exe tool.
You can use a graphical Zip tool provided it manages the internal sub-directory structure properly.
The 7-Zip tool doesn’t work when creating Mozilla XPI signed archives because it sorts the directory entries alphabetically, and Mozilla requires the first entry to be META-INF/zigbert.rsa.
| Code: |
| C:\Projects\CodeSigning\> md signed
C:\Projects\CodeSigning\> copy C:\Projects\fsb\fsb.xpi signed
1 file(s) copied.
C:\Projects\CodeSigning\> cd signed
C:\Projects\CodeSigning\signed> unzip fsb.xpi
Archive: fsb.xpi
creating: chrome/
inflating: chrome.manifest
inflating: chrome/fsb.jar
inflating: install.rdf
C:\Projects\CodeSigning\signed> del fsb.xpi
C:\Projects\CodeSigning\signed> cd .. |
9. Sign your XPI
| Code: |
C:\Projects\CodeSigning\> signtool -d . -k myTestCert -p “password” signed/
using certificate directory: .
Generating signed//META-INF/manifest.mf file..
–> chrome/fsb.jar
–> chrome.manifest
–> install.rdf
Generating zigbert.sf file..
tree “signed/” signed successfully
|
10. Re-package your XPI
Change to the signed/ folder, create a new zip with the META-INF/zigbert.rsa file listed first, then add the remaining files.
| Code: |
| C:\Projects\Certs\> cd signed
C:\Projects\CodeSigning\signed\> zip fsb.xpi META-INF/zigbert.rsa
adding: META-INF/zigbert.rsa (deflated 35%)
C:\Projects\CodeSigning\signed> zip -r -D fsb.xpi * -x META-INF/zigbert.rsa
adding: META-INF/manifest.mf (deflated 37%)
adding: META-INF/zigbert.sf (deflated 40%)
adding: chrome/fsb.jar (deflated 74%)
adding: chrome.manifest (deflated 69%)
adding: install.rdf (deflated 62%) |
11. Temporarily install the Test Certificate Authority into your Mozilla browser
Rename the x509.cacert file generated earlier to x509.cert
Import it into Mozilla Firefox as a Software Developer Certificate Authority. * delete the certificate from Mozilla Firefox once you’ve finished testing
Firefox 1.5: From the Tools menu choose Options->Advanced->Security->View Certificates->Authorities
Firefox 1.0: From the Tools menu choose Options->Advanced->Certificates->Manage Certificates->Authorities
Press the Import button.
Navigate to the folder containing x509.cert and choose it.
In the Downloading Certificate dialog, tick Trust this CA to identify software developers. and press the View button if you wish to examine the certificate more closely.
Press the OK button and you’ll see your new certificate in the list of Authorities.
12. Attempt to install the signed extension
Either drag and drop or browse to and download the signed XPI. When the Mozilla Firefox Software Installation dialog appears the organisation name of the certificate will appear where Firefox usually displays unsigned.
13. Obtaining a valid software developer code-signing certificate
Now you know it all works, you need to add a real software developer’s
certificate to the NSS certificate database, and use that to sign the
XPI. There are several issuers of software developer certificates, with
the three key differentials: availability, cost and identity
verification.
Many issuers will not provide a software developer certificate to
individuals (how ridiculous) so you may have to search hard to find one
that will, and who also has a CA root Authority installed in Mozilla
Firefox.
Without the certificate-issuers CA root certificate Mozilla Firefox
will not confirm the validity of your certificate to users who want to
install your extension.
Ideally you want a certificate that has a root CA installed in all
major platforms (Microsoft Windows, Sun Java, Mozilla/Netscape
Firefox/Navigator, Opera) so you only use one certificate for signing
all your software, no matter which platform it is for.
The cheapest universally supported (Mozilla, Java, Microsoft)
certificate seems to be the Comodo Instant-SSL offering. You can get a free certificate for open-source developers from Unizeto Certum, but their root certificate is only present in Mozilla Firefox and Opera (not Java or Microsoft).
Here are some current issuers:
Comodo Instant-SSL Code Signing
Digi-Sign Digi-Code
GeoTrust Code Signing
Thawte Code Signing (owned by Verisign)
Unizeto Certum Code-signing (free certificates for open-source authors) *only available in Mozilla Firefox and Opera
Verisign Code Signing
You will need to apply for a Code Signing Certificate
and satisfy the Issuer’s identity verification procedures. They will
then issue a signed certificate. When you receive the signed
certificate it must be imported into the certificate database.
Your browser will generate a new private key and Code Signing Request (CSR) in the background without you necessarily realising it. The CSR will be uploaded to the Issuer. Later, you must use the same browser when installing the new certificate because the key and certificate pair must be together.
Hint: When applying for a certificate ensure that the Organisation (O) contains your name and not the Issuer’s default text, because this is what is displayed to users.
For this guide I applied for a free certificate from Unizeto Certum.
After completing the application process where I entered my details
into the online application, I received an automated email requesting
documentary evidence of my ID in the form of a photo-ID or similar.
I have hi-resolution scanned images of my passport and drivers license
for these situations so I placed them on my web-server temporarily in a
hidden location and emailed Unizeto Certum with the details and
location of the files.
Within a few hours I received a confirmation email from a human
accepting the ID images and giving me a hyperlink to the certifcate
download area.
Install the certificate into Mozilla Firefox (which goes with the private key created earlier), and copy/paste the displayed certificate text into a new file called C:\Projects\CodeSigning\Certum Code Signing.cer
14. Installing your real certificate
There are two steps required to install the new certificate in the Code Signing NSS certificate database.
Install the Issuer’s Certificate Authority Root
Install your key and certificate
The root CA establishes the trust of your certificate. Many issuer’s
have multiple root CAs for different levels of trust. find out which
one was used for your certificate and download it.
You can view the details of your certificate in Mozilla Firefox and get this information from the Issued By Common Name (Unizeto Certum’s free certificate CA is Certum Level I).
Download the Root CA and any intermediate certificates used to sign
your certificate from the Issuer; their web site will have a link
somewhere to their root CAs and public certificates. (Certum public key page). I downloaded the Certum Root CA and Certum Level I Digital ID for WWW and SSL/TLS Servers, copied the text and saved them to the files C:\Projects\CodeSigning\Certum Root CA.cer and C:\Projects\CodeSigning\Certum Level I.cer.
Open a command prompt (ensure the paths to the NSS tools are set as in
step 5) in the CodeSigning folder, install the Issuer CA certificates,
and check they have been added correctly.
| Code: |
| C:\Projects\CodeSigning> certutil -A -n “Certum Root CA” -t “TC,TC,TC” -d . -i “Certum Root CA.cer”
C:\Projects\CodeSigning> certutil -A -n “Certum Level I” -t “c,c,C” -d . -i “Certum Level I.cer”
C:\Projects\CodeSigning> certutil -L -d .
myTestCert u,u,Cu
Certum Root CA CT,C,C
Certum Level I CT,C,C |
The name given to the newly issued certificate in the Mozilla Firefox
keystore is not the easiest key alias in the world to remember, so I’ve
added an additional step here that lets you rename it (its not just a
simple rename operation, unfortunately).
To find the name, in Mozilla Firefox navigate to the Certificate Manager (described in Step 11), choose Your Certificates, select the new certificate, press View, choose Details and look at the first entry in the Certificate Fields tree-view.
My Unizeto Certum certificate is named “TJ’s Unizeto Sp. z o.o. ID” but I want it to be called “Code Signing (Certum)”.
The trick is to install the certificate (without the key) first and
give your chosen nickname at that point. When the key/certificate pair
is imported from Mozilla Firefox afterwards, the private key will be
added but the certificate name will remain the same.
| Code: |
| C:\Projects\CodeSigning> certutil -A -n “Code Signing (Certum)” -t “u,u,u” -d . -i “Certum Code Signing.cer”
C:\Projects\CodeSigning> certutil -L -d .
myTestCert u,u,Cu
Certum Root CA CT,C,C
Certum Level I CT,C,C
Code Signing (Certum) ,,
C:\Projects\CodeSigning> signtool -l -d .
using certificate directory: .
Object signing certificates
—————————————
myTestCert
Issued by: myTestCert (XPI Test)
Expires: Tue Mar 14, 2006
Code Signing (Certum)
Issued by: Certum Level I (Certum Level I)
Expires: Tue Mar 14, 2006
—————————————
For a list including CA’s, use “signtool -L” |
Now you must export the new key/certificate pair from the Mozilla
Firefox certificate database and into the NSS certificate database.
The hardest part is locating Mozilla’s key database. It consists of two files named key3.db and cert8.db.
They usually live in the Mozilla Firefox user profile folder. I found mine in C:\Documents and Settings\TJ\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default\ where xxxxxxxx is a random string of characters.
This procedure assumes you installed the new certificate into Mozilla Firefox in step 13.
Here’s the commands required to export it to a file, import it to the
Code Signing database, and verify the signing attributes (u,u,u).
Ensure you use the nickname of your certificate in place of mine, and
the directory where your Mozilla Firefox key database files are:
| Code: |
C:\Projects\CodeSigning>
pk12util -o “Certum Code Signing.pkcs12″ -n “TJ’s Unizeto Sp. z o.o.
ID” -d “C:\Documents and Settings\TJ\Application
Data\Mozilla\Firefox\Profiles\xxxxxxxx.default”
Enter password for PKCS12 file:
Re-enter password:
pk12util: PKCS12 EXPORT SUCCESSFUL
C:\Projects\CodeSigning> pk12util -i “Certum Code Signing.pkcs12″ -d .
Enter Password or Pin for “NSS Certificate DB”:
Enter password for PKCS12 file:
pk12util: PKCS12 IMPORT SUCCESSFUL
C:\Projects\CodeSigning> certutil -L -d .
myTestCert u,u,Cu
Certum Root CA CT,C,C
Certum Level I c,c,C
Code Signing (Certum) u,u,u |
You should notice that the existing certificate has been updated.
15. Signing with your real certificate
This is a repeat of steps 8, 9 and 10 using the real certificate’s details. Here’s the output on a test directory:
| Code: |
C:\Projects\CodeSigning>signtool -d . -k “Code Signing (Certum)” -p ******* test
using certificate directory: .
Generating test/META-INF/manifest.mf file..
–> test.txt
Generating zigbert.sf file..
tree “test” signed successfully |
Warning: Currently NSS signtool does not
include the certificate chain in the signing certificate (zigbert.rsa).
This means that Firefox will refuse to install code signed via an
intermediate certificate authority such as Certum Level I unless the user installs that certificate into Firefox first.
A bug report
has been raised with the NSS team to find a way to allow a certificate
chain to be used for code signing. Please post your supporting comments
on the bug there so the NSS team know this is something that many
people wish to have.
16. Incorporating signing into your build process
You may want to incorporate these steps into your existing build process. I have a build.bat file that automates the creation of the jar and xpi files. This example is using the CygWin bin/zip.exe tool.
build.bat is placed in the extension’s root folder. E.g.
/dev/fsb/build.bat
/dev/fsb/install.rdf
/dev/fsb/chrome.manifest
/dev/fsb/chrome/
/dev/fsb/chrome/content/
/dev/fsb/chrome/locale/
/dev/fsb/chrome/skin/
Here it is with the code-signing steps included:
| Code: |
@echo off
set x=%cd%
echo Building %x%.xpi …
echo Started at %DATE% %TIME% > %x%\build.log
md build\chrome
cd chrome
zip -r -0 “%x%.jar” * >> %x%\build.log
move “%x%.jar” ..\build\chrome >> %x%\build.log
cd ..
copy install.rdf build >> %x%\build.log
copy chrome.manifest build >>%x%\build.log
signtool.exe -d C:\Projects\CodeSigning -k “Code Signing (Certum)” -p “password” build/ >> %x%\build.log
cd build
zip “%x%.xpi” META-INF/zigbert.rsa >> %x%\build.log
zip -r -D “%x%.xpi” * -x META-INF/zigbert.rsa >> %x%\build.log
rem copy “%x%.xpi” ..\..\..\http\fsb.xpi >> %x%\build.log
move “%x%.xpi” ..\ >> %x%\build.log
cd ..
rd build /s/q
echo Done. |
Make sure to replace password with your NSS Certificate database password.
17. Happy Signing