Commit 3540d427 authored by Vincent Pelletier's avatar Vincent Pelletier

shell/caucase.sh: Make shellcheck happy.

Do not rely on test's -a & -o.
Escape backslashes which are intended as literals.
Avoid one useless "cat".
Avoid testing $?.
Simplify "is integer ?" test.
Quote a few variable expansions.
Arithmetic expression does not need explicit expansion.
Split declaration and assignment to unmask status.
Disable shellcheck warning about "local" being undefined in POSIX.
parent 1c9b9b6d
...@@ -33,6 +33,7 @@ pairs2obj () { ...@@ -33,6 +33,7 @@ pairs2obj () {
# Keys are expected unquoted, as they must be strings anyway. # Keys are expected unquoted, as they must be strings anyway.
# Values are expected in json. # Values are expected in json.
# If arg count is odd, last argument is ignored. # If arg count is odd, last argument is ignored.
# shellcheck disable=SC2039
local first=1 local first=1
printf '{' printf '{'
while [ $# -ge 2 ]; do while [ $# -ge 2 ]; do
...@@ -51,16 +52,20 @@ forEachJSONListItem () { ...@@ -51,16 +52,20 @@ forEachJSONListItem () {
# Usage: <command> [<arg> ...] < json # Usage: <command> [<arg> ...] < json
# <command> is receives each item in json as input. # <command> is receives each item in json as input.
# If <command> exit status is non-zero, enumeration stops. # If <command> exit status is non-zero, enumeration stops.
local list="$(cat)" index # shellcheck disable=SC2039
for index in $(seq 0 $(($(printf "%s\n" "$list" | jq length) - 1))); do local list index
printf "%s\n" "$list" | jq ".[$index]" | "$@" || return $? list="$(cat)"
for index in $(seq 0 $(($(printf "%s\\n" "$list" | jq length) - 1))); do
printf "%s\\n" "$list" | jq ".[$index]" | "$@" || return $?
done done
} }
wrap () { wrap () {
# Wrap payload in a format suitable for caucase and sign it # Wrap payload in a format suitable for caucase and sign it
# Usage: wrap <key file> <digest> < payload > wrapped # Usage: wrap <key file> <digest> < payload > wrapped
local digest="$2" payload="$(cat)" # shellcheck disable=SC2039
local digest="$2" payload
payload="$(cat)"
# Note: $() looses trailing newlines, so payload should not need to end with # Note: $() looses trailing newlines, so payload should not need to end with
# any newline. # any newline.
pairs2obj \ pairs2obj \
...@@ -90,14 +95,16 @@ unwrap () { ...@@ -90,14 +95,16 @@ unwrap () {
# Usage: unwrap <command> [...] < wrapped > payload # Usage: unwrap <command> [...] < wrapped > payload
# <command> must output the x509 certificate to use to verify the signature. # <command> must output the x509 certificate to use to verify the signature.
# It receives the payload being unwrapped. # It receives the payload being unwrapped.
local wrapped="$(cat)" status json_digest digest signature_file payload pubkey_file # shellcheck disable=SC2039
local wrapped status json_digest digest signature_file payload pubkey_file
wrapped="$(cat)"
json_digest="$(printf "%s\n" "$wrapped" | jq .digest)" json_digest="$(printf "%s\\n" "$wrapped" | jq .digest)"
if [ "$json_digest" = "null" ]; then if [ "$json_digest" = "null" ]; then
return 1 return 1
fi fi
digest="$( digest="$(
printf "%s\n" "$json_digest" | jq --raw-output ascii_downcase printf "%s\\n" "$json_digest" | jq --raw-output ascii_downcase
)" )"
case "$digest" in case "$digest" in
sha256|sha384|sha512) sha256|sha384|sha512)
...@@ -111,12 +118,11 @@ unwrap () { ...@@ -111,12 +118,11 @@ unwrap () {
;; ;;
esac esac
signature_file="$(mktemp --suffix=unwrap.sig)" signature_file="$(mktemp --suffix=unwrap.sig)"
printf "%s\n" "$wrapped" | jq --raw-output .signature | \ printf "%s\\n" "$wrapped" | jq --raw-output .signature | \
base64 -d > "$signature_file" base64 -d > "$signature_file"
payload="$(printf "%s\n" "$wrapped" | jq --raw-output .payload)" payload="$(printf "%s\\n" "$wrapped" | jq --raw-output .payload)"
PUBKEY_FILE="$(mktemp --suffix=unwrap.pub)" PUBKEY_FILE="$(mktemp --suffix=unwrap.pub)"
printf "%s\n" "$payload" "$@" | openssl x509 -pubkey -noout > "$pubkey_file" if printf "%s\\n" "$payload" "$@" | openssl x509 -pubkey -noout > "$pubkey_file"; then
if [ $? -eq 0 ]; then
printf "%s%s " "$payload" "$digest" \ printf "%s%s " "$payload" "$digest" \
| openssl dgst \ | openssl dgst \
-"$digest" \ -"$digest" \
...@@ -136,26 +142,28 @@ unwrap () { ...@@ -136,26 +142,28 @@ unwrap () {
nullUnwrap () { nullUnwrap () {
# Usage: nullUnwrap < wrapped > payload # Usage: nullUnwrap < wrapped > payload
local wrapped="$(cat)" # shellcheck disable=SC2039
if [ "$(printf "%s\n" "$wrapped" | jq '.digest')" != "null" ]; then local wrapped
wrapped="$(cat)"
if [ "$(printf "%s\\n" "$wrapped" | jq '.digest')" != "null" ]; then
return 1 return 1
fi fi
printf "%s\n" "$wrapped" | jq .payload printf "%s\\n" "$wrapped" | jq .payload
} }
writeCertKey () { writeCertKey () {
# Write given certificate and key to file(s). # Write given certificate and key to file(s).
# Usage: writeCertKey <crt data> <crt path> <key data> <key path> # Usage: writeCertKey <crt data> <crt path> <key data> <key path>
# shellcheck disable=SC2039
local crt_path="$1" crt_data="$2" key_path="$3" key_data="$4" need_chmod local crt_path="$1" crt_data="$2" key_path="$3" key_data="$4" need_chmod
test ! -e "$key_path" test ! -e "$key_path"
need_chmod=$? need_chmod=$?
# Empty both files first, as they may be the same. # Empty both files first, as they may be the same.
: > "$crt_path" : > "$crt_path"
: > "$key_path" : > "$key_path"
test $need_chmod -eq 0 && chmod go= "$key_path" test $need_chmod -eq 0 && chmod go= "$key_path"
printf "%s\n" "$key_data" >> "$key_path" printf "%s\\n" "$key_data" >> "$key_path"
printf "%s\n" "$crt_data" >> "$crt_path" printf "%s\\n" "$crt_data" >> "$crt_path"
} }
alias CURL='curl --silent' alias CURL='curl --silent'
...@@ -164,29 +172,31 @@ alias PUT='CURL --upload-file -' ...@@ -164,29 +172,31 @@ alias PUT='CURL --upload-file -'
PUTNoOut () { PUTNoOut () {
# For when PUT does not provide a response body, so the only way to check # For when PUT does not provide a response body, so the only way to check
# for issues is checking HTTP status. # for issues is checking HTTP status.
# shellcheck disable=SC2039
local result local result
result="$( if result="$(
PUT \ PUT \
--write-out "\n%{http_code}\n" \ --write-out "\\n%{http_code}\\n" \
"$@" "$@"
)" )"; then
if [ $? -ne 0 ]; then :
else
return 3 return 3
fi fi
case "$(printf "%s\n" "$result" | tail -n 1)" in case "$(printf "%s\\n" "$result" | tail -n 1)" in
2?? ) 2?? )
return 0 return 0
;; ;;
401 ) 401 )
printf "Unauthorized\n" >&2 printf "Unauthorized\\n" >&2
return 2 return 2
;; ;;
409 ) 409 )
printf "Found\n" >&2 printf "Found\\n" >&2
return 4 return 4
;; ;;
* ) * )
printf "%s\n" "$result" | head -n -1 >&2 printf "%s\\n" "$result" | head -n -1 >&2
return 1 return 1
;; ;;
esac esac
...@@ -212,18 +222,19 @@ _forEachPEM () { ...@@ -212,18 +222,19 @@ _forEachPEM () {
# <type tester> is called with the end boundary as argument # <type tester> is called with the end boundary as argument
# <command> receives each matching PEM element as input. # <command> receives each matching PEM element as input.
# If <command> exit status is non-zero, enumeration stops. # If <command> exit status is non-zero, enumeration stops.
# shellcheck disable=SC2039
local tester="$1" current="" local tester="$1" current=""
shift shift
while IFS= read -r line; do while IFS= read -r line; do
if [ -z "$current" ]; then if [ -z "$current" ]; then
current="$line" current="$line"
else else
current="$(printf "%s\n%s" "$current" "$line")" current="$(printf "%s\\n%s" "$current" "$line")"
fi fi
case "$line" in case "$line" in
"-----END "*"-----") "-----END "*"-----")
if "$tester" "$line"; then if "$tester" "$line"; then
printf "%s\n" "$current" | "$@" || return $? printf "%s\\n" "$current" | "$@" || return $?
fi fi
current="" current=""
;; ;;
...@@ -251,7 +262,9 @@ expiresBefore () { ...@@ -251,7 +262,9 @@ expiresBefore () {
# Tests whether certificate is expired at given date # Tests whether certificate is expired at given date
# Usage: expiresBefore <date> < certificate > certificate # Usage: expiresBefore <date> < certificate > certificate
# <date> must be a unix timestamp (date +%s) # <date> must be a unix timestamp (date +%s)
local enddate="$(openssl x509 -enddate -noout | sed "s/^[^=]*=//")" # shellcheck disable=SC2039
local enddate
enddate="$(openssl x509 -enddate -noout | sed "s/^[^=]*=//")"
test $? -ne 0 && return 1 test $? -ne 0 && return 1
test "$(date --date="$enddate" +%s)" -lt "$1" test "$(date --date="$enddate" +%s)" -lt "$1"
return $? return $?
...@@ -261,8 +274,10 @@ printIfExpiresAfter () { ...@@ -261,8 +274,10 @@ printIfExpiresAfter () {
# Print certificate if it expires after given date # Print certificate if it expires after given date
# Usage: printIfExpiresAfter <date> < certificate > certificate # Usage: printIfExpiresAfter <date> < certificate > certificate
# <date> must be a unix timestamp (date +%s) # <date> must be a unix timestamp (date +%s)
local crt="$(cat)" # shellcheck disable=SC2039
printf "%s\n" "$crt" | expiresBefore "$1" || printf "%s\n" "$crt" local crt
crt="$(cat)"
printf "%s\\n" "$crt" | expiresBefore "$1" || printf "%s\\n" "$crt"
} }
appendValidCA () { appendValidCA () {
...@@ -270,19 +285,20 @@ appendValidCA () { ...@@ -270,19 +285,20 @@ appendValidCA () {
# Append CA to given file if it is signed by a CA we know of already. # Append CA to given file if it is signed by a CA we know of already.
# Usage: _appendValidCA <ca path> < json # Usage: _appendValidCA <ca path> < json
# Appends valid certificates to the file at <ca path> # Appends valid certificates to the file at <ca path>
# shellcheck disable=SC2039
local ca="$1" payload cert local ca="$1" payload cert
payload=$(unwrap jq --raw-output .old_pem) if payload=$(unwrap jq --raw-output .old_pem); then
if [ $? -ne 0 ]; then :
else
printf "Bad signature, something is very wrong" >&2 printf "Bad signature, something is very wrong" >&2
return 1 return 1
fi fi
cert="$(printf "%s\n" "$payload" | jq --raw-output .old_pem)" cert="$(printf "%s\\n" "$payload" | jq --raw-output .old_pem)"
cat "$ca" \ forEachCertificate \
| forEachCertificate \
pemFingerprintIs \ pemFingerprintIs \
"$(printf "%s\n" "$cert" | pem2fingerprint)" "$(printf "%s\\n" "$cert" | pem2fingerprint)" < "$ca"
if [ $? -eq 1 ]; then if [ $? -eq 1 ]; then
printf "%s\n" "$cert" >> "$ca" printf "%s\\n" "$cert" >> "$ca"
fi fi
} }
...@@ -291,7 +307,7 @@ checkCertificateMatchesKey () { ...@@ -291,7 +307,7 @@ checkCertificateMatchesKey () {
# Returns 0 if certificate's public key matches private key's public key, # Returns 0 if certificate's public key matches private key's public key,
# 1 otherwise. # 1 otherwise.
test "$( test "$(
printf "%s\n" "$1" | openssl x509 -modulus -noout | sed "s/^Modulus=//" printf "%s\\n" "$1" | openssl x509 -modulus -noout | sed "s/^Modulus=//"
)" = "$( )" = "$(
echo "$2" | openssl rsa -modulus -noout | sed "s/^Modulus=//" echo "$2" | openssl rsa -modulus -noout | sed "s/^Modulus=//"
)" )"
...@@ -299,6 +315,7 @@ checkCertificateMatchesKey () { ...@@ -299,6 +315,7 @@ checkCertificateMatchesKey () {
} }
checkDeps () { checkDeps () {
# shellcheck disable=SC2039
local missingdeps="" dep local missingdeps="" dep
# Expected builtins & keywords: # Expected builtins & keywords:
# alias local if then else elif fi for in do done case esac return [ test # alias local if then else elif fi for in do done case esac return [ test
...@@ -310,7 +327,7 @@ checkDeps () { ...@@ -310,7 +327,7 @@ checkDeps () {
echo "Missing dependencies: $missingdeps" >&2 echo "Missing dependencies: $missingdeps" >&2
return 1 return 1
fi fi
if [ ! -r /dev/null -o ! -w /dev/null ]; then if [ ! -r /dev/null ] || [ ! -w /dev/null ]; then
echo "Cannot read from & write to /dev/null" >&2 echo "Cannot read from & write to /dev/null" >&2
return 1 return 1
fi fi
...@@ -324,16 +341,18 @@ renewCertificate () { ...@@ -324,16 +341,18 @@ renewCertificate () {
# on success. # on success.
# If created, key file permissions will be set so group and other have no # If created, key file permissions will be set so group and other have no
# access. # access.
# shellcheck disable=SC2039
local url="$1" oldkey="$2" bits="$3" newcrt="$4" newkey="$5" local url="$1" oldkey="$2" bits="$3" newcrt="$4" newkey="$5"
# shellcheck disable=SC2039
local newkeydata newcrtdata local newkeydata newcrtdata
newkeydata="$( newkeydata="$(
openssl genpkey \ openssl genpkey \
-algorithm rsa \ -algorithm rsa \
-pkeyopt rsa_keygen_bits:$bits \ -pkeyopt "rsa_keygen_bits:$bits" \
-outform PEM 2> /dev/null -outform PEM 2> /dev/null
)" )"
newcrtdata="$( if newcrtdata="$(
pairs2obj \ pairs2obj \
"crt_pem" "$(str2json)" \ "crt_pem" "$(str2json)" \
"renew_csr_pem" "$( "renew_csr_pem" "$(
...@@ -349,10 +368,9 @@ renewCertificate () { ...@@ -349,10 +368,9 @@ renewCertificate () {
| PUT --insecure \ | PUT --insecure \
--header "Content-Type: application/json" \ --header "Content-Type: application/json" \
"$url/crt/renew/" "$url/crt/renew/"
)" )"; then
if [ $? -eq 0 ]; then
if [ \ if [ \
"x$(printf "%s\n" "$newcrtdata" | head -n 1)" \ "x$(printf "%s\\n" "$newcrtdata" | head -n 1)" \
= \ = \
"x-----BEGIN CERTIFICATE-----" \ "x-----BEGIN CERTIFICATE-----" \
]; then ]; then
...@@ -360,7 +378,7 @@ renewCertificate () { ...@@ -360,7 +378,7 @@ renewCertificate () {
writeCertKey "$newcrt" "$newcrtdata" "$newkey" "$newkeydata" writeCertKey "$newcrt" "$newcrtdata" "$newkey" "$newkeydata"
return 0 return 0
fi fi
printf "Certificate does not match private key\n" >&2 printf "Certificate does not match private key\\n" >&2
else else
printf "%s" "$newcrtdata" >&2 printf "%s" "$newcrtdata" >&2
fi fi
...@@ -405,6 +423,7 @@ revokeSerial () { ...@@ -405,6 +423,7 @@ revokeSerial () {
updateCACertificate () { updateCACertificate () {
# Usage: <url> <cas_ca> <ca> # Usage: <url> <cas_ca> <ca>
# shellcheck disable=SC2039
local url="$1" cas_ca="$2" ca="$3" future_ca status orig_ca valid_ca local url="$1" cas_ca="$2" ca="$3" future_ca status orig_ca valid_ca
orig_ca="$( orig_ca="$(
if [ -e "$ca" ]; then if [ -e "$ca" ]; then
...@@ -416,24 +435,24 @@ updateCACertificate () { ...@@ -416,24 +435,24 @@ updateCACertificate () {
status=$? status=$?
test $status -ne 0 && return 1 test $status -ne 0 && return 1
valid_ca="$( valid_ca="$(
printf "%s\n" "$orig_ca" \ printf "%s\\n" "$orig_ca" \
| forEachCertificate printIfExpiresAfter "$(date +%s)" | forEachCertificate printIfExpiresAfter "$(date +%s)"
)" )"
status=$? status=$?
test $status -ne 0 && return 1 test $status -ne 0 && return 1
printf "%s\n" "$valid_ca" > "$ca" printf "%s\\n" "$valid_ca" > "$ca"
if [ ! -r "$cas_ca" ]; then if [ ! -r "$cas_ca" ]; then
# Should never be reached, as this function should be run once with # Should never be reached, as this function should be run once with
# cas_ca == ca (to update CAS' CA), in which case cas_ca exists by this # cas_ca == ca (to update CAS' CA), in which case cas_ca exists by this
# point. CAU's CA should only be updated after, and by that point CAS' CA # point. CAU's CA should only be updated after, and by that point CAS' CA
# already exists. # already exists.
printf "%s does not exist\n" "$cas_ca" printf "%s does not exist\\n" "$cas_ca"
return 1 return 1
fi fi
future_ca="$(CURL --cacert "$cas_ca" "$url/crt/ca.crt.json")" future_ca="$(CURL --cacert "$cas_ca" "$url/crt/ca.crt.json")"
status=$? status=$?
test $status -ne 0 && return 1 test $status -ne 0 && return 1
printf "%s\n" "$future_ca" | forEachJSONListItem appendValidCA "$ca" printf "%s\\n" "$future_ca" | forEachJSONListItem appendValidCA "$ca"
} }
getCertificateRevocationList () { getCertificateRevocationList () {
...@@ -462,7 +481,7 @@ createCertificateSigningRequest () { ...@@ -462,7 +481,7 @@ createCertificateSigningRequest () {
# So strip it with sed instead. # So strip it with sed instead.
case "$line" in case "$line" in
"Location: "*) "Location: "*)
printf "%s\n" "$line" | sed "s/^Location: \(\S*\).*/\1/" printf "%s\\n" "$line" | sed "s/^Location: \\(\\S*\\).*/\\1/"
;; ;;
esac esac
done done
...@@ -477,22 +496,24 @@ deletePendingCertificateRequest () { ...@@ -477,22 +496,24 @@ deletePendingCertificateRequest () {
getCertificate () { getCertificate () {
# Usage: <url> <csr id> # Usage: <url> <csr id>
# shellcheck disable=SC2039
local status local status
CURL --fail --insecure "$1/crt/$2" CURL --fail --insecure "$1/crt/$2"
status=$? status=$?
if [ $status -ne 0 ]; then if [ $status -ne 0 ]; then
printf "Certificate %s not found (not signed yet or rejected)\n" "$2" >&2 printf "Certificate %s not found (not signed yet or rejected)\\n" "$2" >&2
return 1 return 1
fi fi
} }
createCertificate () { createCertificate () {
# Usage: <url> <ca> <user crt> <csr id> # Usage: <url> <ca> <user crt> <csr id>
# shellcheck disable=SC2039
local result local result
PUTNoOut --cert "$3" --cacert "$2" "$1/crt/$4" < /dev/null PUTNoOut --cert "$3" --cacert "$2" "$1/crt/$4" < /dev/null
result=$? result=$?
if [ $result -ne 0 ]; then if [ $result -ne 0 ]; then
printf "%s: No such pending signing request\n" "$4" >&2 printf "%s: No such pending signing request\\n" "$4" >&2
fi fi
return $result return $result
} }
...@@ -596,13 +617,13 @@ EOF ...@@ -596,13 +617,13 @@ EOF
} }
_argUsage () { _argUsage () {
printf "%s: %s\n" "$arg" "$1" >&2 printf "%s: %s\\n" "$arg" "$1" >&2
_usage >&2 _usage >&2
} }
_needArg () { _needArg () {
if [ "$argc" -lt "$1" ]; then if [ "$argc" -lt "$1" ]; then
printf "%s\n" "$arg needs $1 arguments" >&2 printf "%s\\n" "$arg needs $1 arguments" >&2
_usage >&2 _usage >&2
return 1 return 1
fi fi
...@@ -610,7 +631,7 @@ EOF ...@@ -610,7 +631,7 @@ EOF
_needURLAndArg () { _needURLAndArg () {
if [ -z "$ca_anon_url" ]; then if [ -z "$ca_anon_url" ]; then
printf "%s\n" "--ca-url must be provided before $arg" >&2 printf "%s\\n" "--ca-url must be provided before $arg" >&2
return 1 return 1
fi fi
_needArg "$1" || return 1 _needArg "$1" || return 1
...@@ -618,7 +639,7 @@ EOF ...@@ -618,7 +639,7 @@ EOF
_needAuthURLAndArg () { _needAuthURLAndArg () {
if [ -z "$user_key" ]; then if [ -z "$user_key" ]; then
printf "%s\n" "--user-key must be provided before $arg" >&2 printf "%s\\n" "--user-key must be provided before $arg" >&2
return 1 return 1
fi fi
_needURLAndArg "$1" || return 1 _needURLAndArg "$1" || return 1
...@@ -626,7 +647,7 @@ EOF ...@@ -626,7 +647,7 @@ EOF
_checkCertficateMatchesOneKey () { _checkCertficateMatchesOneKey () {
# Called from _main, sets global "key_found". # Called from _main, sets global "key_found".
test $key_found -ne 0 && return 2 test "$key_found" -ne 0 && return 2
key_found=1 key_found=1
checkCertificateMatchesKey "$1" "$(cat)" || return 1 checkCertificateMatchesKey "$1" "$(cat)" || return 1
} }
...@@ -643,7 +664,7 @@ EOF ...@@ -643,7 +664,7 @@ EOF
_printOneCert () { _printOneCert () {
# Called indirectly from _main, sets global "crt_found". # Called indirectly from _main, sets global "crt_found".
if [ $crt_found -ne 0 ]; then if [ "$crt_found" -ne 0 ]; then
_argUsage "Multiple certificates" _argUsage "Multiple certificates"
return 1 return 1
fi fi
...@@ -653,18 +674,21 @@ EOF ...@@ -653,18 +674,21 @@ EOF
_printOneMatchingCert () { _printOneMatchingCert () {
# Called indirectly from _main, sets global "crt_found". # Called indirectly from _main, sets global "crt_found".
local crt="$(cat)" # shellcheck disable=SC2039
local crt
crt="$(cat)"
if [ $crt_found -ne 0 ]; then if [ $crt_found -ne 0 ]; then
_argUsage "Multiple certificates" _argUsage "Multiple certificates"
return 1 return 1
fi fi
crt_found=1 crt_found=1
checkCertificateMatchesKey "$crt" "$1" && printf "%s\n" "$crt" checkCertificateMatchesKey "$crt" "$1" && printf "%s\\n" "$crt"
} }
_matchOneKeyAndPrintOneMatchingCert () { _matchOneKeyAndPrintOneMatchingCert () {
# Usage: _matchOneKeyAndPrintOneMatchingCert <crt path> <key path> # Usage: _matchOneKeyAndPrintOneMatchingCert <crt path> <key path>
# Sets globals "crt_found" and "key_found" # Sets globals "crt_found" and "key_found"
# shellcheck disable=SC2039
local crt local crt
key_found=0 key_found=0
key="$(forEachPrivateKey _printOneKey < "$2")" key="$(forEachPrivateKey _printOneKey < "$2")"
...@@ -678,20 +702,23 @@ EOF ...@@ -678,20 +702,23 @@ EOF
_argUsage "No certificate matches private key" _argUsage "No certificate matches private key"
return 1 return 1
fi fi
printf "%s\n" "$crt" printf "%s\\n" "$crt"
} }
_printPendingCSR () { _printPendingCSR () {
local json="$(cat)" # shellcheck disable=SC2039
printf "%20s | %s\n" \ local json
"$(printf "%s\n" "$json" | jq --raw-output .id)" \ json="$(cat)"
"$(printf "%s\n" "$json" | jq --raw-output .csr \ printf "%20s | %s\\n" \
"$(printf "%s\\n" "$json" | jq --raw-output .id)" \
"$(printf "%s\\n" "$json" | jq --raw-output .csr \
| openssl req -subject -noout | sed "s/^subject=//")" | openssl req -subject -noout | sed "s/^subject=//")"
} }
_main() { _main() {
checkDeps || return 1 checkDeps || return 1
# shellcheck disable=SC2039
local ca_anon_url="" \ local ca_anon_url="" \
ca_auth_url \ ca_auth_url \
mode="service" \ mode="service" \
...@@ -706,7 +733,7 @@ EOF ...@@ -706,7 +733,7 @@ EOF
threshold=31 \ threshold=31 \
status arg argc \ status arg argc \
ca_netloc ca_address ca_port ca_path \ ca_netloc ca_address ca_port ca_path \
csr_id csr csr_path crl crt crt_path key_path key serial \ csr_id csr csr_path crl crt crt_path crt_dir key_path key serial \
csr_list_json csr_list_json
while test $# -gt 0; do while test $# -gt 0; do
...@@ -728,10 +755,10 @@ EOF ...@@ -728,10 +755,10 @@ EOF
;; ;;
http://*) http://*)
ca_netloc="$( ca_netloc="$(
printf "%s\n" "$ca_anon_url" | sed "s!^http://\([^/?#]*\).*!\1!" printf "%s\\n" "$ca_anon_url" | sed "s!^http://\\([^/?#]*\\).*!\\1!"
)" )"
ca_path="$( ca_path="$(
printf "%s\n" "$ca_anon_url" | sed "s!^http://[^/?#]*!!" printf "%s\\n" "$ca_anon_url" | sed "s!^http://[^/?#]*!!"
)" )"
ca_port=80 ca_port=80
# Note: too bad there is no portable case fall-through... # Note: too bad there is no portable case fall-through...
...@@ -739,38 +766,38 @@ EOF ...@@ -739,38 +766,38 @@ EOF
*]:*) *]:*)
# Bracket-enclosed address, which may contain colons # Bracket-enclosed address, which may contain colons
ca_address="$( ca_address="$(
printf "%s\n" "$ca_netloc" | sed "s!^\(.*\]\).*!\1!" printf "%s\\n" "$ca_netloc" | sed "s!^\\(.*\\]\\).*!\\1!"
)" )"
ca_port="$( ca_port="$(
printf "%s\n" "$ca_netloc" | sed "s!^[^\]]*\]:!!" printf "%s\\n" "$ca_netloc" | sed "s!^[^\\]]*\\]:!!"
)" )"
;; ;;
*]*) *]*)
# Bracket-enclosed address, which may contain colons # Bracket-enclosed address, which may contain colons
ca_address="$( ca_address="$(
printf "%s\n" "$ca_netloc" | sed "s!^\(.*\]\).*!\1!" printf "%s\\n" "$ca_netloc" | sed "s!^\\(.*\\]\\).*!\\1!"
)" )"
;; ;;
*:*) *:*)
# No bracket-encosed address, rely on colon # No bracket-encosed address, rely on colon
ca_address="$( ca_address="$(
printf "%s\n" "$ca_netloc" | sed "s!^\([^:]*\).*!\1!" printf "%s\\n" "$ca_netloc" | sed "s!^\\([^:]*\\).*!\\1!"
)" )"
ca_port="$( ca_port="$(
printf "%s\n" "$ca_netloc" | sed "s!^[^:]*:!!" printf "%s\\n" "$ca_netloc" | sed "s!^[^:]*:!!"
)" )"
;; ;;
*) *)
# No bracket-encosed address, rely on colon # No bracket-encosed address, rely on colon
ca_address="$( ca_address="$(
printf "%s\n" "$ca_netloc" | sed "s!^\([^:]*\).*!\1!" printf "%s\\n" "$ca_netloc" | sed "s!^\\([^:]*\\).*!\\1!"
)" )"
;; ;;
esac esac
if [ "$ca_port" -eq 80 ]; then if [ "$ca_port" -eq 80 ]; then
ca_port="" ca_port=""
else else
ca_port=":$(($ca_port + 1))" ca_port=":$((ca_port + 1))"
fi fi
ca_auth_url="https://${ca_address}${ca_port}${ca_path}" ca_auth_url="https://${ca_address}${ca_port}${ca_path}"
;; ;;
...@@ -811,11 +838,9 @@ EOF ...@@ -811,11 +838,9 @@ EOF
_needArg 1 || return 1 _needArg 1 || return 1
threshold="$1" threshold="$1"
shift shift
# Apparent no-op, but fails if "$threshoold" is not a number if [ "$threshold" -eq "$threshold" ] 2> /dev/null ; then
# Also, test outside of "if" statemnt so we do not have an :
# "if ... then : else ... fi". else
test "$threshold" -ge 0 -o "$threshold" -lt 0
if [ $? -ne 0 ]; then
_argUsage "Argument must be an integer" _argUsage "Argument must be an integer"
return 1 return 1
fi fi
...@@ -860,7 +885,7 @@ EOF ...@@ -860,7 +885,7 @@ EOF
)" )"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
printf "%s %s\n" "$csr_id" "$1" printf "%s %s\\n" "$csr_id" "$1"
shift shift
;; ;;
--get-crt) --get-crt)
...@@ -868,9 +893,14 @@ EOF ...@@ -868,9 +893,14 @@ EOF
csr_id="$1" csr_id="$1"
crt_path="$2" crt_path="$2"
shift 2 shift 2
if [ "$crt_path" != "-" -a ! -d "$(dirname "$crt_path")" -o "(" \ crt_dir="$(dirname "$crt_path")"
-e "$crt_path" -a ! "(" -w "$crt_path" -a -r "$crt_path" ")" \ if [ "x$crt_path" = "x-" ]; then # stdin & stdout
")" ]; then :
elif [ -w "$crt_path" ] && [ -r "$crt_path" ]; then # existing file
:
elif [ -w "$crt_dir" ] && [ -x "$crt_dir" ]; then # containing directory
:
else
_argUsage \ _argUsage \
"$crt_path is not writeable (and/or not readable if exists)" "$crt_path is not writeable (and/or not readable if exists)"
return 1 return 1
...@@ -879,7 +909,7 @@ EOF ...@@ -879,7 +909,7 @@ EOF
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
if [ "$crt_path" = "-" ]; then if [ "$crt_path" = "-" ]; then
printf "%s\n" "$crt" printf "%s\\n" "$crt"
else else
if [ -e "$crt_path" ]; then if [ -e "$crt_path" ]; then
key_found=0 key_found=0
...@@ -894,7 +924,7 @@ EOF ...@@ -894,7 +924,7 @@ EOF
return 1 return 1
fi fi
fi fi
printf "%s\n" "$crt" >> "$crt_path" printf "%s\\n" "$crt" >> "$crt_path"
fi fi
;; ;;
--revoke-crt) --revoke-crt)
...@@ -905,7 +935,7 @@ EOF ...@@ -905,7 +935,7 @@ EOF
crt="$(_matchOneKeyAndPrintOneMatchingCert "$crt_path" "$key_path")" crt="$(_matchOneKeyAndPrintOneMatchingCert "$crt_path" "$key_path")"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
printf "%s\n" "$crt" \ printf "%s\\n" "$crt" \
| revokeCertificate "${ca_anon_url}/${mode_path}" "$key_path" | revokeCertificate "${ca_anon_url}/${mode_path}" "$key_path"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
...@@ -918,9 +948,9 @@ EOF ...@@ -918,9 +948,9 @@ EOF
crt="$(_matchOneKeyAndPrintOneMatchingCert "$crt_path" "$key_path")" crt="$(_matchOneKeyAndPrintOneMatchingCert "$crt_path" "$key_path")"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
if printf "%s\n" "$crt" \ if printf "%s\\n" "$crt" \
| expiresBefore "$(date --date="$threshold days" +%s)"; then | expiresBefore "$(date --date="$threshold days" +%s)"; then
printf "%s\n" "$crt" \ printf "%s\\n" "$crt" \
| renewCertificate "${ca_anon_url}/${mode_path}" \ | renewCertificate "${ca_anon_url}/${mode_path}" \
"$key_path" \ "$key_path" \
"$key_len" \ "$key_len" \
...@@ -928,7 +958,7 @@ EOF ...@@ -928,7 +958,7 @@ EOF
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
else else
printf "%s did not reach renew threshold, not renewing\n" \ printf "%s did not reach renew threshold, not renewing\\n" \
"$crt_path" >&2 "$crt_path" >&2
fi fi
;; ;;
...@@ -943,9 +973,9 @@ EOF ...@@ -943,9 +973,9 @@ EOF
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
if [ "$csr_path" = "-" ]; then if [ "$csr_path" = "-" ]; then
printf "%s\n" "$csr" printf "%s\\n" "$csr"
else else
printf "%s\n" "$csr" > "$csr_path" printf "%s\\n" "$csr" > "$csr_path"
fi fi
;; ;;
--update-user) --update-user)
...@@ -955,9 +985,9 @@ EOF ...@@ -955,9 +985,9 @@ EOF
# Authenticated actions # Authenticated actions
--list-csr) --list-csr)
_needAuthURLAndArg 0 || return 1 _needAuthURLAndArg 0 || return 1
printf "%s\n" "-- pending $mode CSRs --" printf "%s\\n" "-- pending $mode CSRs --"
printf \ printf \
"%20s | subject preview (fetch csr and check full content !)\n" \ "%20s | subject preview (fetch csr and check full content !)\\n" \
"csr_id" "csr_id"
csr_list_json="$( csr_list_json="$(
getPendingCertificateRequestList "${ca_auth_url}/${mode_path}" \ getPendingCertificateRequestList "${ca_auth_url}/${mode_path}" \
...@@ -966,7 +996,7 @@ EOF ...@@ -966,7 +996,7 @@ EOF
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
printf "%s" "$csr_list_json" | forEachJSONListItem _printPendingCSR printf "%s" "$csr_list_json" | forEachJSONListItem _printPendingCSR
printf "%s\n" "-- end of pending $mode CSRs --" printf "%s\\n" "-- end of pending $mode CSRs --"
;; ;;
--sign-csr) --sign-csr)
_needAuthURLAndArg 1 || return 1 _needAuthURLAndArg 1 || return 1
...@@ -1004,7 +1034,7 @@ EOF ...@@ -1004,7 +1034,7 @@ EOF
crt="$(forEachCertificate _printOneCert < "$crt_path")" crt="$(forEachCertificate _printOneCert < "$crt_path")"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
printf "%s\n" "$crt" | revokeCRTWithoutKey \ printf "%s\\n" "$crt" | revokeCRTWithoutKey \
"${ca_auth_url}/${mode_path}" "$cas_ca" "$user_key" "${ca_auth_url}/${mode_path}" "$cas_ca" "$user_key"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
...@@ -1025,27 +1055,25 @@ EOF ...@@ -1025,27 +1055,25 @@ EOF
;; ;;
esac esac
done done
if [ -n "$ca_anon_url" -a -r "$cas_ca" ]; then if [ -n "$ca_anon_url" ] && [ -r "$cas_ca" ]; then
crl="$( if crl="$(
getCertificateRevocationList "${ca_anon_url}/cas" "$cas_ca" getCertificateRevocationList "${ca_anon_url}/cas" "$cas_ca"
)" )"; then
if [ $? -eq 0 ]; then printf "%s\\n" "$crl" > "$cas_crl"
printf "%s\n" "$crl" > "$cas_crl"
else else
printf "Received CAS CRL was not signed by CAS CA certificate, skipping\n" printf "Received CAS CRL was not signed by CAS CA certificate, skipping\\n"
fi fi
if [ $update_user -eq 1 ]; then if [ $update_user -eq 1 ]; then
updateCACertificate "${ca_anon_url}/cau" "$cas_ca" "$cau_ca" updateCACertificate "${ca_anon_url}/cau" "$cas_ca" "$cau_ca"
status=$? status=$?
test $status -ne 0 && return $status test $status -ne 0 && return $status
crl="$( if crl="$(
getCertificateRevocationList "${ca_anon_url}/cau" "$cau_ca" getCertificateRevocationList "${ca_anon_url}/cau" "$cau_ca"
)" )"; then
if [ $? -eq 0 ]; then printf "%s\\n" "$crl" > "$cau_crl"
printf "%s\n" "$crl" > "$cau_crl"
else else
printf \ printf \
"Received CAU CRL was not signed by CAU CA certificate, skipping\n" "Received CAU CRL was not signed by CAU CA certificate, skipping\\n"
fi fi
fi fi
fi fi
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment