#!/bin/bash source $(dirname $(readlink -f $0))/../lib/ca-functions # XXX: Add an interactive mode to this script to obviate the need for a # pre-existing config file? e.g. # $ cd /empty/directory or /dir/containing/partial/conf # $ ca-init -i # or maybe: # $ ca-init -i /path/to/CA_HOME # + modify config file loading to check current directory too? # XXX: corollary to above: provide --long-options for all config file # variables also, reducing or eliminating *requirement* for config file? usage() { cat <<__EOT__ Usage: $PROGNAME [options] Options: -h, --help Print this helpful message! -c, --encrypt Encrypt CA private key with Triple-DES -f, --config FILE Use config file instead of $CONFFILE -d, --days DAYS CA Certificate valid for DAYS days instead of CA_DAYS -l, --crl-days DAYS Make CRL valid for DAYS days instead of CA_CRL_DAYS -b, --bits BITS Generate a BITS bit certificate instead of CA_CRT_BITS -i, --template FILE Use alternative index.html template -o, --output FILE Generate CA index.html in FILE -s, --sign-only Only generate CA cert/key, use pre-created config -x, --cnf-only Only generate CA config file, don't create CA cert/key __EOT__ } short="hcf:d:l:b:i:o:sx" long="help,encrypt,config:,days:,crl-days:,bits:" long="$long,template:,output:,sign-only,cnf-only" opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" ) if [ 0 -ne $? ]; then echo; usage; exit 1; fi eval set -- "$opts"; CRT_ONLY=0 CNF_ONLY=0 while :; do case "$1" in -h|--help) usage; exit 0;; -c|--encrypt) CRYPTKEY=""; shift;; -f|--config) shift; CONFFILE="$1"; CONFFILECLI=1; shift;; -d|--days) shift; USER_CA_DAYS="$1"; shift;; -l|--crl-days) shift; USER_CA_CRL_DAYS="$1"; shift;; -b|--bits) shift; USER_CA_CRT_BITS="$1"; shift;; -i|--template) shift; INDEXTPL="$1"; shift;; -o|--output) shift; INDEXOUT="$1"; shift;; -s|--sign-only) CRT_ONLY=1; shift;; -x|--cnf-only) CNF_ONLY=1; shift;; --) shift; break;; *) echo "Unknown value '$1'"; exit 1;; esac done # load up the configuration file ca_load_conf if [ 1 -eq "$CRT_ONLY" -a 1 -eq "$CNF_ONLY" ]; then error "The --crt-only and --cnf-only options are mutually exclusive." fi if [ 1 -eq "$CNF_ONLY" -a -n "$INDEXOUT" ]; then error "Cannot generate index.html when not creating certificates." fi if [ 1 -ne "$CRT_ONLY" ]; then # create the directory structure that'll be populated by the scripts mkdir -p $CA_HOME/{cnf,crl,crt,csr,db,idx,key,p12} echo "01" > $CA_HOME/db/crlnumber touch $CA_HOME/db/index.txt touch $CA_HOME/db/.rand # generate an openssl configuration for this CA ca_template ca-config "$CA_HOME/cnf/$CA_NAME.ca.cnf" fi if [ 1 -ne "$CNF_ONLY" ]; then if [ ! -f "$CA_HOME/cnf/$CA_NAME.ca.cnf" ]; then # looks like someone's running ca-init with -s without using -x first error "Could not find CA config. Please run ca-init -x before using ca-init -s." fi # generate a self-signed cert that is valid for 10 years, with # ... the private key in $CA_HOME/key/$CA_NAME.ca.key # ... the certificate in $CA_HOME/crt/$CA_NAME.ca.crt # ... using the config in $CA_HOME/cnf/$CA_NAME.ca.cnf openssl req -new $CRYPTKEY -config "$CA_HOME/cnf/$CA_NAME.ca.cnf" \ -keyout "$CA_HOME/key/$CA_NAME.ca.key" \ -out "$CA_HOME/csr/$CA_NAME.ca.csr" chmod 400 "$CA_HOME/key/$CA_NAME.ca.key" openssl ca -create_serial -selfsign -days "$CA_DAYS" -batch \ -name ca_scripts -extensions ca_x509_extensions \ -config "$CA_HOME/cnf/$CA_NAME.ca.cnf" \ -in "$CA_HOME/csr/$CA_NAME.ca.csr" \ -keyfile "$CA_HOME/key/$CA_NAME.ca.key" \ -out "$CA_HOME/crt/$CA_NAME.ca.crt" # generate an initial CRL too (yes it will be empty, but we should serve it) ca_gen_crl if [ -n "$INDEXOUT" ]; then ca_checksum ca_template $INDEXTPL $INDEXOUT fi fi