#!/bin/bash

# Sign apk for each target architecture.
# This script requires two command line arguments.
# Usage: android-signing <version> <path/to/signing/key>

# In addition, hard-coding the path to an Android SDK build-tools version, as
# BUILD_TOOLS, is required.

set -x
set -e

VERSION=$1
SIGNING_KEY_PATH=$2

# TODO set correctly.
BUILD_TOOLS=/path/to/build-tools/version
export PATH="${BUILD_TOOLS}:${PATH}"

ARCHS="armv7 aarch64 x86 x86_64"

# Sign individual apk
sign_apk() {
    INPUTAPK="$1"

    # https://developer.android.com/studio/publish/app-signing#sign-manually
    # After running `gradlew assembleRelease`, creates an unsigned-unaligned apk

    # Aligning ensures that all uncompressed data starts with a particular byte
    # alignment relative to the start of the file, which may reduce the amount
    # of RAM consumed by an app.
    # zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
    echo Aligning and signing ${INPUTAPK}

    # Append the different stages of signing
    UNSIGNED_UNALIGNED_APK=`echo "${INPUTAPK}" | sed 's/\.apk/-unsigned-unaligned.apk/'`
    UNSIGNED_APK=`echo "${UNSIGNED_UNALIGNED_APK}" | sed 's/-unaligned//'`
    SIGNED_APK=`echo "${UNSIGNED_APK}" | sed 's/-unsigned//'`

    cp "${INPUTAPK}" "${UNSIGNED_UNALIGNED_APK}"

    # Step 1: Align
    zipalign -v -p 4 "${UNSIGNED_UNALIGNED_APK}" "${UNSIGNED_APK}"
    if [ ! $? = 0 ]; then
        echo "zipalign failed"
        exit 1
    fi
    echo zipalign succeeded

    # Step 2: Verify alignment
    zipalign -vc 4 "${UNSIGNED_APK}"
    if [ ! $? = 0 ]; then
        echo "zipalign verify failed"
        exit 1
    fi
    echo zipalign verify succeeded

    # Step 3: Sign
    # Use this command if reading key from file
    apksigner sign --verbose -ks ${SIGNING_KEY_PATH} --ks-type pkcs12 --ks-pass env:KSPASS --debuggable-apk-permitted=false --out "${SIGNED_APK}" "${UNSIGNED_APK}"

    # Or, use below command if using a hardware token
    # apksigner sign --verbose --provider-class sun.security.pkcs11.SunPKCS11 --provider-arg pkcs11_java.cfg --ks NONE --ks-type PKCS11 --debuggable-apk-permitted=false --out "${SIGNED_APK}" "${UNSIGNED_APK}"

    if [ ! $? = 0 ]; then
        echo "apksigner sign failed"
        exit 1
    fi
    echo apksigner sign succeeded

    # Step 4: Verify signature
    apksigner verify --verbose "${SIGNED_APK}"
    if [ ! $? = 0 ]; then
        echo "apksigner verify failed"
        exit 1
    fi

    echo apksigner verify succeeded
}

# Rename and verify signing certificate
finalize() {
  for arch in ${ARCHS}; do
      mv tor-browser-${VERSION}-android-${arch}-multi{-qa,}.apk
  done

  for arch in ${ARCHS}; do
      verified=`apksigner verify --print-certs --verbose tor-browser-${VERSION}-android-${arch}-multi.apk`
      scheme_v1=
      scheme_v2=
      cert_digest=
      pubkey_digest=

      # Verify the expected signing key was used, Alpha verses Release based on the filename.
      if `echo ${VERSION} | grep -q a`; then
          scheme_v1="Verified using v1 scheme (JAR signing): true"
          scheme_v2="Verified using v2 scheme (APK Signature Scheme v2): true"
          cert_digest="Signer #1 certificate SHA-256 digest: 15f760b41acbe4783e667102c9f67119be2af62fab07763f9d57f01e5e1074e1"
          pubkey_digest="Signer #1 public key SHA-256 digest: 4e617e6516f81123ca58e718d617a704ac8365c575bd9e7a731ba5dd0476869d"
      else
          scheme_v1="Verified using v1 scheme (JAR signing): true"
          scheme_v2="Verified using v2 scheme (APK Signature Scheme v2): true"
          cert_digest="Signer #1 certificate SHA-256 digest: 20061f045e737c67375c17794cfedb436a03cec6bacb7cb9f96642205ca2cec8"
          pubkey_digest="Signer #1 public key SHA-256 digest: 343ca8a2e5452670bdc335a181a4baed909f868937d68c4653e44ef84de8dfc6"
      fi
      for digest in "${scheme_v1}" "${scheme_v2}" "${cert_digest}" "${pubkey_digest}"; do
          if ! `echo "${verified}" | grep -q "${digest}"`; then
              echo "Expected digest not found:"
              echo ${digest}
              echo "in:"
              echo ${verified}
              exit 1
          fi
      done
  done

  echo Done.
}

if [ -z "$VERSION" ]; then
    echo Provide version number
    exit
fi

if [ -z "${SIGNING_KEY_PATH}" ]; then
    echo Provide the path to the signing key: release or alpha
    exit
fi

if [ -z "$KSPASS" ]; then
    echo "Enter keystore passphrase"
    stty -echo; read KSPASS; stty echo
    export KSPASS
fi

# Sign all packages
for arch in ${ARCHS}; do
    sign_apk tor-browser-${VERSION}-android-${arch}-multi-qa.apk
done

finalize
