github.com/nats-io/nats-server/v2@v2.11.0-preview.2/test/configs/certs/regenerate_rdns_svid.sh (about) 1 #!/usr/bin/env bash 2 set -euo pipefail 3 # 4 # regenerate_rnds_svid: just remake the certs in the rdns & svid dirs. 5 # 6 # We're getting the hard requirements down in scripts, can integrate all into 7 # one all-singing all-dancing script later, so that anyone can regenerate 8 # without having to read test source code. 9 # 10 11 progname="$(basename "$0" .sh)" 12 note() { printf >&2 '%s: %s\n' "$progname" "$*"; } 13 warn() { note "$@"; } 14 die() { warn "$@"; exit 1; } 15 16 readonly CERT_SUBDIR='test/configs/certs' 17 readonly RDNS_SUBDIR='rdns' 18 readonly SVID_SUBDIR='svid' 19 20 # WARNING: 21 # This data is hard-coded into tests such as TestTLSClientAuthWithRDNSequence 22 # so do not "fix" it without editing the tests too! 23 readonly COMMON_SUB_COUNTRY=US 24 readonly COMMON_SUB_STATE=CA 25 readonly COMMON_SUB_LOCALITY='Los Angeles' 26 readonly COMMON_SUB_ORG=NATS 27 readonly COMMON_SUB_ORGUNIT=NATS 28 readonly COMMON_SUBJECT_OOU="/C=$COMMON_SUB_COUNTRY/ST=$COMMON_SUB_STATE/L=$COMMON_SUB_LOCALITY/O=$COMMON_SUB_ORG/OU=$COMMON_SUB_ORGUNIT" 29 readonly COMMON_SUBJECT_OUO="/C=$COMMON_SUB_COUNTRY/ST=$COMMON_SUB_STATE/L=$COMMON_SUB_LOCALITY/OU=$COMMON_SUB_ORGUNIT/O=$COMMON_SUB_ORG" 30 readonly RDNS_COMMON_SAN='subjectAltName=DNS:localhost,DNS:example.com,DNS:www.example.com' 31 32 readonly CA_KEYFILE=ca.key CA_CERTFILE=ca.pem CA_NAME='NATS CA' CA_SERIAL_FILE='ca.srl' 33 readonly RSA_SIZE=2048 34 readonly DIGEST_ALG=sha256 35 readonly CERT_DURATION=$((2 * 365)) 36 37 REPO_TOP="$(git rev-parse --show-toplevel)" 38 CERT_ABSOLUTE_DIR="$REPO_TOP/$CERT_SUBDIR" 39 readonly REPO_TOP CERT_ABSOLUTE_DIR 40 41 okay=true 42 for cmd in openssl ; do 43 if command -v "$cmd" >/dev/null 2>&1; then 44 continue 45 fi 46 okay=false 47 warn "missing command: $cmd" 48 done 49 $okay || die "missing necessary commands" 50 51 make_keyfile() { 52 local keyfile="${1:?need a keyfile to create}" 53 (umask 077; openssl genrsa "$RSA_SIZE" > "$keyfile") 54 } 55 56 ensure_keyfile() { 57 local keyfile="${1:?need a keyfile to create}" 58 local description="${2:?need a description}" 59 if [ -f "$keyfile" ]; then 60 note "reusing EXISTING $description file: $keyfile" 61 return 0 62 fi 63 note "creating NEW $description file: $keyfile" 64 make_keyfile "$keyfile" 65 } 66 67 o_req_newkey() { openssl req -newkey "rsa:$RSA_SIZE" -nodes "$@"; } 68 69 o_x509_casign() { 70 local extfile_contents="$1" 71 shift 72 openssl x509 -req -days "$CERT_DURATION" \ 73 -CA "$CA_CERTFILE" -CAkey "$CA_KEYFILE" -CAcreateserial \ 74 -sha256 \ 75 -extfile <(printf '%s\n' "$extfile_contents") \ 76 "$@" 77 } 78 79 o_new_cafile() { 80 local keyfile="$1" cacertfile="$2" 81 shift 2 82 openssl req -x509 -new -key "$CA_KEYFILE" -out "$CA_CERTFILE" -outform pem \ 83 -days "$CERT_DURATION" -subj "/CN=$CA_NAME" \ 84 "$@" 85 # We want these: 86 # -addext subjectKeyIdentifier=hash \ 87 # -addext authorityKeyIdentifier=keyid:always,issuer \ 88 # -addext basicConstraints=critical,CA:true \ 89 # but even without an extensions section, those seem to have been included anyway, 90 # resulting in a doubling when I created them, and Go cert parsing did not like 91 # the doubled X509v3 extensions data, leading to a panic. 92 # So, removed. 93 } 94 95 # ######################################################################## 96 # RDNS 97 98 note "Working on rdns files" 99 cd "$CERT_ABSOLUTE_DIR/$RDNS_SUBDIR" || die "unable to chdir($CERT_ABSOLUTE_DIR/$RDNS_SUBDIR)" 100 101 note "creating: CA" 102 # This one is kept in-git, so we don't force-recreate. 103 # TBD: should we delete, as we do in the parent dir? 104 ensure_keyfile "$CA_KEYFILE" "rdns CA key" 105 o_new_cafile "$CA_KEYFILE" "$CA_CERTFILE" 106 107 make_rdns_client_pair() { 108 local client_id="$1" 109 local subject="$2" 110 shift 2 111 local prefix="client-$client_id" 112 note "creating: $prefix" 113 rm -fv -- "$prefix.key" "$prefix.csr" "$prefix.pem" 114 # TBD: preserve the .key if it already exists? 115 # For now, just using the same ultimate command as was documented in the tls_test.go comments, 116 # so that we minimize moving parts to debug. Key preservation is a future optimization. 117 # The "$@" goes into the req invocation to let us specify -multivalue-rdn 118 o_req_newkey -keyout "$prefix.key" -out "$prefix.csr" "$@" -subj "$subject" -addext extendedKeyUsage=clientAuth 119 o_x509_casign "$RDNS_COMMON_SAN" -in "$prefix.csr" -out "$prefix.pem" 120 rm -v -- "$prefix.csr" 121 echo >&2 122 } 123 124 make_svid_rsa_pair() { 125 local prefix="$1" 126 local subject="$2" 127 local san_addition="$3" 128 shift 3 129 note "creating: $prefix" 130 rm -fv -- "$prefix.key" "$prefix.csr" "$prefix.pem" 131 # TBD: preserve the .key if it already exists? 132 # For now, just using the same ultimate command as was documented in the tls_test.go comments, 133 # so that we minimize moving parts to debug. Key preservation is a future optimization. 134 o_req_newkey -keyout "$prefix.key" -out "$prefix.csr" -subj "$subject" -addext extendedKeyUsage=clientAuth 135 o_x509_casign "$RDNS_COMMON_SAN${san_addition:+,}${san_addition:-}" -in "$prefix.csr" -out "$prefix.pem" 136 rm -v -- "$prefix.csr" 137 echo >&2 138 } 139 140 # KEEP DN STRINGS HERE MATCHING THOSE IN tls_test.go SO THAT IT's COPY/PASTE! 141 142 # C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo1, DC = foo2 143 make_rdns_client_pair a "$COMMON_SUBJECT_OOU/CN=localhost/DC=foo1/DC=foo2" 144 145 # C = US, ST = California, L = Los Angeles, O = NATS, OU = NATS, CN = localhost 146 make_rdns_client_pair b "$COMMON_SUBJECT_OOU/CN=localhost" 147 148 # C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo3, DC = foo4 149 make_rdns_client_pair c "$COMMON_SUBJECT_OOU/CN=localhost/DC=foo3/DC=foo4" 150 151 # C = US, ST = CA, L = Los Angeles, OU = NATS, O = NATS, CN = *.example.com, DC = example, DC = com 152 make_rdns_client_pair d "$COMMON_SUBJECT_OUO/CN=*.example.com/DC=example/DC=com" 153 154 # OpenSSL: -subj "/CN=John Doe/CN=123456/CN=jdoe/OU=Users/OU=Organic Units/DC=acme/DC=com" 155 make_rdns_client_pair e "/CN=John Doe/CN=123456/CN=jdoe/OU=Users/OU=Organic Units/DC=acme/DC=com" 156 157 # OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" 158 # WITH -multivalue-rdn for the -req 159 make_rdns_client_pair f "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 160 161 note "creating: server" 162 rm -fv -- "server.key" "server.csr" "server.pem" 163 o_req_newkey -keyout "server.key" -out "server.csr" -subj "/CN=localhost" 164 o_x509_casign "$RDNS_COMMON_SAN" -in "server.csr" -out "server.pem" 165 rm -v -- "server.csr" 166 echo >&2 167 168 rm -rfv "$CA_SERIAL_FILE" 169 170 # ######################################################################## 171 # SVID 172 173 note "Working on svid files" 174 cd "$CERT_ABSOLUTE_DIR/$SVID_SUBDIR" || die "unable to chdir($CERT_ABSOLUTE_DIR/$SVID_SUBDIR)" 175 176 note "creating: CA" 177 ensure_keyfile "$CA_KEYFILE" "svid CA key" 178 o_new_cafile "$CA_KEYFILE" "$CA_CERTFILE" 179 180 make_svid_rsa_pair client-a "$COMMON_SUBJECT_OOU/CN=localhost/DC=foo1/DC=foo2" 'URI:spiffe://localhost/my-nats-service/user-a' 181 182 make_svid_rsa_pair client-b "/C=US/O=SPIRE" 'URI:spiffe://localhost/my-nats-service/user-b' 183 184 make_svid_rsa_pair server "/CN=localhost" '' 185 186 rm -rfv "$CA_SERIAL_FILE" 187 188 # FIXME: svid-user-a and svid-user-b are ECC certs, but not expiring at the 189 # same time as the rest and with differing requirements, so not coding that up 190 # now.