tl;dr where is Mozilla's the root CA for verifying Mozilla-signed Firefox extensions?
I'm trying to understand and validate Mozilla's Add-on/Extension signatures outside of the Firefox GUI. In Mozilla's documentation, the *.xpi
file created and signed by Mozilla is easily understood as a zip-file with a META-INF
folder containing a sha256 checksum file cryptographically signed by mozilla. However, the root Certificate Authority is (obviously) not bundled with the extension but with the Firefox binary. The documentation describes how to verify a signature of the sha256sum file as:
$ 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
However, I cannot for the life of me find the location of test.addons.signing.root.ca.crt
(for -CAfile
). The documentation is unhelpful: "The root cert is not stored in the document but shipped with Firefox directly."
Scanning both system and user mozilla and firefox directories for *.pem
and *.crt
files yielded only results related to verifying website certificates but nothing for addons.
So, then, where is Mozilla's the root CA for verifying Mozilla-signed Firefox extensions?
I hate to answer my own question, but after beating my head against a brick wall, and a lot of trial and error, I think I have this figured out. As of 2024-07-29, (a) the addon cert is in gecko-dev
and (b) the Mozilla Wiki is wrong.
Certificates (including the addon certificates) are located in the gecko-dev repository, specifically in the master/security/ssl folder. The addon certificate we want is addons-public.crt
:
https://github.com/mozilla/gecko-dev/blob/master/security/manager/ssl/addons-public.crt
The needed action is NOT openssl cms -verify
but openssl smime -verify
. You can learn about the differences between cms
and smime
in this security stackexchange answer.
Altogether, the command to be used should be:
openssl smime -verify \
-inform der -in META-INF/mozilla.rsa \
-content META-INF/mozilla.sf \
-CAfile addons-public.crt -purpose any
WARNING - the reason why -CAfile
is used is because this makes openssl implicitly trust the certificate file without any additional tests! As such it is absolutely critical that you trust this file, never receive it from third-party sources, ensure it's accurate, and keep it safe.
What we just did is verify the cryptographic signature of META-INF/mozilla.sf
, which contains the sha1 and sha256 digests of the file META-INF/manifest.mf
. You can verify the sha256 digest of META-INF/manifest.mf
simply by comparing the SHA256-Digest-Manifest:
line in META-INF/mozilla.sf
to the sha256 digest calculated as:
openssl sha256 -binary META-INF/manifest.mf | base64
The file META-INF/manifest.mf
likewise contains a list of all the files in the extension and their sha1 and sha256 digests, which can then be checked/verified to ensure authenticity.
FINAL WARNING - it's possible for a malicious actor to add or remove files to an .xpi
addon without them being added or removed to/from META-INF/manifest.mf
. You should therefore check not only for any files listed in META-INF/manifest.mf
which do not exist, as well as files which are not listed in META-INF/manifest.mf
. By the same logic, file names in META-INF/manifest.mf
that point outside it's directory structure should be a red flag of a potentially malicious .xpi
addon.