Skip to content

Instantly share code, notes, and snippets.

@lukecampbell
Last active May 2, 2022 09:15
Show Gist options
  • Select an option

  • Save lukecampbell/a8109a380ae0ecc49c468fb413cf7940 to your computer and use it in GitHub Desktop.

Select an option

Save lukecampbell/a8109a380ae0ecc49c468fb413cf7940 to your computer and use it in GitHub Desktop.
Generic script to create openssl based Certificate Authority
#!/bin/bash
set -e
echo "Creating new OpenSSL Certificate Authority"
echo -n "Enter path to CA [.]: "
read ca_path
ca_path=${ca_path:-$PWD}
if [[ "$ca_path" != /* ]]; then
ca_path="$PWD/$ca_path"
fi
echo "Installing in $ca_path"
if [[ ! -d "$ca_path" ]]; then
mkdir -p "$ca_path"
fi
cd "$ca_path"
for dir in certs crl newcerts private; do
if [[ ! -d "$dir" ]]; then
mkdir "$dir"
fi
done
echo "[-] Created CA Directories"
chmod 700 private
touch index.txt
echo 1000 > serial
echo -n "Enter default Country Name (2 letter code): "
read country_name
echo -n "Enter default State or Province Name: "
read state_name
echo -n "Enter default Locality Name: "
read locality_name
echo -n "Enter default Organization Name: "
read org_name
echo -n "Enter default Organizational Unit Name: "
read org_unit_name
echo -n "Enter default Email Address: "
read email_address
cat > openssl.cnf << EOF
# OpenSSL root CA configuration file.
# Copy to \`/root/ca/openssl.cnf\`.
[ ca ]
# \`man ca\`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = $ca_path
certs = \$dir/certs
crl_dir = \$dir/crl
new_certs_dir = \$dir/newcerts
database = \$dir/index.txt
serial = \$dir/serial
RANDFILE = \$dir/private/.rand
# The root key and root certificate.
private_key = \$dir/private/ca.key.pem
certificate = \$dir/certs/ca.cert.pem
# For certificate revocation lists.
crlnumber = \$dir/crlnumber
crl = \$dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of \`man ca\`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the \`ca\` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the \`req\` tool (\`man req\`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = $country_name
stateOrProvinceName_default = $state_name
localityName_default = $locality_name
0.organizationName_default = $org_name
organizationalUnitName_default = $org_unit_name
emailAddress_default = $email_address
[ v3_ca ]
# Extensions for a typical CA (\`man x509v3_config\`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (\`man x509v3_config\`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (\`man x509v3_config\`).
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 ]
# Extensions for server certificates (\`man x509v3_config\`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ crl_ext ]
# Extension for CRLs (\`man x509v3_config\`).
authorityKeyIdentifier=keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (\`man ocsp\`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
EOF
echo "[-] Generated OpenSSL CA Configuration"
openssl genrsa -aes256 -out private/ca.key.pem 4096
chmod 400 private/ca.key.pem
openssl req -config openssl.cnf \
-key private/ca.key.pem \
-new -x509 -days 7300 -sha256 -extensions v3_ca \
-out certs/ca.cert.pem
chmod 444 certs/ca.cert.pem
echo "Finished setting up CA"
echo -n "Do you want to set up an intermediate CA? [y]: "
read setup_inter
setup_inter=${setup_inter:-y}
if [[ $setup_inter != "y" ]]; then
exit 0
fi
if [[ ! -d intermediate ]]; then
mkdir intermediate
fi
pushd intermediate
for dir in config certs crl csr newcerts private; do
if [[ ! -d $dir ]]; then
mkdir $dir
fi
done
chmod 700 private
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber
cat > openssl.cnf << EOF
# OpenSSL intermediate CA configuration file.
# Copy to \`/root/ca/intermediate/openssl.cnf\`.
[ ca ]
# \`man ca\`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = $ca_path/intermediate
certs = \$dir/certs
crl_dir = \$dir/crl
new_certs_dir = \$dir/newcerts
database = \$dir/index.txt
serial = \$dir/serial
RANDFILE = \$dir/private/.rand
# The root key and root certificate.
private_key = \$dir/private/intermediate.key.pem
certificate = \$dir/certs/intermediate.cert.pem
# For certificate revocation lists.
crlnumber = \$dir/crlnumber
crl = \$dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of \`man ca\`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the \`ca\` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the \`req\` tool (\`man req\`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = $country_name
stateOrProvinceName_default = $state_name
localityName_default = $locality_name
0.organizationName_default = $org_name
organizationalUnitName_default = $org_unit_name
emailAddress_default = $email_address
[ v3_ca ]
# Extensions for a typical CA (\`man x509v3_config\`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (\`man x509v3_config\`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (\`man x509v3_config\`).
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 ]
# Extensions for server certificates (\`man x509v3_config\`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ crl_ext ]
# Extension for CRLs (\`man x509v3_config\`).
authorityKeyIdentifier=keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (\`man ocsp\`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
EOF
popd
openssl genrsa -aes256 \
-out intermediate/private/intermediate.key.pem 4096
chmod 400 intermediate/private/intermediate.key.pem
openssl req -config intermediate/openssl.cnf -new -sha256 \
-key intermediate/private/intermediate.key.pem \
-out intermediate/csr/intermediate.csr.pem
openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-in intermediate/csr/intermediate.csr.pem \
-out intermediate/certs/intermediate.cert.pem
chmod 444 intermediate/certs/intermediate.cert.pem
cat index.txt
echo "Verifying intermediate certificate..."
openssl verify -CAfile certs/ca.cert.pem \
intermediate/certs/intermediate.cert.pem
echo "Creating the certificate chain file"
cat intermediate/certs/intermediate.cert.pem \
certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
chmod 444 intermediate/certs/ca-chain.cert.pem
@utthungagokul
Copy link
Copy Markdown

This is works fine for standalone script. Nice work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment