#!/bin/sh
. /lib/functions.sh

create_config() {
	configname="$1"
	/usr/bin/logger -t SCEP -p info  "Create config : $configname"
	config_load scep
	config_get name "$configname" name
	config_get key "$configname" key
	config_get rsa "$configname" rsa
	config_get dsa "$configname" dsa
	config_get ecdsa "$configname" ecdsa
	config_get country "$configname" country
	config_get state "$configname" state
	config_get locality "$configname" locality
	config_get organization "$configname" organization
	config_get organization_unit "$configname" organization_unit
	config_get common_n "$configname" common_n
	config_get cert_type "$configname" cert_type
	config_get url "$configname" url
	config_get pw "$configname" pw
	config_get altname "$configname" altname
	config_get ip "$configname" ip
	config_get dns "$configname" dns
	config_get email "$configname" email
	config_get caid "$configname" caid
	config_get encryption "$configname" encryption
	config_get signature "$configname" signature

if [ "$name" != "" ]
then
	PREFIX=$name
fi
if [ "$country" != "" ]
then
	COUNTRY=$country
fi
if [ "$state" != "" ]
then
	STATE=$state
fi
if [ "$locality" != "" ]
then
	LOCALITY=$locality
fi
if [ "$organization" != "" ]
then
	ORGANIZATION=$organization
fi
if [ "$organization_unit" != "" ]
then
	ORGANIZATION_UNIT=$organization_unit
fi
if [ "$common_n" != "" ]
then
	COMMON_NAME=$common_n
fi
if [ "$key" != "" ]
then
	KEY_TYPE=$key
fi
if [ "$rsa" != "" ]
then
	KEYBITS_RSA=$rsa
fi
if [ "$ecdsa" != "" ]
then
	KEYBITS_ECDSA=$ecdsa
fi
if [ "$url" != "" ]
then
	URL=$url
fi
if [ "$pw" != "" ]
then
	PASSWORD=$pw
fi
if [ "$altname" != "" ]
then
	ALTNAME=$altname
fi
if [ "$ip" != "" ]
then
	CERTIP=$ip
fi
if [ "$dns" != "" ]
then
	CERTDNS=$dns
fi
if [ "$email" != "" ]
then
	CERTEMAIL=$email
fi

#Create file path
CONFIG=/etc/scep/${PREFIX}.cnf

#Crete .cnf to create .csr file
cat << _EOF_ > $CONFIG
[ req ]
prompt = no
distinguished_name = req_distinguished_name
_EOF_

if [ "$PASSWORD" ]; then
cat << _EOF_ >> $CONFIG
attributes=req_attributes
[ req_attributes ]
challengePassword=$PASSWORD
_EOF_
fi

echo "[ req_distinguished_name ]" >> $CONFIG

if [ "$COUNTRY" ]; then
	echo "C=$COUNTRY" >> $CONFIG
fi
if [ "$STATE" ]; then
	echo "ST=$STATE" >> $CONFIG
fi
if [ "$LOCALITY" ]; then
	echo "L=$LOCALITY" >> $CONFIG
fi
if [ "$ORGANIZATION" ]; then
	echo "O=$ORGANIZATION" >> $CONFIG
fi
if [ "$ORGANIZATION_UNIT" ]; then
	echo "OU=$ORGANIZATION_UNIT" >> $CONFIG
fi
if [ "$COMMON_NAME" ]; then
	echo "CN=$COMMON_NAME" >> $CONFIG
fi


#Check alternate name if available
if [ $ALTNAME != None ]; then	
	if [ $ALTNAME == certip ]; then
		NAME=CERTIP
		PARAMETER="$CERTIP"
		EXT=x509v3_IPAddr
	elif [ $ALTNAME == certdns ]; then
		NAME=CERTNAME
		PARAMETER="$CERTDNS"
		EXT=x509v3_DNS
	elif [ $ALTNAME == certemail ]; then
		NAME=CERTEMAIL
		PARAMETER="$CERTEMAIL"
		EXT=x509v3_Email
	fi

cat << _EOF_ >> $CONFIG
[x509v3_IPAddr]
subjectAltName=critical,IP:$PARAMETER
[x509v3_DNS]
subjectAltName=critical,DNS:$PARAMETER
[x509v3_Email]
subjectAltName=critical,email:$PARAMETER
_EOF_

fi
}

Enroll() {
	# Enroll Certificate
	local configname="$1"
	#Check certificate existed and valid
	if [ -f $KEY -a -f $CA_CERT_PEM -a -f $CERT_PEM ]; then
		if openssl x509 -checkend 0 -noout -in $CERT_PEM 2>&1 | tee -a "$STATUS"
		then
			echo "Certificate is already enrolled" 2>&1 | tee -a "$STATUS"
			return
		else
			echo "Certificate Expired" 2>&1 | tee -a "$STATUS"
		fi
	fi

	#Create config file to generate csr
	create_config "$configname"

	# Generate key
	if [ "$KEY_TYPE" == "RSA" ]; then
		openssl genrsa -out "$KEY" "$KEYBITS_RSA"
		chmod 600 "$KEY"

	# elif [ $KEY_TYPE == "ECDSA" ]; then
	#	openssl ecparam -name ${KEYBITS_ECDSA} -genkey -noout -out $KEY
	fi

	# Make request
	if [ "$ALTNAME" != "None" ]; then
		#Create CSR, if ext is available
		openssl req -new -key $KEY -out $CSR -config $CONFIG -reqexts $EXT
	else
		openssl req -new -key $KEY -out $CSR -config $CONFIG
	# log -t scep -p info "request for CSR is done for certificate name ${PREFIX}"
	fi

	if [ ! -f $CSR ]; then
		echo "Failed to create CSR" 2>&1 | tee -a "$STATUS"
	fi

	if [ "$URL" ]; then
		#If given URL is invalid, then taking more time to execute the script
		/sbin/sscep getca -u $URL -c $CA_CERT_PEM 2>&1 | tee -a "$STATUS"

		if [ -f  $CA_CERT_PEM ]; then
			#Enroll Certificate
			#Check if the encryption & signature configured, default to None
			if [ "$encryption" != "None" && "$signature" != "None" ]; then
				/sbin/sscep enroll -u $URL -c $CA_CERT_PEM -k $KEY -r $CSR -l $CERT_PEM -E $encryption -S $signature 2>&1 | tee -a "$STATUS"
			else
				/sbin/sscep enroll -u $URL -c $CA_CERT_PEM -k $KEY -r $CSR -l $CERT_PEM 2>&1 | tee -a "$STATUS"
			fi
			if [ ! -f $CERT_PEM ]; then
				echo "incorrect password" 2>&1 | tee -a "$STATUS"
			fi
		else
			echo "incorrect server url" 2>&1 | tee -a "$STATUS"
		fi
	fi

	if [ -f $CA_CERT_PEM -a -f $KEY -a -f $CERT_PEM ]; then
		startdate=$(openssl x509 -startdate -noout -in $CERT_PEM | awk -F '=' '{print$2}' | xargs echo -n)
		enddate=$(openssl x509 -enddate -noout -in $CERT_PEM | awk -F '=' '{print$2}' | xargs echo -n)
		subject=$(openssl x509 -noout -subject -in $CERT_PEM | awk -F 'subject=' '{print$2}' | xargs echo -n)
		echo $startdate > $START_DATE
		echo $enddate > $END_DATE
		echo $subject > $SUBJECT

		#set enroll status
		if [[ "$startdate" != "" && "$enddate" != "" ]]; then
			echo "certificate enrolled successfully" 2>&1 | tee -a "$STATUS"
			uci set scep.${configname}.enroll_status=1
			uci commit
		fi

		#convert .pem to .der
		openssl x509 -inform pem -in $CA_CERT_PEM  -outform der -out $CA_CERT_DER
		openssl x509 -inform pem -in $CERT_PEM  -outform der -out $CERT_DER

	else
		# Delete certificates if any one of the certificate gen failed
		if [ -f $CA_CERT_PEM ]; then
			rm -rf $CA_CERT_PEM $CA_CERT_DER
		fi
		if [ -f $KEY ]; then
			rm -rf $KEY
		fi
		if [ -f $CERT_PEM ]; then
			rm -rf $CERT_PEM $CERT_DER
		fi
	fi

	# Remove config file
	if [ -f $CONFIG ]; then
		rm -rf $CONFIG
	fi

	#Delete csr created for certificate
	if [ -f $CSR ]; then
		rm -rf $CSR
	fi
}

Renew() {
	# Renew certificate
	configname="$1"
	/usr/bin/logger -t SCEP -p info  "Renew : $configname"
	
	if [ -f $KEY -a -f $CA_CERT_PEM -a -f $CERT_PEM ]; then
		#Create config file to generate csr
		create_config "$configname"

		# Generate key
		if [ "$KEY_TYPE" == "RSA" ]; then
			openssl genrsa -out $NEW_KEY ${KEYBITS_RSA}
			chmod 600 $NEW_KEY
		#elif [ "$KEY_TYPE" == "ECDSA" ]; then
		#	openssl ecparam -name ${KEYBITS_ECDSA} -genkey -noout -out $NEW_KEY
		#	chmod 600 $NEW_KEY
		fi

		# Create request for CSR
		if [ "$ALTNAME" != "None" ]; then
			#Create CSR, if ext is available
			openssl req -new -key $NEW_KEY -out $NEW_CSR -config $CONFIG -reqexts $EXT
		else
			openssl req -new -key $NEW_KEY -out $NEW_CSR -config $CONFIG
		fi

		/sbin/sscep enroll -u $URL -c $CA_CERT_PEM -K $KEY -O $CERT_PEM -k NEW_KEY -r NEW_CSR -l $NEW_CERT_PEM

		if [ -f $NEW_KEY -a -f $NEW_CSR -a -f $NEW_CERT_PEM ]; then
			rm -rf $CERT_PEM $CERT_DER $KEY
			mv $NEW_CERT_PEM $CERT_PEM
			mv $NEW_KEY $KEY

			startdate=$(openssl x509 -startdate -noout -in $CERT_PEM  | awk -F '=' '{print$2}' | xargs echo -n)
			enddate=$(openssl x509 -enddate -noout -in $CERT_PEM  | awk -F '=' '{print$2}' | xargs echo -n)
			subject=$(openssl x509 -noout -subject -in $CERT_PEM | awk -F 'subject=' '{print$2}' | xargs echo -n)
			echo $startdate > $START_DATE
			echo $enddate > $END_DATE
			echo $subject > $SUBJECT

			echo "Certificate renew is success" 2>&1 | tee -a "$STATUS"
			#convert .pem to .der
			openssl x509 -inform pem -in $CA_CERT_PEM  -outform der -out $CA_CERT_DER
			openssl x509 -inform pem -in $CERT_PEM  -outform der -out $CERT_DER
		else
			rm -rf $NEW_KEY
			echo "Certificate renew is notpermit" 2>&1 | tee -a "$STATUS"
		fi

		# Remove config file
		if [ -f $CONFIG ]; then
			rm -rf $CONFIG
		fi

		#Delete csr created for certificate
		if [ -f $NEW_CSR ]; then
			rm -rf $NEW_CSR
		fi
	else
		echo "Certificate is not existed, failed" 2>&1 | tee -a "$STATUS"
		return
	fi
}

Delete() {
	configname="$1"
	/usr/bin/logger -t SCEP -p info  "Delete : $configname"
	uci delete scep."$configname"
	uci commit

	#Remove certificate
	rm -rf $KEY $CA_CERT_PEM $CA_CERT_DER $CERT_PEM $CERT_DER $START_DATE $END_DATE $SUBJECT
	rm -rf $CERT_PATH
	echo "Certificate Deleted successfully" 2>&1 | tee -a "$STATUS"
}

main() {
	/usr/bin/logger -t SCEP -p info  "Received command: $@"
	option="$1"
	configname="$2"

	config_load scep
	config_get name "$configname" name
	if [ "$name" != "" ]; then
		CERTNAME="$name"
	fi

	#SCEP base path
	BASE="/etc/scep"
	CERT_PATH="$BASE/$CERTNAME"

	mkdir -p "$BASE"
	mkdir -p "$CERT_PATH"

	#Create file path
	KEY="$CERT_PATH/$CERTNAME-key.key"
	CA_CERT_PEM="$CERT_PATH/$CERTNAME-ca.pem"
	CERT_PEM="$CERT_PATH/$CERTNAME.pem"
	CA_CERT_DER="$CERT_PATH/$CERTNAME-ca.der"
	CERT_DER="$CERT_PATH/$CERTNAME.der"
	CSR="$CERT_PATH/$CERTNAME.csr"
	NEW_CSR="$CERT_PATH/$CERTNAME-new.csr"
	NEW_KEY="$CERT_PATH/$CERTNAME-new-key.key"
	NEW_CERT_PEM="$CERT_PATH/$CERTNAME-new.pem"
	START_DATE="$CERT_PATH/startDate"
	END_DATE="$CERT_PATH/endDate"
	SUBJECT="$CERT_PATH/subject"
	STATUS="/tmp/scepstatus"

	${option} "${configname}"
}

main "$@"
