#!/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> -s <secret>'
  echo '   or: echo <secret> |' $(basename "$0") '-k <encrypted-key>'
}

while getopts k:K:s:hv FLAG; do
  case $FLAG in
    k)
      encrypted_key_base64=$OPTARG
      ;;
    K)
      key_base64=$OPTARG
      ;;
    s)
      final_base64=$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 <secret> is passed as an argument, try getting it from stdin if we're
# not interactive
[ "$final_base64" == "" ] && [ ! -t 0 ] && {
  final_base64=$(cat -);
}

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

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

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

iv_base64=$(echo -n "$final_base64" | base64 --decode | dd count=1 bs=16 2>/dev/null | base64)
iv_hex=$(echo -n "$final_base64" | base64 --decode | dd count=1 bs=16 2>/dev/null | xxd -p | tr -d '\n')

encrypted_value_base64=$(echo -n "$final_base64" | base64 --decode | dd skip=16 bs=1 2>/dev/null | base64)
encrypted_value_hex=$(echo -n "$final_base64" | base64 --decode | dd skip=16 bs=1 2>/dev/null | xxd -p | tr -d '\n')

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

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

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

  (>&2 echo 'encrypted_value:');
  (>&2 echo base64: "$encrypted_value_base64");
  (>&2 echo hex: "$encrypted_value_hex");
  (>&2 echo);
}

echo -n "$encrypted_value_base64" | base64 --decode | openssl enc -aes-256-cbc -d -iv "$iv_hex" -K "$key_hex"
