codesign.sh raw

   1  #!/usr/bin/env bash
   2  # Copyright (c) 2021-present The Bitcoin Core developers
   3  # Distributed under the MIT software license, see the accompanying
   4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  export LC_ALL=C
   6  set -e -o pipefail
   7  
   8  # Environment variables for determinism
   9  export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name"
  10  export TZ=UTC
  11  
  12  # Although Guix _does_ set umask when building its own packages (in our case,
  13  # this is all packages in manifest.scm), it does not set it for `guix
  14  # shell`. It does make sense for at least `guix shell --container`
  15  # to set umask, so if that change gets merged upstream and we bump the
  16  # time-machine to a commit which includes the aforementioned change, we can
  17  # remove this line.
  18  #
  19  # This line should be placed before any commands which creates files.
  20  umask 0022
  21  
  22  if [ -n "$V" ]; then
  23      # Print both unexpanded (-v) and expanded (-x) forms of commands as they are
  24      # read from this file.
  25      set -vx
  26      # Set VERBOSE for CMake-based builds
  27      export VERBOSE="$V"
  28  fi
  29  
  30  # Check that required environment variables are set
  31  cat << EOF
  32  Required environment variables as seen inside the container:
  33      CODESIGNING_TARBALL: ${CODESIGNING_TARBALL:?not set}
  34      DETACHED_SIGS_REPO: ${DETACHED_SIGS_REPO:?not set}
  35      DIST_ARCHIVE_BASE: ${DIST_ARCHIVE_BASE:?not set}
  36      DISTNAME: ${DISTNAME:?not set}
  37      HOST: ${HOST:?not set}
  38      SOURCE_DATE_EPOCH: ${SOURCE_DATE_EPOCH:?not set}
  39      DISTSRC: ${DISTSRC:?not set}
  40      OUTDIR: ${OUTDIR:?not set}
  41  EOF
  42  
  43  ACTUAL_OUTDIR="${OUTDIR}"
  44  OUTDIR="${DISTSRC}/output"
  45  
  46  git_head_version() {
  47      local recent_tag
  48      if recent_tag="$(git -C "$1" describe --exact-match HEAD 2> /dev/null)"; then
  49          echo "${recent_tag#v}"
  50      else
  51          git -C "$1" rev-parse --short=12 HEAD
  52      fi
  53  }
  54  
  55  CODESIGNATURE_GIT_ARCHIVE="${DIST_ARCHIVE_BASE}/${DISTNAME}-codesignatures-$(git_head_version "$DETACHED_SIGS_REPO").tar.gz"
  56  
  57  # Create the codesignature tarball if not already there
  58  if [ ! -e "$CODESIGNATURE_GIT_ARCHIVE" ]; then
  59      mkdir -p "$(dirname "$CODESIGNATURE_GIT_ARCHIVE")"
  60      git -C "$DETACHED_SIGS_REPO" archive --output="$CODESIGNATURE_GIT_ARCHIVE" HEAD
  61  fi
  62  
  63  mkdir -p "$OUTDIR"
  64  
  65  mkdir -p "$DISTSRC"
  66  (
  67      cd "$DISTSRC"
  68  
  69      tar -xf "$CODESIGNING_TARBALL"
  70  
  71      mkdir -p codesignatures
  72      tar -C codesignatures -xf "$CODESIGNATURE_GIT_ARCHIVE"
  73  
  74      case "$HOST" in
  75          *mingw*)
  76              # Apply detached codesignatures
  77              WORKDIR=".tmp"
  78              mkdir -p ${WORKDIR}
  79              cp -r --target-directory="${WORKDIR}" "unsigned/${DISTNAME}"
  80              find "${WORKDIR}/${DISTNAME}" -name "*.exe" -type f -exec rm {} \;
  81              find unsigned/ -name "*.exe" -type f | while read -r bin
  82              do
  83                  bin_base="$(realpath --relative-to=unsigned/ "${bin}")"
  84                  mkdir -p "${WORKDIR}/$(dirname "${bin_base}")"
  85                  osslsigncode attach-signature \
  86                                   -in "${bin}" \
  87                                   -out "${WORKDIR}/${bin_base/-unsigned}" \
  88                                   -CAfile "$GUIX_ENVIRONMENT/etc/ssl/certs/ca-certificates.crt" \
  89                                   -sigin codesignatures/win/"${bin_base}".pem
  90              done
  91  
  92              # Move installer to outdir
  93              cd "${WORKDIR}"
  94              find . -name "*setup.exe" -print0 \
  95                  | xargs -0r mv --target-directory="${OUTDIR}"
  96  
  97              # Make .zip from binaries
  98              find "${DISTNAME}" -print0 \
  99                  | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
 100              find "${DISTNAME}" \
 101                  | sort \
 102                  | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \
 103                  || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 )
 104              ;;
 105          *darwin*)
 106              case "$HOST" in
 107                  arm64*) ARCH="arm64" ;;
 108                  x86_64*) ARCH="x86_64" ;;
 109              esac
 110  
 111              # Apply detached codesignatures (in-place)
 112              signapple apply dist/Bitcoin-Qt.app codesignatures/osx/"${HOST}"/dist/Bitcoin-Qt.app
 113              find "${DISTNAME}" \( -wholename "*/bin/*" -o -wholename "*/libexec/*" \) -type f | while read -r bin
 114              do
 115                  signapple apply "${bin}" "codesignatures/osx/${HOST}/${bin}.${ARCH}sign"
 116              done
 117  
 118              # Make a .zip from dist/
 119              cd dist/
 120              find . -print0 \
 121                  | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
 122              find . | sort \
 123                  | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST}.zip"
 124              cd ..
 125  
 126              # Make a .tar.gz from bins
 127              find "${DISTNAME}" -print0 \
 128                  | sort --zero-terminated \
 129                  | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
 130                  | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \
 131                  || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 )
 132              ;;
 133          *)
 134              exit 1
 135              ;;
 136      esac
 137  )  # $DISTSRC
 138  
 139  rm -rf "$ACTUAL_OUTDIR"
 140  mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
 141      || ( rm -rf "$ACTUAL_OUTDIR" && exit 1 )
 142  
 143  (
 144      tmp="$(mktemp)"
 145      cd /outdir-base
 146      {
 147          echo "$CODESIGNING_TARBALL"
 148          echo "$CODESIGNATURE_GIT_ARCHIVE"
 149          find "$ACTUAL_OUTDIR" -type f
 150      } | xargs realpath --relative-base="$PWD" \
 151          | xargs sha256sum \
 152          | sort -k2 \
 153          > "$tmp";
 154      mv "$tmp" "$ACTUAL_OUTDIR"/SHA256SUMS.part
 155  )
 156