# A simple CA interface for openssl. See make help for details.

ifeq ($(length),)
length = 4096
endif

ifneq ($(cipher),)
usecipher = "-$(cipher)"
endif

.PHONY: default init revoke gencrl clean cleanauth

.PRECIOUS: %.svr.crt %.cli.crt %.crt %.req %.svr.key %.cli.key %.key %.password

default: help

init: ca-cert.pem ca-cert.der

ca-cert.pem ca-cert.der:
	@echo
	@echo '>>> Generating a certification authority <<<'
	@echo
	@test ! -f serial
	@mkdir crl newcerts private
	@chmod go-rwx private
	@echo '01' > serial
	@touch index
	@openssl req -utf8 -sha512 -nameopt oneline,-esc_msb -nodes -config openssl_auth.cnf -days 3650 -x509 -newkey rsa:8192 -out ca-cert.pem -outform PEM
	@openssl x509 -in ca-cert.pem -inform PEM -outform DER -out ca-cert.der

revoke:
ifeq ($(cert),)
	@echo 'Usage: make revoke cert=<cert_filename>'
	@exit 1	
endif
	@echo
	@echo '>>> Revoking the certificate <<<'
	@echo
	@openssl ca -utf8 -config openssl_auth.cnf -revoke $(cert)
	@$(MAKE) gencrl

gencrl:
	@echo
	@echo '>>> Generating the Certificate Revocation List <<<'
	@echo
	@openssl ca -utf8 -config openssl_auth.cnf -gencrl -out ca-crl.pem
	@openssl crl -inform PEM -in ca-crl.pem -outform DER -out ca-crl.der

clean:
	@echo
	@echo '>>> Cleaning all leftover files <<<'
	@echo
	@rm -rf *.key *.req *.crt *.p12 *.password 

cleanauth_and_i_am_really_sure: clean
	@echo
	@echo '>>> Removing the certification authority <<<'
	@echo
	@rm -Rf crl newcerts private
	@rm -rf ca-{cert,crl}.{pem,der} index* serial* 

%.password:
	@mkpasswd -l 20 > $@

%.key: %.password
ifeq ($(usecipher),)
	@echo 'Warning: No cipher selected! Unencrypted certificates are not safe for personal use.'
	@until [ "$$answer" = 'yes' -o "$$answer" = 'no' ]; do\
		echo -n 'Proceed? (yes|no) ';\
		read answer;\
	done;\
	if [ "$$answer" = 'no' ]; then exit 2; fi
endif
	@echo
	@echo '>>> Generating a key and a random password <<<'
	@echo
	@openssl genrsa $(usecipher) -passout file:$< -out $@ $(length)

%.req: %.key
	@echo
	@echo '>>> Generating a certificate request <<<'
	@echo
	@openssl req -utf8 -sha512 -nameopt oneline,-esc_msb -config openssl_crt.cnf -passin file:$*.password -new -newhdr -days 365 -outform PEM -key $< -out $@

%.cli.crt: %.cli.req
	@echo
	@echo '>>> Signing the EAP client certificate request <<<'
	@echo
	@openssl ca -utf8 -md sha512 -config openssl_auth.cnf -in $< -out $@ -extensions xpclient_ext -extfile xpextensions
	@[ -f $@ ] && rm $<

%.svr.crt: %.svr.req
	@echo
	@echo '>>> Signing the EAP server certificate request <<<'
	@echo
	@openssl ca -utf8 -md sha512 -config openssl_auth.cnf -in $< -out $@ -extensions xpserver_ext -extfile xpextensions
	@[ -f $@ ] && rm $<

%.ipsec.crt: %.ipsec.req
	@echo
	@echo '>>> Signing the IPSec host certificate request <<<'
	@echo
	@openssl ca -utf8 -md sha512 -config openssl_auth.cnf -in $< -out $@ -extensions ipsec_ext -extfile xpextensions
	@[ -f $@ ] && rm $<

%.crt: %.req
	@echo
	@echo '>>> Signing the certificate request <<<'
	@echo
	@openssl ca -utf8 -md sha512 -config openssl_auth.cnf -in $< -out $@
	@[ -f $@ ] && rm $<

%.der: %.crt
	@openssl x509 -in $< -inform PEM -out $@ -outform DER

%.p12: %.crt
	@echo
	@echo '>>> Making a pkcs12 certificate package <<<'
	@echo
	@cat $*.password | openssl pkcs12 -export -name 'Podzimek Second CA' -in $< -inkey $*.key -passin stdin -passout file:$*.password -certfile ca-cert.pem -out $@
	@rm $*.key

help:
	@echo
	@echo 'make init'
	@echo '  - required initial setup command for new CA'
	@echo
	@echo 'make cleanauth_and_i_am_really_sure'
	@echo '  - removes all leftover files'
	@echo '  - removes all the CA data, including keys and database'
	@echo '  - USE WITH CAUTION!'
	@echo
	@echo 'make filename.key [cipher=<cipher_option>]'
	@echo '  - creates a private key'
	@echo
	@echo 'make filename.req [cipher=<cipher_option>]'
	@echo '  - creates a private key'
	@echo '  - creates a certificate request based on the key'
	@echo
	@echo 'make filename.crt [cipher=<cipher_option>]'
	@echo '  - creates a private key'
	@echo '  - creates a certificate request based on the key'
	@echo '  - signs the certificate request'
	@echo
	@echo 'make filename.cli.crt [cipher=<cipher_option>]'
	@echo '  - same as above, but adds data required by the Windows supplicant'
	@echo '  - to be used for EAP-TLS on client side'
	@echo
	@echo 'make filename.svr.crt [cipher=<cipher_option>]'
	@echo '  - same as above, this time for EAP-TLS server side'
	@echo
	@echo 'DNS=f.q.d.n make filename.ipsec.crt [cipher=<cipher_option>]'
	@echo '  - same as above, this time for IPSec host usage'
	@echo
	@echo 'make filename.der [cipher=<cipher_option>]'
	@echo '  - all options and file name suffixes applicable to *.crt files apply here'
	@echo '  - after signing the certificate, also creates its DER version'
	@echo
	@echo 'make filename.p12 cipher=<cipher_option>'
	@echo '  - creates a private key'
	@echo '  - creates a certificate request based on the key'
	@echo '  - signs the certificate request'
	@echo '  - creates a pkcs12 package based on the signed request'
	@echo '  - please see man openssl for a list of available cipher options (des3 recommended)'
	@echo
	@echo 'make filename.cli.p12 cipher=<cipher_option>'
	@echo '  - same as above, but adds data required by the Windows supplicant'
	@echo '  - to be used for EAP-TLS on client side'
	@echo
	@echo 'make filename.svr.p12 cipher=<cipher_option>'
	@echo '  - same as above, this time form EAP-TLS server side'
	@echo
	@echo 'make revoke cert=<cert_filename>'
	@echo '  - revokes certificate in named file and calls gencrl'
	@echo
	@echo 'make gencrl'
	@echo '  - updates Certificate Revocation List (CRL)'
	@echo
	@echo 'make clean'
	@echo '  - removes all leftover files'
	@echo '  - Make sure you SAVE all your new certificates first!'
	@echo

