#!/bin/sh

. /etc/functions.sh

localca=0;
MAX_CNT=256

cert_del() {
        config_get lstatus $1 status
        if   [ "$lstatus" != "Requesting" ]; then
                return 0;
        fi

        config_get lsubject $1 subject

        if   [ "$lsubject" != "$subject" ]; then
                return 0;
        fi
	
		rm -rf /etc/ipsec.d/certs/$1.pem
		cp $TEMP_CERT /etc/ipsec.d/certs/$1.crt
		
		uci set certificate.$1.issuer="$issuer"  
		uci set certificate.$1.subject="$subject"  
		uci set certificate.$1.from="$from"  
		uci set certificate.$1.to="$to"  
		uci set certificate.$1.status="$status"
		uci set certificate.$1.upload_type="$2"
		localca=1;	  
}

OPENSSL_RSA="openssl rsa"
OPENSSL_X509="openssl x509"
VAR_MODULUS="/var/private_modulus"
TEMP_CERT="/var/certificate_tmp"
CERT_MODULUS="/var/cert_modulus"
CERT_OUTPUT="/var/tmp_cert_output"
TEMP_KEY="/var/certificate_tmp_key"
TEMP_CERT_PKCS12="/var/certificate_tmp_pkcs12.pem"

name=$( echo $1  |cut -d"." -f 1);

cert_status=$(uci -c /etc/config/ get certificate.$name.status);
if [ "$cert_status" != "" -a "$cert_status" != "Requesting" ]; then
	json set uploadcert status=duplicated
	return 0;
fi

if [ "$2" = "1" ]; then
	echo "Upload PKCS12" > /dev/console
	upload_pass="$3"
	openssl pkcs12 -in $TEMP_CERT -info -nodes -password pass:test_$upload_pass 1>/tmp/check_pkcs12 2>&1
	[ "$(cat /tmp/check_pkcs12 | grep "invalid password" -c)" = "0" ] && {
		echo "Please upload PKCS12 file"
		json set uploadcert status=certfileinvalid
		return 0;
	}
	openssl pkcs12 -in $TEMP_CERT -out $TEMP_CERT_PKCS12 -nodes -password pass:$upload_pass
	[ -s $TEMP_CERT_PKCS12 ] || {
		echo "Invalid Password"
		json set uploadcert status=passwordinvalid
		return 0;
	}
	rm $TEMP_CERT
	openssl rsa -in $TEMP_CERT_PKCS12 -out $TEMP_KEY
	openssl x509 -in $TEMP_CERT_PKCS12 -out $TEMP_CERT
elif [ "$2" = "2" ]; then
	echo "Upload Certificate and Private Key" > /dev/console
	upload_pass="$3"
	[ "$(cat $TEMP_CERT | grep "BEGIN CERTIFICATE" -c)" = "0" ] && {
		echo "Invalid certificate."
		json set uploadcert status=certfileinvalid
		return 0;
	}
	openssl rsa -inform PEM -outform PEM -in $TEMP_KEY -out $TEMP_KEY -passin pass:$upload_pass
	[ "$(cat $TEMP_KEY | grep "BEGIN RSA PRIVATE KEY" -c)" = "0" ] && {
		echo "Invalid private key."
		json set uploadcert status=keyfileinvalid
		return 0;
	}
	[ "$(cat $TEMP_KEY | grep "ENCRYPTED" -c)" != "0" ] && {
		echo "Invalid Password"
		json set uploadcert status=passwordinvalid
		return 0;
	}
fi

$OPENSSL_X509 -in $TEMP_CERT -noout -issuer -subject -dates > $CERT_OUTPUT

if [ ! -s $CERT_OUTPUT ]; then
	echo "Certificate file is invalid"
	json set uploadcert status=certfileinvalid
	return 0;
fi

issuer=$(cat $CERT_OUTPUT | grep issuer | cut -c 8-100);
subject=$(cat $CERT_OUTPUT | grep subject | cut -c 9-100);
from=$(cat $CERT_OUTPUT | grep notBefore| cut -c 11-100);
to=$(cat $CERT_OUTPUT | grep notAfter | cut -c 10-100);
status="OK";


num=$(uci show certificate | grep -c usercertificate)
if [ "$num" -ge "$MAX_CNT" ]; then
	echo "The max entries of Local Certificate is $MAX_CNT"
	json set uploadcert status=entryexceed
	return 0;
fi

echo "Import Success"
json set uploadcert status=importsuccess
config_load certificate
config_foreach cert_del    

if [ $localca -lt 1 ];then
		cp $TEMP_CERT /etc/ipsec.d/certs/$name.crt
		uci set certificate.$name=usercertificate
		uci set certificate.$name.issuer="$issuer"  
		uci set certificate.$name.subject="$subject"  
		uci set certificate.$name.from="$from"  
		uci set certificate.$name.to="$to"  
		uci set certificate.$name.status="$status"
		if [ -s /etc/ipsec.d/private/private_key_$name.pem ]; then
			uci set certificate.$name.upload_type="2"
		else
			uci set certificate.$name.upload_type="$2"
		fi
		if [ "$2" = "1" -o "$2" = "2" ]; then
			cp $TEMP_KEY /etc/ipsec.d/private/private_key_$name.pem
		fi
		uci commit certificate
		
		if [ "$(uci show ipsec_cer_config.$name | grep $name -c)" = "0" ]; then
			echo "config 'certificate-config' '$name'" >> /etc/config/ipsec_cer_config
			echo "        option 'organization_unit' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'organization' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'location' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'state' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'common_name' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'e_mail' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'key_size' ''" >> /etc/config/ipsec_cer_config
			if [ "$2" = "2" ]; then
				echo "        option 'passkey' '$upload_pass'" >> /etc/config/ipsec_cer_config
			else
				echo "        option 'passkey' ''" >> /etc/config/ipsec_cer_config
			fi
			echo "        option 'country' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'selfsign' ''" >> /etc/config/ipsec_cer_config
			if [ "$(openssl x509 -in $TEMP_CERT -text | grep DNS: -c)" = "1" ]; then
				echo "        option 'id_type' 'domainname'" >> /etc/config/ipsec_cer_config
				echo "        option 'id_value' '$(openssl x509 -in $TEMP_CERT -text | grep DNS: | cut -d ':' -f 2)'" >> /etc/config/ipsec_cer_config
			elif [ "$(openssl x509 -in $TEMP_CERT -text | grep "IP Address:" -c)" = "1" ]; then
				echo "        option 'id_type' 'IP'" >> /etc/config/ipsec_cer_config
				echo "        option 'id_value' '$(openssl x509 -in $TEMP_CERT -text | grep "IP Address:" | cut -d ':' -f 2)'" >> /etc/config/ipsec_cer_config
			elif [ "$(openssl x509 -in $TEMP_CERT -text | grep "email:" -c)" = "1" ]; then
				echo "        option 'id_type' 'email'" >> /etc/config/ipsec_cer_config
				echo "        option 'id_value' '$(openssl x509 -in $TEMP_CERT -text | grep "email:" | cut -d ':' -f 2)'" >> /etc/config/ipsec_cer_config
			else
				echo "        option 'id_type' 'none'" >> /etc/config/ipsec_cer_config
				echo "        option 'id_value' ''" >> /etc/config/ipsec_cer_config
			fi
			echo "        option 'pass' ''" >> /etc/config/ipsec_cer_config
			echo "        option 'new' '0'" >> /etc/config/ipsec_cer_config
			uci commit ipsec_cer_config
		fi
fi

rm -f $CERT_OUTPUT 2>/dev/null
rm -f $TEMP_CERT 2>/dev/null
rm -f $TEMP_KEY 2>/dev/null
rm -f $TEMP_CERT_PKCS12 2>/dev/null