initial commit of ca-scripts devel work
This commit is contained in:
commit
348a0df638
19 changed files with 1121 additions and 0 deletions
169
bin/ca-create-cert
Executable file
169
bin/ca-create-cert
Executable file
|
@ -0,0 +1,169 @@
|
|||
#! /bin/bash
|
||||
|
||||
. "/home/alex/code/ca-scripts/lib/ca-functions"
|
||||
|
||||
ALT_NAMES=()
|
||||
TPL_ONLY=0
|
||||
CSR_ONLY=0
|
||||
CRT_ONLY=0
|
||||
MAKE_P12=0
|
||||
|
||||
# XXX: in the ca_extension_policy section of ca-config.tpl it states that the
|
||||
# C= and O= DN values in a CSR have to match those of the CA
|
||||
# should we have options here to change them when it will cause breakage?
|
||||
usage() {
|
||||
cat <<__EOT__
|
||||
Usage:
|
||||
$PROGNAME -t server [options] <hostname>
|
||||
$PROGNAME -t client [options] <hostname>
|
||||
$PROGNAME -t user [options] <username>
|
||||
|
||||
Options:
|
||||
-h, --help Print this helpful message!
|
||||
-c, --encrypt Encrypt certificate private key with Triple-DES
|
||||
-f, --config FILE Use config file instead of $CONFFILE
|
||||
-t, --type Certificate type: "server", "client" or "user"
|
||||
-n, --alt-name Alternative host name (can be provided multiple times)
|
||||
-p, --pkcs12 Create PKCS#12 certificate archive from generated cert
|
||||
-r, --csr-only Only generate CSR, don't sign it
|
||||
-s, --crt-only Only sign certificate, requires CSR in place
|
||||
-x, --tpl-only Only generate templates, do not create CSR or sign CRT
|
||||
--country Certificate DN -- C
|
||||
--state Certificate DN -- ST
|
||||
--loc Certificate DN -- L
|
||||
--org Certificate DN -- O
|
||||
--org-unit Certificate DN -- OU
|
||||
--email Certificate DN -- E
|
||||
--comment Certificate nsComment field
|
||||
|
||||
__EOT__
|
||||
}
|
||||
|
||||
short='hcf:t:n:prsx'
|
||||
long='help,encrypt.config:,type:,alt-name:,csr-only,crt-only,tpl-only,pkcs12'
|
||||
long="$long,country:,state:,loc:,org:,org-unit:,email:,comment:"
|
||||
opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" )
|
||||
if [ 0 -ne $? ]; then echo; usage; exit 1; fi
|
||||
eval set -- "$opts";
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-c|--encrypt) CRYPTKEY=""; shift;;
|
||||
-f|--config) shift; CONFFILE="$1"; shift;;
|
||||
-t|--type) shift; CA_CRT_TYPE="$1"; shift;;
|
||||
-n|--alt-name) shift; ALT_NAMES+=("$1"); shift;;
|
||||
-p|--pkcs12) MAKE_P12=1; shift;;
|
||||
-r|--csr-only) CSR_ONLY=1; shift;;
|
||||
-s|--crt-only) CRT_ONLY=1; shift;;
|
||||
-x|--tpl-only) TPL_ONLY=1; shift;;
|
||||
--country) shift; CA_CRT_C="$1"; shift;;
|
||||
--state) shift; CA_CRT_ST="$1"; shift;;
|
||||
--location) shift; CA_CRT_L="$1"; shift;;
|
||||
--org) shift; CA_CRT_O="$1"; shift;;
|
||||
--org-unit) shift; CA_CRT_OU="$1"; shift;;
|
||||
--email) shift; CA_CRT_E="$1"; shift;;
|
||||
--comment) shift; CA_CRT_COMMENT="$1"; shift;;
|
||||
--) shift; break;;
|
||||
*) echo "Unknown value '$1'"; exit 1;;
|
||||
esac
|
||||
done
|
||||
CA_CRT_CN="$1";
|
||||
|
||||
# load up the configuration file
|
||||
ca_load_conf
|
||||
|
||||
# parameter checking fun -- we need a type and a cn (either user or host name)
|
||||
if [ -z "$CA_CRT_CN" ]; then
|
||||
error "The host or username parameter is mandatory!"
|
||||
fi
|
||||
|
||||
if [ 1 -eq "$CSR_ONLY" -a 1 -eq "$CRT_ONLY" ]; then
|
||||
error "Options --csr-only and --crt-only are mutually exclusive."
|
||||
fi
|
||||
|
||||
if [ "$CA_CRT_TYPE" = "user" ]; then
|
||||
# append @$CA_DOMAIN to user CN if it's not already there
|
||||
if [ "${CA_CRT_CN%%@*}" = "$CA_CRT_CN" ]; then
|
||||
CA_CRT_CN="$CA_CRT_CN@$CA_DOMAIN";
|
||||
fi
|
||||
else
|
||||
# fully qualify server or client CN with $CA_DOMAIN if it's not already
|
||||
if [ "${CA_CRT_CN%%.*}" = "$CA_CRT_CN" ]; then
|
||||
# however we may also want the unqualified one as an alt-name
|
||||
ALT_NAMES+=("$CA_CRT_CN")
|
||||
CA_CRT_CN="$CA_CRT_CN.$CA_DOMAIN"
|
||||
fi
|
||||
fi
|
||||
CNF_NAME=$( echo -n "$CA_CRT_CN" | tr -c '[:alnum:]@-' _ )".$CA_CRT_TYPE";
|
||||
|
||||
# if they've provided a comment, reformat it correctly
|
||||
if [ -n "$CA_CRT_COMMENT" ]; then
|
||||
CA_CRT_COMMENT="$( tr -d\" <<< $CA_CRT_COMMENT )"
|
||||
CA_CRT_COMMENT="nsComment = \"$CA_CRT_COMMENT\"\n"
|
||||
else
|
||||
CA_CRT_COMMENT=""
|
||||
fi
|
||||
|
||||
CA_CRT_ALT_NAMES=""
|
||||
# generate a list of alternative DNS names for server certificates
|
||||
if [ "$CA_CRT_TYPE" = "server" ]; then
|
||||
i=1
|
||||
for ALT_NAME in "$CA_CRT_CN" "${ALT_NAMES[@]}"; do
|
||||
# also fully-qualify unqualified alt-names too (see below)
|
||||
if [ "${ALT_NAME%%.*}" = "$ALT_NAME" ]; then
|
||||
CA_CRT_ALT_NAMES="${CA_CRT_ALT_NAMES}DNS.$i=$ALT_NAME.$CA_DOMAIN\n"
|
||||
i=$(( $i+1 ))
|
||||
fi
|
||||
CA_CRT_ALT_NAMES="${CA_CRT_ALT_NAMES}DNS.$i=$ALT_NAME\n"
|
||||
i=$(( $i+1 ))
|
||||
done
|
||||
fi
|
||||
|
||||
if [ 1 -ne "$CRT_ONLY" ]; then
|
||||
if [ 1 -eq "$TPL_ONLY" -o "$CSR_ONLY" -eq "$TPL_ONLY" ]; then
|
||||
# dirty logic here that probably needs commenting!
|
||||
# generate a *new* certificate request configuration if...
|
||||
# a) --tpl-only is set, i.e. we only want to generate a config
|
||||
# b) both --tpl-only and --csr-only are unset, i.e.
|
||||
# we're just generating a csr/crt as per usual
|
||||
# c) both --tpl-only and --csr-only are set, i.e.
|
||||
# we're just generating the config and not the csr itself
|
||||
ca_template "req-config" "$CA_HOME/cnf/$CNF_NAME.req.cnf"
|
||||
fi
|
||||
if [ 1 -ne "$TPL_ONLY" ]; then
|
||||
if [ ! -f "$CA_HOME/cnf/$CNF_NAME.req.cnf" ]; then
|
||||
error "Couldn't find CSR config $CA_HOME/cnf/$CNF_NAME.req.cnf!"
|
||||
fi
|
||||
# the above logic means that if you pass --csr-only but not
|
||||
# --tpl-only, you can re-use a pre-existing config to generate
|
||||
# a new csr, should you wish to do so...
|
||||
openssl req -new $CRYPTKEY -config "$CA_HOME/cnf/$CNF_NAME.req.cnf" \
|
||||
-keyout "$CA_HOME/key/$CNF_NAME.key" \
|
||||
-out "$CA_HOME/csr/$CNF_NAME.csr"
|
||||
fi
|
||||
fi
|
||||
if [ 1 -ne "$CSR_ONLY" ]; then
|
||||
if [ 1 -eq "$TPL_ONLY" -o "$CRT_ONLY" -eq "$TPL_ONLY" ]; then
|
||||
# same logic above applies here, but for generating the extensions
|
||||
# configuration file and signed certificate instead
|
||||
ca_template "$CA_CRT_TYPE-ext" "$CA_HOME/cnf/$CNF_NAME.ext.cnf"
|
||||
fi
|
||||
if [ 1 -ne "$TPL_ONLY" ]; then
|
||||
# ensure relevant files are in place before continuing...
|
||||
if [ ! -f "$CA_HOME/csr/$CNF_NAME.csr" ]; then
|
||||
error "CSR not present in $CA_HOME/csr/$CNF_NAME.csr"
|
||||
fi
|
||||
if [ ! -f "$CA_HOME/cnf/$CNF_NAME.ext.cnf" ]; then
|
||||
error "Couldn't find extensions in $CA_HOME/cnf/$CNF_NAME.ext.cnf"
|
||||
fi
|
||||
openssl ca -config "$CA_HOME/cnf/$CA_NAME.ca.cnf" \
|
||||
-extfile "$CA_HOME/cnf/$CNF_NAME.ext.cnf" -batch \
|
||||
-out "$CA_HOME/crt/$CNF_NAME.crt" \
|
||||
-in "$CA_HOME/csr/$CNF_NAME.csr"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ 1 -eq "$MAKE_P12" ]; then
|
||||
ca_gen_p12 "$CNF_NAME"
|
||||
fi
|
72
bin/ca-init
Executable file
72
bin/ca-init
Executable file
|
@ -0,0 +1,72 @@
|
|||
#! /bin/bash
|
||||
|
||||
. "/home/alex/code/ca-scripts/lib/ca-functions"
|
||||
|
||||
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
|
||||
-i, --template FILE Use alternative index.html template
|
||||
-o, --output FILE Generate CA index.html in FILE
|
||||
|
||||
__EOT__
|
||||
}
|
||||
|
||||
short='hcf:i:o:'
|
||||
long='help,encrypt,config:,template:,output:'
|
||||
opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" )
|
||||
if [ 0 -ne $? ]; then echo; usage; exit 1; fi
|
||||
eval set -- "$opts";
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-c|--encrypt) CRYPTKEY=""; shift;;
|
||||
-f|--config) shift; CONFFILE="$1"; shift;;
|
||||
-i|--template) shift; INDEXTPL="$1"; shift;;
|
||||
-o|--output) shift; INDEXOUT="$1"; shift;;
|
||||
--) shift; break;;
|
||||
*) echo "Unknown value '$1'"; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# load up the configuration file
|
||||
CA_CRT_TYPE="ca"
|
||||
ca_load_conf
|
||||
|
||||
# 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
|
||||
chmod 600 $CA_HOME/db/.rand
|
||||
chmod 700 $CA_HOME/key
|
||||
|
||||
# generate an openssl configuration for this CA
|
||||
ca_template ca-config "$CA_HOME/cnf/$CA_NAME.ca.cnf"
|
||||
|
||||
# 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"
|
||||
|
||||
openssl ca -create_serial -selfsign -days 3652 -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
|
80
bin/ca-renew-cert
Executable file
80
bin/ca-renew-cert
Executable file
|
@ -0,0 +1,80 @@
|
|||
#! /bin/bash
|
||||
|
||||
. "/home/alex/code/ca-scripts/lib/ca-functions"
|
||||
|
||||
usage() {
|
||||
cat <<__EOT__
|
||||
Usage: $PROGNAME -t <type> [options] <hostname|username|certpath>
|
||||
|
||||
Options:
|
||||
-h, --help Print this helpful message!
|
||||
-f, --config FILE Use config file instead of $CONFFILE
|
||||
-t, --type Certificate type: "server", "client" or "user"
|
||||
|
||||
__EOT__
|
||||
}
|
||||
|
||||
short='hf:t:'
|
||||
long='help,config:,type:'
|
||||
opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" )
|
||||
if [ 0 -ne $? ]; then echo; usage; exit 1; fi
|
||||
eval set -- "$opts";
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-f|--config) shift; CONFFILE="$1"; shift;;
|
||||
-t|--type) shift; CA_CRT_TYPE="$1"; shift;;
|
||||
--) shift; break;;
|
||||
*) echo "Unknown value '$1'"; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
CNF_NAME="$1"
|
||||
|
||||
ca_load_conf
|
||||
|
||||
CNF_NAME=$( ca_find_cnf "$CNF_NAME" )
|
||||
CRT="$CA_HOME/crt/$CNF_NAME.crt"
|
||||
|
||||
# make sure that configuration files are present as expected
|
||||
if [ ! -f "$CA_HOME/cnf/$CNF_NAME.ext.cnf" ]; then
|
||||
error "Couldn't find extensions in $CA_HOME/cnf/$CNF_NAME-ext.cnf"
|
||||
fi
|
||||
|
||||
# according to the below URL we should create the new CRT using the old CSR
|
||||
# and with the same serial as the previous certificate.
|
||||
# http://blog.fupps.com/2007/11/30/x509ssl-certificate-prolongation/
|
||||
# After some fun googling, I found the following URL which tells us how...
|
||||
# http://ca.dutchgrid.nl/info/CA_gymnastics.html
|
||||
# XXX: this is only *really* relevant for certs that have been used for code
|
||||
# or e-mail encryption. should we regenerate client/server certs entirely?
|
||||
# ... for the moment there's always the revoke/recreate route for people.
|
||||
|
||||
# acquire required info from old certificate
|
||||
ENDDATE=$( openssl x509 -in "$CRT" -noout -enddate | cut -d= -f2 )
|
||||
SERIAL=$( openssl x509 -in "$CRT" -noout -serial | cut -d= -f2 )
|
||||
# work out new expiry date based on expiry date of current cert + 1 year
|
||||
# these dates are "<year> <day of year>"
|
||||
export TZ=UTC
|
||||
NOWYEAR=$( date +%Y )
|
||||
NOWDAYS=$( date +%j )
|
||||
ENDYEAR=$( date +%Y -d "$ENDDATE + 1 year" )
|
||||
ENDDAYS=$( date +%j -d "$ENDDATE + 1 year" )
|
||||
CERTDATE=$( date +%Y-%m-%d -d "$ENDDATE" )
|
||||
|
||||
# and this does the maths to work out how many days there are from now
|
||||
# (when we're creating the new cert) to the new expiry date
|
||||
DAYS=$(( ($ENDYEAR-$NOWYEAR)*365 + ($ENDDAYS-$NOWDAYS) ))
|
||||
|
||||
# Now perform required CA gymnastics ;p
|
||||
openssl x509 -req -set_serial "0x$SERIAL" -days "$DAYS" \
|
||||
-CA "$CA_HOME/crt/$CA_NAME.ca.crt" \
|
||||
-CAkey "$CA_HOME/key/$CA_NAME.ca.key" \
|
||||
-extfile "$CA_HOME/cfg/$CNF_NAME.ext.cnf" \
|
||||
-out "$CA_HOME/crt/$CNF_NAME.crt" \
|
||||
-in "$CA_HOME/csr/$CNF_NAME.csr"
|
||||
|
||||
# This doesn't update the original certificate in the index, so let's do that
|
||||
mv "$CA_HOME/idx/$SERIAL.pem" "$CA_HOME/idx/$SERIAL.$CERTDATE.pem"
|
||||
cp "$CA_HOME/crt/$CNF_NAME.crt" "$CA_HOME/idx/$SERIAL.pem"
|
51
bin/ca-revoke-cert
Executable file
51
bin/ca-revoke-cert
Executable file
|
@ -0,0 +1,51 @@
|
|||
#! /bin/sh
|
||||
|
||||
. "/home/alex/code/ca-scripts/lib/ca-functions"
|
||||
|
||||
usage() {
|
||||
cat <<__EOT__
|
||||
Usage: $PROGNAME -t <type> [options] <hostname|username|certpath>
|
||||
|
||||
Options:
|
||||
-h, --help Print this helpful message!
|
||||
-f, --config FILE Use config file instead of $CONFFILE
|
||||
-t, --type Certificate type: "server", "client" or "user"
|
||||
-i, --template FILE Use alternative index.html template
|
||||
-o, --output FILE Generate CA index.html in FILE
|
||||
|
||||
__EOT__
|
||||
}
|
||||
|
||||
short='hf:t:i:o:'
|
||||
long='help,config:,type:,template:,output:'
|
||||
opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" )
|
||||
if [ 0 -ne $? ]; then echo; usage; exit 1; fi
|
||||
eval set -- "$opts";
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-f|--config) shift; CONFFILE="$1"; shift;;
|
||||
-t|--type) shift; CA_CRT_TYPE="$1"; shift;;
|
||||
-i|--template) shift; INDEXTPL="$1"; shift;;
|
||||
-o|--output) shift; INDEXOUT="$1"; shift;;
|
||||
--) shift; break;;
|
||||
*) echo "Unknown value '$1'"; exit 1;;
|
||||
esac
|
||||
done
|
||||
CNF_NAME="$1"
|
||||
|
||||
ca_load_conf
|
||||
|
||||
CNF_NAME=$( ca_find_cnf "$CNF_NAME" "$TYPE" )
|
||||
CRT="$CA_HOME/crt/$CNF_NAME.crt"
|
||||
|
||||
openssl ca -config $CA_HOME/cnf/$CA_NAME.ca.cnf \
|
||||
-revoke $CRT -crl_reason superseded
|
||||
|
||||
ca_gen_crl
|
||||
if [ -n "$INDEXOUT" ]; then
|
||||
ca_checksum
|
||||
ca_template $INDEXTPL $INDEXOUT
|
||||
fi
|
||||
|
45
ca-scripts.conf
Normal file
45
ca-scripts.conf
Normal file
|
@ -0,0 +1,45 @@
|
|||
# example ca-scripts configuration file
|
||||
|
||||
# REQUIRED: CA_HOME provides the path to the root of the CA directory tree
|
||||
# this directory must exist and be writeable
|
||||
#CA_HOME="/etc/ssl/ca"
|
||||
CA_HOME="/tmp/ca"
|
||||
|
||||
# REQUIRED: CA_DOMAIN provides a template for other optional variables and
|
||||
# the filenames that are generated within the directory tree
|
||||
CA_DOMAIN="example.com"
|
||||
|
||||
# OPTIONAL: CA_NAME is the internal templating variable for filenames etc
|
||||
# Defaults to:
|
||||
# CA_NAME="$( echo $CA_DOMAIN | tr 'A-Z' 'a-z' | tr -c '-a-z0-9' '_' )"
|
||||
|
||||
# REQUIRED: CA_DN_* configures the Distinguished Name fields present in the
|
||||
# CA certificate generated by ca-init
|
||||
CA_DN_C="GB"
|
||||
CA_DN_ST="London"
|
||||
CA_DN_L="Example House, Mayfair"
|
||||
CA_DN_O="Example Security Services Ltd."
|
||||
CA_DN_OU="Example Internet Encryption Division"
|
||||
CA_DN_CN="Example Security Services Root Certificate Authority"
|
||||
|
||||
# OPTIONAL: CA_DESC configures a single-line description for your CA
|
||||
# using the CN= or O= line from your DN is recommended
|
||||
# Default value:
|
||||
# CA_DESC="$CA_DN_CN"
|
||||
|
||||
# OPTIONAL: CA_EMAIL provides an e-mail address that is embedded into all
|
||||
# generated certificates as a point-of-contact
|
||||
# Default value:
|
||||
# CA_EMAIL="ca@$CA_DOMAIN"
|
||||
|
||||
# OPTIONAL: CA_CRT_URI and CA_CRL_URI provide locations where the CA
|
||||
# certificate and revocation lists can be found
|
||||
# Default value:
|
||||
# CA_CRT_URI="http://$CA_DOMAIN/ca/$CA_NAME.ca.crt"
|
||||
# CA_CRL_URI="http://$CA_DOMAIN/ca/$CA_NAME.ca.crl"
|
||||
|
||||
# OPTIONAL: CA_PATHLEN sets the maximum number of intermediate CA certificates
|
||||
# that can be in the chain of authority between the root CA and the
|
||||
# final certificate.
|
||||
# Default value:
|
||||
# CA_PATHLEN=0
|
61
doc/README
Normal file
61
doc/README
Normal file
|
@ -0,0 +1,61 @@
|
|||
1. Creating a Certificate Authority.
|
||||
|
||||
|
||||
|
||||
|
||||
To fully understand it's contents you're unfortunately going to need to read ca(1ssl),
|
||||
req(1ssl), x509(1ssl), config(5ssl), and x509v3_config(5ssl). Particularly
|
||||
important are the x509v3 extensions present in the certificate, which are
|
||||
defined in the "stglab_x509_ca_extensions" section of the config file.
|
||||
|
||||
The ca-cert script configures some important files in db/, then creates a
|
||||
certificate request and signs it. It also generates an initial (empty)
|
||||
revocation list, then substitutes the correct fingerprints into the html
|
||||
template for serving the CA certificate and CRL to the intranet.
|
||||
|
||||
2. Creating a certificate.
|
||||
|
||||
The create-cert script can generate three "types" of certificate -- server
|
||||
certificates for securing a service with SSL/TLS, client certificates for
|
||||
authenticating a client to these services, and user certificates for
|
||||
authentication, S/MIME e-mail signing or encryption, and code signing. There
|
||||
are minor but important differences in the extensions present in these
|
||||
different certificate types, but these are set in the *-ext.tpl files in tpl/
|
||||
and thus you shouldn't need to worry about them.
|
||||
|
||||
The create-cert script takes a number of arguments, of which the hostname or
|
||||
username and the type are mandatory. It is also a very good idea to supply a
|
||||
number of alternative DNS names when generating a server certificate, because
|
||||
while the script will happily append "stglab.manchester.uk.ibm.com" to an
|
||||
un-qualified host name, it won't append "transitives.com" and for the moment we
|
||||
probably need that.
|
||||
|
||||
You should also provide a team name for the organisational unit, e.g.
|
||||
"Manchester STG Lab Test", an e-mail address (preferably for the team rather
|
||||
than an individual for server/client certificates), and a comment that reflects
|
||||
the usage of the certificate, e.g. "Soak Infrastructure Live Server". Reasonable
|
||||
defaults are provided for all of these for our team's use.
|
||||
|
||||
3. Renewing a certificate.
|
||||
|
||||
The renew-cert script does some painful certificate manipulation that is not
|
||||
strictly necessary in most cases, and may in fact decrease SSL security
|
||||
slightly. This is done because the normal renewal process re-generates the
|
||||
certificate signing request and thus creates a new public/private keypair.
|
||||
If the certificates are used for S/MIME encryption or code signing, this
|
||||
renders all the encrypted e-mail unreadable and requires you to re-sign the
|
||||
code with your new private key. The code in renew-cert re-signs the old
|
||||
certificate request with a new expiry date and the extensions generated when
|
||||
the original certificate was created, and avoids this problem.
|
||||
|
||||
Renewing a certificate is done by giving the hostname, username or path to
|
||||
the certificate to renew-cert.sh.
|
||||
|
||||
4. Revoking a certificate.
|
||||
|
||||
Revoking a certificate is done by giving the hostname, username or path to
|
||||
the certificat to revoke-cert.sh. This script also regenerates a new CRL in
|
||||
both PEM and DER encodings (firefox prefers the latter while IE and other
|
||||
browsers work better with the former), and re-generates the html file with the
|
||||
new fingerprints.
|
||||
|
17
doc/ca-cert.txt
Normal file
17
doc/ca-cert.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
# a brief man-page for ca-cert.sh
|
||||
# $Id: ca-cert.txt 2660 2009-07-24 18:49:52Z alexeb $
|
||||
|
||||
NAME
|
||||
ca-cert.sh - generate a CA cert and perform initial db setup
|
||||
|
||||
SYNOPSIS
|
||||
ca-cert.sh
|
||||
|
||||
DESCRIPTION
|
||||
This script generates a CSR and signs it to turn it into a root
|
||||
certificate authority. It also sets up some important files in the CA
|
||||
database directory, generates an initial empty revocation list, and
|
||||
creates index.html from the template.
|
||||
|
||||
OPTIONS
|
||||
This script takes no options.
|
97
doc/create-cert.txt
Normal file
97
doc/create-cert.txt
Normal file
|
@ -0,0 +1,97 @@
|
|||
# a brief man-page for create-cert.sh
|
||||
# $Id: create-cert.txt 2660 2009-07-24 18:49:52Z alexeb $
|
||||
|
||||
NAME
|
||||
create-cert.sh - generate a signed X.509 certificate
|
||||
|
||||
SYNOPSIS
|
||||
create-cert.sh -t server [options] <hostname>
|
||||
create-cert.sh -t client [options] <hostname>
|
||||
create-cert.sh -t user [options] <username>
|
||||
|
||||
DESCRIPTION
|
||||
The create-cert.sh script creates the configuration files necessary
|
||||
for generating a signed X.509 certificate, creates a certificate
|
||||
signing request using these configuration files, and signs that request
|
||||
using the root CA key so that it is trusted by anything that has
|
||||
imported the CA certificate.
|
||||
|
||||
OPTIONS
|
||||
-h, --help
|
||||
Prints out a short synopsis of the arguments that this script takes.
|
||||
|
||||
-t, --type {server|client|user}
|
||||
This argument is mandatory. create-cert.sh can create three types of
|
||||
X.509 certificate: server, client, and user. These differ in the
|
||||
X.509v3 extensions present, and in the uses the certificate is trusted
|
||||
for.
|
||||
|
||||
Server certificates are used for securing SSL/TLS services, such as
|
||||
TLS-encrypted LDAP connections or SSL HTTP. In this case the <hostname>
|
||||
argument is used for the Common Name in the certificate, and any
|
||||
additional alternative names supplied by -n are added to the X.509v3
|
||||
"SubjectAltName" extension.
|
||||
|
||||
Client certificates are used for authenticating to SSL/TLS services.
|
||||
For the most part they will be used by automated systems to identify
|
||||
and authenticate to services they interact with.
|
||||
|
||||
User certificates are for individuals to authenticate themselves to
|
||||
SSL/TLS services in the same manner as client certificates, but they
|
||||
may also be used for S/MIME e-mail encryption and code signing.
|
||||
|
||||
-c, --comment "COMMENT"
|
||||
This argument sets the "Netscape Comment" X.509 extension.
|
||||
|
||||
-n, --alt-name HOSTNAME
|
||||
This argument adds an alternative hostname to the "SubjectAltName"
|
||||
X.509v3 extension. It may be supplied multiple times to add more than
|
||||
one additional hostname.
|
||||
|
||||
-l, --location LOCATION
|
||||
This argument sets the "Location" field of the certificate's
|
||||
distinguished name. Syggested values are "Maybrook House" and
|
||||
"Jackson House", but the field is freeform text.
|
||||
|
||||
-o, --org-unit TEAMNAME
|
||||
This argument sets the "Organisational Unit" field of the certificate's
|
||||
distinguished name. Ideally this should begin with "Manchester STG Lab"
|
||||
for consistency's sake, for example:
|
||||
|
||||
Manchester STG Lab Systems and Network Infrastructure
|
||||
Manchester STG Lab Testing
|
||||
Manchester STG Lab Starlight Development
|
||||
|
||||
-e, --email EMAIL
|
||||
This argument sets the "E-Mail Address" field of the certificate's
|
||||
distinguished name. As per current X.509 standards this is actually
|
||||
removed from the DN of the CSR and placed into the "SubjectAltName"
|
||||
extension in the signed certificate. In general it should be a team
|
||||
alias rather than an individual's address for server and client certs.
|
||||
|
||||
-r, --csr-only
|
||||
This argument causes create-cert.sh to only generate a new CSR. It will
|
||||
not generate the request configuration files in cfg/ unless --tpl-only
|
||||
is also passed; in this case it will just create the configuration
|
||||
files instead. This allows you to re-generate a CSR after manually
|
||||
tweaking the configuration files.
|
||||
|
||||
-s, --crt-only
|
||||
This argument causes create-cert.sh to only sign an existing CSR. As
|
||||
with --csr-only, it will not generate extension configuration files
|
||||
unless --tpl-only is also passed; again in this case it will just
|
||||
create the configuration files so that you can re-sign the same CSR
|
||||
with new extensions.
|
||||
|
||||
-t, --tpl-only
|
||||
This argument modifies the behaviour of the previous two options when
|
||||
passed with them, as described above. On it's own it causes
|
||||
create-cert.sh to generate both sets of configuration files, but
|
||||
not generate either the signing request or the signed certificate.
|
||||
|
||||
DEFAULTS
|
||||
* The LOCATION defaults to "Maybrook House"
|
||||
* The TEAM defaults to "Manchester STG Lab Systems and Network Infrastructure"
|
||||
* The EMAIL defaults to "mcr_lab_lsni@wwpdl.vnet.ibm.com"
|
||||
* There is no COMMENT set by default
|
||||
|
17
doc/create-p12.txt
Normal file
17
doc/create-p12.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
# a brief man-page for create-p12.sh
|
||||
# $Id: create-p12.txt 2660 2009-07-24 18:49:52Z alexeb $
|
||||
|
||||
NAME
|
||||
create-p12.sh - create a PKCS#12 archive of a certificate and key
|
||||
|
||||
SYNOPSIS
|
||||
create-p12.sh /path/to/certificate
|
||||
create-p12.sh <username>
|
||||
|
||||
DESCRIPTION
|
||||
This script exports a PKCS#12 archive containing a user's certificate,
|
||||
private key, and the CA certificate. It will prompt for a password to
|
||||
lock the archive with, and then place it in p12/.
|
||||
|
||||
OPTIONS
|
||||
This script takes no options.
|
20
doc/renew-cert.txt
Normal file
20
doc/renew-cert.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
# a brief man-page for renew-cert.sh
|
||||
# $Id: renew-cert.txt 2660 2009-07-24 18:49:52Z alexeb $
|
||||
|
||||
NAME
|
||||
renew-cert.sh - renew a previously generated cert for another year
|
||||
|
||||
SYNOPSIS
|
||||
renew-cert.sh /path/to/certificate
|
||||
renew-cert.sh <hostname>
|
||||
renew-cert.sh <username>
|
||||
|
||||
DESCRIPTION
|
||||
This script renews a certificate for another 365 days from it's current
|
||||
end-date. It does some interesting hackery to re-sign the certificate
|
||||
request generated when the certificate was initially signed, using the
|
||||
same key-pair and the same serial, so that S/MIME encrypted e-mail and
|
||||
previously signed code does not become unusable.
|
||||
|
||||
OPTIONS
|
||||
This script takes no options.
|
18
doc/revoke-cert.txt
Normal file
18
doc/revoke-cert.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
# a brief man-page for revoke-cert.sh
|
||||
# $Id: revoke-cert.txt 2660 2009-07-24 18:49:52Z alexeb $
|
||||
|
||||
NAME
|
||||
revoke-cert.sh - revoke a certificate and generate revocation list
|
||||
|
||||
SYNOPSIS
|
||||
revoke-cert.sh /path/to/certificate
|
||||
revoke-cert.sh <hostname>
|
||||
revoke-cert.sh <username>
|
||||
|
||||
DESCRIPTION
|
||||
This script revokes the provided certificate and updates the revocation
|
||||
list. It generates both a PEM and a DER encoded version of the CRL for
|
||||
different browsers, and updates the html page with the new fingerprints.
|
||||
|
||||
OPTIONS
|
||||
This script takes no options.
|
198
lib/ca-functions
Normal file
198
lib/ca-functions
Normal file
|
@ -0,0 +1,198 @@
|
|||
#! /bin/bash
|
||||
# common functions for ca-scripts
|
||||
|
||||
PROGNAME=$( basename $0 )
|
||||
CONFFILE="/etc/ca-scripts.conf"
|
||||
SHAREDIR="/home/alex/code/ca-scripts/tpl"
|
||||
CRYPTKEY="-nodes"
|
||||
|
||||
INDEXTPL="index-html"
|
||||
INDEXOUT=""
|
||||
|
||||
error() {
|
||||
usage >&2
|
||||
echo -e "ERROR: $1\n" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
ca_check_var() {
|
||||
local varname vartest
|
||||
|
||||
varname="$1"
|
||||
vartest="$2"
|
||||
eval "if [ ! $vartest \"\$$varname\" ]; then
|
||||
echo '$varname value \"\$$varname\" failed \"$vartest\" test'
|
||||
fi"
|
||||
}
|
||||
|
||||
ca_set_default() {
|
||||
local varname vardef
|
||||
|
||||
varname="$1"
|
||||
vardef="$2"
|
||||
eval "if [ -z \"\$$varname\" ]; then
|
||||
$varname=\"$vardef\";
|
||||
fi"
|
||||
}
|
||||
|
||||
ca_load_conf() {
|
||||
local varname vartest varerr vardef error ca_name
|
||||
if [ ! -r "$CONFFILE" ]; then
|
||||
error "Unable to find $CONFFILE."
|
||||
fi
|
||||
# XXX: seems like . <file> doesn't work if it's not relative to a directory
|
||||
# look this up on the internet sometime to work out why...
|
||||
if [ "$CONFFILE" = "$( basename $CONFFILE )" ]; then
|
||||
CONFFILE="./$CONFFILE"
|
||||
fi
|
||||
. "$CONFFILE"
|
||||
|
||||
error=""
|
||||
while read vartest varname; do
|
||||
varerr=$( ca_check_var "$varname" "$vartest" )
|
||||
if [ -n "$varerr" ]; then
|
||||
error="$error\n $varerr"
|
||||
fi
|
||||
done <<__TESTS__
|
||||
-d CA_HOME
|
||||
-n CA_DOMAIN
|
||||
-n CA_DN_C
|
||||
-n CA_DN_ST
|
||||
-n CA_DN_L
|
||||
-n CA_DN_O
|
||||
-n CA_DN_OU
|
||||
-n CA_DN_CN
|
||||
__TESTS__
|
||||
if [ -n "$error" ]; then
|
||||
error "Parsing config file $CONFFILE failed:\n$error"
|
||||
fi
|
||||
|
||||
case "$CA_CRT_TYPE" in
|
||||
server|client|user|ca) :;;
|
||||
'') error "The type option is mandatory!";;
|
||||
*) error "Unrecognised type '$CA_CRT_TYPE'!";;
|
||||
esac
|
||||
|
||||
# we need to do these first to use them in other default defs
|
||||
# NOTE: bash's here-string syntax appends \n which tr turns to _ :(
|
||||
ca_set_default CA_NAME "$( echo -n "$CA_DOMAIN" | tr -c '[:alnum:]@-' _ )"
|
||||
ca_set_default CA_EMAIL "ca@$CA_DOMAIN"
|
||||
|
||||
while read varname vardef; do
|
||||
ca_set_default "$varname" "$vardef"
|
||||
done <<__DEFAULTS__
|
||||
CA_DESC $CA_DN_CN
|
||||
CA_CRT_URI http://$CA_DOMAIN/ca/$CA_NAME.ca.crt
|
||||
CA_CRL_URI http://$CA_DOMAIN/ca/$CA_NAME.ca.crl
|
||||
CA_PATHLEN 0
|
||||
CA_CRT_C $CA_DN_C
|
||||
CA_CRT_ST $CA_DN_ST
|
||||
CA_CRT_L $CA_DN_L
|
||||
CA_CRT_O $CA_DN_O
|
||||
CA_CRT_OU $CA_DN_OU
|
||||
CA_CRT_E $CA_EMAIL
|
||||
__DEFAULTS__
|
||||
}
|
||||
|
||||
ca_sed_cmd() {
|
||||
# MD5 in CA_CR[TL]_MD5_FP has a non alphabetic character :(
|
||||
# XXX: pretty sure this is a dirty and wrong way of templating vars
|
||||
set | awk -F\= '/^CA_[A-Z5_]*=/{print $1}' | while read ca_var; do
|
||||
echo "s#%$ca_var%#${!ca_var}#;"
|
||||
done
|
||||
}
|
||||
|
||||
ca_template() {
|
||||
local template dest
|
||||
|
||||
if [ -r "$1" ]; then
|
||||
template="$1"
|
||||
elif [ -r "$SHAREDIR/$1.tpl" ]; then
|
||||
template="$SHAREDIR/$1.tpl"
|
||||
else
|
||||
error "Could not read from template $1"
|
||||
fi
|
||||
dest="$2"
|
||||
|
||||
sed -e "$(ca_sed_cmd)" <"$template" >"$dest"
|
||||
}
|
||||
|
||||
ca_gen_crl() {
|
||||
openssl ca -config "$CA_HOME/cnf/$CA_NAME.ca.cnf" \
|
||||
-gencrl -out "$CA_HOME/crl/$CA_NAME.ca.crl" -md sha1
|
||||
openssl crl -in "$CA_HOME/crl/$CA_NAME.ca.crl" \
|
||||
-out "$CA_HOME/crl/$CA_NAME.ca.crl.der" -outform DER
|
||||
}
|
||||
|
||||
ca_gen_p12() {
|
||||
local cnf_name
|
||||
cnf_name="$1"
|
||||
openssl pkcs12 -export -descert -out $CA_HOME/p12/$cnf_name.p12 \
|
||||
-in $CA_HOME/crt/$cnf_name.crt \
|
||||
-inkey $CA_HOME/key/$cnf_name.key \
|
||||
-certfile $CA_HOME/crt/$CA_NAME.ca.crt
|
||||
}
|
||||
|
||||
ca_checksum() {
|
||||
CA_CRT_MD5_FP="$( openssl x509 -in $CA_HOME/crt/$CA_NAME.ca.crt \
|
||||
-noout -md5 -fingerprint | cut -d= -f2 )"
|
||||
CA_CRT_SHA_FP="$( openssl x509 -in $CA_HOME/crt/$CA_NAME.ca.crt \
|
||||
-noout -sha1 -fingerprint | cut -d= -f2 )"
|
||||
CA_CRL_MD5_FP="$( openssl crl -in $CA_HOME/crl/$CA_NAME.ca.crl \
|
||||
-noout -md5 -fingerprint | cut -d= -f2 )"
|
||||
CA_CRL_SHA_FP="$( openssl crl -in $CA_HOME/crl/$CA_NAME.ca.crl \
|
||||
-noout -sha1 -fingerprint | cut -d= -f2 )"
|
||||
}
|
||||
|
||||
ca_cnf_name() {
|
||||
local crt
|
||||
crt="$1"
|
||||
# work out what configuration files we should be using from the cert's CN
|
||||
echo $( openssl x509 -in "$crt" -noout -nameopt sep_multiline,use_quote \
|
||||
-subject | grep "CN=" | cut -d= -f2 | tr -c '[:alnum:]@-' _ )
|
||||
}
|
||||
|
||||
ca_find_cnf() {
|
||||
local name _name
|
||||
name="$1"
|
||||
|
||||
if [ -f "$name" ]; then
|
||||
if ! grep -q "$CA_CRT_TYPE" <<<"$name"; then
|
||||
error "Certificate '$name' does not appear to be of type '$CA_CRT_TYPE'"
|
||||
else
|
||||
echo "$(ca_cnf_name $name).$CA_CRT_TYPE"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
_name=$( echo -n "$name" | tr -c '[:alnum:]@-' _ )
|
||||
if [ "$CA_CRT_TYPE" = "user" ]; then
|
||||
# user names may have dots etc. in, so use munged version in match
|
||||
# check if name is "user@domain", append $CA_DOMAIN if not
|
||||
if [ "${_name%%@*}" = "$_name" \
|
||||
-a -f "$CA_HOME/crt/${_name}@$CA_NAME.$CA_CRT_TYPE.crt" ];
|
||||
then
|
||||
# name is not fully-qualified, but a cert exists for it
|
||||
echo "${_name}@$CA_NAME.$CA_CRT_TYPE"
|
||||
elif [ -f "$CA_HOME/crt/$_name.$CA_CRT_TYPE.crt" ]; then
|
||||
# name was fully-qualified and a cert exists
|
||||
echo "$_name.$CA_CRT_TYPE"
|
||||
else
|
||||
error "Could not find $CA_CRT_TYPE certificate configuration matching '$name'"
|
||||
fi
|
||||
else
|
||||
# check if name is fully-qualified -- contains more than 1 dot
|
||||
# NOTE: we have to do this test with the unmunged name ...
|
||||
if [ "${name%%.*}" = "$name" \
|
||||
-a -f "$CA_HOME/crt/${_name}_$CA_NAME.$CA_CRT_TYPE.crt" ];
|
||||
then
|
||||
# name is not fully-qualified, but a cert exists for it
|
||||
echo "${_name}_$CA_NAME.$CA_CRT_TYPE"
|
||||
elif [ -f "$CA_HOME/crt/$_name.$CA_CRT_TYPE.crt" ]; then
|
||||
# name was fully-qualified and a cert exists
|
||||
echo "$_name.$CA_CRT_TYPE"
|
||||
else
|
||||
error "Could not find $CA_CRT_TYPE certificate configuration matching '$name'"
|
||||
fi
|
||||
fi
|
||||
}
|
160
tpl/ca-config.tpl
Normal file
160
tpl/ca-config.tpl
Normal file
|
@ -0,0 +1,160 @@
|
|||
# CA configuration file template
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the CA configuration to use
|
||||
[ ca ]
|
||||
default_ca = ca_scripts
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines our CA configuration
|
||||
[ ca_scripts ]
|
||||
# interpolation variables defining the directories to use
|
||||
dir = %CA_HOME% # root data directory of CA
|
||||
db_dir = $dir/db # database files are kept here
|
||||
csr_dir = $dir/csr # generated CSRs are kept here
|
||||
crt_dir = $dir/crt # signed CRTs are kept here
|
||||
key_dir = $dir/key # generated KEYs are kept here
|
||||
crl_dir = $dir/crl # generated CRL is kept here
|
||||
new_certs_dir = $dir/idx # default place for new CRTs
|
||||
|
||||
# required settings
|
||||
database = $db_dir/index.txt # database index file
|
||||
serial = $db_dir/serial # serial number index file
|
||||
certificate = $crt_dir/%CA_NAME%.ca.crt # CA certificate
|
||||
private_key = $key_dir/%CA_NAME%.ca.key # CA private key
|
||||
crl = $crl_dir/%CA_NAME%.ca.crl # current CRL
|
||||
RANDFILE = $db_dir/.rand # private random number file
|
||||
|
||||
# these two CA directives can be commented out so that v1 CRLs are created
|
||||
crlnumber = $db_dir/crlnumber # crlnumber index file
|
||||
crl_extensions = ca_crl_extensions # extensions in v2 CRL
|
||||
|
||||
# x509v3 certificate extensions and certificate signing policy
|
||||
x509_extensions = ca_x509_default_extensions
|
||||
copy_extensions = copy # copy extensions from CSR to CRT
|
||||
policy = ca_extension_policy # policy on required CSR attributes
|
||||
|
||||
# leave these defaults
|
||||
name_opt = oneline # Subject Name options - x509(1)
|
||||
cert_opt = ca_default # Certificate field options - x509(1)
|
||||
default_days = 365 # how long to certify for
|
||||
default_crl_days= 365 # how long before next CRL
|
||||
default_md = sha1 # which md to use.
|
||||
preserve = no # keep passed DN ordering
|
||||
unique_subject = no # recommended
|
||||
email_in_dn = no # remove email from CSR DN when signing
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the CA's policy on required CSR attributes.
|
||||
# It requires:
|
||||
# the country [C] to be supplied in the CSR and match the CA
|
||||
# the state or province [ST] to be supplied in the CSR
|
||||
# the locality [L] to be supplied in the CSR
|
||||
# the organisation name [O] to be supplied in the CSR and match the CA
|
||||
# the organisational unit [OU] to be supplied in the CSR
|
||||
# the server common name [CN] to be supplied in the CSR
|
||||
# ... and an [emailAddress] may optionally be supplied in the CSR
|
||||
# XXX: is this too restrictive or not restrictive enough?
|
||||
# should options for ca-create-cert to change "match" values even exist?
|
||||
[ ca_extension_policy ]
|
||||
countryName = match
|
||||
stateOrProvinceName = supplied
|
||||
localityName = supplied
|
||||
organizationName = match
|
||||
organizationalUnitName = supplied
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the default x509 extensions present in a cert signed by the CA.
|
||||
# These should be replaced by a specific set of extensions per certificate.
|
||||
[ ca_x509_default_extensions ]
|
||||
|
||||
# certificates signed by this CA by default are not CA certificates themselves
|
||||
basicConstraints = CA:FALSE
|
||||
|
||||
# old netscape certificate attributes
|
||||
nsCertType = server
|
||||
nsComment = "%CA_DESC% Certificate"
|
||||
nsRevocationUrl = %CA_CRL_URI%
|
||||
|
||||
# key usage restrictions
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
|
||||
extendedKeyUsage = serverAuth
|
||||
|
||||
issuerAltName = issuer:copy
|
||||
subjectAltName = URI:%CA_CRT_URI%
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
authorityInfoAccess = caIssuers;URI:%CA_CRT_URI%
|
||||
crlDistributionPoints = URI:%CA_CRL_URI%
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the x509 extensions present in the generated CA certificate.
|
||||
[ ca_x509_extensions ]
|
||||
|
||||
# this certificate is authoritative and allowed to sign other certificates
|
||||
# pathlen=1 implies there may be up to one intermediate CA in the chain
|
||||
# that leads to this root CA certificate.
|
||||
basicConstraints = critical,CA:TRUE,pathlen:%CA_PATHLEN%
|
||||
|
||||
# old netscape certificate attributes
|
||||
nsCertType = objsign, sslCA, emailCA, objCA
|
||||
nsComment = "%CA_DESC%"
|
||||
nsRevocationUrl = %CA_CRL_URI%
|
||||
nsCaRevocationUrl = %CA_CRL_URI%
|
||||
|
||||
# key usage restrictions
|
||||
keyUsage = critical, cRLSign, keyCertSign
|
||||
extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection, timeStamping
|
||||
|
||||
issuerAltName = @ca_altname
|
||||
subjectAltName = @ca_altname
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
authorityInfoAccess = caIssuers;URI:%CA_CRT_URI%
|
||||
crlDistributionPoints = URI:%CA_CRL_URI%
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This is a separate section defining the attributes in the CA's subjectAltName.
|
||||
[ ca_altname ]
|
||||
URI=%CA_CRT_URI%
|
||||
DNS.1=%CA_DOMAIN%
|
||||
DNS.2=*.%CA_DOMAIN%
|
||||
email=%CA_EMAIL%
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the extensions present in the CRLs generated by this CA.
|
||||
[ ca_crl_extensions ]
|
||||
issuerAltName = issuer:copy
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
# the below is only supported in the very latest releases of openssl
|
||||
# issuingDistributionPoint= URI:%CA_CRL_URI%
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the extensions present in the CSRs created by this CA.
|
||||
[ ca_req_extensions ]
|
||||
basicConstraints = critical, CA:FALSE
|
||||
keyUsage = critical, nonRepudiation, keyEncipherment, keyAgreement
|
||||
extendedKeyUsage = serverAuth
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines default settings for certificate requests and CA cert creation.
|
||||
[ req ]
|
||||
default_bits = 2048
|
||||
default_md = sha1
|
||||
distinguished_name = ca_req_dn
|
||||
x509_extensions = ca_x509_extensions
|
||||
req_extensions = ca_req_extensions
|
||||
string_mask = nombstr
|
||||
prompt = no
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# This defines the DN of the CA certificate.
|
||||
[ ca_req_dn ]
|
||||
C = %CA_DN_C%
|
||||
ST = %CA_DN_ST%
|
||||
L = %CA_DN_L%
|
||||
O = %CA_DN_O%
|
||||
OU = %CA_DN_OU%
|
||||
CN = %CA_DN_CN%
|
17
tpl/client-ext.tpl
Normal file
17
tpl/client-ext.tpl
Normal file
|
@ -0,0 +1,17 @@
|
|||
basicConstraints = critical, CA:FALSE
|
||||
nsCertType = client
|
||||
nsRevocationUrl = %CA_CRL_URI%
|
||||
%CA_CRT_COMMENT%
|
||||
keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature
|
||||
extendedKeyUsage = clientAuth, timeStamping
|
||||
|
||||
issuerAltName = issuer:copy
|
||||
subjectAltName = @client_altname
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
authorityInfoAccess = caIssuers;URI:%CA_CRT_URI%
|
||||
crlDistributionPoints = URI:%CA_CRL_URI%
|
||||
|
||||
[ client_altname ]
|
||||
URI=%CA_CRT_URI%
|
||||
email=move
|
27
tpl/index-html.tpl
Normal file
27
tpl/index-html.tpl
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<HTML>
|
||||
<HEAD><TITLE>%CA_DESC%</TITLE>
|
||||
<STYLE>
|
||||
BODY { font-family: arial,sans-serif; }
|
||||
H1 { font-size: xx-large; margin-left: 50px; }
|
||||
H3 { font-size: large; margin-top: 50px; margin-left: 50px; }
|
||||
IMG { border: 0; }
|
||||
P { width: 700px; margin-left: 100px; }
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<H1>%CA_DESC%</H1>
|
||||
<H3>CA Certificate</H3>
|
||||
<P>The CA certificate can be found
|
||||
<A href="%CA_CRT_URI%">here</A></P>
|
||||
<P>MD5 Fingerprint: %CA_CRT_MD5_FP%</P>
|
||||
<P>SHA1 Fingerprint: %CA_CRT_SHA_FP%</P>
|
||||
<H3>Certificate Revocation List</H3>
|
||||
<P>The certificate revocation list can be found
|
||||
<A href="%CA_CRL_URI%.der">here</A> (DER encoded)
|
||||
or <A href="%CA_CRL_URI%">here</A> (PEM encoded)</P>
|
||||
<P>MD5 Fingerprint: %CA_CRL_MD5_FP%</P>
|
||||
<P>SHA1 Fingerprint: %CA_CRL_SHA_FP%</P>
|
||||
</BODY>
|
||||
</HTML>
|
32
tpl/req-config.tpl
Normal file
32
tpl/req-config.tpl
Normal file
|
@ -0,0 +1,32 @@
|
|||
[ req ]
|
||||
default_bits = 2048
|
||||
default_md = sha1
|
||||
distinguished_name = req_dn
|
||||
req_extensions = req_%CA_CRT_TYPE%_extensions
|
||||
string_mask = nombstr
|
||||
prompt = no
|
||||
|
||||
[ req_dn ]
|
||||
C = %CA_CRT_C%
|
||||
ST = %CA_CRT_ST%
|
||||
L = %CA_CRT_L%
|
||||
O = %CA_CRT_O%
|
||||
OU = %CA_CRT_OU%
|
||||
CN = %CA_CRT_CN%
|
||||
emailAddress = %CA_CRT_E%
|
||||
|
||||
[ req_server_extensions ]
|
||||
basicConstraints = critical, CA:FALSE
|
||||
keyUsage = critical, keyEncipherment, keyAgreement
|
||||
extendedKeyUsage = serverAuth
|
||||
|
||||
[ req_client_extensions ]
|
||||
basicConstraints = critical, CA:FALSE
|
||||
keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature
|
||||
extendedKeyUsage = clientAuth, timeStamping
|
||||
|
||||
[ req_user_extensions ]
|
||||
basicConstraints = critical, CA:FALSE
|
||||
keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature, nonRepudiation, dataEncipherment
|
||||
extendedKeyUsage = clientAuth, codeSigning, emailProtection
|
||||
|
19
tpl/server-ext.tpl
Normal file
19
tpl/server-ext.tpl
Normal file
|
@ -0,0 +1,19 @@
|
|||
basicConstraints = critical, CA:FALSE
|
||||
nsCertType = server
|
||||
nsRevocationUrl = %CA_CRL_URI%
|
||||
%CA_CRT_COMMENT%
|
||||
keyUsage = critical, keyEncipherment, keyAgreement
|
||||
extendedKeyUsage = serverAuth
|
||||
|
||||
issuerAltName = issuer:copy
|
||||
subjectAltName = @server_altname
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
authorityInfoAccess = caIssuers;URI:%CA_CRT_URI%
|
||||
crlDistributionPoints = URI:%CA_CRL_URI%
|
||||
|
||||
[ server_altname ]
|
||||
URI=%CA_CRT_URI%
|
||||
email=move
|
||||
%CA_CRT_ALT_NAMES%
|
||||
|
18
tpl/user-ext.tpl
Normal file
18
tpl/user-ext.tpl
Normal file
|
@ -0,0 +1,18 @@
|
|||
basicConstraints = critical, CA:FALSE
|
||||
nsCertType = client, objsign, email
|
||||
nsRevocationUrl = %CA_CRL_URI%
|
||||
%CA_CRT_COMMENT%
|
||||
keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature, nonRepudiation, dataEncipherment
|
||||
extendedKeyUsage = clientAuth, codeSigning, emailProtection
|
||||
|
||||
issuerAltName = issuer:copy
|
||||
subjectAltName = @user_altname
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
authorityInfoAccess = caIssuers;URI:%CA_CRT_URI%
|
||||
crlDistributionPoints = URI:%CA_CRL_URI%
|
||||
|
||||
[ user_altname ]
|
||||
URI=%CA_CRT_URI%
|
||||
email=move
|
||||
|
3
vims
Normal file
3
vims
Normal file
|
@ -0,0 +1,3 @@
|
|||
gvim -p bin/* lib/*
|
||||
gvim -p ca-scripts.conf tpl/*
|
||||
gvim -p doc/*
|
Loading…
Reference in a new issue