Set +x on create-user-database script
[clinton/scripts.git] / ca-sign
diff --git a/ca-sign b/ca-sign
index 687ad5b..a587cc0 100755 (executable)
--- a/ca-sign
+++ b/ca-sign
@@ -1,11 +1,30 @@
-#!/bin/sh -e
+#!/bin/bash
 #
 # Sign a certificate request as a CA.  Run this on deleuze as an
-# admin.
+# admin.  If a domain is provided, then the certificate request must
+# apply only to that domain.
 #
-# Usage: ca-sign days request.csr out-cert-file.pem
+# Run this on deleuze as an admin.
+#
+# Usage: ca-sign days request.csr key.asc outfile.pem [domain]
+#
+# If we need to generate a new CA private key and cert, do:
+#
+# $ openssl genrsa -out private/ca.key 2048 -nodes
+# $ openssl req -config openssl.cnf -x509 -sha1 -days 3650 \
+#   -key private/ca.key -new -out ca.crt
 
-test -n "$3" || exit 1
+if test -n "$6" || test -z "$4"; then
+    echo "Incorrect arguments."
+    echo "Usage: ca-sign days request.csr key.asc outfile.pem [domain]"
+    exit 1
+fi
+
+# Make sure we run this from deleuze
+if test "$(hostname -s)" != "deleuze"; then
+    echo "Error: This script must be run from deleuze."
+    exit 1
+fi
 
 DIR=/var/local/lib/ca
 CONF=$DIR/openssl.cnf
@@ -16,24 +35,68 @@ CRL1=$DIR/crl-v1
 CRL2=$DIR/crl-v2
 CA_LOC=/afs/hcoop.net/user/h/hc/hcoop/public_html/ca
 
+# Parameters
 DAYS=$1
 REQUEST=$2
-PEM=$3
+KEY=$3
+PEM=$4
+DOMAIN=$5
+
+# Make sure completed certificate does not already exist
+if test -e "$PEM"; then
+    echo "Error: Refusing to overwrite existing certificate at"
+    echo "       $PEM."
+    exit 1
+fi
+
+# Make sure that the key and request do exist
+if test ! -f "$REQUEST"; then
+    echo "Error: The given certificate request file does not exist."
+    exit 1
+fi
+if test ! -f "$KEY"; then
+    echo "Error: The given key file does not exist."
+    exit 1
+fi
+
+# Verify request
+STATUS=$(openssl req -noout -in "$REQUEST" -verify 2>&1)
+if test "$STATUS" != "verify OK"; then
+    echo "Error: This is not a valid certificate request."
+    exit 1
+fi
+if test -n "$DOMAIN"; then
+    CN=$(openssl req -text -in "$REQUEST" | grep "Subject:" | grep "CN=." | \
+        sed -r -e 's/^.*CN=([^/=,]+).*$/\1/1')
+    if test "${CN%%${DOMAIN}}" = "${CN}"; then
+        echo "Error: Domain in cert does not match $DOMAIN."
+        exit 1
+    fi
+fi
+
+# Get new serial number
 ID=$(cat -- $DIR/serial)
 
-# Sign.
+# Exit on error
+set -e
+
+# Sign
 echo "Signing certificate request $REQUEST ..."
-openssl ca -config $CONF -policy $POLICY -out $PEM -in $REQUEST -days $DAYS
+openssl ca -config $CONF -policy $POLICY -out "$PEM" -in "$REQUEST" \
+    -days "$DAYS"
 echo
 
 # Make a copy of the request
-cp $REQUEST $DIR/requests/$ID.csr
+cp "$REQUEST" $DIR/requests/$ID.csr
+
+# Append key to generated certificate
+cat "$KEY" >> "$PEM"
 
 # Update revocation list.
 echo "Updating certificate revocation list ..."
-openssl ca -config $CONF -batch -gencrl -crldays 180 -out $CRL1.pem
+openssl ca -config $CONF -batch -gencrl -crldays 30 -out $CRL1.pem
 openssl crl -outform DER -out $CRL1.crl -in $CRL1.pem
-openssl ca -config $CONF -batch -gencrl -crldays 180 -crlexts crl_ext \
+openssl ca -config $CONF -batch -gencrl -crldays 30 -crlexts crl_ext \
     -out $CRL2.pem
 openssl crl -outform DER -out $CRL2.crl -in $CRL2.pem
 cp $CRL1.crl $CRL2.crl $CA_LOC