Skip to content

Instantly share code, notes, and snippets.

@arnehormann
Last active April 20, 2016 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnehormann/5875687 to your computer and use it in GitHub Desktop.
Save arnehormann/5875687 to your computer and use it in GitHub Desktop.
create openssl certificates for ca, server and user (email); and sign them
#!/bin/bash
# crash on error exit codes and undefined variables
set -e -u
if [ "true" = "$TRACE" ]; then
# trace execution (+x to get rid of noise)
set -x
fi
DOMAIN='example.com'
EMAIL="me@$DOMAIN"
USER="$EMAIL"
COMPANY="ExampleLtd"
SUBJECT_PREFIX="/C=US/ST=CA/L=San Francisco/O=$COMPANY/OU="
CA_NAME="$COMPANY-CA"
CA_EMAIL="ssl-ca@$DOMAIN"
EMAIL_SERVER="mail.$DOMAIN"
EMAIL_SERVER_EMAIL="postmaster@$DOMAIN"
EMAIL_SERVER_DAYSVALID=3650
CA_DAYSVALID=3650
DAYSVALID=365
CA_KEY="$CA_NAME.key"
CA_CERT="$CA_NAME.pem"
EMAIL_SERVER_CSR="$EMAIL_SERVER.csr"
EMAIL_SERVER_KEY="$EMAIL_SERVER.key"
EMAIL_SERVER_CERT="$EMAIL_SERVER.pem"
USER_CSR="$EMAIL.csr"
USER_KEY="$EMAIL.key"
USER_CERT="$EMAIL.pem"
USER_P12="$EMAIL.pfx"
DIGEST=sha1
ENCRYPT_REQ=rsa
ENCRYPT_REQ_BITS=2048
ENCRYPT_PKCS=aes128
# source of entropy
RAND_SOURCE=/dev/urandom
# ephermal minimal config file
OPENSSL_CONF=$(cat <<EOF_SSL_CONF
[req]
distinguished_name=rdn
[rdn]
C=.
ST=.
L=.
O=.
OU=.
CN=.
EOF_SSL_CONF)
# create a serial number derived from a file
# It prints a serial which is max 20 bytes long when represented as positive integer
# ARGUMENTS
# $1 = filename
# $2 = prefix (salt?) - must be [0-9a-fA-F]*
# DEPENDENCIES
# sha1sum or shasum, cut, tr, bc
sslserial() {
if [ "$#" != 1 ] && [ "$#" != 2 ]; then
echo 'sslserial must be called with a filename and an optional prefix'
exit 2
fi
# get sha1 checksum of file (sha1sum for Linux, shasum in OS X)
SHA1=$($(which sha1sum || which shasum) "$1")
# prepend the prefix, take the first 40 hex chars, convert to title case
SHA1SLICE=$(echo "$2$SHA1" | cut -b 1-40 | tr a-f A-F)
# convert from hexadecimal to decimal
bc -q <<EOF_BC_CONF
obase=10
ibase=16
$SHA1SLICE
EOF_BC_CONF
}
if [ ! -f "$CA_KEY" ] || [ ! -f "$CA_CERT" ]; then
# Create the CA key pair
openssl req\
-config <(echo "$OPENSSL_CONF") -rand "$RAND_SOURCE"\
-x509 -days "$CA_DAYSVALID"\
-nodes -newkey "$ENCRYPT_REQ:$ENCRYPT_REQ_BITS" -"$DIGEST"\
-subj "$SUBJECT_PREFIX/CN=$CA_NAME/emailAddress=$CA_EMAIL"\
-keyout "$CA_KEY" -out "$CA_CERT"
fi
if [ ! -f "$EMAIL_SERVER_KEY" ] && [ ! -f "$EMAIL_SERVER_CERT" ]; then
# Create the server key pair
openssl req\
-config <(echo "$OPENSSL_CONF") -rand "$RAND_SOURCE"\
-new -days "$EMAIL_SERVER_DAYSVALID"\
-nodes -newkey "$ENCRYPT_REQ:$ENCRYPT_REQ_BITS" -"$DIGEST"\
-subj "$SUBJECT_PREFIX/CN=$EMAIL_SERVER/emailAddress=$EMAIL_SERVER_EMAIL"\
-keyout "$EMAIL_SERVER_KEY" -out "$EMAIL_SERVER_CSR"
# Sign the server key
openssl x509\
-in "$EMAIL_SERVER_CSR" -CA "$CA_CERT" -CAkey "$CA_KEY"\
-set_serial $(sslserial "$EMAIL_SERVER_KEY" "1")\
-req -days "$DAYSVALID"\
-out "$EMAIL_SERVER_CERT"
fi
# Create a key and a signing request.
# Could use [-nodes] or [-passout <(echo "$PASSWORD")] after a PASSOWORD=read?
openssl req\
-config <(echo "$OPENSSL_CONF") -rand "$RAND_SOURCE"\
-new -days "$EMAIL_SERVER_DAYSVALID"\
-nodes -newkey "$ENCRYPT_REQ:$ENCRYPT_REQ_BITS" -"$DIGEST"\
-subj "$SUBJECT_PREFIX/CN=$USER/emailAddress=$EMAIL"\
-keyout "$USER_KEY" -out "$USER_CSR"
# Sign the certificate, get the PEM file
openssl x509\
-in "$USER_CSR" -CAkey "$CA_KEY" -CA "$CA_CERT"\
-set_serial $(sslserial "$USER_KEY" "E")\
-req -days "$DAYSVALID"\
-out "$USER_CERT"
# convert our PEM to PKCS12
openssl pkcs12 -"$ENCRYPT_PKCS" -export -in "$USER_CERT" -inkey "$USER_KEY" -out "$USER_P12"
# delete leftovers?
#rm "$EMAIL_SERVER_CSR" "$USER_CSR"
@arnehormann
Copy link
Author

... and for inspection...

# textual representation
openssl x509 -noout -text -in ???.pem
# asn1 raw data
openssl asn1parse -inform PEM -in ???.pem

@arnehormann
Copy link
Author

openssl and ssh-keygen to create ssh keys:
http://serverfault.com/questions/358239/choosing-the-encryption-algorithm-used-by-osx-ssh-keygen/358247#358247

You could generate your key using OpenSSL directly.

# create 1024 bit rsa and encrypt with des3 
#    make sure you set your umask or chmod this so that it is 0600, 
#    or else ssh will refuse to use it.
openssl genrsa -des3 -out .ssh/id_rsa 1024
chmod 0600 .ssh/id_rsa
# export an ssh public key
ssh-keygen -y -f .ssh/id_rsa > .ssh/id_rsa.pub

You could also convert the cipher of an existing key after the fact using OpenSSL.

openssl rsa -in id_rsa -out newkey_id_rsa -des3

and
http://security.stackexchange.com/questions/32768/converting-keys-between-openssl-and-openssh

Putty-export:

apt-get install putty-tools
puttygen SSHKEY -o PUTTYKEY.ppk -C "COMMENT"

and signed SSH keys:
https://www.digitalocean.com/community/tutorials/how-to-create-an-ssh-ca-to-validate-hosts-and-clients-with-ubuntu

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