# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: ssl,v 1.3 2006/04/07 04:28:16 mlhuang Exp $
+# $Id: ssl,v 1.4 2006/04/25 21:18:19 mlhuang Exp $
#
# Source function library and configuration
. /etc/plc.d/functions
. /etc/planetlab/plc_config
+# Be verbose
+set -x
+
+mkcert ()
+{
+ CN=$1
+ KEY=$2
+ CRT=$3
+
+ # Generate a temporary CSR. We could save the CSR, but it's not
+ # worth the trouble.
+ csr=$(mktemp /tmp/csr.XXXXXX)
+
+ mkdir -p $(dirname $KEY)
+ openssl req -config /etc/planetlab/ssl/openssl.cnf \
+ -new -extensions v3_req -days 365 -set_serial $RANDOM \
+ -batch -subj "/CN=$CN" \
+ -nodes -keyout $KEY -out $csr
+ check
+ chmod 600 $KEY
+
+ # Generate and sign certificate from CSR
+ serial=$(cat /etc/planetlab/ssl/serial)
+
+ openssl ca -config /etc/planetlab/ssl/openssl.cnf \
+ -keyfile $PLC_ROOT_CA_SSL_KEY \
+ -cert $PLC_ROOT_CA_SSL_CRT \
+ -batch -infiles $csr
+ check
+
+ mv /etc/planetlab/ssl/$serial.pem $CRT
+ chmod 644 $CRT
+
+ # Delete CSR
+ rm -f $csr
+}
+
case "$1" in
start)
MESSAGE=$"Generating SSL certificates"
dialog "$MESSAGE"
- # Generate self-signed SSL certificate(s). These nice
- # commands come from the mod_ssl spec file for Fedora Core
- # 2. We generate a certificate for each enabled server
- # with a different hostname. These self-signed
- # certificates may be overridden later.
+ # Check if root CA certificate is valid
+ if [ -f $PLC_ROOT_CA_SSL_CRT ] ; then
+ verify=$(openssl verify $PLC_ROOT_CA_SSL_CRT)
+ # If self signed, assume that we generated it
+ if grep -q "self signed certificate" <<<$verify ; then
+ # Delete if expired or PLC name or e-mail address has changed
+ if grep -q "expired" <<<$verify || \
+ [ "$(ssl_cname $PLC_ROOT_CA_SSL_CRT)" != "$PLC_NAME Root CA" ] || \
+ [ "$(ssl_email $PLC_ROOT_CA_SSL_CRT)" != "$PLC_MAIL_SUPPORT_ADDRESS" ] ; then
+ rm -f $PLC_ROOT_CA_SSL_CRT
+ fi
+ fi
+ fi
+
+ # Generate root CA key pair and certificate
+ if [ ! -f $PLC_ROOT_CA_SSL_CRT ] ; then
+ mkdir -p $(dirname $PLC_ROOT_CA_SSL_CRT)
+ openssl req -config /etc/planetlab/ssl/openssl.cnf \
+ -new -x509 -extensions v3_ca -days 3650 -set_serial $RANDOM \
+ -batch -subj "/CN=$PLC_NAME Root CA/emailAddress=$PLC_MAIL_SUPPORT_ADDRESS" \
+ -nodes -keyout $PLC_ROOT_CA_SSL_KEY -out $PLC_ROOT_CA_SSL_CRT
+ check
+ chmod 600 $PLC_ROOT_CA_SSL_KEY
+ chmod 644 $PLC_ROOT_CA_SSL_CRT
+
+ # API certificate verification requires a public key
+ openssl rsa -pubout <$PLC_ROOT_CA_SSL_KEY >$PLC_ROOT_CA_SSL_KEY_PUB
+ check
+ chmod 644 $PLC_ROOT_CA_SSL_KEY_PUB
+
+ # Reset DB
+ >/etc/planetlab/ssl/index.txt
+ echo "01" >/etc/planetlab/ssl/serial
+ fi
+
+ # Check if MA/SA certificate is valid
+ if [ -f $PLC_MA_SA_SSL_CRT ] ; then
+ verify=$(openssl verify -CAfile $PLC_ROOT_CA_SSL_CRT $PLC_MA_SA_SSL_CRT)
+ # Delete if expired or not signed correctly
+ if grep -q "error" <<<$verify ; then
+ rm -f $PLC_MA_SA_SSL_CRT
+ fi
+ fi
+
+ # Generate MA/SA key pair and certificate
+ if [ ! -f $PLC_MA_SA_SSL_CRT ] ; then
+ mkcert "$PLC_NAME Management and Slice Authority" \
+ $PLC_MA_SA_SSL_KEY $PLC_MA_SA_SSL_CRT
+
+ # API requires a public key for slice ticket verification
+ openssl rsa -pubout <$PLC_MA_SA_SSL_KEY >$PLC_MA_SA_SSL_KEY_PUB
+ check
+ chmod 644 $PLC_MA_SA_SSL_KEY_PUB
+ fi
+
+ # Generate HTTPS certificate(s). We generate a certificate for
+ # each enabled server with a different hostname.
for server in WWW API BOOT ; do
ssl_key=PLC_${server}_SSL_KEY
ssl_crt=PLC_${server}_SSL_CRT
fi
done
- # Check if self signed certificate is valid
+ # Check if certificate is valid
if [ -f ${!ssl_crt} ] ; then
- verify=$(openssl verify ${!ssl_crt})
- # If self signed
- if grep -q "self signed certificate" <<<$verify ; then
- # Delete if expired or hostname changed
- if grep -q "expired" <<<$verify || \
- [ "$(ssl_cname ${!ssl_crt})" != "${!hostname}" ] ; then
- rm -f ${!ssl_crt}
- fi
- else
- echo "$verify" >&2
+ verify=$(openssl verify -CAfile $PLC_ROOT_CA_SSL_CRT ${!ssl_crt})
+ # Delete if expired or hostname changed. These
+ # certificates do not necessarily have to be signed by
+ # the root CA; they may be signed by a third party,
+ # e.g., Entrust or Verisign.
+ if grep -q "expired" <<<$verify || \
+ [ "$(ssl_cname ${!ssl_crt})" != "${!hostname}" ] ; then
+ rm -f ${!ssl_crt}
fi
fi
- # Generate new self signed certificate
+ # Generate and sign certificate
if [ ! -f ${!ssl_crt} ] ; then
- mkdir -p $(dirname ${!ssl_crt})
- openssl req -new -x509 -days 365 -set_serial $RANDOM \
- -batch -subj "/CN=${!hostname}" \
- -nodes -keyout ${!ssl_key} -out ${!ssl_crt}
- check
- chmod 644 ${!ssl_crt}
+ mkcert ${!hostname} ${!ssl_key} ${!ssl_crt}
fi
done
- # API requires a public key for slice ticket verification
- if [ ! -f $PLC_API_SSL_KEY_PUB ] ; then
- openssl rsa -pubout <$PLC_API_SSL_KEY >$PLC_API_SSL_KEY_PUB
- check
- fi
-
- # Install into both /etc/pki (Fedora Core 4) and
- # /etc/httpd/conf (Fedora Core 2). If the API, boot, and
- # web servers are all running on the same machine, the web
+ # Install HTTPS certificates into both /etc/pki (Fedora Core
+ # 4) and /etc/httpd/conf (Fedora Core 2). If the API, boot,
+ # and web servers are all running on the same machine, the web
# server certificate takes precedence.
for server in API BOOT WWW ; do
enabled=PLC_${server}_ENABLED