#!/bin/bash

set -euo pipefail

main() {
  echo "Create new certificates tailored for teleop use with TLS/DTLS/DDS Secure"
  echo "Using "${1}" as the openssl config
  echo "Args "${@:2}" should all be security or governance xml files to be signed
  echo "Pipe the command yes to this script to avoid the prompts"

  local openssl_cnf="${1}"
  local cakey=myCA/private/cakey.pem
  local cacert=myCA/cacert.pem
  local valid_days=3650

  createCA "${openssl_cnf}"
  createPeerCert tcc

  for xml in "${@:2}"
  do
    signDdsSecureFiles "${xml}"
  done
}

createPeerCert() {
  echo "creating Certificates for ${1}"

  local peer_name="${1}"

  # identity, create certificate request and private key
  local req=myCA/peer/"${peer_name}"req.pem
  local key=myCA/peer/${1}key.pem
  local cert=myCA/newcerts/"${peer_name}"cert.pem
  local certwithkey=myCA/peercerts/"${peer_name}".pem

  openssl req -nodes -new -newkey rsa:2048 -config "${openssl_cnf}" -keyout "${key}" -out "${req}"
  # use "self signed cert" to sign the request and generate a certificate
  openssl ca -create_serial -config "${openssl_cnf}" -days "${valid_days}" -in "${req}" -out "${cert}"
  # Append private key to peer certificate
  cat "${cert}" "${key}" > "${certwithkey}"
  # Copy cert with key file to our current directory
  cp "${certwithkey}" .
}

signDdsSecureFiles() {
  local xmlpath="${1}"
  local base_name="$(basename "${xmlpath}" .xml)"

  # Generate a signed governance or security permissions file in the current directory
  openssl smime -sign -in "${xmlpath}" -text -out signed_"${base_name}".p7s -signer "${cacert}" -inkey "${cakey}"
}

createCA() {
  echo "creating certificate authority"

  mkdir -p myCA/certs
  mkdir -p myCA/private
  mkdir -p myCA/newcerts
  mkdir -p myCA/peercerts
  mkdir -p myCA/crl
  mkdir -p myCA/peer
  touch myCA/index.txt

  # create a self signed cert
  openssl req -nodes -x509 -days "${valid_days}" -newkey rsa:2048  -keyout "${cakey}" -out "${cacert}" -config "${openssl_cnf}"

  # Copy cacert file to our current directory
  cp "${cacert}" .
}

main $@
