Module: Sepa::Utilities
- Included in:
- ApplicationRequest, ApplicationResponse, Client, NordeaResponse, OpResponse, Response, SoapBuilder
- Defined in:
- lib/sepa/utilities.rb
Overview
Contains utility methods that are used in this gem.
Instance Method Summary collapse
-
#calculate_digest(node) ⇒ String
Calculates a SHA1 digest for a given node.
-
#canonicalize_exclusively(value) ⇒ String
Canonicalizes an xml node exclusively without comments.
-
#canonicalized_node(doc, namespace, node) ⇒ String?
Canonicalizes a node inclusively.
-
#cert_request_valid?(cert_request) ⇒ true, false
Checks whether a certificate signing request is valid.
-
#check_validity_against_schema(doc, schema) ⇒ Object
Validates whether a doc is valid against a schema.
-
#csr_to_binary(csr) ⇒ String
Converts a certificate signing request from base64 encoded string to binary string.
-
#decode(value) ⇒ String
Decodes a base64 encoded string.
-
#encode(value) ⇒ String
Base64 encodes a given value.
-
#extract_cert(doc, node, namespace) ⇒ OpenSSL::X509::Certificate?
Extracts a certificate from a document and returns it as an OpenSSL X509 certificate.
-
#format_cert(cert) ⇒ String
Removes begin and end certificate texts from a certificate and removes whitespaces to make the certificate read to be embedded in xml.
-
#format_cert_request(cert_request) ⇒ String
Removes begin and end certificate request texts from a certificate signing request and removes whitespaces.
-
#hmac(pin, csr) ⇒ String
Calculates an HMAC for a given pin and certificate signing request.
-
#iso_time ⇒ String
Gets current utc time in iso-format.
-
#load_body_template(template) ⇒ Nokogiri::XML::Document
Loads a soap or application request xml template according to a parameter and command.
-
#process_cert_value(cert_value) ⇒ String
Takes a certificate, adds begin and end certificate texts and splits it into multiple lines so that OpenSSL can read it.
-
#rsa_key(key_as_string) ⇒ OpenSSL::PKey::RSA
Creates a new OpenSSL RSA key from a string key.
-
#set_node_id(document, namespace, node, position) ⇒ String
Generates a random id for a node in soap and sets it to the soap header.
-
#validate_signature(doc, certificate, canonicalization_method) ⇒ true, false
Verifies that a signature has been created with the private key of a certificate.
-
#verify_certificate_against_root_certificate(certificate, root_certificate) ⇒ true, false
Verifies that a certificate has been signed by the private key of a root certificate.
-
#x509_certificate(value) ⇒ OpenSSL::X509::Certificate
Creates a new OpenSSL X509 certificate from a string.
-
#xml_doc(value) ⇒ Nokogiri::XML::Document
Converts an xml string to a nokogiri document.
Instance Method Details
#calculate_digest(node) ⇒ String
Calculates a SHA1 digest for a given node. Before the calculation, the node is canonicalized exclusively.
9 10 11 12 13 14 15 |
# File 'lib/sepa/utilities.rb', line 9 def calculate_digest(node) sha1 = OpenSSL::Digest::SHA1.new canon_node = canonicalize_exclusively(node) encode(sha1.digest(canon_node)).gsub(/\s+/, "") end |
#canonicalize_exclusively(value) ⇒ String
Canonicalizes an xml node exclusively without comments
189 190 191 |
# File 'lib/sepa/utilities.rb', line 189 def canonicalize_exclusively(value) value.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0) end |
#canonicalized_node(doc, namespace, node) ⇒ String?
Canonicalizes a node inclusively
164 165 166 167 |
# File 'lib/sepa/utilities.rb', line 164 def canonicalized_node(doc, namespace, node) content_node = doc.at("xmlns|#{node}", xmlns: namespace) content_node.canonicalize if content_node end |
#cert_request_valid?(cert_request) ⇒ true, false
rename
Checks whether a certificate signing request is valid
104 105 106 107 108 109 110 111 112 |
# File 'lib/sepa/utilities.rb', line 104 def cert_request_valid?(cert_request) begin OpenSSL::X509::Request.new cert_request rescue return false end true end |
#check_validity_against_schema(doc, schema) ⇒ Object
Validates whether a doc is valid against a schema. Adds error using ActiveModel validations if document is not valid against the schema.
61 62 63 64 65 66 67 68 |
# File 'lib/sepa/utilities.rb', line 61 def check_validity_against_schema(doc, schema) Dir.chdir(SCHEMA_PATH) do xsd = Nokogiri::XML::Schema(IO.read(schema)) unless doc.respond_to?(:canonicalize) && xsd.valid?(doc) errors.add(:base, 'The document did not validate against the schema file') end end end |
#csr_to_binary(csr) ⇒ String
Converts a certificate signing request from base64 encoded string to binary string
153 154 155 |
# File 'lib/sepa/utilities.rb', line 153 def csr_to_binary(csr) OpenSSL::X509::Request.new(csr).to_der end |
#decode(value) ⇒ String
Decodes a base64 encoded string
181 182 183 |
# File 'lib/sepa/utilities.rb', line 181 def decode(value) Base64.decode64 value end |
#encode(value) ⇒ String
Base64 encodes a given value
229 230 231 |
# File 'lib/sepa/utilities.rb', line 229 def encode(value) Base64.encode64 value end |
#extract_cert(doc, node, namespace) ⇒ OpenSSL::X509::Certificate?
refactor not to fail
Extracts a certificate from a document and returns it as an OpenSSL X509 certificate. Returns nil if the node cannot be found
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/sepa/utilities.rb', line 80 def extract_cert(doc, node, namespace) cert_raw = doc.at("xmlns|#{node}", 'xmlns' => namespace) return nil unless cert_raw cert_raw = cert_raw.content.gsub(/\s+/, "") cert = process_cert_value(cert_raw) begin x509_certificate(cert) rescue => e fail OpenSSL::X509::CertificateError, "The certificate could not be processed. It's most likely corrupted. " \ "OpenSSL had this to say: #{e}." end end |
#format_cert(cert) ⇒ String
rename maybe
Removes begin and end certificate texts from a certificate and removes whitespaces to make the certificate read to be embedded in xml.
37 38 39 40 41 42 |
# File 'lib/sepa/utilities.rb', line 37 def format_cert(cert) cert = cert.to_s cert = cert.split('-----BEGIN CERTIFICATE-----')[1] cert = cert.split('-----END CERTIFICATE-----')[0] cert.gsub!(/\s+/, "") end |
#format_cert_request(cert_request) ⇒ String
rename
Removes begin and end certificate request texts from a certificate signing request and removes whitespaces
50 51 52 53 54 |
# File 'lib/sepa/utilities.rb', line 50 def format_cert_request(cert_request) cert_request = cert_request.split('-----BEGIN CERTIFICATE REQUEST-----')[1] cert_request = cert_request.split('-----END CERTIFICATE REQUEST-----')[0] cert_request.gsub!(/\s+/, "") end |
#hmac(pin, csr) ⇒ String
Calculates an HMAC for a given pin and certificate signing request. Used by Nordea certificate requests.
145 146 147 |
# File 'lib/sepa/utilities.rb', line 145 def hmac(pin, csr) encode(OpenSSL::HMAC.digest('sha1', pin, csr)).chop end |
#iso_time ⇒ String
Gets current utc time in iso-format
135 136 137 |
# File 'lib/sepa/utilities.rb', line 135 def iso_time @iso_time ||= Time.now.utc.iso8601 end |
#load_body_template(template) ⇒ Nokogiri::XML::Document
Loads a soap or application request xml template according to a parameter and command.
120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/sepa/utilities.rb', line 120 def load_body_template(template) fail ArgumentError, 'Unsupported command' unless SUPPORTED_COMMANDS.include?(@command) file = if STANDARD_COMMANDS.include?(@command) "#{template}/#{@command}.xml" else "#{template}/#{@bank}/#{@command}.xml" end xml_doc(File.open(file)) end |
#process_cert_value(cert_value) ⇒ String
rename maybe because this seems more formatting than #format_cert
Takes a certificate, adds begin and end certificate texts and splits it into multiple lines so that OpenSSL can read it.
23 24 25 26 27 28 |
# File 'lib/sepa/utilities.rb', line 23 def process_cert_value(cert_value) cert = "-----BEGIN CERTIFICATE-----\n" cert << cert_value.to_s.gsub(/\s+/, "").scan(/.{1,64}/).join("\n") cert << "\n" cert << "-----END CERTIFICATE-----" end |
#rsa_key(key_as_string) ⇒ OpenSSL::PKey::RSA
Creates a new OpenSSL RSA key from a string key
254 255 256 |
# File 'lib/sepa/utilities.rb', line 254 def rsa_key(key_as_string) OpenSSL::PKey::RSA.new key_as_string end |
#set_node_id(document, namespace, node, position) ⇒ String
create functionality to automatically add reference nodes to header so than position is not needed
Generates a random id for a node in soap and sets it to the soap header
defines which reference is used. Numbering starts from 0.
268 269 270 271 272 273 274 |
# File 'lib/sepa/utilities.rb', line 268 def set_node_id(document, namespace, node, position) node_id = "#{node.downcase}-#{SecureRandom.uuid}" document.at("xmlns|#{node}", xmlns: namespace)['wsu:Id'] = node_id @header_template.css('dsig|Reference')[position]['URI'] = "##{node_id}" node_id end |
#validate_signature(doc, certificate, canonicalization_method) ⇒ true, false
Verifies that a signature has been created with the private key of a certificate
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/sepa/utilities.rb', line 285 def validate_signature(doc, certificate, canonicalization_method) node = doc.at('xmlns|SignedInfo', xmlns: DSIG) return false unless node node = case canonicalization_method when :normal node.canonicalize when :exclusive canonicalize_exclusively node end signature = doc.at('xmlns|SignatureValue', xmlns: DSIG).content signature = decode(signature) # Return true or false certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, node) end |
#verify_certificate_against_root_certificate(certificate, root_certificate) ⇒ true, false
Verifies that a certificate has been signed by the private key of a root certificate
312 313 314 315 316 317 |
# File 'lib/sepa/utilities.rb', line 312 def verify_certificate_against_root_certificate(certificate, root_certificate) return false unless certificate && root_certificate return false unless root_certificate.subject == certificate.issuer certificate.verify(root_certificate.public_key) end |
#x509_certificate(value) ⇒ OpenSSL::X509::Certificate
Creates a new OpenSSL X509 certificate from a string
221 222 223 |
# File 'lib/sepa/utilities.rb', line 221 def x509_certificate(value) OpenSSL::X509::Certificate.new value end |
#xml_doc(value) ⇒ Nokogiri::XML::Document
Converts an xml string to a nokogiri document
173 174 175 |
# File 'lib/sepa/utilities.rb', line 173 def xml_doc(value) Nokogiri::XML value end |