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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/check_certificate_chain +53 -13
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6befb1fbe46dc8874a339d0c4520c5b109496ede77e659dc3fadbf1892ca11e
4
- data.tar.gz: c401f0289313bd3b61b602c68805ff9a8c651fb569dac441fce6024e455295a5
3
+ metadata.gz: 27a772594eae8ed954707e4d446184fc6bbfcde6348facdd9ee7b4a1f7050be2
4
+ data.tar.gz: 0015ff495b15b9bba9511b13c46762137945632af903cf4401d7c6310ce506e5
5
5
  SHA512:
6
- metadata.gz: 2c55067f1e178b0c4d650bbf66b22a58feffa26871af7bacc39094db508d9a20502a327e0ef95756566c447e822a68bad0b53de4eabb31b5c1eb0417bc73a221
7
- data.tar.gz: a7c26f08455795e27fa7394381f1f3a9fccd9a6200b5a8d6caa56e6a70314fd0fce8912cddac1a3c8c9867ddbf747df8fab9f9cf7e11ca2a7e4339709a2e89a6
6
+ metadata.gz: b562158f6c3d2160f95d2f46be905bc6199eede081126b54d2b9b27572d55feef2f8eb9d41249143b51714a9e4d14e56170cfd244a8c002d79edc405baae3138
7
+ data.tar.gz: 57a5bc19f8524abec71372cbe4a71fc423d8bbc5861b4bcc79f0d0be624b7a53604679ad158af96f752215fc24ec095ddbd3cd686f7da5683f978435ee6fdacf
@@ -6,8 +6,33 @@ require 'socket'
6
6
  require 'net/http'
7
7
  require 'pastel'
8
8
 
9
- hostname = URI(ARGV[0])
10
- hostname = hostname.host.nil? ? hostname.to_s : hostname.host
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(hostname, 443)
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 = 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, hostname
70
- output[:hostname_check] << good["The hostname #{good_bold[hostname]} is correctly listed in the certificate."]
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[hostname]}."]
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? chain_certificate &&
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
- long_output(certificate_store.chain.last, output)
223
- output[:data] << "---"
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
- output[:issues] << bad[" Root certificate is not trusted."]
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.0
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-05 00:00:00.000000000 Z
11
+ date: 2019-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: openssl