# vim:set ft=make noet ts=8 sw=2 nowrap:

# 20240508 PeterG

# Using 'cc -E' causes some problems.
CPP			=cpp

CA			=com.example
CNLIST			=com.example.www com.example.mail

# 2048 bits are currently (2003) recommended for CAs.
ABITS			=3072
ADAYS			=750

# 2048 bits too, 1024 are weak in 2015.
# Older browsers only support 512 and 1024.
NBITS			=2048
NDAYS			=750
#RDAYS			=3

ASERI			=_CASer
APKEY			=_CAKey
ACERT			=_CAPub
ABOTH			=_CA

NPKEY			=_Key
NCREQ			=_Req
NCERT			=_Pub
NBOTH			=

T			=tmp/
C			=certs/
P			=private/

#NPGRP			=ssl-cert

# We want the private key, certificate, and merged
# version for our CN.

all:				${T} ${P} ${C}

all:				${P}${CA}${APKEY}.pem
all:				${C}${CA}${ACERT}.pem
#all:				${P}${CA}${ABOTH}.p12
#all:				${P}${CA}${ABOTH}.pem

all:				$(foreach CN,${CNLIST},${P}${CN}${NPKEY}.pem)
all:				$(foreach CN,${CNLIST},${T}${CN}${NCREQ}.pem)
all:				$(foreach CN,${CNLIST},${C}${CN}${NCERT}.pem)
#all:				$(foreach CN,${CNLIST},${P}${CN}${NBOTH}.p12)
#all:				$(foreach CN,${CNLIST},${P}${CN}${NBOTH}.pem)

# We never want to lose the CA private key, certificate,
# and merged version.

.PRECIOUS:			${P}${CA}${APKEY}.pem
.PRECIOUS:			${C}${CA}${ACERT}.pem
.PRECIOUS:			${P}${CA}${ABOTH}.pem
.PRECIOUS:			${P}${CA}${ABOTH}.p12

# Don't delete intermediate files, but then don't create them
# unless necessary.
.SECONDARY:

${T}:
	mkdir '$@'
	chmod a+rx '$@'

${P}:
	mkdir '$@'
	chmod u=rwx,go= '$@'

${C}:
	mkdir '$@'

# A '.cnf' file (for CA or CN) is the concatenation of
# 'default.ini' and the specific '.ini', processed.

${T}%.cnf:				 default.ini %.ini
	cpp -D HASH='%%#' -I. '$*.ini' | sed 's/ *%% *//g' > '$@'

# Generate site CA private key using RSA and encrypted

${P}%${APKEY}.pem:			
	openssl genrsa	-out			'$@' \
			  -aes128		'${ABITS}'
	chmod og= '$@'

# Generate site CA certificate via self-signing.
# Use 'openssl req' instead of 'openssl ca' because the CA has not
# yet been set up.

${C}%${ACERT}.pem:			 ${T}%${ACERT}.cnf ${P}%${APKEY}.pem
	openssl req	 -x509 -out		'$@' \
			  -sha256		\
			  -new			\
			  -config		'${T}$*${ACERT}.cnf' \
			  -key			'${P}$*${APKEY}.pem' \
			  -days			'${ADAYS}'
	chmod a+r '$@'

${P}%${ABOTH}.pem:			 ${P}%${APKEY}.pem ${C}%${ACERT}.pem
	cat '${P}$*${APKEY}.pem' '${C}$*${ACERT}.pem' > '$@'
	chmod og= '$@'

${P}%${ABOTH}.p12:			 ${P}%${APKEY}.pem ${C}%${ACERT}.pem
	openssl pkcs12	-export -out		'$@' \
			  -aes128		\
			  -name			'${CA}' \
			  -CAfile		'${C}${CA}${ACERT}.pem' \
			  -inkey		'${P}$*${APKEY}.pem' \
			  -in			'${C}$*${ACERT}.pem'
	chmod og= '$@'

# Generate unencrypted host key and an unencrypted signing request.

${P}%${NPKEY}.pem:			
	openssl genrsa	-out			'$@'
	chmod g=r,o= '$@'

${T}%${NCREQ}.pem:			 ${T}%${NCREQ}.cnf ${P}%${NPKEY}.pem
	openssl req	-noenc -out		'$@' \
			  -sha256		\
			  -new			\
			  -config		'${T}$*${NCREQ}.cnf' \
			  -key			'${P}$*${NPKEY}.pem'
	chmod og= '$@'

# Generate signed site certificate from the request.

${C}%${NCERT}.pem:			 ${P}${CA}${APKEY}.pem ${C}${CA}${ACERT}.pem \
					  ${T}%${NCERT}.cnf ${T}%${NCREQ}.pem
	openssl x509	-out			'$@' \
			  -sha256		\
			  -req 			\
			  -CAcreateserial 	\
			  -CAserial		'${P}${CA}${ASERI}.txt' \
			  -CAkey		'${P}${CA}${APKEY}.pem' \
			  -CA			'${C}${CA}${ACERT}.pem' \
			  -extfile		'${T}$*${NCERT}.cnf' \
	 		  -in			'${T}$*${NCREQ}.pem' \
			  -days			'${NDAYS}'
	chmod a+r '$@'

${P}%${NBOTH}.pem:			 ${P}%${NPKEY}.pem ${C}%${NCERT}.pem
	cat '${P}$*${NPKEY}.pem' '${C}$*${NCERT}.pem' > '$@'
	chmod og= '$@'

${P}%${NBOTH}.p12:			 ${C}${CA}${ACERT}.pem \
					  ${P}%${NPKEY}.pem ${C}%${NCERT}.pem
	openssl pkcs12	-export -out		'$@' \
			  -CAfile		'${C}${CA}${ACERT}.pem' \
			  -name			'$*' \
			  -inkey		'${P}$*${NPKEY}.pem' \
			  -in			'${C}$*${NCERT}.pem'
	chmod og= '$@'
