source: tests/scripts/checkremotecerts.sh @ 6d9aa92

Last change on this file since 6d9aa92 was 6d9aa92, checked in by zzz <zzz@…>, 18 months ago

Tests: Fix some bashisms, add more files to bashisms check

  • Property mode set to 100755
File size: 4.0 KB
Line 
1#!/bin/sh
2set -e
3set -u
4
5BASEDIR="$(dirname $0)/../../"
6cd "$BASEDIR"
7RESEEDHOSTS=$(sed -e '/^\s\+"https:\/\/[-a-z0-9.]/!d' -e 's/.*"https:\/\/\([-a-z0-9.:]\+\).*/\1/' router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java)
8CERTHOME="installer/resources/certificates"
9CACERTS=$(mktemp)
10WORK=$(mktemp -d)
11FAIL=0
12MAX=5
13OPENSSL=0
14CERTTOOL=0
15
16check_for_prog() {
17    if which $1 > /dev/null 2>&1 ; then
18        return 0
19    else
20        return 1
21    fi
22}
23
24if pidof /usr/bin/tor > /dev/null 2>&1 && check_for_prog torsocks; then
25    echo "-- Detected Tor, will try using it --"
26    GNUTLS_BIN="torsocks gnutls-cli"
27    OPENSSL_BIN="torsocks openssl"
28else
29    GNUTLS_BIN="gnutls-cli"
30    OPENSSL_BIN="openssl"
31fi
32
33if check_for_prog certtool; then
34    CERTTOOL=1
35    echo "-- Checking certificates with GnuTLS --"
36elif check_for_prog openssl; then
37    OPENSSL=1
38    echo "-- Checking certificates with OpenSSL --"
39fi
40
41if [ $CERTTOOL -ne 1 ] && [ $OPENSSL -ne 1 ]; then
42    echo "ERROR: This script requires either gnutls or openssl" >&2
43    exit
44fi
45
46assemble_ca() {
47    # Combine system certificates with the certificates shipped with I2P into
48    # a large CA file for use with gnutls-cli later
49    cat /etc/ssl/certs/ca-certificates.crt "$CERTHOME"/*/*.crt > "$CACERTS"
50}
51
52retry ()
53# retry function borrowed from zzz's sync-mtn script
54{
55    if [ $# -eq 0 ]
56    then
57        echo 'usage: $0 command args...'
58        exit 1
59    fi
60
61    i=1
62    while ! "$@"
63    do
64        echo "try $i of $MAX failed for command $@" >&2
65        if [ $i -ge $MAX ]
66        then
67            break
68        fi
69        i=$(expr $i + 1)
70        sleep 15
71    done
72    if [ $i = $MAX ]; then
73        return 1
74    fi
75}
76
77normalize(){
78    # Convert fingerprint to the format output by GnuTLS
79    sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'
80}
81
82connect() {
83    if [ $OPENSSL -eq 1 ]; then
84        $OPENSSL_BIN s_client -connect "$1:$2" -CAfile $CACERTS -servername $1 < /dev/null 2> /dev/null
85    else
86        $GNUTLS_BIN --insecure --print-cert --x509cafile "$CACERTS" "$1" -p "$2"  < /dev/null 2>/dev/null
87    fi
88}
89
90extract_finger() {
91    if [ $CERTTOOL -eq 1 ]; then
92        # Roughly equivalent to "grep -A1 "SHA-1 fingerprint" | head -n 2 | grep -o '[a-f0-9]{40}'"
93        certtool -i < $1 | sed -n '/SHA-1 fingerprint/{n;p;q}' | sed 's/\s\+\([a-f0-9]\{40\}\)/\1/'
94    else
95        openssl x509 -in $1 -fingerprint -noout | normalize
96    fi
97}
98
99verify_fingerprint() {
100    if [ -e "$CERTHOME/ssl/$1.crt" ]; then
101        EXPECTED=$(extract_finger "$CERTHOME/ssl/$1.crt")
102        FOUND=$(extract_finger "$WORK/$1")
103        if [ "$EXPECTED" != "$FOUND" ]; then
104            echo -n "invalid certificate. Expected $EXPECTED, got $FOUND"
105            FAIL=1
106            echo $HOST >> $WORK/bad
107        fi
108    else
109        echo "Untrusted certficate and certificate not found at $CERTHOME/ssl" >&2
110        FAIL=1
111        echo $HOST >> $WORK/bad
112    fi
113}
114
115cleanup() {
116    rm -rf $CACERTS $WORK
117    exit $FAIL
118}
119
120check_hosts() {
121    for HOST in $RESEEDHOSTS; do
122        if $(echo $HOST | grep -q ':'); then
123            OLDIFS=$IFS
124            IFS=":"
125            set -- $HOST
126            HOSTNAM=$1
127            PORT=$2
128            IFS=$OLDIFS
129        else
130            HOSTNAM=$HOST
131            PORT=443
132        fi
133
134        echo -n "Checking $HOSTNAM:$PORT..."
135        if retry connect "$HOSTNAM" "$PORT"  < /dev/null 1> "$WORK/$HOST"; then
136
137            # OpenSSL returns "return code: 0 (ok)"
138            # GnuTLS returns "certificate is trusted"
139            # GnuTLS v2 has the word "Peer" before certificate, v3 has the word "The" before it
140            if ! grep -q 'Verify return code: 0 (ok)\|certificate is trusted' "$WORK/$HOST"; then
141                # If we end up here, it's possible that the certificate is valid, but CA: false is set in the certificate.
142                # The OpenSSL binary is "picky" about this. GnuTLS doesn't seem to be.
143                verify_fingerprint $HOST
144            fi
145            echo
146        else
147            echo "failed to connect to $HOST" >&2
148            FAIL=1
149        fi
150    done
151}
152
153assemble_ca
154check_hosts
155cleanup
156
Note: See TracBrowser for help on using the repository browser.