Skip to content

Instantly share code, notes, and snippets.

@riyad
Last active November 17, 2018 22:35
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riyad/e9dd6e688ea5de69a65a to your computer and use it in GitHub Desktop.
Save riyad/e9dd6e688ea5de69a65a to your computer and use it in GitHub Desktop.
Using CFSSL building your own CA and generating service specific key, cert and chain files.
{
"CN": "Another Intermediate CA",
"hosts": [
""
],
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
}
]
}
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"intermediate": {
"ca_constraint": {
"is_ca": true
},
"usages": [
"cert sign",
"crl sign"
],
"expiry": "8760h"
},
"server": {
"usages": [
"server auth"
],
"expiry": "8760h"
}
}
}
}
{
"CN": "some.foo.tld",
"hosts": [
"some.foo.tld"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"OU": "IMAP Service"
}
]
}
{
"CN": "some.foo.tld",
"hosts": [
"some.foo.tld"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"OU": "SMTP Service"
}
]
}
{
"CN": "Foo Root CA",
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
}
]
}
{
"CN": "some.foo.tld",
"hosts": [
"some.foo.tld"
],
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
"OU": "Web Service"
}
]
}
#!/bin/bash
#
# Author: Riyad Preukschas <riyad@informatik.uni-bremen.de>
# License: MIT
#
# Generates root, internediate CA and service keys.
function generate_root_ca() {
local root_ca="$1"
echo "Generating root CA into ${root_ca}/"
[[ ! -d "${root_ca}" ]] && mkdir "${root_ca}"
cfssl genkey -initca "${root_ca}_csr.json" | cfssljson -bare "${root_ca}/root"
}
function generate_intermediate_ca() {
local root_ca="$1"
local intermediate_ca="$2"
echo "Generating intermediate CA into ${intermediate_ca}/ (for root CA ${root_ca}/)"
[[ ! -d "${intermediate_ca}" ]] && mkdir "${intermediate_ca}"
cfssl gencert -ca "${root_ca}/root.pem" -ca-key "${root_ca}/root-key.pem" -config="config.json" -profile="intermediate" "${intermediate_ca}_csr.json" | cfssljson -bare "${intermediate_ca}/intermediate"
}
function generate_service_keys() {
local root_ca="$1"
local intermediate_ca="$2"
local service_type="$3"
local key_name="$4"
local dist_dir="${intermediate_ca}/dist"
echo "Generating ${service_type} key pair into ${intermediate_ca}/"
[[ ! -d "${dist_dir}" ]] && mkdir "${dist_dir}"
cfssl gencert -ca "${intermediate_ca}/intermediate.pem" -ca-key "${intermediate_ca}/intermediate-key.pem" -config="config.json" -profile="server" "${key_name}_csr.json" | cfssljson -bare "${intermediate_ca}/${key_name}"
cp "${intermediate_ca}/${key_name}.pem" "${dist_dir}/"
cp "${intermediate_ca}/${key_name}-key.pem" "${dist_dir}/"
case "${service_type}" in
dovecot)
cat "${intermediate_ca}/intermediate.pem" "${root_ca}/root.pem" > "${dist_dir}/${key_name}-cachain.pem"
;;
nginx)
cat "${intermediate_ca}/${key_name}.pem" "${intermediate_ca}/intermediate.pem" "${root_ca}/root.pem" > "${dist_dir}/${key_name}.pem"
;;
postfix)
cat "${intermediate_ca}/intermediate.pem" "${root_ca}/root.pem" > "${dist_dir}/${key_name}-cachain.pem"
;;
esac
}
# Foo root CA
ROOT_CA="foo-root-ca"
#generate_root_ca "${ROOT_CA}"
# Some intermediate CA
generate_intermediate_ca "${ROOT_CA}" "some-intermediate-ca"
generate_service_keys "${ROOT_CA}" "some-intermediate-ca" "nginx" "foo-some-web"
# Another intermediate CA
generate_intermediate_ca "${ROOT_CA}" "another-intermediate-ca"
generate_service_keys "${ROOT_CA}" "some-intermediate-ca" "dovecot" "foo-another-imap"
generate_service_keys "${ROOT_CA}" "some-intermediate-ca" "postfix" "foo-another-smtp"
{
"CN": "Some Intermediate CA",
"hosts": [
""
],
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
}
]
}
@mgoodness
Copy link

Thanks for this. PKI is still way too difficult to sort out.

@riyad
Copy link
Author

riyad commented Oct 4, 2016

Fixed some issues with this Gist:

  • Updated cfssl_config.json:
    • Made newer versions of cfssl recognize the the is_ca option for intermediate CAs
    • Removed unnecessary entries in usages sections
  • Renamed intermediate CAs
  • Added missing example CSRs
  • Updated renew-certs.sh:
    • Now checks if directories exist before running mkdir (produces cleaner logs)
    • Example can now be run without errors

@riyad
Copy link
Author

riyad commented Oct 8, 2017

Update:

  • Cleaned up renew-certs.sh by extracting functions for generating root CA, intermediate CA and service keys.

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