Created
April 19, 2012 15:27
-
-
Save wolever/2421697 to your computer and use it in GitHub Desktop.
Tools for creating private certificate authorities
This file contains 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 | |
set -e | |
nodes="-nodes" | |
if [[ "$1" == "-des" ]]; then | |
nodes="" | |
shift | |
fi | |
if [[ ! "$1" || ! "$2" || "$1" =~ "^-" ]]; then | |
echo "usage: $0 [-des] CommonName directory" | |
exit 2 | |
fi | |
name="$1" | |
dir="$2" | |
subj="/C=CA/ST=Ontario/L=Toronto/O=Luminautics Inc./CN=$name" | |
cakey="ca.key" | |
if [[ ! "$nodes" ]]; then | |
cakey="$cakey-encrypted" | |
fi | |
if [[ -d "$dir" ]]; then | |
echo "error: $dir/ exists" | |
exit 1 | |
fi | |
mkdir "$dir" | |
cat "`dirname "$0"`"/openssl.default.cfg | sed -e "s/{{CAKEY}}/$cakey/" > "$dir/openssl.cfg" | |
cd "$dir" | |
# Because we want to explicitly set the default start and end dates (see | |
# default_startdate, default_enddate in openssl.cfg), some hoops need to be | |
# jumped through: | |
# - A key + self-signed cert must be created | |
# - A CSR must be generated from that key | |
# - Then the self-signed cert must be used to sign the CSR | |
# First create a key + self-signed certificate | |
openssl req -new -x509 -config ./openssl.cfg \ | |
-keyout "$cakey" \ | |
-out "temp_cert.crt" \ | |
-subj "$subj" \ | |
$nodes \ | |
-extensions "standard_ca" | |
mkdir "certs" | |
touch "database" | |
echo "0001" > "serial" | |
# Generate a new CSR from the private key | |
openssl req -new -config ./openssl.cfg \ | |
-key "$cakey" \ | |
-out "temp_csr.csr" \ | |
-subj "$subj" \ | |
$nodes \ | |
-extensions "standard_ca" | |
# Use the self-signed certificate to sign the CSR, producing the final | |
# certificate. | |
openssl ca -config ./openssl.cfg \ | |
-batch \ | |
-cert "temp_cert.crt" \ | |
-out "ca.crt" \ | |
-in "temp_csr.csr" \ | |
-extensions "standard_ca" | |
# Optionally, export the cert in pkcs12 format | |
#openssl pkcs12 -export -in "$cakey" -out "ca.p12" | |
# Cleanup! | |
rm temp_* |
This file contains 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 | |
set -e | |
usage() { | |
echo "usage: $0 [-server] [-des] ca keyname" | |
echo " -server include 'nsCertType=server' in the certificate" | |
echo " (for use with OpenVPN's 'ns-cert-type' option)" | |
echo " -des also include an encrypted private key" | |
} | |
extensions="standard" | |
nodes="-nodes" | |
while :; do | |
if [[ $# -eq 2 ]]; then | |
break | |
fi | |
case "${1-}" in | |
"-server") | |
extensions="server" | |
shift | |
;; | |
"-des") | |
nodes="" | |
shift | |
;; | |
**) | |
usage | |
exit 2 | |
;; | |
esac | |
done | |
ca="${1%/}" | |
keyname="$2" | |
subj="/C=CA/ST=Ontario/L=Toronto/O=Luminautics Inc./CN=$keyname" | |
if [[ ! -d "$ca" ]]; then | |
echo "error: can't find $ca/" | |
exit 1 | |
fi | |
cd "$ca/" | |
echo "--- creating key ---" | |
keyfile="$keyname-temp.key" | |
reqfile="$keyname-temp.csr" | |
crtfile="$keyname-temp.crt" | |
openssl req -new -config ./openssl.cfg \ | |
-keyout "$keyfile" \ | |
-out "$reqfile" \ | |
-subj "$subj" \ | |
-nodes \ | |
-extensions "$extensions" | |
if [[ -f "passphrase" ]]; then | |
echo "==========" | |
echo "PASSWORD: `cat passphrase`" | |
echo "==========" | |
fi | |
openssl ca -config ./openssl.cfg \ | |
-batch \ | |
-noemailDN \ | |
-in "$reqfile" \ | |
-out "$crtfile" \ | |
-extensions "$extensions" | |
pemfile="certs/$keyname.pem" | |
if [[ "$nodes" ]]; then | |
cat "$crtfile" "$keyfile" > "$pemfile" | |
echo "$ca/$pemfile created." | |
else | |
# Store an encrypted copy of the certificate in the CA's store | |
openssl rsa '-in' "$keyfile" -des3 -out "$keyfile-encrypted" | |
cat "$crtfile" "$keyfile-encrypted" > "$pemfile-encrypted" | |
echo "$ca/$pemfile-encrypted created." | |
# And stick an unencrypted copy of the certificate in /tmp/ | |
touch "/tmp/$keyname.pem" | |
chmod 600 "/tmp/$keyname.pem" | |
cat "$crtfile" "$keyfile" > "/tmp/$keyname.pem" | |
echo "/tmp/$keyname.pem created" | |
fi | |
rm "$keyname-temp"* |
This file contains 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
# | |
# OpenSSL configuration file. | |
# | |
# Establish working directory. | |
dir = . | |
[ ca ] | |
default_ca = CA_default | |
[ CA_default ] | |
serial = $dir/serial | |
database = $dir/database | |
new_certs_dir = $dir/certs | |
certificate = $dir/ca.crt | |
private_key = $dir/{{CAKEY}} | |
default_md = sha1 | |
preserve = no | |
nameopt = default_ca | |
certopt = default_ca | |
policy = policy_match | |
default_days = | |
default_startdate = 700101000001Z | |
default_enddate = 300101000000Z | |
[ policy_match ] | |
countryName = optional | |
stateOrProvinceName = optional | |
localityName = optional | |
organizationName = optional | |
organizationalUnitName = optional | |
commonName = supplied | |
emailAddress = optional | |
[ req ] | |
default_bits = 1024 # Size of keys | |
default_keyfile = key.pem # name of generated keys | |
default_md = sha1 # message digest algorithm | |
string_mask = nombstr # permitted characters | |
distinguished_name = req_distinguished_name | |
[ req_distinguished_name ] | |
#0.organizationName = Organization Name (company) | |
#organizationalUnitName = Organizational Unit Name (department, division) | |
#emailAddress = Email Address | |
#emailAddress_max = 40 | |
#localityName = Locality Name (city, district) | |
#stateOrProvinceName = State or Province Name (full name) | |
#countryName = Country Name (2 letter code) | |
#countryName_min = 2 | |
#countryName_max = 2 | |
#commonName = commonName (hostname) | |
#commonName_max = 64 | |
#0.organizationName_default = David Wolever | |
#organizationalUnitName_defaul = | |
#emailAddress_default = david@wolever.net | |
#localityName_default = Toronto | |
#stateOrProvinceName_default = Ontario | |
#countryName_default = CA | |
# | |
# Custom extension definitions | |
# | |
[ standard_ca ] | |
basicConstraints = CA:TRUE | |
subjectKeyIdentifier = hash | |
authorityKeyIdentifier = keyid:always | |
[ standard ] | |
basicConstraints = CA:FALSE | |
subjectKeyIdentifier = hash | |
authorityKeyIdentifier = keyid:always,issuer:always | |
[ server ] | |
basicConstraints = CA:FALSE | |
subjectKeyIdentifier = hash | |
authorityKeyIdentifier = keyid:always,issuer:always | |
nsCertType = server |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment