forked from I2P_Developers/i2p.i2p
checkremotecerts.sh: clean-ups, compatibility updates
It now works with either gnutls or openssl, and both gnutls v2 and gnutls v3.
This commit is contained in:
@ -2,26 +2,46 @@
|
|||||||
set -e
|
set -e
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
if ! which openssl > /dev/null 2>&1 || ! which gnutls-cli > /dev/null 2>&1; then
|
|
||||||
echo "This script (currently) requires both gnutls and openssl" >&2
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if pidof /usr/bin/tor > /dev/null 2>&1 && which torify > /dev/null 2>&1; then
|
|
||||||
echo "-- Detected Tor, will try using it --"
|
|
||||||
GNUTLS="torify gnutls-cli"
|
|
||||||
else
|
|
||||||
GNUTLS="gnutls-cli"
|
|
||||||
fi
|
|
||||||
|
|
||||||
BASEDIR="$(dirname $0)/../../"
|
BASEDIR="$(dirname $0)/../../"
|
||||||
cd "$BASEDIR"
|
cd "$BASEDIR"
|
||||||
RESEEDHOSTS=$(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)
|
RESEEDHOSTS=$(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)
|
||||||
|
CERTHOME="installer/resources/certificates"
|
||||||
CACERTS=$(mktemp)
|
CACERTS=$(mktemp)
|
||||||
WORK=$(mktemp -d)
|
WORK=$(mktemp -d)
|
||||||
FAIL=0
|
FAIL=0
|
||||||
CERTHOME="installer/resources/certificates"
|
MAX=5
|
||||||
|
OPENSSL=0
|
||||||
|
CERTTOOL=0
|
||||||
|
|
||||||
|
check_for_prog() {
|
||||||
|
if which $1 > /dev/null 2>&1 ; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if pidof /usr/bin/tor > /dev/null 2>&1 && check_for_prog torify; then
|
||||||
|
echo "-- Detected Tor, will try using it --"
|
||||||
|
GNUTLS_BIN="torify gnutls-cli"
|
||||||
|
OPENSSL_BIN="torify openssl"
|
||||||
|
else
|
||||||
|
GNUTLS_BIN="gnutls-cli"
|
||||||
|
OPENSSL_BIN="openssl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_prog certtool1; then
|
||||||
|
CERTTOOL=1
|
||||||
|
echo "-- Checking certificates with GnuTLS --"
|
||||||
|
elif check_for_prog openssl; then
|
||||||
|
OPENSSL=1
|
||||||
|
echo "-- Checking certificates with OpenSSL --"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $CERTTOOL -ne 1 ] && [ $OPENSSL -ne 1 ]; then
|
||||||
|
echo "ERROR: This script requires either gnutls or openssl" >&2
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
assemble_ca() {
|
assemble_ca() {
|
||||||
# Combine system certificates with the certificates shipped with I2P into
|
# Combine system certificates with the certificates shipped with I2P into
|
||||||
@ -52,39 +72,75 @@ retry ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
normalize(){
|
normalize(){
|
||||||
# The format displayed by gnutls-cli. This function is not used yet.
|
# Convert fingerprint to the format output by GnuTLS
|
||||||
sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'
|
sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
connect() {
|
||||||
for HOST in $RESEEDHOSTS; do
|
if [ $OPENSSL -eq 1 ]; then
|
||||||
echo -n "Checking $HOST..."
|
retry $OPENSSL_BIN s_client -connect "$1:443" -no_ign_eof -CAfile $CACERTS -servername $1 < /dev/null 2>/dev/null
|
||||||
# Using --insecure here for those cases in which our
|
else
|
||||||
retry $GNUTLS --insecure --print-cert --x509cafile="$CACERTS" "$HOST" < /dev/null > "$WORK/$HOST.test"
|
retry $GNUTLS_BIN --insecure --print-cert --x509cafile "$CACERTS" "$1" < /dev/null 2>/dev/null
|
||||||
if $(grep -q 'The certificate issuer is unknown' "$WORK/$HOST.test"); then
|
fi
|
||||||
# If we end up here it's for one of two probable reasons:
|
}
|
||||||
# 1) the the CN in the certificate doesn't match the hostname.
|
|
||||||
# 2) the certificate is invalid
|
extract_finger() {
|
||||||
if [ -e "$CERTHOME/ssl/$HOST.crt" ]; then
|
if [ $CERTTOOL -eq 1 ]; then
|
||||||
openssl x509 -in "$CERTHOME/ssl/$HOST.crt" -fingerprint -noout > "$WORK/$HOST.expected.finger"
|
# Roughly equivalent to "grep -A1 "SHA-1 fingerprint" | head -n 2 | grep -o '[a-f0-9]{40}'"
|
||||||
openssl x509 -in "$WORK/$HOST.test" -fingerprint -noout > "$WORK/$HOST.real.finger"
|
certtool -i < $1 | sed -n '/SHA-1 fingerprint/{n;p;q}' | sed 's/\s\+\([a-f0-9]\{40\}\)/\1/'
|
||||||
if [ "$(cat "$WORK/$HOST.expected.finger")" != "$(cat "$WORK/$HOST.real.finger")" ]; then
|
else
|
||||||
echo -n "invalid certificate for $HOST"
|
openssl x509 -in $1 -fingerprint -noout | normalize
|
||||||
FAIL=1
|
fi
|
||||||
echo $HOST >> $WORK/bad
|
}
|
||||||
fi
|
|
||||||
else
|
verify_fingerprint() {
|
||||||
echo "Untrusted certficate and certificate not found at $CERTHOME/ssl" >&2
|
if [ -e "$CERTHOME/ssl/$1.crt" ]; then
|
||||||
|
EXPECTED=$(extract_finger "$CERTHOME/ssl/$1.crt")
|
||||||
|
FOUND=$(extract_finger "$WORK/$1")
|
||||||
|
if [ "$EXPECTED" != "$FOUND" ]; then
|
||||||
|
echo -n "invalid certificate. Expected $EXPECTED, got $FOUND"
|
||||||
FAIL=1
|
FAIL=1
|
||||||
echo $HOST >> $WORK/bad
|
echo $HOST >> $WORK/bad
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
echo "Untrusted certficate and certificate not found at $CERTHOME/ssl" >&2
|
||||||
|
FAIL=1
|
||||||
|
echo $HOST >> $WORK/bad
|
||||||
fi
|
fi
|
||||||
echo
|
}
|
||||||
done
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf $CACERTS $WORK
|
||||||
|
exit $FAIL
|
||||||
|
}
|
||||||
|
|
||||||
|
check_hosts() {
|
||||||
|
for HOST in $RESEEDHOSTS; do
|
||||||
|
echo -n "Checking $HOST..."
|
||||||
|
connect "$HOST" < /dev/null > "$WORK/$HOST"
|
||||||
|
|
||||||
|
# OpenSSL returns "return code: 0 (ok)"
|
||||||
|
# GnuTLS returns "certificate is trusted"
|
||||||
|
# GnuTLS v2 has the word "Peer" before certificate, v3 has the word "The" before it
|
||||||
|
if ! grep -q 'Verify return code: 0 (ok)\|certificate is trusted' "$WORK/$HOST"; then
|
||||||
|
# If we end up here it's for one of two probable reasons:
|
||||||
|
# 1) the the CN in the certificate doesn't match the hostname.
|
||||||
|
# 2) the certificate is invalid
|
||||||
|
|
||||||
|
# OpenSSL returns code 21 with self-signed certs.
|
||||||
|
# GnuTLS returns "certificate issuer is unknown"
|
||||||
|
# As noted above, GnuTLS v2 has the word "Peer" before certificate, v3 has the word "The" before it
|
||||||
|
|
||||||
|
# If the CN just doesn't match the hostname, pass
|
||||||
|
if ! grep -q 'Verify return code: 21\|certificate issuer is unknown' "$WORK/$HOST"; then : ;else
|
||||||
|
verify_fingerprint $HOST
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
assemble_ca
|
assemble_ca
|
||||||
check
|
check_hosts
|
||||||
|
cleanup
|
||||||
|
|
||||||
rm -rf $CACERTS $WORK
|
|
||||||
exit $FAIL
|
|
||||||
|
Reference in New Issue
Block a user