commit e487b6ffca7b023442fd8820eed8345a20310fde Author: Georg Koppen gk@torproject.org Date: Tue Apr 21 11:32:00 2015 +0000
Bug 15539: Make stripping signatures reproducible
NSIS is neither padding properly nor creating a correct PE-file checksum. This makes it hard to verify that the Windows installer we ship is actually matching the one we got built reproducibly.
This fix makes sure that we pad the .exe where needed and that the PE-file checksum is generated.
Thanks to a cypherpunk for this workaround idea. --- gitian/build-helpers/pe_checksum_fix.py | 56 ++++++++++++++++++++++++++ gitian/descriptors/windows/gitian-bundle.yml | 14 +++++++ 2 files changed, 70 insertions(+)
diff --git a/gitian/build-helpers/pe_checksum_fix.py b/gitian/build-helpers/pe_checksum_fix.py new file mode 100755 index 0000000..101e77f --- /dev/null +++ b/gitian/build-helpers/pe_checksum_fix.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# Copyright (c) 2015, The Tor Project, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# * Neither the names of the copyright owners nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +NSIS is neither padding nor calculating the PE-file checksum. But the tool +we use for signing and the tools for stripping the signature do which leads to a +SHA256 mismatch if one tries to check that the binary we offer is actually the +the one we got from our reproducible builds. + +This small Python snippet does both things: It pads the .exe if necessary and it +recalculates the PE-file checksum. Details of the discussion can be foun in bug +15339: https://bugs.torproject.org/15539. + +Thanks to a cypherpunk for this workaround idea. +""" + +import pefile; + +f = open('torbrowser-install-tmp.exe') +exe = f.read() +f.close() +remainder = len(exe) % 8 +if remainder > 0: + exe += '\0' * (8 - remainder) +pef = pefile.PE(data=exe, fast_load=True) +pef.OPTIONAL_HEADER.CheckSum = pef.generate_checksum() +pef.write(filename='torbrowser-install-tmp2.exe') diff --git a/gitian/descriptors/windows/gitian-bundle.yml b/gitian/descriptors/windows/gitian-bundle.yml index 92b9382..54ea258 100644 --- a/gitian/descriptors/windows/gitian-bundle.yml +++ b/gitian/descriptors/windows/gitian-bundle.yml @@ -9,6 +9,9 @@ packages: - "unzip" - "zip" - "nsis" +# Needed to compensate NSIS's failure of regenerating the PE-file checksum and +# proper padding. +- "python-pefile" # These three packages are needed for assembling the HTTPS-Everywhere rules # since 5.0. - "python-lxml" @@ -43,6 +46,7 @@ files: - "versions" - "mar-tools-win32.zip" - "tbb-docs.zip" +- "pe_checksum_fix.py" script: | INSTDIR="$HOME/install" source versions @@ -145,6 +149,11 @@ script: | MAR_FILE=tor-browser-win32-${TORBROWSER_VERSION}_en-US.mar MAR=$MARTOOLS/mar MBSDIFF=$MARTOOLS/mbsdiff.exe $MARTOOLS/make_full_update.sh -q $OUTDIR/$MAR_FILE "Tor Browser"/Browser makensis torbrowser.nsi + # Working around NSIS braindamage + mv torbrowser-install.exe torbrowser-install-tmp.exe + python ~/build/pe_checksum_fix.py + mv torbrowser-install-tmp2.exe torbrowser-install.exe + rm torbrowser-install-tmp.exe mv torbrowser-install.exe $OUTDIR/torbrowser-install-${TORBROWSER_VERSION}_en-US.exe # unzip ../win32-langpacks.zip @@ -181,6 +190,11 @@ script: | MAR_FILE=tor-browser-win32-${TORBROWSER_VERSION}_$LANG.mar MAR=$MARTOOLS/mar MBSDIFF=$MARTOOLS/mbsdiff.exe $MARTOOLS/make_full_update.sh -q $OUTDIR/$MAR_FILE "Tor Browser"/Browser makensis torbrowser.nsi + # Working around NSIS braindamage + mv torbrowser-install.exe torbrowser-install-tmp.exe + python ~/build/pe_checksum_fix.py + mv torbrowser-install-tmp2.exe torbrowser-install.exe + rm torbrowser-install-tmp.exe mv torbrowser-install.exe $OUTDIR/torbrowser-install-${TORBROWSER_VERSION}_$LANG.exe rm "Tor Browser"/Browser/TorBrowser/Data/Browser/profile.default/extensions/langpack-$LANG@firefox.mozilla.org.xpi cd win32-langpacks
tor-commits@lists.torproject.org