<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ben Hearsum (Posts about signing)</title><link>https://hearsum.ca/</link><description></description><atom:link href="https://hearsum.ca/categories/signing.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2025 &lt;a href="mailto:ben@hearsum.ca"&gt;Ben Hearsum&lt;/a&gt; </copyright><lastBuildDate>Fri, 07 Feb 2025 16:48:05 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>A Brief History of Code Signing at Mozilla</title><link>https://hearsum.ca/posts/history-of-code-signing-at-mozilla/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Shipping large software to end-user devices is a complicated process. Shipping large software &lt;em&gt;securely&lt;/em&gt; to end-user devices is even more complicated. Signing the things that ship to end-user devices is one of those complications, and it gets even more complicated when you sign thousands of artifacts per day.&lt;/p&gt;

&lt;p&gt;Mozilla has been signing Firefox in some form beginning with Firefox 1.0. This began with detached GPG signatures for builds, and progressed to Authenticode signing for Windows installers in Firefox 1.0.1. Since then it has evolved over time to encompass other platforms, other types of files within our products, and other ways that we ship (such as our own update packages). This post will provide a overview of the what, when, why, and how of code signing at Mozilla over the past ~20 years.&lt;/p&gt;

&lt;h1&gt;What, when, and why&lt;/h1&gt;

&lt;h3&gt;Early GPG &amp;amp; Authenticode Signing&lt;/h3&gt;

&lt;p&gt;When we first began signing, it happened on a Windows machine. Late in the release process, after Windows installers had been built, we would download all of the release artifacts to this machine, sign the Windows installers, and generate detached GPG signatures for those before pushing the artifacts elsewhere.&lt;/p&gt;

&lt;p&gt;At this time, the private keys and certificates were held on a USB stick that was kept removed from the machine at-rest. A Release Engineer needed to be physically present in Mountain View to perform this step. Once inserted, signing could be done via Remote Desktop rather than at the physical machine (but don't forget to remove the USB stick afterwards!).&lt;/p&gt;

&lt;p&gt;GPG signing was done with the standard GPG tools, running in cygwin. Authenticode signing was also done with the standard (at the time) Microsoft 'signcode.exe' tool. An annoying fact about that tool, is that it only accepted the necessary passphrase from a GUI dialog. To work around this, we had an &lt;a href="https://en.wikipedia.org/wiki/AutoIt"&gt;AutoIt&lt;/a&gt; script running in the background that injected the passphrase into this dialog whenever it popped up. This interesting way of automating the process meant that mouse movements or keyboard interaction at the wrong time could interfere with the signing process.&lt;/p&gt;

&lt;p&gt;This process was partly scripted, but there was still a series of ~15 commands someone had to run by hand (and not mess up) to get everything done. You can see these commands for yourself in our now-ancient &lt;a href="https://wiki.mozilla.org/ReleaseEngineering/Unified_Release_Process#Sign_builds"&gt;Unified Release Process&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h3&gt;Windows internal file signing&lt;/h3&gt;

&lt;p&gt;Careful readers may have noted that early Authenticode signing only covered the Firefox installer itself, not the EXEs and DLLs inside of it. At some point (I haven't gone to the effort of tracking down exactly where...) we started signing these inner files as well. This process seems to have been &lt;a href="https://wiki.mozilla.org/ReleaseEngineering/Unified_Release_Process#Signing_windows_files"&gt;lost to the sands of time&lt;/a&gt;, but I seem to recall it worked very similarly to the installer signing process, but without the GPG parts.&lt;/p&gt;

&lt;h3&gt;Improved signing on Windows&lt;/h3&gt;

&lt;p&gt;The first notable improvement we had to this process was to automate most of the copy/pasting that was done from the wiki. This came in the form of &lt;a href="https://github.com/mozilla/build-tools/blob/dba69406faad0c8e7a016150a3f5761ef83914d2/release/signing/Makefile"&gt;a Makefile that with a few mere inputs&lt;/a&gt;, would download, sign, and re-upload the signed builds. The main benefit of this was reduced opportunity for human error.&lt;/p&gt;

&lt;p&gt;Not long after that, &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470146"&gt;we had our first real game-changing improvements&lt;/a&gt;. Chris AtLee &lt;a href="https://atlee.ca/posts/blog20090804faster-signing/"&gt;wrote a nice post about it back in 2009&lt;/a&gt;, and how his changes took signing time from 8 hours all the way down to sub-15 minutes. This was accomplished through a combination of faster hardware, parallelized signing, in-process compression &amp;amp; decompression, and better caching. His changes also introduced &lt;a href="https://github.com/mozilla/build-tools/blob/c2e8e6f048db8990d629f169072d2a06b42e4759/release/signing/sign-release.py"&gt;a hefty amount of python&lt;/a&gt; into the signing process, which paved the way for the next big improvement...&lt;/p&gt;

&lt;h3&gt;Automatic signing&lt;/h3&gt;

&lt;p&gt;Despite the signing process now being very quick once it gets started, it could still sometimes take hours or longer to begin the process. Typically this would happen if our build and repack processes finished at a time when no Release Engineer was around to begin signing. This was solved with what we called "autosign". Rather than require a Release Engineer to be around at the right moment, we adjusted our scripts to allow them to &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=558464#c1"&gt;be started ahead of time&lt;/a&gt;, and be smart enough to know when all of the files it needs to sign are ready. This work eliminated all wait time between builds being ready and signing running.&lt;/p&gt;

&lt;h3&gt;Signing Windows builds...on Linux!&lt;/h3&gt;

&lt;p&gt;In 2011, &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509158#c10"&gt;signing was rearchitected altogether&lt;/a&gt;. In short, the idea was to move signing to a highly secured Linux server, and sign builds through an API as part of the build process. This allowed builds to be signed as they were produced, and reduced the number of times builds had to move from one server to another before they shipped.

An obvious question here is how we would manage to sign Windows binaries on Linux...as it turns out, the mono project had &lt;a href="https://manpages.debian.org/testing/mono-devel/signcode.1.en.html"&gt;its own version of signcode that ran natively on Linux&lt;/a&gt; that we were able to make use of.&lt;/p&gt;

&lt;h3&gt;MAR Signing&lt;/h3&gt;

&lt;p&gt;Shortly after (and perhaps even motivating - I'm not sure at this point) the aforementioned signing server work, we &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=699700"&gt;began signing our MAR (Mozilla ARchive) packages&lt;/a&gt; that update users from an older version of Firefox to a newer version. Thanks to the earlier work, it was fairly trivial to use the same architecture to sign these files.&lt;/p&gt;

&lt;h3&gt;macOS .app signing&lt;/h3&gt;

&lt;p&gt;The idea of signing .app bundles for macOS was filed &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400296#c0"&gt;all the way back in 2007&lt;/a&gt;. There was &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400296#c25"&gt;some initial work on this&lt;/a&gt; in 2010, but we were unable to land it at that time. Around the same time that MAR signing was happening in 2012, we &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400296#c68"&gt;picked up this work again&lt;/a&gt; and managed to drive it home this time.&lt;/p&gt;

&lt;p&gt;Unfortunately, there were no tools available at the time to sign macOS builds on anything except a fairly modern macOS machine. For this reason, we had to run additional copies of our signing server on macOS and sign those builds with them. (If you've ever had to run macOS as a server you'll know just how unfortunate this was...)&lt;/p&gt;

&lt;h3&gt;Taskcluster/signingscript/iscript&lt;/h3&gt;

&lt;p&gt;In 2018, Mozilla migrated its CI and Release automation from our aging Buildbot systems to &lt;a href="https://taskcluster.net/"&gt;Taskcluster&lt;/a&gt;. As part of this, signing tasks moved to specialized Taskcluster workers known as "signingscript" and "iscript", used for signing non-macOS and macOS builds respectively. These specialized workers continued to outsource the actual work of signing to the previously discussed signing servers.&lt;/p&gt;

&lt;p&gt;An important part of this change is the introduction of &lt;a href="https://scriptworker.readthedocs.io/en/latest/chain_of_trust.html"&gt;Chain of Trust&lt;/a&gt;, a significant security enhancement that helps ensure that only authentic artifacts are signed to this day.&lt;/p&gt;

&lt;h3&gt;Introducing...Autograph!&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla-services/autograph"&gt;Autograph&lt;/a&gt; is Mozilla's modern code signing service. It was built specifically to provide a signing service that allowed us to keep private key material in Hardware Security Modules (HSMs). Migrating release signing to it was a huge improvement over the existing signing server where Release Engineers had direct access to such things. It was initially used for signing XPIs and APKs, but by the end of 2019 we had migrated all non-macOS signing to it and retired the old Linux signing servers.&lt;/p&gt;

&lt;p&gt;In addition to the security enhancements it brought, we saw great performance wins with it as well, largely in thanks to it's support for &lt;a href="https://github.com/mozilla-services/autograph/blob/main/docs/architecture.md#overview"&gt; only requiring a hash of the bytes being signed to be sent over the wire&lt;/a&gt;. (This requires that the client has some advanced knowledge of the file being signed, but it saves a &lt;em&gt;tremendous&lt;/em&gt; amount of network traffic at our scale.)

&lt;/p&gt;&lt;h3&gt;Notarization with rcodesign&lt;/h3&gt;

In 2023 we started making use of &lt;a href="https://gregoryszorc.com/docs/apple-codesign/0.17.0/apple_codesign_rcodesign.html"&gt;rcodesign&lt;/a&gt; to &lt;a href="https://github.com/mozilla-releng/scriptworker-scripts/pull/714"&gt;notarize and staple our macOS builds&lt;/a&gt;. While actual macOS code signing itself continues to happen on macOS machines, this allowed us to move at least some of our operations into the cloud and reduce our reliance on mac hardware.

&lt;h1&gt;Tools and tech&lt;/h1&gt;

&lt;p&gt;I've mentioned a number of tools and technology that we use as part of signing, but I've purposely glossed over some details in the interest of brevity. The following section is a glossary of sorts, and introduces some more under the hood tools that we use as part of signing. If you're interested in the gory details, the links below should be enough to find them for yourself! Or you can stop by &lt;a href="https://chat.mozilla.org/#/room/#firefox-ci:mozilla.org"&gt;#firefox-ci on Matrix to ask questions!&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;osslsigncode&lt;/h3&gt;
&lt;p&gt;osslsigncode is a &lt;a href="https://github.com/mtrojnar/osslsigncode"&gt;tool that implements parts of Microsoft's signtool.exe&lt;/a&gt;. In the past, we used it to directly sign PE files. These days, we use it's support for attaching the signatures that Autograph makes to them.&lt;/p&gt;

&lt;h3&gt;winsign&lt;/h3&gt;
&lt;p&gt;Winsign is a &lt;a href="https://github.com/mozilla-releng/winsign"&gt;python library for signing and manipulating Authenticode signatures&lt;/a&gt;. It relies on osslsigncode for writing signatures, and supports signing directly with a private key, or outsourcing the signing process to a passed in function. The latter is what we use, and it's how we inject a call to Autograph into the signing process.&lt;/p&gt;

&lt;h3&gt;msix-packaging&lt;/h3&gt;
&lt;p&gt;In 2021 we began shipping Firefox as an MSIX package. As part of this we discovered that osslsigncode does not support signing MSIX packages. Luckily for us, Microsoft's MSIX packaging tools are open source and run on Linux, and we found a &lt;a href="https://github.com/microsoft/msix-packaging/issues/340#issuecomment-620797067"&gt;fork that contained most of what was needed&lt;/a&gt; to support signing. With a few additional modifications, we were able to support signing these packages in our existing systems.&lt;/p&gt;

&lt;h3&gt;apple-codesign&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://gregoryszorc.com/docs/apple-codesign/0.17.0/index.html"&gt;apple-codesign&lt;/a&gt; is a very exciting project from Gregory Szorc which provides 3rd party tools capable of signing, notarizing, and stapling .app bundles and other Apple formats such as .pkg and .dmg. These tools run on Linux, and as noted above, we're already making use of them to notarize and staple our .app bundles.

We're extremely excited about this project, and grateful to Gregory Szorc for all the effort he's bit into it. In the future we're looking forward to migrating our actual code signing to these tools which would (finally) allow us to retire our dedicated macOS signing machines.&lt;/p&gt;

&lt;h3&gt;mardor&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/mozilla-releng/build-mar"&gt;mardor&lt;/a&gt; is a python tool to manage, and most importantly, sign, MAR files. In the days before Autograph it was used to directly sign MAR files. These days we only use it to inject signatures made by Autograph into the files, similar to our usage of osslsigncode.&lt;/p&gt;

&lt;h3&gt;signingscript&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/mozilla-releng/scriptworker-scripts/tree/master/signingscript"&gt;signingscript&lt;/a&gt; is the glue between our CI system (Taskcluster) and Autograph. Through a combination of the tools listed above, custom code in signingscript itself, and communication with Autograph it produces signed builds. It is additionally responsible for notarizing and stapling our macOS builds.&lt;/p&gt;

&lt;h3&gt;iscript&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/mozilla-releng/scriptworker-scripts/tree/master/iscript"&gt;iscript&lt;/a&gt; is essentially a pared down version of signingscript (in fact their code is both derived from our early signing server code), and is responsible for signing our macOS builds. iscript runs on a small cluster of mac minis, which are a huge pain in the butt to manage.

&lt;/p&gt;&lt;h3&gt;autograph&lt;/h3&gt;
As noted in an earlier section &lt;a href="https://github.com/mozilla-services/autograph"&gt;Autograph&lt;/a&gt; is our modern code signing service. It has a simple HTTP API that accepts signing requests and returns signed data or files. In addition to signing various artifacts that we ship it also makes &lt;a href="https://github.com/mozilla-services/autograph/blob/main/signer/contentsignaturepki/README.md"&gt;Content Signatures&lt;/a&gt; on behalf of addons.mozilla.org, aus5.mozilla.org/Balrog (our update server), and some other backend services that Firefox communicates with, helping to ensure the security and integrity of requests made between Firefox and Mozilla-run services.

&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;What a ride it's been over the last 20 years! We've gone from signing nothing to signing nearly everything in some form. Signing started off as a very manual process, and now happens seamlessly thousands of times per day.&lt;/p&gt;

&lt;p&gt;I don't think it would be possible to name everyone that contributed to this, but it took the ideas and efforts of tens, if not hundreds, of people to get to this point: release engineers, build system experts, security folks, and many others were all critical to getting us where we are today.&lt;/p&gt;

&lt;p&gt;I've got this post as brief as possible, but if you're interested in more details on any parts here feel free to reach out!&lt;/p&gt;</description><category>release-automation</category><category>signing</category><guid>https://hearsum.ca/posts/history-of-code-signing-at-mozilla/</guid><pubDate>Thu, 30 Jan 2025 16:18:15 GMT</pubDate></item><item><title>Mozilla Software Release GPG Key Transition</title><link>https://hearsum.ca/posts/mozilla-software-release-gpg-key-transition/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Late last week we discovered the expiration of the GPG key that we use to sign Firefox, Fennec, and Thunderbird nightly builds and releases. We had &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1139929"&gt;been aware that this was coming up&lt;/a&gt;, but we unfortunately missed our deadline to renew it. This caused failures in many of our automated nightly builds, so it was quickly noticed and acted upon.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gpg.mozilla.org/pks/lookup?op=get&amp;amp;search=0x61B7B526D98F0353"&gt;Our new GPG key is as follows&lt;/a&gt;, and available on keyservers such as &lt;a href="https://gpg.mozilla.org"&gt;gpg.mozilla.org&lt;/a&gt; and &lt;a href="https://pgp.mit.edu/"&gt;pgp.mit.edu&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;
pub   4096R/0x61B7B526D98F0353 2015-07-17
      Key fingerprint = 14F2 6682 D091 6CDD 81E3  7B6D 61B7 B526 D98F 0353
uid                            Mozilla Software Releases &lt;release&gt;
sub   4096R/0x1C69C4E55E9905DB 2015-07-17 [expires: 2017-07-16]
&lt;/release&gt;&lt;/pre&gt;

&lt;p&gt;The new primary key is signed by many Mozillians, the old master key, as well as our OpSec team's GPG key. Nightlies and releases will now be signed with the subkey (0x1C69C4E55E9905DB), and a new one will be generated from the same primary key before this one expires. This means that you can validate Firefox releases with the primary public key in perpetuity.&lt;/p&gt;

&lt;p&gt;We are investigating a few options to &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1185610"&gt;make sure key renewal happens without delay in the future.&lt;/a&gt;&lt;/p&gt;</description><category>planet-mozilla</category><category>releng</category><category>signing</category><guid>https://hearsum.ca/posts/mozilla-software-release-gpg-key-transition/</guid><pubDate>Tue, 21 Jul 2015 18:45:18 GMT</pubDate></item><item><title>Signing Software at Scale</title><link>https://hearsum.ca/posts/signing-software-at-scale/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Mozilla produces a lot of builds. We build Firefox for somewhere between 5 to 10 platforms (depending how you count). We release Nightly and Aurora every single day, Beta twice a week, and Release and ESR every 6 weeks (at least). Each release contains an en-US build and nearly a hundred localized repacks. In the past the only builds we signed were Betas (which were once a week at the time), Releases, and ESRs. We had a pretty well established manual for it, but due to being manual it was still error prone and impractical to use for Nightly and Aurora. Signing of Nightly and Aurora became an important issue when &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=481815"&gt;background updates&lt;/a&gt; were implemented because one of the new security requirements with background updates was signed installers and MARs.&lt;/p&gt;

&lt;h2&gt;Enter: Signing Server&lt;/h2&gt;
&lt;p&gt;At this point it was clear that the only practical way to sign all the builds that we need to is to automate it. It sounded crazy to me at first. How can you automate something that depends on secret keys, passphrases, and very unfriendly tools? Well, there's some tricks you need to know, and throughout the development and improvement of our "signing server", we've learned a lot. In the post I'll talk about those tricks and show you how can use them (or even our entire signing server!) to make your signing process faster and easier.&lt;/p&gt;

&lt;p&gt;Credit where credit is due: &lt;a href="http://atlee.ca/blog/"&gt;Chris AtLee&lt;/a&gt; wrote the core of the signing server and support for some of the signature types. Over time &lt;a href="http://www.erickdransch.com/blog/"&gt;Erick Dransch&lt;/a&gt;, &lt;a href="http://blog.drapostles.org/"&gt;Justin Wood&lt;/a&gt;, &lt;a href="http://code.v.igoro.us/"&gt;Dustin Mitchell&lt;/a&gt;, and I have made some improvements and added support for additional types of signatures.&lt;/p&gt;
&lt;hr&gt;

&lt;h3&gt;Tip #1: Collect passphrases at startup&lt;/h3&gt;
&lt;p&gt;This should be obvious to most, but it's very important not to store the passphrases to your private keys unencrypted. However, because they're needed to unlock the private keys when doing any signing the server needs to have access to them somehow. We've dealt with this by asking for them when launching a signing server instance:&lt;/p&gt;
&lt;pre&gt;
$ bin/python tools/release/signing/signing-server.py signing.ini
gpg passphrase: 
signcode passphrase: 
mar passphrase: 
&lt;/pre&gt;

&lt;p&gt;Because instances are started manually by someone in the small set of people with access to passphrases we're able to ensure that keys are never left unencrypted at rest.&lt;/p&gt;

&lt;h3&gt;Tip #2: Don't let just any machine request signed files&lt;/h3&gt;
&lt;p&gt;One of the first problems you run into when you have an API for signing files is how to make sure you don't accidentally sign malicious files. We've dealt with this in a few ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You need a special token in order to request any type of signing. These tokens are time limited and only a small subset of segregated machines may request them (on behalf of the build machines). Since build jobs can only be created if you're able to push to hg.mozilla.org, random people are unable to submit anything for signing.&lt;/li&gt;
&lt;li&gt;Only our build machines are allowed to make signing requests. Even if you managed to get hold of a valid signing token, you wouldn't be able to do anything with it without also having access to a build machine. This is a layer of security that helps us protect against a situation where an evil doer may gain access to a &lt;a href="https://wiki.mozilla.org/ReleaseEngineering/How_To/Request_a_slave"&gt;loaner machine&lt;/a&gt; or other less restricted part of our infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have other layers of security built in too (HTTPS, firewalls, access control, etc.), but these are the key ones built into the signing server itself.&lt;/p&gt;

&lt;h3&gt;Tip #3: Use input redirection and other tricks to work around unfriendly command line tools&lt;/h3&gt;
&lt;p&gt;One of the trickiest parts about automating signing is getting all the necessary command line tools to accept input that's not coming from a console. Some of them are relative easy and accept passphrases via stdin:&lt;/p&gt;
&lt;pre&gt;
proc = Popen(command, stdout=stdout, stderr=STDOUT, stdin=PIPE)
proc.stdin.write(passphrase)
proc.stdin.close()
&lt;/pre&gt;

&lt;p&gt;Others, like OpenSSL, are fussier and require the use of pexpect:&lt;/p&gt;
&lt;pre&gt;
proc = pexpect.spawn("openssl", args)
proc.logfile_read = stdout
proc.expect('Enter pass phrase')
proc.sendline(passphrase)
&lt;/pre&gt;

&lt;p&gt;And it's no surprise at all that OS X is the fussiest of them all. In order to sign you have to unlock the keychain by hand, run the signing command, and relock the keychain yourself:&lt;/p&gt;
&lt;pre&gt;
child = pexpect.spawn("security unlock-keychain" + keychain)
child.expect('password to unlock .*')
child.sendline(passphrase)
check_call(sign_command + [f], cwd=dir_, stdout=stdout, stderr=STDOUT)
check_call(["security", "lock-keychain", keychain])
&lt;/pre&gt;

&lt;p&gt;Although the code is simple in the end, a lot of trial, error, and frustration was necessary to arrive at it.&lt;/p&gt;

&lt;h3&gt;Tip #4: Sign everything you can on Linux (including Windows binaries!)&lt;/h3&gt;
&lt;p&gt;As fussy as automating tools like openssl can be on Linux, it pales in comparison to trying to automate anything on Windows. In the days before the signing server we had a scripted signing method that ran on Windows. Instead of providing the passphrase directly to the signing tool, it had to typed into a modal window. It was "automated" with an &lt;a href="https://www.autoitscript.com/site/autoit/"&gt;AutoIt&lt;/a&gt; script that typed in the password whenever the window popped up. This was hacky, and sometimes lead to issues if someone moved the mouse or pressed a key at the wrong time and changed window focus.&lt;/p&gt;

&lt;p&gt;Thankfully there's tools available for Linux that are capable of signing Windows binaries. We started off by using &lt;a href="http://docs.go-mono.com/index.aspx?link=man%3asigncode%281%29"&gt;Mono's signcode&lt;/a&gt; - a more or less drop in replacement for Microsoft's:&lt;/p&gt;
&lt;pre&gt;
$ signcode -spc MozAuthenticode.spc -v MozAuthenticode.pvk -t http://timestamp.verisign.com/scripts/timestamp.dll -i http://www.mozilla.com -a sha1 -tr 5 -tw 60 /tmp/test.exe
Mono SignCode - version 2.4.3.1
Sign assemblies and PE files using Authenticode(tm).
Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed.

Enter password for MozAuthenticode.pvk: 
Success
&lt;/pre&gt;

&lt;p&gt;This works great for 32-bit binaries - we've been shipping binaries signed with it for years. For some reason that we haven't figured out though, it doesn't sign 64-bit binaries properly. For those we're using &lt;a href="http://osslsigncode.sourceforge.net/"&gt;"osslsigncode"&lt;/a&gt;, which is an OpenSSL based tool to do Authenticode signing:&lt;/p&gt;
&lt;pre&gt;
$ osslsigncode -certs MozAuthenticode.spc -key MozAuthenticode.pvk -i http://www.mozilla.com -h sha1 -in /tmp/test64.exe -out /tmp/test64-signed.exe
Enter PEM pass phrase:
Succeeded

$ osslsigncode verify /tmp/test64-signed.exe 
Signature verification: ok

Number of signers: 1
    Signer #0:
        Subject: /C=US/ST=CA/L=Mountain View/O=Mozilla Corporation/CN=Mozilla Corporation
        Issuer : /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Code Signing CA-1

Number of certificates: 3
    Cert #0:
        Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
        Issuer : /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
    Cert #1:
        Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Code Signing CA-1
        Issuer : /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA
    Cert #2:
        Subject: /C=US/ST=CA/L=Mountain View/O=Mozilla Corporation/CN=Mozilla Corporation
        Issuer : /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Code Signing CA-1
&lt;/pre&gt;

&lt;p&gt;In addition to Authenticode signing we also do GPG, APK, and couple of Mozilla-specific types of signing (MAR, EME Voucher) on Linux. We also sign our Mac builds with the signing server. Unfortunately, the tools needed for that are only available on OS X, so we have to run separate signing servers for these.&lt;/p&gt;

&lt;h3&gt;Tip #5: Run multiple signing servers&lt;/h3&gt;
Nobody likes a single point of failure, so we've built support our signing client to retry against multiple instances. Even if we lose part of our signing server pool, our infrastructure stays up:
&lt;pre&gt;
$ python signtool.py --cachedir cache -t token -n nonce -c host.cert -H dmgv2:mac-v2-signing1.srv.releng.scl3.mozilla.com:9120 -H dmgv2:mac-v2-signing2.srv.releng.scl3.mozilla.com:9120 -H dmgv2:mac-v2-signing3.srv.releng.scl3.mozilla.com:9120 -H dmgv2:mac-v2-signing4.srv.releng.scl3.mozilla.com:9120 --formats dmgv2 Firefox.app
2015-01-23 06:17:59,112 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: processing Firefox.app.tar.gz on https://mac-v2-signing3.srv.releng.scl3.mozilla.com:9120
2015-01-23 06:17:59,118 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: connection error; trying again soon
2015-01-23 06:18:00,119 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: processing Firefox.app.tar.gz on https://mac-v2-signing4.srv.releng.scl3.mozilla.com:9120
2015-01-23 06:18:00,141 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: uploading for signing
2015-01-23 06:18:10,748 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: processing Firefox.app.tar.gz on https://mac-v2-signing4.srv.releng.scl3.mozilla.com:9120
2015-01-23 06:19:11,848 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: processing Firefox.app.tar.gz on https://mac-v2-signing4.srv.releng.scl3.mozilla.com:9120
2015-01-23 06:19:40,480 - ed40176524e7c197f4e23f6065a64dc3c9a62e71: OK
&lt;/pre&gt;

&lt;h2&gt;Running your own signing server&lt;/h2&gt;
&lt;p&gt;It's easy! All of the code you need to run your own signing server is in our &lt;a href="https://github.com/mozilla/build-tools/tree/master/release/signing"&gt;tools repository&lt;/a&gt;. You'll need to set-up a virtualenv and create your own config file, but once you're ready you can attempt to start it with the following command:&lt;/p&gt;
&lt;pre&gt;
python signing-server.py signing.ini
&lt;/pre&gt;

&lt;p&gt;You'll be prompted for the passphrases to your private keys. If there's any problems with your config file or the passphrases the server will fail to start. Once you've got it up and running you can use try signing! &lt;a href="https://github.com/mozilla/build-tools/blob/master/release/signing/get_token.py"&gt;get_token.py&lt;/a&gt; has an example of how to generate a signing token, and &lt;a href="https://github.com/mozilla/build-tools/blob/master/release/signing/signtool.py"&gt;signtool.py&lt;/a&gt; will take your unsigned files and give you back signed versions. Happy signing!&lt;/p&gt;</description><category>planet-mozilla</category><category>signing</category><guid>https://hearsum.ca/posts/signing-software-at-scale/</guid><pubDate>Wed, 28 Jan 2015 16:45:21 GMT</pubDate></item><item><title>Upcoming changes to Mac package layout, signing</title><link>https://hearsum.ca/posts/upcoming-changes-to-mac-package-layout-signing/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Apple recently &lt;a href="https://developer.apple.com/library/mac/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG205"&gt;announced changes to how OS X applications must be packaged and signed&lt;/a&gt; in order for them to function correctly on OS X 10.9.5 and 10.10. The tl;dr version of this is "only mach-O binaries may live in .app/Contents/MacOS, and signing must be done on 10.9 or later". Without any changes, future versions of Firefox will cease to function out-of-the-box on OS X 10.9.5 and 10.10. We do not have a release date for either of these OS X versions yet.



Changes required:

* Move all non-mach-O files out of .app/Contents/MacOS. Most of these will move to .app/Contents/Resources, but files that could legitimately change at runtime (eg: everything in defaults/) will move to .app/MozResources (which can be modified without breaking the signature): https://bugzilla.mozilla.org/showdependencytree.cgi?id=1046906&amp;amp;hide_resolved=1. This work is in progress, but no patches are ready yet.

* Add new features to the client side update code to allow partner repacks to continue to work. (https://bugzilla.mozilla.org/show_bug.cgi?id=1048921)

* Create and use 10.9 signing servers for these new-style apps. We still need to use our existing 10.6 signing servers for any builds without these changes. (https://bugzilla.mozilla.org/show_bug.cgi?id=1046749 and https://bugzilla.mozilla.org/show_bug.cgi?id=1049595)

* Update signing server code to support new v2 signatures.



Timeline:

We are intending to ship the required changes with Gecko 34, which ships on November 25th, 2014. The changes required are very invasive, and we don't feel that they can be safely backported to any earlier version quickly enough without major risk of regressions. We are still looking at whether or not we'll backport to ESR 31. To this end, we've asked that Apple whitelist Firefox and Thunderbird versions that will not have the necessary changes in them. We're still working with them to confirm whether or not this can happen.



This has been cross posted a few places - please send all follow-ups to the mozilla.dev.platform newsgroup.&lt;/p&gt;</description><category>osx</category><category>planet-mozilla</category><category>signing</category><guid>https://hearsum.ca/posts/upcoming-changes-to-mac-package-layout-signing/</guid><pubDate>Tue, 12 Aug 2014 16:05:31 GMT</pubDate></item><item><title>Update on Mac Code Signing #2</title><link>https://hearsum.ca/posts/update-on-mac-code-signing-2/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;In my previous post I said that Mac signing had been turned on, and that it would stay on. Unfortunately, the following morning we &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758046"&gt;caught some issues that only came up after updating&lt;/a&gt;. It took a bit of time to resolve those, but as of this morning we got them worked out, and signed mac builds are back. There are a couple of &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758644&amp;gt;minor&amp;lt;/a&amp;gt;%20&amp;lt;a%20href=" https:&gt;follow-up&lt;/a&gt; issues to address, but we're in a good enough state to backport signing to Aurora and Beta, and ship it in Firefox 13.0. On Saturday evening I'll be enabling it on Aurora, and on Monday morning on Beta - assuming no new issues come up.



If you see ANY issues related to updating on Mac please file a bug and cc me (:bhearsum). It's very important that any issues are brought up immediately, as we intend to ship this to the release channel on June 5th.



Huge thanks (again) to Steven Michaud, Ted Mielczarek, Erick Dransch, and anyone else that helped make this happen.&lt;/p&gt;</description><category>signing</category><guid>https://hearsum.ca/posts/update-on-mac-code-signing-2/</guid><pubDate>Fri, 25 May 2012 17:45:05 GMT</pubDate></item><item><title>Update on Mac Code Signing of Firefox</title><link>https://hearsum.ca/posts/update-on-mac-code-signing-of-firefox/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Last week &lt;a href="http://blog.mozilla.org/bhearsum/archives/287"&gt;I talked about our plans around Mac build signing&lt;/a&gt;. In it, I said that I intended to have signed dep/try builds by the end of last week and signed Nightly builds early this week. Unfortunately, shortly after publishing I realized that due to some complicated infrastructure reasons, we couldn't turn on dep/try build signing prior to Nightly. However, I'm pleased to announce that all the necessary work for Mac builds signing is landed and in production. From now on, mozilla-central based builds will be signed. As other branches merge the necessary patch, they will be signed too. Nightly updates have been disabled for now, to give QA a chance to verify everything. Nightly updates should be re-enabled sometime tomorrow. This should be an invisible change to everyone, but please file bugs on any issues (especially those related to new installs or updates) and cc me (bhearsum@mozilla.com).



Additionally, I want to correct one thing in my previous post. I said that applications 'will not run on 10.8 unless the user has allowed “applications downloaded from anywhere” to run'. However, it has come to my attention that this isn't entirely true. You _can_ except specific applications from this policy if you ctrl+click the application and hit "open". This works for unsigned apps, self signed apps, and those signed with a Mac Development certificate.&lt;/p&gt;</description><category>signing</category><guid>https://hearsum.ca/posts/update-on-mac-code-signing-of-firefox/</guid><pubDate>Tue, 22 May 2012 21:11:07 GMT</pubDate></item><item><title>Code signing coming to Firefox Mac builds</title><link>https://hearsum.ca/posts/code-signing-coming-to-firefox-mac-builds/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;A few weeks ago a new Developer Preview of OS X 10.8 was released and it was discovered that as things stand now, Firefox will not run on it. With the current default settings, 10.8 will not allow any software to run unless it's signed with an Apple Developer ID (essentially, a certificate issued by a particular Apple Root CA). We don't know exactly when 10.8 will be released to the public but some have speculated that it could be as early as the week of June 11th at WWDC 2012. We must have a signed and released Firefox out there before the general public starts upgrading and we've been working hard to make that happen as soon as possible. This post will give a short history of Mac signing at Mozilla and talk about our timeline for enabling it.



&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;

Code signing of Mac builds has been on our radar for a long time. &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400296"&gt;Bug 400296&lt;/a&gt; was originally filed in 2007. In late 2010 Syed Albiz did a ton of great work figuring out the Apple tools and how we can integrate them into our automation. That work didn't quite get finished before his internship was completed and the bug stagnated for some time afterwards. At the start of this year there was renewed energy when Erick Dransch picked up the bug. We attempted to land his work and enable signing on nightlies in mid-April, but that ended up bouncing due to some conflicts with our upgrade to 10.7-based build machines. Erick's internship expired before everything could be fixed up, and the bug fell to me.



After gaining access to Mozilla's Apple Developer account on Monday there was a lot of early iteration before we got to the point where we could sign a build in a way that Mountain Lion liked. There's multiple certificates types that one can get from Apple ("Development Certificate", "Mac App Certificate", "Developer ID Certificate") and multiple versions of OS X and XCode (each with their own quirks) that one can sign with. Mostly thanks to Steven Michaud's knowledge and assistance we figured out exactly what combination of these we'll need to use to have signed Firefox builds that work everywhere.



&lt;h3&gt;Where we're at now&lt;/h3&gt;

At this point in time we've got all the tools we need to sign all Mac Firefox builds. The only blocking issue at this point is figuring out access restrictions to our Apple Developer Account, so that we can generate our final Developer ID certificates.



&lt;h3&gt;Endgoal&lt;/h3&gt;

Like with Windows Authenticode signing we will have 3 different certificates for different types of Firefox builds. Dep and try builds are at the lowest level of trust and have no regular users and therefore will be signed with a self signed certificate. This means that they will not run on 10.8 unless the user has allowed "applications downloaded from anywhere" to run (which is not the default). Nightly and Aurora are at an elevated level of trust and have a userbase. These will be signed with their own Developer ID certificate. Finally, Beta and Release builds are at the highest level of trust and oversight, and represent the majority of our users. They will be signed with a separate Developer ID certificate. From a user standpoint, Nightly, Aurora, Beta and Release will all look the same but using separate certificates gives us some degree of isolation in terms of certificate revocation.



&lt;h3&gt;Timeline&lt;/h3&gt;

I intend to have &lt;em&gt;dep and try builds signed by the end of the week&lt;/em&gt;. After we figure out the access restrictions to our Developer Account we will turn on signing of &lt;em&gt;Nightly builds, hopefully early/mid next week&lt;/em&gt;. After letting those settle for a day or two we will turn on signing of &lt;em&gt;Aurora and Beta builds, hopefully by the end of next week&lt;/em&gt;.



&lt;hr&gt;



If you're interested in the technical details of signing Mac builds &lt;a href="http://www.erickdransch.com/blog/2012/02/signing-mac-builds/"&gt;Erick wrote an excellent blog post&lt;/a&gt; detailing the trials and tribulations of writing tools around them.</description><category>firefox</category><category>signing</category><guid>https://hearsum.ca/posts/code-signing-coming-to-firefox-mac-builds/</guid><pubDate>Thu, 17 May 2012 12:42:08 GMT</pubDate></item><item><title>Using Authenticode Code Signing Certificates with OS X's Signing Tools</title><link>https://hearsum.ca/posts/using-authenticode-code-signing-certificates-with-os-xs-signing-tools/</link><dc:creator>Ben Hearsum</dc:creator><description>&lt;p&gt;Our intern &lt;a href="http://www.erickdransch.com/blog/"&gt;Erick&lt;/a&gt; has been doing some great work reviving, polishing and finalizing the patches that will allow us to &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400296"&gt;start signing OS X builds&lt;/a&gt; (more to come on that in his blog!). When we do start signing them we're planning to use our existing set of code signing certificates for them rather than buy new ones. I thought it would be a simple task to convert them so I set off to convert our internal, self-generated ones. After hours and hours of head scratching and frustration I learned that some versions of Microsoft's "makecert" tool are broken, and generate invalid PKCS7 certs that openssl can't cope with properly. From &lt;a href="http://www.drh-consultancy.demon.co.uk/pkcs12faq.html"&gt;the OpenSSL PKCS#12 FAQ&lt;/a&gt;:

&lt;code&gt;

Q. What are SPC files?

    A. They are simply DER encoded PKCS#7 files containing the certificates. Well they are in the newer versions of the tools. The older versions used an invalid PKCS#7 format.

&lt;/code&gt;



The end result of all my attempts ended up being a PKCS#12 certificate that Apple's codesign tool claimed couldn't be used to do code signing.



After finding that FAQ, I decided to try to convert our Nightly code signing certificate instead. Following the great instructions found on &lt;a href="http://www.entropy.ch/blog/Developer/2008/02/11/Mac-OS-X-Application-Code-Signing.html"&gt;Marc Liyanage's blog&lt;/a&gt; I managed to successfully convert the certificate, import it into a Keychain, and successfully sign something! Here's the shortened version of what I did. Note that it requires &lt;a href="http://www.drh-consultancy.demon.co.uk/pvk.html"&gt;the PVK tool found here&lt;/a&gt;:

&lt;code&gt;

~/pvk.exe -in Nightly.pvk -out Nightly.key.pem

openssl pkcs7 -inform der -print_certs  Nightly.cert.pem

openssl pkcs12 -export -inkey Nightly.key.pem -in Nightly.cert.pem -out Nightly.p12

&lt;/code&gt;



I hope this helps someone else avoid the same frustration!&lt;/p&gt;</description><category>signing</category><guid>https://hearsum.ca/posts/using-authenticode-code-signing-certificates-with-os-xs-signing-tools/</guid><pubDate>Tue, 28 Feb 2012 16:15:55 GMT</pubDate></item></channel></rss>