#! /bin/sh
#
#
dir=.
prefix=new
bits=1024
stamp=`date '+%Y%m%d-%H%M%S'`
host=`hostname`
oldkey=

while :; do
  case "$1" in
  -d )			dir="$2" ; shift 2 ;;
  -o )			prefix="$2" ; shift 2 ;;
  -b )			bits="$2" ; shift 2 ;;
  -k | --inkey )	oldkey="$2" ; shift 2 ;;
  * )			break ;;
  esac
done

case "$#" in 
1 ) certf="$1" ;;
* ) echo "Usage: $0 [-h] [-d targetdir] [-o prefix] [-k oldkey] cert.pem" >&2
    exit 1 ;;
esac

if [ ! -f "$certf" ]; then
  echo "Cannot find your old certificate in $certf" >&2
  echo "Did you specify the proper file? For " >&2
  echo "- personal certificates, it is usually $HOME/.globus/" >&2
  echo "- host certificates, it is usually /etc/grid-security/XXXXcert.pem" >&2
  echo "Please locate your certificate and restart this utility" >&2
  exit 1
fi

if [ ! -d "$dir" ]; then
  echo "The directory $dir does not exist, or is not a directory" >&2
  echo "Please specify a new targer directory, or create it with mkdir" >&2
  exit 1
fi

awktest=`awk 'END { print 1 }' < /dev/null 2>/dev/null`
if [ "$awktest" -ne 1 ]; then
  echo "The AWK system utility could not be found, please install it " >&2
  echo "and only then try again." >&2
  exit 1
fi


openssltest=`openssl version 2>/dev/null | awk '/openssl/i { print $1} '`
if [ x"$openssltest" = x"" ]; then
  echo "The OpenSSL utility could not be found. Please install it first" >&2
  echo "and only then try the rekeying script again" >&2
  exit 1
fi


rq="$dir/$prefix-requestconfig.cnf"
newkey="$dir/${prefix}key.pem"
newreq="$dir/${prefix}cert_request.pem"
newcert="$dir/${prefix}cert.pem"
newmail="$dir/${prefix}request.mail"

if [ x"$oldkey" = x ]; then
  oldkey=`echo $certf | sed -e 's/cert/key/'`
  echo "Notice: private key file not specified, attempting $oldkey" >&2
fi

if [ ! -f "$oldkey" ]; then
  echo "Cannot find old key in $oldkey" >&2
  echo "Please make sure your private key is still available, and specify" >&2
  echo "its location using the --inkey argument to this utility" >&2
  exit 1
fi

[ -f "$newkey" ] && mv $newkey $newkey.bak$$
[ -f "$newreq" ] && mv $newreq $newreq.bak$$
[ -f "$newcert" ] && mv $newcert $newcert.bak$$
[ -f "$newmail" ] && mv $newmail $newmail.bak$$




subject=`openssl x509 -noout -subject -in $certf | sed -e 's/^subject= *//'`

echo "Using" 
echo "  certificate: $certf"
echo "  private key: $oldkey" 
echo "  subject:     $subject"
echo ""

emailto=`awk '/^To: / { print substr($0,5) }' $certf`
while [ x"$emailaddr" == x"" ]; do
  rest="nonsense"
  while [ x"$rest" != x"" ]; do
    if [ x"$emailto" = x"" ]; then
      echo "Please enter your email (to send the new certificate to): " >&2
    else
      echo "Please enter your email (for default $emailto press Enter): " >&2
    fi
    read emailaddr rest
    if [ x"$rest" != x"" ]; then
      echo "Error: Your email address should not contain spaces, please retry" >&2
    fi
  done
  if [ x"$emailaddr" == x"" ]; then
    emailaddr=$emailto
  fi
done

echo ""
echo "Who is your preferred (original) Registration Authority?" >&2
echo "  (please give an email address if you know it, but" >&2
echo "   it's also OK to leave this empty, just press Enter)" >&2
read rainfo

cat > $rq <<EOFA
[ req ]
default_bits            = $bits
default_keyfile         = $newkey
distinguished_name      = req_distinguished_name
prompt                  = no

[ req_distinguished_name ]
EOFA

openssl x509 -noout -subject -nameopt multiline -nameopt sname -in $certf |
( io=0 ;
  while read x ; do case "$x" in
    O* ) echo " $io.$x" ; io=`expr $io + 1` ;;
    CN* ) echo " $x" ;;
    OU* ) echo " $x" ;;
  esac
  done
) >> $rq

# who was the original issuer???
issuer=`openssl x509 -noout -issuer -in $certf`
case "$issuer" in
*medium-security* )
		ca="CA" ;;
*demo* )	ca="DutchDemo" ;;
* )		echo "The issuer of original cert not recognised" >&2
		echo "$issuer" >&2
		exit 1 ;;
esac

# was old key encrypted
encrypted=`grep -c ENCRYPTED $oldkey`
if [ $encrypted -eq 0 ]; then
  desoption="-nodes "
fi


# generate new request
echo "">&2
echo "Please enter a passphrase to protect your NEW private key" >&2
echo "(note that you will have to type this same passphrase twice)" >&2
openssl req $desoption -new -config $rq -text -out $newreq -keyout $newkey
if [ $? -ne 0 -o ! \( -s $newkey -a -s $newreq \) ]; then
  echo "Did not properly generate key/request pair" >&2
  exit 1
fi
chmod go-rwx $newkey
chmod u-w $newkey
chmod ugo-w $newreq


# put the request in a signed mail
cat > $newmail <<EOFB

Dear subscriber:

Mail this message to the DutchGrid Certification Authority at 

        <ca@dutchgrid.nl>

Your Registration Authority will be contacted automatically to reconfirm 
your renewal request. Normally, this re-validation process will not take 
longer than three days.  After the registration authority has re-
confirmed your application, you will receive your newly signed certificate. 

  Email address:  $emailaddr

  Timestamp:      $stamp
  Host:           $host
  CA target:      $ca

  RApreference:   $rainfo

EOFB
cat $newreq >>$newmail 

echo "***" >&2
echo "*** please enter the passphrase for your OLD private key" >&2
echo "*** in order to sign your e-mail request to the CA" >&2
openssl smime -sign -in $newmail -out $newmail.mime \
	-signer $certf -inkey $oldkey -text

if [ `grep -c 'Content-Type: multipart/signed' $newmail.mime` -ne 1 ] ; then
  echo "" >&2
  echo "!!! WARNING: an invalid S/MIME message may have been generated" >&2
  echo "             please review the message in $newmail - " >&2
  echo "             If something in this file looks like an error, please " >&2
  echo "             mail the contents of this file to the CA in addition " >&2
  echo "             to mailing the request as instructed" >&2
  echo "" >&2
  echo "             Note that the request must still be sent off to the CA" >&2
  echo "             Sorry for the trouble." >&2
  echo "" >&2
  preserve=1
else
  preserve=0
fi

rm -f $newmail
echo "To: ca@nikhef.nl" > $newmail
echo "Subject: [$ca] Renewal for $subject" >> $newmail
DATE=`date -R`
echo "Date: $DATE" >> $newmail
ID=`whoami`
echo "X-Renew-WhoAmI: $ID" >> $newmail
HOST=`hostname -f`
echo "X-Renew-Hostname: $HOST" >> $newmail
PWDIR=`pwd`
echo "X-Renew-Working-Directory: $PWDIR" >> $newmail
echo "X-Renew-Target-Directory: $dir" >> $newmail
echo "X-Renew-DES-Option: $desoption" >> $newmail
echo "X-Renew-Script-Version: DCA-20050914-01" >> $newmail

cat $newmail.mime >> $newmail
[ "$preserve" -ne 1 ] && rm $newmail.mime

for sendmail in /usr/lib/sendmail /usr/sbin/sendmail /usr/etc/sendmail
do
  [ -x $sendmail ] && break
done
[ -x $sendmail ] || sendmail=sendmail

echo "***" >&2
echo "*** You are about to send your renewal request to the DutchGrid CA" >&2
echo "*** The mail is stored in the file $newmail," >&2
echo "*** use to following command to mail it, but do not modify the" >&2
echo "*** contents of the e-mail!" >&2
echo "*** Command:" >&2
echo "    $sendmail -t < $newmail" >&2
echo ""
echo "*** You must now go to your Registration Authority to re-confirm your"
echo "*** identification. The RA must acknowledge this by mail to the CA"
echo "*** The new certificate will be sent to $emailaddr" >&2
echo ""

