#! /bin/sh
# set -x
#
# Generate agent passwords , private key and self-signed certificate
#

# do a clean up of unecessary files
clean() {

  # Remove temporary file containing the random seed
  rm -f ${MFWK_TMP_SEED}

  # Remove agent certificate request
  rm -f ${SECURITY_DIR}/certreq.agent

  # Remove exported CA certificate 
#  rm -f ${SECURITY_DIR}/nss/cert.ca

  # Remove exported agent certificate
#  rm -f ${SECURITY_DIR}/cert.agent

  # Removing the temporary output file if not yet done.
  rm -f ${TMP_OUT}

  # Removing the temporary seed file 
  rm -f ${MFWK_TMP_SEED}

  # Restoring initial umask in case this script is sourced.
  umask ${SAVED_UMASK}
}

# Print error and do a clean up before leaving with exit code 1
error() {
  echo "ERROR: " $1
  cat ${TMP_OUT}  | sort -u | ${GREP} -v Exception
  clean
  exit 1
}

OOSS=`uname -s`


EXEC_DIR=`dirname $0`

while getopts p:d: c
do
    case $c in
      p) PASSWORD=$OPTARG;;
      d) SECURITY_DIR=$OPTARG;;
    esac
done

. ${EXEC_DIR}/.env

# Sanity check
echo "Creating security directories (if needed)"
${MKDIR} -p $SECURITY_DIR/nss
${MKDIR} -p $SECURITY_DIR/jsse

# Remove any previous installed files

rm -f ${AGENT_PASS_FILE}
rm -f ${AGENT_KEYSTORE}
rm -f ${AGENT_TRUSTSTORE}
rm -f ${SECURITY_DIR}/nss/cert.ca
rm -f ${SECURITY_DIR}/nss/cert*.db
rm -f ${SECURITY_DIR}/nss/key*.db
rm -f ${SECURITY_DIR}/nss/secmod.db
rm -f ${SECURITY_DIR}/certreq.agent
rm -f ${SECURITY_DIR}/cert.agent
rm -f ${MFWK_TMP_SEED}

# Create security dir if it does not already exist
[ ! -d ${SECURITY_DIR} ] && mkdir -p ${SECURITY_DIR}
chmod 755 ${SECURITY_DIR}

# Generate a random password
umask 0377
rm -f ${TMP_OUT}
${JAVA} -cp ${CLASSPATH} ${GEN_PASS_CLASS} > ${AGENT_PASS_FILE} 2>${TMP_OUT}
[ $? -ne 0 ] && error "Error: cannot generate agent password"

# Read the password from password file
AGENT_PASSWORD=`cat ${AGENT_PASS_FILE}`

# Generate a random seed for certutil
umask 077
rm -f ${TMP_OUT}
${JAVA} -cp ${CLASSPATH} ${GEN_SEED_CLASS} 24 > ${MFWK_TMP_SEED} 2>${TMP_OUT}
[ $? -ne 0 ] && error "Error: cannot generate random seed"

# Restoring initial umask
umask ${SAVED_UMASK}

# Generate the agent private key and the self-signed certificate
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}" | ${KEYTOOL} -genkey \
          -alias ${AGENT_PRIV_ALIAS} \
          -keyalg $ALGO \
          -keysize $KEYSIZE \
          -sigalg $SIGALGO \
          -keystore ${AGENT_KEYSTORE} \
          -storetype ${STORETYPE} \
          -dname "$DNAME" \
          -validity $VALIDITY > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}" | ${KEYTOOL} -genkey \
          -alias ${AGENT_PRIV_ALIAS} \
	  -keyalg $ALGO \
	  -keysize $KEYSIZE \
	  -sigalg $SIGALGO \
          -keystore ${AGENT_KEYSTORE} \
	  -storetype ${STORETYPE} \
          -dname "$DNAME" \
	  -validity $VALIDITY > ${TMP_OUT} 2>&1
fi

[ $? -ne 0 ] && error "Error: cannot generate agent private key."

# Local certificate authority creation
mkdir -p ${SECURITY_DIR}/nss
chmod 755 ${SECURITY_DIR}/nss

# Create new certificate and key databases
rm -f ${TMP_OUT}
${CERTUTIL} -N \
            -d ${SECURITY_DIR}/nss \
            -f ${AGENT_PASS_FILE}  > ${TMP_OUT} 2>&1

[ $? -ne 0 ] && error "Error: cannot generate CA db files"

# create self-signed certificate for the MFWK CA
rm -f ${TMP_OUT}
${CERTUTIL} -S \
            -n mfwk_ca \
	    -k rsa \
	    -s "${CA_DNAME}" \
            -x \
	    -v ${VALIDITY_MONTH} \
	    -t "uCT,uCT,uCT" \
	    -z ${MFWK_TMP_SEED} \
	    -d ${SECURITY_DIR}/nss \
	    -f ${AGENT_PASS_FILE} > ${TMP_OUT} 2>&1
     
[ $? -ne 0 ] && error "Error: cannot generate CA self-signed certificate" 

# export MFWK CA self-signed certificate to a file
rm -f ${TMP_OUT}
${CERTUTIL} -L \
	    -n mfwk_ca \
	    -a \
	    -o ${SECURITY_DIR}/nss/cert.ca \
	    -d ${SECURITY_DIR}/nss \
	    -f ${AGENT_PASS_FILE} > ${TMP_OUT} 2>&1

[ $? -ne 0 ] && error "Error: cannot export CA self-signed certificate" 

# Sign the agent certificate with the MFWK CA certificate
# Create the certificate signing request for the agent
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -certreq \
	  -alias  $AGENT_PRIV_ALIAS \
	  -sigalg $SIGALGO \
	  -file ${SECURITY_DIR}/certreq.agent \
	  -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -certreq \
          -alias  $AGENT_PRIV_ALIAS \
          -sigalg $SIGALGO \
          -file ${SECURITY_DIR}/certreq.agent \
          -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1
fi

[ $? -ne 0 ] && error "Error: cannot generate agent certificate signing request."

# Sign the agent certificate with the CA
rm -f ${TMP_OUT}
${CERTUTIL} -C \
	    -i ${SECURITY_DIR}/certreq.agent \
	    -c mfwk_ca \
	    -v $VALIDITY_MONTH \
	    -a \
	    -o ${SECURITY_DIR}/cert.agent \
	    -d ${SECURITY_DIR}/nss \
	    -f ${AGENT_PASS_FILE} > ${TMP_OUT} 2>&1

[ $? -ne 0 ] && error "Error: cannot sign agent certificate with CA."

# Import CA certificate in agent's keystore
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -import \
	      -noprompt \
	      -alias mfwk_ca \
	      -file ${SECURITY_DIR}/nss/cert.ca \
	      -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -import \
              -noprompt \
              -alias mfwk_ca \
              -file ${SECURITY_DIR}/nss/cert.ca \
              -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1

fi

[ $? -ne 0 ] && error "Error: cannot import CA self-signed certificate into agent's keystore"

# Import CA certificate in common truststore
rm -f ${TMP_OUT}
${KEYTOOL} -import \
	-noprompt \
	-alias mfwk_ca \
	-file ${SECURITY_DIR}/nss/cert.ca \
	-storepass ${AGENT_TRUST_PASS} \
	-keystore ${AGENT_TRUSTSTORE} > ${TMP_OUT} 2>&1

[ $? -ne 0 ] && error "Error: cannot import CA self-signed certificate into agent's truststore"
 
# Import certificate reply
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -import \
	   -alias ${AGENT_PRIV_ALIAS} \
	   -file ${SECURITY_DIR}/cert.agent \
	   -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -import \
           -alias ${AGENT_PRIV_ALIAS} \
           -file ${SECURITY_DIR}/cert.agent \
           -keystore ${AGENT_KEYSTORE} > ${TMP_OUT} 2>&1

fi
[ $? -ne 0 ] && error "Error: cannot import agent certificate into agent's keystore"

# Generate the agent discovery private key and the self-signed certificate
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}" | ${KEYTOOL} -genkey \
	  -alias ${AGENT_DISC_PRIV_ALIAS} \
	  -keyalg $ALGO \
	  -keysize $KEYSIZE \
	  -sigalg $SIGALGO \
	  -keystore ${AGENT_KEYSTORE} \
	  -storetype ${STORETYPE} \
	  -dname "$DNAME" \
	  -validity $VALIDITY > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}" | ${KEYTOOL} -genkey \
          -alias ${AGENT_DISC_PRIV_ALIAS} \
          -keyalg $ALGO \
          -keysize $KEYSIZE \
          -sigalg $SIGALGO \
          -keystore ${AGENT_KEYSTORE} \
          -storetype ${STORETYPE} \
          -dname "$DNAME" \
          -validity $VALIDITY > ${TMP_OUT} 2>&1
fi
[ $? -ne 0 ] && error "Error: cannot generate agent discovery private key."

# Export the agent discovery public key 
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
  echo -e "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -export \
	  -alias ${AGENT_DISC_PRIV_ALIAS} \
	  -keystore ${AGENT_KEYSTORE} \
	  -rfc \
	  -file ${SECURITY_DIR}/jsse/disc.cert > ${TMP_OUT} 2>&1
else
  echo "${AGENT_PASSWORD}\n${AGENT_PASSWORD}"  | ${KEYTOOL} -export \
          -alias ${AGENT_DISC_PRIV_ALIAS} \
          -keystore ${AGENT_KEYSTORE} \
          -rfc \
          -file ${SECURITY_DIR}/jsse/disc.cert > ${TMP_OUT} 2>&1
fi

[ $? -ne 0 ] && error "Error: cannot export agent discovery public key."

# Save Truststore password in a file
# Fix bug 6357179
echo ${AGENT_TRUST_PASS} | awk '{printf("%s",$0);}' > ${TRUST_PASS_FILE} 

# Sanity check
if [ ! -f ${TRUST_PASS_FILE} ]
then
  echo "Error: Failed to create Truststore password file $TRUST_PASS_FILE.."
  clean
  exit 1
fi

# Import the agent discovery public key in the JKS truststore
# Fix bug 6357179
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
echo -e "${AGENT_TRUST_PASS}\n${AGENT_TRUST_PASS}" | ${KEYTOOL} -import \
	-alias ${AGENT_DISC_PRIV_ALIAS} \
	-keystore ${AGENT_TRUSTSTORE} \
	-file ${SECURITY_DIR}/jsse/disc.cert \
	-noprompt > ${TMP_OUT} 2>&1
else
echo "${AGENT_TRUST_PASS}\n${AGENT_TRUST_PASS}" | ${KEYTOOL} -import \
        -alias ${AGENT_DISC_PRIV_ALIAS} \
        -keystore ${AGENT_TRUSTSTORE} \
        -file ${SECURITY_DIR}/jsse/disc.cert \
        -noprompt > ${TMP_OUT} 2>&1
fi

[ $? -ne 0 ] && error "Error: cannot import agent discovery public key in JKS truststore."

# Import the agent discovery public key in the NSS truststore
# Fix bug 6357179
rm -f ${TMP_OUT}
if [ ${OOSS} = "Linux" ]
then
echo -e "${AGENT_TRUST_PASS}\n${AGENT_TRUST_PASS}" | ${CERTUTIL} -A \
        -n ${AGENT_DISC_PRIV_ALIAS} \
        -t "CT,CT,CT" \
        -d ${SECURITY_DIR}/nss \
        -a \
        -i ${SECURITY_DIR}/jsse/disc.cert \
        -f ${TRUST_PASS_FILE} > ${TMP_OUT} 2>&1
else
echo "${AGENT_TRUST_PASS}\n${AGENT_TRUST_PASS}" | ${CERTUTIL} -A \
        -n ${AGENT_DISC_PRIV_ALIAS} \
        -t "CT,CT,CT" \
        -d ${SECURITY_DIR}/nss \
        -a \
        -i ${SECURITY_DIR}/jsse/disc.cert \
        -f ${TRUST_PASS_FILE} > ${TMP_OUT} 2>&1
fi


[ $? -ne 0 ] && error "Error: cannot import agent discovery public key in NSS truststore."

# Let do a cleanup
clean

# Even if the mask is correct, every file created by certutil has a
# restricted set of permissions. So enforce the permissions really required
# do ti in one shot: chmod will not stop if one file is missing
${CHMOD} ${SECURITY_DIRECTORY_UMASK} $SECURITY_DIR $SECURITY_DIR/nss $SECURITY_DIR/jsse

${CHMOD} ${SECURITY_AGT_UMASK} ${AGENT_PASS_FILE} ${AGENT_KEYSTORE}
${CHMOD} ${PASSWD_FILE_UMASK} ${TRUST_PASS_FILE}
${CHMOD} ${SECURITY_CPS_UMASK} ${AGENT_TRUSTSTORE} $SECURITY_DIR/nss/* 
