Skip to content

Instantly share code, notes, and snippets.

@kumakichi
Created January 24, 2019 11:57
Show Gist options
  • Save kumakichi/c4476d32b44c0c50043a80a9b771086d to your computer and use it in GitHub Desktop.
Save kumakichi/c4476d32b44c0c50043a80a9b771086d to your computer and use it in GitHub Desktop.
HOWTO: Create Your Own Self-Signed Certificate with Subject Alternative Names Using OpenSSL in Bash
#!/bin/bash
caDir="myCA"
caCnf="caconfig.cnf"
localCnf="local.cnf"
caPEMPass="11001"
pemPass="11002"
DNS="test.example.com"
# https://gist.github.com/jchandra74/36d5f8d0e11960dd8f80260801109ab0
# https://www.openssl.org/docs/manmaster/man5/x509v3_config.html
CUR_BASE_DIR=${PWD}
rm -rf "${caDir}"
mkdir ${caDir} && mkdir -p ${caDir}/signedcerts && mkdir ${caDir}/private && cd "${caDir}" || exit
echo '01' > serial && touch index.txt
cat<<EOF>${caCnf}
# My sample caconfig.cnf file.
#
# Default configuration to use when one is not provided on the command line.
#
[ ca ]
default_ca = local_ca
#
#
# Default location of directories and files needed to generate certificates.
#
[ local_ca ]
dir = ${CUR_BASE_DIR}
certificate = ${CUR_BASE_DIR}/${caDir}/CA.pem
database = ${CUR_BASE_DIR}/${caDir}/index.txt
new_certs_dir = ${CUR_BASE_DIR}/${caDir}/signedcerts
private_key = ${CUR_BASE_DIR}/${caDir}/private/cakey.pem
serial = ${CUR_BASE_DIR}/${caDir}/serial
#
#
# Default expiration and encryption policies for certificates
#
default_crl_days = 365
default_days = 1825
# sha1 is no longer recommended, we will be using sha256
default_md = sha256
#
policy = local_ca_policy
x509_extensions = local_ca_extensions
#
#
# Copy extensions specified in the certificate request
#
copy_extensions = copy
#
#
# Default policy to use when generating server certificates.
# The following fields must be defined in the server certificate.
#
# DO NOT CHANGE "supplied" BELOW TO ANYTHING ELSE.
# It is the correct content.
#
[ local_ca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = supplied
organizationName = supplied
organizationalUnitName = supplied
#
#
# x509 extensions to use when generating server certificates
#
[ local_ca_extensions ]
basicConstraints = CA:false
#
#
# The default root certificate generation policy
#
[ req ]
default_bits = 2048
default_keyfile = ${CUR_BASE_DIR}/${caDir}/private/cakey.pem
#
# sha1 is no longer recommended, we will be using sha256
default_md = sha256
#
prompt = no
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions
#
#
# Root Certificate Authority distinguished name
#
# DO CHANGE THE CONTENT OF THESE FIELDS TO MATCH
# YOUR OWN SETTINGS!
#
[ root_ca_distinguished_name ]
commonName = Cloudchain Root Certificate Authority
stateOrProvinceName = NSW
countryName = AU
emailAddress = nobody@querycap.com
organizationName = Cloudchain
organizationalUnitName = Development
#
[ root_ca_extensions ]
basicConstraints = CA:true
EOF
/usr/bin/expect <<EOD
spawn openssl req -x509 -newkey rsa:2048 -out CA.pem -outform PEM -days 3650 -config ${CUR_BASE_DIR}/${caDir}/${caCnf}
expect {
"Enter PEM pass phrase:" { send "$caPEMPass\n"; exp_continue}
"Verifying - Enter PEM pass phrase:" { send "$caPEMPass\n" }
}
EOD
cat<<EOF>${localCnf}
#
# localhost.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
req_extensions = v3_req
[ server_distinguished_name ]
commonName = localhost
stateOrProvinceName = NSW
countryName = AU
emailAddress = invoicesmashteam@coupa.com
organizationName = Coupa InvoiceSmash
organizationalUnitName = Development
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, keyCertSign, cRLSign
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.0 = ${DNS}
EOF
/usr/bin/expect <<EOD
spawn openssl req -newkey rsa:2048 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM -config ${CUR_BASE_DIR}/${caDir}/${localCnf}
expect {
"Enter PEM pass phrase:" { send "$pemPass\n"; exp_continue}
"Verifying - Enter PEM pass phrase:" { send "$pemPass\n" }
}
spawn openssl rsa -in tempkey.pem -out server_key.pem
expect {
".pem:" { send "$pemPass\n"}
}
EOD
/usr/bin/expect <<EOD
spawn openssl ca -in tempreq.pem -out cert.pem -config ${CUR_BASE_DIR}/${caDir}/${caCnf}
expect {
"Enter pass phrase for ${CUR_BASE_DIR}/${caDir}/private/cakey.pem:" { send "$caPEMPass\n"; exp_continue}
"n]:" { send "y\n"; exp_continue}
"n]" { send "y\n"; exp_continue}
}
spawn openssl pkcs8 -topk8 -inform pem -in tempkey.pem -outform pem -nocrypt -out keyfile
expect {
".pem:" { send "$pemPass\n"; exp_continue}
}
EOD
echo "Successfully generated:"
echo "CA: ${CUR_BASE_DIR}/${caDir}/CA.pem"
echo "cert: ${CUR_BASE_DIR}/${caDir}/cert.pem"
echo "key: ${CUR_BASE_DIR}/${caDir}/keyfile"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment