Class: Sepa::Response
- Inherits:
-
Object
- Object
- Sepa::Response
- Defined in:
- lib/sepa/response.rb
Instance Method Summary collapse
-
#application_response ⇒ Object
Gets the application response from the response as an Nokogiri::XML document.
-
#cert_is_trusted?(root_cert) ⇒ Boolean
Verifies that the soap’s certificate is trusted.
-
#certificate ⇒ Object
Returns the x509 certificate embedded in the soap as an OpenSSL::X509::Certificate.
-
#hashes_match?(options = {}) ⇒ Boolean
Verifies that all digest values in the response match the actual ones.
-
#initialize(response) ⇒ Response
constructor
A new instance of Response.
-
#signature_is_valid? ⇒ Boolean
Verifies the signature by extracting the public key from the certificate embedded in the soap header and verifying the signature value with that.
Constructor Details
#initialize(response) ⇒ Response
Returns a new instance of Response.
3 4 5 6 7 8 9 10 11 12 13 |
# File 'lib/sepa/response.rb', line 3 def initialize(response) @response = response if !@response.respond_to?(:canonicalize) fail ArgumentError, "The response you provided is not a valid Nokogiri::XML file." elsif !valid_against_schema?(@response) fail ArgumentError, "The response you provided doesn't validate against soap schema." end end |
Instance Method Details
#application_response ⇒ Object
Gets the application response from the response as an Nokogiri::XML document
97 98 99 100 101 |
# File 'lib/sepa/response.rb', line 97 def application_response ar = @response.at_css('mod|ApplicationResponse').content ar = Base64.decode64(ar) Nokogiri::XML(ar) end |
#cert_is_trusted?(root_cert) ⇒ Boolean
Verifies that the soap’s certificate is trusted.
36 37 38 39 40 41 42 43 44 |
# File 'lib/sepa/response.rb', line 36 def cert_is_trusted?(root_cert) if root_cert.subject == certificate.issuer certificate.verify(root_cert.public_key) else fail SecurityError, "The issuer of the certificate doesn't match the subject of the roo" \ "t certificate." end end |
#certificate ⇒ Object
Returns the x509 certificate embedded in the soap as an OpenSSL::X509::Certificate
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/sepa/response.rb', line 17 def certificate cert_value = @response.at_css( 'wsse|BinarySecurityToken', 'wsse' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ws' \ 'security-secext-1.0.xsd' ).content.gsub(/\s+/, "") cert = process_cert_value(cert_value) begin cert = OpenSSL::X509::Certificate.new(cert) rescue => e fail OpenSSL::X509::CertificateError, "The certificate embedded to the soap response could not be process" \ "ed. It's most likely corrupted. OpenSSL had this to say: #{e}." end end |
#hashes_match?(options = {}) ⇒ Boolean
Verifies that all digest values in the response match the actual ones. Takes an optional verbose parameter to show which digests didn’t match i.e. verbose: true
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/sepa/response.rb', line 49 def hashes_match?( = {}) digests = find_digest_values(@response) nodes = find_nodes_to_verify(@response, digests) verified_digests = digests.select do |uri, digest| uri = uri.sub(/^#/, '') digest == nodes[uri] end if digests == verified_digests true else unverified_digests = digests.select do |uri, digest| uri = uri.sub(/^#/, '') digest != nodes[uri] end if [:verbose] puts "These digests failed to verify: #{unverified_digests}." end false end end |
#signature_is_valid? ⇒ Boolean
Verifies the signature by extracting the public key from the certificate embedded in the soap header and verifying the signature value with that.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/sepa/response.rb', line 76 def signature_is_valid? node = @response.at_css('xmlns|SignedInfo', 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#') node = node.canonicalize( mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0, inclusive_namespaces=nil,with_comments=false ) signature = @response.at_css( 'xmlns|SignatureValue', 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#' ).content signature = Base64.decode64(signature) certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, node) end |