From af79b74c8cef941edc8539e5da40df82970c3a82 Mon Sep 17 00:00:00 2001
From: kytv <kytv@mail.i2p>
Date: Sat, 30 Mar 2013 21:52:01 +0000
Subject: [PATCH] checkcerts.sh: cross platform support on *NIX

- function to convert dates to Julian to perform date calculation if GNU date is
  not present.
---
 tests/scripts/checkcerts.sh | 130 ++++++++++++++++++++++++++++--------
 1 file changed, 101 insertions(+), 29 deletions(-)

diff --git a/tests/scripts/checkcerts.sh b/tests/scripts/checkcerts.sh
index 72aa9c53bd..bfa3e180f2 100755
--- a/tests/scripts/checkcerts.sh
+++ b/tests/scripts/checkcerts.sh
@@ -18,42 +18,90 @@ WARN=60
 SOON=30
 
 
-if [ $(which openssl) ]; then
-    OPENSSL=1
-elif [ $(which certtool) ]; then : ;else
-    echo "ERROR: Neither certtool nor openssl were found..." >&2
-    exit 1
-fi
+date2julian() {
+    # Julian date conversion adapted from a post (its code released into the public
+    # domain) by Tapani Tarvainen to comp.unix.shell (1998) for portability
+    # (e.g. using 'expr' instead of requiring Bash, ksh, or zsh).
+    #   $1 = Month
+    #   $2 = Day
+    #   $3 = Year
 
-# This "grouping hack" is here to prevent errors from being displayed with the
-# original Bourne shell (Linux shells don't need the {}s
-if { date --help;} >/dev/null 2>&1 ; then
-    HAVE_GNUDATE=1
-fi
+    if [ "${1}" != "" ] && [ "${2}" != ""  ] && [ "${3}" != "" ]; then
+        ## Because leap years add a day at the end of February,
+        ## calculations are done from 1 March 0000 (a fictional year)
+        d2j_tmpmonth=$(expr 12 \* $3 + $1 - 3)
+
+        ## If it is not yet March, the year is changed to the previous year
+        d2j_tmpyear=$(expr ${d2j_tmpmonth} / 12)
+
+        ## The number of days from 1 March 0000 is calculated
+        ## and the number of days from 1 Jan. 4713BC is added
+        expr \( 734 \* ${d2j_tmpmonth} + 15 \) / 24 - 2 \* ${d2j_tmpyear} + ${d2j_tmpyear} / 4 - ${d2j_tmpyear} / 100 + ${d2j_tmpyear} / 400 + $2 + 1721119
+    else
+        # We *really* shouldn't get here
+        echo 0
+    fi
+}
+
+getmonth() {
+    case ${1} in
+        Jan)
+            echo 1
+            ;;
+        Feb)
+            echo 2
+            ;;
+        Mar)
+            echo 3
+            ;;
+        Apr)
+            echo 4
+            ;;
+        May)
+            echo 5
+            ;;
+        Jun)
+            echo 6
+            ;;
+        Jul)
+            echo 7
+            ;;
+        Aug)
+            echo 8
+            ;;
+        Sep)
+            echo 9
+            ;;
+        Oct)
+            echo 10
+            ;;
+        Nov)
+            echo 11
+            ;;
+        Dec)
+            echo 12
+            ;;
+          *)
+            echo  0
+            ;;
+    esac
+}
 
 checkcert() {
     if [ $OPENSSL ]; then
+        # OpenSSL's format: Mar  7 16:08:35 2022 GMT
         DATA=$(openssl x509 -enddate -noout -in $1| cut -d'=' -f2-)
     else
+        # Certtool's format: Mon Mar 07 16:08:35 UTC 2022
         DATA=$(certtool -i < "$1" | sed -e '/Not\sAfter/!d' -e 's/^.*:\s\(.*\)/\1/')
+        # The formatting is normalized for passing to the date2julian function (if needed)
+        set -- `echo $DATA`
+        DATA="$2 $3 $4 $6 GMT"
     fi
-    # While this isn't strictly needed it'll ensure that the output is consistent,
-    # regardles of the tool used. Dates/times are formatting according to OpenSSL's output
-    # since this available by default on most systems.
-    if [ -n "$HAVE_GNUDATE" ]; then
-        LANG=C date -u -d "$(echo $DATA)" '+%b %d %H:%M:%S %Y GMT'
-    else
-        echo $DATA
-    fi
+    echo $DATA
 }
 
-compute_dates() {
-    # Date computations currently depend on GNU date(1).
-    # If run on a non-Linux system just print the expiration date.
-    # TODO Cross-platform date calculation support
-    if [ -n "$HAVE_GNUDATE" ]; then
-        SECS=$(date -u -d "$EXPIRES" '+%s')
-        DAYS="$(expr \( $SECS - $NOW \) / 86400)"
+print_status() {
         if [ $DAYS -ge $SOON ]; then
             echo "Expires in $DAYS days ($EXPIRES)"
         elif [ $DAYS -eq 1 ]; then
@@ -73,14 +121,38 @@ compute_dates() {
             echo "****** Check for $i failed, expired $DAYS days ago ($EXPIRES) ******"
             FAIL=1
         fi
+}
+
+compute_dates() {
+    if [ -n "$HAVE_GNUDATE" ]; then
+        SECS=$(date -u -d "$EXPIRES" '+%s')
+        DAYS="$(expr \( $SECS - $NOW \) / 86400)"
     else
-        echo $EXPIRES
+        set -- `echo $EXPIRES`
+        # date2julian needs the format mm dd yyyy
+        SECS=$(date2julian `getmonth $1` $2 $4)
+        DAYS=$(expr $SECS - $NOW)
     fi
+    print_status
 }
 
-cd `dirname $0`/../../installer/resources/certificates
+# This "grouping hack" is here to prevent errors from being displayed with the
+# original Bourne shell (Linux shells don't need the {}s
+if { date --help;} >/dev/null 2>&1 ; then
+    HAVE_GNUDATE=1
+    NOW=$(date -u '+%s')
+else
+    NOW=$(date2julian `date -u '+%m %d %Y'`)
+fi
 
-NOW=$(date -u '+%s')
+if [ $(which openssl) ]; then
+    OPENSSL=1
+elif [ $(which certtool) ]; then : ;else
+    echo "ERROR: Neither certtool nor openssl were found..." >&2
+    exit 1
+fi
+
+cd `dirname $0`/../../installer/resources/certificates
 
 for i in *.crt
 do
-- 
GitLab