#!/bin/bash -e

hash aws &>/dev/null || {
  (>&2 echo 'Error: AWS CLI not found on PATH');
  exit 1;
}

function usage {
  echo 'Usage:' $(basename "$0") '-k <encrypted-key> -p <plaintext>'
  echo '   or: echo <plaintext> |' $(basename "$0") '-k <encrypted-key>'
}

while getopts k:K:p:hv FLAG; do
  case $FLAG in
    k)
      encrypted_key_base64=$OPTARG
      ;;
    K)
      key_base64=$OPTARG
      ;;
    p)
      value=$OPTARG
      ;;
    v)
      DEBUG=true
      ;;
    h)
      usage
      exit
      ;;
    ?)
      echo
      usage
      exit 1
      ;;
  esac
done

shift "$((OPTIND - 1))"

if [ -n "$encrypted_key_base64" ]; then
  [ "$DEBUG" == "true" ] && (>&2 echo 'Decrypting Data Key')
  key_base64=$(aws kms decrypt --ciphertext-blob fileb://<(echo -n "$encrypted_key_base64" | base64 --decode) --query Plaintext --output text)
fi

[ "$key_base64" == "" ] && {
  (>&2 echo 'Error: Missing Key');
  echo;
  usage;
  exit 1;
}

# if no <plaintext> is passed as an argument, try getting it from stdin if we're
# not interactive
[ "$value" == "" ] && [ ! -t 0 ] && {
  value=$(cat -);
}

[ "$value" == "" ] && {
  (>&2 echo 'Error: Missing Plaintext');
  echo;
  usage;
  exit 1;
}

key_hex=$(echo -n "$key_base64" | base64 --decode | xxd -p | tr -d '\n')

iv_base64=$(head -c16 /dev/urandom | base64)
iv_hex=$(echo -n "$iv_base64" | base64 --decode | xxd -p | tr -d '\n')

[ "$DEBUG" == "true" ] && {
  (>&2 echo 'key:');
  (>&2 echo base64: "$key_base64");
  (>&2 echo hex: "$key_hex");
  (>&2 echo);

  (>&2 echo 'iv:');
  (>&2 echo base64: "$iv_base64");
  (>&2 echo hex: "$iv_hex");
  (>&2 echo);
}

encrypted_value_base64=$(echo -n "$value" | openssl enc -aes-256-cbc -iv "$iv_hex" -K "$key_hex" | base64)
encrypted_value_hex=$(echo -n "$encrypted_value_base64" | base64 --decode | xxd -p | tr -d '\n')

final_hex="$iv_hex$encrypted_value_hex"
final_base64=$(echo -n "$final_hex" | xxd -ps -r | base64)

[ "$DEBUG" == "true" ] && {
  (>&2 echo 'encrypted value:');
  (>&2 echo base64: "$encrypted_value_base64");
  (>&2 echo hex: "$encrypted_value_hex");
  (>&2 echo);

  (>&2 echo 'final:');
  (>&2 echo base64: "$final_base64");
  (>&2 echo hex: "$final_hex");
  (>&2 echo);
}

echo -n "$final_base64"
