check_certificate_chain 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/check_certificate_chain +53 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27a772594eae8ed954707e4d446184fc6bbfcde6348facdd9ee7b4a1f7050be2
|
4
|
+
data.tar.gz: 0015ff495b15b9bba9511b13c46762137945632af903cf4401d7c6310ce506e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b562158f6c3d2160f95d2f46be905bc6199eede081126b54d2b9b27572d55feef2f8eb9d41249143b51714a9e4d14e56170cfd244a8c002d79edc405baae3138
|
7
|
+
data.tar.gz: 57a5bc19f8524abec71372cbe4a71fc423d8bbc5861b4bcc79f0d0be624b7a53604679ad158af96f752215fc24ec095ddbd3cd686f7da5683f978435ee6fdacf
|
data/bin/check_certificate_chain
CHANGED
@@ -6,8 +6,33 @@ require 'socket'
|
|
6
6
|
require 'net/http'
|
7
7
|
require 'pastel'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
servername = ""
|
10
|
+
host = ""
|
11
|
+
port = ""
|
12
|
+
|
13
|
+
|
14
|
+
def usage
|
15
|
+
puts "Usage: script.rb servername:host:port",
|
16
|
+
"Usage: script.rb host:port",
|
17
|
+
"Usage: script.rb host",
|
18
|
+
"Notice: if servername omitted, script takes host as TSL SNI servername",
|
19
|
+
"Notice: if port is omitted script takes 443 as default"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
23
|
+
usage if ARGV.size != 1
|
24
|
+
|
25
|
+
argument_re = /^(((?<ip01>(\d{1,3}\.){3}\d{1,3})|(?<domain01>([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,})):)?
|
26
|
+
((?<ip02>(\d{1,3}\.){3}\d{1,3})|(?<domain02>([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}))
|
27
|
+
(:(?<port>\d{1,5}))?$/xi
|
28
|
+
|
29
|
+
|
30
|
+
argument_match_result = ARGV[0].match argument_re
|
31
|
+
|
32
|
+
host = argument_match_result[:ip02] || argument_match_result[:domain02]
|
33
|
+
servername = (argument_match_result[:ip01] || argument_match_result[:domain01]) || host
|
34
|
+
port = argument_match_result[:port] || "443"
|
35
|
+
|
11
36
|
|
12
37
|
pastel = Pastel.new(eachline: "\n")
|
13
38
|
|
@@ -22,13 +47,13 @@ warning = pastel.yellow.detach
|
|
22
47
|
|
23
48
|
openssl_context = OpenSSL::SSL::SSLContext.new
|
24
49
|
|
25
|
-
tcp_socket = TCPSocket.new(
|
50
|
+
tcp_socket = TCPSocket.new(host, port.to_i)
|
26
51
|
ip = tcp_socket.peeraddr(false).last
|
27
52
|
|
28
53
|
chain = nil
|
29
54
|
|
30
55
|
OpenSSL::SSL::SSLSocket.new(tcp_socket, openssl_context).tap do |ssl_socket|
|
31
|
-
ssl_socket.hostname =
|
56
|
+
ssl_socket.hostname = servername
|
32
57
|
ssl_socket.sync_close = true
|
33
58
|
ssl_socket.connect
|
34
59
|
|
@@ -43,7 +68,7 @@ certificate_store.set_default_paths
|
|
43
68
|
output = {}
|
44
69
|
output[:header] = "---"
|
45
70
|
|
46
|
-
output[:header] << "\nConnected to #{ip}\n---\n"
|
71
|
+
output[:header] << "\nConnected to #{ip}:#{port} with #{servername} as TLS SNI servername\n---\n"
|
47
72
|
|
48
73
|
output[:hostname_check] = ""
|
49
74
|
output[:date_check] = ""
|
@@ -66,11 +91,18 @@ end
|
|
66
91
|
certificate = chain.first
|
67
92
|
|
68
93
|
# Check certificate hostname
|
69
|
-
if OpenSSL::SSL.verify_certificate_identity certificate,
|
70
|
-
|
94
|
+
if OpenSSL::SSL.verify_certificate_identity certificate, servername
|
95
|
+
if certificate.subject.to_a.empty?
|
96
|
+
output[:issues] << warning[" Subject is empty"]
|
97
|
+
else
|
98
|
+
output[:issues] << warning[" Canonic Name is empty in subject"] unless certificate.subject.to_a.any?{|cn_entry_array| cn_entry_array.first.eql? "CN"}
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
output[:hostname_check] << good["The hostname #{good_bold[servername]} is correctly listed in the certificate."]
|
71
103
|
check_certificate_hostname = true
|
72
104
|
else
|
73
|
-
output[:hostname_check] << bad["None of the common names in the certificate match the name that was entered #{bad_bold[
|
105
|
+
output[:hostname_check] << bad["None of the common names in the certificate match the name that was entered #{bad_bold[servername]}."]
|
74
106
|
check_certificate_hostname = false
|
75
107
|
end
|
76
108
|
|
@@ -205,25 +237,33 @@ chain.each_with_index do |chain_certificate, index|
|
|
205
237
|
|
206
238
|
if chain_check_status
|
207
239
|
check_status = chain.any? do |possible_issuer|
|
208
|
-
unless possible_issuer.eql?
|
209
|
-
is_root?(chain_certificate)
|
240
|
+
unless possible_issuer.eql?(chain_certificate) && is_root?(chain_certificate)
|
210
241
|
if chain_certificate.verify possible_issuer.public_key
|
242
|
+
output[:issues] << bad[" Certificate is self-signed"] if chain_certificate.eql?(possible_issuer)
|
211
243
|
if chain.index(possible_issuer) - chain.index(chain_certificate) > 1
|
212
244
|
chain_order_status = false
|
213
245
|
end
|
214
246
|
true
|
215
247
|
end
|
248
|
+
else
|
249
|
+
check_status = false
|
216
250
|
end
|
217
251
|
end
|
218
252
|
|
219
253
|
# If check failed check against the root store
|
220
254
|
unless check_status
|
221
255
|
if certificate_store.verify chain_certificate
|
222
|
-
|
223
|
-
|
256
|
+
unless root_anchor
|
257
|
+
long_output(certificate_store.chain.last, output)
|
258
|
+
output[:data] << "---"
|
259
|
+
end
|
224
260
|
else
|
225
261
|
chain_check_status = false
|
226
|
-
|
262
|
+
if is_root? chain_certificate
|
263
|
+
output[:issues] << bad[" Root certificate is not trusted."]
|
264
|
+
else
|
265
|
+
output[:issues] << bad[" Chain is broken."]
|
266
|
+
end
|
227
267
|
end
|
228
268
|
end
|
229
269
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: check_certificate_chain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jora Porcu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: openssl
|