lib/cert_checker.rb in cert_checker-0.1.2 vs lib/cert_checker.rb in cert_checker-0.1.3
- old
+ new
@@ -13,42 +13,42 @@
DEFAULT_TIMEOUT = 5
ONE_DAY = 3600.0 * 24
def get_cert(host, port = 443, timeout: DEFAULT_TIMEOUT)
tcp_client = Socket.tcp(host, port, connect_timeout: timeout)
- ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client)
+ ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, new_ctx)
ssl_client.hostname = host
begin
ssl_client.connect_nonblock
rescue IO::WaitReadable
retry if IO.select([ssl_client], nil, nil, timeout)
rescue IO::WaitWritable
retry if IO.select(nil, [ssl_client], nil, timeout)
end
- [ssl_client.peer_cert, ssl_client.peer_cert_chain].tap do
+ [ssl_client.peer_cert, ssl_client.peer_cert_chain, ssl_client.alpn_protocol].tap do
ssl_client.close
tcp_client.close
end
rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
raise CertChecker::Error.new("Failed to get cert of #{host}:#{port}. #{e.inspect}")
end
# @return [cert, verify_result, cert_chain, err_str]
def verify(host, *args)
- cert, cert_chain = get_cert(host, *args)
+ cert, cert_chain, alpn_protocol = get_cert(host, *args)
if cert
err = nil
result = cert_store.verify(cert, cert_chain) { |r, s| err = s.error_string unless r; r }
- [cert, result, cert_chain, err]
+ [cert, result, cert_chain, alpn_protocol, err]
end
end
# @return [status_symbol, host, issuer, expired_at, desc]
def check(host, *args)
- cert, verify_result, _cert_chain, err_str = verify(host, *args)
+ cert, verify_result, _cert_chain, alpn_protocol, err_str = verify(host, *args)
return [:failed, host, nil, nil, nil] unless cert
status_sym = :unverifiable unless verify_result
issuer = get_cert_issuer_name(cert)
expired_at = cert.not_after
@@ -61,19 +61,25 @@
elsif expired_at <= Time.now + 15 * ONE_DAY then :urgent
elsif expired_at <= Time.now + 30 * ONE_DAY then :warning
else :ok
end
- [status_sym, host, issuer, expired_at, desc]
+ [status_sym, host, issuer, expired_at, desc, alpn_protocol]
end
def cert_store
@cert_store ||= OpenSSL::X509::Store.new.tap do |store|
store.set_default_paths
end
end
private
+
+ def new_ctx
+ OpenSSL::SSL::SSLContext.new.tap do |ctx|
+ ctx.alpn_protocols = %w{http/1.1 h2}
+ end
+ end
def verify_cert_dns(host, cert)
dns_ext = cert.extensions.find { |e| e.oid == 'subjectAltName' }
dns = dns_ext.value.split(',').map { |d| d.split(':').last }
!dns.all? { |d| !(Regexp.new('\A' + d.gsub('*', '.+') + '\z') =~ host) }