#!/bin/bash

# Directories
cur=`pwd`
tmp="/var/mobile/Library/AirMessage/"
scriptName=`basename $0`

# Certificate Variables
C="UK"
ST="England"
L="London"
O="Spark"
OU="Spark"
CN=${1}
emailAddress="sam@sparkservers.co.uk"
OUTPATH="/var/mobile/Library/AirMessage/"
VERBOSE=0
pass=${2}

safeExit() {
  if [ -d $tmp ]; then
    if [ $VERBOSE -eq 1 ]; then
      echo "Removing temporary directory '${tmp}'"
    fi
    #rm -rf $tmp
  fi

  trap - INT TERM EXIT
  exit
}

# Test output path is valid
testPath() {
  if [ ! -d $OUTPATH ]; then
    echo "The specified directory \"${OUTPATH}\" does not exist"
    exit 1
  fi
}


# Prompt for variables that were not provided in arguments
checkVariables() {
  # Country
  if [[ $C -eq "" ]]; then
    echo -n "Country Name (2 letter code) [AU]:"
    read C
  fi

  # State
  if [[ $ST -eq "" ]]; then
    echo -n "State or Province Name (full name) [Some-State]:"
    read ST
  fi

  # Locality
  if [[ $L -eq "" ]]; then
    echo -n "Locality Name (eg, city) []:"
    read L
  fi

  # Organization
  if [[ $O -eq "" ]]; then
    echo -n "Organization Name (eg, company) [Internet Widgits Pty Ltd]:"
    read O
  fi

  # Organizational Unit
  if [[ $OU -eq "" ]]; then
    echo -n "Organizational Unit Name (eg, section) []:"
    read OU
  fi

  # Common Name
  if [[ $CN -eq "" ]]; then
    echo -n "Common Name (e.g. server FQDN or YOUR name) []:"
    read CN
  fi

  # Common Name
  if [[ $emailAddress -eq "" ]]; then
    echo -n "Email Address []:"
    read emailAddress
  fi
}

# Show variable values
showVals() {
  echo "Country: ${C}";
  echo "State: ${ST}";
  echo "Locality: ${L}";
  echo "Organization: ${O}";
  echo "Organization Unit: ${OU}";
  echo "Common Name: ${CN}";
  echo "Email: ${emailAddress}";
  echo "Output Path: ${OUTPATH}";
  echo "Verbose: ${VERBOSE}";
}

# Init
init() {
  cd $tmp
  pwd
}

# Cleanup
cleanup() {
  echo "Cleaning up"
  cd $cur
  rm -rf $tmp
}

buildCsrCnf() {
cat << EOF > ${tmp}/tmp.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=${C}
ST=${ST}
L=${L}
O=${O}
OU=${OU}
CN=${CN}
emailAddress=${emailAddress}
[SAN]
subjectAltName=DNS:${CN}
EOF
}

buildExtCnf() {
cat << EOF > ${tmp}/v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = ${CN}
EOF
}

# Build TLS Certificate
build() {
  rm -r ${OUTPATH}cert.csr
  rm -r ${OUTPATH}cert.crt
  rm -r ${OUTPATH}cert.key
  rm -r ${OUTPATH}cert.p12

  # Generate CA key & crt
  openssl genrsa -out ${tmp}/tmp.key 2048
  openssl req -x509 -new -nodes -key ${tmp}/tmp.key -sha256 -days 3650 -out ${tmp}/tmp.pem -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${emailAddress}"
  
  # CSR Configuration
  buildCsrCnf

  # Create v3.ext configuration file
  buildExtCnf

  # Server key
  openssl req -new -sha256 -nodes -out ${OUTPATH}cert.csr -newkey rsa:2048 -keyout ${OUTPATH}cert.key -config <( cat ${tmp}/tmp.csr.cnf )

  # Server certificate
  openssl x509 -req -in ${OUTPATH}cert.csr -CA ${tmp}/tmp.pem -CAkey ${tmp}/tmp.key -CAcreateserial -out ${OUTPATH}cert.crt -days 3650 -sha256 -extfile ${tmp}/v3.ext

  openssl pkcs12 -export -out ${OUTPATH}cert.p12 -inkey ${OUTPATH}cert.key -in ${OUTPATH}cert.crt -password pass:${pass}
}

build
# showVals
safeExit
