1*e0c4386eSCy Schubert#! /bin/bash 2*e0c4386eSCy Schubert# 3*e0c4386eSCy Schubert# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. 4*e0c4386eSCy Schubert# Copyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>. 5*e0c4386eSCy Schubert# All rights reserved. 6*e0c4386eSCy Schubert# 7*e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License"). You may not use 8*e0c4386eSCy Schubert# this file except in compliance with the License. You can obtain a copy 9*e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at 10*e0c4386eSCy Schubert# https://www.openssl.org/source/license.html 11*e0c4386eSCy Schubert 12*e0c4386eSCy Schubert# This file is dual-licensed and is also available under other terms. 13*e0c4386eSCy Schubert# Please contact the author. 14*e0c4386eSCy Schubert 15*e0c4386eSCy Schubert# 100 years should be enough for now 16*e0c4386eSCy Schubertif [ -z "$DAYS" ]; then 17*e0c4386eSCy Schubert DAYS=36525 18*e0c4386eSCy Schubertfi 19*e0c4386eSCy Schubert 20*e0c4386eSCy Schubertif [ -z "$OPENSSL_SIGALG" ]; then 21*e0c4386eSCy Schubert OPENSSL_SIGALG=sha256 22*e0c4386eSCy Schubertfi 23*e0c4386eSCy Schubert 24*e0c4386eSCy Schubertif [ -z "$REQMASK" ]; then 25*e0c4386eSCy Schubert REQMASK=utf8only 26*e0c4386eSCy Schubertfi 27*e0c4386eSCy Schubert 28*e0c4386eSCy Schubertstderr_onerror() { 29*e0c4386eSCy Schubert ( 30*e0c4386eSCy Schubert err=$("$@" >&3 2>&1) || { 31*e0c4386eSCy Schubert printf "%s\n" "$err" >&2 32*e0c4386eSCy Schubert exit 1 33*e0c4386eSCy Schubert } 34*e0c4386eSCy Schubert ) 3>&1 35*e0c4386eSCy Schubert} 36*e0c4386eSCy Schubert 37*e0c4386eSCy Schubertkey() { 38*e0c4386eSCy Schubert local key=$1; shift 39*e0c4386eSCy Schubert 40*e0c4386eSCy Schubert local alg=rsa 41*e0c4386eSCy Schubert if [ -n "$OPENSSL_KEYALG" ]; then 42*e0c4386eSCy Schubert alg=$OPENSSL_KEYALG 43*e0c4386eSCy Schubert fi 44*e0c4386eSCy Schubert 45*e0c4386eSCy Schubert local bits=2048 46*e0c4386eSCy Schubert if [ -n "$OPENSSL_KEYBITS" ]; then 47*e0c4386eSCy Schubert bits=$OPENSSL_KEYBITS 48*e0c4386eSCy Schubert fi 49*e0c4386eSCy Schubert 50*e0c4386eSCy Schubert if [ ! -f "${key}.pem" ]; then 51*e0c4386eSCy Schubert args=(-algorithm "$alg") 52*e0c4386eSCy Schubert case $alg in 53*e0c4386eSCy Schubert rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );; 54*e0c4386eSCy Schubert ec) args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits") 55*e0c4386eSCy Schubert args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);; 56*e0c4386eSCy Schubert dsa) args=(-paramfile "$bits");; 57*e0c4386eSCy Schubert ed25519) ;; 58*e0c4386eSCy Schubert ed448) ;; 59*e0c4386eSCy Schubert *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;; 60*e0c4386eSCy Schubert esac 61*e0c4386eSCy Schubert stderr_onerror \ 62*e0c4386eSCy Schubert openssl genpkey "${args[@]}" -out "${key}.pem" 63*e0c4386eSCy Schubert fi 64*e0c4386eSCy Schubert} 65*e0c4386eSCy Schubert 66*e0c4386eSCy Schubert# Usage: $0 req keyname dn1 dn2 ... 67*e0c4386eSCy Schubertreq() { 68*e0c4386eSCy Schubert local key=$1; shift 69*e0c4386eSCy Schubert 70*e0c4386eSCy Schubert key "$key" 71*e0c4386eSCy Schubert local errs 72*e0c4386eSCy Schubert 73*e0c4386eSCy Schubert stderr_onerror \ 74*e0c4386eSCy Schubert openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \ 75*e0c4386eSCy Schubert -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \ 76*e0c4386eSCy Schubert "$REQMASK" "prompt = no" "distinguished_name = dn" 77*e0c4386eSCy Schubert for dn in "$@"; do echo "$dn"; done) 78*e0c4386eSCy Schubert} 79*e0c4386eSCy Schubert 80*e0c4386eSCy Schubertreq_nocn() { 81*e0c4386eSCy Schubert local key=$1; shift 82*e0c4386eSCy Schubert 83*e0c4386eSCy Schubert key "$key" 84*e0c4386eSCy Schubert stderr_onerror \ 85*e0c4386eSCy Schubert openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \ 86*e0c4386eSCy Schubert -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \ 87*e0c4386eSCy Schubert "distinguished_name = dn") 88*e0c4386eSCy Schubert} 89*e0c4386eSCy Schubert 90*e0c4386eSCy Schubertcert() { 91*e0c4386eSCy Schubert local cert=$1; shift 92*e0c4386eSCy Schubert local exts=$1; shift 93*e0c4386eSCy Schubert 94*e0c4386eSCy Schubert stderr_onerror \ 95*e0c4386eSCy Schubert openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \ 96*e0c4386eSCy Schubert -extfile <(printf "%s\n" "$exts") "$@" 97*e0c4386eSCy Schubert} 98*e0c4386eSCy Schubert 99*e0c4386eSCy Schubertgenroot() { 100*e0c4386eSCy Schubert local cn=$1; shift 101*e0c4386eSCy Schubert local key=$1; shift 102*e0c4386eSCy Schubert local cert=$1; shift 103*e0c4386eSCy Schubert local bcon="basicConstraints = critical,CA:true" 104*e0c4386eSCy Schubert local ku="keyUsage = keyCertSign,cRLSign" 105*e0c4386eSCy Schubert local skid="subjectKeyIdentifier = hash" 106*e0c4386eSCy Schubert local akid="authorityKeyIdentifier = keyid" 107*e0c4386eSCy Schubert 108*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n" "$bcon" "$ku" "$skid" "$akid") 109*e0c4386eSCy Schubert for eku in "$@" 110*e0c4386eSCy Schubert do 111*e0c4386eSCy Schubert exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku") 112*e0c4386eSCy Schubert done 113*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 114*e0c4386eSCy Schubert echo "$csr" | 115*e0c4386eSCy Schubert cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}" 116*e0c4386eSCy Schubert} 117*e0c4386eSCy Schubert 118*e0c4386eSCy Schubertgenca() { 119*e0c4386eSCy Schubert local OPTIND=1 120*e0c4386eSCy Schubert local purpose= 121*e0c4386eSCy Schubert 122*e0c4386eSCy Schubert while getopts p:c: o 123*e0c4386eSCy Schubert do 124*e0c4386eSCy Schubert case $o in 125*e0c4386eSCy Schubert p) purpose="$OPTARG";; 126*e0c4386eSCy Schubert c) certpol="$OPTARG";; 127*e0c4386eSCy Schubert *) echo "Usage: $0 genca [-p EKU][-c policyoid] cn keyname certname cakeyname cacertname" >&2 128*e0c4386eSCy Schubert return 1;; 129*e0c4386eSCy Schubert esac 130*e0c4386eSCy Schubert done 131*e0c4386eSCy Schubert 132*e0c4386eSCy Schubert shift $((OPTIND - 1)) 133*e0c4386eSCy Schubert local cn=$1; shift 134*e0c4386eSCy Schubert local key=$1; shift 135*e0c4386eSCy Schubert local cert=$1; shift 136*e0c4386eSCy Schubert local cakey=$1; shift 137*e0c4386eSCy Schubert local cacert=$1; shift 138*e0c4386eSCy Schubert local bcon="basicConstraints = critical,CA:true" 139*e0c4386eSCy Schubert local ku="keyUsage = keyCertSign,cRLSign" 140*e0c4386eSCy Schubert local skid="subjectKeyIdentifier = hash" 141*e0c4386eSCy Schubert local akid="authorityKeyIdentifier = keyid" 142*e0c4386eSCy Schubert 143*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n" "$bcon" "$ku" "$skid" "$akid") 144*e0c4386eSCy Schubert if [ -n "$purpose" ]; then 145*e0c4386eSCy Schubert exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$purpose") 146*e0c4386eSCy Schubert fi 147*e0c4386eSCy Schubert if [ -n "$NC" ]; then 148*e0c4386eSCy Schubert exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC") 149*e0c4386eSCy Schubert fi 150*e0c4386eSCy Schubert if [ -n "$certpol" ]; then 151*e0c4386eSCy Schubert exts=$(printf "%s\ncertificatePolicies = %s\n" "$exts" "$certpol") 152*e0c4386eSCy Schubert fi 153*e0c4386eSCy Schubert 154*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 155*e0c4386eSCy Schubert echo "$csr" | 156*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \ 157*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 158*e0c4386eSCy Schubert} 159*e0c4386eSCy Schubert 160*e0c4386eSCy Schubertgen_nonbc_ca() { 161*e0c4386eSCy Schubert local cn=$1; shift 162*e0c4386eSCy Schubert local key=$1; shift 163*e0c4386eSCy Schubert local cert=$1; shift 164*e0c4386eSCy Schubert local cakey=$1; shift 165*e0c4386eSCy Schubert local cacert=$1; shift 166*e0c4386eSCy Schubert local skid="subjectKeyIdentifier = hash" 167*e0c4386eSCy Schubert local akid="authorityKeyIdentifier = keyid" 168*e0c4386eSCy Schubert 169*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid") 170*e0c4386eSCy Schubert exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign") 171*e0c4386eSCy Schubert for eku in "$@" 172*e0c4386eSCy Schubert do 173*e0c4386eSCy Schubert exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku") 174*e0c4386eSCy Schubert done 175*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 176*e0c4386eSCy Schubert echo "$csr" | 177*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \ 178*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" 179*e0c4386eSCy Schubert} 180*e0c4386eSCy Schubert 181*e0c4386eSCy Schubert# Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ... 182*e0c4386eSCy Schubert# 183*e0c4386eSCy Schubert# Note: takes csr on stdin, so must be used with $0 req like this: 184*e0c4386eSCy Schubert# 185*e0c4386eSCy Schubert# $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ... 186*e0c4386eSCy Schubertgenpc() { 187*e0c4386eSCy Schubert local key=$1; shift 188*e0c4386eSCy Schubert local cert=$1; shift 189*e0c4386eSCy Schubert local cakey=$1; shift 190*e0c4386eSCy Schubert local ca=$1; shift 191*e0c4386eSCy Schubert 192*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n" \ 193*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 194*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer:always" \ 195*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 196*e0c4386eSCy Schubert "proxyCertInfo = critical, @pcexts"; 197*e0c4386eSCy Schubert echo "[pcexts]"; 198*e0c4386eSCy Schubert for x in "$@"; do echo $x; done) 199*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 200*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" 201*e0c4386eSCy Schubert} 202*e0c4386eSCy Schubert 203*e0c4386eSCy Schubertgeneeconfig() { 204*e0c4386eSCy Schubert local key=$1; shift 205*e0c4386eSCy Schubert local cert=$1; shift 206*e0c4386eSCy Schubert local cakey=$1; shift 207*e0c4386eSCy Schubert local ca=$1; shift 208*e0c4386eSCy Schubert local conf=$1; shift 209*e0c4386eSCy Schubert 210*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n" \ 211*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 212*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid" \ 213*e0c4386eSCy Schubert "basicConstraints = CA:false"; \ 214*e0c4386eSCy Schubert echo "$conf") 215*e0c4386eSCy Schubert 216*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 217*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" 218*e0c4386eSCy Schubert} 219*e0c4386eSCy Schubert 220*e0c4386eSCy Schubert# Usage: $0 geneealt keyname certname cakeyname cacertname alt1 alt2 ... 221*e0c4386eSCy Schubert# 222*e0c4386eSCy Schubert# Note: takes csr on stdin, so must be used with $0 req like this: 223*e0c4386eSCy Schubert# 224*e0c4386eSCy Schubert# $0 req keyname dn | $0 geneealt keyname certname cakeyname cacertname alt ... 225*e0c4386eSCy Schubertgeneealt() { 226*e0c4386eSCy Schubert local key=$1; shift 227*e0c4386eSCy Schubert local cert=$1; shift 228*e0c4386eSCy Schubert local cakey=$1; shift 229*e0c4386eSCy Schubert local ca=$1; shift 230*e0c4386eSCy Schubert 231*e0c4386eSCy Schubert conf=$(echo "subjectAltName = @alts" 232*e0c4386eSCy Schubert echo "[alts]"; 233*e0c4386eSCy Schubert for x in "$@"; do echo "$x"; done) 234*e0c4386eSCy Schubert 235*e0c4386eSCy Schubert geneeconfig $key $cert $cakey $ca "$conf" 236*e0c4386eSCy Schubert} 237*e0c4386eSCy Schubert 238*e0c4386eSCy Schubertgenee() { 239*e0c4386eSCy Schubert local OPTIND=1 240*e0c4386eSCy Schubert local purpose=serverAuth 241*e0c4386eSCy Schubert 242*e0c4386eSCy Schubert while getopts p: o 243*e0c4386eSCy Schubert do 244*e0c4386eSCy Schubert case $o in 245*e0c4386eSCy Schubert p) purpose="$OPTARG";; 246*e0c4386eSCy Schubert *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2 247*e0c4386eSCy Schubert return 1;; 248*e0c4386eSCy Schubert esac 249*e0c4386eSCy Schubert done 250*e0c4386eSCy Schubert 251*e0c4386eSCy Schubert shift $((OPTIND - 1)) 252*e0c4386eSCy Schubert local cn=$1; shift 253*e0c4386eSCy Schubert local key=$1; shift 254*e0c4386eSCy Schubert local cert=$1; shift 255*e0c4386eSCy Schubert local cakey=$1; shift 256*e0c4386eSCy Schubert local ca=$1; shift 257*e0c4386eSCy Schubert 258*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ 259*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 260*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 261*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 262*e0c4386eSCy Schubert "extendedKeyUsage = $purpose" \ 263*e0c4386eSCy Schubert "subjectAltName = @alts" "DNS=${cn}") 264*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 265*e0c4386eSCy Schubert echo "$csr" | 266*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 267*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 268*e0c4386eSCy Schubert} 269*e0c4386eSCy Schubert 270*e0c4386eSCy Schubertgeneeextra() { 271*e0c4386eSCy Schubert local OPTIND=1 272*e0c4386eSCy Schubert local purpose=serverAuth 273*e0c4386eSCy Schubert 274*e0c4386eSCy Schubert while getopts p: o 275*e0c4386eSCy Schubert do 276*e0c4386eSCy Schubert case $o in 277*e0c4386eSCy Schubert p) purpose="$OPTARG";; 278*e0c4386eSCy Schubert *) echo "Usage: $0 geneeextra [-p EKU] cn keyname certname cakeyname cacertname extraext" >&2 279*e0c4386eSCy Schubert return 1;; 280*e0c4386eSCy Schubert esac 281*e0c4386eSCy Schubert done 282*e0c4386eSCy Schubert 283*e0c4386eSCy Schubert shift $((OPTIND - 1)) 284*e0c4386eSCy Schubert local cn=$1; shift 285*e0c4386eSCy Schubert local key=$1; shift 286*e0c4386eSCy Schubert local cert=$1; shift 287*e0c4386eSCy Schubert local cakey=$1; shift 288*e0c4386eSCy Schubert local ca=$1; shift 289*e0c4386eSCy Schubert local extraext=$1; shift 290*e0c4386eSCy Schubert 291*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ 292*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 293*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 294*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 295*e0c4386eSCy Schubert "extendedKeyUsage = $purpose" \ 296*e0c4386eSCy Schubert "subjectAltName = @alts"\ 297*e0c4386eSCy Schubert "$extraext" "DNS=${cn}") 298*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 299*e0c4386eSCy Schubert echo "$csr" | 300*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 301*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 302*e0c4386eSCy Schubert} 303*e0c4386eSCy Schubert 304*e0c4386eSCy Schubertgeneenocsr() { 305*e0c4386eSCy Schubert local OPTIND=1 306*e0c4386eSCy Schubert local purpose=serverAuth 307*e0c4386eSCy Schubert 308*e0c4386eSCy Schubert while getopts p: o 309*e0c4386eSCy Schubert do 310*e0c4386eSCy Schubert case $o in 311*e0c4386eSCy Schubert p) purpose="$OPTARG";; 312*e0c4386eSCy Schubert *) echo "Usage: $0 geneenocsr [-p EKU] cn certname cakeyname cacertname" >&2 313*e0c4386eSCy Schubert return 1;; 314*e0c4386eSCy Schubert esac 315*e0c4386eSCy Schubert done 316*e0c4386eSCy Schubert 317*e0c4386eSCy Schubert shift $((OPTIND - 1)) 318*e0c4386eSCy Schubert local cn=$1; shift 319*e0c4386eSCy Schubert local cert=$1; shift 320*e0c4386eSCy Schubert local cakey=$1; shift 321*e0c4386eSCy Schubert local ca=$1; shift 322*e0c4386eSCy Schubert 323*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ 324*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 325*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 326*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 327*e0c4386eSCy Schubert "extendedKeyUsage = $purpose" \ 328*e0c4386eSCy Schubert "subjectAltName = @alts" "DNS=${cn}") 329*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 330*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 331*e0c4386eSCy Schubert} 332*e0c4386eSCy Schubert 333*e0c4386eSCy Schubertgenss() { 334*e0c4386eSCy Schubert local cn=$1; shift 335*e0c4386eSCy Schubert local key=$1; shift 336*e0c4386eSCy Schubert local cert=$1; shift 337*e0c4386eSCy Schubert 338*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ 339*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 340*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 341*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 342*e0c4386eSCy Schubert "extendedKeyUsage = serverAuth" \ 343*e0c4386eSCy Schubert "subjectAltName = @alts" "DNS=${cn}") 344*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 345*e0c4386eSCy Schubert echo "$csr" | 346*e0c4386eSCy Schubert cert "$cert" "$exts" -signkey "${key}.pem" \ 347*e0c4386eSCy Schubert -set_serial 1 -days "${DAYS}" "$@" 348*e0c4386eSCy Schubert} 349*e0c4386eSCy Schubert 350*e0c4386eSCy Schubertgennocn() { 351*e0c4386eSCy Schubert local key=$1; shift 352*e0c4386eSCy Schubert local cert=$1; shift 353*e0c4386eSCy Schubert 354*e0c4386eSCy Schubert csr=$(req_nocn "$key") || return 1 355*e0c4386eSCy Schubert echo "$csr" | 356*e0c4386eSCy Schubert cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@" 357*e0c4386eSCy Schubert} 358*e0c4386eSCy Schubert 359*e0c4386eSCy Schubertgenct() { 360*e0c4386eSCy Schubert local OPTIND=1 361*e0c4386eSCy Schubert local purpose=serverAuth 362*e0c4386eSCy Schubert 363*e0c4386eSCy Schubert while getopts p: o 364*e0c4386eSCy Schubert do 365*e0c4386eSCy Schubert case $o in 366*e0c4386eSCy Schubert p) purpose="$OPTARG";; 367*e0c4386eSCy Schubert *) echo "Usage: $0 genct [-p EKU] cn keyname certname cakeyname cacertname ctlogkey" >&2 368*e0c4386eSCy Schubert return 1;; 369*e0c4386eSCy Schubert esac 370*e0c4386eSCy Schubert done 371*e0c4386eSCy Schubert 372*e0c4386eSCy Schubert shift $((OPTIND - 1)) 373*e0c4386eSCy Schubert local cn=$1; shift 374*e0c4386eSCy Schubert local key=$1; shift 375*e0c4386eSCy Schubert local cert=$1; shift 376*e0c4386eSCy Schubert local cakey=$1; shift 377*e0c4386eSCy Schubert local ca=$1; shift 378*e0c4386eSCy Schubert local logkey=$1; shift 379*e0c4386eSCy Schubert 380*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ 381*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 382*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 383*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 384*e0c4386eSCy Schubert "extendedKeyUsage = $purpose" \ 385*e0c4386eSCy Schubert "1.3.6.1.4.1.11129.2.4.3 = critical,ASN1:NULL"\ 386*e0c4386eSCy Schubert "subjectAltName = @alts" "DNS=${cn}") 387*e0c4386eSCy Schubert csr=$(req "$key" "CN = $cn") || return 1 388*e0c4386eSCy Schubert echo "$csr" | 389*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 390*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 391*e0c4386eSCy Schubert cat ${cert}.pem ${ca}.pem > ${cert}-chain.pem 392*e0c4386eSCy Schubert go run github.com/google/certificate-transparency-go/ctutil/sctgen \ 393*e0c4386eSCy Schubert --log_private_key ${logkey}.pem \ 394*e0c4386eSCy Schubert --timestamp="2020-01-01T00:00:00Z" \ 395*e0c4386eSCy Schubert --cert_chain ${cert}-chain.pem \ 396*e0c4386eSCy Schubert --tls_out ${cert}.tlssct 397*e0c4386eSCy Schubert rm ${cert}-chain.pem 398*e0c4386eSCy Schubert filesize=$(wc -c <${cert}.tlssct) 399*e0c4386eSCy Schubert exts=$(printf "%s\n%s\n%s\n%s\n%s%04X%04X%s\n%s\n[alts]\n%s\n" \ 400*e0c4386eSCy Schubert "subjectKeyIdentifier = hash" \ 401*e0c4386eSCy Schubert "authorityKeyIdentifier = keyid, issuer" \ 402*e0c4386eSCy Schubert "basicConstraints = CA:false" \ 403*e0c4386eSCy Schubert "extendedKeyUsage = $purpose" \ 404*e0c4386eSCy Schubert "1.3.6.1.4.1.11129.2.4.2 = ASN1:FORMAT:HEX,OCT:" $((filesize+2)) $filesize `xxd -p ${cert}.tlssct | tr -d '\n'` \ 405*e0c4386eSCy Schubert "subjectAltName = @alts" "DNS=${cn}") 406*e0c4386eSCy Schubert echo "$csr" | 407*e0c4386eSCy Schubert cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \ 408*e0c4386eSCy Schubert -set_serial 2 -days "${DAYS}" "$@" 409*e0c4386eSCy Schubert} 410*e0c4386eSCy Schubert 411*e0c4386eSCy Schubert"$@" 412