X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=plc.d%2Fssl;h=c1811565f4f9a5cb19e4ee349f8f064ac611694a;hb=9620105bcffdbb71d9d32692e976267d14579d10;hp=0615d75d586587009ef7a1b060fc0ebff356e502;hpb=acafa75f495e5beb8641cc4c984779978aa7dc57;p=myplc.git diff --git a/plc.d/ssl b/plc.d/ssl index 0615d75..c181156 100755 --- a/plc.d/ssl +++ b/plc.d/ssl @@ -7,7 +7,7 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: ssl,v 1.4 2006/04/25 21:18:19 mlhuang Exp $ +# $Id: ssl,v 1.11 2007/01/18 18:44:18 mlhuang Exp $ # # Source function library and configuration @@ -17,105 +17,73 @@ # Be verbose set -x -mkcert () +# Print the CNAME of an SSL certificate +ssl_cname () { - 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 + openssl x509 -noout -in $1 -subject | \ + sed -n -e 's@.*/CN=\([^/]*\).*@\1@p' | \ + lower } -case "$1" in - start) - MESSAGE=$"Generating SSL certificates" - dialog "$MESSAGE" - - # 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 +# Verify a certificate. If invalid, generate a new self-signed +# certificate. +verify_or_generate_certificate() { + crt=$1 + key=$2 + ca=$3 + cname=$(lower $4) + + # If the CA certificate does not exist, assume that the + # certificate is self-signed. + if [ ! -f $ca ] ; then + cp -a $crt $ca + fi + + if [ -f $crt ] ; then + # Check if certificate is valid + verify=$(openssl verify -CAfile $ca $crt) + # Delete if invalid or if the subject has changed + if grep -q "error" <<<$verify || \ + [ "$(ssl_cname $crt)" != "$cname" ] ; then + rm -f $crt $ca 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 + if [ ! -f $crt ] ; then + # Set subject + subj= + if [ -n "$cname" ] ; then + subj="$subj/CN=$cname" 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 new self-signed certificate + mkdir -p $(dirname $crt) + openssl req -new -x509 -days 3650 -set_serial $RANDOM \ + -batch -subj "$subj" \ + -nodes -keyout $key -out $crt + check - # 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 + # The certificate it self-signed, so it is its own CA + cp -a $crt $ca + fi - # 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 + # Fix permissions + chmod 644 $crt $ca +} + +case "$1" in + start) + MESSAGE=$"Generating SSL certificates" + dialog "$MESSAGE" - # Generate HTTPS certificate(s). We generate a certificate for - # each enabled server with a different hostname. + # Generate HTTPS certificates if necessary. We generate a + # certificate for each enabled server with a different + # hostname. These self-signed certificates may be overridden + # later. for server in WWW API BOOT ; do ssl_key=PLC_${server}_SSL_KEY ssl_crt=PLC_${server}_SSL_CRT + ca_ssl_crt=PLC_${server}_CA_SSL_CRT hostname=PLC_${server}_HOST # Check if we have already generated a certificate for @@ -126,33 +94,21 @@ case "$1" in fi previous_ssl_key=PLC_${previous_server}_SSL_KEY previous_ssl_crt=PLC_${previous_server}_SSL_CRT + previous_ca_ssl_crt=PLC_${previous_server}_CA_SSL_CRT previous_hostname=PLC_${previous_server}_HOST if [ -f ${!previous_ssl_crt} ] && \ [ "$(ssl_cname ${!previous_ssl_crt})" = "${!hostname}" ] ; then cp -a ${!previous_ssl_key} ${!ssl_key} cp -a ${!previous_ssl_crt} ${!ssl_crt} + cp -a ${!previous_ca_ssl_crt} ${!ca_ssl_crt} break fi done - # Check if certificate is valid - if [ -f ${!ssl_crt} ] ; then - 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 and sign certificate - if [ ! -f ${!ssl_crt} ] ; then - mkcert ${!hostname} ${!ssl_key} ${!ssl_crt} - fi + verify_or_generate_certificate \ + ${!ssl_crt} ${!ssl_key} ${!ca_ssl_crt} \ + ${!hostname} done # Install HTTPS certificates into both /etc/pki (Fedora Core