blob: 28865bda8aa28ce7983ca078762a75a70e917262 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/bin/bash
# see also Docs/ssl-infos/tools/
# i= &&tail -n+$((i*5000)) /tmp/top-1m.csv | head -5000 |~/scripts/cert-info csv $i
# killall -v cert-info -s 0
usage() {
[ -z "$1" ] || echo "$1" >&2
echo "Usage: $0 [options] hostname[:port] [hostname[:port]].." >&2
echo " $0 csv out-dir <file [options]" >&2
echo "options (may be interleaved between hosts):"
awk '/^parse_arg\(/{p=1}
/}/{if(p)exit}
/#/{if(p){sub(/\).*# */,"\t");print}}' "$0"
echo "csv file from http://s3.amazonaws.com/alexa-static/top-1m.csv.zip"
exit 1
}
auto_less() {
[ ! -t 1 ] || { "$0" "$@" | less; exit $?; }
}
main() {
if [ "$1" = "csv" ]; then
[ $# -ge 2 ] || usage "Missing outdir"
outdir="${2:-.}/"
mkdir -p "$outdir"
tmp=$(mktemp); trap "rm -f $tmp" EXIT
shift 2
for arg; do parse_arg "$arg" || usage "Unrecognized option $arg"; done
i=0
while IFS=,; read -r no host; do
# strip path if any
host="${host%%/*}"
[ -n "$host" ] || continue
outfile="$outdir$host.txt"
if [ -e "$outfile" ]; then
echo "Skipping existing $outfile"
else
printf "%5d %s %6d %s\n" $((++i)) "$(date -R)" "$no" "$host"
get_cert "$host" 443 | parse_cert > "$tmp" 2>&1
mv "$tmp" "$outfile"
#[ -s "$outfile" ] || echo "# no cert for $host"
fi
done
elif [ ! -t 0 ]; then
auto_less "$@"
for arg; do
parse_arg "$arg" || :
done
parse_cert
elif [ $# -gt 0 ]; then
auto_less "$@"
for arg; do
! parse_arg "$arg" || continue
host="${arg%%:*}"
port="${arg##*:}"
[ "$port" != "$arg" -a -n "$port" ] || port=443
echo "# === $host:$port ==="
get_cert "$host" "$port" | parse_cert
done
else
usage
fi
}
get_cert() {
local host="$1" port="$2"
if ! nc -z -w 2 "$host" "$port"; then
echo "# conn timeout for $host:$port!" >&2
return 1
fi
</dev/null 2>/dev/null \
timeout 5 openssl s_client \
-connect "$host:$port" -servername "$host" -showcerts
}
parse_arg() {
case "$1" in
-) depth_1=1 ;; # less certificates [def]
+) depth_1=0 ;; # more certificates
-=) cert_only=1 ;; # less output (just raw cert)
+=) cert_only=0 ;; # more output (verbose details) [def]
-cert) include_cert=0 ;; # hide raw cert (-noout)
+cert) include_cert=1 ;; # include raw cert [def]
*) return 1 ;;
esac
}
parse_arg -
parse_arg +=
parse_arg +cert
parse_cert() {
infocmd="openssl x509 -text -nameopt sep_comma_plus_space"
[ $include_cert -eq 1 ] || infocmd="$infocmd -noout"
awk -vOneOnly="$depth_1" -vCertOnly="$cert_only" \
-vinfocmd="$infocmd" '
BEGIN {
sep="# ";
for (i=0; i<77; i++) {
sep=sep"-";
}
}
/^-----BEGIN (TRUSTED )?CERTIFICATE-----$/ {
in_cert=1;
}
{
if (in_cert) {
cert = cert $0 "\n";
}
}
/^-----END (TRUSTED )?CERTIFICATE-----$/ {
in_cert = 0;
}
{
if (!in_cert && cert) {
if (CertOnly) {
print cert;
} else {
print cert | infocmd;
close(infocmd);
print sep;
}
cert="";
if (OneOnly) exit;
}
}
'
}
main "$@"
|