|
@@ -0,0 +1,787 @@
|
|
|
|
|
+#!/bin/bash
|
|
|
|
|
+
|
|
|
|
|
+#------ Settings ------
|
|
|
|
|
+
|
|
|
|
|
+OPENSSL="openssl"
|
|
|
|
|
+CONFIG="./openssl.cnf"
|
|
|
|
|
+
|
|
|
|
|
+ROOTCADAYS="-days 3650" # 10 years
|
|
|
|
|
+CADAYS="-days 1825" # 5 years
|
|
|
|
|
+#CADAYS="-days 825" # 2 years
|
|
|
|
|
+DAYS="-days 397" # 1 year
|
|
|
|
|
+
|
|
|
|
|
+CONFIGOPTION="-config ${CONFIG}"
|
|
|
|
|
+REQ="${OPENSSL} req ${CONFIGOPTION}"
|
|
|
|
|
+CA="${OPENSSL} ca ${CONFIGOPTION}"
|
|
|
|
|
+VERIFY="${OPENSSL} verify"
|
|
|
|
|
+X509="${OPENSSL} x509"
|
|
|
|
|
+PKCS12="${OPENSSL} pkcs12"
|
|
|
|
|
+
|
|
|
|
|
+CAFOLDER="./CA"
|
|
|
|
|
+CAKEY="./cakey.pem"
|
|
|
|
|
+CAREQ="./careq.pem"
|
|
|
|
|
+CACERT="./cacert.pem"
|
|
|
|
|
+PASSEXTENSION="keyfile"
|
|
|
|
|
+PASSFILE="./${PASSEXTENSION}"
|
|
|
|
|
+TYPEFILE="./type"
|
|
|
|
|
+CHAINFILE="./cachain.pem"
|
|
|
|
|
+
|
|
|
|
|
+C="NL"
|
|
|
|
|
+ST="Noord-Brabant"
|
|
|
|
|
+L="Veldhoven"
|
|
|
|
|
+O="Dierkse DataManagement"
|
|
|
|
|
+OU="Secure Digital Certificate Signing"
|
|
|
|
|
+#CN="CommonName"
|
|
|
|
|
+E="certification@dierkse.nl"
|
|
|
|
|
+
|
|
|
|
|
+#------ Functions ------
|
|
|
|
|
+
|
|
|
|
|
+execute() {
|
|
|
|
|
+ COMMAND=$@
|
|
|
|
|
+
|
|
|
|
|
+ eval ${COMMAND}
|
|
|
|
|
+ RETURNVALUE=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${RETURNVALUE}" -ne "0" ]; then
|
|
|
|
|
+ exit ${RETURNVALUE}
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+writeRandomString() {
|
|
|
|
|
+ SIZE=$1
|
|
|
|
|
+ FILE=$2
|
|
|
|
|
+
|
|
|
|
|
+ tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' < /dev/urandom | head -c ${SIZE} > "${FILE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+validateType() {
|
|
|
|
|
+ TYPE=$1
|
|
|
|
|
+ VALIDTYPE=""
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "ROOTCA" ||
|
|
|
|
|
+ "${TYPE}" == "INTERMEDIATECA" ||
|
|
|
|
|
+ "${TYPE}" == "VPNCA" ||
|
|
|
|
|
+ "${TYPE}" == "WEBSERVER" ||
|
|
|
|
|
+ "${TYPE}" == "WEBCLIENT" ||
|
|
|
|
|
+ "${TYPE}" == "APPLICATIONCLIENT" ||
|
|
|
|
|
+ "${TYPE}" == "EMAIL" ||
|
|
|
|
|
+ "${TYPE}" == "VPN" ]]; then
|
|
|
|
|
+ VALIDTYPE=${TYPE}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+copyPem() {
|
|
|
|
|
+ INFILE=$1
|
|
|
|
|
+ OUTFILE=$2
|
|
|
|
|
+ BOUND=$3
|
|
|
|
|
+ FLAG=0
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${INFILE}" ]; then
|
|
|
|
|
+ echo "Missing File ${INFILE}"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$BOUND" ]]; then
|
|
|
|
|
+ echo "Missing Boundary"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ exec < "${INFILE}";
|
|
|
|
|
+ while read LINE; do
|
|
|
|
|
+ if [ ${FLAG} -eq 1 ]; then
|
|
|
|
|
+ echo ${LINE}|grep "^-----END.*${BOUND}" 2>/dev/null 1>/dev/null
|
|
|
|
|
+ if [ $? -eq 0 ] ; then
|
|
|
|
|
+ echo ${LINE} >> "${OUTFILE}"
|
|
|
|
|
+ break
|
|
|
|
|
+ else
|
|
|
|
|
+ echo ${LINE} >> "${OUTFILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ echo ${LINE} | grep "^-----BEGIN.*${BOUND}" 2>/dev/null 1>/dev/null
|
|
|
|
|
+ if [ $? -eq 0 ]; then
|
|
|
|
|
+ echo ${LINE} > "${OUTFILE}"
|
|
|
|
|
+ FLAG=1
|
|
|
|
|
+ fi
|
|
|
|
|
+ done
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+newCertificate() {
|
|
|
|
|
+ KEYBITS=2048
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBSERVER" ]]; then
|
|
|
|
|
+ EXTENSIONS="server_cert -nodes"
|
|
|
|
|
+
|
|
|
|
|
+ SAN=()
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SAN+=("${CN}")
|
|
|
|
|
+ SAN+=("*.${CN}")
|
|
|
|
|
+ fi
|
|
|
|
|
+ SAN+=("${EXTRASAN[@]}")
|
|
|
|
|
+
|
|
|
|
|
+ IP=("${EXTRAIP[@]}")
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="client_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="application_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "EMAIL" ]]; then
|
|
|
|
|
+ EXTENSIONS="email_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "VPN" ]]; then
|
|
|
|
|
+ EXTENSIONS="vpn_cert -nodes"
|
|
|
|
|
+
|
|
|
|
|
+ SAN=()
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SAN+=("${CN}")
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
|
|
|
|
|
+ KEYBITS=4096
|
|
|
|
|
+ DAYS=${CADAYS}
|
|
|
|
|
+ EXTENSIONS="intermediate_extensions"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${REQ} -new -x509 -newkey rsa:${KEYBITS} -extensions server_cert -keyout \"${FILENAME}.key\" -out \"${FILENAME}.crt\" ${DAYS}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
|
|
|
|
|
+ COMMAND+=" -subj \"${SUBJECT}\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then
|
|
|
|
|
+ COMMAND+=" -addext \"subjectAltName="
|
|
|
|
|
+ INDEX=0
|
|
|
|
|
+ for S in "${SAN[@]}"
|
|
|
|
|
+ do
|
|
|
|
|
+ ((INDEX+=1))
|
|
|
|
|
+ COMMAND+="DNS.${INDEX}: ${S},"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ INDEX=0
|
|
|
|
|
+ for I in "${IP[@]}"
|
|
|
|
|
+ do
|
|
|
|
|
+ ((INDEX+=1))
|
|
|
|
|
+ COMMAND+="IP.${INDEX}: ${I},"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND=${COMMAND%?}
|
|
|
|
|
+ COMMAND+="\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+newRequest() {
|
|
|
|
|
+ KEYBITS=2048
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBSERVER" ]]; then
|
|
|
|
|
+ EXTENSIONS="server_cert -nodes"
|
|
|
|
|
+
|
|
|
|
|
+ SAN=()
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SAN+=("${CN}")
|
|
|
|
|
+ SAN+=("*.${CN}")
|
|
|
|
|
+ fi
|
|
|
|
|
+ SAN+=("${EXTRASAN[@]}")
|
|
|
|
|
+
|
|
|
|
|
+ IP=("${EXTRAIP[@]}")
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="client_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="application_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "EMAIL" ]]; then
|
|
|
|
|
+ EXTENSIONS="email_cert -nodes"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "VPN" ]]; then
|
|
|
|
|
+ EXTENSIONS="vpn_cert -nodes"
|
|
|
|
|
+
|
|
|
|
|
+ SAN=()
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SAN+=("${CN}")
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
|
|
|
|
|
+ KEYBITS=4096
|
|
|
|
|
+ writeRandomString 128 "${FILENAME}.${PASSEXTENSION}"
|
|
|
|
|
+ chmod 000 "${FILENAME}.${PASSEXTENSION}"
|
|
|
|
|
+ EXTENSIONS="intermediate_extensions -passout file:\"${FILENAME}.${PASSEXTENSION}\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${REQ} -new -newkey rsa:${KEYBITS} -extensions ${EXTENSIONS} -keyout \"${FILENAME}.key\" -out \"${FILENAME}.csr\""
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
|
|
|
|
|
+ COMMAND+=" -subj \"${SUBJECT}\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then
|
|
|
|
|
+ COMMAND+=" -addext \"subjectAltName="
|
|
|
|
|
+ INDEX=0
|
|
|
|
|
+ for S in "${SAN[@]}"
|
|
|
|
|
+ do
|
|
|
|
|
+ ((INDEX+=1))
|
|
|
|
|
+ COMMAND+="DNS.${INDEX}: ${S},"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ INDEX=0
|
|
|
|
|
+ for I in "${IP[@]}"
|
|
|
|
|
+ do
|
|
|
|
|
+ ((INDEX+=1))
|
|
|
|
|
+ COMMAND+="IP.${INDEX}: ${I},"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND=${COMMAND%?}
|
|
|
|
|
+ COMMAND+="\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+newCertificateAuthority() {
|
|
|
|
|
+ if [[ "${TYPE}" == "ROOTCA" ]]; then
|
|
|
|
|
+ KEYBITS=8192
|
|
|
|
|
+ EXTENSIONS="CA_root"
|
|
|
|
|
+ DAYS=${ROOTCADAYS}
|
|
|
|
|
+ SUBTYPE="INTERMEDIATECA"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
|
|
|
|
|
+ KEYBITS=4096
|
|
|
|
|
+ EXTENSIONS="CA_intermediate"
|
|
|
|
|
+ DAYS=${CADAYS}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "VPNCA" ]]; then
|
|
|
|
|
+ KEYBITS=4096
|
|
|
|
|
+ EXTENSIONS="CA_root"
|
|
|
|
|
+ DAYS=${ROOTCADAYS}
|
|
|
|
|
+ SUBTYPE="VPN"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "${KEYBITS}" ]; then
|
|
|
|
|
+ echo "Error: invalid certificate authority type" >&2
|
|
|
|
|
+
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f ${CAFOLDER}/serial ]; then
|
|
|
|
|
+ mkdir -p ${CAFOLDER}
|
|
|
|
|
+ mkdir -p ${CAFOLDER}/certs
|
|
|
|
|
+ mkdir -p ${CAFOLDER}/crl
|
|
|
|
|
+ mkdir -p ${CAFOLDER}/newcerts
|
|
|
|
|
+ mkdir -p ${CAFOLDER}/private
|
|
|
|
|
+ touch ${CAFOLDER}/index.txt
|
|
|
|
|
+ echo 1000 > ${CAFOLDER}/crl/crlnumber
|
|
|
|
|
+ openssl rand -writerand ${CAFOLDER}/private/.rand
|
|
|
|
|
+ writeRandomString 128 ${CAFOLDER}/private/${PASSFILE}
|
|
|
|
|
+ chmod 000 ${CAFOLDER}/private/${PASSFILE}
|
|
|
|
|
+ if [ ! -z "${SUBTYPE}" ]; then
|
|
|
|
|
+ echo "${SUBTYPE}" > ${CAFOLDER}/${TYPEFILE}
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f ${CAFOLDER}/private/${CAKEY} ]; then
|
|
|
|
|
+ if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
|
|
|
|
|
+ echo "CA certificate filename (or enter to create)"
|
|
|
|
|
+ read NAME
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${NAME}" ]; then
|
|
|
|
|
+ if [ -f "./${NAME}" ]; then
|
|
|
|
|
+ NAME="./${NAME%.*}"
|
|
|
|
|
+ else
|
|
|
|
|
+ if [ -f "../${NAME}" ]; then
|
|
|
|
|
+ NAME="../${NAME%.*}"
|
|
|
|
|
+ else
|
|
|
|
|
+ if [ -f "./${NAME}.crt" ]; then
|
|
|
|
|
+ NAME="./${NAME}"
|
|
|
|
|
+ else
|
|
|
|
|
+ if [ -f "../${NAME}.crt" ]; then
|
|
|
|
|
+ NAME="../${NAME}"
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "Certificate not found"
|
|
|
|
|
+ echo " ("./${NAME}")"
|
|
|
|
|
+ echo " ("../${NAME}")"
|
|
|
|
|
+ echo " ("./${NAME}.crt")"
|
|
|
|
|
+ echo " ("../${NAME}.crt")"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f "${NAME}.csr" ]; then
|
|
|
|
|
+ copyPem "${NAME}.csr" ${CAFOLDER}/${CAREQ} CERTIFICATE
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "CA Request missing (${NAME}.csr)"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f "${NAME}.key" ]; then
|
|
|
|
|
+ copyPem "${NAME}.key" ${CAFOLDER}/private/${CAKEY} PRIVATE
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "CA Private Key missing (${NAME}.key)"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f "${NAME}.${PASSEXTENSION}" ]; then
|
|
|
|
|
+ cp "${NAME}.${PASSEXTENSION}" ${CAFOLDER}/private/${PASSFILE}
|
|
|
|
|
+ chmod 000 ${CAFOLDER}/private/${PASSFILE}
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "CA Private Key Keyfile missing (${NAME}.${PASSEXTENSION})"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f "${NAME}.crt" ]; then
|
|
|
|
|
+ copyPem "${NAME}.crt" ${CAFOLDER}/${CACERT} CERTIFICATE
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "CA Certificate missing (${NAME}.crt)"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f "${NAME}.pem" ]; then
|
|
|
|
|
+ COMMAND="cp \"${NAME}.pem\" ${CAFOLDER}/${CHAINFILE}"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "CA Chain missing (${NAME}.pem)"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${CAFOLDER}/serial" ]; then
|
|
|
|
|
+ COMMAND="$X509 -in ${CAFOLDER}/${CACERT} -noout -next_serial -out ${CAFOLDER}/serial"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+ fi
|
|
|
|
|
+ else
|
|
|
|
|
+ COMMAND="$REQ -new -newkey rsa:${KEYBITS} -passout file:${CAFOLDER}/private/${PASSFILE} -keyout ${CAFOLDER}/private/${CAKEY} -out ${CAFOLDER}/${CAREQ}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -z "${CN}" ]; then
|
|
|
|
|
+ SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
|
|
|
|
|
+ COMMAND+=" -subj \"${SUBJECT}\""
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="$CA -create_serial -out ${CAFOLDER}/${CACERT} ${DAYS} -batch -keyfile ${CAFOLDER}/private/${CAKEY} -passin file:${CAFOLDER}/private/${PASSFILE} -selfsign -name ${EXTENSIONS} -infiles ${CAFOLDER}/${CAREQ}"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ copyPem ${CAFOLDER}/${CACERT} ${CAFOLDER}/${CACERT}.tmp CERTIFICATE
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="mv ${CAFOLDER}/${CACERT}.tmp ${CAFOLDER}/${CACERT}"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="cp ${CAFOLDER}/${CACERT} ${CAFOLDER}/${CHAINFILE}"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ generateCrl
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+renewCertificate() {
|
|
|
|
|
+ revokeCertificate
|
|
|
|
|
+ signRequest
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+renewCertificateAuthorityCertificate() {
|
|
|
|
|
+ # TODO
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ echo "Not implemented"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+signCertificate() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.csr" ]; then
|
|
|
|
|
+ echo "Missing Certificate Request"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${X509} -x509toreq -signkey \"${FILENAME}.key\" -in \"${FILENAME}.csr\" -out temporary.pem"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${CA} -policy policy_anything -passin file:${CAFOLDER}/private/${PASSFILE} ${DAYS} -out \"${FILENAME}.crt\" -infiles temporary.pem"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ copyPem "${FILENAME}.crt" "${FILENAME}.crt.tmp" CERTIFICATE
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="mv \"${FILENAME}.crt.tmp\" \"${FILENAME}.crt\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="cat \"${FILENAME}.crt\" ${CAFOLDER}/${CHAINFILE} > \"${FILENAME}.pem\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+signRequest() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.csr" ]; then
|
|
|
|
|
+ echo "Missing Certificate Request"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBSERVER" ]]; then
|
|
|
|
|
+ EXTENSIONS="server_cert"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "WEBCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="client_cert"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
|
|
|
|
|
+ EXTENSIONS="application_cert"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "EMAIL" ]]; then
|
|
|
|
|
+ EXTENSIONS="email_cert"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "VPN" ]]; then
|
|
|
|
|
+ EXTENSIONS="vpn_cert"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
|
|
|
|
|
+ DAYS=${CADAYS}
|
|
|
|
|
+ EXTENSIONS="intermediate_extensions"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${CA} -policy policy_match -passin file:${CAFOLDER}/private/${PASSFILE} -name CA_intermediate -extensions ${EXTENSIONS} ${DAYS} -out \"${FILENAME}.crt\" -infiles \"${FILENAME}.csr\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ copyPem "${FILENAME}.crt" "${FILENAME}.crt.tmp" CERTIFICATE
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="mv \"${FILENAME}.crt.tmp\" \"${FILENAME}.crt\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="cat \"${FILENAME}.crt\" ${CAFOLDER}/${CHAINFILE} > \"${FILENAME}.pem\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+signCertificateAuthorityCertificate() {
|
|
|
|
|
+ # TODO
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
|
|
|
|
|
+ # RET=$?
|
|
|
|
|
+
|
|
|
|
|
+ echo "Not implemented"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+signRequestAnything() {
|
|
|
|
|
+ # TODO
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # $CA -policy policy_anything -infiles newreq.pem
|
|
|
|
|
+ # RET=$?
|
|
|
|
|
+
|
|
|
|
|
+ echo "Not implemented"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+createCertificatePackage() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.crt" ]; then
|
|
|
|
|
+ echo "Missing Certificate"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.key" ]; then
|
|
|
|
|
+ echo "Missing Private Key"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ CACERTCN=$(${X509} -noout -subject -nameopt multiline -in ${CAFOLDER}/${CACERT} | sed -n 's/ *commonName *= //p')
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${PKCS12} -in \"${FILENAME}.crt\" -inkey \"${FILENAME}.key\" -certfile ${CAFOLDER}/${CHAINFILE} -caname \"${CACERTCN}\" -out \"${FILENAME}.p12\" -export -name \"${FILENAME}\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+generateCrl() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -gencrl -out ${CAFOLDER}/crl/crl.pem"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="cat ${CAFOLDER}/${CHAINFILE} ${CAFOLDER}/crl/crl.pem > ${CAFOLDER}/crl/crl_chain.pem"
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+revokeCertificate() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.crt" ]; then
|
|
|
|
|
+ echo "Missing Certificate"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -revoke \"${FILENAME}.crt\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="mv \"${FILENAME}.crt\" \"${FILENAME}.crt.revoked\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ generateCrl
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+verifyCertificate() {
|
|
|
|
|
+ if [ ! -d ${CAFOLDER} ]; then
|
|
|
|
|
+ echo "Missing CA Folder"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "${FILENAME}.crt" ]; then
|
|
|
|
|
+ echo "Missing Certificate"
|
|
|
|
|
+ exit -1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${VERIFY} -CAfile ${CAFOLDER}/${CHAINFILE} \"${FILENAME}.crt\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+
|
|
|
|
|
+ COMMAND="${VERIFY} -crl_check -CAfile ${CAFOLDER}/crl/crl_chain.pem \"${FILENAME}.crt\""
|
|
|
|
|
+ execute ${COMMAND}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+printHelp() {
|
|
|
|
|
+ echo "" >&2
|
|
|
|
|
+ echo "usage: $0 <OPERATION> -t <TYPE> [--san <SAN>] [--ip <IP>] [COMMON NAME]" >&2
|
|
|
|
|
+ echo "" >&2
|
|
|
|
|
+ echo " Certificate Types:" >&2
|
|
|
|
|
+ echo " ROOTCA " >&2
|
|
|
|
|
+ echo " INTERMEDIATECA " >&2
|
|
|
|
|
+ echo " VPNCA " >&2
|
|
|
|
|
+ echo " WEBSERVER " >&2
|
|
|
|
|
+ echo " WEBCLIENT " >&2
|
|
|
|
|
+ echo " APPLICATIONCLIENT " >&2
|
|
|
|
|
+ echo " EMAIL " >&2
|
|
|
|
|
+ echo " VPN " >&2
|
|
|
|
|
+ echo "" >&2
|
|
|
|
|
+ echo " Operations:" >&2
|
|
|
|
|
+ echo " -c|--newcert Create a new certificate and private key" >&2
|
|
|
|
|
+ echo " -n|--newreq Create a new certificate request and private key" >&2
|
|
|
|
|
+ echo " --newca Create a new certificate authority" >&2
|
|
|
|
|
+ echo " -r|--renewcert Renew an existing certificate (requires a certificate request)" >&2
|
|
|
|
|
+ #echo " --renewca Renew the certificate authority certificate" >&2
|
|
|
|
|
+ echo " --signcert Sign a certificate with the certificate authority" >&2
|
|
|
|
|
+ echo " -s|--signreq Create and sign a new certificate with the certificate autority" >&2
|
|
|
|
|
+ #echo " --signca Sign the certificate authority certificate" >&2
|
|
|
|
|
+ #echo " --xsign Sign the certificate request with the certificate authority using the 'policy_anything' option" >&2
|
|
|
|
|
+ echo " -p|--pkcs12 Create pkcs12 package containing the certificate and its private key" >&2
|
|
|
|
|
+ echo " --revoke Revoke a certificate" >&2
|
|
|
|
|
+ echo " --crl Generate CRL file" >&2
|
|
|
|
|
+ echo " -v|--verify Verify a certificate" >&2
|
|
|
|
|
+ echo " -h|--help Display this help message" >&2
|
|
|
|
|
+ echo "" >&2
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#------ Commandline parsing ------
|
|
|
|
|
+
|
|
|
|
|
+shopt -s nocasematch
|
|
|
|
|
+
|
|
|
|
|
+EXTRASAN=()
|
|
|
|
|
+EXTRAIP=()
|
|
|
|
|
+
|
|
|
|
|
+POSITIONAL=()
|
|
|
|
|
+while [[ $# -gt 0 ]]; do
|
|
|
|
|
+ key="$1"
|
|
|
|
|
+
|
|
|
|
|
+ case $key in
|
|
|
|
|
+ -t|--type)
|
|
|
|
|
+ validateType ${2}
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ shift # past value
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -c|--newcert)
|
|
|
|
|
+ OPERATION="newCertificate"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -n|--newreq)
|
|
|
|
|
+ OPERATION="newRequest"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --newca)
|
|
|
|
|
+ OPERATION="newCertificateAuthority"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -r|--renewcert)
|
|
|
|
|
+ OPERATION="renewCertificate"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ #--renewca)
|
|
|
|
|
+ # OPERATION="renewCertificateAuthorityCertificate"
|
|
|
|
|
+ #
|
|
|
|
|
+ # shift # past argument
|
|
|
|
|
+ # ;;
|
|
|
|
|
+ --signcert)
|
|
|
|
|
+ OPERATION="signCertificate"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -s|--signreq)
|
|
|
|
|
+ OPERATION="signRequest"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ #--signca)
|
|
|
|
|
+ # OPERATION="signCertificateAuthorityCertificate"
|
|
|
|
|
+ #
|
|
|
|
|
+ # shift # past argument
|
|
|
|
|
+ # ;;
|
|
|
|
|
+ #--xsign)
|
|
|
|
|
+ # OPERATION="signRequestAnything"
|
|
|
|
|
+ #
|
|
|
|
|
+ # shift # past argument
|
|
|
|
|
+ # ;;
|
|
|
|
|
+ -p|--pkcs12)
|
|
|
|
|
+ OPERATION="createCertificatePackage"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --revoke)
|
|
|
|
|
+ OPERATION="revokeCertificate"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --crl)
|
|
|
|
|
+ OPERATION="generateCrl"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -v|--verify)
|
|
|
|
|
+ OPERATION="verifyCertificate"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --san)
|
|
|
|
|
+ EXTRASAN+=("$2")
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ shift # past value
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --ip)
|
|
|
|
|
+ EXTRAIP+=("$2")
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ shift # past value
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -h|--help)
|
|
|
|
|
+ OPERATION="printHelp"
|
|
|
|
|
+
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+
|
|
|
|
|
+ *)
|
|
|
|
|
+ POSITIONAL+=("$1")
|
|
|
|
|
+ shift # past argument
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+done
|
|
|
|
|
+
|
|
|
|
|
+FILENAME="newCertificate"
|
|
|
|
|
+if (( ${#POSITIONAL[@]} )); then
|
|
|
|
|
+ CN=${POSITIONAL[0]}
|
|
|
|
|
+ FILENAME=${CN}
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+if [[ -z "${TYPE}" &&
|
|
|
|
|
+ -f "${CAFOLDER}/${TYPEFILE}" ]]; then
|
|
|
|
|
+ TYPE=$(<${CAFOLDER}/${TYPEFILE})
|
|
|
|
|
+
|
|
|
|
|
+ validateType ${TYPE}
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+if [[ -z "${TYPE}" &&
|
|
|
|
|
+ "${OPERATION}" != "revokeCertificate" &&
|
|
|
|
|
+ "${OPERATION}" != "generateCrl" &&
|
|
|
|
|
+ "${OPERATION}" != "verifyCertificate" &&
|
|
|
|
|
+ "${OPERATION}" != "createCertificatePackage" &&
|
|
|
|
|
+ "${OPERATION}" != "printHelp" ]]; then
|
|
|
|
|
+ echo "Error: missing certificate type" >&2
|
|
|
|
|
+
|
|
|
|
|
+ printHelp
|
|
|
|
|
+ exit -1
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+if [[ ! -z "${TYPE}" &&
|
|
|
|
|
+ -z "${VALIDTYPE}" &&
|
|
|
|
|
+ "${OPERATION}" != "revokeCertificate" &&
|
|
|
|
|
+ "${OPERATION}" != "generateCrl" &&
|
|
|
|
|
+ "${OPERATION}" != "verifyCertificate" &&
|
|
|
|
|
+ "${OPERATION}" != "createCertificatePackage" &&
|
|
|
|
|
+ "${OPERATION}" != "printHelp" ]]; then
|
|
|
|
|
+ echo "Error: invalid certificate type" >&2
|
|
|
|
|
+
|
|
|
|
|
+ printHelp
|
|
|
|
|
+ exit -1
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+if [ -z "${OPERATION}" ]; then
|
|
|
|
|
+ echo "Error: missing operation" >&2
|
|
|
|
|
+
|
|
|
|
|
+ printHelp
|
|
|
|
|
+ exit -1
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+TYPE=${VALIDTYPE}
|
|
|
|
|
+eval ${OPERATION}
|
|
|
|
|
+
|
|
|
|
|
+exit 0
|
|
|
|
|
+
|