Class: Puppet::SSL::Validator::DefaultValidator Deprecated Private
- Defined in:
- lib/puppet/ssl/validator/default_validator.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Perform peer certificate verification against the known CA. If there is no CA information known, then no verification is performed
Constant Summary collapse
- FIVE_MINUTES_AS_SECONDS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
5 * 60
Instance Attribute Summary collapse
-
#peer_certs ⇒ Object
readonly
private
< class Puppet::SSL::Validator.
- #verify_errors ⇒ Object readonly private
Instance Method Summary collapse
-
#call(preverify_ok, store_context) ⇒ Boolean
private
Performs verification of the SSL connection and collection of the certificates for use in constructing the error message if the verification failed.
-
#decode_cert_bundle(bundle_str) ⇒ Array<OpenSSL::X509::Certificate>
private
Decode a string of concatenated certificates.
-
#has_authz_peer_cert(peer_certs, authz_certs) ⇒ Boolean
private
Checks if the set of peer_certs contains at least one certificate issued by a certificate listed in authz_certs.
-
#initialize(ca_path = Puppet[:ssl_client_ca_auth] || Puppet[:localcacert]) ⇒ DefaultValidator
constructor
private
Creates a new DefaultValidator, optionally with an SSL Configuration and SSL Host.
-
#read_file(path) ⇒ Object
private
read_file makes testing easier.
-
#reset! ⇒ Object
private
Resets this validator to its initial validation state.
-
#setup_connection(connection, ssl_host = Puppet.lookup(:ssl_host)) ⇒ void
private
Registers the instance’s call method with the connection.
- #ssl_certificates_are_present? ⇒ Boolean private
-
#valid_peer? ⇒ Boolean
private
Validates the peer certificates against the authorized certificates.
Constructor Details
#initialize(ca_path = Puppet[:ssl_client_ca_auth] || Puppet[:localcacert]) ⇒ DefaultValidator
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates a new DefaultValidator, optionally with an SSL Configuration and SSL Host.
22 23 24 25 26 27 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 22 def initialize( ca_path = Puppet[:ssl_client_ca_auth] || Puppet[:localcacert]) reset! @ca_path = ca_path end |
Instance Attribute Details
#peer_certs ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
< class Puppet::SSL::Validator
11 12 13 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 11 def peer_certs @peer_certs end |
#verify_errors ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
12 13 14 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 12 def verify_errors @verify_errors end |
Instance Method Details
#call(preverify_ok, store_context) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
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.
From the [OpenSSL documentation](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_store_ctx is a pointer to the complete context used for the certificate chain verification.
See Network::HTTP::Connection for more information and where this class is intended to be used.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 65 def call(preverify_ok, store_context) current_cert = store_context.current_cert @peer_certs << current_cert # We must make a copy since the scope of the store_context will be lost # across invocations of this method. if preverify_ok # If we've copied all of the certs in the chain out of the SSL library if @peer_certs.length == store_context.chain.length # (#20027) The peer cert must be issued by a specific authority preverify_ok = valid_peer? end else error = store_context.error || 0 error_string = store_context.error_string || "OpenSSL error #{error}" case error when OpenSSL::X509::V_ERR_CRL_NOT_YET_VALID # current_crl can be nil # https://github.com/ruby/ruby/blob/ruby_1_9_3/ext/openssl/ossl_x509store.c#L501-L510 crl = store_context.current_crl if crl if crl.last_update && crl.last_update < Time.now + FIVE_MINUTES_AS_SECONDS Puppet.debug("Ignoring CRL not yet valid, current time #{Time.now.utc}, CRL last updated #{crl.last_update.utc}") preverify_ok = true else @verify_errors << "#{error_string} for #{crl.issuer}" end else @verify_errors << error_string end else @verify_errors << "#{error_string} for #{current_cert.subject}" end end preverify_ok rescue => ex @verify_errors << ex. false end |
#decode_cert_bundle(bundle_str) ⇒ Array<OpenSSL::X509::Certificate>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Decode a string of concatenated certificates
132 133 134 135 136 137 138 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 132 def decode_cert_bundle(bundle_str) re = /-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m pem_ary = bundle_str.scan(re) pem_ary.map do |pem_str| OpenSSL::X509::Certificate.new(pem_str) end end |
#has_authz_peer_cert(peer_certs, authz_certs) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks if the set of peer_certs contains at least one certificate issued by a certificate listed in authz_certs
175 176 177 178 179 180 181 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 175 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 end |
#read_file(path) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
read_file makes testing easier.
141 142 143 144 145 146 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 141 def read_file(path) # https://www.ietf.org/rfc/rfc2459.txt defines the x509 V3 certificate format # CA bundles are concatenated X509 certificates, but may also include # comments, which could have UTF-8 characters Puppet::FileSystem.read(path, :encoding => Encoding::UTF_8) end |
#reset! ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Resets this validator to its initial validation state. The ssl configuration is not changed.
34 35 36 37 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 34 def reset! @peer_certs = [] @verify_errors = [] end |
#setup_connection(connection, ssl_host = Puppet.lookup(:ssl_host)) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Registers the instance’s call method with the connection.
115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 115 def setup_connection(connection, ssl_host = Puppet.lookup(:ssl_host)) if ssl_certificates_are_present? connection.cert_store = ssl_host.ssl_store connection.ca_file = @ca_path connection.cert = ssl_host.certificate.content connection.key = ssl_host.key.content connection.verify_mode = OpenSSL::SSL::VERIFY_PEER connection.verify_callback = self else connection.verify_mode = OpenSSL::SSL::VERIFY_NONE end end |
#ssl_certificates_are_present? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
185 186 187 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 185 def ssl_certificates_are_present? Puppet::FileSystem.exist?(Puppet[:hostcert]) && Puppet::FileSystem.exist?(@ca_path) end |
#valid_peer? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Validates the peer certificates against the authorized certificates.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/puppet/ssl/validator/default_validator.rb', line 152 def valid_peer? descending_cert_chain = @peer_certs.reverse authz_ca_certs = decode_cert_bundle(read_file(@ca_path)) 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 end |