summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2019-08-28 16:01:59 +0200
committerErich Eckner <git@eckner.net>2019-08-28 16:01:59 +0200
commitef01a84a94041987cb952bb1313d33e338818fc4 (patch)
treec500aaa23f533eecec9790277739972da40fa383
parent3ed2a64d43ac58e0a022ec92d71ee6a28d9d2f9e (diff)
downloadsimple-pki-ef01a84a94041987cb952bb1313d33e338818fc4.tar.xz
WIP: Tagesendstand
-rwxr-xr-xgenerate-and-upload-self-signed-keys.in93
-rwxr-xr-xsign-ca12
-rwxr-xr-xsign-request90
3 files changed, 147 insertions, 48 deletions
diff --git a/generate-and-upload-self-signed-keys.in b/generate-and-upload-self-signed-keys.in
index 951bf72..9215d22 100755
--- a/generate-and-upload-self-signed-keys.in
+++ b/generate-and-upload-self-signed-keys.in
@@ -68,61 +68,58 @@ if [ "$(whoami)" != 'http' ]; then
exit
fi
+if [ -n "$(trap)" ]; then
+ >&2 echo 'outer traps set - those will be forgotten!'
+ exit 1
+fi
+
+tmp_dir=$(mktemp -d '/srv/http/httpdocs/.csr/tmp.XXXXXXXXXX')
+trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT
+
printf '%s\n' "${hosts}" \
| while read -r host other_hosts; do
if [ -f "${key_dir}/${host}.key.pem.new" ] \
&& [ -f "${key_dir}/${host}.cert.pem.new" ]; then
continue
fi
- openssl req -x509 -newkey rsa:4096 \
+ if [ -n "${other_hosts}" ]; then
+ extensions="-addext subjectAltName=$(
+ printf ',DNS:%s' \
+ "${host}" \
+ ${other_hosts} \
+ | sed 's/^,//'
+ )"
+ else
+ extensions=''
+ fi
+ openssl req -newkey rsa:4096 \
-keyout "${key_dir}/${host}.key.pem.new" \
- -out "${key_dir}/${host}.cert.pem.new" \
- -days 365 -nodes -subj '/C=DE/ST=Thuringia/L=Jena/O=Eckner/OU=Net/CN='"${host}" -sha256 \
- -config <(
- cat '#ETCDIR#/ssl/openssl.cnf'
- if [ -n "${other_hosts}" ]; then
- printf '\n[SAN]\nsubjectAltName'
- printf ',DNS:%s' \
- "${host}" \
- ${other_hosts} \
- | sed 's/^,/=/'
- fi
- )
+ -out "${tmp_dir}/${host}.csr" \
+ -nodes -subj '/C=DE/ST=Thuringia/L=Jena/O=Eckner/OU=Net/CN='"${host}" -sha256 \
+ ${extensions}
+ printf 'https://%s/.csr/%s/%s.csr %s %s\n' \
+ "${host}" \
+ "${tmp_dir##*/}" \
+ "${host}" \
+ '/C=DE/ST=Thuringia/L=Jena/O=Eckner/OU=Net/CN='"${host}" \
+ "${extensions}" \
+ >> "${tmp_dir}/commands"
done
-rsync --ignore-missing-args \
- $(
- printf -- "${key_dir}"'/%s.cert.pem\n' ${host_key_files}
- printf -- "${key_dir}"'/%s.cert.pem.new\n' ${host_key_files}
- ) \
- "${remote_host}:${remote_dir}/"
+if [ ! -s "${tmp_dir}/commands" ]; then
+ >&2 echo 'nothing to do.'
+ exit
+fi
+
+cd "${tmp_dir}"
-(
- cd "${key_dir}"
- {
- printf '%s.cert.pem\n' ${host_key_files}
- printf '%s.cert.pem.new\n' ${host_key_files}
- } \
- | while read -r key; do
- [ -f "${key}" ] || continue
- printf '%s %s\n' "$(
- date -u --iso-8601=seconds -d@$(stat -c%Y "${key}") \
- | cut -d+ -f1
- )" "$(
- sha512sum "${key}" \
- | sed 's/\s\+/ /'
- )"
- done
-) \
-| ssh "${remote_host}" '
- cd "'"${remote_dir}"'"
- while read -r time sum file; do
- rm -f ????-??-??T??\:??\:??".${file}"
- mv "${file}" "${time}.${file}"
- sed -i '"'"'
- / [^.]\+\.'"'"'"${file//./\.}"'"'"'$/d
- '"'"' sha512sums
- printf '"'"'%s %s\n'"'"' "${sum}" "${time}.${file}" \
- >> sha512sums
- done
-'
+cut -d' ' -f1 \
+< 'commands' \
+| ssh -T erich@192.168.1.3 \
+| tar -xzf -
+
+for host_key_file in ${host_key_files}; do
+ [ -f "${tmp_dir}/${host_key_file}.crt" ] || continue
+ cat "${tmp_dir}/${host_key_file}.crt" \
+ > "${key_dir}/${host_key_file}.cert.pem.new"
+done
diff --git a/sign-ca b/sign-ca
new file mode 100755
index 0000000..f2e8200
--- /dev/null
+++ b/sign-ca
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+openssl req -x509 \
+ -new -nodes \
+ -key eckner-ca.key \
+ -sha256 -days 3654 \
+ -out eckner-ca.crt \
+ -subj '/C=DE/ST=Thuringia/L=Jena/O=Eckner/OU=Net/CN=Certification Authority' \
+ -addext 'subjectKeyIdentifier = hash' \
+ -addext 'authorityKeyIdentifier = keyid:always, issuer' \
+ -addext 'basicConstraints = critical, CA:true' \
+ -addext 'keyUsage = keyCertSign, cRLSign'
diff --git a/sign-request b/sign-request
new file mode 100755
index 0000000..cf3442e
--- /dev/null
+++ b/sign-request
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+cd "${0%/*}"
+
+remove_leading_spaces() {
+ sed '
+ s/^ \{'"$1"'\}//
+ t
+ d
+ '
+}
+
+tmp_dir=$(mktemp -d)
+trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT
+
+while read -r csr; do
+ csr_local="${tmp_dir}/${csr##*/}"
+ curl -Ss "${csr}" -o "${csr_local}"
+ if ! content=$(
+ openssl req -text -noout -verify -in "${csr_local}" 2>/dev/null
+ ); then
+ rm "${csr_local}"
+ continue
+ fi
+ content=$(
+ printf '%s\n' "${content}" \
+ | sed -n '
+ /^Certificate Request:$/,/^\S/p
+ ' \
+ | remove_leading_spaces 4 \
+ | sed -n '
+ /^Data:$/,/^\S/p
+ ' \
+ | remove_leading_spaces 4
+ )
+ cn=$(
+ printf '%s\n' "${content}" \
+ | sed '
+ s/^Subject: .*, CN = \(\S\+\)$/\1/
+ t
+ d
+ '
+ )
+ sans=$(
+ printf '%s\n' "${content}" \
+ | sed -n '
+ /^Requested Extensions:$/,/^\S/ p
+ ' \
+ | remove_leading_spaces 4 \
+ | sed -n '
+ /^X\S\+ Subject Alternative Name:\s*$/,/^\S/ p
+ ' \
+ | remove_leading_spaces 4 \
+ | sed '
+ s/, /\n/g
+ '
+ )
+ if printf '%s\n' "${sans}" | grep -vq '^\(DNS\|IP\):'; then
+ continue
+ fi
+ sans=$(
+ printf '%s\n' "${sans}" \
+ | sed '
+ s/^\(DNS\|IP\)://
+ '
+ )
+ ok_sans=$(
+ printf '%s\n' "${cn}" "${sans}" \
+ | while read -r san; do
+ if ! curl -Ss --insecure 'https://'"${san}/${csr#*//*/}" \
+ | diff -q - "${csr_local}"; then
+ rm "${csr_local}"
+ break
+ fi
+ printf '%s\n' "${san}"
+ done
+ )
+ if [ ! -f "${csr_local}" ]; then
+ continue
+ fi
+ if [ "$(printf '%s\n' "${cn}" "${sans}")" != "${ok_sans}" ]; then
+ rm "${csr_local}"
+ continue
+ fi
+ openssl req -x509 -key eckner-ca.key -in "${csr_local}" -out "${csr_local%.csr}.crt" -addext 'basicConstraints = critical, CA:false'
+ rm "${csr_local}"
+done
+
+cd "${tmp_dir}"
+tar -czf - *