class SSLTool::CertificateStore
Public Class Methods
instantiate_adapter(store_url)
click to toggle source
# File lib/ssltool/certificate_store.rb, line 22 def self.instantiate_adapter(store_url) scheme = URI.parse(store_url).scheme if scheme == 'file' then require_relative 'adapters/filesystem' FilesystemAdapter.new(store_url.sub(%r[^file://], '')) else require_relative 'adapters/sequel' raise ArgumentError unless Sequel::Database::ADAPTERS.include?(scheme.to_sym) SequelAdapter.new(store_url) end end
new(store_url)
click to toggle source
# File lib/ssltool/certificate_store.rb, line 14 def initialize(store_url) @circular_chain_notification_callbacks = [] @adapter = self.class.instantiate_adapter(store_url) @trusted_pool = @adapter.load_pool(:trusted).keep_if(&:acceptable?) @intermediate_pool = @adapter.load_pool(:intermediate).keep_if(&:acceptable?) @excluded_pool = @adapter.load_pool(:excluded) end
Public Instance Methods
combined_trusted_pool_set()
click to toggle source
trust
# File lib/ssltool/certificate_store.rb, line 36 def combined_trusted_pool_set (@trusted_pool + @intermediate_pool).to_set.freeze end
detect_and_merge_intermediates!(unfiltered_pool, strict = true)
click to toggle source
intermediate detection
# File lib/ssltool/certificate_store.rb, line 46 def detect_and_merge_intermediates!(unfiltered_pool, strict = true) return if combined_trusted_pool_set.superset?(unfiltered_pool.to_set) viable_pool = unfiltered_pool .select { |c| !strict || c.version < 2 ? !c.for_domain_name? : c.certificate_authority? && c.certificate_sign? } .select(&:acceptable?) .to_set return if combined_trusted_pool_set.superset?(viable_pool) working_pool = intermediate_pool + viable_pool - excluded_pool all_chains = working_pool.map { |cert| cert.chain_from(working_pool) } unique_chains = all_chains.sort_by(&:length).reverse.inject([]) { |chains, chain| chains << chain unless chains.any? { |longer_chain| (chain - longer_chain).empty? }; chains } trusted_certs = unique_chains.select { |chain| trust?(chain) }.flatten trusted_certs -= detect_circular_chains(unique_chains).flatten return if trusted_certs.to_set == @intermediate_pool @intermediate_pool.replace(trusted_certs) @adapter.store_pool(:intermediate, intermediate_pool) end
detect_circular_chains(chains)
click to toggle source
# File lib/ssltool/certificate_store.rb, line 64 def detect_circular_chains(chains) circular_chains = chains.map(&:dup) .each { |chain| chain.shift until chain[1..-1].to_a.any? { |other_cert| chain.first.signs?(other_cert) } || chain.empty? } .reject { |chain| chain.length <= 1 } .map(&:to_set).uniq.map(&:to_a) @circular_chain_notification_callbacks.each { |proc| proc.call(circular_chains) } unless circular_chains.empty? circular_chains end
on_circular_chain_detection(&block)
click to toggle source
# File lib/ssltool/certificate_store.rb, line 73 def on_circular_chain_detection(&block) raise ArgumentError, "Missing block" unless block_given? @circular_chain_notification_callbacks << block end
resolve_chain(certs)
click to toggle source
chains
# File lib/ssltool/certificate_store.rb, line 80 def resolve_chain(certs) certs = Certificate.scan(certs) if certs.is_a?(String) detect_and_merge_intermediates!(certs) ChainResolution.new(certs, self) end
trust?(*chain)
click to toggle source
# File lib/ssltool/certificate_store.rb, line 40 def trust?(*chain) chain.flatten.reverse.any? { |cert| trusted_pool.any? { |trusted_cert| trusted_cert.signs? cert } } end