#!/bin/sh

# Date: 2010-04-01
# Author: Damien Couderc
# Label: CTL installation tool

############
# CHANGELOG
#===========
# 2010/11/26    crms00276670    Claire Dechriste
#               error during CTL signature verification on some CTL files
#
# 2011/01/07    crms00282829    Claire Dechriste
#               redirect error output
#
# 2011/01/10    crms00285849    Claire Dechriste
#               CTL signature check robustness
#

#set -x

# set constants
XMLPARSER='xmlparse'
PATH_TMP='/var/tmp'
PROGNAME=`basename $0`


# usage display
usage() {
	printf "Usage:\n"  >/dev/console
	printf "\t%s -m <MAC address>\n" $PROGNAME  >/dev/console
	printf "\t%s -x <XML file>\n" $PROGNAME  >/dev/console
	printf "\t%s -h\n" $PROGNAME  >/dev/console
	printf "\n"  >/dev/console
	exit 0
}


# process command line arguments
while getopts "hm:x:" arg; do
	case $arg in
		h)
			usage
			;;

		m)
			# get signer's MAC address and remove colons
			mac=`echo $OPTARG | sed 's/://g'`
			;;

		x)
			# get XML file name
			xmlfile="$OPTARG"
			if [ ! -f $xmlfile ]; then
				printf "XML file '%s' not found.\n" $xmlfile  >/dev/console
				exit 1
			fi
			;;
	esac
done
shift `expr $OPTIND - 1`


#
# check for mandatory arguments
#

# XML file
if [ -z "$xmlfile" ]; then
	printf "XML file option is mandatory.\n"  >/dev/console
	exit 1
fi

# MAC address
if [ -z "$mac" ]; then
	printf "MAC address option is mandatory.\n"  >/dev/console
	exit 1
fi


# set dynamic variables
TS_ALU_PATH=`getICTinfo PATH TS_ALU`
TS_CTL_PATH=`getICTinfo PATH TS_CTL`

FILENAME_XML="$xmlfile"
FILENAME_CERT="$PATH_TMP/cert.pem"
FILENAME_CERT_CA="$PATH_TMP/cert_ca.pem"
FILENAME_CA="$PATH_TMP/ca.pem"
FILENAME_CTL="$PATH_TMP/ctl.pem"
#CRMS00285849
FILENAME_CTL_TMP="$PATH_TMP/ctl_tmp.pem"
FILENAME_SIGNB64="$PATH_TMP/signature.b64"
FILENAME_SIGN="$PATH_TMP/signature"
FILENAME_KEY="$PATH_TMP/key.pem"
FILENAME_INSTALL=`getICTinfo -d PKI CTL`


# set secure mask for temporary files : u=rw,g=,o=
umask 077

# CRMS00276670 +
# Parsing of the xml file
eval "$($XMLPARSER $FILENAME_XML cert CA_ICT signature)"
printf "$cert"       > $FILENAME_CERT
printf "$CA_ICT"     > $FILENAME_CERT_CA
printf "$signature"  > $FILENAME_SIGNB64
# CRMS00276670 -

#CRMS00285849 +
sed -n '/<CTL>/,/<signature encodage="base64">/ p' $FILENAME_XML > $FILENAME_CTL_TMP
lines=`wc -l $FILENAME_CTL_TMP | awk '{print $1}' `
#remove first and last lines
sed -e ''$lines' d' -e '1 d' <$FILENAME_CTL_TMP >$FILENAME_CTL
#CRMS00285849 -

# get CN from certificate's subject
cn=`openssl x509 -subject -noout -in $FILENAME_CERT | sed 's|.*CN=\([^/]*\).*|\1|'`

cn=`echo $cn | tr "a-z" "A-Z"`
mac=`echo $mac | tr "a-z" "A-Z"`

# check if mac adress is matching CN
if [ ! "$cn" = "$mac" ]; then
	printf "CN verification failed.\n" >/dev/console
        displaypopup -t 4 -l error installCTL KO: check CN/@mac
	exit 1
else
	printf "CN verified.\n" >/dev/console
fi

# concatenate phone's ALU CA with xml's CA
cat $TS_ALU_PATH/*.pem $FILENAME_CERT_CA > $FILENAME_CA

# verify certificate
#crms00282829 redirect error output
verify=`openssl verify -CAfile $FILENAME_CA $FILENAME_CERT 2>/dev/null`
if [ ! "$verify" = "$FILENAME_CERT: OK" ]; then
	printf "Certificate verification failed.\n" >/dev/console
        displaypopup -t 4 -l error installCTL KO: bad certificate
	exit 1
else
	printf "Certificate verified.\n" >/dev/console
fi

# extract public key
openssl x509 -inform pem -in $FILENAME_CERT -pubkey -noout > $FILENAME_KEY
if [ $? -ne 0 ]; then
	printf "Public key extraction failed.\n" >/dev/console
        displaypopup -t 4 -l error installCTL KO: bad publick key
	exit 1
fi

# decode base64 signature
openssl enc -d -base64 -in $FILENAME_SIGNB64 -out $FILENAME_SIGN # XXX check ?

# verify signature
#milai support sha256 +
#Try sha256 first
digest=`openssl dgst -sha256 -verify $FILENAME_KEY -signature $FILENAME_SIGN $FILENAME_CTL` 

if [ ! "$digest" = "Verified OK" ]; then
	#if sha256 failed ,try sha1 
	digest=`openssl dgst -sha1 -verify $FILENAME_KEY -signature $FILENAME_SIGN $FILENAME_CTL`  #compatible with sha1 signed CTL
	if [ ! "$digest" = "Verified OK" ]; then
#CRMS00285849 +
		printf "Digest verification failed.\n" >/dev/console
		displaypopup -t 4 -l error installCTL KO: sig check failed
		exit 1
	fi
#CRMS00285849 -
fi
#milai support sha256 -

printf "Digest verified.\n" >/dev/console

# install into trust store
if [ ! -d $TS_CTL_PATH ]; then
	# build path if it does not exists
	mkdir -p $TS_CTL_PATH
	if [ $? -ne 0 ]; then
		printf "Directory creation failed.\n" >/dev/console
                displaypopup -t 4 -l error installCTL KO
		exit 1
	fi
	# set the group
	chown :security $TS_CTL_PATH
	if [ $? -ne 0 ]; then
		printf "Directory's group modification failed.\n"  >/dev/console
                displaypopup -t 4 -l error installCTL KO
		exit 1
	fi
	# now that group is set, change permissions for group
	chmod g+rx $TS_CTL_PATH
	if [ $? -ne 0 ]; then
		printf "Directory's permissions modification failed.\n"  >/dev/console
                displaypopup -t 4 -l error installCTL KO
		exit 1
	fi
fi

# copy CTL file
cp $FILENAME_CTL $FILENAME_INSTALL

if [ $? -ne 0 ]; then
	printf "File copy failed.\n"  >/dev/console
        displaypopup -t 4 -l error installCTL KO
	exit 1
fi

# set the group
chown :security $FILENAME_INSTALL
if [ $? -ne 0 ]; then
	printf "File's group modification failed.\n"  >/dev/console
        displaypopup -t 4 -l error installCTL KO
	exit 1
fi

# now that group is set, change permissions for group
chmod g+r $FILENAME_INSTALL
if [ $? -ne 0 ]; then
	printf "File's permissions modification failed.\n"  >/dev/console
        displaypopup -t 4 -l error installCTL KO
	exit 1
fi

printf "CTL installed.\n"
#crms254872
displaypopup -t 4 -l information CTL installation OK

/usr/sbin/cert/buildCA
printf "Rebuilt main CA.\n"

# clean temporary files
# CRMS00276670 +
rm -f $FILENAME_CERT 2>/dev/null
rm -f $FILENAME_CERT_CA 2>/dev/null
rm -f $FILENAME_CA 2>/dev/null
rm -f $FILENAME_CTL 2>/dev/null
rm -f $FILENAME_CTL_TMP 2>/dev/null
rm -f $FILENAME_SIGN 2>/dev/null
rm -f $FILENAME_SIGNB64 2>/dev/null
rm -f $FILENAME_KEY 2>/dev/null
# CRMS00276670 -
exit 0

# vim: set noexpandtab tabstop=4 softtabstop=4 shiftwidth=4:
