Last active
September 18, 2022 05:48
-
-
Save BrianAker/ba8e874ddb781c3c98d277aa9050b748 to your computer and use it in GitHub Desktop.
This script produces a CA with a restraint that it can only create certificates under a specific domain.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # This script produces a CA with a restraint that it can only create certificates under a specific domain. | |
| # The last 5 lines install the CA where mkcert will make use of it as the root CA ( OSX specific at the moment ) | |
| gTLD="${gTLD:-localhost}" | |
| declare -x HOST_COMMON_NAME | |
| #export exampleIP=192.0.2.2 | |
| force=false | |
| function printConfig() { | |
| cat << EOF > "$gTLD".cfg | |
| [ req ] | |
| prompt=no | |
| default_bits=4096 | |
| default_md=sha256 | |
| preserve=no | |
| distinguished_name=req_distinguished_name | |
| req_extensions=v3_req | |
| x509_extensions=v3_ca | |
| [ req_distinguished_name ] | |
| CN=$gTLD trust CA | |
| emailAddress=root@$gTLD | |
| [ v3_ca ] | |
| basicConstraints=critical,CA:TRUE,pathlen:1 | |
| nameConstraints=critical,permitted;DNS:.$gTLD | |
| keyUsage=critical,cRLSign,digitalSignature,keyCertSign | |
| #extendedKeyUsage=critical,serverAuth,clientAuth,emailProtection | |
| subjectKeyIdentifier=hash | |
| #authorityKeyIdentifier=keyid:always,issuer:always | |
| [ v3_req_ca ] | |
| basicConstraints=critical,CA:TRUE,pathlen:0 | |
| nameConstraints=critical,permitted;DNS:.$gTLD | |
| keyUsage=critical,cRLSign,digitalSignature,keyCertSign | |
| extendedKeyUsage=critical,serverAuth,clientAuth,emailProtection | |
| subjectKeyIdentifier=hash | |
| [ v3_req ] | |
| basicConstraints=critical,CA:TRUE,pathlen:0 | |
| nameConstraints=critical,permitted;DNS:.$gTLD | |
| keyUsage=critical,cRLSign,digitalSignature,keyCertSign | |
| extendedKeyUsage=critical,serverAuth,clientAuth,emailProtection | |
| subjectKeyIdentifier=hash | |
| authorityKeyIdentifier=keyid:always,issuer:always | |
| [ server_req ] | |
| basicConstraints=critical,CA:FALSE | |
| keyUsage=critical,digitalSignature | |
| extendedKeyUsage=critical,serverAuth | |
| subjectKeyIdentifier=hash | |
| subjectAltName=@subjects | |
| [ server_sign ] | |
| basicConstraints=critical,CA:FALSE | |
| keyUsage=critical,digitalSignature | |
| extendedKeyUsage=critical,serverAuth | |
| subjectKeyIdentifier=hash | |
| authorityKeyIdentifier=keyid:always,issuer:always | |
| subjectAltName=@subjects | |
| [ subjects ] | |
| EOF | |
| #DNS.2=www.example.$gTLD | |
| #IP.1=192.0.2.1 | |
| #IP.2=198.51.100.254 | |
| #IP.3=2001:DB8::1 | |
| } | |
| die() { echo "$*" >&2; exit 2; } # complain to STDERR and exit with error | |
| needs_arg() { if [ -z "$OPTARG" ]; then die "No arg for --$OPT option"; fi; } | |
| function printConfigHosts() { | |
| local argIndex="${#BASH_ARGV[@]}" | |
| while [[ argIndex -gt 0 ]] ; do | |
| argIndex=$((argIndex - 1)) | |
| echo -n "${BASH_ARGV[$argIndex]} " | |
| if [[ "$argIndex" -eq '0' ]]; then | |
| HOST_COMMON_NAME=${BASH_ARGV[$argIndex]} | |
| fi | |
| cat << EOF >> "$gTLD".cfg | |
| DNS.$argIndex=${BASH_ARGV[$argIndex]}.$gTLD | |
| EOF | |
| done | |
| } | |
| while getopts fi:-: OPT; do | |
| # support long options: https://stackoverflow.com/a/28466267/519360 | |
| if [ "$OPT" = "-" ]; then # long option: reformulate OPT and OPTARG | |
| OPT="${OPTARG%%=*}" # extract long option name | |
| OPTARG="${OPTARG#"$OPT"}" # extract long option argument (may be empty) | |
| OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` | |
| fi | |
| case "$OPT" in | |
| h | help ) | |
| echo "help" | |
| exit 0 | |
| ;; | |
| f | force ) force=true ;; | |
| i | install ) needs_arg; gTLD="$OPTARG" ;; | |
| ??* ) die "Illegal option --$OPT" ;; # bad long option | |
| ? ) exit 2 ;; # bad short option (error reported via getopts) | |
| esac | |
| done | |
| shift $((OPTIND-1)) # remove parsed options and args from $@ list | |
| if $force; then | |
| echo "Remove files here"; | |
| fi | |
| printConfig | |
| printConfigHosts | |
| if [ ! -r "root-ca.pem" ]; then | |
| openssl req -nodes -x509 -days 3650 -newkey rsa:4096 -sha256 -out root-ca.pem -keyout root-ca.key -config "$gTLD".cfg -subj "/CN=Root CA for $gTLD" | |
| openssl verify -CAfile root-ca.pem root-ca.pem | |
| fi | |
| if [ ! -r "$gTLD"-ca.pem ]; then | |
| openssl req -nodes -new -newkey rsa:4096 -out "$gTLD"-ca.csr -sha256 -keyout "$gTLD"-ca.key -config "$gTLD".cfg -reqexts v3_req_ca -subj "/CN=Intermediate CA for $gTLD" | |
| openssl req -in "$gTLD"-ca.csr -verify -noout | |
| openssl x509 -req -days 365 -in "$gTLD"-ca.csr -CA root-ca.pem -CAkey root-ca.key -sha256 -set_serial 1 -out "$gTLD"-ca.pem -extensions v3_req -extfile "$gTLD".cfg | |
| openssl verify -CAfile root-ca.pem "$gTLD"-ca.pem | |
| cat root-ca.pem >> "$gTLD"-ca.pem | |
| fi | |
| #cat root-ca.pem "$gTLD"-ca.pem > ca.pem | |
| if [ "$HOST_COMMON_NAME" ]; then | |
| openssl req -nodes -new -newkey rsa:4096 -out "$HOST_COMMON_NAME"."$gTLD".csr -sha256 -keyout "$HOST_COMMON_NAME"."$gTLD".key -config "$gTLD".cfg -reqexts server_req -subj "/CN=$HOST_COMMON_NAME.$gTLD" | |
| openssl req -in "$HOST_COMMON_NAME"."$gTLD".csr -verify -noout | |
| openssl x509 -req -days 365 -in "$HOST_COMMON_NAME"."$gTLD".csr -CA "$gTLD"-ca.pem -CAkey "$gTLD"-ca.key -sha256 -out "$HOST_COMMON_NAME"."$gTLD".pem -extensions server_sign -extfile "$gTLD".cfg | |
| #openssl verify -CAfile root-ca.pem "$HOST_COMMON_NAME"."$gTLD".pem | |
| openssl verify -CAfile "$gTLD"-ca.pem "$HOST_COMMON_NAME"."$gTLD".pem | |
| fi | |
| #rm root-ca.key | |
| #openssl pkcs8 -topk8 -in $gTLD-ca.key -out $gTLD-ca.pkcs8.key -nocrypt | |
| #mkdir -p ~/.local/share/mkcert | |
| #chmod 700 ~/.local/share/mkcert | |
| #cat $gTLD-ca.pkcs8.key > ~/.local/share/mkcert/rootCA-key.pem | |
| #cat $gTLD-ca.pem > ~/.local/share/mkcert/rootCA.pem | |
| #chmod 400 ~/.local/share/mkcert/* | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment