check_certificate_chain 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/check_certificate_chain +38 -33
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 75ea7ed83779b3f53f066ec606710f5f442d793119de9b13b5413bd1e2d8f4c2
|
4
|
+
data.tar.gz: 6f696988b3e1db693ec81472c574b5894469b8e2a713ddb79ed2cd4e0b09569f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd1d34e56248593fe06a4a9ce7ca28fbe2a188d2c52e8eafb48409fc3be25f13db2a03f1533677f56e44d130ef65623d2ffcc9c8be1782b58cc3592cba5d2b09
|
7
|
+
data.tar.gz: a5931720fbf5d9c0710fa49eab07656f7ab71b7aa7f1df519d54e2e603a3f420d2a7e6e60f36e107d0fd6786e9805584014969a8f678db6667b2e8af80090121
|
data/bin/check_certificate_chain
CHANGED
@@ -4,10 +4,21 @@ require 'openssl'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'socket'
|
6
6
|
require 'net/http'
|
7
|
+
require 'pastel'
|
7
8
|
|
8
9
|
hostname = URI(ARGV[0])
|
9
10
|
hostname = hostname.host.nil? ? hostname.to_s : hostname.host
|
10
11
|
|
12
|
+
pastel = Pastel.new(eachline: "\n")
|
13
|
+
|
14
|
+
good = pastel.green.detach
|
15
|
+
good_bold = pastel.green.bold.detach
|
16
|
+
goody = pastel.bright_green.detach
|
17
|
+
goody_bold = pastel.bright_green.bold.detach
|
18
|
+
bad = pastel.red.detach
|
19
|
+
bad_bold = pastel.red.bold.detach
|
20
|
+
warning = pastel.yellow.detach
|
21
|
+
|
11
22
|
|
12
23
|
openssl_context = OpenSSL::SSL::SSLContext.new
|
13
24
|
|
@@ -32,8 +43,7 @@ output = {}
|
|
32
43
|
output[:header] = "---"
|
33
44
|
output[:hostname_check] = ""
|
34
45
|
output[:date_check] = ""
|
35
|
-
output[:
|
36
|
-
output[:long] = []
|
46
|
+
output[:data] = []
|
37
47
|
output[:issues] = []
|
38
48
|
output[:ocsp_check] = []
|
39
49
|
|
@@ -53,10 +63,10 @@ certificate = chain.first
|
|
53
63
|
|
54
64
|
# Check certificate hostname
|
55
65
|
if OpenSSL::SSL.verify_certificate_identity certificate, hostname
|
56
|
-
output[:hostname_check] << "The hostname
|
66
|
+
output[:hostname_check] << good["The hostname #{good_bold[hostname]} is correctly listed in the certificate."]
|
57
67
|
check_certificate_hostname = true
|
58
68
|
else
|
59
|
-
output[:hostname_check] << "None of the common names in the certificate match the name that was entered
|
69
|
+
output[:hostname_check] << bad["None of the common names in the certificate match the name that was entered #{bad_bold[hostname]}."]
|
60
70
|
check_certificate_hostname = false
|
61
71
|
end
|
62
72
|
|
@@ -70,10 +80,10 @@ def days
|
|
70
80
|
end
|
71
81
|
|
72
82
|
if AFTER > NOW
|
73
|
-
output[:date_check] << "Certificate is up to date.
|
83
|
+
output[:date_check] << good["Certificate is up to date. #{good_bold[days]} days remaining."]
|
74
84
|
not_expired = true
|
75
85
|
else
|
76
|
-
output[:date_check] << "Certificate is outdated. This certificate has expired
|
86
|
+
output[:date_check] << bad["Certificate is outdated. This certificate has expired #{bad_bold[days]} days ago."]
|
77
87
|
not_expired = false
|
78
88
|
end
|
79
89
|
|
@@ -117,38 +127,38 @@ if check_certificate_hostname && not_expired && authority_info_access
|
|
117
127
|
nonce_status = ocsp_request.check_nonce basic
|
118
128
|
case nonce_status
|
119
129
|
when 1
|
120
|
-
output[:ocsp_check] << "OCSP: nonce is ok."
|
130
|
+
output[:ocsp_check] << goody["OCSP: nonce is #{goody_bold['ok']}."]
|
121
131
|
nonce_check = true
|
122
132
|
when -1, 2, 3
|
123
|
-
output[:ocsp_check] << "OCSP: nonce is
|
133
|
+
output[:ocsp_check] << warning["OCSP: nonce is not supported."]
|
124
134
|
nonce_check = true
|
125
135
|
when 0
|
126
|
-
output[:ocsp_check] << "OCSP: nonce check failed."
|
136
|
+
output[:ocsp_check] << bad["OCSP: nonce check failed."]
|
127
137
|
nonce_check = false
|
128
138
|
end
|
129
139
|
|
130
140
|
if nonce_check
|
131
141
|
ocsp_single_response = basic.find_response(certificate_id)
|
132
142
|
unless ocsp_single_response
|
133
|
-
output[:ocsp_check] << "OCSP: no response for this certificate"
|
143
|
+
output[:ocsp_check] << bad["OCSP: no response for this certificate"]
|
134
144
|
end
|
135
145
|
|
136
146
|
unless ocsp_single_response.check_validity
|
137
|
-
output[:ocsp_check] << "OCSP: time validity failed."
|
147
|
+
output[:ocsp_check] << bad["OCSP: time validity failed."]
|
138
148
|
end
|
139
149
|
|
140
150
|
case ocsp_single_response.cert_status
|
141
151
|
when 0
|
142
|
-
output[:ocsp_check] << "OCSP: certificate is ok."
|
152
|
+
output[:ocsp_check] << goody["OCSP: certificate is #{goody_bold['ok']}."]
|
143
153
|
when 1
|
144
|
-
output[:ocsp_check] << "OCSP: certificate is revoked."
|
154
|
+
output[:ocsp_check] << bad["OCSP: certificate is revoked."]
|
145
155
|
when 2
|
146
|
-
output[:ocsp_check] << "OCSP: certificate status is unknown."
|
156
|
+
output[:ocsp_check] << warning["OCSP: certificate status is unknown."]
|
147
157
|
end
|
148
158
|
end
|
149
159
|
end
|
150
160
|
else
|
151
|
-
output[:ocsp_check] << "OCSP: response returned an error. Status of the response is #{ocsp_response.status_string}"
|
161
|
+
output[:ocsp_check] << bad["OCSP: response returned an error. Status of the response is #{ocsp_response.status_string}"]
|
152
162
|
end
|
153
163
|
end
|
154
164
|
end
|
@@ -161,22 +171,22 @@ root_anchor = chain.find do |certificate|
|
|
161
171
|
end
|
162
172
|
|
163
173
|
if root_anchor
|
164
|
-
output[:issues] << " Certificate chain contains root_anchor. Extra certificate (Which serves no purpose) is increasing the handshake latency."
|
174
|
+
output[:issues] << warning[" Certificate chain contains root_anchor. Extra certificate (Which serves no purpose) is increasing the handshake latency."]
|
165
175
|
end
|
166
176
|
|
167
177
|
def long_output(chain_certificate, output)
|
168
178
|
|
169
|
-
output[:
|
179
|
+
output[:data] << "Common name: #{chain_certificate.subject.to_s[/CN=(.+)/, 1]}"
|
170
180
|
sans = chain_certificate.extensions.find{|extension| extension.oid.eql?("subjectAltName")}
|
171
181
|
unless sans.nil?
|
172
182
|
sans = sans.value.delete("DSN:")
|
173
|
-
output[:
|
183
|
+
output[:data] << "SANs: #{sans}"
|
174
184
|
end
|
175
|
-
output[:
|
185
|
+
output[:data] << chain_certificate.not_before.strftime("Valid from %B %-d, %Y ") +
|
176
186
|
chain_certificate.not_after.strftime("to %B %-d, %Y")
|
177
|
-
output[:
|
178
|
-
output[:
|
179
|
-
output[:
|
187
|
+
output[:data] << "Serial Number: #{chain_certificate.serial.to_s(16).downcase}"
|
188
|
+
output[:data] << "Signature Algorithm: #{chain_certificate.signature_algorithm}"
|
189
|
+
output[:data] << "Issuer: #{chain_certificate.issuer.to_s[/CN=(.+)/, 1]}"
|
180
190
|
# output[:long] << "---\n"
|
181
191
|
end
|
182
192
|
|
@@ -186,11 +196,8 @@ chain_check_status = true
|
|
186
196
|
chain_order_status = true
|
187
197
|
|
188
198
|
chain.each_with_index do |chain_certificate, index|
|
189
|
-
output[:short] << "#{index} s:#{chain_certificate.subject.to_s}"
|
190
|
-
output[:short] << " i:#{chain_certificate.issuer.to_s}"
|
191
|
-
|
192
199
|
long_output(chain_certificate, output)
|
193
|
-
output[:
|
200
|
+
output[:data] << "---"
|
194
201
|
|
195
202
|
if chain_check_status
|
196
203
|
check_status = chain.any? do |possible_issuer|
|
@@ -209,25 +216,23 @@ chain.each_with_index do |chain_certificate, index|
|
|
209
216
|
unless check_status
|
210
217
|
if certificate_store.verify chain_certificate
|
211
218
|
long_output(certificate_store.chain.last, output)
|
212
|
-
output[:
|
219
|
+
output[:data] << "---"
|
213
220
|
else
|
214
221
|
chain_check_status = false
|
215
|
-
output[:issues] << " Root certificate is not trusted."
|
222
|
+
output[:issues] << bad[" Root certificate is not trusted."]
|
216
223
|
end
|
217
224
|
end
|
218
225
|
else
|
219
226
|
chain_check_status = false
|
220
|
-
output[:issues] << " Chain is broken."
|
227
|
+
output[:issues] << bad[" Chain is broken."]
|
221
228
|
end
|
222
229
|
end
|
223
230
|
|
224
231
|
unless chain_order_status
|
225
|
-
output[:issues] << " Incorrect chain order."
|
232
|
+
output[:issues] << warning[" Incorrect chain order."]
|
226
233
|
end
|
227
234
|
|
228
235
|
puts output[:header]
|
229
|
-
puts output[:short]
|
230
|
-
puts "---\n"
|
231
236
|
puts output[:hostname_check]
|
232
237
|
puts output[:date_check]
|
233
238
|
puts output[:ocsp_check]
|
@@ -236,4 +241,4 @@ unless output[:issues].empty?
|
|
236
241
|
puts output[:issues]
|
237
242
|
end
|
238
243
|
puts "---\n"
|
239
|
-
puts output[:
|
244
|
+
puts output[:data]
|
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.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jora Porcu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: openssl
|
@@ -24,8 +24,22 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
-
|
28
|
-
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pastel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: CLI tool to display certificate chain and OCSP status
|
42
|
+
email: admin@punani.ru
|
29
43
|
executables:
|
30
44
|
- check_certificate_chain
|
31
45
|
extensions: []
|
@@ -52,8 +66,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
66
|
version: '0'
|
53
67
|
requirements: []
|
54
68
|
rubyforge_project:
|
55
|
-
rubygems_version: 2.
|
69
|
+
rubygems_version: 2.7.3
|
56
70
|
signing_key:
|
57
71
|
specification_version: 4
|
58
|
-
summary: CLI tool to
|
72
|
+
summary: CLI tool to display certificate chain and OCSP status
|
59
73
|
test_files: []
|