~poptart/hosaka-pki

d9b43ad4c3f19938d5ca98e8ee768545e5ac6e04 — terrorbyte 1 year, 11 months ago c88889c
add more core functions and start cleaning up the structure
5 files changed, 142 insertions(+), 22 deletions(-)

M .gitignore
M Makefile
M config.def
M hosaka-pki.sh
A tmpl/openssl.cnf.tmpl
M .gitignore => .gitignore +1 -0
@@ 4,3 4,4 @@ private/
certs/
*.pem
config
*.old

M Makefile => Makefile +6 -5
@@ 1,6 1,6 @@
include config.mk

all: check
all: check config

check:
	shellcheck -a -x -s sh ./hosaka-pki.sh


@@ 12,19 12,20 @@ config:
		< config.def > config

install:
	@printf "installing hosaka-pki"
	@printf "installing hosaka-pki\\n"
	@mkdir -p "${CONFIGDIR}" "${CONFIGDIR}/ssl" \
		"${CONFIGDIR}/ssh" "${CONFIGDIR}/util"
	@chown 0700 "${CONFIGDIR}/ssl" "${CONFIGDIR}/ssh"
	@cp -f config "${CONFIGDIR}/config"
	@cp -f openssl.cnf.tmpl "${CONFIGDIR}/openssl.cnf.tmpl"
	@cp -f openssl.cnf.tmpl "${CONFIGDIR}/util/openssl.cnf.tmpl"
	@sed -e "s%{{CONFIGDIR}}%${CONFIGDIR}%g" \
		< hosaka-pki.sh > ${PREFIX}/bin/hosaka-pki
	@chown 755 ${PREFIX}/bin/hosaka-pki
	@chmod 755 ${PREFIX}/bin/hosaka-pki
	@printf "hosaka-pki installed into: ${CONFIGDIR}\\n"

clean:
	@printf "cleaning"
	@printf "cleaning\\n"
	@rm -f config

.PHONY:
	all clean install check

M config.def => config.def +5 -4
@@ 1,16 1,17 @@
#This is the hosaka-pki configuration file. It is parsed by the PKI shell 
#script and functions a KEY=VALUE pair set of settings.
#
CONFIGDIR="/etc/hosaka/pki"
SSL_CA_DIR="/etc/hosaka/pki/ssl"
SSH_CA_DIR="/etc/ssh/pki/ssh"
CONFIGDIR=/etc/hosaka/pki
SSL_CA_DIR=/etc/hosaka/pki/ssl
SSH_CA_DIR=/etc/ssh/pki/ssh

### SSL CONFIG OPTIONS
#How many days should the cert be valid for
DAYSVALID=375
CADAYSVALID=3750

#Which signing algorithm to use
MDALGORITHM="sha256"
MDALGORITHM=sha256

#Should we configure an intermediate CA
USEINTERMEDIATE=yes

M hosaka-pki.sh => hosaka-pki.sh +37 -13
@@ 1,11 1,28 @@
#!/bin/sh -e
export CONFIGDIR=""
export SSL_CA_DIR=""
export SSH_CA_DIR=""
export DAYSVALID=""
export CADAYSVALID=""
export MDALGORITHM=""
export USEINTERMEDIATE=""
export WARNROOTCERT=""
export COUNTRYDEFAULT=""
export STATEDEFAULT=""
export LOCALITYDEFAULT=""
export ORGNAMEDEFAULT=""
export ORGUNITDEFAULT=""
export USERCERTCOMMENT=""
export SRVCERTCOMMENT=""
export SSLSERIALDEFAULT=""
export SSHSERIALDEFAULT=""

readconf() {
	while IFS='=' read -r key val; do
    		[ "${key##\#*}" ] || continue
    		export "$key=$val" 2>/dev/null ||
    		     printf '%s is not a valid variable\n' "$key"
	done < "${1}"
	done < "$CONFIGDIR/config"
}

checkvars() {


@@ 13,6 30,7 @@ checkvars() {
	[ -z "$SSL_CA_DIR" ] && printf "Arguments cannot be empty: %s\\n" "$SSL_CA_DIR" 1>&2 && exit 1
	[ -z "$SSH_CA_DIR" ] && printf "Arguments cannot be empty: %s\\n" "$SSH_CA_DIR" 1>&2 && exit 1
	[ -z "$DAYSVALID" ] && printf "Arguments cannot be empty: %s\\n" "$DAYSVALID" 1>&2 && exit 1
	[ -z "$CADAYSVALID" ] && printf "Arguments cannot be empty: %s\\n" "$CADAYSVALID" 1>&2 && exit 1
	[ -z "$MDALGORITHM" ] && printf "Arguments cannot be empty: %s\\n" "$MDALGORITHM" 1>&2 && exit 1
	[ -z "$USEINTERMEDIATE" ] && printf "Arguments cannot be empty: %s\\n" "$USEINTERMEDIATE" 1>&2 && exit 1
	[ -z "$WARNROOTCERT" ] && printf "Arguments cannot be empty: %s\\n" "$WARNROOTCERT" 1>&2 && exit 1


@@ 30,27 48,26 @@ checkvars() {
getconf() {
	#The "compilation" step used for hosaka-pki just uses templates and
	#this will work even if the template injection works or not.
	CONFDIR="{{CONFIGDIR}}"
	case $CONFDIR in
	CONFIGDIR="{{CONFIGDIR}}"
	case $CONFIGDIR in
		""|"{{CONFIGDIR}}")
			CONFDIR="/etc/hosaka/pki"
			CONFIGDIR="/etc/hosaka/pki"
			;;
		*)
			CONFDIR="${CONFIGDIR}"
		;;
			CONFIGDIR="${CONFIGDIR}"
			;;
	esac
	[ -f "${CONFIGDIR}/config" ] && readconf "${CONFIGDIR}/config"
}

sslgenconf() {
	getconf
	checkvars
	#Generate conf for the CA and if an intermediate is in use, generate
	#for that as well
	sed -e "s%{{SSLDIR}}%${SSL_CA_DIR}%g" \
		-e "s%{{MDALGORITHM}}%${MDALGORITHM}%g" \
		-e "s%{{DAYSVALID}}%${DAYSVALID}%g" \
		-e "s%{{COUNTRYDEFAULT}}%${COUNTRYDEFAUL}%g" \
		-e "s%{{CADAYSVALID}}%${CADAYSVALID}%g" \
		-e "s%{{COUNTRYDEFAULT}}%${COUNTRYDEFAULT}%g" \
		-e "s%{{STATEDEFAULT}}%${STATEDEFAULT}%g" \
		-e "s%{{LOCALITYDEFAULT}}%${LOCALITYDEFAULT}%g" \
		-e "s%{{ORGNAMEDEFAULT}}%${ORGNAMEDEFAULT}%g" \


@@ 58,11 75,12 @@ sslgenconf() {
		-e "s%{{USERCERTCOMMENT}}%${USERCERTCOMMENT}%g" \
		-e "s%{{SERVERCERTCOMMENT}}%${SERVERCERTCOMMENT}%g" \
		-e "s%{{SSLSERIALDEFAULT}}%${SSLSERIALDEFAULT}%g" \
		< "$SSL_CA_DIR/openssl.cnf.tmpl" > "$SSL_CA_DIR/openssl.cnf"
		< "$CONFIGDIR/util/openssl.cnf.tmpl" > "$SSL_CA_DIR/openssl.cnf"
	ssluseintermediate && sed -e "s%{{SSLDIR}}%${SSL_CA_DIR}/intermediate%g" \
		-e "s%{{MDALGORITHM}}%${MDALGORITHM}%g" \
		-e "s%{{DAYSVALID}}%${DAYSVALID}%g" \
		-e "s%{{COUNTRYDEFAULT}}%${COUNTRYDEFAUL}%g" \
		-e "s%{{CADAYSVALID}}%${CADAYSVALID}%g" \
		-e "s%{{COUNTRYDEFAULT}}%${COUNTRYDEFAULT}%g" \
		-e "s%{{STATEDEFAULT}}%${STATEDEFAULT}%g" \
		-e "s%{{LOCALITYDEFAULT}}%${LOCALITYDEFAULT}%g" \
		-e "s%{{ORGNAMEDEFAULT}}%${ORGNAMEDEFAULT}%g" \


@@ 70,7 88,7 @@ sslgenconf() {
		-e "s%{{USERCERTCOMMENT}}%${USERCERTCOMMENT}%g" \
		-e "s%{{SERVERCERTCOMMENT}}%${SERVERCERTCOMMENT}%g" \
		-e "s%{{SSLSERIALDEFAULT}}%${SSLSERIALDEFAULT}%g" \
		< "$SSL_CA_DIR/openssl.cnf.tmpl" > "$SSL_CA_DIR/openssl_intermediate.cnf"
		< "$CONFIGDIR/util/openssl.cnf.tmpl" > "$SSL_CA_DIR/openssl_intermediate.cnf"
}

sslgenca() {


@@ 97,7 115,8 @@ ssluseintermediate() {
		y*|Y*)
			return 0
		;;
	*)
		*)
			return 1
		;;
	esac
	return 1


@@ 146,6 165,11 @@ sslgenintermediate() {
sslcheckcaondisk() {
	[ -f "$SSL_CA_DIR/private/ca.key.pem" ] && printf "CA file is on disk. This is not a secure configuration and the root CA should not be stored with the intermediate and should only be used to generate new intermediates.\\n" 1>&2
}

getconf
sslcheckcaondisk
sslcreatedirs
sslgenconf
#
#sslsignserver() {
#

A tmpl/openssl.cnf.tmpl => tmpl/openssl.cnf.tmpl +93 -0
@@ 0,0 1,93 @@
[ ca ]
default_ca = CA_default

[ CA_default ]
dir = /home/ca/ssl
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/new
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pem
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30
default_md        = sha256
name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict

[ policy_strict ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256
x509_extensions     = v3_ca

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name

countryName_default             = HX 
stateOrProvinceName_default     = Cyberspace 
localityName_default            = NULL
0.organizationName_default      = Hosaka Corporation 
organizationalUnitName_default = Crypto Munitions Bureau

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
authorityKeyIdentifier=keyid:always