You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
7.9 KiB
218 lines
7.9 KiB
#!/bin/sh |
|
## |
|
## x509-util.sh -- X.509 Certificate Generation Utility |
|
## Copyright (c) 2007-2014 Ralf S. Engelschall <rse@engelschall.com> |
|
## |
|
## This program is free software; you can redistribute it and/or modify |
|
## it under the terms of the GNU General Public License as published by |
|
## the Free Software Foundation; either version 2 of the License, or |
|
## (at your option) any later version. |
|
## |
|
## This program is distributed in the hope that it will be useful, |
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
## General Public License for more details. |
|
## |
|
## You should have received a copy of the GNU General Public License |
|
## along with this program; if not, write to the Free Software |
|
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>. |
|
## |
|
|
|
# sane run-time environment |
|
umask 022 |
|
|
|
# parameter defaults |
|
prefix="@l_prefix@" |
|
tag="snakeoil" |
|
password="snakeoil" |
|
domain="snakeoil.invalid" |
|
organization="Snakeoil Corporation" |
|
lifetime="3650" |
|
num_server="2" |
|
num_client="4" |
|
num_object="4" |
|
tmpdir="${TMPDIR-/tmp}" |
|
outdir="`pwd`" |
|
|
|
# parse command line options |
|
while [ $# -gt 0 ]; do |
|
case "$1" in |
|
--prefix=* ) prefix=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--tag=* ) tag=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--password=* ) password=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--domain=* ) domain=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--organization=* ) organization=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--lifetime=* ) lifetime=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--num-server=* ) num_server=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--num-client=* ) num_client=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--num-object=* ) num_object=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--tmpdir=* ) tmpdir=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--outdir=* ) outdir=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;; |
|
--help ) |
|
echo "Usage: x509-util [--prefix=<prefix>] [--tag=<tag>] [--password=<password>]" |
|
echo " [--domain=<domain>] [--organization=<organization>] [--lifetime=<lifetime>]" |
|
echo " [--num-server=<num-server>] [--num-client=<num-client>] [--num-object=<num-object>]" |
|
echo " [--tmpdir=<tmpdir>] [--outdir=<outdir>] [--help]" |
|
exit 0 |
|
;; |
|
* ) |
|
break |
|
;; |
|
esac |
|
done |
|
|
|
# display information about parameters |
|
echo "++ generating X.509 certificate/key set with configuration:" |
|
echo "-- OpenPKG prefix (--prefix): $prefix" |
|
echo "-- Short-hand tag (--tag): $tag" |
|
echo "-- Encryption Password (--password): $password" |
|
echo "-- DNS Domain (--domain): $domain" |
|
echo "-- Organization Name (--organization): $organization" |
|
echo "-- Certificate Lifetimes (--lifetime): $lifetime" |
|
echo "-- Number of Server Certificates (--num-server): $num_server" |
|
echo "-- Number of Client Certificates (--num-client): $num_client" |
|
echo "-- Number of Object Certificates (--num-object): $num_object" |
|
echo "-- Temporary Directory (--tmpdir): $tmpdir" |
|
echo "-- Output Directory (--outdir): $outdir" |
|
|
|
# sanity check environment |
|
if [ ! -x "$prefix/bin/shtool" ]; then |
|
echo "ERROR: $prefix/bin/shtool (OpenPKG \"shtool\" package) required" 1>&2 |
|
exit 1 |
|
fi |
|
if [ ! -x "$prefix/bin/csp" ]; then |
|
echo "ERROR: $prefix/bin/csp (OpenPKG \"csp\" package) required" 1>&2 |
|
exit 1 |
|
fi |
|
if [ ! -x "$prefix/bin/perl" ]; then |
|
echo "ERROR: $prefix/bin/perl (OpenPKG \"perl\" package) required" 1>&2 |
|
exit 1 |
|
fi |
|
|
|
# ensure out directory exists |
|
test -d $outdir || mkdir $outdir 2>/dev/null || true |
|
|
|
# create temporary location |
|
echo "++ creating temporary location" |
|
if [ ! -d $tmpdir ]; then |
|
echo "$0: ERROR: temporary directory not existing: $tmpdir" 1>&2 |
|
exit 1 |
|
fi |
|
tmpdir="$tmpdir/x509-util.$$.tmp" |
|
test -d $tmpdir && rm -rf $tmpdir >/dev/null 2>&1 || true |
|
mkdir $tmpdir || exit $? |
|
cd $tmpdir || exit $? |
|
|
|
# display processing information |
|
echo "++ creating CSP environment" |
|
|
|
# create CSP environment |
|
rm -rf etc csp |
|
ln -s $prefix/etc/csp etc |
|
mkdir csp |
|
$prefix/bin/csp $tag create |
|
|
|
# optionally adjust configuration |
|
$prefix/bin/shtool subst -q \ |
|
-e "s;example\\.com;$domain;g" \ |
|
csp/$tag/extensions.conf |
|
rm -f csp/$tag/extensions.conf.orig |
|
|
|
# display processing information |
|
echo "++ generate CA private key and certificate" |
|
|
|
# generate CA private key and certificate |
|
$prefix/bin/csp $tag init \ |
|
--keysize=4096 --keypass="$password" --type=ca --days=$lifetime \ |
|
"CN=Certificate Authority (CA), OU=Certification Department, O=$organization" |
|
idx=0 |
|
|
|
# make all files available under common path |
|
echo "-- $tag-ca.key.pem" |
|
cp csp/$tag/private/ca.key $outdir/$tag-ca.key.pem |
|
echo "-- $tag-ca.crt.pem" |
|
cp csp/$tag/ca.crt $outdir/$tag-ca.crt.pem |
|
|
|
# provide textual presentations |
|
echo "-- $tag-ca.key.txt" |
|
$prefix/bin/openssl rsa \ |
|
-in $outdir/$tag-ca.key.pem -passin "pass:$password" \ |
|
-noout -text \ |
|
>$outdir/$tag-ca.key.txt |
|
echo "-- $tag-ca.crt.txt" |
|
$prefix/bin/openssl x509 \ |
|
-in $outdir/$tag-ca.crt.pem \ |
|
-noout -text \ |
|
>$outdir/$tag-ca.crt.txt |
|
|
|
# generate regular private keys and certificates |
|
for type in server client object; do |
|
eval "max=\$num_$type" |
|
i=1 |
|
while [ $i -le $max ]; do |
|
# determine name |
|
name="$type" |
|
if [ $max -gt 1 ]; then |
|
name="$name$i" |
|
fi |
|
i=`expr $i + 1` |
|
|
|
echo "++ generate $type private key and certificate" |
|
|
|
# generate private key and certificate request |
|
echo "-- $tag-$name.key.pem" |
|
department=`$prefix/bin/perl -e 'printf("%s%s", uc(substr($ARGV[0], 0, 1)), substr($ARGV[0], 1));' $type` |
|
keysize=1024 |
|
if [ ".$type" = .server ]; then |
|
keysize=2048 |
|
fi |
|
$prefix/bin/csp $tag request \ |
|
--csrfile=$outdir/$tag-$name.csr.pem \ |
|
--keyfile=$outdir/$tag-$name.key.pem \ |
|
--keysize=$keysize --keypass="$password" \ |
|
"CN=$name.$domain, OU=$department, O=$organization" |
|
|
|
# generate server certificate |
|
echo "-- $tag-$name.crt.pem" |
|
echo "y" | $prefix/bin/csp $tag sign \ |
|
--csrfile=$outdir/$tag-$name.csr.pem \ |
|
--type=$type --days=$lifetime --capass="$password" >/dev/null |
|
|
|
# cleanup by removing certificate request |
|
rm -f $outdir/$tag-$name.csr.pem |
|
|
|
# make all files available under common path |
|
idx=`expr $idx + 1` |
|
cp csp/$tag/certs/`echo . | awk '{ printf("%02X", idx); }' idx=$idx`.pem \ |
|
$outdir/$tag-$name.crt.pem |
|
|
|
# provide textual presentations |
|
echo "-- $tag-$name.key.txt" |
|
$prefix/bin/openssl rsa \ |
|
-in $outdir/$tag-$name.key.pem -passin "pass:$password" \ |
|
-noout -text \ |
|
>$outdir/$tag-$name.key.txt |
|
echo "-- $tag-$name.crt.txt" |
|
$prefix/bin/openssl x509 \ |
|
-in $outdir/$tag-$name.crt.pem \ |
|
-noout -text \ |
|
>$outdir/$tag-$name.crt.txt |
|
|
|
# make server private key insecure but necessarily unprotected |
|
# for unattended use by a server daemon |
|
if [ ".$type" = .server ]; then |
|
$prefix/bin/openssl rsa \ |
|
-in $outdir/$tag-$name.key.pem -passin "pass:$password" \ |
|
-out $outdir/$tag-$name.key.pem.new 2>/dev/null |
|
mv $outdir/$tag-$name.key.pem.new \ |
|
$outdir/$tag-$name.key.pem |
|
fi |
|
done |
|
done |
|
|
|
# cleanup |
|
echo "++ deleting temporary location" |
|
cd / || exit $? |
|
rm -rf $tmpdir >/dev/null 2>&1 || true |
|
|
|
|