lib/puppet/ssl/validator.rb in puppet-3.3.2 vs lib/puppet/ssl/validator.rb in puppet-3.4.0.rc1

- old
+ new

@@ -1,116 +1,60 @@ -require 'puppet/ssl' require 'openssl' -module Puppet -module SSL -class Validator - attr_reader :peer_certs - attr_reader :verify_errors - attr_reader :ssl_configuration - ## - # @param [Hash] opts the options to initialze the instance with. +# API for certificate verification +# +# @api public +class Puppet::SSL::Validator + + # Factory method for creating an instance of a null/no validator. + # This method does not have to be implemented by concrete implementations of this API. # - # @option opts [Puppet::SSL::Configuration] :ssl_configuration to use for - # authorizing the peer certificate chain. - def initialize(opts = {}) - reset! - @ssl_configuration = opts[:ssl_configuration] or raise ArgumentError, ":ssl_configuration is required" + # @return [Puppet::SSL::Validator] produces a validator that performs no validation + # + # @api public + # + def self.no_validator() + @@no_validator_cache ||= Puppet::SSL::Validator::NoValidator.new() end - ## - # reset to the initial state. - def reset! - @peer_certs = [] - @verify_errors = [] - end - - ## - # call performs verification of the SSL connection and collection of the - # certificates for use in constructing the error message if the verification - # failed. This callback will be executed once for each certificate in a - # chain being verified. + # Factory method for creating an instance of the default Puppet validator. + # This method does not have to be implemented by concrete implementations of this API. # - # From the [OpenSSL - # documentation](http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html): - # The `verify_callback` function is used to control the behaviour when the - # SSL_VERIFY_PEER flag is set. It must be supplied by the application and - # receives two arguments: preverify_ok indicates, whether the verification of - # the certificate in question was passed (preverify_ok=1) or not - # (preverify_ok=0). x509_ctx is a pointer to the complete context used for - # the certificate chain verification. + # @return [Puppet::SSL::Validator] produces a validator that performs no validation # - # See {Puppet::Network::HTTP::Connection} for more information and where this - # class is intended to be used. + # @api public # - # @param [Boolean] preverify_ok indicates whether the verification of the - # certificate in question was passed (preverify_ok=true) - # @param [OpenSSL::SSL::SSLContext] ssl_context holds the SSLContext for the - # chain being verified. - # - # @return [Boolean] false if the peer is invalid, true otherwise. - def call(preverify_ok, ssl_context) - # We must make a copy since the scope of the ssl_context will be lost - # across invocations of this method. - current_cert = ssl_context.current_cert - @peer_certs << Puppet::SSL::Certificate.from_instance(current_cert) - - if preverify_ok - # If we've copied all of the certs in the chain out of the SSL library - if @peer_certs.length == ssl_context.chain.length - # (#20027) The peer cert must be issued by a specific authority - preverify_ok = valid_peer? - end - else - if ssl_context.error_string - @verify_errors << "#{ssl_context.error_string} for #{current_cert.subject}" - end - end - preverify_ok - rescue => ex - @verify_errors << ex.message - false + def self.default_validator() + Puppet::SSL::Validator::DefaultValidator.new() end - ## - # Register the instance's call method with the connection. + # Array of peer certificates + # @return [Array<Puppet::SSL::Certificate>] peer certificates # - # @param [Net::HTTP] connection The connection to velidate + # @api public # - # @return [void] - def register_verify_callback(connection) - connection.verify_callback = self + def peer_certs + raise NotImplementedError, "Concrete class should have implemented this method" end - ## - # Validate the peer certificates against the authorized certificates. - def valid_peer? - descending_cert_chain = @peer_certs.reverse.map {|c| c.content } - authz_ca_certs = ssl_configuration.ca_auth_certificates - - if not has_authz_peer_cert(descending_cert_chain, authz_ca_certs) - msg = "The server presented a SSL certificate chain which does not include a " << - "CA listed in the ssl_client_ca_auth file. " - msg << "Authorized Issuers: #{authz_ca_certs.collect {|c| c.subject}.join(', ')} " << - "Peer Chain: #{descending_cert_chain.collect {|c| c.subject}.join(' => ')}" - @verify_errors << msg - false - else - true - end + # Contains the result of validation + # @return [Array<String>, nil] nil, empty Array, or Array with messages + # + # @api public + # + def verify_errors + raise NotImplementedError, "Concrete class should have implemented this method" end - ## - # checks if the set of peer_certs contains at least one certificate issued - # by a certificate listed in authz_certs + # Registers the connection to validate. # - # @return [Boolean] - def has_authz_peer_cert(peer_certs, authz_certs) - peer_certs.any? do |peer_cert| - authz_certs.any? do |authz_cert| - peer_cert.verify(authz_cert.public_key) - end - end + # @param [Net::HTTP] connection The connection to validate + # + # @return [void] + # + # @api public + # + def setup_connection(connection) + raise NotImplementedError, "Concrete class should have implemented this method" end end -end -end +