Confirmed users
529
edits
No edit summary |
|||
| Line 1: | Line 1: | ||
Mozilla | Mozilla requires all extensions to be signed by Mozilla in order for them to be installable in Release and Beta versions of Firefox. Signing is be done through [http://addons.mozilla.org/ addons.mozilla.org (AMO)] and is be mandatory for all extensions, regardless of where they are hosted. | ||
== Algorithm == | |||
Extension signing is controlled by Mozilla and requires access to a private signing infrastructure exposed by [https://addons.mozilla.org/ AMO], and internal services like [https://github.com/mozilla-services/autograph Autograph]. | |||
Addons and Extensions are XPI files (zip archives) where each file in the archives is hashed, and the manifest containing all the hashes is signed. When signing an extension, a manifest file containing the hash of each file in the XPI is first generated. The manifest file is stored in the signed XPI under '''META-INF/manifest.mf'''. The snippet below shows an example of manifest file. | |||
<source> | |||
Manifest-Version: 1.0 | |||
Name: install.rdf | |||
Digest-Algorithms: MD5 SHA1 | |||
MD5-Digest: rzkfLZ5nC80leZsgMSGT3w== | |||
SHA1-Digest: +43YVUxeOYeiJeOKeJaRdancg5I= | |||
Name: bootstrap.js | |||
Digest-Algorithms: MD5 SHA1 | |||
MD5-Digest: 2rUx2iRkGHx9yehpvoF2Wg== | |||
SHA1-Digest: 7F7q7SUdOpxp7EYDFLENUqrNWMo= | |||
Name: test.txt | |||
Digest-Algorithms: MD5 SHA1 | |||
MD5-Digest: tT4aaxDCqRgFrpVHhe//Wg== | |||
SHA1-Digest: 8mPWZnQPS9arW9Tu/vmC+JHgnYA= | |||
</source> | |||
A signature file is then created containing the hash of the manifest file (eg. `openssl dgst -binary -sha1 manifest.mf | base64`). The signature file is stored in the XPI under '''META-INF/mozilla.sf'''. An example is shown below: | |||
<source> | |||
Signature-Version: 1.0 | |||
MD5-Digest-Manifest: OlmmwIHcPmhoIt4uMxdh8A== | |||
SHA1-Digest-Manifest: 82zZH0Aq6GaTNMq+PnBlzep6fEA= | |||
</source> | |||
A PKCS7 detached signature is computed on "mozilla.sf", using a signing certificate generated for each signature. The signing certificate, also called end-entity cert, is issued by an intermediate certificate of the Firefox private PKI. No special key usage or extended key usage is required in the end-entity cert, but its subject CN must match the addon ID (for example, addon ID test@tests.mozilla.org would have a cert CN set to that value). | |||
The [https://tools.ietf.org/html/rfc2315 PKCS #7 (section 9.1 SignedData type)] signature is a binary file stored in the XPI under '''META-INF/mozilla.rsa'''. Because it is a standard PKCS7 signature, it can be verified using OpenSSL, as follows: | |||
<source lang:bash> | |||
$ openssl cms -verify -inform der -in META-INF/mozilla.rsa -content META-INF/mozilla.sf -CAfile test.addons.signing.root.ca.crt -purpose any | |||
Signature-Version: 1.0 | |||
MD5-Digest-Manifest: OlmmwIHcPmhoIt4uMxdh8A== | |||
SHA1-Digest-Manifest: 82zZH0Aq6GaTNMq+PnBlzep6fEA= | |||
Verification successful | |||
</source> | |||
Both the end-entity and the intermediate certificates are also stored in the | |||
SignedData.Certificates document. The root cert is not stored in the document | |||
but shipped with Firefox directly. | |||
When installing addons, Firefox does the following verifications: | |||
* verify the signature of `mozilla.sf` using `mozilla.rsa` | |||
* verify the signing cert chains back to the Firefox Root CA | |||
* verify the hash of `manifest.mf` matches the hash stored in `mozilla.sf` | |||
* verify the hashes of all files in the XPI match the hashes stored in `manifest.mf` | |||
* verify all files in the XPI are listed in `manifest.mf` | |||
=== Signing of special addons === | |||
There are three special cases of addons developed by Mozilla: System addons, Mozilla Extensions and Hotfixes. | |||
If the addon is a system addon, the Organizational Unit (OU) of the end-entity certificate must be set to "Mozilla Components". | |||
If the addon is a Mozilla Extension, the OU of the EE cert must be set to "Mozilla Extensions". | |||
If the addon is a hotfix, the addon ID must match the pref `extensions.hotfix.id` | |||
(currently `firefox-hotfix@mozilla.org`) and the public key hash of the end-entity cert must match the fingerprints set in `extensions.hotfix.certs.1.sha1Fingerprint` or | |||
`extensions.hotfix.certs.2.sha1Fingerprint`. | |||
refs: | |||
* https://dxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/internal/XPIProvider.jsm | |||
* https://developer.mozilla.org/en-US/docs/Signing_a_XPI | |||
== Documentation == | == Documentation == | ||