From 3540d427862500b6d10573aa984f700a427a37eb Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <plr.vincent@gmail.com>
Date: Sun, 8 Jul 2018 10:15:10 +0000
Subject: [PATCH] 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.
---
 shell/caucase.sh | 242 ++++++++++++++++++++++++++---------------------
 1 file changed, 135 insertions(+), 107 deletions(-)

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