1#!/bin/ksh 2 3# 4# Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org> 5# 6# Permission to use, copy, modify, and distribute this software for any 7# purpose with or without fee is hereby granted, provided that the above 8# copyright notice and this permission notice appear in all copies. 9# 10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17# 18 19set -e 20set -u 21set -x 22 23readonly SUBJECT="/CN=LibreSSL Test" 24 25readonly TMPDIR=$(mktemp -d) 26 27cleanup() { 28 rm -rf "${TMPDIR}" 29} 30 31trap cleanup EXIT INT 32 33reset() { 34 echo '100001' > ${TMPDIR}/certserial 35 cat /dev/null > ${TMPDIR}/certindex 36} 37 38setup() { 39 reset 40 41 cat > ${TMPDIR}/openssl.cnf <<EOF 42[ca] 43default_ca = test_ca 44 45[test_ca] 46new_certs_dir = ${TMPDIR}/ 47database = ${TMPDIR}/certindex 48default_days = 365 49default_md = sha256 50policy = test_policy 51serial = ${TMPDIR}/certserial 52 53[test_policy] 54countryName = optional 55stateOrProvinceName = optional 56localityName = optional 57organizationName = optional 58organizationalUnitName = optional 59commonName = supplied 60emailAddress = optional 61 62[v3_ca_root] 63subjectKeyIdentifier = hash 64authorityKeyIdentifier = keyid:always,issuer 65basicConstraints = critical, CA:true 66keyUsage = critical, cRLSign, keyCertSign 67 68[v3_ca_int] 69subjectKeyIdentifier = hash 70authorityKeyIdentifier = keyid:always,issuer 71basicConstraints = critical, CA:true 72keyUsage = critical, cRLSign, keyCertSign 73 74[v3_other] 75subjectKeyIdentifier = hash 76authorityKeyIdentifier = keyid:always,issuer 77basicConstraints = critical, CA:false 78keyUsage = critical, digitalSignature 79 80[req] 81distinguished_name = req_distinguished_name 82 83[ req_distinguished_name ] 84EOF 85} 86 87key_type_to_args() { 88 local key_type=$1 89 90 alg=${key_type%:*} 91 param=${key_type#*:} 92 93 if [[ "${alg}" == "rsa" ]]; then 94 echo "-newkey ${key_type}"; 95 elif [[ "${alg}" == "ec" ]]; then 96 echo "-newkey $alg -pkeyopt ec_paramgen_curve:${param}" 97 else 98 echo "Unknown key type ${key_type}" >&2 99 exit 1 100 fi 101} 102 103create_root() { 104 local name=$1 file=$2 key_type=$3 105 106 key_args=$(key_type_to_args "${key_type}") 107 108 openssl req -new -days 3650 -nodes ${key_args} -sha256 -x509 \ 109 -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ 110 -config ${TMPDIR}/openssl.cnf -extensions v3_ca_root \ 111 -out "${TMPDIR}/${file}.crt" 112} 113 114create_intermediate() { 115 local name=$1 file=$2 issuer_file=$3 key_type=$4 116 117 key_args=$(key_type_to_args "${key_type}") 118 119 openssl req -new -days 3650 -nodes ${key_args} -sha256 \ 120 -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ 121 -out "${TMPDIR}/${file}.csr" 122 openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ 123 -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial \ 124 -extfile ${TMPDIR}/openssl.cnf -extensions v3_ca_int \ 125 -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" 126} 127 128create_leaf() { 129 local name=$1 file=$2 issuer_file=$3 key_type=$4 130 131 key_args=$(key_type_to_args "${key_type}") 132 133 openssl req -new -days 3650 -nodes ${key_args} -sha256 \ 134 -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ 135 -out "${TMPDIR}/${file}.csr" 136 openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ 137 -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial -sha256 \ 138 -extfile ${TMPDIR}/openssl.cnf -extensions v3_other \ 139 -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" 140} 141 142create_expired_leaf() { 143 local name=$1 file=$2 issuer_file=$3 key_type=$4 144 145 key_args=$(key_type_to_args "${key_type}") 146 147 openssl req -new -days 3650 -nodes ${key_args} -sha256 \ 148 -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ 149 -out "${TMPDIR}/${file}.csr" 150 openssl ca -batch -notext -cert "${TMPDIR}/${issuer_file}.crt" \ 151 -keyfile "${TMPDIR}/${issuer_file}.key" \ 152 -config ${TMPDIR}/openssl.cnf -extensions v3_other \ 153 -startdate 20100101000000Z -enddate 20200101000000Z \ 154 -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" 155} 156 157create_revoked_leaf() { 158 local name=$1 file=$2 issuer_file=$3 key_type=$4 159 160 key_args=$(key_type_to_args "${key_type}") 161 162 openssl req -new -days 3650 -nodes ${key_args} -sha256 \ 163 -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ 164 -out "${TMPDIR}/${file}.csr" 165 openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ 166 -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial \ 167 -extfile ${TMPDIR}/openssl.cnf -extensions v3_other \ 168 -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" 169 openssl ca -cert "${TMPDIR}/${issuer_file}.crt" \ 170 -keyfile "${TMPDIR}/${issuer_file}.key" \ 171 -config "${TMPDIR}/openssl.cnf" -extensions v3_other \ 172 -revoke "${TMPDIR}/${file}.crt" 173 openssl ca -gencrl -cert "${TMPDIR}/${issuer_file}.crt" \ 174 -keyfile "${TMPDIR}/${issuer_file}.key" \ 175 -config "${TMPDIR}/openssl.cnf" -extensions v3_other \ 176 -crldays 30 -out "${TMPDIR}/${issuer_file}.crl" 177} 178 179create_bundle() { 180 local bundle_file=$1 181 shift 182 183 mkdir -p $(dirname ${bundle_file}) 184 cat /dev/null > ${bundle_file} 185 186 for _cert_file in $@; do 187 openssl x509 -nameopt oneline -subject -issuer \ 188 -in "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} 189 done 190} 191 192create_bundle_with_key() { 193 local bundle_file=$1 194 shift 195 196 mkdir -p $(dirname ${bundle_file}) 197 cat /dev/null > ${bundle_file} 198 199 for _cert_file in $@; do 200 openssl x509 -nameopt oneline -subject -issuer -noout \ 201 -in "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} 202 done 203 for _cert_file in $@; do 204 cat "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} 205 done 206 for _key_file in $@; do 207 cat "${TMPDIR}/${_key_file}.key" >> ${bundle_file} 208 done 209} 210 211setup 212 213reset 214create_root "Root CA RSA" "ca-root-rsa" "rsa:2048" 215create_intermediate "Intermediate CA RSA" "ca-int-rsa" "ca-root-rsa" "rsa:2048" 216create_leaf "Server 1 RSA" "server-1-rsa" "ca-int-rsa" "rsa:2048" 217create_expired_leaf "Server 2 RSA" "server-2-rsa" "ca-int-rsa" "rsa:2048" 218create_revoked_leaf "Server 3 RSA" "server-3-rsa" "ca-int-rsa" "rsa:2048" 219create_leaf "Client 1 RSA" "client-1-rsa" "ca-int-rsa" "rsa:2048" 220create_expired_leaf "Client 2 RSA" "client-2-rsa" "ca-int-rsa" "rsa:2048" 221create_revoked_leaf "Client 3 RSA" "client-3-rsa" "ca-int-rsa" "rsa:2048" 222 223create_bundle "./ca-root-rsa.pem" "ca-root-rsa" 224create_bundle "./ca-int-rsa.pem" "ca-int-rsa" 225cp "${TMPDIR}/ca-int-rsa.crl" "./ca-int-rsa.crl" 226create_bundle_with_key "./server1-rsa.pem" "server-1-rsa" 227create_bundle "./server1-rsa-chain.pem" "server-1-rsa" "ca-int-rsa" 228create_bundle_with_key "./server2-rsa.pem" "server-2-rsa" 229create_bundle "./server2-rsa-chain.pem" "server-2-rsa" "ca-int-rsa" 230create_bundle_with_key "./server3-rsa.pem" "server-3-rsa" 231create_bundle "./server3-rsa-chain.pem" "server-3-rsa" "ca-int-rsa" 232create_bundle_with_key "./client1-rsa.pem" "client-1-rsa" 233create_bundle "./client1-rsa-chain.pem" "client-1-rsa" "ca-int-rsa" 234create_bundle_with_key "./client2-rsa.pem" "client-2-rsa" 235create_bundle "./client2-rsa-chain.pem" "client-2-rsa" "ca-int-rsa" 236create_bundle_with_key "./client3-rsa.pem" "client-3-rsa" 237create_bundle "./client3-rsa-chain.pem" "client-3-rsa" "ca-int-rsa" 238 239reset 240create_root "Root CA ECDSA" "ca-root-ecdsa" "ec:prime256v1" 241create_intermediate "Intermediate CA ECDSA" "ca-int-ecdsa" "ca-root-ecdsa" "ec:prime256v1" 242create_leaf "Server 1 ECDSA" "server-1-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 243create_expired_leaf "Server 2 ECDSA" "server-2-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 244create_revoked_leaf "Server 3 ECDSA" "server-3-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 245create_leaf "Client 1 ECDSA" "client-1-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 246create_expired_leaf "Client 2 ECDSA" "client-2-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 247create_revoked_leaf "Client 3 ECDSA" "client-3-ecdsa" "ca-int-ecdsa" "ec:prime256v1" 248 249create_bundle "./ca-root-ecdsa.pem" "ca-root-ecdsa" 250create_bundle "./ca-int-ecdsa.pem" "ca-int-ecdsa" 251cp "${TMPDIR}/ca-int-ecdsa.crl" "./ca-int-ecdsa.crl" 252create_bundle_with_key "./server1-ecdsa.pem" "server-1-ecdsa" 253create_bundle "./server1-ecdsa-chain.pem" "server-1-ecdsa" "ca-int-ecdsa" 254create_bundle_with_key "./server2-ecdsa.pem" "server-2-ecdsa" 255create_bundle "./server2-ecdsa-chain.pem" "server-2-ecdsa" "ca-int-ecdsa" 256create_bundle_with_key "./server3-ecdsa.pem" "server-3-ecdsa" 257create_bundle "./server3-ecdsa-chain.pem" "server-3-ecdsa" "ca-int-ecdsa" 258create_bundle_with_key "./client1-ecdsa.pem" "client-1-ecdsa" 259create_bundle "./client1-ecdsa-chain.pem" "client-1-ecdsa" "ca-int-ecdsa" 260create_bundle_with_key "./client2-ecdsa.pem" "client-2-ecdsa" 261create_bundle "./client2-ecdsa-chain.pem" "client-2-ecdsa" "ca-int-ecdsa" 262create_bundle_with_key "./client3-ecdsa.pem" "client-3-ecdsa" 263create_bundle "./client3-ecdsa-chain.pem" "client-3-ecdsa" "ca-int-ecdsa" 264