From 914868a05dfcae0f766283e0065aa36762cc5abe Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 21 Nov 2014 19:26:45 -0500 Subject: [PATCH] build: add a deterministic dmg signer --- Makefile.am | 4 +- .../gitian-descriptors/gitian-osx-signer.yml | 37 +++++++++++++ contrib/gitian-descriptors/gitian-osx.yml | 15 +++++- contrib/macdeploy/detached-sig-apply.sh | 53 +++++++++++++++++++ contrib/macdeploy/detached-sig-create.sh | 46 ++++++++++++++++ 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 contrib/gitian-descriptors/gitian-osx-signer.yml create mode 100755 contrib/macdeploy/detached-sig-apply.sh create mode 100755 contrib/macdeploy/detached-sig-create.sh diff --git a/Makefile.am b/Makefile.am index e144fb11e..b51f477b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,7 +26,9 @@ WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ $(top_srcdir)/contrib/macdeploy/background.png \ - $(top_srcdir)/contrib/macdeploy/DS_Store + $(top_srcdir)/contrib/macdeploy/DS_Store \ + $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ + $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml new file mode 100644 index 000000000..db9b4af93 --- /dev/null +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -0,0 +1,37 @@ +--- +name: "bitcoin-dmg-signer" +suites: +- "precise" +architectures: +- "amd64" +packages: +- "libc6:i386" +- "faketime" +reference_datetime: "2013-06-01 00:00:00" +remotes: [] +files: +- "bitcoin-0.9.99-osx-unsigned.tar.gz" +- "signature.tar.gz" +script: | + WRAP_DIR=$HOME/wrapped + mkdir -p ${WRAP_DIR} + export PATH=`pwd`:$PATH + FAKETIME_PROGS="dmg genisoimage" + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + UNSIGNED=`echo bitcoin-*.tar.gz` + SIGNED=`echo ${UNSIGNED} | sed 's/.tar.*//' | sed 's/-unsigned//'`.dmg + + tar -xf ${UNSIGNED} + ./detached-sig-apply.sh ${UNSIGNED} signature.tar.gz + ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index cbe28e4f3..eb6df2096 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -106,8 +106,21 @@ script: | ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} make install-strip + + make deploydir + mkdir -p unsigned-app-${i} + cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} + cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate + cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff + mv dist unsigned-app-${i} + pushd unsigned-app-${i} + find . | sort | tar --no-recursion -czf ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz -T - + popd + make deploy - ${WRAP_DIR}/dmg dmg Bitcoin-Qt.dmg ${OUTDIR}/${DISTNAME}-osx.dmg + ${WRAP_DIR}/dmg dmg Bitcoin-Qt.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg cd installed find . -name "lib*.la" -delete diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh new file mode 100755 index 000000000..7b3eb1b19 --- /dev/null +++ b/contrib/macdeploy/detached-sig-apply.sh @@ -0,0 +1,53 @@ +#!/bin/sh +set -e + +UNSIGNED=$1 +SIGNATURE=$2 +ARCH=x86_64 +ROOTDIR=dist +BUNDLE=${ROOTDIR}/Bitcoin-Qt.app +TEMPDIR=signed.temp +OUTDIR=signed-app + +if [ -z "$UNSIGNED" ]; then + echo "usage: $0 " + exit 1 +fi + +if [ -z "$SIGNATURE" ]; then + echo "usage: $0 " + exit 1 +fi + +rm -rf ${TEMPDIR} && mkdir -p ${TEMPDIR} +tar -C ${TEMPDIR} -xf ${UNSIGNED} +tar -C ${TEMPDIR} -xf ${SIGNATURE} + +if [ -z "${PAGESTUFF}" ]; then + PAGESTUFF=${TEMPDIR}/pagestuff +fi + +if [ -z "${CODESIGN_ALLOCATE}" ]; then + CODESIGN_ALLOCATE=${TEMPDIR}/codesign_allocate +fi + +for i in `find ${TEMPDIR} -name "*.sign"`; do + SIZE=`stat -c %s ${i}` + TARGET_FILE=`echo ${i} | sed 's/\.sign$//'` + + echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}" + ${CODESIGN_ALLOCATE} -i ${TARGET_FILE} -a ${ARCH} ${SIZE} -o ${i}.tmp + + OFFSET=`${PAGESTUFF} ${i}.tmp -p | tail -2 | grep offset | sed 's/[^0-9]*//g'` + if [ -z ${QUIET} ]; then + echo "Attaching signature at offset ${OFFSET}" + fi + + dd if=$i of=${i}.tmp bs=1 seek=${OFFSET} count=${SIZE} 2>/dev/null + mv ${i}.tmp ${TARGET_FILE} + rm ${i} + echo "Success." +done +mv ${TEMPDIR}/${ROOTDIR} ${OUTDIR} +rm -rf ${TEMPDIR} +echo "Signed: ${OUTDIR}" diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh new file mode 100755 index 000000000..aff4f08da --- /dev/null +++ b/contrib/macdeploy/detached-sig-create.sh @@ -0,0 +1,46 @@ +#!/bin/sh +set -e + +ROOTDIR=dist +BUNDLE=${ROOTDIR}/Bitcoin-Qt.app +CODESIGN=codesign +TEMPDIR=sign.temp +TEMPLIST=${TEMPDIR}/signatures.txt +OUT=signature.tar.gz + +if [ ! -n "$1" ]; then + echo "usage: $0 " + echo "example: $0 -s MyIdentity" + exit 1 +fi + +rm -rf ${TEMPDIR} ${TEMPLIST} +mkdir -p ${TEMPDIR} + +${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}" + +for i in `grep -v CodeResources ${TEMPLIST}`; do + TARGETFILE="${BUNDLE}/`echo ${i} | sed "s|.*${BUNDLE}/||"`" + SIZE=`pagestuff $i -p | tail -2 | grep size | sed 's/[^0-9]*//g'` + OFFSET=`pagestuff $i -p | tail -2 | grep offset | sed 's/[^0-9]*//g'` + SIGNFILE="${TEMPDIR}/${TARGETFILE}.sign" + DIRNAME="`dirname ${SIGNFILE}`" + mkdir -p "${DIRNAME}" + echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}" + dd if=$i of=${SIGNFILE} bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null +done + +for i in `grep CodeResources ${TEMPLIST}`; do + TARGETFILE="${BUNDLE}/`echo ${i} | sed "s|.*${BUNDLE}/||"`" + RESOURCE="${TEMPDIR}/${TARGETFILE}" + DIRNAME="`dirname "${RESOURCE}"`" + mkdir -p "${DIRNAME}" + echo "Adding resource for: "${TARGETFILE}"" + cp "${i}" "${RESOURCE}" +done + +rm ${TEMPLIST} + +tar -C ${TEMPDIR} -czf ${OUT} . +rm -rf ${TEMPDIR} +echo "Created ${OUT}"